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.
- package/.agents/skills/spec-ask/SKILL.md +6 -0
- package/.agents/skills/spec-reindex/SKILL.md +40 -0
- package/.agents/skills/speccore-router/SKILL.md +9 -0
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/about.d.ts.map +1 -1
- package/dist/commands/about.js +10 -3
- package/dist/commands/about.js.map +1 -1
- package/dist/commands/analyze.d.ts +2 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +141 -0
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/change.d.ts.map +1 -1
- package/dist/commands/change.js +3 -0
- package/dist/commands/change.js.map +1 -1
- package/dist/commands/doc2spec.d.ts +1 -0
- package/dist/commands/doc2spec.d.ts.map +1 -1
- package/dist/commands/doc2spec.js +175 -0
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +20 -6
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +32 -5
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/iteration/create.d.ts.map +1 -1
- package/dist/commands/iteration/create.js +38 -10
- package/dist/commands/iteration/create.js.map +1 -1
- package/dist/commands/iteration/split.d.ts.map +1 -1
- package/dist/commands/iteration/split.js +125 -9
- package/dist/commands/iteration/split.js.map +1 -1
- package/dist/commands/rag-index.d.ts +19 -0
- package/dist/commands/rag-index.d.ts.map +1 -0
- package/dist/commands/rag-index.js +272 -0
- package/dist/commands/rag-index.js.map +1 -0
- package/dist/commands/refresh.d.ts +21 -0
- package/dist/commands/refresh.d.ts.map +1 -0
- package/dist/commands/refresh.js +185 -0
- package/dist/commands/refresh.js.map +1 -0
- package/dist/commands/sync-global.js +41 -0
- package/dist/commands/sync-global.js.map +1 -1
- package/dist/core/ai-context-generator.d.ts +2 -0
- package/dist/core/ai-context-generator.d.ts.map +1 -1
- package/dist/core/ai-context-generator.js +8 -6
- package/dist/core/ai-context-generator.js.map +1 -1
- package/dist/core/analyze-engine.d.ts +19 -0
- package/dist/core/analyze-engine.d.ts.map +1 -1
- package/dist/core/analyze-engine.js +326 -9
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-engine.d.ts.map +1 -1
- package/dist/core/ask-engine.js +113 -4
- package/dist/core/ask-engine.js.map +1 -1
- package/dist/core/ask-host-ai.d.ts.map +1 -1
- package/dist/core/ask-host-ai.js +9 -6
- package/dist/core/ask-host-ai.js.map +1 -1
- package/dist/core/code-scanner.d.ts +24 -2
- package/dist/core/code-scanner.d.ts.map +1 -1
- package/dist/core/code-scanner.js +235 -5
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +29 -7
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/decay-detector.d.ts +2 -2
- package/dist/core/decay-detector.d.ts.map +1 -1
- package/dist/core/decay-detector.js +149 -8
- package/dist/core/decay-detector.js.map +1 -1
- package/dist/core/git-integration.d.ts +50 -2
- package/dist/core/git-integration.d.ts.map +1 -1
- package/dist/core/git-integration.js +217 -27
- package/dist/core/git-integration.js.map +1 -1
- package/dist/core/global-knowledge.d.ts +25 -0
- package/dist/core/global-knowledge.d.ts.map +1 -0
- package/dist/core/global-knowledge.js +228 -0
- package/dist/core/global-knowledge.js.map +1 -0
- package/dist/core/index-guard.d.ts +57 -0
- package/dist/core/index-guard.d.ts.map +1 -0
- package/dist/core/index-guard.js +202 -0
- package/dist/core/index-guard.js.map +1 -0
- package/dist/core/intent-cache.d.ts +3 -1
- package/dist/core/intent-cache.d.ts.map +1 -1
- package/dist/core/intent-cache.js +33 -3
- package/dist/core/intent-cache.js.map +1 -1
- package/dist/core/knowledge-graph.d.ts +7 -1
- package/dist/core/knowledge-graph.d.ts.map +1 -1
- package/dist/core/knowledge-graph.js +265 -32
- package/dist/core/knowledge-graph.js.map +1 -1
- package/dist/core/platform-registry.d.ts +7 -2
- package/dist/core/platform-registry.d.ts.map +1 -1
- package/dist/core/platform-registry.js +57 -4
- package/dist/core/platform-registry.js.map +1 -1
- package/dist/core/prompt-builder.d.ts +3 -2
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +231 -71
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/rag-engine.d.ts +152 -0
- package/dist/core/rag-engine.d.ts.map +1 -0
- package/dist/core/rag-engine.js +816 -0
- package/dist/core/rag-engine.js.map +1 -0
- package/dist/core/reindex-engine.js +5 -5
- package/dist/core/reindex-engine.js.map +1 -1
- package/dist/core/task-paths.d.ts +2 -2
- package/dist/core/task-paths.d.ts.map +1 -1
- package/dist/core/task-paths.js +6 -4
- package/dist/core/task-paths.js.map +1 -1
- package/dist/core/unified-retrieval.d.ts +140 -0
- package/dist/core/unified-retrieval.d.ts.map +1 -0
- package/dist/core/unified-retrieval.js +466 -0
- package/dist/core/unified-retrieval.js.map +1 -0
- 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
|
-
|
|
97
|
-
|
|
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
|
|
105
|
-
detail:
|
|
124
|
+
severity,
|
|
125
|
+
detail: `内容已变更(强度: ${intensity}, hash: ${oldHash} → ${entity.hash})`,
|
|
106
126
|
});
|
|
107
127
|
}
|
|
108
128
|
}
|
|
109
129
|
}
|
|
110
|
-
// 检测 2: downstream_stale —
|
|
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
|
|
15
|
-
/**
|
|
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;
|
|
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
|
-
//
|
|
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
|
-
|
|
34
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
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 (
|
|
63
|
-
const content =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
//
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
82
|
-
|
|
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
|
-
//
|
|
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'))
|