speccore 5.13.0 → 5.15.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/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +1 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +96 -0
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/done.d.ts.map +1 -1
- package/dist/commands/done.js +6 -0
- package/dist/commands/done.js.map +1 -1
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +6 -1
- package/dist/commands/execute.js.map +1 -1
- package/dist/core/git-integration.d.ts.map +1 -1
- package/dist/core/git-integration.js +1 -2
- package/dist/core/git-integration.js.map +1 -1
- package/dist/core/question-checklist.d.ts +14 -0
- package/dist/core/question-checklist.d.ts.map +1 -0
- package/dist/core/question-checklist.js +105 -0
- package/dist/core/question-checklist.js.map +1 -0
- package/package.json +1 -1
- package/dist/core/safe-write.d.ts +0 -20
- package/dist/core/safe-write.d.ts.map +0 -1
- package/dist/core/safe-write.js +0 -34
- package/dist/core/safe-write.js.map +0 -1
- package/dist/core/task-lock.d.ts +0 -30
- package/dist/core/task-lock.d.ts.map +0 -1
- package/dist/core/task-lock.js +0 -94
- package/dist/core/task-lock.js.map +0 -1
- package/dist/core/tx-wrapper.d.ts +0 -17
- package/dist/core/tx-wrapper.d.ts.map +0 -1
- package/dist/core/tx-wrapper.js +0 -31
- package/dist/core/tx-wrapper.js.map +0 -1
- package/dist/locales/en-US.json +0 -153
- package/dist/locales/zh-CN.json +0 -153
- package/dist/utils/file.d.ts +0 -29
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js +0 -126
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/git.d.ts +0 -25
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js +0 -77
- package/dist/utils/git.js.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractQuestions = extractQuestions;
|
|
4
|
+
exports.showQuestionChecklist = showQuestionChecklist;
|
|
5
|
+
/**
|
|
6
|
+
* question-checklist — 从 ANALYSIS.md 提取待确认问题,执行后提醒用户审查
|
|
7
|
+
*/
|
|
8
|
+
const fs_extra_1 = require("fs-extra");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const logger_1 = require("../utils/logger");
|
|
11
|
+
/**
|
|
12
|
+
* 从迭代 ANALYSIS.md 提取所有待确认问题
|
|
13
|
+
*/
|
|
14
|
+
async function extractQuestions(iterationDir) {
|
|
15
|
+
const analysisPath = (0, path_1.join)(iterationDir, '00-需求文档', 'ANALYSIS.md');
|
|
16
|
+
if (!(await (0, fs_extra_1.pathExists)(analysisPath)))
|
|
17
|
+
return [];
|
|
18
|
+
const content = await (0, fs_extra_1.readFile)(analysisPath, 'utf-8');
|
|
19
|
+
const questions = [];
|
|
20
|
+
// 从「待确认」section 提取
|
|
21
|
+
const pendingSection = content.match(/(?:###\s*待确认|##\s*(?:\d+\.\s*)?待确认)[\s\S]*?(?=###|\n---|$)/);
|
|
22
|
+
if (pendingSection) {
|
|
23
|
+
const items = pendingSection[0].match(/[-*]\s+(\[[ x]\]\s*)?[^\n]+/g) || [];
|
|
24
|
+
for (const item of items) {
|
|
25
|
+
const text = item.replace(/^[-*]\s+(\[[ x]\]\s*)?/, '').trim();
|
|
26
|
+
if (text.length > 5) {
|
|
27
|
+
questions.push({
|
|
28
|
+
text,
|
|
29
|
+
category: detectCategory(text),
|
|
30
|
+
severity: '🟡',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// 从「阻断问题」提取
|
|
36
|
+
const blockerSection = content.match(/(?:###\s*阻断问题|##\s*Blockers)[\s\S]*?(?=###|\n---|$)/);
|
|
37
|
+
if (blockerSection) {
|
|
38
|
+
const items = blockerSection[0].match(/[-*]\s+.+/g) || [];
|
|
39
|
+
for (const item of items) {
|
|
40
|
+
const text = item.replace(/^[-*]\s+(\[[ x]\]\s*)?/, '').trim();
|
|
41
|
+
if (text.length > 5) {
|
|
42
|
+
questions.push({
|
|
43
|
+
text,
|
|
44
|
+
category: detectCategory(text),
|
|
45
|
+
severity: '🔴',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 从需求分析标记提取
|
|
51
|
+
const warnLines = content.match(/[⚠️🟡].+/g) || [];
|
|
52
|
+
for (const line of warnLines) {
|
|
53
|
+
const text = line.replace(/[⚠️🟡]\s*/, '').trim();
|
|
54
|
+
if (text.length > 5 && !questions.some(q => q.text.includes(text.slice(0, 10)))) {
|
|
55
|
+
questions.push({
|
|
56
|
+
text,
|
|
57
|
+
category: 'requirement',
|
|
58
|
+
severity: '🟡',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return questions;
|
|
63
|
+
}
|
|
64
|
+
function detectCategory(text) {
|
|
65
|
+
if (text.match(/接口|API|端点|endpoint/i))
|
|
66
|
+
return 'dependency';
|
|
67
|
+
if (text.match(/技术|框架|选型|DB|数据库|中间件|MQ|Redis/i))
|
|
68
|
+
return 'tech';
|
|
69
|
+
if (text.match(/风险|安全|权限|并发|性能/i))
|
|
70
|
+
return 'risk';
|
|
71
|
+
return 'requirement';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 显示问题审查清单
|
|
75
|
+
*/
|
|
76
|
+
function showQuestionChecklist(questions, context = '') {
|
|
77
|
+
if (questions.length === 0) {
|
|
78
|
+
logger_1.logger.info(' ✅ 无待确认问题');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const blockers = questions.filter(q => q.severity === '🔴');
|
|
82
|
+
const pending = questions.filter(q => q.severity === '🟡');
|
|
83
|
+
logger_1.logger.info('');
|
|
84
|
+
logger_1.logger.info(`╔══════════════════════════════════════════╗`);
|
|
85
|
+
logger_1.logger.info(`║ 📋 ${context || '待确认问题清单'} (${questions.length} 项) ║`);
|
|
86
|
+
logger_1.logger.info(`╚══════════════════════════════════════════╝`);
|
|
87
|
+
logger_1.logger.info('');
|
|
88
|
+
if (blockers.length > 0) {
|
|
89
|
+
logger_1.logger.info(` 🔴 阻断 (${blockers.length}):`);
|
|
90
|
+
for (const q of blockers) {
|
|
91
|
+
logger_1.logger.info(` - ${q.text}`);
|
|
92
|
+
}
|
|
93
|
+
logger_1.logger.info('');
|
|
94
|
+
}
|
|
95
|
+
if (pending.length > 0) {
|
|
96
|
+
logger_1.logger.info(` 🟡 待确认 (${pending.length}):`);
|
|
97
|
+
for (const q of pending) {
|
|
98
|
+
logger_1.logger.info(` - ${q.text}`);
|
|
99
|
+
}
|
|
100
|
+
logger_1.logger.info('');
|
|
101
|
+
}
|
|
102
|
+
logger_1.logger.info(' 💡 建议: 逐项确认后再执行 speccore done');
|
|
103
|
+
logger_1.logger.info('');
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=question-checklist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-checklist.js","sourceRoot":"","sources":["../../src/core/question-checklist.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Safe Write Wrapper — 所有命令写文件的统一入口
|
|
3
|
-
*
|
|
4
|
-
* 自动附加 FileTransaction 保护。在不需要完整事务的地方,
|
|
5
|
-
* 至少提供原子写入保障。
|
|
6
|
-
*/
|
|
7
|
-
import { FileTransaction } from './transaction';
|
|
8
|
-
/**
|
|
9
|
-
* 带事务保护的批量写入
|
|
10
|
-
*/
|
|
11
|
-
export declare function createWriteTransaction(): FileTransaction;
|
|
12
|
-
/**
|
|
13
|
-
* 安全单文件写入(原子操作)
|
|
14
|
-
*/
|
|
15
|
-
export declare function safeWriteFile(path: string, content: string): Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* 受事务保护的单文件写入
|
|
18
|
-
*/
|
|
19
|
-
export declare function transactionSafeWrite(tx: FileTransaction, path: string, content: string): Promise<void>;
|
|
20
|
-
//# sourceMappingURL=safe-write.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"safe-write.d.ts","sourceRoot":"","sources":["../../src/core/safe-write.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAExD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5G"}
|
package/dist/core/safe-write.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Safe Write Wrapper — 所有命令写文件的统一入口
|
|
4
|
-
*
|
|
5
|
-
* 自动附加 FileTransaction 保护。在不需要完整事务的地方,
|
|
6
|
-
* 至少提供原子写入保障。
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.createWriteTransaction = createWriteTransaction;
|
|
10
|
-
exports.safeWriteFile = safeWriteFile;
|
|
11
|
-
exports.transactionSafeWrite = transactionSafeWrite;
|
|
12
|
-
const fs_extra_1 = require("fs-extra");
|
|
13
|
-
const path_1 = require("path");
|
|
14
|
-
const transaction_1 = require("./transaction");
|
|
15
|
-
/**
|
|
16
|
-
* 带事务保护的批量写入
|
|
17
|
-
*/
|
|
18
|
-
function createWriteTransaction() {
|
|
19
|
-
return new transaction_1.FileTransaction();
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* 安全单文件写入(原子操作)
|
|
23
|
-
*/
|
|
24
|
-
async function safeWriteFile(path, content) {
|
|
25
|
-
await (0, fs_extra_1.ensureDir)((0, path_1.dirname)(path));
|
|
26
|
-
await (0, fs_extra_1.writeFile)(path, content);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 受事务保护的单文件写入
|
|
30
|
-
*/
|
|
31
|
-
async function transactionSafeWrite(tx, path, content) {
|
|
32
|
-
tx.write(path, content);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=safe-write.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"safe-write.js","sourceRoot":"","sources":["../../src/core/safe-write.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AASH,wDAEC;AAKD,sCAGC;AAKD,oDAEC;AAxBD,uCAAgD;AAChD,+BAA+B;AAC/B,+CAAgD;AAEhD;;GAEG;AACH,SAAgB,sBAAsB;IACpC,OAAO,IAAI,6BAAe,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IAC/D,MAAM,IAAA,oBAAS,EAAC,IAAA,cAAO,EAAC,IAAI,CAAC,CAAC,CAAC;IAC/B,MAAM,IAAA,oBAAS,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,oBAAoB,CAAC,EAAmB,EAAE,IAAY,EAAE,OAAe;IAC3F,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/core/task-lock.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task Lock — 远程协作锁机制
|
|
3
|
-
*
|
|
4
|
-
* 防止多人同时修改同一个 Task
|
|
5
|
-
* 锁文件:.speccore/.locks/{taskId}.lock
|
|
6
|
-
*/
|
|
7
|
-
interface LockData {
|
|
8
|
-
taskId: string;
|
|
9
|
-
holder: string;
|
|
10
|
-
operation: string;
|
|
11
|
-
acquiredAt: string;
|
|
12
|
-
expiresAt: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* 获取锁(如果可用)
|
|
16
|
-
*/
|
|
17
|
-
export declare function acquireLock(taskId: string, operation: string): {
|
|
18
|
-
holder: string;
|
|
19
|
-
acquiredAt: string;
|
|
20
|
-
} | null;
|
|
21
|
-
/**
|
|
22
|
-
* 释放锁
|
|
23
|
-
*/
|
|
24
|
-
export declare function releaseLock(taskId: string): void;
|
|
25
|
-
/**
|
|
26
|
-
* 检查锁状态
|
|
27
|
-
*/
|
|
28
|
-
export declare function checkLock(taskId: string): LockData | null;
|
|
29
|
-
export {};
|
|
30
|
-
//# sourceMappingURL=task-lock.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"task-lock.d.ts","sourceRoot":"","sources":["../../src/core/task-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,UAAU,QAAQ;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAkBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA+B5G;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAczD"}
|
package/dist/core/task-lock.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Task Lock — 远程协作锁机制
|
|
4
|
-
*
|
|
5
|
-
* 防止多人同时修改同一个 Task
|
|
6
|
-
* 锁文件:.speccore/.locks/{taskId}.lock
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.acquireLock = acquireLock;
|
|
10
|
-
exports.releaseLock = releaseLock;
|
|
11
|
-
exports.checkLock = checkLock;
|
|
12
|
-
const fs_1 = require("fs");
|
|
13
|
-
const path_1 = require("path");
|
|
14
|
-
const LOCKS_DIR = '.speccore/.locks';
|
|
15
|
-
const LOCK_TIMEOUT_MINUTES = 30;
|
|
16
|
-
function getLockPath(taskId) {
|
|
17
|
-
return (0, path_1.join)(LOCKS_DIR, `${taskId}.lock`);
|
|
18
|
-
}
|
|
19
|
-
function getUser() {
|
|
20
|
-
try {
|
|
21
|
-
const { execSync } = require('child_process');
|
|
22
|
-
return execSync('git config user.name', { encoding: 'utf-8', stdio: 'pipe' }).trim() || 'unknown';
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return 'unknown';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 获取锁(如果可用)
|
|
30
|
-
*/
|
|
31
|
-
function acquireLock(taskId, operation) {
|
|
32
|
-
ensureLocksDir();
|
|
33
|
-
const lockPath = getLockPath(taskId);
|
|
34
|
-
// 检查已有锁
|
|
35
|
-
if ((0, fs_1.existsSync)(lockPath)) {
|
|
36
|
-
try {
|
|
37
|
-
const existing = JSON.parse((0, fs_1.readFileSync)(lockPath, 'utf-8'));
|
|
38
|
-
const expired = Date.now() > new Date(existing.expiresAt).getTime();
|
|
39
|
-
if (!expired) {
|
|
40
|
-
return { holder: existing.holder, acquiredAt: existing.acquiredAt };
|
|
41
|
-
}
|
|
42
|
-
// 过期锁,删除
|
|
43
|
-
(0, fs_1.unlinkSync)(lockPath);
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
(0, fs_1.unlinkSync)(lockPath);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// 创建新锁
|
|
50
|
-
const user = getUser();
|
|
51
|
-
const data = {
|
|
52
|
-
taskId,
|
|
53
|
-
holder: user,
|
|
54
|
-
operation,
|
|
55
|
-
acquiredAt: new Date().toISOString(),
|
|
56
|
-
expiresAt: new Date(Date.now() + LOCK_TIMEOUT_MINUTES * 60 * 1000).toISOString(),
|
|
57
|
-
};
|
|
58
|
-
(0, fs_1.writeFileSync)(lockPath, JSON.stringify(data, null, 2));
|
|
59
|
-
return null; // 锁获取成功,返回 null 表示无冲突
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* 释放锁
|
|
63
|
-
*/
|
|
64
|
-
function releaseLock(taskId) {
|
|
65
|
-
const lockPath = getLockPath(taskId);
|
|
66
|
-
if ((0, fs_1.existsSync)(lockPath)) {
|
|
67
|
-
(0, fs_1.unlinkSync)(lockPath);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* 检查锁状态
|
|
72
|
-
*/
|
|
73
|
-
function checkLock(taskId) {
|
|
74
|
-
const lockPath = getLockPath(taskId);
|
|
75
|
-
if (!(0, fs_1.existsSync)(lockPath))
|
|
76
|
-
return null;
|
|
77
|
-
try {
|
|
78
|
-
const data = JSON.parse((0, fs_1.readFileSync)(lockPath, 'utf-8'));
|
|
79
|
-
if (Date.now() > new Date(data.expiresAt).getTime()) {
|
|
80
|
-
(0, fs_1.unlinkSync)(lockPath);
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
return data;
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function ensureLocksDir() {
|
|
90
|
-
if (!(0, fs_1.existsSync)(LOCKS_DIR)) {
|
|
91
|
-
(0, fs_1.mkdirSync)(LOCKS_DIR, { recursive: true });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=task-lock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"task-lock.js","sourceRoot":"","sources":["../../src/core/task-lock.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAgCH,kCA+BC;AAKD,kCAKC;AAKD,8BAcC;AA1FD,2BAAoF;AACpF,+BAA4B;AAU5B,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACrC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,IAAA,WAAI,EAAC,SAAS,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,OAAO;IACd,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC9C,OAAO,QAAQ,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACpG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,MAAc,EAAE,SAAiB;IAC3D,cAAc,EAAE,CAAC;IACjB,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,QAAQ;IACR,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAa,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YACpE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;YACtE,CAAC;YACD,SAAS;YACT,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO;IACP,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAa;QACrB,MAAM;QACN,MAAM,EAAE,IAAI;QACZ,SAAS;QACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;KACjF,CAAC;IAEF,IAAA,kBAAa,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,CAAC,sBAAsB;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,MAAc;IACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,MAAc;IACtC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAa,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC,IAAA,eAAU,EAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,IAAA,cAAS,EAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 事务包装工具 — 简化 FileTransaction 在命令中的使用
|
|
3
|
-
*
|
|
4
|
-
* 用法:
|
|
5
|
-
* import { transactional } from './tx-wrapper';
|
|
6
|
-
* await transactional(async (tx) => {
|
|
7
|
-
* tx.write(path, content);
|
|
8
|
-
* tx.write(otherPath, otherContent);
|
|
9
|
-
* });
|
|
10
|
-
*/
|
|
11
|
-
import { FileTransaction } from '../core/transaction';
|
|
12
|
-
export declare function transactional(fn: (tx: FileTransaction) => Promise<void>): Promise<void>;
|
|
13
|
-
/**
|
|
14
|
-
* 快速单文件安全写入
|
|
15
|
-
*/
|
|
16
|
-
export declare function safeWrite(path: string, content: string): Promise<void>;
|
|
17
|
-
//# sourceMappingURL=tx-wrapper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tx-wrapper.d.ts","sourceRoot":"","sources":["../../src/core/tx-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,wBAAsB,aAAa,CACjC,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5E"}
|
package/dist/core/tx-wrapper.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 事务包装工具 — 简化 FileTransaction 在命令中的使用
|
|
4
|
-
*
|
|
5
|
-
* 用法:
|
|
6
|
-
* import { transactional } from './tx-wrapper';
|
|
7
|
-
* await transactional(async (tx) => {
|
|
8
|
-
* tx.write(path, content);
|
|
9
|
-
* tx.write(otherPath, otherContent);
|
|
10
|
-
* });
|
|
11
|
-
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.transactional = transactional;
|
|
14
|
-
exports.safeWrite = safeWrite;
|
|
15
|
-
const transaction_1 = require("../core/transaction");
|
|
16
|
-
async function transactional(fn) {
|
|
17
|
-
const tx = new transaction_1.FileTransaction();
|
|
18
|
-
await fn(tx);
|
|
19
|
-
if (tx.length > 0) {
|
|
20
|
-
await tx.commit();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 快速单文件安全写入
|
|
25
|
-
*/
|
|
26
|
-
async function safeWrite(path, content) {
|
|
27
|
-
const tx = new transaction_1.FileTransaction();
|
|
28
|
-
tx.write(path, content);
|
|
29
|
-
await tx.commit();
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=tx-wrapper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tx-wrapper.js","sourceRoot":"","sources":["../../src/core/tx-wrapper.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAIH,sCAQC;AAKD,8BAIC;AAnBD,qDAAsD;AAE/C,KAAK,UAAU,aAAa,CACjC,EAA0C;IAE1C,MAAM,EAAE,GAAG,IAAI,6BAAe,EAAE,CAAC;IACjC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACb,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,OAAe;IAC3D,MAAM,EAAE,GAAG,IAAI,6BAAe,EAAE,CAAC;IACjC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxB,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
package/dist/locales/en-US.json
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_meta": {
|
|
3
|
-
"locale": "en-US",
|
|
4
|
-
"name": "English"
|
|
5
|
-
},
|
|
6
|
-
"cmd": {
|
|
7
|
-
"init": {
|
|
8
|
-
"start": "Initializing SpecCore project...",
|
|
9
|
-
"success": "Project initialized!",
|
|
10
|
-
"already": "SpecCore already initialized. Use --force to overwrite.",
|
|
11
|
-
"force": "Re-initializing with --force..."
|
|
12
|
-
},
|
|
13
|
-
"import": {
|
|
14
|
-
"start": "Importing project to global layer...",
|
|
15
|
-
"success": "Project imported to global layer",
|
|
16
|
-
"scanning": "Scanning project: {project} ({type})",
|
|
17
|
-
"found": "Found {count} API endpoints, {models} data models",
|
|
18
|
-
"generated_req": "Generated requirement: {req}"
|
|
19
|
-
},
|
|
20
|
-
"execute": {
|
|
21
|
-
"start": "Preparing execution...",
|
|
22
|
-
"preview": "Execution Preview",
|
|
23
|
-
"executing": "Executing {task}...",
|
|
24
|
-
"success": "Execution complete!",
|
|
25
|
-
"dry_run": "Dry run mode — no actual changes",
|
|
26
|
-
"no_tasks": "No matching tasks found",
|
|
27
|
-
"batch_start": "Batch mode: {batches} batches of up to {size} tasks",
|
|
28
|
-
"task_not_found": "Task \"{task}\" not found. Available: {list}",
|
|
29
|
-
"completed": "Task {task} completed",
|
|
30
|
-
"branch_created": "Created branch: {branch}"
|
|
31
|
-
},
|
|
32
|
-
"plan": {
|
|
33
|
-
"start": "Generating execution plan...",
|
|
34
|
-
"success": "Execution plan generated",
|
|
35
|
-
"assigned": "Assigned {assignee} to {task}"
|
|
36
|
-
},
|
|
37
|
-
"validate": {
|
|
38
|
-
"start": "Validating specs...",
|
|
39
|
-
"success": "Validation complete",
|
|
40
|
-
"failed": "Validation failed: {error}",
|
|
41
|
-
"pass_rate": "Pass Rate: {rate}%",
|
|
42
|
-
"total_checks": "Total Checks: {total}",
|
|
43
|
-
"errors": "Errors: {errors}",
|
|
44
|
-
"warnings": "Warnings: {warnings}"
|
|
45
|
-
},
|
|
46
|
-
"progress": {
|
|
47
|
-
"start": "Loading progress...",
|
|
48
|
-
"success": "Progress loaded",
|
|
49
|
-
"report": "Progress Report: {iteration}",
|
|
50
|
-
"total": "Total: {total} | Completed: {done} | In Progress: {wip} | Pending: {pending} | Archived: {archived}",
|
|
51
|
-
"completion_rate": "Completion Rate: {rate}%",
|
|
52
|
-
"no_tasks": "No tasks found"
|
|
53
|
-
},
|
|
54
|
-
"health": {
|
|
55
|
-
"start": "Generating health report...",
|
|
56
|
-
"success": "Health report generated",
|
|
57
|
-
"overall": "Overall Health: {score}%",
|
|
58
|
-
"dimensions": "Dimensions:"
|
|
59
|
-
},
|
|
60
|
-
"archive": {
|
|
61
|
-
"start": "Archiving tasks",
|
|
62
|
-
"success": "Task archived: {task}",
|
|
63
|
-
"all_success": "{count} tasks archived",
|
|
64
|
-
"list": "Archived tasks listed",
|
|
65
|
-
"restore": "Task restored: {task}",
|
|
66
|
-
"not_found": "Task not found: {task}"
|
|
67
|
-
},
|
|
68
|
-
"delete": {
|
|
69
|
-
"moved": "Moved to: {path}",
|
|
70
|
-
"success": "Task \"{task}\" deleted and all references cleaned.",
|
|
71
|
-
"recover_hint": "To recover: mv the directory back from .speccore/trash/",
|
|
72
|
-
"not_found": "Task \"{task}\" not found in any iteration."
|
|
73
|
-
},
|
|
74
|
-
"search": {
|
|
75
|
-
"result": "Search: \"{query}\" — {count} matches",
|
|
76
|
-
"no_match": "No matches found."
|
|
77
|
-
},
|
|
78
|
-
"sync": {
|
|
79
|
-
"start": "Syncing specs...",
|
|
80
|
-
"success": "Spec sync complete",
|
|
81
|
-
"reverse_scan": "Reverse sync: scanning code for @spec annotations...",
|
|
82
|
-
"reverse_no_refs": "No @spec references found in code",
|
|
83
|
-
"reverse_complete": "Reverse sync complete: {count} tasks updated"
|
|
84
|
-
},
|
|
85
|
-
"change": {
|
|
86
|
-
"success": "Change recorded",
|
|
87
|
-
"require_task": "Please specify a task. Usage: speccore change --task=<id> --desc=\"<description>\""
|
|
88
|
-
},
|
|
89
|
-
"backup": {
|
|
90
|
-
"created": "Backup created: {path}",
|
|
91
|
-
"list": "Backup list",
|
|
92
|
-
"restore": "Backup restored: {name}"
|
|
93
|
-
},
|
|
94
|
-
"status": {
|
|
95
|
-
"success": "Status loaded",
|
|
96
|
-
"report": "Status Report: {iteration}"
|
|
97
|
-
},
|
|
98
|
-
"report": {
|
|
99
|
-
"success": "Report generated: {path}"
|
|
100
|
-
},
|
|
101
|
-
"hooks": {
|
|
102
|
-
"installed": "Git hooks installed: pre-commit + pre-push",
|
|
103
|
-
"not_git": "Not a Git repository"
|
|
104
|
-
},
|
|
105
|
-
"current": {
|
|
106
|
-
"no_task": "No task associated with current branch.",
|
|
107
|
-
"hint": "Use \"speccore execute --task=Task-XXX\" to create an associated branch."
|
|
108
|
-
},
|
|
109
|
-
"migrate": {
|
|
110
|
-
"success": "Migration complete",
|
|
111
|
-
"dry_run": "Dry run — no changes applied",
|
|
112
|
-
"file_changes": "{count} file changes pending. Remove --dry-run to apply."
|
|
113
|
-
},
|
|
114
|
-
"iteration": {
|
|
115
|
-
"created": "Iteration created: {name}",
|
|
116
|
-
"exists": "Iteration already exists: {name}"
|
|
117
|
-
},
|
|
118
|
-
"task": {
|
|
119
|
-
"created": "Task created successfully",
|
|
120
|
-
"task_created": "Task {id} created: {name}",
|
|
121
|
-
"exists": "Task already exists: {id}"
|
|
122
|
-
},
|
|
123
|
-
"handover": {
|
|
124
|
-
"generated": "Handover doc generated: {path}"
|
|
125
|
-
},
|
|
126
|
-
"retro": {
|
|
127
|
-
"generated": "Retrospective generated: {path}"
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
"common": {
|
|
131
|
-
"next_steps": "Next steps:",
|
|
132
|
-
"error": "Error: {msg}",
|
|
133
|
-
"warning": "Warning: {msg}",
|
|
134
|
-
"no_iteration": "No active iteration found. Use --iteration=<name> to specify.",
|
|
135
|
-
"usage": "Usage: {cmd}",
|
|
136
|
-
"loading": "Loading...",
|
|
137
|
-
"done": "Done"
|
|
138
|
-
},
|
|
139
|
-
"task": {
|
|
140
|
-
"status": {
|
|
141
|
-
"pending": "Pending",
|
|
142
|
-
"in_progress": "In Progress",
|
|
143
|
-
"completed": "Completed",
|
|
144
|
-
"blocked": "Blocked",
|
|
145
|
-
"archived": "Archived"
|
|
146
|
-
},
|
|
147
|
-
"type": {
|
|
148
|
-
"feature": "Feature",
|
|
149
|
-
"bugfix": "Bug Fix",
|
|
150
|
-
"research": "Research"
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|