devflow-agents 0.7.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.
Files changed (35) hide show
  1. package/.claude/commands/agents/architect.md +1162 -0
  2. package/.claude/commands/agents/architect.meta.yaml +124 -0
  3. package/.claude/commands/agents/builder.md +1432 -0
  4. package/.claude/commands/agents/builder.meta.yaml +117 -0
  5. package/.claude/commands/agents/chronicler.md +633 -0
  6. package/.claude/commands/agents/chronicler.meta.yaml +217 -0
  7. package/.claude/commands/agents/guardian.md +456 -0
  8. package/.claude/commands/agents/guardian.meta.yaml +127 -0
  9. package/.claude/commands/agents/strategist.md +483 -0
  10. package/.claude/commands/agents/strategist.meta.yaml +158 -0
  11. package/.claude/commands/agents/system-designer.md +1137 -0
  12. package/.claude/commands/agents/system-designer.meta.yaml +156 -0
  13. package/.claude/commands/devflow-help.md +93 -0
  14. package/.claude/commands/devflow-status.md +60 -0
  15. package/.claude/commands/quick/create-adr.md +82 -0
  16. package/.claude/commands/quick/new-feature.md +57 -0
  17. package/.claude/commands/quick/security-check.md +54 -0
  18. package/.claude/commands/quick/system-design.md +58 -0
  19. package/.claude_project +52 -0
  20. package/.devflow/agents/architect.meta.yaml +122 -0
  21. package/.devflow/agents/builder.meta.yaml +116 -0
  22. package/.devflow/agents/chronicler.meta.yaml +222 -0
  23. package/.devflow/agents/guardian.meta.yaml +127 -0
  24. package/.devflow/agents/strategist.meta.yaml +158 -0
  25. package/.devflow/agents/system-designer.meta.yaml +265 -0
  26. package/.devflow/project.yaml +242 -0
  27. package/.gitignore-template +83 -0
  28. package/LICENSE +21 -0
  29. package/README.md +244 -0
  30. package/bin/devflow.js +32 -0
  31. package/lib/constants.js +75 -0
  32. package/lib/init.js +162 -0
  33. package/lib/update.js +181 -0
  34. package/lib/utils.js +157 -0
  35. package/package.json +46 -0
