@jahanxu/code-flow 0.1.2 → 0.2.1
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/package.json +1 -1
- package/src/adapters/claude/CLAUDE.md +11 -1
- package/src/adapters/claude/commands/cf-init.md +269 -0
- package/src/adapters/claude/commands/cf-inject.md +41 -0
- package/src/adapters/claude/commands/cf-learn.md +120 -0
- package/src/adapters/claude/commands/cf-scan.md +56 -0
- package/src/adapters/claude/commands/cf-stats.md +65 -0
- package/src/adapters/claude/commands/cf-validate.md +71 -0
- package/src/cli.js +96 -14
- package/src/adapters/claude/skills/cf-init.md +0 -13
- package/src/adapters/claude/skills/cf-inject.md +0 -12
- package/src/adapters/claude/skills/cf-learn.md +0 -11
- package/src/adapters/claude/skills/cf-scan.md +0 -12
- package/src/adapters/claude/skills/cf-stats.md +0 -11
- package/src/adapters/claude/skills/cf-validate.md +0 -12
- package/src/core/code-flow/scripts/cf_init.py +0 -829
- package/src/core/code-flow/scripts/cf_inject.py +0 -150
- package/src/core/code-flow/scripts/cf_learn.py +0 -202
- package/src/core/code-flow/scripts/cf_validate.py +0 -340
package/src/cli.js
CHANGED
|
@@ -6,9 +6,12 @@ const fs = require('fs');
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const { spawnSync } = require('child_process');
|
|
8
8
|
|
|
9
|
+
const pkg = require('../package.json');
|
|
10
|
+
|
|
9
11
|
const usage = [
|
|
10
12
|
'Usage: code-flow init',
|
|
11
|
-
' code-flow --
|
|
13
|
+
' code-flow -v | --version',
|
|
14
|
+
' code-flow -h | --help'
|
|
12
15
|
].join('\n');
|
|
13
16
|
|
|
14
17
|
function printUsage(stream) {
|
|
@@ -57,6 +60,21 @@ function copyDirRecursive(srcDir, destDir) {
|
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
|
|
63
|
+
function collectFiles(dir, base) {
|
|
64
|
+
const results = [];
|
|
65
|
+
if (!fs.existsSync(dir)) return results;
|
|
66
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
67
|
+
for (const entry of entries) {
|
|
68
|
+
const rel = path.join(base, entry.name);
|
|
69
|
+
if (entry.isDirectory()) {
|
|
70
|
+
results.push(...collectFiles(path.join(dir, entry.name), rel));
|
|
71
|
+
} else if (entry.isFile()) {
|
|
72
|
+
results.push(rel);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
function runInit() {
|
|
61
79
|
ensurePython3();
|
|
62
80
|
|
|
@@ -65,27 +83,91 @@ function runInit() {
|
|
|
65
83
|
const coreDir = path.join(baseDir, 'core');
|
|
66
84
|
const adaptersDir = path.join(baseDir, 'adapters');
|
|
67
85
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
86
|
+
const created = [];
|
|
87
|
+
const skipped = [];
|
|
88
|
+
|
|
89
|
+
// Track files before copy
|
|
90
|
+
const track = (srcDir, destDir, prefix) => {
|
|
91
|
+
if (!fs.existsSync(srcDir)) return;
|
|
92
|
+
const files = collectFiles(srcDir, '');
|
|
93
|
+
for (const rel of files) {
|
|
94
|
+
const dest = path.join(destDir, rel);
|
|
95
|
+
const label = path.join(prefix, rel);
|
|
96
|
+
if (fs.existsSync(dest)) {
|
|
97
|
+
skipped.push(label);
|
|
98
|
+
} else {
|
|
99
|
+
created.push(label);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
track(path.join(coreDir, 'code-flow'), path.join(cwd, '.code-flow'), '.code-flow');
|
|
105
|
+
const claudeMdDest = path.join(cwd, 'CLAUDE.md');
|
|
106
|
+
if (fs.existsSync(claudeMdDest)) {
|
|
107
|
+
skipped.push('CLAUDE.md');
|
|
108
|
+
} else {
|
|
109
|
+
created.push('CLAUDE.md');
|
|
110
|
+
}
|
|
111
|
+
track(path.join(adaptersDir, 'claude', 'commands'), path.join(cwd, '.claude', 'commands'), '.claude/commands');
|
|
112
|
+
const settingsDest = path.join(cwd, '.claude', 'settings.local.json');
|
|
113
|
+
if (fs.existsSync(settingsDest)) {
|
|
114
|
+
skipped.push('.claude/settings.local.json');
|
|
115
|
+
} else {
|
|
116
|
+
created.push('.claude/settings.local.json');
|
|
117
|
+
}
|
|
71
118
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
119
|
+
// Perform copy
|
|
120
|
+
copyDirRecursive(path.join(coreDir, 'code-flow'), path.join(cwd, '.code-flow'));
|
|
121
|
+
copyFileIfMissing(path.join(adaptersDir, 'claude', 'CLAUDE.md'), claudeMdDest);
|
|
122
|
+
fs.mkdirSync(path.join(cwd, '.claude', 'commands'), { recursive: true });
|
|
123
|
+
copyDirRecursive(path.join(adaptersDir, 'claude', 'commands'), path.join(cwd, '.claude', 'commands'));
|
|
124
|
+
copyFileIfMissing(path.join(adaptersDir, 'claude', 'settings.local.json'), settingsDest);
|
|
125
|
+
|
|
126
|
+
// Clean up legacy .claude/skills/ if it exists
|
|
127
|
+
const legacySkills = path.join(cwd, '.claude', 'skills');
|
|
128
|
+
if (fs.existsSync(legacySkills)) {
|
|
129
|
+
fs.rmSync(legacySkills, { recursive: true });
|
|
130
|
+
process.stdout.write('Cleaned up legacy .claude/skills/\n');
|
|
131
|
+
}
|
|
77
132
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
133
|
+
// Install pyyaml
|
|
134
|
+
const pip = spawnSync('python3', ['-m', 'pip', 'install', 'pyyaml'], {
|
|
135
|
+
stdio: 'ignore'
|
|
136
|
+
});
|
|
137
|
+
if (pip.error || pip.status !== 0) {
|
|
138
|
+
process.stderr.write('Warning: pyyaml install failed. Run manually: pip install pyyaml\n');
|
|
81
139
|
}
|
|
82
140
|
|
|
83
|
-
|
|
141
|
+
// Output summary
|
|
142
|
+
process.stdout.write('\ncode-flow initialized!\n\n');
|
|
143
|
+
if (created.length > 0) {
|
|
144
|
+
process.stdout.write('Created:\n');
|
|
145
|
+
for (const f of created) {
|
|
146
|
+
process.stdout.write(` + ${f}\n`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (skipped.length > 0) {
|
|
150
|
+
process.stdout.write('Skipped (already exist):\n');
|
|
151
|
+
for (const f of skipped) {
|
|
152
|
+
process.stdout.write(` - ${f}\n`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
process.stdout.write('\nNext steps:\n');
|
|
156
|
+
process.stdout.write(' 1. Edit CLAUDE.md — fill in team/project info\n');
|
|
157
|
+
process.stdout.write(' 2. Edit .code-flow/specs/ — fill in your coding standards\n');
|
|
158
|
+
process.stdout.write(' 3. Run /project:cf-learn in Claude Code to auto-discover constraints\n');
|
|
159
|
+
process.exit(0);
|
|
84
160
|
}
|
|
85
161
|
|
|
86
162
|
const args = process.argv.slice(2);
|
|
87
163
|
|
|
88
|
-
if (args.
|
|
164
|
+
if (args.includes('-v') || args.includes('--version')) {
|
|
165
|
+
process.stdout.write(`${pkg.version}\n`);
|
|
166
|
+
process.exit(0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
170
|
+
process.stdout.write(`code-flow v${pkg.version}\n\n`);
|
|
89
171
|
printUsage(process.stdout);
|
|
90
172
|
process.exit(0);
|
|
91
173
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# cf-init
|
|
2
|
-
|
|
3
|
-
初始化 code-flow 规范体系(目录、配置、spec、skill、hooks)。
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
- `/cf-init`
|
|
7
|
-
- `/cf-init frontend|backend|fullstack`
|
|
8
|
-
|
|
9
|
-
## Command
|
|
10
|
-
- `python3 .code-flow/scripts/cf_init.py [frontend|backend|fullstack]`
|
|
11
|
-
|
|
12
|
-
## Notes
|
|
13
|
-
- 依赖 Python 3.9+ 与 pyyaml(脚本会尝试自动安装)。
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# cf-inject
|
|
2
|
-
|
|
3
|
-
手动注入指定领域或文件路径对应的规范(Hook 失败时回退)。
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
- `/cf-inject frontend|backend`
|
|
7
|
-
- `/cf-inject path/to/file.ext`
|
|
8
|
-
- `/cf-inject --list-specs --domain=frontend`
|
|
9
|
-
|
|
10
|
-
## Command
|
|
11
|
-
- `python3 .code-flow/scripts/cf_inject.py [domain|file_path]`
|
|
12
|
-
- `python3 .code-flow/scripts/cf_inject.py --list-specs --domain=frontend`
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# cf-learn
|
|
2
|
-
|
|
3
|
-
将经验沉淀到对应规范的 Learnings 段落。
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
- `/cf-learn --scope=global --content="..." `
|
|
7
|
-
- `/cf-learn --scope=frontend --content="..." --file=frontend/component-specs.md`
|
|
8
|
-
- `/cf-learn --scope=backend --content="..." --file=backend/logging.md`
|
|
9
|
-
|
|
10
|
-
## Command
|
|
11
|
-
- `python3 .code-flow/scripts/cf_learn.py --scope=global|frontend|backend --content=\"...\" [--file=spec] [--dry-run]`
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# cf-validate
|
|
2
|
-
|
|
3
|
-
基于变更文件执行验证规则(类型检查/测试/lint)。
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
- `/cf-validate`
|
|
7
|
-
- `/cf-validate path/to/file.py`
|
|
8
|
-
- `/cf-validate --files=src/a.ts,src/b.ts`
|
|
9
|
-
- `/cf-validate --only-failed`
|
|
10
|
-
|
|
11
|
-
## Command
|
|
12
|
-
- `python3 .code-flow/scripts/cf_validate.py [file_path] [--files=...] [--only-failed] [--json-short] [--output=table]`
|