brain-dev 1.1.1 → 1.2.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/README.md +10 -0
- package/bin/brain-tools.cjs +6 -0
- package/bin/lib/commands/upgrade.cjs +48 -0
- package/bin/lib/commands.cjs +9 -0
- package/bin/lib/init.cjs +8 -0
- package/commands/brain/upgrade.md +20 -0
- package/hooks/bootstrap.sh +6 -1
- package/hooks/check-update.sh +37 -0
- package/hooks/statusline.sh +13 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -185,6 +185,16 @@ pending → discussing → discussed → planning → executing → executed →
|
|
|
185
185
|
|
|
186
186
|
Every command knows what comes next. `brain-dev progress` always tells you the right next step.
|
|
187
187
|
|
|
188
|
+
## Auto Update Notification
|
|
189
|
+
|
|
190
|
+
Brain checks for newer versions on session start (background, non-blocking). If an update is available, the statusline shows:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
⬆ /brain:upgrade | brain | [########--] 78% | P2: executing
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Type `/brain:upgrade` to see the upgrade command and clear the notification.
|
|
197
|
+
|
|
188
198
|
## Zero Dependencies
|
|
189
199
|
|
|
190
200
|
Brain is a single npm package with zero runtime dependencies. Just Node.js 22+.
|
package/bin/brain-tools.cjs
CHANGED
|
@@ -178,6 +178,12 @@ async function main() {
|
|
|
178
178
|
await require('./lib/commands/update.cjs').run(args.slice(1));
|
|
179
179
|
break;
|
|
180
180
|
|
|
181
|
+
case 'upgrade':
|
|
182
|
+
await require('./lib/commands/upgrade.cjs').run(args.slice(1), {
|
|
183
|
+
brainDir: path.join(process.cwd(), '.brain')
|
|
184
|
+
});
|
|
185
|
+
break;
|
|
186
|
+
|
|
181
187
|
case 'health':
|
|
182
188
|
await require('./lib/commands/health.cjs').run(args.slice(1));
|
|
183
189
|
break;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { output, prefix } = require('../core.cjs');
|
|
5
|
+
|
|
6
|
+
async function run(args = [], opts = {}) {
|
|
7
|
+
const brainDir = opts.brainDir || path.join(process.cwd(), '.brain');
|
|
8
|
+
|
|
9
|
+
// Read cache
|
|
10
|
+
const cachePath = path.join(brainDir, '.update-check.json');
|
|
11
|
+
let cache = null;
|
|
12
|
+
try {
|
|
13
|
+
cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
|
|
14
|
+
} catch {}
|
|
15
|
+
|
|
16
|
+
if (!cache || !cache.update_available) {
|
|
17
|
+
const lines = [
|
|
18
|
+
prefix('You are on the latest version.'),
|
|
19
|
+
prefix(`Installed: ${cache?.installed || 'unknown'}`)
|
|
20
|
+
];
|
|
21
|
+
output({ action: 'up-to-date', installed: cache?.installed || 'unknown' }, lines.join('\n'));
|
|
22
|
+
return { action: 'up-to-date' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Show upgrade info
|
|
26
|
+
const lines = [
|
|
27
|
+
prefix(`Update available: ${cache.installed} → ${cache.latest}`),
|
|
28
|
+
'',
|
|
29
|
+
prefix('To upgrade, run:'),
|
|
30
|
+
prefix(` npx brain-dev@${cache.latest} update`),
|
|
31
|
+
'',
|
|
32
|
+
prefix('Or update globally:'),
|
|
33
|
+
prefix(' npm install -g brain-dev@latest'),
|
|
34
|
+
'',
|
|
35
|
+
prefix('After updating, restart Claude Code to pick up new features.')
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
output({
|
|
39
|
+
action: 'upgrade-available',
|
|
40
|
+
installed: cache.installed,
|
|
41
|
+
latest: cache.latest,
|
|
42
|
+
command: `npx brain-dev@${cache.latest} update`
|
|
43
|
+
}, lines.join('\n'));
|
|
44
|
+
|
|
45
|
+
return { action: 'upgrade-available', installed: cache.installed, latest: cache.latest };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = { run };
|
package/bin/lib/commands.cjs
CHANGED
|
@@ -234,6 +234,15 @@ const COMMANDS = [
|
|
|
234
234
|
needsState: false,
|
|
235
235
|
args: ' --fix Enable aggressive repair of hooks and templates\n --quick Run safe checks only (used by bootstrap)\n --json Force JSON output'
|
|
236
236
|
},
|
|
237
|
+
{
|
|
238
|
+
name: 'upgrade',
|
|
239
|
+
description: 'Check and apply Brain updates',
|
|
240
|
+
usage: 'brain-dev upgrade',
|
|
241
|
+
group: 'Meta',
|
|
242
|
+
implemented: true,
|
|
243
|
+
needsState: false,
|
|
244
|
+
args: ''
|
|
245
|
+
},
|
|
237
246
|
{
|
|
238
247
|
name: 'version',
|
|
239
248
|
description: 'Show brain-dev version',
|
package/bin/lib/init.cjs
CHANGED
|
@@ -249,10 +249,18 @@ async function run(args = []) {
|
|
|
249
249
|
fs.chmodSync(path.join(brainDir, 'hooks', 'post-tool-use.sh'), 0o755);
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
+
// Copy update check hook
|
|
253
|
+
const checkUpdateSrc = packagePath('hooks', 'check-update.sh');
|
|
254
|
+
if (fs.existsSync(checkUpdateSrc)) {
|
|
255
|
+
fs.copyFileSync(checkUpdateSrc, path.join(brainDir, 'hooks', 'check-update.sh'));
|
|
256
|
+
fs.chmodSync(path.join(brainDir, 'hooks', 'check-update.sh'), 0o755);
|
|
257
|
+
}
|
|
258
|
+
|
|
252
259
|
// Write .gitignore
|
|
253
260
|
const gitignoreContent = [
|
|
254
261
|
'*.tmp',
|
|
255
262
|
'*.lock',
|
|
263
|
+
'.update-check.json',
|
|
256
264
|
'storm/fragments/',
|
|
257
265
|
'storm/events.jsonl',
|
|
258
266
|
''
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brain:upgrade
|
|
3
|
+
description: Check for and apply Brain updates
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Bash
|
|
7
|
+
---
|
|
8
|
+
<objective>
|
|
9
|
+
Check if a newer version of brain-dev is available and show upgrade instructions.
|
|
10
|
+
</objective>
|
|
11
|
+
|
|
12
|
+
<process>
|
|
13
|
+
1. Run: `npx brain-dev upgrade`
|
|
14
|
+
2. Brain will:
|
|
15
|
+
- Check the cached update status from `.brain/.update-check.json`
|
|
16
|
+
- Show current vs latest version if an update is available
|
|
17
|
+
- Provide the exact command to run for upgrading
|
|
18
|
+
- Clear the update notification from the statusline
|
|
19
|
+
3. If already up to date, confirms the current version.
|
|
20
|
+
</process>
|
package/hooks/bootstrap.sh
CHANGED
|
@@ -48,7 +48,7 @@ try {
|
|
|
48
48
|
'Phase: ' + (data.phase && data.phase.current || 0) + ' (' + (data.phase && data.phase.status || 'initialized') + ')',
|
|
49
49
|
'Next: ' + (data.nextAction || '/brain:new-project'),
|
|
50
50
|
'',
|
|
51
|
-
'Commands: /brain:new-project, /brain:story, /brain:discuss, /brain:plan, /brain:execute, /brain:verify, /brain:complete, /brain:quick, /brain:new-task, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:update, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map, /brain:recover, /brain:dashboard, /brain:auto (or execute --auto)',
|
|
51
|
+
'Commands: /brain:new-project, /brain:story, /brain:discuss, /brain:plan, /brain:execute, /brain:verify, /brain:complete, /brain:quick, /brain:new-task, /brain:progress, /brain:pause, /brain:resume, /brain:help, /brain:health, /brain:update, /brain:upgrade, /brain:storm, /brain:adr, /brain:phase, /brain:config, /brain:map, /brain:recover, /brain:dashboard, /brain:auto (or execute --auto)',
|
|
52
52
|
'',
|
|
53
53
|
'Instructions for Claude:',
|
|
54
54
|
'- When user types /brain:<command>, run: npx brain-dev <command> [args]',
|
|
@@ -66,3 +66,8 @@ try {
|
|
|
66
66
|
if [ -f "$BRAIN_DIR/brain.json" ]; then
|
|
67
67
|
npx brain-dev health --quick 2>/dev/null
|
|
68
68
|
fi
|
|
69
|
+
|
|
70
|
+
# Background update check (non-blocking)
|
|
71
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
72
|
+
bash "$SCRIPT_DIR/check-update.sh" "$BRAIN_DIR" &>/dev/null &
|
|
73
|
+
disown
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Background npm version check — writes result to .brain/.update-check.json
|
|
3
|
+
# Called by bootstrap.sh with & (background, non-blocking)
|
|
4
|
+
|
|
5
|
+
BRAIN_DIR="${1:-.brain}"
|
|
6
|
+
CACHE_FILE="$BRAIN_DIR/.update-check.json"
|
|
7
|
+
|
|
8
|
+
# Read installed version from package
|
|
9
|
+
INSTALLED=$(node -e "try{console.log(require('brain-dev/package.json').version)}catch{console.log('unknown')}" 2>/dev/null)
|
|
10
|
+
if [ "$INSTALLED" = "unknown" ] || [ -z "$INSTALLED" ]; then
|
|
11
|
+
INSTALLED=$(npx brain-dev version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Query npm for latest (10 second timeout)
|
|
15
|
+
LATEST=$(timeout 10 npm view brain-dev version 2>/dev/null)
|
|
16
|
+
|
|
17
|
+
if [ -z "$LATEST" ]; then
|
|
18
|
+
# npm unavailable or timeout — skip silently
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Trim whitespace to prevent false positives
|
|
23
|
+
INSTALLED=$(echo "$INSTALLED" | tr -d '[:space:]')
|
|
24
|
+
LATEST=$(echo "$LATEST" | tr -d '[:space:]')
|
|
25
|
+
|
|
26
|
+
# Write cache safely using node (prevents JSON injection from malformed version strings)
|
|
27
|
+
node -e "
|
|
28
|
+
const fs = require('fs');
|
|
29
|
+
const installed = process.argv[1];
|
|
30
|
+
const latest = process.argv[2];
|
|
31
|
+
fs.writeFileSync(process.argv[3], JSON.stringify({
|
|
32
|
+
update_available: installed !== latest,
|
|
33
|
+
installed: installed,
|
|
34
|
+
latest: latest,
|
|
35
|
+
checked: Math.floor(Date.now() / 1000)
|
|
36
|
+
}));
|
|
37
|
+
" "$INSTALLED" "$LATEST" "$CACHE_FILE"
|
package/hooks/statusline.sh
CHANGED
|
@@ -125,6 +125,18 @@ node -e "
|
|
|
125
125
|
phaseDisplay = ' | P' + phaseCurrent + (phaseStatus ? ': ' + phaseStatus : '');
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// Read update cache for upgrade notification
|
|
129
|
+
let updatePrefix = '';
|
|
130
|
+
try {
|
|
131
|
+
const cachePath = '$BRAIN_DIR/.update-check.json';
|
|
132
|
+
if (fs.existsSync(cachePath)) {
|
|
133
|
+
const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
|
|
134
|
+
if (cache.update_available === true) {
|
|
135
|
+
updatePrefix = '\x1b[33m\u2B06 /brain:upgrade\x1b[0m | ';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {}
|
|
139
|
+
|
|
128
140
|
// Output status line to stdout
|
|
129
|
-
process.stdout.write(projectName + phaseDisplay + ' | ' + bar);
|
|
141
|
+
process.stdout.write(updatePrefix + projectName + phaseDisplay + ' | ' + bar);
|
|
130
142
|
" "$input" 2>/dev/null || echo "brain | ---"
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brain-dev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "AI-powered development workflow orchestrator",
|
|
5
5
|
"author": "halilcosdu",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/halilcosdu/brain-dev"
|
|
9
|
+
"url": "git+https://github.com/halilcosdu/brain-dev.git"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://github.com/halilcosdu/brain-dev#readme",
|
|
12
12
|
"bugs": {
|