brain-dev 0.1.1 → 0.1.2

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.
@@ -162,6 +162,10 @@ async function main() {
162
162
  await require('./lib/commands/config.cjs').run(args.slice(1), path.join(process.cwd(), '.brain'));
163
163
  break;
164
164
 
165
+ case 'update':
166
+ await require('./lib/commands/update.cjs').run(args.slice(1));
167
+ break;
168
+
165
169
  case 'health':
166
170
  await require('./lib/commands/health.cjs').run(args.slice(1));
167
171
  break;
@@ -0,0 +1,148 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const { readState, writeState, migrateState } = require('../state.cjs');
6
+ const { detectPlatform } = require('../platform.cjs');
7
+ const { packagePath, registerClaudeHooks, registerAgents, registerCommands, cleanupLegacySkills } = require('../init.cjs');
8
+ const { output, error, success, prefix } = require('../core.cjs');
9
+
10
+ /**
11
+ * Copy hook scripts from package to .brain/hooks/.
12
+ * Preserves executable permissions.
13
+ * @param {string} brainDir
14
+ */
15
+ function copyHooks(brainDir) {
16
+ const hooksDir = path.join(brainDir, 'hooks');
17
+ fs.mkdirSync(hooksDir, { recursive: true });
18
+
19
+ const hookFiles = ['bootstrap.sh', 'statusline.sh', 'post-tool-use.sh'];
20
+ for (const file of hookFiles) {
21
+ const src = packagePath('hooks', file);
22
+ if (fs.existsSync(src)) {
23
+ const dest = path.join(hooksDir, file);
24
+ fs.copyFileSync(src, dest);
25
+ try { fs.chmodSync(dest, 0o755); } catch { /* skip on unsupported FS */ }
26
+ }
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Update .brain/.gitignore with current patterns.
32
+ * @param {string} brainDir
33
+ */
34
+ function updateGitignore(brainDir) {
35
+ const content = [
36
+ '*.tmp',
37
+ '*.lock',
38
+ 'storm/fragments/',
39
+ 'storm/events.jsonl',
40
+ ''
41
+ ].join('\n');
42
+ fs.writeFileSync(path.join(brainDir, '.gitignore'), content, 'utf8');
43
+ }
44
+
45
+ /**
46
+ * Run the update command.
47
+ * Updates tool files (hooks, agents, commands) while preserving project state.
48
+ *
49
+ * brain-dev update → Update tool files + migrate state
50
+ * brain-dev update --check → Only check version, don't update
51
+ *
52
+ * @param {string[]} args
53
+ * @param {object} [opts]
54
+ */
55
+ async function run(args = [], opts = {}) {
56
+ const brainDir = opts.brainDir || path.join(process.cwd(), '.brain');
57
+ const cwd = opts.cwd || process.cwd();
58
+
59
+ // 1. Validate .brain/ exists
60
+ if (!fs.existsSync(brainDir)) {
61
+ error("No brain project found. Run 'npx brain-dev init' first.");
62
+ return { error: 'no-project' };
63
+ }
64
+
65
+ // 2. Read current state
66
+ const state = readState(brainDir);
67
+ if (!state) {
68
+ error("Corrupted brain.json. Run 'npx brain-dev init --force' to reset.");
69
+ return { error: 'corrupted-state' };
70
+ }
71
+
72
+ // 3. Get versions
73
+ const installedVersion = state.version || '0.0.0';
74
+ const packageVersion = require(path.join(__dirname, '..', '..', '..', 'package.json')).version;
75
+
76
+ // --check mode
77
+ if (args.includes('--check')) {
78
+ const upToDate = installedVersion === packageVersion;
79
+ const msg = upToDate
80
+ ? `brain-dev v${installedVersion} is up to date.`
81
+ : `Update available: v${installedVersion} → v${packageVersion}. Run: npx brain-dev update`;
82
+
83
+ output({
84
+ action: 'version-check',
85
+ installed: installedVersion,
86
+ package: packageVersion,
87
+ upToDate
88
+ }, prefix(msg));
89
+
90
+ return { action: 'version-check', installed: installedVersion, package: packageVersion, upToDate };
91
+ }
92
+
93
+ // 4. Backup state before update
94
+ const backupPath = path.join(brainDir, 'brain.json.pre-update');
95
+ try {
96
+ fs.copyFileSync(path.join(brainDir, 'brain.json'), backupPath);
97
+ } catch (e) {
98
+ error(`Could not backup brain.json: ${e.message}`);
99
+ return { error: 'backup-failed' };
100
+ }
101
+
102
+ // 5. Ensure required directories exist
103
+ const requiredDirs = ['hooks', 'debug', 'specs', 'codebase'];
104
+ for (const dir of requiredDirs) {
105
+ fs.mkdirSync(path.join(brainDir, dir), { recursive: true });
106
+ }
107
+
108
+ // 6. Update hook scripts
109
+ copyHooks(brainDir);
110
+
111
+ // 7. Platform-specific updates
112
+ const platform = detectPlatform({ cwd });
113
+ if (platform === 'claude-code') {
114
+ registerClaudeHooks(cwd);
115
+ cleanupLegacySkills(cwd);
116
+ registerCommands(cwd);
117
+ registerAgents(cwd);
118
+ }
119
+
120
+ // 8. Migrate state (adds new fields, preserves all existing data)
121
+ const migrated = migrateState(state);
122
+ writeState(brainDir, migrated);
123
+
124
+ // 9. Update .gitignore
125
+ updateGitignore(brainDir);
126
+
127
+ // 10. Report
128
+ const isUpgrade = installedVersion !== packageVersion;
129
+ const msg = isUpgrade
130
+ ? `Updated brain-dev v${installedVersion} → v${packageVersion}. State preserved. Backup: brain.json.pre-update`
131
+ : `brain-dev v${packageVersion} tool files refreshed. State preserved.`;
132
+
133
+ success(msg);
134
+
135
+ const result = {
136
+ action: 'updated',
137
+ from: installedVersion,
138
+ to: packageVersion,
139
+ backup: backupPath,
140
+ statePreserved: true,
141
+ nextAction: '/brain:progress'
142
+ };
143
+
144
+ output(result, '');
145
+ return result;
146
+ }
147
+
148
+ module.exports = { run };
@@ -180,6 +180,15 @@ const COMMANDS = [
180
180
  },
181
181
 
182
182
  // Meta
183
+ {
184
+ name: 'update',
185
+ description: 'Update tool files while preserving project state',
186
+ usage: 'brain-dev update [--check]',
187
+ group: 'Meta',
188
+ implemented: true,
189
+ needsState: false,
190
+ args: ' --check Only check for new version, don\'t update'
191
+ },
183
192
  {
184
193
  name: 'health',
185
194
  description: 'Run health diagnostics and auto-repair safe issues',
package/bin/lib/init.cjs CHANGED
@@ -307,4 +307,4 @@ async function run(args = []) {
307
307
  console.log(prefix('Next: /brain:new-project to start planning'));
308
308
  }
309
309
 
310
- module.exports = { run };
310
+ module.exports = { run, packagePath, registerClaudeHooks, registerAgents, registerCommands, cleanupLegacySkills };
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: brain:update
3
+ description: Update brain tool files while preserving project state
4
+ allowed-tools:
5
+ - Read
6
+ - Bash
7
+ ---
8
+ <objective>
9
+ Update brain's hooks, agents, and commands to the latest version without losing project state (brain.json, phases, roadmap, etc.).
10
+ </objective>
11
+
12
+ <process>
13
+ 1. Run: `npx brain-dev@latest update`
14
+ 2. Brain will:
15
+ - Backup brain.json to brain.json.pre-update
16
+ - Update hook scripts (.brain/hooks/)
17
+ - Update agent definitions (.claude/agents/)
18
+ - Update command files (.claude/commands/brain/)
19
+ - Migrate brain.json schema (add new fields, preserve existing)
20
+ - Regenerate STATE.md
21
+ 3. All project data is preserved: phases, plans, roadmap, research, quick tasks.
22
+ </process>
@@ -34,7 +34,7 @@ try {
34
34
  'Phase: ' + (data.phase && data.phase.current || 0) + ' (' + (data.phase && data.phase.status || 'initialized') + ')',
35
35
  'Next: ' + (data.nextAction || '/brain:new-project'),
36
36
  '',
37
- 'Commands: /brain:new-project, /brain:discuss, /brain:plan, /brain:execute, /brain:verify, /brain:complete, /brain:quick, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map',
37
+ 'Commands: /brain:new-project, /brain:discuss, /brain:plan, /brain:execute, /brain:verify, /brain:complete, /brain:quick, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:update, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map',
38
38
  '',
39
39
  'Instructions for Claude:',
40
40
  '- When user types /brain:<command>, run: npx brain-dev <command> [args]',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brain-dev",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "AI-powered development workflow orchestrator",
5
5
  "author": "halilcosdu",
6
6
  "license": "MIT",