speccore 6.5.1 → 6.10.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 (108) hide show
  1. package/.agents/skills/spec-ask/SKILL.md +6 -0
  2. package/.agents/skills/spec-reindex/SKILL.md +40 -0
  3. package/.agents/skills/speccore-router/SKILL.md +9 -0
  4. package/dist/cli.js +9 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/about.d.ts.map +1 -1
  7. package/dist/commands/about.js +10 -3
  8. package/dist/commands/about.js.map +1 -1
  9. package/dist/commands/analyze.d.ts +2 -0
  10. package/dist/commands/analyze.d.ts.map +1 -1
  11. package/dist/commands/analyze.js +141 -0
  12. package/dist/commands/analyze.js.map +1 -1
  13. package/dist/commands/change.d.ts.map +1 -1
  14. package/dist/commands/change.js +3 -0
  15. package/dist/commands/change.js.map +1 -1
  16. package/dist/commands/doc2spec.d.ts +1 -0
  17. package/dist/commands/doc2spec.d.ts.map +1 -1
  18. package/dist/commands/doc2spec.js +175 -0
  19. package/dist/commands/doc2spec.js.map +1 -1
  20. package/dist/commands/execute.d.ts.map +1 -1
  21. package/dist/commands/execute.js +20 -6
  22. package/dist/commands/execute.js.map +1 -1
  23. package/dist/commands/help.js +32 -5
  24. package/dist/commands/help.js.map +1 -1
  25. package/dist/commands/iteration/create.d.ts.map +1 -1
  26. package/dist/commands/iteration/create.js +38 -10
  27. package/dist/commands/iteration/create.js.map +1 -1
  28. package/dist/commands/iteration/split.d.ts.map +1 -1
  29. package/dist/commands/iteration/split.js +125 -9
  30. package/dist/commands/iteration/split.js.map +1 -1
  31. package/dist/commands/rag-index.d.ts +19 -0
  32. package/dist/commands/rag-index.d.ts.map +1 -0
  33. package/dist/commands/rag-index.js +272 -0
  34. package/dist/commands/rag-index.js.map +1 -0
  35. package/dist/commands/refresh.d.ts +21 -0
  36. package/dist/commands/refresh.d.ts.map +1 -0
  37. package/dist/commands/refresh.js +185 -0
  38. package/dist/commands/refresh.js.map +1 -0
  39. package/dist/commands/sync-global.js +41 -0
  40. package/dist/commands/sync-global.js.map +1 -1
  41. package/dist/core/ai-context-generator.d.ts +2 -0
  42. package/dist/core/ai-context-generator.d.ts.map +1 -1
  43. package/dist/core/ai-context-generator.js +8 -6
  44. package/dist/core/ai-context-generator.js.map +1 -1
  45. package/dist/core/analyze-engine.d.ts +19 -0
  46. package/dist/core/analyze-engine.d.ts.map +1 -1
  47. package/dist/core/analyze-engine.js +326 -9
  48. package/dist/core/analyze-engine.js.map +1 -1
  49. package/dist/core/ask-engine.d.ts.map +1 -1
  50. package/dist/core/ask-engine.js +113 -4
  51. package/dist/core/ask-engine.js.map +1 -1
  52. package/dist/core/ask-host-ai.d.ts.map +1 -1
  53. package/dist/core/ask-host-ai.js +9 -6
  54. package/dist/core/ask-host-ai.js.map +1 -1
  55. package/dist/core/code-scanner.d.ts +24 -2
  56. package/dist/core/code-scanner.d.ts.map +1 -1
  57. package/dist/core/code-scanner.js +235 -5
  58. package/dist/core/code-scanner.js.map +1 -1
  59. package/dist/core/context-builder.d.ts.map +1 -1
  60. package/dist/core/context-builder.js +29 -7
  61. package/dist/core/context-builder.js.map +1 -1
  62. package/dist/core/decay-detector.d.ts +2 -2
  63. package/dist/core/decay-detector.d.ts.map +1 -1
  64. package/dist/core/decay-detector.js +149 -8
  65. package/dist/core/decay-detector.js.map +1 -1
  66. package/dist/core/git-integration.d.ts +50 -2
  67. package/dist/core/git-integration.d.ts.map +1 -1
  68. package/dist/core/git-integration.js +217 -27
  69. package/dist/core/git-integration.js.map +1 -1
  70. package/dist/core/global-knowledge.d.ts +25 -0
  71. package/dist/core/global-knowledge.d.ts.map +1 -0
  72. package/dist/core/global-knowledge.js +228 -0
  73. package/dist/core/global-knowledge.js.map +1 -0
  74. package/dist/core/index-guard.d.ts +57 -0
  75. package/dist/core/index-guard.d.ts.map +1 -0
  76. package/dist/core/index-guard.js +202 -0
  77. package/dist/core/index-guard.js.map +1 -0
  78. package/dist/core/intent-cache.d.ts +3 -1
  79. package/dist/core/intent-cache.d.ts.map +1 -1
  80. package/dist/core/intent-cache.js +33 -3
  81. package/dist/core/intent-cache.js.map +1 -1
  82. package/dist/core/knowledge-graph.d.ts +7 -1
  83. package/dist/core/knowledge-graph.d.ts.map +1 -1
  84. package/dist/core/knowledge-graph.js +265 -32
  85. package/dist/core/knowledge-graph.js.map +1 -1
  86. package/dist/core/platform-registry.d.ts +7 -2
  87. package/dist/core/platform-registry.d.ts.map +1 -1
  88. package/dist/core/platform-registry.js +57 -4
  89. package/dist/core/platform-registry.js.map +1 -1
  90. package/dist/core/prompt-builder.d.ts +3 -2
  91. package/dist/core/prompt-builder.d.ts.map +1 -1
  92. package/dist/core/prompt-builder.js +231 -71
  93. package/dist/core/prompt-builder.js.map +1 -1
  94. package/dist/core/rag-engine.d.ts +152 -0
  95. package/dist/core/rag-engine.d.ts.map +1 -0
  96. package/dist/core/rag-engine.js +816 -0
  97. package/dist/core/rag-engine.js.map +1 -0
  98. package/dist/core/reindex-engine.js +5 -5
  99. package/dist/core/reindex-engine.js.map +1 -1
  100. package/dist/core/task-paths.d.ts +2 -2
  101. package/dist/core/task-paths.d.ts.map +1 -1
  102. package/dist/core/task-paths.js +6 -4
  103. package/dist/core/task-paths.js.map +1 -1
  104. package/dist/core/unified-retrieval.d.ts +140 -0
  105. package/dist/core/unified-retrieval.d.ts.map +1 -0
  106. package/dist/core/unified-retrieval.js +466 -0
  107. package/dist/core/unified-retrieval.js.map +1 -0
  108. package/package.json +1 -1
