@relipa/ai-flow-kit 0.0.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/AIFLOW.md +432 -0
- package/CHANGELOG.md +78 -0
- package/CONTRIBUTING.md +351 -0
- package/IMPLEMENTATION_SUMMARY.md +348 -0
- package/QUICK_START.md +392 -0
- package/README.md +323 -0
- package/bin/aiflow.js +178 -0
- package/custom/mcp-presets/README.md +138 -0
- package/custom/mcp-presets/backlog.json +15 -0
- package/custom/mcp-presets/figma.json +15 -0
- package/custom/mcp-presets/google-sheets.json +14 -0
- package/custom/mcp-presets/jira.json +16 -0
- package/custom/prompts/bug-fix.md +149 -0
- package/custom/prompts/feature.md +190 -0
- package/custom/prompts/investigation.md +164 -0
- package/custom/rules/code-style.md +7 -0
- package/custom/rules/java/code-style.md +11 -0
- package/custom/rules/java/naming.md +17 -0
- package/custom/rules/java/review-checklist.md +36 -0
- package/custom/rules/javascript/code-style.md +12 -0
- package/custom/rules/javascript/naming.md +14 -0
- package/custom/rules/naming.md +9 -0
- package/custom/rules/php/code-style.md +10 -0
- package/custom/rules/php/naming.md +15 -0
- package/custom/rules/review-checklist.md +9 -0
- package/custom/skills/figma-to-component/SKILL.md +207 -0
- package/custom/skills/generate-spec/SKILL.md +97 -0
- package/custom/skills/impact-analysis/SKILL.md +94 -0
- package/custom/skills/investigate-bug/SKILL.md +93 -0
- package/custom/skills/report-customer/SKILL.md +95 -0
- package/custom/skills/review-plan/SKILL.md +158 -0
- package/custom/skills/validate-ticket/SKILL.md +240 -0
- package/custom/templates/laravel.md +90 -0
- package/custom/templates/nextjs.md +89 -0
- package/custom/templates/reactjs.md +567 -0
- package/custom/templates/spring-boot.md +598 -0
- package/custom/templates/vue-nuxt.md +89 -0
- package/docs/architecture.md +395 -0
- package/docs/cli-reference.md +438 -0
- package/docs/configuration.md +412 -0
- package/docs/getting-started.md +248 -0
- package/docs/troubleshooting.md +587 -0
- package/docs/workflows/bug-fix.md +126 -0
- package/docs/workflows/feature.md +123 -0
- package/docs/workflows/impact-analysis.md +13 -0
- package/docs/workflows/investigation.md +13 -0
- package/docs/workflows/refactor.md +13 -0
- package/index.js +27 -0
- package/package.json +70 -0
- package/scripts/config.js +317 -0
- package/scripts/context.js +117 -0
- package/scripts/detect.js +239 -0
- package/scripts/doctor.js +48 -0
- package/scripts/guide.js +282 -0
- package/scripts/hooks/session-start.js +140 -0
- package/scripts/init.js +453 -0
- package/scripts/memory.js +247 -0
- package/scripts/prompt.js +392 -0
- package/scripts/remove.js +170 -0
- package/scripts/update.js +111 -0
- package/scripts/use.js +570 -0
- package/scripts/validate.js +303 -0
- package/upstream/.claude-plugin/marketplace.json +20 -0
- package/upstream/.claude-plugin/plugin.json +20 -0
- package/upstream/.codex/INSTALL.md +67 -0
- package/upstream/.cursor-plugin/plugin.json +25 -0
- package/upstream/.gitattributes +18 -0
- package/upstream/.github/FUNDING.yml +3 -0
- package/upstream/.github/ISSUE_TEMPLATE/bug_report.md +52 -0
- package/upstream/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/upstream/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
- package/upstream/.github/ISSUE_TEMPLATE/platform_support.md +23 -0
- package/upstream/.github/PULL_REQUEST_TEMPLATE.md +87 -0
- package/upstream/.opencode/INSTALL.md +83 -0
- package/upstream/.opencode/plugins/superpowers.js +112 -0
- package/upstream/.version-bump.json +19 -0
- package/upstream/AGENTS.md +1 -0
- package/upstream/CHANGELOG.md +13 -0
- package/upstream/CLAUDE.md +85 -0
- package/upstream/CODE_OF_CONDUCT.md +128 -0
- package/upstream/GEMINI.md +2 -0
- package/upstream/LICENSE +21 -0
- package/upstream/README.md +190 -0
- package/upstream/RELEASE-NOTES.md +1096 -0
- package/upstream/agents/code-reviewer.md +48 -0
- package/upstream/commands/brainstorm.md +5 -0
- package/upstream/commands/execute-plan.md +5 -0
- package/upstream/commands/write-plan.md +5 -0
- package/upstream/docs/README.codex.md +126 -0
- package/upstream/docs/README.opencode.md +130 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-design.md +294 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-implementation.md +1095 -0
- package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +711 -0
- package/upstream/docs/plans/2026-01-17-visual-brainstorming.md +571 -0
- package/upstream/docs/superpowers/plans/2026-01-22-document-review-system.md +301 -0
- package/upstream/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +523 -0
- package/upstream/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +479 -0
- package/upstream/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +564 -0
- package/upstream/docs/superpowers/specs/2026-01-22-document-review-system-design.md +136 -0
- package/upstream/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +162 -0
- package/upstream/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +118 -0
- package/upstream/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +244 -0
- package/upstream/docs/testing.md +303 -0
- package/upstream/docs/windows/polyglot-hooks.md +212 -0
- package/upstream/gemini-extension.json +6 -0
- package/upstream/hooks/hooks-cursor.json +10 -0
- package/upstream/hooks/hooks.json +16 -0
- package/upstream/hooks/run-hook.cmd +46 -0
- package/upstream/hooks/session-start +57 -0
- package/upstream/package.json +6 -0
- package/upstream/scripts/bump-version.sh +220 -0
- package/upstream/skills/brainstorming/SKILL.md +164 -0
- package/upstream/skills/brainstorming/scripts/frame-template.html +214 -0
- package/upstream/skills/brainstorming/scripts/helper.js +88 -0
- package/upstream/skills/brainstorming/scripts/server.cjs +354 -0
- package/upstream/skills/brainstorming/scripts/start-server.sh +148 -0
- package/upstream/skills/brainstorming/scripts/stop-server.sh +56 -0
- package/upstream/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/upstream/skills/brainstorming/visual-companion.md +287 -0
- package/upstream/skills/dispatching-parallel-agents/SKILL.md +182 -0
- package/upstream/skills/executing-plans/SKILL.md +70 -0
- package/upstream/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/upstream/skills/receiving-code-review/SKILL.md +213 -0
- package/upstream/skills/requesting-code-review/SKILL.md +105 -0
- package/upstream/skills/requesting-code-review/code-reviewer.md +146 -0
- package/upstream/skills/subagent-driven-development/SKILL.md +277 -0
- package/upstream/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/upstream/skills/subagent-driven-development/implementer-prompt.md +113 -0
- package/upstream/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/upstream/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/upstream/skills/systematic-debugging/SKILL.md +296 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/upstream/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/upstream/skills/systematic-debugging/find-polluter.sh +63 -0
- package/upstream/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/upstream/skills/systematic-debugging/test-academic.md +14 -0
- package/upstream/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/upstream/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/upstream/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/upstream/skills/test-driven-development/SKILL.md +371 -0
- package/upstream/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/upstream/skills/using-git-worktrees/SKILL.md +218 -0
- package/upstream/skills/using-superpowers/SKILL.md +117 -0
- package/upstream/skills/using-superpowers/references/codex-tools.md +100 -0
- package/upstream/skills/using-superpowers/references/copilot-tools.md +52 -0
- package/upstream/skills/using-superpowers/references/gemini-tools.md +33 -0
- package/upstream/skills/verification-before-completion/SKILL.md +139 -0
- package/upstream/skills/writing-plans/SKILL.md +152 -0
- package/upstream/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/upstream/skills/writing-skills/SKILL.md +655 -0
- package/upstream/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/upstream/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/upstream/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/upstream/skills/writing-skills/persuasion-principles.md +187 -0
- package/upstream/skills/writing-skills/render-graphs.js +168 -0
- package/upstream/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/upstream/tests/brainstorm-server/package-lock.json +36 -0
- package/upstream/tests/brainstorm-server/package.json +10 -0
- package/upstream/tests/brainstorm-server/server.test.js +427 -0
- package/upstream/tests/brainstorm-server/windows-lifecycle.test.sh +351 -0
- package/upstream/tests/brainstorm-server/ws-protocol.test.js +392 -0
- package/upstream/tests/claude-code/README.md +158 -0
- package/upstream/tests/claude-code/analyze-token-usage.py +168 -0
- package/upstream/tests/claude-code/run-skill-tests.sh +187 -0
- package/upstream/tests/claude-code/test-document-review-system.sh +177 -0
- package/upstream/tests/claude-code/test-helpers.sh +202 -0
- package/upstream/tests/claude-code/test-subagent-driven-development-integration.sh +314 -0
- package/upstream/tests/claude-code/test-subagent-driven-development.sh +165 -0
- package/upstream/tests/explicit-skill-requests/prompts/action-oriented.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/after-planning-flow.txt +17 -0
- package/upstream/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +11 -0
- package/upstream/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +8 -0
- package/upstream/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +1 -0
- package/upstream/tests/explicit-skill-requests/prompts/skip-formalities.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +1 -0
- package/upstream/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +1 -0
- package/upstream/tests/explicit-skill-requests/run-all.sh +70 -0
- package/upstream/tests/explicit-skill-requests/run-claude-describes-sdd.sh +100 -0
- package/upstream/tests/explicit-skill-requests/run-extended-multiturn-test.sh +113 -0
- package/upstream/tests/explicit-skill-requests/run-haiku-test.sh +144 -0
- package/upstream/tests/explicit-skill-requests/run-multiturn-test.sh +143 -0
- package/upstream/tests/explicit-skill-requests/run-test.sh +136 -0
- package/upstream/tests/opencode/run-tests.sh +163 -0
- package/upstream/tests/opencode/setup.sh +88 -0
- package/upstream/tests/opencode/test-plugin-loading.sh +82 -0
- package/upstream/tests/opencode/test-priority.sh +198 -0
- package/upstream/tests/opencode/test-tools.sh +104 -0
- package/upstream/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +8 -0
- package/upstream/tests/skill-triggering/prompts/executing-plans.txt +1 -0
- package/upstream/tests/skill-triggering/prompts/requesting-code-review.txt +3 -0
- package/upstream/tests/skill-triggering/prompts/systematic-debugging.txt +11 -0
- package/upstream/tests/skill-triggering/prompts/test-driven-development.txt +7 -0
- package/upstream/tests/skill-triggering/prompts/writing-plans.txt +10 -0
- package/upstream/tests/skill-triggering/run-all.sh +60 -0
- package/upstream/tests/skill-triggering/run-test.sh +88 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/design.md +81 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/plan.md +172 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/scaffold.sh +45 -0
- package/upstream/tests/subagent-driven-dev/run-test.sh +106 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/design.md +70 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/plan.md +222 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/scaffold.sh +46 -0
|
@@ -0,0 +1,170 @@
|
|
|
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(' ✗ CLAUDE.md and .mcp.json are NOT removed (your content)\n'));
|
|
43
|
+
|
|
44
|
+
const ok = await confirm({ message: 'Continue?' });
|
|
45
|
+
if (!ok) {
|
|
46
|
+
console.log(chalk.gray('Cancelled.'));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Remove .aiflow/
|
|
51
|
+
await fs.remove(AIFLOW_DIR);
|
|
52
|
+
console.log(chalk.green('✓ Removed .aiflow/'));
|
|
53
|
+
|
|
54
|
+
// Remove .claude/skills, hooks, settings.json — but keep the rest (e.g. context user may want)
|
|
55
|
+
const claudeDir = path.join(PROJECT_DIR, '.claude');
|
|
56
|
+
const skillsDir = path.join(claudeDir, 'skills');
|
|
57
|
+
const hooksDir = path.join(claudeDir, 'hooks');
|
|
58
|
+
const settingsFile = path.join(claudeDir, 'settings.json');
|
|
59
|
+
|
|
60
|
+
if (await fs.pathExists(skillsDir)) {
|
|
61
|
+
await fs.remove(skillsDir);
|
|
62
|
+
console.log(chalk.green('✓ Removed .claude/skills/'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (await fs.pathExists(hooksDir)) {
|
|
66
|
+
await fs.remove(hooksDir);
|
|
67
|
+
console.log(chalk.green('✓ Removed .claude/hooks/'));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (await fs.pathExists(settingsFile)) {
|
|
71
|
+
// Only remove the _aiflowKit hook entry, not the whole file
|
|
72
|
+
const settings = await fs.readJson(settingsFile).catch(() => ({}));
|
|
73
|
+
if (settings.hooks?.SessionStart) {
|
|
74
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart.filter(
|
|
75
|
+
h => !h._aiflowKit
|
|
76
|
+
);
|
|
77
|
+
if (settings.hooks.SessionStart.length === 0) {
|
|
78
|
+
delete settings.hooks.SessionStart;
|
|
79
|
+
}
|
|
80
|
+
await fs.writeJson(settingsFile, settings, { spaces: 2 });
|
|
81
|
+
console.log(chalk.green('✓ Removed ai-flow-kit hook from .claude/settings.json'));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Remove .rules/
|
|
86
|
+
const rulesDir = path.join(PROJECT_DIR, '.rules');
|
|
87
|
+
if (await fs.pathExists(rulesDir)) {
|
|
88
|
+
await fs.remove(rulesDir);
|
|
89
|
+
console.log(chalk.green('✓ Removed .rules/'));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log(chalk.green('\n✨ ai-flow-kit removed from project.'));
|
|
93
|
+
console.log(chalk.gray('To reinstall: aiflow init'));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ──────────────────────────────────────────────────────────────
|
|
97
|
+
// Case 2: Uninstall the global npm package
|
|
98
|
+
// ──────────────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
async function removeGlobal() {
|
|
101
|
+
console.log(chalk.yellow('\nThis will uninstall ai-flow-kit globally from your system.'));
|
|
102
|
+
console.log(chalk.gray('Project files (.aiflow/, .claude/, .rules/) are NOT affected.\n'));
|
|
103
|
+
|
|
104
|
+
const ok = await confirm({ message: 'Uninstall global package?' });
|
|
105
|
+
if (!ok) {
|
|
106
|
+
console.log(chalk.gray('Cancelled.'));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const { execSync } = require('child_process');
|
|
111
|
+
try {
|
|
112
|
+
console.log(chalk.blue('Running: npm uninstall -g ai-flow-kit ...'));
|
|
113
|
+
execSync('npm uninstall -g ai-flow-kit', { stdio: 'inherit' });
|
|
114
|
+
console.log(chalk.green('\n✨ ai-flow-kit uninstalled globally.'));
|
|
115
|
+
console.log(chalk.gray('The `aiflow` command is no longer available.'));
|
|
116
|
+
} catch (err) {
|
|
117
|
+
// execSync throws on non-zero exit; message already printed via stdio: inherit
|
|
118
|
+
console.log(chalk.red('\nFailed to uninstall. Try manually: npm uninstall -g ai-flow-kit'));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ──────────────────────────────────────────────────────────────
|
|
123
|
+
// Case 3: Remove a specific cached version from .aiflow/versions/
|
|
124
|
+
// ──────────────────────────────────────────────────────────────
|
|
125
|
+
|
|
126
|
+
async function removeVersion(version) {
|
|
127
|
+
if (!(await fs.pathExists(STATE_FILE))) {
|
|
128
|
+
console.log(chalk.red('Project is not initialized. Run `aiflow init` first.'));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const versionsDir = path.join(AIFLOW_DIR, 'versions');
|
|
133
|
+
const targetDir = path.join(versionsDir, version);
|
|
134
|
+
|
|
135
|
+
if (!(await fs.pathExists(targetDir))) {
|
|
136
|
+
console.log(chalk.red(`Version v${version} is not cached in this project.`));
|
|
137
|
+
|
|
138
|
+
// Show what's available
|
|
139
|
+
if (await fs.pathExists(versionsDir)) {
|
|
140
|
+
const available = await fs.readdir(versionsDir);
|
|
141
|
+
if (available.length) {
|
|
142
|
+
console.log(chalk.gray(`Cached versions: ${available.map(v => `v${v}`).join(', ')}`));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Prevent removing the currently active version
|
|
149
|
+
const state = await fs.readJson(STATE_FILE);
|
|
150
|
+
if (state.current_version === version) {
|
|
151
|
+
console.log(chalk.red(`v${version} is currently active — cannot remove it.`));
|
|
152
|
+
console.log(chalk.gray('Switch to another version first: aiflow use <version>'));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const ok = await confirm({ message: `Delete cached version v${version}?` });
|
|
157
|
+
if (!ok) {
|
|
158
|
+
console.log(chalk.gray('Cancelled.'));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await fs.remove(targetDir);
|
|
163
|
+
console.log(chalk.green(`✓ Removed cached version v${version}.`));
|
|
164
|
+
|
|
165
|
+
// Show remaining versions
|
|
166
|
+
const remaining = await fs.readdir(versionsDir).catch(() => []);
|
|
167
|
+
if (remaining.length) {
|
|
168
|
+
console.log(chalk.gray(`Remaining: ${remaining.map(v => `v${v}`).join(', ')}`));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { confirm, select } = require('@inquirer/prompts');
|
|
5
|
+
|
|
6
|
+
const PKG_DIR = path.join(__dirname, '..');
|
|
7
|
+
const PKG_VERSION = require('../package.json').version;
|
|
8
|
+
|
|
9
|
+
// Same language map as init.js
|
|
10
|
+
const FRAMEWORK_LANGUAGE = {
|
|
11
|
+
'laravel': 'php',
|
|
12
|
+
'spring-boot': 'java',
|
|
13
|
+
'reactjs': 'javascript',
|
|
14
|
+
'nextjs': 'javascript',
|
|
15
|
+
'vue-nuxt': 'javascript',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = async function update(options = {}) {
|
|
19
|
+
const projectDir = process.cwd();
|
|
20
|
+
const aiflowDir = path.join(projectDir, '.aiflow');
|
|
21
|
+
const stateFile = path.join(aiflowDir, 'state.json');
|
|
22
|
+
|
|
23
|
+
if (!(await fs.pathExists(stateFile))) {
|
|
24
|
+
console.log(chalk.red('Project is not initialized. Please run `aiflow init` first.'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const state = await fs.readJson(stateFile);
|
|
29
|
+
const currentVersion = state.current_version;
|
|
30
|
+
|
|
31
|
+
if (currentVersion === PKG_VERSION && !options.force) {
|
|
32
|
+
console.log(chalk.green(`Already on v${PKG_VERSION}. Use --force to re-copy assets anyway.`));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(chalk.blue(`Updating from v${currentVersion} to v${PKG_VERSION}...`));
|
|
37
|
+
|
|
38
|
+
const newVersionDir = path.join(aiflowDir, 'versions', PKG_VERSION);
|
|
39
|
+
await fs.ensureDir(newVersionDir);
|
|
40
|
+
|
|
41
|
+
// Merge skills
|
|
42
|
+
const upstreamSkills = path.join(PKG_DIR, 'upstream', 'skills');
|
|
43
|
+
const customSkills = path.join(PKG_DIR, 'custom', 'skills');
|
|
44
|
+
|
|
45
|
+
await fs.ensureDir(path.join(newVersionDir, 'skills'));
|
|
46
|
+
if (await fs.pathExists(upstreamSkills)) {
|
|
47
|
+
await fs.copy(upstreamSkills, path.join(newVersionDir, 'skills'), { overwrite: true });
|
|
48
|
+
}
|
|
49
|
+
if (await fs.pathExists(customSkills)) {
|
|
50
|
+
await fs.copy(customSkills, path.join(newVersionDir, 'skills'), { overwrite: true });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Copy rules: common first, then language-specific overlay (mirrors init.js logic)
|
|
54
|
+
const rulesTarget = path.join(newVersionDir, 'rules');
|
|
55
|
+
const commonRules = path.join(PKG_DIR, 'custom', 'rules', 'common');
|
|
56
|
+
const allRules = path.join(PKG_DIR, 'custom', 'rules');
|
|
57
|
+
const primaryFramework = (state.frameworks || [])[0] || null;
|
|
58
|
+
|
|
59
|
+
await fs.ensureDir(rulesTarget);
|
|
60
|
+
if (await fs.pathExists(commonRules)) {
|
|
61
|
+
await fs.copy(commonRules, rulesTarget, { overwrite: true });
|
|
62
|
+
} else if (await fs.pathExists(allRules)) {
|
|
63
|
+
const entries = await fs.readdir(allRules, { withFileTypes: true });
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
66
|
+
await fs.copy(path.join(allRules, entry.name), path.join(rulesTarget, entry.name), { overwrite: true });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (primaryFramework) {
|
|
72
|
+
const lang = FRAMEWORK_LANGUAGE[primaryFramework];
|
|
73
|
+
if (lang) {
|
|
74
|
+
const langRules = path.join(PKG_DIR, 'custom', 'rules', lang);
|
|
75
|
+
if (await fs.pathExists(langRules)) {
|
|
76
|
+
await fs.copy(langRules, rulesTarget, { overwrite: true });
|
|
77
|
+
console.log(chalk.gray(` ✓ Applied ${lang} rules`));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log(chalk.green(`✓ Downloaded assets for v${PKG_VERSION} into the project.`));
|
|
83
|
+
|
|
84
|
+
// Only offer to delete old version when it's a different version.
|
|
85
|
+
// When --force re-copies the same version, old === new === newVersionDir,
|
|
86
|
+
// so deleting "old" would immediately break the copy step below.
|
|
87
|
+
const isSameVersion = currentVersion === PKG_VERSION;
|
|
88
|
+
if (!isSameVersion) {
|
|
89
|
+
const deleteOld = await confirm({ message: `Do you want to delete the old version (v${currentVersion})?` });
|
|
90
|
+
if (deleteOld) {
|
|
91
|
+
await fs.remove(path.join(aiflowDir, 'versions', currentVersion));
|
|
92
|
+
console.log(chalk.gray(`Deleted v${currentVersion}.`));
|
|
93
|
+
} else {
|
|
94
|
+
console.log(chalk.gray(`Kept v${currentVersion}. You can switch back using 'aiflow use ${currentVersion}'.`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Switch to new version
|
|
99
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
100
|
+
await fs.emptyDir(claudeDir);
|
|
101
|
+
await fs.copy(path.join(newVersionDir, 'skills'), path.join(claudeDir, 'skills'), { overwrite: true });
|
|
102
|
+
|
|
103
|
+
const rulesDir = path.join(projectDir, '.rules');
|
|
104
|
+
await fs.emptyDir(rulesDir);
|
|
105
|
+
await fs.copy(path.join(newVersionDir, 'rules'), rulesDir, { overwrite: true });
|
|
106
|
+
|
|
107
|
+
state.current_version = PKG_VERSION;
|
|
108
|
+
await fs.writeJson(stateFile, state);
|
|
109
|
+
|
|
110
|
+
console.log(chalk.green(`\n✨ Update completed! Your project is now on v${PKG_VERSION}.`));
|
|
111
|
+
};
|