@kunlv/atdc 1.0.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.md +58 -0
- package/GO.md +245 -0
- package/bin/add-command.py +144 -0
- package/bin/atdc.js +460 -0
- package/bin/cls.js +98 -0
- package/central/link.sh +60 -0
- package/central/ticket_center_server/.handoffs/TASK-238389_QYinVipLimit.md +128 -0
- package/central/ticket_center_server/.test_plans/TASK-227254-SupportMembership-self-test-plan.md +566 -0
- package/central/ticket_center_server/.test_plans/task-238389-qyin-vip-limit-self-test-plan.md +210 -0
- package/commands/claude/atd.md +3 -0
- package/commands/claude/atdc/1-spec.md +5 -0
- package/commands/claude/atdc/1-update.md +5 -0
- package/commands/claude/atdc/2-qa.md +3 -0
- package/commands/claude/atdc/3-impl-skip-spec.md +5 -0
- package/commands/claude/atdc/3-impl.md +3 -0
- package/commands/claude/atdc/4-verify.md +3 -0
- package/commands/claude/atdc/5-done.md +3 -0
- package/commands/claude/atdc/add-command.md +4 -0
- package/commands/claude/atdc/add-to-hc.md +3 -0
- package/commands/claude/atdc/analysis-cls-log.md +4 -0
- package/commands/claude/atdc/article.md +6 -0
- package/commands/claude/atdc/bugfix.md +4 -0
- package/commands/claude/atdc/code-simplifier.md +8 -0
- package/commands/claude/atdc/commit.md +4 -0
- package/commands/claude/atdc/compound.md +5 -0
- package/commands/claude/atdc/context.md +3 -0
- package/commands/claude/atdc/diagnose.md +8 -0
- package/commands/claude/atdc/git-guardrails.md +18 -0
- package/commands/claude/atdc/grill-with-docs.md +8 -0
- package/commands/claude/atdc/handoff.md +8 -0
- package/commands/claude/atdc/health.md +3 -0
- package/commands/claude/atdc/learn.md +4 -0
- package/commands/claude/atdc/review.md +10 -0
- package/commands/claude/atdc/search.md +4 -0
- package/commands/claude/atdc/strategy.md +3 -0
- package/commands/claude/atdc/table2xlsx.md +4 -0
- package/commands/claude/atdc/test-plan.md +5 -0
- package/commands/claude/atdc/travel-planner.md +4 -0
- package/commands/claude/atdc/xlsx2sql-insert.md +4 -0
- package/commands/claude/atdc/xlsx2sql-update.md +4 -0
- package/commands/claude/atdc/zoom-out.md +8 -0
- package/commands/codex/atdc/SKILL.md +8 -0
- package/commands/codex/atdc-1-spec/SKILL.md +8 -0
- package/commands/codex/atdc-1-update/SKILL.md +8 -0
- package/commands/codex/atdc-2-qa/SKILL.md +8 -0
- package/commands/codex/atdc-3-impl/SKILL.md +8 -0
- package/commands/codex/atdc-3-impl-skip-spec/SKILL.md +8 -0
- package/commands/codex/atdc-4-verify/SKILL.md +8 -0
- package/commands/codex/atdc-5-done/SKILL.md +8 -0
- package/commands/codex/atdc-add-command/SKILL.md +7 -0
- package/commands/codex/atdc-add-to-hc/SKILL.md +8 -0
- package/commands/codex/atdc-analysis-cls-log/SKILL.md +5 -0
- package/commands/codex/atdc-article/SKILL.md +8 -0
- package/commands/codex/atdc-bugfix/SKILL.md +5 -0
- package/commands/codex/atdc-code-simplifier/SKILL.md +7 -0
- package/commands/codex/atdc-commit/SKILL.md +7 -0
- package/commands/codex/atdc-compound/SKILL.md +8 -0
- package/commands/codex/atdc-context/SKILL.md +8 -0
- package/commands/codex/atdc-diagnose/SKILL.md +9 -0
- package/commands/codex/atdc-git-guardrails/SKILL.md +19 -0
- package/commands/codex/atdc-grill-with-docs/SKILL.md +9 -0
- package/commands/codex/atdc-handoff/SKILL.md +9 -0
- package/commands/codex/atdc-health/SKILL.md +8 -0
- package/commands/codex/atdc-learn/SKILL.md +7 -0
- package/commands/codex/atdc-review/SKILL.md +49 -0
- package/commands/codex/atdc-search/SKILL.md +5 -0
- package/commands/codex/atdc-strategy/SKILL.md +8 -0
- package/commands/codex/atdc-table2xlsx/SKILL.md +8 -0
- package/commands/codex/atdc-test-plan/SKILL.md +13 -0
- package/commands/codex/atdc-travel-planner/SKILL.md +7 -0
- package/commands/codex/atdc-xlsx2sql-insert/SKILL.md +8 -0
- package/commands/codex/atdc-xlsx2sql-update/SKILL.md +8 -0
- package/commands/codex/atdc-zoom-out/SKILL.md +9 -0
- package/commands/cursor/atdc/SKILL.md +8 -0
- package/commands/cursor/atdc-1-spec/SKILL.md +8 -0
- package/commands/cursor/atdc-1-update/SKILL.md +8 -0
- package/commands/cursor/atdc-2-qa/SKILL.md +8 -0
- package/commands/cursor/atdc-3-impl/SKILL.md +8 -0
- package/commands/cursor/atdc-3-impl-skip-spec/SKILL.md +8 -0
- package/commands/cursor/atdc-4-verify/SKILL.md +8 -0
- package/commands/cursor/atdc-5-done/SKILL.md +8 -0
- package/commands/cursor/atdc-add-command/SKILL.md +7 -0
- package/commands/cursor/atdc-add-to-hc/SKILL.md +8 -0
- package/commands/cursor/atdc-analysis-cls-log/SKILL.md +5 -0
- package/commands/cursor/atdc-article/SKILL.md +8 -0
- package/commands/cursor/atdc-bugfix/SKILL.md +5 -0
- package/commands/cursor/atdc-code-simplifier/SKILL.md +7 -0
- package/commands/cursor/atdc-commit/SKILL.md +7 -0
- package/commands/cursor/atdc-compound/SKILL.md +8 -0
- package/commands/cursor/atdc-context/SKILL.md +8 -0
- package/commands/cursor/atdc-diagnose/SKILL.md +8 -0
- package/commands/cursor/atdc-git-guardrails/SKILL.md +18 -0
- package/commands/cursor/atdc-grill-with-docs/SKILL.md +8 -0
- package/commands/cursor/atdc-handoff/SKILL.md +8 -0
- package/commands/cursor/atdc-health/SKILL.md +8 -0
- package/commands/cursor/atdc-learn/SKILL.md +7 -0
- package/commands/cursor/atdc-review/SKILL.md +49 -0
- package/commands/cursor/atdc-search/SKILL.md +5 -0
- package/commands/cursor/atdc-strategy/SKILL.md +8 -0
- package/commands/cursor/atdc-table2xlsx/SKILL.md +8 -0
- package/commands/cursor/atdc-test-plan/SKILL.md +7 -0
- package/commands/cursor/atdc-travel-planner/SKILL.md +7 -0
- package/commands/cursor/atdc-xlsx2sql-insert/SKILL.md +8 -0
- package/commands/cursor/atdc-xlsx2sql-update/SKILL.md +8 -0
- package/commands/cursor/atdc-zoom-out/SKILL.md +8 -0
- package/commands/opencode/atd.md +6 -0
- package/commands/opencode/atdc/1-spec.md +8 -0
- package/commands/opencode/atdc/1-update.md +8 -0
- package/commands/opencode/atdc/2-qa.md +6 -0
- package/commands/opencode/atdc/3-impl-skip-spec.md +8 -0
- package/commands/opencode/atdc/3-impl.md +6 -0
- package/commands/opencode/atdc/4-verify.md +6 -0
- package/commands/opencode/atdc/5-done.md +6 -0
- package/commands/opencode/atdc/add-command.md +6 -0
- package/commands/opencode/atdc/add-to-hc.md +6 -0
- package/commands/opencode/atdc/analysis-cls-log.md +6 -0
- package/commands/opencode/atdc/article.md +6 -0
- package/commands/opencode/atdc/bugfix.md +6 -0
- package/commands/opencode/atdc/code-simplifier.md +8 -0
- package/commands/opencode/atdc/commit.md +6 -0
- package/commands/opencode/atdc/compound.md +8 -0
- package/commands/opencode/atdc/context.md +6 -0
- package/commands/opencode/atdc/diagnose.md +8 -0
- package/commands/opencode/atdc/git-guardrails.md +18 -0
- package/commands/opencode/atdc/grill-with-docs.md +8 -0
- package/commands/opencode/atdc/handoff.md +8 -0
- package/commands/opencode/atdc/health.md +6 -0
- package/commands/opencode/atdc/learn.md +6 -0
- package/commands/opencode/atdc/review.md +7 -0
- package/commands/opencode/atdc/search.md +6 -0
- package/commands/opencode/atdc/strategy.md +6 -0
- package/commands/opencode/atdc/table2xlsx.md +6 -0
- package/commands/opencode/atdc/test-plan.md +6 -0
- package/commands/opencode/atdc/travel-planner.md +6 -0
- package/commands/opencode/atdc/xlsx2sql-insert.md +6 -0
- package/commands/opencode/atdc/xlsx2sql-update.md +6 -0
- package/commands/opencode/atdc/zoom-out.md +8 -0
- package/config/cls-defaults.json +19 -0
- package/hooks/atd-archive.sh +86 -0
- package/hooks/atd-state.sh +165 -0
- package/hooks/evidence-hook.sh +88 -0
- package/hooks/evidence-log.sh +54 -0
- package/hooks/guardrails.sh +65 -0
- package/hooks/handoff-compress.sh +104 -0
- package/hooks/phase-guard.sh +134 -0
- package/hooks/phase-write-guard.sh +96 -0
- package/hooks/ponytail-fix.sh +179 -0
- package/hooks/ponytail-guard.sh +66 -0
- package/hooks/ponytail-scan.sh +62 -0
- package/install.sh +276 -0
- package/package.json +20 -0
- package/packages/cls/bin/cls.js +146 -0
- package/packages/cls/config/defaults.json +17 -0
- package/packages/cls/mcp/server.js +142 -0
- package/packages/cls/package.json +29 -0
- package/packages/cls/scripts/postinstall.js +19 -0
- package/packages/cls/src/client.js +262 -0
- package/prompts/1-spec.md +271 -0
- package/prompts/1-update.md +198 -0
- package/prompts/2-qa.md +164 -0
- package/prompts/3-impl-bugfix.md +271 -0
- package/prompts/3-impl.md +419 -0
- package/prompts/4-verify.md +160 -0
- package/prompts/5-done.md +227 -0
- package/prompts/6-article.md +571 -0
- package/prompts/X-add-command.md +60 -0
- package/prompts/X-add-to-hc.md +178 -0
- package/prompts/X-analysis-cls-log.md +68 -0
- package/prompts/X-bugfix.md +10 -0
- package/prompts/X-code-simplifier.md +38 -0
- package/prompts/X-commit.md +116 -0
- package/prompts/X-compound.md +188 -0
- package/prompts/X-context-scan.md +101 -0
- package/prompts/X-diagnose.md +116 -0
- package/prompts/X-grill-with-docs.md +120 -0
- package/prompts/X-handoff.md +80 -0
- package/prompts/X-health.md +78 -0
- package/prompts/X-learn.md +151 -0
- package/prompts/X-review.md +417 -0
- package/prompts/X-search.md +74 -0
- package/prompts/X-strategy.md +95 -0
- package/prompts/X-table2xlsx.md +46 -0
- package/prompts/X-test-plan.md +436 -0
- package/prompts/X-travel-planner.md +22 -0
- package/prompts/X-xlsx2sql-insert.md +34 -0
- package/prompts/X-xlsx2sql-update.md +40 -0
- package/prompts/X-zoom-out.md +119 -0
- package/reference/diagnose-loop.md +66 -0
- package/reference/gates.md +90 -0
- package/reference/git-guardrails.md +71 -0
- package/reference/guards.md +275 -0
- package/reference/learn.md +100 -0
- package/reference/memory.md +190 -0
- package/reference/risk.md +74 -0
- package/reference/tdd.md +40 -0
- package/scripts/svg2png.js +46 -0
- package/src/cls/client.js +244 -0
- package/src/constants.js +49 -0
- package/src/evidence/ai-draft-metrics.js +157 -0
- package/src/evidence/canvas.js +184 -0
- package/src/evidence/index.js +98 -0
- package/src/evidence/sink-events.js +165 -0
- package/src/evidence/stage-timing.js +112 -0
- package/src/installers/claude.js +79 -0
- package/src/installers/codex.js +62 -0
- package/src/installers/opencode.js +72 -0
- package/src/manifest/ponytail-patterns.json +185 -0
- package/src/mcp/cls-mcp-server.js +142 -0
- package/src/utils.js +79 -0
- package/src/validators/state-validate.js +123 -0
- package/templates/.phase-state.json +13 -0
- package/templates/adr.md +62 -0
- package/templates/changelog.md +21 -0
- package/templates/concepts.md +35 -0
- package/templates/design.md +47 -0
- package/templates/handoff.md +64 -0
- package/templates/learn-skill.md +43 -0
- package/templates/progress.json +17 -0
- package/templates/proposal.md +29 -0
- package/templates/solution.md +36 -0
- package/templates/strategy.md +39 -0
- package/templates/tasks.md +41 -0
package/src/utils.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { PACKAGE_DIR, PLACEHOLDER } = require('./constants');
|
|
4
|
+
|
|
5
|
+
function exists(p) {
|
|
6
|
+
try { fs.accessSync(p); return true; } catch { return false; }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function isSymlink(p) {
|
|
10
|
+
try { return fs.lstatSync(p).isSymbolicLink(); } catch { return false; }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getSymlinkTarget(p) {
|
|
14
|
+
try { return fs.readlinkSync(p); } catch { return null; }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function mkdirp(dir) {
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createSymlink(target, linkPath) {
|
|
22
|
+
const linkDir = path.dirname(linkPath);
|
|
23
|
+
mkdirp(linkDir);
|
|
24
|
+
if (exists(linkPath) || isSymlink(linkPath)) {
|
|
25
|
+
fs.rmSync(linkPath, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
const stat = fs.statSync(target);
|
|
28
|
+
const type = stat.isDirectory() ? 'dir' : 'file';
|
|
29
|
+
fs.symlinkSync(target, linkPath, type);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function removeSymlink(linkPath) {
|
|
33
|
+
if (isSymlink(linkPath)) {
|
|
34
|
+
fs.unlinkSync(linkPath);
|
|
35
|
+
} else if (exists(linkPath)) {
|
|
36
|
+
fs.rmSync(linkPath, { recursive: true, force: true });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function replaceInFile(filePath, search, replacement) {
|
|
41
|
+
if (!exists(filePath)) return false;
|
|
42
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
43
|
+
if (content.includes(replacement)) return false;
|
|
44
|
+
if (!content.includes(search)) return false;
|
|
45
|
+
content = content.split(search).join(replacement);
|
|
46
|
+
fs.writeFileSync(filePath, content);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function replaceAllInDir(dir, search, replacement) {
|
|
51
|
+
if (!exists(dir)) return 0;
|
|
52
|
+
let count = 0;
|
|
53
|
+
const walk = (d) => {
|
|
54
|
+
for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
|
|
55
|
+
const fp = path.join(d, entry.name);
|
|
56
|
+
if (entry.isDirectory()) { walk(fp); }
|
|
57
|
+
else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
58
|
+
if (replaceInFile(fp, search, replacement)) count++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
walk(dir);
|
|
63
|
+
return count;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function resolvePackageDir() {
|
|
67
|
+
return PACKAGE_DIR;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isTerminalInstalled(checkDirs) {
|
|
71
|
+
return checkDirs.some(exists);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
exists, isSymlink, getSymlinkTarget, mkdirp,
|
|
76
|
+
createSymlink, removeSymlink,
|
|
77
|
+
replaceInFile, replaceAllInDir,
|
|
78
|
+
resolvePackageDir, isTerminalInstalled,
|
|
79
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// state-validate.js — validates .phase-state.json schema integrity
|
|
5
|
+
// Usage: node state-validate.js [--file=<path>]
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const REQUIRED_FIELDS = ['change', 'phase', 'mode', 'tasks', 'verifiedAt', 'archived'];
|
|
11
|
+
const VALID_PHASES = ['open', 'design', 'build', 'verify', 'archive'];
|
|
12
|
+
const VALID_MODES = ['full', 'hotfix', 'tweak'];
|
|
13
|
+
const KNOWN_FIELDS = [
|
|
14
|
+
...REQUIRED_FIELDS, 'verificationReport', 'branchStatus',
|
|
15
|
+
'startedAt', 'updatedAt'
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function findStateFile() {
|
|
19
|
+
const arg = process.argv.find(a => a.startsWith('--file='));
|
|
20
|
+
if (arg) return arg.slice(7);
|
|
21
|
+
|
|
22
|
+
// Auto-detect: find first active change with .phase-state.json
|
|
23
|
+
const changesDir = 'openspec/changes';
|
|
24
|
+
if (!fs.existsSync(changesDir)) return null;
|
|
25
|
+
const entries = fs.readdirSync(changesDir).filter(e => {
|
|
26
|
+
if (e === 'archive') return false;
|
|
27
|
+
const stat = fs.statSync(path.join(changesDir, e));
|
|
28
|
+
if (!stat.isDirectory()) return false;
|
|
29
|
+
return fs.existsSync(path.join(changesDir, e, '.phase-state.json'));
|
|
30
|
+
});
|
|
31
|
+
if (entries.length === 0) return null;
|
|
32
|
+
return path.join(changesDir, entries[0], '.phase-state.json');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function main() {
|
|
36
|
+
const filePath = findStateFile();
|
|
37
|
+
if (!filePath) {
|
|
38
|
+
console.log('No .phase-state.json found. Use --file= to specify path.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let data;
|
|
43
|
+
try {
|
|
44
|
+
data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.log(`FAIL: invalid JSON in ${filePath}`);
|
|
47
|
+
console.log(` ${e.message}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(`Validating: ${filePath}`);
|
|
52
|
+
const errors = [];
|
|
53
|
+
const warnings = [];
|
|
54
|
+
|
|
55
|
+
// Check required fields
|
|
56
|
+
for (const field of REQUIRED_FIELDS) {
|
|
57
|
+
if (!(field in data)) {
|
|
58
|
+
errors.push(`missing required field: ${field}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Check phase value
|
|
63
|
+
if (data.phase && !VALID_PHASES.includes(data.phase)) {
|
|
64
|
+
errors.push(`invalid phase "${data.phase}" (valid: ${VALID_PHASES.join(', ')})`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check mode value
|
|
68
|
+
if (data.mode && !VALID_MODES.includes(data.mode)) {
|
|
69
|
+
errors.push(`invalid mode "${data.mode}" (valid: ${VALID_MODES.join(', ')})`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check tasks structure
|
|
73
|
+
if (data.tasks && typeof data.tasks !== 'object') {
|
|
74
|
+
errors.push('tasks must be an object with {total, completed}');
|
|
75
|
+
} else if (data.tasks) {
|
|
76
|
+
if (typeof data.tasks.total !== 'number') errors.push('tasks.total must be a number');
|
|
77
|
+
if (typeof data.tasks.completed !== 'number') errors.push('tasks.completed must be a number');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Check types
|
|
81
|
+
if (data.phase !== undefined && typeof data.phase !== 'string') {
|
|
82
|
+
errors.push('phase must be a string');
|
|
83
|
+
}
|
|
84
|
+
if (data.mode !== undefined && typeof data.mode !== 'string') {
|
|
85
|
+
errors.push('mode must be a string');
|
|
86
|
+
}
|
|
87
|
+
if (data.archived !== undefined && typeof data.archived !== 'boolean') {
|
|
88
|
+
errors.push('archived must be a boolean');
|
|
89
|
+
}
|
|
90
|
+
if (data.verifiedAt !== undefined && data.verifiedAt !== null && typeof data.verifiedAt !== 'string') {
|
|
91
|
+
errors.push('verifiedAt must be a string or null');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Check unknown fields (warnings only)
|
|
95
|
+
for (const key of Object.keys(data)) {
|
|
96
|
+
if (!KNOWN_FIELDS.includes(key)) {
|
|
97
|
+
warnings.push(`unknown field: ${key}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Report
|
|
102
|
+
if (errors.length > 0) {
|
|
103
|
+
console.log(`\nERRORS (${errors.length}):`);
|
|
104
|
+
errors.forEach(e => console.log(` ✗ ${e}`));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (warnings.length > 0) {
|
|
108
|
+
console.log(`\nWARNINGS (${warnings.length}):`);
|
|
109
|
+
warnings.forEach(w => console.log(` ⚠ ${w}`));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (errors.length === 0) {
|
|
113
|
+
if (warnings.length === 0) {
|
|
114
|
+
console.log('✓ schema valid');
|
|
115
|
+
} else {
|
|
116
|
+
console.log('✓ schema valid (with warnings)');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
process.exit(errors.length > 0 ? 1 : 0);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": ".atd-code/phase-state.schema.json",
|
|
3
|
+
"change": "",
|
|
4
|
+
"phase": "open",
|
|
5
|
+
"mode": "full",
|
|
6
|
+
"tasks": { "total": 0, "completed": 0 },
|
|
7
|
+
"verifiedAt": null,
|
|
8
|
+
"archived": false,
|
|
9
|
+
"verificationReport": null,
|
|
10
|
+
"branchStatus": "pending",
|
|
11
|
+
"startedAt": "",
|
|
12
|
+
"updatedAt": ""
|
|
13
|
+
}
|
package/templates/adr.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# ADR-<序号>: <标题>
|
|
2
|
+
|
|
3
|
+
> 状态:提议 / 已采纳 / 已废弃 / 已取代
|
|
4
|
+
> 日期:<YYYY-MM-DD>
|
|
5
|
+
> 决策者:<@user 或 AI + user 确认>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 背景
|
|
10
|
+
|
|
11
|
+
<为什么需要做这个决策?遇到了什么问题?有什么约束?>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 决策
|
|
16
|
+
|
|
17
|
+
<我们决定做什么?一句话。>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 考虑的方案
|
|
22
|
+
|
|
23
|
+
### 方案 A:<名称>(✅ 选定)
|
|
24
|
+
|
|
25
|
+
- 优点:
|
|
26
|
+
- 缺点:
|
|
27
|
+
- 风险:
|
|
28
|
+
|
|
29
|
+
### 方案 B:<名称>
|
|
30
|
+
|
|
31
|
+
- 优点:
|
|
32
|
+
- 缺点:
|
|
33
|
+
- 风险:
|
|
34
|
+
- 为什么没选:
|
|
35
|
+
|
|
36
|
+
### 方案 C:<名称>(如有)
|
|
37
|
+
|
|
38
|
+
- 优点:
|
|
39
|
+
- 缺点:
|
|
40
|
+
- 风险:
|
|
41
|
+
- 为什么没选:
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 后果
|
|
46
|
+
|
|
47
|
+
### 正面影响
|
|
48
|
+
|
|
49
|
+
- <决策带来的好处>
|
|
50
|
+
|
|
51
|
+
### 负面影响 / 需要关注的
|
|
52
|
+
|
|
53
|
+
- <决策带来的代价、限制、技术债>
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 相关
|
|
58
|
+
|
|
59
|
+
- 被以下 ADR 取代:<ADR-xxx>(如有)
|
|
60
|
+
- 取代以下 ADR:<ADR-xxx>(如有)
|
|
61
|
+
- 相关模块:<模块名>
|
|
62
|
+
- 相关 Change:<change-name>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# changelog: <change-name>
|
|
2
|
+
|
|
3
|
+
需求变更记录。每次变更由 `/atd:1-update` 自动追加,按时间倒序排列。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [YYYY-MM-DD] <变更标题>
|
|
8
|
+
|
|
9
|
+
**类型**:新增 / 修改 / 删除
|
|
10
|
+
**原因**:<变更原因>
|
|
11
|
+
**内容**:<变更描述>
|
|
12
|
+
|
|
13
|
+
**影响文件**:
|
|
14
|
+
- `proposal.md`:<具体变更>
|
|
15
|
+
- `design.md`:<具体变更>
|
|
16
|
+
- `specs/<模块>/spec.md`:<具体变更>
|
|
17
|
+
- `tasks.md`:<具体变更(新增/删除/修改)>
|
|
18
|
+
|
|
19
|
+
**Verification Checklist 变更**:
|
|
20
|
+
- 新增:<条目>
|
|
21
|
+
- 删除:<条目>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Concepts — <项目名>
|
|
2
|
+
|
|
3
|
+
> 项目共享领域词汇表。新成员/新 session 快速理解业务语言。
|
|
4
|
+
> 由 `/atd compound` 和 `/atd context` 自动维护,也可手动编辑。
|
|
5
|
+
|
|
6
|
+
## 核心实体
|
|
7
|
+
|
|
8
|
+
| 术语 | 英文/代码名 | 含义 | 关联文件 |
|
|
9
|
+
|------|------------|------|---------|
|
|
10
|
+
| <术语> | <代码中的命名> | <业务含义> | <相关文件路径> |
|
|
11
|
+
|
|
12
|
+
## 命名流程
|
|
13
|
+
|
|
14
|
+
| 流程名 | 触发条件 | 核心步骤 | 入口函数/API |
|
|
15
|
+
|--------|---------|---------|-------------|
|
|
16
|
+
| <流程名> | <什么情况下触发> | <1-3 步概述> | <函数名或路由> |
|
|
17
|
+
|
|
18
|
+
## 状态机
|
|
19
|
+
|
|
20
|
+
| 实体 | 状态 | 含义 | 可流转到 |
|
|
21
|
+
|------|------|------|---------|
|
|
22
|
+
| <实体名> | <状态值> | <业务含义> | <下一状态列表> |
|
|
23
|
+
|
|
24
|
+
## 约定与缩写
|
|
25
|
+
|
|
26
|
+
| 缩写/术语 | 全称 | 说明 |
|
|
27
|
+
|-----------|------|------|
|
|
28
|
+
| <缩写> | <全称> | <什么时候用> |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
> **维护规则**:
|
|
33
|
+
> - 每个术语一行,不超过 3 列(术语、含义、关联)。
|
|
34
|
+
> - 只记录非显而易见的业务概念,不记录通用技术术语(如 "HTTP"、"JSON")。
|
|
35
|
+
> - 新增概念时同步更新此文件,可通过 `/atd compound` 自动提取。
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# design: <change-name>
|
|
2
|
+
|
|
3
|
+
## 模块划分
|
|
4
|
+
|
|
5
|
+
| 模块 | 职责 | 涉及文件 |
|
|
6
|
+
|------|------|---------|
|
|
7
|
+
| <模块名> | <一句话> | `<文件路径>` |
|
|
8
|
+
|
|
9
|
+
## 关键接口定义
|
|
10
|
+
|
|
11
|
+
### <接口名>
|
|
12
|
+
|
|
13
|
+
```go
|
|
14
|
+
// <函数签名>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- **输入**:<参数说明>
|
|
18
|
+
- **输出**:<返回值说明>
|
|
19
|
+
- **错误处理**:<错误类型及触发条件>
|
|
20
|
+
|
|
21
|
+
### API 路由(如有)
|
|
22
|
+
|
|
23
|
+
| 方法 | 路径 | 说明 | 请求/响应 |
|
|
24
|
+
|------|------|------|----------|
|
|
25
|
+
| POST | `/api/v1/xxx` | <说明> | 见 specs |
|
|
26
|
+
|
|
27
|
+
## 数据流
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
<调用方> → <函数A> → <函数B> → <存储/外部依赖>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
<补充说明:缓存策略、事务边界、并发控制等>
|
|
34
|
+
|
|
35
|
+
## 关键决策与 ADR
|
|
36
|
+
|
|
37
|
+
| 决策 | 选项 | 选定 | 理由 |
|
|
38
|
+
|------|------|------|------|
|
|
39
|
+
| <决策点> | A / B / C | <B> | <理由> |
|
|
40
|
+
|
|
41
|
+
## 外部依赖
|
|
42
|
+
|
|
43
|
+
- <依赖名称>:<用途>,<是否已存在>
|
|
44
|
+
|
|
45
|
+
## 风险点
|
|
46
|
+
|
|
47
|
+
- <风险描述>:<缓解措施>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# <change-name> 交接文档
|
|
2
|
+
|
|
3
|
+
> 生成时间:<YYYY-MM-DD HH:MM>
|
|
4
|
+
> 生成方式:/atd:handoff
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 做了什么
|
|
9
|
+
|
|
10
|
+
**动机**:<为什么做这个 change,一句话>
|
|
11
|
+
|
|
12
|
+
**结果**:<达成了什么,一句话>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 关键决策
|
|
17
|
+
|
|
18
|
+
| # | 决策 | 选了 | 排除了 | 原因 |
|
|
19
|
+
|---|------|------|--------|------|
|
|
20
|
+
| 1 | <决策主题> | <选定方案> | <排除方案> | <一句话原因> |
|
|
21
|
+
| 2 | ... | ... | ... | ... |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 受影响模块
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
<模块A>/
|
|
29
|
+
├── <文件1> — <改动简述>
|
|
30
|
+
├── <文件2> — <改动简述>
|
|
31
|
+
<模块B>/
|
|
32
|
+
└── <文件3> — <改动简述>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 测试状态
|
|
38
|
+
|
|
39
|
+
| 覆盖范围 | 状态 | 说明 |
|
|
40
|
+
|---------|------|------|
|
|
41
|
+
| 单元测试 | ✅ / ⚠️ / ❌ | <补充说明> |
|
|
42
|
+
| 集成测试 | ✅ / ⚠️ / ❌ | <补充说明> |
|
|
43
|
+
| 回归测试 | ✅ / ⚠️ / ❌ | <补充说明> |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 未解决问题
|
|
48
|
+
|
|
49
|
+
- <问题1>:<当前状态,为什么没解决>
|
|
50
|
+
- <问题2>:<当前状态,为什么没解决>
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 下一步
|
|
55
|
+
|
|
56
|
+
<接手的人应该从哪里开始,做什么>
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 相关资源
|
|
61
|
+
|
|
62
|
+
- ADR:`docs/adr/<序号>-<标题>.md`
|
|
63
|
+
- Issue:<链接>
|
|
64
|
+
- 监控面板:<链接>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# prompts/X-<name> · <short_desc>
|
|
2
|
+
|
|
3
|
+
横向命令,任意时刻可触发:`/atd:<name> <args>`
|
|
4
|
+
|
|
5
|
+
> 🧠 Auto-harvested by self-learning from session `<YYYY-MM-DD>`
|
|
6
|
+
> 关联 change: `<change-name 或 "独立发现">`
|
|
7
|
+
> 关联 error: `.errors-log.md` 条目 `<YYYY-MM-DD>`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 失败模式
|
|
12
|
+
|
|
13
|
+
**这个 skill 避免的诊断**:`<named failure pattern>`
|
|
14
|
+
- 症状:`<现象>`
|
|
15
|
+
- 如果不走这个路径会怎样:`<后果>`
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 执行步骤
|
|
20
|
+
|
|
21
|
+
### 1. 确定输入
|
|
22
|
+
|
|
23
|
+
### 2. 执行
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## What didn't work
|
|
28
|
+
|
|
29
|
+
| 尝试 | 排除原因 |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| `<方案 A>` | `<为什么不 work>` |
|
|
32
|
+
| `<方案 B>` | `<为什么不 work>` |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 验证方式
|
|
37
|
+
|
|
38
|
+
`<passing check — 什么命令/测试验证了这个路径>`
|
|
39
|
+
|
|
40
|
+
验证输出:
|
|
41
|
+
```
|
|
42
|
+
<paste 关键输出行>
|
|
43
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"change": "",
|
|
3
|
+
"mode": "direct",
|
|
4
|
+
"currentStep": "gate-check",
|
|
5
|
+
"completedTasks": [],
|
|
6
|
+
"failedAt": null,
|
|
7
|
+
"failedReason": null,
|
|
8
|
+
"startedAt": "",
|
|
9
|
+
"updatedAt": "",
|
|
10
|
+
"traceability": [],
|
|
11
|
+
"gateResults": {
|
|
12
|
+
"gate1": null,
|
|
13
|
+
"gate2": null,
|
|
14
|
+
"gate3": null,
|
|
15
|
+
"gate4": null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# change: <name>
|
|
2
|
+
|
|
3
|
+
## 背景与目标
|
|
4
|
+
|
|
5
|
+
<对谁 / 做什么 / 达到什么效果,一句话>
|
|
6
|
+
|
|
7
|
+
## 技术方案
|
|
8
|
+
|
|
9
|
+
<选定方案名称及核心理由>
|
|
10
|
+
|
|
11
|
+
## 排除的方案
|
|
12
|
+
|
|
13
|
+
- <方案 A>:<排除原因>
|
|
14
|
+
- <方案 B>:<排除原因>
|
|
15
|
+
|
|
16
|
+
## 实施范围
|
|
17
|
+
|
|
18
|
+
涉及模块:
|
|
19
|
+
- `<模块路径>`:<职责说明>
|
|
20
|
+
|
|
21
|
+
涉及文件:
|
|
22
|
+
- `<文件路径>`
|
|
23
|
+
|
|
24
|
+
接口变更:
|
|
25
|
+
- <函数签名 / API 路由>
|
|
26
|
+
|
|
27
|
+
## 参考文档
|
|
28
|
+
|
|
29
|
+
- Brainstorming 设计文档:<路径或"无">
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "<问题标题>"
|
|
3
|
+
date: "<YYYY-MM-DD>"
|
|
4
|
+
change: "<关联的 change 名称,无则省略>"
|
|
5
|
+
branch: "<关联分支,无则省略>"
|
|
6
|
+
tags: ["<标签1>", "<标签2>"]
|
|
7
|
+
difficulty: "<easy|medium|hard>"
|
|
8
|
+
module: "<涉及模块/目录>"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# <问题标题>
|
|
12
|
+
|
|
13
|
+
## 问题
|
|
14
|
+
|
|
15
|
+
<遇到了什么问题?症状、报错、异常行为。>
|
|
16
|
+
|
|
17
|
+
## 根因
|
|
18
|
+
|
|
19
|
+
<问题根因是什么?排除的调查路径也可以简述。>
|
|
20
|
+
|
|
21
|
+
## 解决方案
|
|
22
|
+
|
|
23
|
+
<最终采用的方案,核心代码/配置变更。>
|
|
24
|
+
|
|
25
|
+
## 排除的方案
|
|
26
|
+
|
|
27
|
+
- <方案 A>:<排除原因>
|
|
28
|
+
- <方案 B>:<排除原因>
|
|
29
|
+
|
|
30
|
+
## 教训
|
|
31
|
+
|
|
32
|
+
<一句话总结,供未来参考。>
|
|
33
|
+
|
|
34
|
+
## 可检索关键词
|
|
35
|
+
|
|
36
|
+
<列出 3-5 个关键词,方便未来搜索匹配。例:redis timeout connection pool concurrent>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Strategy — <产品名>
|
|
2
|
+
|
|
3
|
+
> 上次更新:<日期>
|
|
4
|
+
|
|
5
|
+
## Target Problem
|
|
6
|
+
|
|
7
|
+
<这个产品解决什么问题?为谁解决?一句话。>
|
|
8
|
+
|
|
9
|
+
## Approach
|
|
10
|
+
|
|
11
|
+
<用什么方式解决?核心机制/差异化点是什么?>
|
|
12
|
+
|
|
13
|
+
## Persona
|
|
14
|
+
|
|
15
|
+
<目标用户画像:角色、场景、技术水平>
|
|
16
|
+
|
|
17
|
+
## Key Metrics
|
|
18
|
+
|
|
19
|
+
| 指标 | 当前值 | 目标 | 含义 |
|
|
20
|
+
|------|--------|------|------|
|
|
21
|
+
| <指标名> | <值> | <值> | <这个指标说明什么> |
|
|
22
|
+
|
|
23
|
+
## Tracks
|
|
24
|
+
|
|
25
|
+
> 当前正在推进的工作轨道(按优先级排列,每条 1-2 行)
|
|
26
|
+
|
|
27
|
+
1. **<轨道名>**:<做什么、达到什么状态>
|
|
28
|
+
2. **<轨道名>**:<做什么、达到什么状态>
|
|
29
|
+
|
|
30
|
+
## Out of Scope
|
|
31
|
+
|
|
32
|
+
<当前明确不做的事,避免 scope creep>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
> **维护规则**:
|
|
37
|
+
> - 策略是锚点,不是计划。Features 归 proposal,排期归 issue tracker。
|
|
38
|
+
> - 每条控制在 1-2 行。新增章节的成本比看起来高,谨慎扩展。
|
|
39
|
+
> - 可重复运行 `/atd strategy` 更新,只刷新 stale 部分。
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# tasks: <change-name>
|
|
2
|
+
|
|
3
|
+
## 任务清单
|
|
4
|
+
|
|
5
|
+
### 1. <任务标题>
|
|
6
|
+
|
|
7
|
+
**目标**: <完成后达到什么状态>
|
|
8
|
+
**Files**: [path/to/file1.go, path/to/file2.go]
|
|
9
|
+
**Dependencies**: none
|
|
10
|
+
**估时**: 10 分钟
|
|
11
|
+
|
|
12
|
+
实现步骤:
|
|
13
|
+
1.
|
|
14
|
+
2.
|
|
15
|
+
|
|
16
|
+
验证方式:
|
|
17
|
+
- [ ] `go test ./path/... -run TestXxx`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### 2. <任务标题>
|
|
22
|
+
|
|
23
|
+
**目标**:
|
|
24
|
+
**Files**: []
|
|
25
|
+
**Dependencies**: Task 1
|
|
26
|
+
**估时**: 15 分钟
|
|
27
|
+
|
|
28
|
+
实现步骤:
|
|
29
|
+
1.
|
|
30
|
+
|
|
31
|
+
验证方式:
|
|
32
|
+
- [ ]
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Verification Checklist
|
|
37
|
+
|
|
38
|
+
<!-- 由 propose 阶段从 openspec/changes/<name>/specs/ 自动填充 -->
|
|
39
|
+
|
|
40
|
+
- [ ] 系统 SHALL <需求描述> → Task N
|
|
41
|
+
- [ ] 系统 MUST <需求描述> → Task N
|