@@ -44,6 +44,8 @@ exports.formatDecayReport = formatDecayReport;
44
44
  const fs_extra_1 = require("fs-extra");
45
45
  const path_1 = require("path");
46
46
  const crypto_1 = require("crypto");
47
+ const code_scanner_1 = require("./code-scanner");
48
+ const reverse_sync_1 = require("./reverse-sync");
47
49
  // ═══════════════════════════════════════════════
48
50
  // 核心检测
49
51
  // ═══════════════════════════════════════════════
@@ -89,28 +91,46 @@ async function detectDecay(cwd, graph) {
89
91
  };
90
92
  const entities = Object.values(graph.entities);
91
93
  report.summary.total = entities.length;
92
- // 检测 1: content_changed — 文件内容与上次快照不一致
94
+ // 检测 1: content_changed — 文件内容与上次快照不一致,按变更程度分级
93
95
  for (const entity of entities) {
94
96
  if (!entity.file || !entity.hash)
95
97
  continue;
96
- if (snapshot && snapshot.files[entity.file]) {
97
- const oldHash = snapshot.files[entity.file].hash;
98
+ // 直接查找(路径格式一致时匹配)
99
+ let snapshotEntry = snapshot?.files[entity.file];
100
+ // 回退:basename 匹配(应对路径格式不一致的情况)
101
+ if (!snapshotEntry && snapshot) {
102
+ const entityBase = entity.file.split('/').pop();
103
+ for (const [snapPath, snapEntry] of Object.entries(snapshot.files)) {
104
+ if (snapPath.split('/').pop() === entityBase) {
105
+ snapshotEntry = snapEntry;
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ if (snapshotEntry) {
111
+ const oldHash = snapshotEntry.hash;
98
112
  if (oldHash !== entity.hash) {
113
+ // 计算变更强度:基于文件大小变化比例
114
+ const sizeChangeRatio = snapshotEntry.size > 0
115
+ ? Math.abs((entity.hash.length ? snapshotEntry.size : 0) - snapshotEntry.size) / snapshotEntry.size
116
+ : 1;
117
+ const intensity = sizeChangeRatio > 0.5 ? 'major' : sizeChangeRatio > 0.1 ? 'moderate' : 'minor';
118
+ const severity = intensity === 'major' ? 'critical' : intensity === 'moderate' ? 'warning' : 'info';
99
119
  report.decayedFiles.push({
100
120
  entityId: entity.id,
101
121
  title: entity.title,
102
122
  file: entity.file,
103
123
  type: 'content_changed',
104
- severity: 'warning',
105
- detail: `内容自上次索引后已变更(hash: ${oldHash} → ${entity.hash})`,
124
+ severity,
125
+ detail: `内容已变更(强度: ${intensity}, hash: ${oldHash} → ${entity.hash})`,
106
126
  });
107
127
  }
108
128
  }
109
129
  }
110
- // 检测 2: downstream_stale — 上游需求变更,下游 spec/task 未更新
111
- // 找出所有变更的需求
130
+ // 检测 2: downstream_stale — 上游需求重大变更,下游 spec/task 未更新
131
+ // 只关注重大变更(major/critical),忽略 minor 的 typo 修复
112
132
  const changedReqs = new Set(report.decayedFiles
113
- .filter(d => d.type === 'content_changed')
133
+ .filter(d => d.type === 'content_changed' && (d.severity === 'critical' || d.severity === 'warning'))
114
134
  .map(d => d.entityId));
115
135
  for (const reqId of changedReqs) {
116
136
  // 找实现该需求的任务
@@ -147,10 +167,110 @@ async function detectDecay(cwd, graph) {
147
167
  });
148
168
  }
149
169
  }
170
+ // 检测 4: code_ahead_of_spec — 代码已变更但关联 Spec/Task 未同步更新
171
+ const codeDrift = await detectCodeSpecDrift(cwd, graph);
172
+ for (const item of codeDrift) {
173
+ report.decayedFiles.push(item);
174
+ }
150
175
  report.summary.decayed = report.decayedFiles.length;
151
176
  report.summary.healthy = report.summary.total - report.summary.decayed;
152
177
  return report;
153
178
  }
179
+ /**
180
+ * 检测代码→Task→Spec 漂移:代码文件已修改,但关联的 Task/Spec 未更新
181
+ *
182
+ * 逻辑:
183
+ * 1. 扫描代码中的 @spec 注释,建立 filePath → taskId 映射
184
+ * 2. 对比 code-index 中记录的 lastModified 与当前文件 mtime
185
+ * 3. 如果代码文件已变更,查找关联的 Task
186
+ * 4. 通过知识图谱查找 Task 关联的 Spec/Req
187
+ * 5. 生成 code_ahead_of_spec 类型的 DecayItem,affectedDownstream 包含完整影响链
188
+ */
189
+ async function detectCodeSpecDrift(cwd, graph) {
190
+ const results = [];
191
+ // 1. 加载代码索引
192
+ const codeIndex = await (0, code_scanner_1.loadCodeIndex)();
193
+ if (!codeIndex || codeIndex.files.length === 0)
194
+ return results;
195
+ // 2. 扫描 @spec 注释(建立 filePath → taskId 映射)
196
+ const specAnnotations = await (0, reverse_sync_1.scanCodeForSpecAnnotations)(cwd);
197
+ const fileToTasks = new Map();
198
+ for (const ref of specAnnotations) {
199
+ const fullPath = (0, path_1.join)(cwd, ref.file);
200
+ if (!fileToTasks.has(fullPath))
201
+ fileToTasks.set(fullPath, []);
202
+ fileToTasks.get(fullPath).push(ref.taskId);
203
+ }
204
+ // 3. 检查每个有 @spec 关联的代码文件是否已变更
205
+ const checkedTasks = new Set(); // 避免同一 Task 重复报告
206
+ for (const codeFile of codeIndex.files) {
207
+ const fullPath = (0, path_1.join)(cwd, codeFile.path);
208
+ const taskIds = fileToTasks.get(fullPath);
209
+ if (!taskIds || taskIds.length === 0)
210
+ continue;
211
+ // 检查文件当前 mtime 是否大于索引记录的 lastModified
212
+ let currentMtime = 0;
213
+ try {
214
+ const st = await (0, fs_extra_1.stat)(fullPath);
215
+ currentMtime = st.mtimeMs;
216
+ }
217
+ catch {
218
+ continue;
219
+ }
220
+ // 文件在索引建立后有过修改(5分钟容差)
221
+ if (currentMtime <= codeFile.lastModified + 5 * 60 * 1000)
222
+ continue;
223
+ // 4. 对每个关联的 Task,推断影响范围
224
+ for (const taskId of taskIds) {
225
+ if (checkedTasks.has(taskId))
226
+ continue;
227
+ checkedTasks.add(taskId);
228
+ const taskEntity = graph.entities[taskId];
229
+ if (!taskEntity)
230
+ continue;
231
+ // 检查 Task 的 spec 文件是否也更新了
232
+ const taskFile = taskEntity.file;
233
+ let taskMtime = 0;
234
+ if (taskFile) {
235
+ try {
236
+ const st = await (0, fs_extra_1.stat)((0, path_1.join)(cwd, taskFile));
237
+ taskMtime = st.mtimeMs;
238
+ }
239
+ catch { }
240
+ }
241
+ // 如果代码比 Task spec 新,说明存在漂移
242
+ if (taskMtime > 0 && taskMtime >= currentMtime - 60 * 1000)
243
+ continue; // Task 也在最近更新,不算漂移
244
+ // 5. 通过知识图谱查找关联的 Spec/Req
245
+ const affectedChain = [];
246
+ // Task 实现了哪些需求
247
+ const implRelations = graph.relations.filter(r => r.from === taskId && r.type === 'implements');
248
+ for (const rel of implRelations) {
249
+ affectedChain.push(rel.to);
250
+ }
251
+ // Task 参考了哪些规格
252
+ const refRelations = graph.relations.filter(r => r.from === taskId && r.type === 'references');
253
+ for (const rel of refRelations) {
254
+ affectedChain.push(rel.to);
255
+ }
256
+ // Task 依赖了哪些任务(上游也可能受影响)
257
+ const depRelations = graph.relations.filter(r => r.from === taskId && r.type === 'depends_on');
258
+ for (const rel of depRelations) {
259
+ affectedChain.push(rel.to);
260
+ }
261
+ results.push({
262
+ entityId: taskId,
263
+ title: taskEntity.title || taskId,
264
+ file: codeFile.path,
265
+ type: 'code_ahead_of_spec',
266
+ severity: 'warning',
267
+ detail: `代码文件 ${codeFile.path} 已修改(${new Date(currentMtime).toLocaleString()}),但关联的 ${taskId} 及 Spec 未同步更新`,
268
+ affectedDownstream: affectedChain.length > 0 ? affectedChain : undefined,
269
+ });
270
+ }
271
+ }
272
+ return results;
273
+ }
154
274
  /** 格式化衰减报告为 Markdown */
155
275
  function formatDecayReport(report) {
156
276
  const lines = [];
@@ -162,6 +282,8 @@ function formatDecayReport(report) {
162
282
  }
163
283
  const critical = report.decayedFiles.filter(d => d.severity === 'critical');
164
284
  const warning = report.decayedFiles.filter(d => d.severity === 'warning');
285
+ const info = report.decayedFiles.filter(d => d.severity === 'info');
286
+ const codeDrift = report.decayedFiles.filter(d => d.type === 'code_ahead_of_spec');
165
287
  if (critical.length > 0) {
166
288
  lines.push('### ❌ 严重(上下游不一致)');
167
289
  lines.push('');
@@ -170,6 +292,17 @@ function formatDecayReport(report) {
170
292
  }
171
293
  lines.push('');
172
294
  }
295
+ if (codeDrift.length > 0) {
296
+ lines.push('### 📝 代码先行(代码已改但 Spec 未同步)');
297
+ lines.push('');
298
+ for (const item of codeDrift) {
299
+ lines.push(`| \`${item.entityId}\` | ${item.title} | ${item.detail} |`);
300
+ if (item.affectedDownstream && item.affectedDownstream.length > 0) {
301
+ lines.push(`| | 影响链: | ${item.affectedDownstream.join(' → ')} |`);
302
+ }
303
+ }
304
+ lines.push('');
305
+ }
173
306
  if (warning.length > 0) {
174
307
  lines.push('### ⚠️ 警告(内容已变更)');
175
308
  lines.push('');
@@ -178,6 +311,14 @@ function formatDecayReport(report) {
178
311
  }
179
312
  lines.push('');
180
313
  }
314
+ if (info.length > 0) {
315
+ lines.push('### ℹ️ 提示(轻微变更)');
316
+ lines.push('');
317
+ for (const item of info) {
318
+ lines.push(`| \`${item.entityId}\` | ${item.title} | ${item.detail} |`);
319
+ }
320
+ lines.push('');
321
+ }
181
322
  lines.push(`> 共 ${report.summary.total} 个实体,${report.summary.decayed} 个需关注`);
182
323
  return lines.join('\n');
183
324
  }
@@ -1 +1 @@
1
- {"version":3,"file":"decay-detector.js","sourceRoot":"","sources":["../../src/core/decay-detector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decay-detector.js","sourceRoot":"","sources":["../../src/core/decay-detector.ts"],"names":[],"mappings":"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"}
@@ -8,11 +8,59 @@
8
8
  * - Git Hook 安装
9
9
  * - 保护分支拦截
10
10
  */
11
+ /**
12
+ * Git 配置 — 三级回退:子任务级 > 迭代级 > 全局级 > 默认值
13
+ *
14
+ * 继承链:命令行参数 > 子任务 .meta/git-config > 迭代级 PROJECT_GRAPH.md > 全局 CONSTITUTION.md > 默认值
15
+ */
16
+ export interface GitConfig {
17
+ /** 默认基础分支(如 main/master) */
18
+ defaultBranch: string;
19
+ /** 分支类型(feature/bugfix/refactor/research),由任务 type 决定 */
20
+ branchType: string;
21
+ /** 分支前缀(如 2060708),三级回退 */
22
+ branchPrefix: string;
23
+ /** 分支命名格式模板 */
24
+ branchFormat: string;
25
+ /** 创建分支前是否自动 git pull */
26
+ autoPull: boolean;
27
+ /** 远程仓库名称 */
28
+ remoteName: string;
29
+ /** 保护分支列表 */
30
+ protectedBranches: string[];
31
+ }
32
+ /** 任务类型 → 分支类型映射 */
33
+ export declare const TASK_TYPE_TO_BRANCH_TYPE: Record<string, string>;
11
34
  /**
12
35
  * 为任务创建 Git 分支
36
+ *
37
+ * 分支名按子任务级/迭代级/全局配置生成,支持自定义前缀和格式模板
38
+ * 三级回退:子任务 .meta/git-config > 迭代 PROJECT_GRAPH.md > 全局 CONSTITUTION.md
39
+ */
40
+ export declare function createTaskBranch(taskId: string, taskName: string, baseBranch?: string, iteration?: string, taskDir?: string, taskType?: string): string | null;
41
+ /**
42
+ * 读取子任务级 Git 配置
43
+ *
44
+ * 从任务 .meta/git-config 文件读取,格式(每行 key-value):
45
+ * 分支前缀: 2060708
46
+ * 源分支: develop
47
+ * 分支格式: {type}/{prefix}{name}-{hash4}
48
+ * 自动拉取: true
49
+ */
50
+ export declare function loadSubtaskGitConfig(taskDir: string): Partial<GitConfig>;
51
+ /**
52
+ * 加载完整 Git 配置 — 子任务级 > 迭代级 > 全局 > 默认值
53
+ *
54
+ * 配置来源优先级:
55
+ * 1. 子任务级 .meta/git-config 任务自身配置
56
+ * 2. 迭代级 PROJECT_GRAPH.md frontmatter 字段
57
+ * 3. 全局 CONSTITUTION.md Git 分支策略章节
58
+ * 4. 默认值
59
+ *
60
+ * 每个字段独立回退:子任务只配了 branchPrefix,defaultBranch 仍从迭代/全局继承
13
61
  */
14
- export declare function createTaskBranch(taskId: string, taskName: string, baseBranch?: string, iteration?: string): string | null;
15
- /** 检测默认分支: 迭代配置 > CONSTITUTION > git remote > 本地 */
62
+ export declare function loadGitConfig(iteration?: string, taskDir?: string): GitConfig;
63
+ /** 检测默认分支 — 兼容旧接口,内部调用 loadGitConfig */
16
64
  export declare function detectDefaultBranch(iteration?: string): string | undefined;
17
65
  /**
18
66
  * 获取当前分支关联的任务
@@ -1 +1 @@
1
- {"version":3,"file":"git-integration.d.ts","sourceRoot":"","sources":["../../src/core/git-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgBH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6BzH;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAsC1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQnF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAchG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAc/C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAa7D;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA6E1E;AA2BD,6BAA6B;AAC7B,wBAAgB,eAAe,IAAI,OAAO,CAazC"}
1
+ {"version":3,"file":"git-integration.d.ts","sourceRoot":"","sources":["../../src/core/git-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa;IACb,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,oBAAoB;AACpB,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK3D,CAAC;AAYF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAyEf;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA4BxE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAgF7E;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmB1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQnF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAchG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmB9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAc/C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAa7D;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA6E1E;AA2BD,6BAA6B;AAC7B,wBAAgB,eAAe,IAAI,OAAO,CAazC"}
@@ -10,7 +10,10 @@
10
10
  * - 保护分支拦截
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.TASK_TYPE_TO_BRANCH_TYPE = void 0;
13
14
  exports.createTaskBranch = createTaskBranch;
15
+ exports.loadSubtaskGitConfig = loadSubtaskGitConfig;
16
+ exports.loadGitConfig = loadGitConfig;
14
17
  exports.detectDefaultBranch = detectDefaultBranch;
15
18
  exports.getCurrentTaskMapping = getCurrentTaskMapping;
16
19
  exports.generateCommitMessage = generateCommitMessage;
@@ -22,19 +25,66 @@ exports.cleanStaleCache = cleanStaleCache;
22
25
  const fs_extra_1 = require("fs-extra");
23
26
  const path_1 = require("path");
24
27
  const child_process_1 = require("child_process");
28
+ const crypto_1 = require("crypto");
25
29
  const GIT_MAPPING_PATH = '.speccore/.git-mapping.json';
30
+ /** 任务类型 → 分支类型映射 */
31
+ exports.TASK_TYPE_TO_BRANCH_TYPE = {
32
+ feature: 'feature',
33
+ bugfix: 'bugfix',
34
+ refactor: 'refactor',
35
+ research: 'research',
36
+ };
37
+ const DEFAULT_GIT_CONFIG = {
38
+ defaultBranch: 'main',
39
+ branchType: 'feature',
40
+ branchPrefix: '',
41
+ branchFormat: '{type}/{prefix}{name}-{hash4}',
42
+ autoPull: false,
43
+ remoteName: 'origin',
44
+ protectedBranches: ['main', 'master'],
45
+ };
26
46
  /**
27
47
  * 为任务创建 Git 分支
48
+ *
49
+ * 分支名按子任务级/迭代级/全局配置生成,支持自定义前缀和格式模板
50
+ * 三级回退:子任务 .meta/git-config > 迭代 PROJECT_GRAPH.md > 全局 CONSTITUTION.md
28
51
  */
29
- function createTaskBranch(taskId, taskName, baseBranch, iteration) {
52
+ function createTaskBranch(taskId, taskName, baseBranch, iteration, taskDir, taskType) {
30
53
  try {
31
- // 分支名 = taskId + 任务名精简(确保和目录名一致)
54
+ // 读取 Git 配置(子任务级 > 迭代级 > 全局 > 默认)
55
+ const gitConfig = loadGitConfig(iteration, taskDir);
56
+ // 任务类型 → 分支类型
57
+ const branchType = taskType
58
+ ? (exports.TASK_TYPE_TO_BRANCH_TYPE[taskType] || taskType)
59
+ : gitConfig.branchType;
60
+ // 任务名安全处理
32
61
  const safeName = taskName.replace(/[^a-zA-Z0-9\u4e00-\u9fff_-]/g, '-');
33
- const branchName = `feature/${taskId}-${safeName}`.substring(0, 250);
34
- // 确定 base 分支: 显式指定 > 依赖分支 > 迭代配置 > CONSTITUTION > git检测
62
+ // 4 位随机 hex hash
63
+ const hash4 = (0, crypto_1.randomBytes)(2).toString('hex');
64
+ // 前缀段:有值时追加连字符,无值时为空
65
+ const prefixSegment = gitConfig.branchPrefix ? `${gitConfig.branchPrefix}-` : '';
66
+ // 按格式模板生成分支名
67
+ const branchName = formatBranchName(gitConfig.branchFormat, {
68
+ type: branchType,
69
+ prefix: prefixSegment,
70
+ taskId,
71
+ name: safeName,
72
+ date: new Date().toISOString().slice(0, 10).replace(/-/g, ''),
73
+ hash4,
74
+ }).substring(0, 250);
75
+ // 确定 base 分支: 显式指定 > 子任务配置 > 迭代配置 > 全局 > git检测
35
76
  let effectiveBase = baseBranch;
36
77
  if (!effectiveBase) {
37
- effectiveBase = detectDefaultBranch(iteration);
78
+ effectiveBase = gitConfig.defaultBranch;
79
+ }
80
+ // 自动拉取(如果配置开启)
81
+ if (gitConfig.autoPull && effectiveBase) {
82
+ try {
83
+ (0, child_process_1.execSync)(`git pull ${gitConfig.remoteName} "${effectiveBase}"`, { stdio: 'pipe' });
84
+ }
85
+ catch {
86
+ // pull 失败不阻断,继续创建分支
87
+ }
38
88
  }
39
89
  if (effectiveBase) {
40
90
  (0, child_process_1.execSync)(`git checkout "${effectiveBase}"`, { stdio: 'pipe' });
@@ -48,38 +98,178 @@ function createTaskBranch(taskId, taskName, baseBranch, iteration) {
48
98
  }
49
99
  catch (e) {
50
100
  // 分支已存在等非致命错误
51
- if (e.message?.includes('already exists'))
52
- return `feature/${taskId}`;
101
+ if (e.message?.includes('already exists')) {
102
+ const cfg = loadGitConfig(iteration, taskDir);
103
+ const bt = taskType ? (exports.TASK_TYPE_TO_BRANCH_TYPE[taskType] || taskType) : cfg.branchType;
104
+ const ps = cfg.branchPrefix ? `${cfg.branchPrefix}-` : '';
105
+ return formatBranchName(cfg.branchFormat, {
106
+ type: bt,
107
+ prefix: ps,
108
+ taskId,
109
+ name: '',
110
+ date: '',
111
+ hash4: '',
112
+ }).replace(/-{2,}/g, '-').replace(/-$/, '');
113
+ }
53
114
  return null;
54
115
  }
55
116
  }
56
- /** 检测默认分支: 迭代配置 > CONSTITUTION > git remote > 本地 */
57
- function detectDefaultBranch(iteration) {
58
- // 1. 迭代级配置 (PROJECT_GRAPH.md 中 默认分支 字段)
117
+ /**
118
+ * 按模板格式化分支名
119
+ *
120
+ * 支持变量: {type}, {prefix}, {taskId}, {name}, {date}, {hash4}
121
+ */
122
+ function formatBranchName(template, vars) {
123
+ return template
124
+ .replace(/\{type\}/g, vars.type)
125
+ .replace(/\{prefix\}/g, vars.prefix)
126
+ .replace(/\{taskId\}/g, vars.taskId)
127
+ .replace(/\{name\}/g, vars.name)
128
+ .replace(/\{date\}/g, vars.date)
129
+ .replace(/\{hash4\}/g, vars.hash4)
130
+ .replace(/-{2,}/g, '-') // 清理连续连字符
131
+ .replace(/\/$/g, '') // 清理尾部斜杠
132
+ .replace(/^-|-$/g, ''); // 清理头尾连字符
133
+ }
134
+ /**
135
+ * 读取子任务级 Git 配置
136
+ *
137
+ * 从任务 .meta/git-config 文件读取,格式(每行 key-value):
138
+ * 分支前缀: 2060708
139
+ * 源分支: develop
140
+ * 分支格式: {type}/{prefix}{name}-{hash4}
141
+ * 自动拉取: true
142
+ */
143
+ function loadSubtaskGitConfig(taskDir) {
144
+ const config = {};
145
+ try {
146
+ const configPath = (0, path_1.join)(taskDir, '.meta', 'git-config');
147
+ if (!(0, fs_extra_1.existsSync)(configPath))
148
+ return config;
149
+ const content = (0, fs_extra_1.readFileSync)(configPath, 'utf-8');
150
+ // 分支前缀
151
+ const prefixMatch = content.match(/分支前缀[::]\s*(\S+)/);
152
+ if (prefixMatch)
153
+ config.branchPrefix = prefixMatch[1];
154
+ // 源分支
155
+ const branchMatch = content.match(/源分支[::]\s*(\S+)/);
156
+ if (branchMatch)
157
+ config.defaultBranch = branchMatch[1];
158
+ // 分支格式
159
+ const formatMatch = content.match(/分支格式[::]\s*(.+)/);
160
+ if (formatMatch)
161
+ config.branchFormat = formatMatch[1].trim();
162
+ // 自动拉取
163
+ const pullMatch = content.match(/自动拉取[::]\s*(\S+)/);
164
+ if (pullMatch)
165
+ config.autoPull = pullMatch[1] === 'true' || pullMatch[1] === '开启';
166
+ // 远程名称
167
+ const remoteMatch = content.match(/远程名称[::]\s*(\S+)/);
168
+ if (remoteMatch)
169
+ config.remoteName = remoteMatch[1];
170
+ }
171
+ catch { }
172
+ return config;
173
+ }
174
+ /**
175
+ * 加载完整 Git 配置 — 子任务级 > 迭代级 > 全局 > 默认值
176
+ *
177
+ * 配置来源优先级:
178
+ * 1. 子任务级 .meta/git-config 任务自身配置
179
+ * 2. 迭代级 PROJECT_GRAPH.md frontmatter 字段
180
+ * 3. 全局 CONSTITUTION.md Git 分支策略章节
181
+ * 4. 默认值
182
+ *
183
+ * 每个字段独立回退:子任务只配了 branchPrefix,defaultBranch 仍从迭代/全局继承
184
+ */
185
+ function loadGitConfig(iteration, taskDir) {
186
+ const config = {};
187
+ // ── 1. 读取全局 CONSTITUTION.md ──
188
+ try {
189
+ const constitutionPath = (0, path_1.join)('.speccore', 'CONSTITUTION.md');
190
+ if ((0, fs_extra_1.existsSync)(constitutionPath)) {
191
+ const content = (0, fs_extra_1.readFileSync)(constitutionPath, 'utf-8');
192
+ // 默认分支
193
+ const branchMatch = content.match(/默认分支[::]\s*(\S+)/);
194
+ if (branchMatch)
195
+ config.defaultBranch = branchMatch[1];
196
+ // 任务分支前缀(从"任务分支: feature/{Task-ID}"提取前缀)
197
+ const taskBranchMatch = content.match(/任务分支[::]\s*(\S+?)\//);
198
+ if (taskBranchMatch)
199
+ config.branchPrefix = taskBranchMatch[1];
200
+ // 保护分支
201
+ const protectMatch = content.match(/保护分支[::]\s*(.+)/);
202
+ if (protectMatch) {
203
+ config.protectedBranches = protectMatch[1]
204
+ .split(',')
205
+ .map((s) => s.trim())
206
+ .filter(Boolean);
207
+ }
208
+ }
209
+ }
210
+ catch { }
211
+ // ── 2. 迭代级 PROJECT_GRAPH.md 覆盖全局 ──
59
212
  if (iteration) {
60
213
  try {
61
214
  const iterGraphPath = (0, path_1.join)(`Iteration-${iteration}`, '000-overview', 'PROJECT_GRAPH.md');
62
- if (require('fs').existsSync(iterGraphPath)) {
63
- const content = require('fs').readFileSync(iterGraphPath, 'utf-8');
64
- const match = content.match(/默认分支[::]\s*(\S+)/);
65
- if (match)
66
- return match[1];
215
+ if ((0, fs_extra_1.existsSync)(iterGraphPath)) {
216
+ const content = (0, fs_extra_1.readFileSync)(iterGraphPath, 'utf-8');
217
+ // 默认分支
218
+ const branchMatch = content.match(/默认分支[::]\s*(\S+)/);
219
+ if (branchMatch && branchMatch[1] !== '继承全局配置') {
220
+ config.defaultBranch = branchMatch[1];
221
+ }
222
+ // 分支前缀
223
+ const prefixMatch = content.match(/分支前缀[::]\s*(\S+)/);
224
+ if (prefixMatch)
225
+ config.branchPrefix = prefixMatch[1];
226
+ // 分支格式
227
+ const formatMatch = content.match(/分支格式[::]\s*(.+)/);
228
+ if (formatMatch)
229
+ config.branchFormat = formatMatch[1].trim();
230
+ // 自动拉取
231
+ const pullMatch = content.match(/自动拉取[::]\s*(\S+)/);
232
+ if (pullMatch)
233
+ config.autoPull = pullMatch[1] === 'true' || pullMatch[1] === '开启';
234
+ // 远程名称
235
+ const remoteMatch = content.match(/远程名称[::]\s*(\S+)/);
236
+ if (remoteMatch)
237
+ config.remoteName = remoteMatch[1];
67
238
  }
68
239
  }
69
240
  catch { }
70
241
  }
71
- // 2. 全局 CONSTITUTION.md
72
- try {
73
- const constitutionPath = (0, path_1.join)('.speccore', 'CONSTITUTION.md');
74
- if (require('fs').existsSync(constitutionPath)) {
75
- const content = require('fs').readFileSync(constitutionPath, 'utf-8');
76
- const match = content.match(/默认分支[::]\s*(\S+)/);
77
- if (match)
78
- return match[1];
79
- }
242
+ // ── 3. 子任务级 .meta/git-config 覆盖迭代级(每个字段独立判断) ──
243
+ if (taskDir) {
244
+ const subtaskConfig = loadSubtaskGitConfig(taskDir);
245
+ if (subtaskConfig.branchPrefix !== undefined)
246
+ config.branchPrefix = subtaskConfig.branchPrefix;
247
+ if (subtaskConfig.defaultBranch !== undefined)
248
+ config.defaultBranch = subtaskConfig.defaultBranch;
249
+ if (subtaskConfig.branchFormat !== undefined)
250
+ config.branchFormat = subtaskConfig.branchFormat;
251
+ if (subtaskConfig.autoPull !== undefined)
252
+ config.autoPull = subtaskConfig.autoPull;
253
+ if (subtaskConfig.remoteName !== undefined)
254
+ config.remoteName = subtaskConfig.remoteName;
80
255
  }
81
- catch { }
82
- // 3. git remote HEAD
256
+ // ── 4. 合并默认值 ──
257
+ return {
258
+ defaultBranch: config.defaultBranch || DEFAULT_GIT_CONFIG.defaultBranch,
259
+ branchType: config.branchType || DEFAULT_GIT_CONFIG.branchType,
260
+ branchPrefix: config.branchPrefix !== undefined ? config.branchPrefix : DEFAULT_GIT_CONFIG.branchPrefix,
261
+ branchFormat: config.branchFormat || DEFAULT_GIT_CONFIG.branchFormat,
262
+ autoPull: config.autoPull !== undefined ? config.autoPull : DEFAULT_GIT_CONFIG.autoPull,
263
+ remoteName: config.remoteName || DEFAULT_GIT_CONFIG.remoteName,
264
+ protectedBranches: config.protectedBranches || DEFAULT_GIT_CONFIG.protectedBranches,
265
+ };
266
+ }
267
+ /** 检测默认分支 — 兼容旧接口,内部调用 loadGitConfig */
268
+ function detectDefaultBranch(iteration) {
269
+ const cfg = loadGitConfig(iteration);
270
+ if (cfg.defaultBranch)
271
+ return cfg.defaultBranch;
272
+ // 回退:git remote HEAD
83
273
  try {
84
274
  const remote = (0, child_process_1.execSync)('git remote show origin 2>/dev/null', { encoding: 'utf-8' });
85
275
  const headMatch = remote.match(/HEAD branch:\s*(\S+)/);
@@ -87,7 +277,7 @@ function detectDefaultBranch(iteration) {
87
277
  return headMatch[1];
88
278
  }
89
279
  catch { }
90
- // 4. 本地分支
280
+ // 回退:本地分支
91
281
  try {
92
282
  const branches = (0, child_process_1.execSync)('git branch', { encoding: 'utf-8' });
93
283
  if (branches.includes('main') || branches.includes(' main'))