package/lib/update.js ADDED
@@ -0,0 +1,181 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const {
4
+ VERSION,
5
+ PACKAGE_ROOT,
6
+ BASE_DIRS,
7
+ DOCS_DIRS,
8
+ GITKEEP_DIRS,
9
+ } = require('./constants');
10
+ const {
11
+ printHeader,
12
+ success,
13
+ error,
14
+ warn,
15
+ info,
16
+ printUpdateSuccess,
17
+ confirm,
18
+ copyDir,
19
+ copyFile,
20
+ ensureDirs,
21
+ createGitkeep,
22
+ pathExists,
23
+ resolveTarget,
24
+ } = require('./utils');
25
+
26
+ async function updateCommand(targetArg, options) {
27
+ printHeader(VERSION);
28
+
29
+ const targetDir = resolveTarget(targetArg);
30
+
31
+ // 1. Verify DevFlow is installed
32
+ const hasAgents = await pathExists(path.join(targetDir, '.claude', 'commands', 'agents'));
33
+ const hasDevflow = await pathExists(path.join(targetDir, '.devflow'));
34
+
35
+ if (!hasAgents && !hasDevflow) {
36
+ error(`DevFlow not found in: ${targetDir}`);
37
+ info('Use "devflow init" to install for the first time.');
38
+ process.exit(1);
39
+ }
40
+
41
+ // 2. Read installed version
42
+ let installedVersion = 'unknown';
43
+ const projectYamlPath = path.join(targetDir, '.devflow', 'project.yaml');
44
+ try {
45
+ const content = await fs.promises.readFile(projectYamlPath, 'utf8');
46
+ const match = content.match(/^\s*version:\s*"?([^"\s]+)"?/m);
47
+ if (match) installedVersion = match[1];
48
+ } catch { /* file may not exist */ }
49
+
50
+ info(`Project: ${targetDir}`);
51
+ info(`Installed version: ${installedVersion}`);
52
+ info(`New version: ${VERSION}`);
53
+ console.log();
54
+
55
+ // 3. Check if already up to date
56
+ if (installedVersion === VERSION) {
57
+ success('DevFlow is already up to date!');
58
+ return;
59
+ }
60
+
61
+ // 4. Confirm update
62
+ if (!options.force) {
63
+ warn('The update will overwrite agent files.');
64
+ warn('Customizations in .claude/commands/agents/ will be lost.');
65
+ console.log();
66
+ const shouldContinue = await confirm('Continue with update?');
67
+ if (!shouldContinue) {
68
+ warn('Update cancelled.');
69
+ return;
70
+ }
71
+ }
72
+
73
+ console.log();
74
+ info('Updating DevFlow...');
75
+ console.log();
76
+
77
+ // 5. Backup existing agents
78
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
79
+ const backupDir = path.join(targetDir, '.devflow', `backup-${timestamp}`);
80
+ await fs.promises.mkdir(backupDir, { recursive: true });
81
+
82
+ try {
83
+ await fs.promises.cp(
84
+ path.join(targetDir, '.claude', 'commands', 'agents'),
85
+ path.join(backupDir, 'agents'),
86
+ { recursive: true }
87
+ );
88
+ } catch { /* may not exist */ }
89
+
90
+ try {
91
+ await fs.promises.copyFile(
92
+ projectYamlPath,
93
+ path.join(backupDir, 'project.yaml')
94
+ );
95
+ } catch { /* may not exist */ }
96
+
97
+ success(`Backup created: .devflow/${path.basename(backupDir)}/`);
98
+
99
+ // 6. Update agents
100
+ console.log(' \u2192 Updating agents...');
101
+ await copyDir(
102
+ path.join(PACKAGE_ROOT, '.claude', 'commands', 'agents'),
103
+ path.join(targetDir, '.claude', 'commands', 'agents')
104
+ );
105
+ success('Agents updated (.claude/commands/agents/)');
106
+
107
+ // 7. Update quick commands
108
+ console.log(' \u2192 Updating quick commands...');
109
+ await copyDir(
110
+ path.join(PACKAGE_ROOT, '.claude', 'commands', 'quick'),
111
+ path.join(targetDir, '.claude', 'commands', 'quick')
112
+ );
113
+ success('Quick commands updated');
114
+
115
+ // 8. Update help & status commands
116
+ console.log(' \u2192 Updating help & status commands...');
117
+ for (const file of ['devflow-help.md', 'devflow-status.md']) {
118
+ try {
119
+ await copyFile(
120
+ path.join(PACKAGE_ROOT, '.claude', 'commands', file),
121
+ path.join(targetDir, '.claude', 'commands', file)
122
+ );
123
+ } catch { /* skip if missing */ }
124
+ }
125
+
126
+ // 9. Update .claude_project
127
+ console.log(' \u2192 Updating .claude_project...');
128
+ await copyFile(
129
+ path.join(PACKAGE_ROOT, '.claude_project'),
130
+ path.join(targetDir, '.claude_project')
131
+ );
132
+ success('.claude_project updated');
133
+
134
+ // 10. Update .devflow/agents/ meta.yaml files
135
+ console.log(' \u2192 Updating .devflow/agents/ meta.yaml files...');
136
+ await copyDir(
137
+ path.join(PACKAGE_ROOT, '.devflow', 'agents'),
138
+ path.join(targetDir, '.devflow', 'agents')
139
+ );
140
+ success('.devflow/agents/ updated');
141
+
142
+ // 11. Update project.yaml version
143
+ console.log(' \u2192 Updating project.yaml version...');
144
+ try {
145
+ let content = await fs.promises.readFile(projectYamlPath, 'utf8');
146
+ content = content.replace(
147
+ /version:\s*"?[^"\s]+"?/,
148
+ `version: "${VERSION}"`
149
+ );
150
+ await fs.promises.writeFile(projectYamlPath, content, 'utf8');
151
+ success(`project.yaml version updated to ${VERSION}`);
152
+ } catch {
153
+ await copyFile(
154
+ path.join(PACKAGE_ROOT, '.devflow', 'project.yaml'),
155
+ projectYamlPath
156
+ );
157
+ success('project.yaml created');
158
+ }
159
+
160
+ // 12. Ensure directory structure is complete
161
+ console.log(' \u2192 Verifying directory structure...');
162
+ await ensureDirs(targetDir, [...BASE_DIRS, ...DOCS_DIRS]);
163
+ await createGitkeep(targetDir, GITKEEP_DIRS);
164
+ success('Directory structure verified');
165
+
166
+ // 13. Success output
167
+ printUpdateSuccess(VERSION);
168
+ info('What was updated:');
169
+ console.log(' \u2022 Agents in .claude/commands/agents/');
170
+ console.log(' \u2022 Quick commands in .claude/commands/quick/');
171
+ console.log(' \u2022 .claude_project orchestration rules');
172
+ console.log(' \u2022 .devflow/agents/ meta.yaml files');
173
+ console.log(' \u2022 Directory structure');
174
+ console.log();
175
+ info(`Backup saved in: .devflow/${path.basename(backupDir)}/`);
176
+ console.log();
177
+ info('Tip: Use /agents:strategist to start a new feature');
178
+ console.log();
179
+ }
180
+
181
+ module.exports = { updateCommand };
package/lib/utils.js ADDED
@@ -0,0 +1,157 @@
1
+ const { execSync } = require('node:child_process');
2
+ const fs = require('node:fs');
3
+ const path = require('node:path');
4
+ const readline = require('node:readline');
5
+
6
+ // ANSI color helpers (no chalk dependency)
7
+ const c = {
8
+ red: (s) => `\x1b[0;31m${s}\x1b[0m`,
9
+ green: (s) => `\x1b[0;32m${s}\x1b[0m`,
10
+ yellow: (s) => `\x1b[1;33m${s}\x1b[0m`,
11
+ blue: (s) => `\x1b[0;34m${s}\x1b[0m`,
12
+ };
13
+
14
+ function printHeader(version) {
15
+ const line = c.blue('\u2501'.repeat(55));
16
+ console.log(line);
17
+ console.log(c.blue(` DevFlow CLI v${version}`));
18
+ console.log(line);
19
+ console.log();
20
+ }
21
+
22
+ function success(msg) { console.log(`${c.green('\u2713')} ${msg}`); }
23
+ function error(msg) { console.log(`${c.red('\u2717')} ${msg}`); }
24
+ function warn(msg) { console.log(`${c.yellow('\u26A0')} ${msg}`); }
25
+ function info(msg) { console.log(`${c.blue('\u2139')} ${msg}`); }
26
+
27
+ function printSuccess(version) {
28
+ const line = c.green('\u2501'.repeat(55));
29
+ console.log();
30
+ console.log(line);
31
+ console.log(c.green(` \u2713 DevFlow v${version} installed successfully!`));
32
+ console.log(line);
33
+ console.log();
34
+ }
35
+
36
+ function printUpdateSuccess(version) {
37
+ const line = c.green('\u2501'.repeat(55));
38
+ console.log();
39
+ console.log(line);
40
+ console.log(c.green(` \u2713 DevFlow updated to v${version}!`));
41
+ console.log(line);
42
+ console.log();
43
+ }
44
+
45
+ // Interactive y/N confirmation
46
+ function confirm(question) {
47
+ return new Promise((resolve) => {
48
+ const rl = readline.createInterface({
49
+ input: process.stdin,
50
+ output: process.stdout,
51
+ });
52
+ rl.question(`${question} (y/N) `, (answer) => {
53
+ rl.close();
54
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
55
+ });
56
+ });
57
+ }
58
+
59
+ // Check if a CLI command exists
60
+ function commandExists(cmd) {
61
+ try {
62
+ execSync(`command -v ${cmd}`, { stdio: 'ignore' });
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ // Check required/recommended dependencies
70
+ function checkDependencies() {
71
+ const platform = process.platform === 'darwin' ? 'macOS'
72
+ : process.platform === 'win32' ? 'Windows'
73
+ : 'Linux';
74
+ info(`System: ${platform}`);
75
+ console.log();
76
+
77
+ if (commandExists('claude')) {
78
+ success('Claude Code: installed');
79
+ } else {
80
+ warn('Claude Code: not found');
81
+ console.log(' Install: npm install -g @anthropic-ai/claude-code');
82
+ }
83
+
84
+ if (commandExists('git')) {
85
+ success('Git: installed');
86
+ } else {
87
+ warn('Git: not found (recommended)');
88
+ }
89
+
90
+ console.log();
91
+ }
92
+
93
+ // Copy directory recursively using Node 18+ fs.cp
94
+ async function copyDir(src, dest) {
95
+ await fs.promises.mkdir(path.dirname(dest), { recursive: true });
96
+ await fs.promises.cp(src, dest, { recursive: true, force: true });
97
+ }
98
+
99
+ // Copy single file, creating parent dirs as needed
100
+ async function copyFile(src, dest) {
101
+ await fs.promises.mkdir(path.dirname(dest), { recursive: true });
102
+ await fs.promises.copyFile(src, dest);
103
+ }
104
+
105
+ // Create multiple directories
106
+ async function ensureDirs(root, dirs) {
107
+ for (const dir of dirs) {
108
+ await fs.promises.mkdir(path.join(root, dir), { recursive: true });
109
+ }
110
+ }
111
+
112
+ // Create .gitkeep in directories that should be tracked but are empty
113
+ async function createGitkeep(root, dirs) {
114
+ for (const dir of dirs) {
115
+ const gitkeepPath = path.join(root, dir, '.gitkeep');
116
+ try {
117
+ await fs.promises.access(gitkeepPath);
118
+ } catch {
119
+ await fs.promises.writeFile(gitkeepPath, '');
120
+ }
121
+ }
122
+ }
123
+
124
+ // Check if a path exists
125
+ async function pathExists(p) {
126
+ try {
127
+ await fs.promises.access(p);
128
+ return true;
129
+ } catch {
130
+ return false;
131
+ }
132
+ }
133
+
134
+ // Resolve target path relative to cwd
135
+ function resolveTarget(targetArg) {
136
+ return path.resolve(process.cwd(), targetArg);
137
+ }
138
+
139
+ module.exports = {
140
+ c,
141
+ printHeader,
142
+ success,
143
+ error,
144
+ warn,
145
+ info,
146
+ printSuccess,
147
+ printUpdateSuccess,
148
+ confirm,
149
+ commandExists,
150
+ checkDependencies,
151
+ copyDir,
152
+ copyFile,
153
+ ensureDirs,
154
+ createGitkeep,
155
+ pathExists,
156
+ resolveTarget,
157
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "devflow-agents",
3
+ "version": "0.7.0",
4
+ "description": "Multi-agent system for software development with Claude Code. 6 specialized agents (Strategist, Architect, System Designer, Builder, Guardian, Chronicler) as slash commands.",
5
+ "keywords": [
6
+ "claude-code",
7
+ "ai-agents",
8
+ "multi-agent",
9
+ "devflow",
10
+ "claude",
11
+ "anthropic",
12
+ "software-development"
13
+ ],
14
+ "author": "Evolve Labs",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/evolve-labs-cloud/devflow.git"
19
+ },
20
+ "homepage": "https://github.com/evolve-labs-cloud/devflow",
21
+ "bin": {
22
+ "devflow": "bin/devflow.js"
23
+ },
24
+ "type": "commonjs",
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "files": [
29
+ "bin/",
30
+ "lib/",
31
+ ".claude/commands/",
32
+ ".claude_project",
33
+ ".devflow/agents/",
34
+ ".devflow/project.yaml",
35
+ ".gitignore-template",
36
+ "docs/decisions/000-template.md",
37
+ "LICENSE",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "commander": "^12.0.0"
42
+ },
43
+ "scripts": {
44
+ "prepublishOnly": "cp .gitignore .gitignore-template"
45
+ }
46
+ }