@relipa/ai-flow-kit 0.1.8 → 0.1.9
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/README.md +21 -3
- package/bin/aiflow.js +3 -2
- package/custom/rules/ml-conventions.md +0 -1
- package/custom/rules/project-conventions.md +0 -1
- package/custom/skills/generate-spec/SKILL.md +7 -0
- package/custom/skills/read-study-requirement/SKILL.md +56 -9
- package/custom/skills/review-plan/SKILL.md +4 -26
- package/custom/templates/shared/coding-workflow.md +3 -1
- package/custom/templates/shared/create-spec-workflow.md +23 -7
- package/custom/templates/shared/gate-workflow.md +3 -4
- package/custom/templates/shared/ml-gate-workflow.md +1 -2
- package/custom/templates/tools/codex.md +75 -0
- package/docs/common/AIFLOW.md +3 -2
- package/docs/common/CHANGELOG.md +42 -0
- package/docs/common/INDEX.md +2 -1
- package/docs/common/QUICK_START.md +1 -0
- package/docs/common/ai-integration.md +69 -2
- package/docs/common/cli-reference.md +1 -1
- package/package.json +2 -2
- package/scripts/doctor.js +83 -0
- package/scripts/guide.js +1 -1
- package/scripts/init.js +331 -35
- package/scripts/prompt.js +3 -6
- package/scripts/remove.js +251 -224
- package/scripts/update.js +5 -1
- package/scripts/use.js +21 -2
- package/custom/rules/java/review-checklist.md +0 -36
- package/custom/rules/ml-review-checklist.md +0 -14
- package/custom/rules/review-checklist.md +0 -9
package/scripts/remove.js
CHANGED
|
@@ -1,224 +1,251 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const chalk = require('chalk');
|
|
4
|
-
const { confirm } = require('@inquirer/prompts');
|
|
5
|
-
|
|
6
|
-
const PROJECT_DIR = process.cwd();
|
|
7
|
-
const AIFLOW_DIR = path.join(PROJECT_DIR, '.aiflow');
|
|
8
|
-
const STATE_FILE = path.join(AIFLOW_DIR, 'state.json');
|
|
9
|
-
|
|
10
|
-
// ──────────────────────────────────────────────────────────────
|
|
11
|
-
// Entry point
|
|
12
|
-
// ──────────────────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
module.exports = async function remove(options = {}) {
|
|
15
|
-
try {
|
|
16
|
-
if (options.global) return await removeGlobal();
|
|
17
|
-
if (options.version) return await removeVersion(options.version);
|
|
18
|
-
return await removeFromProject();
|
|
19
|
-
} catch (err) {
|
|
20
|
-
console.error(chalk.red(`Error: ${err.message}`));
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// ──────────────────────────────────────────────────────────────
|
|
25
|
-
// Case 1: Remove ai-flow-kit setup from current project
|
|
26
|
-
// Deletes .aiflow/, .claude/skills, .claude/hooks, .claude/settings.json, .rules/
|
|
27
|
-
// Does NOT delete CLAUDE.md or .mcp.json (user content)
|
|
28
|
-
// ──────────────────────────────────────────────────────────────
|
|
29
|
-
|
|
30
|
-
async function removeFromProject() {
|
|
31
|
-
if (!(await fs.pathExists(AIFLOW_DIR))) {
|
|
32
|
-
console.log(chalk.yellow('ai-flow-kit is not initialized in this project.'));
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
console.log(chalk.yellow('\nThis will remove ai-flow-kit from the current project:'));
|
|
37
|
-
console.log(chalk.gray(' • .aiflow/ (state, versions, context, memory)'));
|
|
38
|
-
console.log(chalk.gray(' • .claude/skills/ (superpowers + custom skills)'));
|
|
39
|
-
console.log(chalk.gray(' • .claude/hooks/ (SessionStart hook)'));
|
|
40
|
-
console.log(chalk.gray(' • .claude/settings.json (hook config)'));
|
|
41
|
-
console.log(chalk.gray(' • .rules/ (team rules)'));
|
|
42
|
-
console.log(chalk.gray('
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
await fs.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { confirm } = require('@inquirer/prompts');
|
|
5
|
+
|
|
6
|
+
const PROJECT_DIR = process.cwd();
|
|
7
|
+
const AIFLOW_DIR = path.join(PROJECT_DIR, '.aiflow');
|
|
8
|
+
const STATE_FILE = path.join(AIFLOW_DIR, 'state.json');
|
|
9
|
+
|
|
10
|
+
// ──────────────────────────────────────────────────────────────
|
|
11
|
+
// Entry point
|
|
12
|
+
// ──────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
module.exports = async function remove(options = {}) {
|
|
15
|
+
try {
|
|
16
|
+
if (options.global) return await removeGlobal();
|
|
17
|
+
if (options.version) return await removeVersion(options.version);
|
|
18
|
+
return await removeFromProject();
|
|
19
|
+
} catch (err) {
|
|
20
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// ──────────────────────────────────────────────────────────────
|
|
25
|
+
// Case 1: Remove ai-flow-kit setup from current project
|
|
26
|
+
// Deletes .aiflow/, .claude/skills, .claude/hooks, .claude/settings.json, .rules/
|
|
27
|
+
// Does NOT delete CLAUDE.md or .mcp.json (user content)
|
|
28
|
+
// ──────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
async function removeFromProject() {
|
|
31
|
+
if (!(await fs.pathExists(AIFLOW_DIR))) {
|
|
32
|
+
console.log(chalk.yellow('ai-flow-kit is not initialized in this project.'));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(chalk.yellow('\nThis will remove ai-flow-kit from the current project:'));
|
|
37
|
+
console.log(chalk.gray(' • .aiflow/ (state, versions, context, memory)'));
|
|
38
|
+
console.log(chalk.gray(' • .claude/skills/ (superpowers + custom skills)'));
|
|
39
|
+
console.log(chalk.gray(' • .claude/hooks/ (SessionStart hook)'));
|
|
40
|
+
console.log(chalk.gray(' • .claude/settings.json (hook config)'));
|
|
41
|
+
console.log(chalk.gray(' • .rules/ (team rules)'));
|
|
42
|
+
console.log(chalk.gray(' • .codex/skills/ (Codex skill mirror)'));
|
|
43
|
+
console.log(chalk.gray(' • .codex/config.toml (only if kit-managed)'));
|
|
44
|
+
console.log(chalk.gray(' ✗ CLAUDE.md, AGENTS.md and .mcp.json are NOT removed (your content)\n'));
|
|
45
|
+
|
|
46
|
+
const ok = await confirm({ message: 'Continue?' });
|
|
47
|
+
if (!ok) {
|
|
48
|
+
console.log(chalk.gray('Cancelled.'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Remove .aiflow/
|
|
53
|
+
await fs.remove(AIFLOW_DIR);
|
|
54
|
+
console.log(chalk.green('✓ Removed .aiflow/'));
|
|
55
|
+
|
|
56
|
+
// Remove .claude/skills, hooks, settings.json — but keep the rest (e.g. context user may want)
|
|
57
|
+
const claudeDir = path.join(PROJECT_DIR, '.claude');
|
|
58
|
+
const skillsDir = path.join(claudeDir, 'skills');
|
|
59
|
+
const hooksDir = path.join(claudeDir, 'hooks');
|
|
60
|
+
const settingsFile = path.join(claudeDir, 'settings.json');
|
|
61
|
+
|
|
62
|
+
if (await fs.pathExists(skillsDir)) {
|
|
63
|
+
await fs.remove(skillsDir);
|
|
64
|
+
console.log(chalk.green('✓ Removed .claude/skills/'));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (await fs.pathExists(hooksDir)) {
|
|
68
|
+
await fs.remove(hooksDir);
|
|
69
|
+
console.log(chalk.green('✓ Removed .claude/hooks/'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (await fs.pathExists(settingsFile)) {
|
|
73
|
+
// Only remove the _aiflowKit hook entry, not the whole file
|
|
74
|
+
const settings = await fs.readJson(settingsFile).catch(() => ({}));
|
|
75
|
+
if (settings.hooks?.SessionStart) {
|
|
76
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart.filter(
|
|
77
|
+
h => !h._aiflowKit
|
|
78
|
+
);
|
|
79
|
+
if (settings.hooks.SessionStart.length === 0) {
|
|
80
|
+
delete settings.hooks.SessionStart;
|
|
81
|
+
}
|
|
82
|
+
await fs.writeJson(settingsFile, settings, { spaces: 2 });
|
|
83
|
+
console.log(chalk.green('✓ Removed ai-flow-kit hook from .claude/settings.json'));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Remove .rules/
|
|
88
|
+
const rulesDir = path.join(PROJECT_DIR, '.rules');
|
|
89
|
+
if (await fs.pathExists(rulesDir)) {
|
|
90
|
+
await fs.remove(rulesDir);
|
|
91
|
+
console.log(chalk.green('✓ Removed .rules/'));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Remove Codex assets. config.toml only if it still carries our header —
|
|
95
|
+
// a hand-edited config belongs to the developer.
|
|
96
|
+
const codexDir = path.join(PROJECT_DIR, '.codex');
|
|
97
|
+
const codexSkillsDir = path.join(codexDir, 'skills');
|
|
98
|
+
const codexConfig = path.join(codexDir, 'config.toml');
|
|
99
|
+
|
|
100
|
+
if (await fs.pathExists(codexSkillsDir)) {
|
|
101
|
+
await fs.remove(codexSkillsDir);
|
|
102
|
+
console.log(chalk.green('✓ Removed .codex/skills/'));
|
|
103
|
+
}
|
|
104
|
+
if (await fs.pathExists(codexConfig)) {
|
|
105
|
+
const cfg = await fs.readFile(codexConfig, 'utf-8').catch(() => '');
|
|
106
|
+
if (cfg.includes('# ai-flow-kit managed')) {
|
|
107
|
+
await fs.remove(codexConfig);
|
|
108
|
+
console.log(chalk.green('✓ Removed .codex/config.toml'));
|
|
109
|
+
} else {
|
|
110
|
+
console.log(chalk.gray(' Kept .codex/config.toml (hand-managed — not ours to delete)'));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Drop .codex/ only when nothing of the developer's is left in it
|
|
114
|
+
if (await fs.pathExists(codexDir)) {
|
|
115
|
+
const leftovers = await fs.readdir(codexDir);
|
|
116
|
+
if (leftovers.length === 0) await fs.remove(codexDir);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Clean up AI Tool files (CLAUDE.md, AGENTS.md, .cursorrules, etc.)
|
|
120
|
+
const { AI_TOOL_FILES } = require('./init');
|
|
121
|
+
const markerStart = '<!-- aiflow-kit-start -->';
|
|
122
|
+
const markerEnd = '<!-- aiflow-kit-end -->';
|
|
123
|
+
|
|
124
|
+
for (const tool in AI_TOOL_FILES) {
|
|
125
|
+
const filePath = path.join(PROJECT_DIR, AI_TOOL_FILES[tool]);
|
|
126
|
+
if (!(await fs.pathExists(filePath))) continue;
|
|
127
|
+
|
|
128
|
+
let content = await fs.readFile(filePath, 'utf-8');
|
|
129
|
+
let cleaned = false;
|
|
130
|
+
|
|
131
|
+
if (content.includes(markerStart) && content.includes(markerEnd)) {
|
|
132
|
+
// Precise removal using markers
|
|
133
|
+
const startIndex = content.indexOf(markerStart);
|
|
134
|
+
const endIndex = content.indexOf(markerEnd) + markerEnd.length;
|
|
135
|
+
content = content.slice(0, startIndex).trim() + '\n' + content.slice(endIndex).trim();
|
|
136
|
+
content = content.trim();
|
|
137
|
+
cleaned = true;
|
|
138
|
+
} else if (content.includes('## AI Skill Registry (Superpowers)')) {
|
|
139
|
+
// Fallback for legacy installs: remove sections by headers
|
|
140
|
+
console.log(chalk.yellow(` ⚠ Found legacy aiflow sections in ${AI_TOOL_FILES[tool]}`));
|
|
141
|
+
const ok = await confirm({ message: `Remove ai-flow-kit sections from ${AI_TOOL_FILES[tool]}?`, default: true });
|
|
142
|
+
if (ok) {
|
|
143
|
+
// Heuristic: remove from "## AI Skill Registry" or "# Claude AI System Instructions"
|
|
144
|
+
// This is simple and covers most cases. For complex cases, user should manual clean.
|
|
145
|
+
const headers = [
|
|
146
|
+
'# Claude AI System Instructions',
|
|
147
|
+
'## AI Skill Registry (Superpowers)',
|
|
148
|
+
'## MANDATORY: Strict Gate Workflow'
|
|
149
|
+
];
|
|
150
|
+
let minIndex = content.length;
|
|
151
|
+
for (const h of headers) {
|
|
152
|
+
const idx = content.indexOf(h);
|
|
153
|
+
if (idx !== -1 && idx < minIndex) minIndex = idx;
|
|
154
|
+
}
|
|
155
|
+
if (minIndex < content.length) {
|
|
156
|
+
content = content.slice(0, minIndex).trim();
|
|
157
|
+
cleaned = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (cleaned) {
|
|
163
|
+
if (content.length === 0) {
|
|
164
|
+
await fs.remove(filePath);
|
|
165
|
+
console.log(chalk.green(`✓ Deleted ${AI_TOOL_FILES[tool]} (it was aiflow-only)`));
|
|
166
|
+
} else {
|
|
167
|
+
await fs.writeFile(filePath, content);
|
|
168
|
+
console.log(chalk.green(`✓ Cleaned up ai-flow-kit instructions from ${AI_TOOL_FILES[tool]}`));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
console.log(chalk.green('\n✨ ai-flow-kit removed from project.'));
|
|
174
|
+
console.log(chalk.gray('To reinstall: aiflow init'));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ──────────────────────────────────────────────────────────────
|
|
178
|
+
// Case 2: Uninstall the global npm package
|
|
179
|
+
// ──────────────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
async function removeGlobal() {
|
|
182
|
+
console.log(chalk.yellow('\nThis will uninstall ai-flow-kit globally from your system.'));
|
|
183
|
+
console.log(chalk.gray('Project files (.aiflow/, .claude/, .rules/) are NOT affected.\n'));
|
|
184
|
+
|
|
185
|
+
const ok = await confirm({ message: 'Uninstall global package?' });
|
|
186
|
+
if (!ok) {
|
|
187
|
+
console.log(chalk.gray('Cancelled.'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const { execSync } = require('child_process');
|
|
192
|
+
try {
|
|
193
|
+
console.log(chalk.blue('Running: npm uninstall -g ai-flow-kit ...'));
|
|
194
|
+
execSync('npm uninstall -g ai-flow-kit', { stdio: 'inherit' });
|
|
195
|
+
console.log(chalk.green('\n✨ ai-flow-kit uninstalled globally.'));
|
|
196
|
+
console.log(chalk.gray('The `aiflow` command is no longer available.'));
|
|
197
|
+
} catch (err) {
|
|
198
|
+
// execSync throws on non-zero exit; message already printed via stdio: inherit
|
|
199
|
+
console.log(chalk.red('\nFailed to uninstall. Try manually: npm uninstall -g ai-flow-kit'));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ──────────────────────────────────────────────────────────────
|
|
204
|
+
// Case 3: Remove a specific cached version from .aiflow/versions/
|
|
205
|
+
// ──────────────────────────────────────────────────────────────
|
|
206
|
+
|
|
207
|
+
async function removeVersion(version) {
|
|
208
|
+
if (!(await fs.pathExists(STATE_FILE))) {
|
|
209
|
+
console.log(chalk.red('Project is not initialized. Run `aiflow init` first.'));
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const versionsDir = path.join(AIFLOW_DIR, 'versions');
|
|
214
|
+
const targetDir = path.join(versionsDir, version);
|
|
215
|
+
|
|
216
|
+
if (!(await fs.pathExists(targetDir))) {
|
|
217
|
+
console.log(chalk.red(`Version v${version} is not cached in this project.`));
|
|
218
|
+
|
|
219
|
+
// Show what's available
|
|
220
|
+
if (await fs.pathExists(versionsDir)) {
|
|
221
|
+
const available = await fs.readdir(versionsDir);
|
|
222
|
+
if (available.length) {
|
|
223
|
+
console.log(chalk.gray(`Cached versions: ${available.map(v => `v${v}`).join(', ')}`));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Prevent removing the currently active version
|
|
230
|
+
const state = await fs.readJson(STATE_FILE);
|
|
231
|
+
if (state.current_version === version) {
|
|
232
|
+
console.log(chalk.red(`v${version} is currently active — cannot remove it.`));
|
|
233
|
+
console.log(chalk.gray('Switch to another version first: aiflow use <version>'));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const ok = await confirm({ message: `Delete cached version v${version}?` });
|
|
238
|
+
if (!ok) {
|
|
239
|
+
console.log(chalk.gray('Cancelled.'));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
await fs.remove(targetDir);
|
|
244
|
+
console.log(chalk.green(`✓ Removed cached version v${version}.`));
|
|
245
|
+
|
|
246
|
+
// Show remaining versions
|
|
247
|
+
const remaining = await fs.readdir(versionsDir).catch(() => []);
|
|
248
|
+
if (remaining.length) {
|
|
249
|
+
console.log(chalk.gray(`Remaining: ${remaining.map(v => `v${v}`).join(', ')}`));
|
|
250
|
+
}
|
|
251
|
+
}
|
package/scripts/update.js
CHANGED
|
@@ -126,7 +126,7 @@ module.exports = async function update(options = {}) {
|
|
|
126
126
|
|
|
127
127
|
// Sync instruction files with the updated skills.
|
|
128
128
|
// Support both old 'framework' (singular string) and new 'frameworks' (array).
|
|
129
|
-
const { setupFramework, AI_TOOL_FILES, ensureAiflowGitignored, setupClaudeCommands, copyDocsToProject } = require('./init');
|
|
129
|
+
const { setupFramework, AI_TOOL_FILES, ensureAiflowGitignored, setupClaudeCommands, copyDocsToProject, setupCodex } = require('./init');
|
|
130
130
|
const frameworks = state.frameworks || (state.framework ? [state.framework] : []);
|
|
131
131
|
const selectedTools = state.aiTools || Object.keys(AI_TOOL_FILES);
|
|
132
132
|
for (const fw of frameworks) {
|
|
@@ -136,6 +136,10 @@ module.exports = async function update(options = {}) {
|
|
|
136
136
|
// Install / refresh Claude Code custom commands (.claude/commands/)
|
|
137
137
|
await setupClaudeCommands(projectDir);
|
|
138
138
|
|
|
139
|
+
// Refresh Codex assets (.codex/skills/, .codex/config.toml) when codex is selected.
|
|
140
|
+
// Runs after the skill copy above so the mirror picks up the new version's skills.
|
|
141
|
+
await setupCodex(projectDir, selectedTools);
|
|
142
|
+
|
|
139
143
|
// Refresh .aiflow/docs with the latest docs/common/ (feeds `ak ask` / aiflow-help).
|
|
140
144
|
// Without this, docs promoted after the project's `ak init` never reach the project.
|
|
141
145
|
await copyDocsToProject(projectDir);
|
package/scripts/use.js
CHANGED
|
@@ -1072,11 +1072,15 @@ async function suggestNextStep() {
|
|
|
1072
1072
|
|
|
1073
1073
|
console.log(chalk.cyan("\nNext Steps:"));
|
|
1074
1074
|
|
|
1075
|
-
const hasCLI =
|
|
1075
|
+
const hasCLI =
|
|
1076
|
+
aiTools.includes("claude") ||
|
|
1077
|
+
aiTools.includes("gemini") ||
|
|
1078
|
+
aiTools.includes("codex");
|
|
1076
1079
|
const hasIDE =
|
|
1077
1080
|
aiTools.includes("claude") ||
|
|
1078
1081
|
aiTools.includes("cursor") ||
|
|
1079
|
-
aiTools.includes("copilot")
|
|
1082
|
+
aiTools.includes("copilot") ||
|
|
1083
|
+
aiTools.includes("codex");
|
|
1080
1084
|
|
|
1081
1085
|
if (hasCLI) {
|
|
1082
1086
|
console.log(chalk.white("\n CLI:"));
|
|
@@ -1091,6 +1095,11 @@ async function suggestNextStep() {
|
|
|
1091
1095
|
` ${++step}. ${chalk.white("Gemini:")} Run ${chalk.bold.green("gemini")} then type ${chalk.bold.green('"start"')} or ${chalk.bold.green('"Gate 1"')}.`,
|
|
1092
1096
|
);
|
|
1093
1097
|
}
|
|
1098
|
+
if (aiTools.includes("codex")) {
|
|
1099
|
+
console.log(
|
|
1100
|
+
` ${++step}. ${chalk.white("Codex:")} Run ${chalk.bold.green("codex")} then use ${chalk.bold.green("/ak-coding")} ${chalk.gray("(or type \"Gate 1\")")}.`,
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1094
1103
|
}
|
|
1095
1104
|
|
|
1096
1105
|
if (hasIDE) {
|
|
@@ -1098,6 +1107,16 @@ async function suggestNextStep() {
|
|
|
1098
1107
|
console.log(
|
|
1099
1108
|
` Run ${chalk.bold.green("aiflow prompt")} → prompt auto-copied to clipboard → paste into your AI extension chat.`,
|
|
1100
1109
|
);
|
|
1110
|
+
if (aiTools.includes("codex")) {
|
|
1111
|
+
console.log(
|
|
1112
|
+
` ${chalk.white("Codex (VS Code extension / ChatGPT desktop app):")} open this folder, then run ${chalk.bold.green("/ak-coding")} in the Codex panel.`,
|
|
1113
|
+
);
|
|
1114
|
+
console.log(
|
|
1115
|
+
chalk.gray(
|
|
1116
|
+
" Codex has no session-start hook — start a NEW Codex session after `ak use` so it re-reads AGENTS.md and the ticket context.",
|
|
1117
|
+
),
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1101
1120
|
}
|
|
1102
1121
|
|
|
1103
1122
|
console.log(
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Code Review Checklist — Java / Spring Boot
|
|
2
|
-
|
|
3
|
-
## Architecture
|
|
4
|
-
- [ ] Controller only handles HTTP (parse request, call service, return response) — no business logic
|
|
5
|
-
- [ ] Business logic resides in Service, not in Controller or Repository
|
|
6
|
-
- [ ] Repository only performs data access — no business logic
|
|
7
|
-
- [ ] Entity is not exposed directly — always use DTOs
|
|
8
|
-
|
|
9
|
-
## Code Quality
|
|
10
|
-
- [ ] No `@Autowired` field injection — use constructor injection (Lombok `@RequiredArgsConstructor`)
|
|
11
|
-
- [ ] No `@Data` on Entity — use `@Getter @Setter` separately
|
|
12
|
-
- [ ] No `new RuntimeException()` — create specific custom exceptions
|
|
13
|
-
- [ ] No magic numbers/strings — use named constants
|
|
14
|
-
- [ ] No dead code (commented-out code, unused variables)
|
|
15
|
-
|
|
16
|
-
## Database & Performance
|
|
17
|
-
- [ ] No N+1 queries — use `@EntityGraph` or `JOIN FETCH`
|
|
18
|
-
- [ ] Lists are paginated — do not return the entire table
|
|
19
|
-
- [ ] Read-only service methods have `@Transactional(readOnly = true)`
|
|
20
|
-
- [ ] Indexes on columns frequently used in WHERE/JOIN
|
|
21
|
-
|
|
22
|
-
## Testing
|
|
23
|
-
- [ ] Unit tests for Service layer (Mockito)
|
|
24
|
-
- [ ] Tests cover: happy path, error cases, edge cases
|
|
25
|
-
- [ ] Do not mock things that don't need mocking
|
|
26
|
-
|
|
27
|
-
## Security
|
|
28
|
-
- [ ] Input is validated using Bean Validation (`@Valid`)
|
|
29
|
-
- [ ] No logging of passwords, tokens, or PII
|
|
30
|
-
- [ ] SQL injection is not possible (use parameterized JPA/JPQL)
|
|
31
|
-
- [ ] Stack traces are not returned to the client
|
|
32
|
-
|
|
33
|
-
## Logging
|
|
34
|
-
- [ ] Use `@Slf4j` + SLF4J — no `System.out.println`
|
|
35
|
-
- [ ] Correct log levels: `info` (normal), `warn` (recoverable), `error` (unexpected + exception)
|
|
36
|
-
- [ ] Log messages have enough context for debugging (include ID, action)
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# ML Review Checklist
|
|
2
|
-
|
|
3
|
-
Before completing Gate 4 and creating a Pull Request, verify:
|
|
4
|
-
|
|
5
|
-
- [ ] Evaluation metric matches the problem type and business goal defined in Gate 1.
|
|
6
|
-
- [ ] Model beats the baseline by at least the success threshold defined in Gate 1.
|
|
7
|
-
- [ ] No data leakage — all three types re-checked: target leakage, train/test contamination, and temporal leakage.
|
|
8
|
-
- [ ] Result is reproducible: re-run with the logged seed, pinned environment, and saved config produces the same metric.
|
|
9
|
-
- [ ] No overfitting: train / validation / test metric gap is acceptable and documented.
|
|
10
|
-
- [ ] Error analysis performed: worst slices, classes, or failure cases identified and documented.
|
|
11
|
-
- [ ] Robustness assessed: behavior under noise, shifted inputs, or edge cases verified; fairness across sensitive slices checked where applicable.
|
|
12
|
-
- [ ] All experiments tracked: params, metrics, data version, and git commit SHA logged in MLflow / wandb for every run (including failures).
|
|
13
|
-
- [ ] Model card present: intended use, training data, evaluation metrics, known limitations, and owner documented.
|
|
14
|
-
- [ ] Impact on data pipeline assessed via `impact-analysis` skill and implications documented.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Code Review Checklist
|
|
2
|
-
|
|
3
|
-
Before creating a Pull Request, verify:
|
|
4
|
-
- [ ] Code compiles and passes all local tests.
|
|
5
|
-
- [ ] No strict dependency on local environment (hardcoded IPs, paths).
|
|
6
|
-
- [ ] Security checks: No exposed API keys, no raw SQL vulnerability.
|
|
7
|
-
- [ ] Impact Analysis run (via `impact-analysis` skill) and implications documented.
|
|
8
|
-
- [ ] Naming and Code Style rules observed.
|
|
9
|
-
- [ ] Feature is covered by unit/feature tests where applicable.
|