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.
- package/bin/brain-tools.cjs +4 -0
- package/bin/lib/commands/update.cjs +148 -0
- package/bin/lib/commands.cjs +9 -0
- package/bin/lib/init.cjs +1 -1
- package/commands/brain/update.md +22 -0
- package/hooks/bootstrap.sh +1 -1
- package/package.json +1 -1
package/bin/brain-tools.cjs
CHANGED
|
@@ -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 };
|
package/bin/lib/commands.cjs
CHANGED
|
@@ -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
|
@@ -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>
|
package/hooks/bootstrap.sh
CHANGED
|
@@ -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]',
|