agile-context-engineering 0.2.1 → 0.2.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/README.md CHANGED
@@ -124,6 +124,10 @@ npx agile-context-engineering --opencode --global # Crush (formerly OpenCode), g
124
124
  npx agile-context-engineering --all --global # All runtimes, global install
125
125
  ```
126
126
 
127
+ ### Updating
128
+
129
+ When a new version is available, your status bar will show a yellow `/ace:update` indicator. Run the `/ace:update` command inside Claude Code to update — it detects your install type (global/local, Claude/Crush) automatically and runs the correct installer.
130
+
127
131
  ### Prerequisites
128
132
 
129
133
  | Requirement | Purpose |
@@ -0,0 +1,207 @@
1
+ <workflow>
2
+
3
+ <purpose>
4
+ Check for ACE updates via npm, display version comparison, obtain user confirmation,
5
+ and execute clean installation with cache clearing.
6
+ </purpose>
7
+
8
+ <mandatory-context>
9
+ Read all files referenced by the invoking prompt's execution-context before starting.
10
+ </mandatory-context>
11
+
12
+ <process>
13
+
14
+ <!-- ══════════════════════════════════════════════════════════════════ -->
15
+ <!-- STEP 1: DETECT INSTALLATION -->
16
+ <!-- ══════════════════════════════════════════════════════════════════ -->
17
+
18
+ <step name="detect-installation" order="1">
19
+ Detect whether ACE is installed locally or globally, and for which runtime.
20
+
21
+ ```bash
22
+ if [ -f "./.claude/agile-context-engineering/VERSION" ]; then
23
+ echo "SCOPE=local"
24
+ echo "RUNTIME=claude"
25
+ echo "VERSION=$(cat ./.claude/agile-context-engineering/VERSION)"
26
+ elif [ -f "$HOME/.claude/agile-context-engineering/VERSION" ]; then
27
+ echo "SCOPE=global"
28
+ echo "RUNTIME=claude"
29
+ echo "VERSION=$(cat $HOME/.claude/agile-context-engineering/VERSION)"
30
+ elif [ -f "./.opencode/agile-context-engineering/VERSION" ]; then
31
+ echo "SCOPE=local"
32
+ echo "RUNTIME=opencode"
33
+ echo "VERSION=$(cat ./.opencode/agile-context-engineering/VERSION)"
34
+ elif [ -f "$HOME/.opencode/agile-context-engineering/VERSION" ]; then
35
+ echo "SCOPE=global"
36
+ echo "RUNTIME=opencode"
37
+ echo "VERSION=$(cat $HOME/.opencode/agile-context-engineering/VERSION)"
38
+ else
39
+ echo "SCOPE=unknown"
40
+ echo "RUNTIME=claude"
41
+ echo "VERSION=0.0.0"
42
+ fi
43
+ ```
44
+
45
+ Parse SCOPE, RUNTIME, and VERSION from the output.
46
+
47
+ **If SCOPE is "unknown":**
48
+ ```
49
+ ## ACE Update
50
+
51
+ **Installed version:** Unknown
52
+
53
+ Your installation doesn't include version tracking.
54
+ Running fresh install...
55
+ ```
56
+
57
+ Proceed with VERSION=0.0.0.
58
+ </step>
59
+
60
+ <!-- ══════════════════════════════════════════════════════════════════ -->
61
+ <!-- STEP 2: CHECK LATEST VERSION -->
62
+ <!-- ══════════════════════════════════════════════════════════════════ -->
63
+
64
+ <step name="check-latest-version" order="2">
65
+ Check npm for the latest published version:
66
+
67
+ ```bash
68
+ npm view agile-context-engineering version 2>/dev/null
69
+ ```
70
+
71
+ **If npm check fails:**
72
+ ```
73
+ Couldn't check for updates (offline or npm unavailable).
74
+
75
+ To update manually: `npx agile-context-engineering --claude --global`
76
+ ```
77
+ Exit.
78
+ </step>
79
+
80
+ <!-- ══════════════════════════════════════════════════════════════════ -->
81
+ <!-- STEP 3: COMPARE VERSIONS -->
82
+ <!-- ══════════════════════════════════════════════════════════════════ -->
83
+
84
+ <step name="compare-versions" order="3">
85
+ Compare installed vs latest.
86
+
87
+ **If installed == latest:**
88
+ ```
89
+ ## ACE Update
90
+
91
+ **Installed:** X.Y.Z
92
+ **Latest:** X.Y.Z
93
+
94
+ You're already on the latest version.
95
+ ```
96
+ Exit.
97
+
98
+ **If installed > latest:**
99
+ ```
100
+ ## ACE Update
101
+
102
+ **Installed:** X.Y.Z
103
+ **Latest:** A.B.C
104
+
105
+ You're ahead of the latest release (development version?).
106
+ ```
107
+ Exit.
108
+ </step>
109
+
110
+ <!-- ══════════════════════════════════════════════════════════════════ -->
111
+ <!-- STEP 4: CONFIRM UPDATE -->
112
+ <!-- ══════════════════════════════════════════════════════════════════ -->
113
+
114
+ <step name="confirm-update" order="4">
115
+ If update is available, show what will happen and ask for confirmation:
116
+
117
+ ```
118
+ ## ACE Update Available
119
+
120
+ **Installed:** {installed_version}
121
+ **Latest:** {latest_version}
122
+
123
+ The installer performs a clean install of ACE folders:
124
+ - `commands/ace/` will be wiped and replaced
125
+ - `agile-context-engineering/` will be wiped and replaced
126
+ - `agents/ace-*` files will be replaced
127
+
128
+ Your custom files are preserved:
129
+ - Custom commands not in `commands/ace/`
130
+ - Custom agents not prefixed with `ace-`
131
+ - Your CLAUDE.md files
132
+ - Your .ace/ project artifacts
133
+ ```
134
+
135
+ Use AskUserQuestion:
136
+ - Question: "Proceed with update?"
137
+ - Options:
138
+ - "Yes, update now"
139
+ - "No, cancel"
140
+
141
+ **If user cancels:** Exit.
142
+ </step>
143
+
144
+ <!-- ══════════════════════════════════════════════════════════════════ -->
145
+ <!-- STEP 5: RUN UPDATE -->
146
+ <!-- ══════════════════════════════════════════════════════════════════ -->
147
+
148
+ <step name="run-update" order="5">
149
+ Run the update using detected SCOPE and RUNTIME from step 1.
150
+
151
+ Build the command: `npx agile-context-engineering --{RUNTIME} --{SCOPE}`
152
+
153
+ Examples:
154
+ - Global Claude: `npx agile-context-engineering --claude --global`
155
+ - Local Claude: `npx agile-context-engineering --claude --local`
156
+ - Global Crush: `npx agile-context-engineering --opencode --global`
157
+ - Local Crush: `npx agile-context-engineering --opencode --local`
158
+
159
+ If SCOPE was "unknown", default to `--claude --global`.
160
+
161
+ Capture output. If install fails, show error and exit.
162
+
163
+ Clear the update cache so statusline indicator disappears:
164
+
165
+ **If SCOPE is "local":**
166
+ ```bash
167
+ rm -f ./.claude/cache/ace-update-check.json
168
+ ```
169
+
170
+ **If SCOPE is "global":**
171
+ ```bash
172
+ rm -f "$HOME/.claude/cache/ace-update-check.json"
173
+ ```
174
+
175
+ For Crush runtime, substitute `.opencode` for `.claude` in the cache path.
176
+ </step>
177
+
178
+ <!-- ══════════════════════════════════════════════════════════════════ -->
179
+ <!-- STEP 6: DISPLAY RESULT -->
180
+ <!-- ══════════════════════════════════════════════════════════════════ -->
181
+
182
+ <step name="display-result" order="6">
183
+ Format completion message:
184
+
185
+ ```
186
+ ============================================================
187
+ ACE Updated: v{old} -> v{new}
188
+ ============================================================
189
+
190
+ Restart Claude Code to pick up the new commands.
191
+ ```
192
+ </step>
193
+
194
+ </process>
195
+
196
+ <success_criteria>
197
+ <check>Installed version detected correctly (local/global, claude/crush)</check>
198
+ <check>Latest version checked via npm</check>
199
+ <check>Update skipped if already current</check>
200
+ <check>Clean install warning shown</check>
201
+ <check>User confirmation obtained before update</check>
202
+ <check>Update executed with correct --runtime and --scope flags</check>
203
+ <check>Update cache cleared</check>
204
+ <check>Restart reminder shown</check>
205
+ </success_criteria>
206
+
207
+ </workflow>
package/bin/install.js CHANGED
@@ -5,7 +5,7 @@ const path = require('path');
5
5
  const readline = require('readline');
6
6
  const os = require('os');
7
7
 
8
- const VERSION = '0.1.0';
8
+ const VERSION = require('../package.json').version;
9
9
 
10
10
  // ANSI color codes
11
11
  const colors = {
@@ -67,12 +67,31 @@ function parseArgs() {
67
67
  all: args.includes('--all'),
68
68
  global: args.includes('--global'),
69
69
  local: args.includes('--local'),
70
+ forceStatusline: args.includes('--force-statusline'),
70
71
  help: args.includes('--help') || args.includes('-h'),
71
72
  version: args.includes('--version') || args.includes('-v'),
72
73
  };
73
74
  return flags;
74
75
  }
75
76
 
77
+ // Read or create settings.json
78
+ function readSettings(settingsPath) {
79
+ if (fs.existsSync(settingsPath)) {
80
+ try {
81
+ return JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
82
+ } catch (e) {
83
+ return {};
84
+ }
85
+ }
86
+ return {};
87
+ }
88
+
89
+ // Build hook command with proper quoting for the target directory
90
+ function buildHookCommand(targetDir, hookFile) {
91
+ const hookPath = path.join(targetDir, 'hooks', hookFile);
92
+ return `node "${hookPath.replace(/\\/g, '/')}"`;
93
+ }
94
+
76
95
  function showHelp() {
77
96
  log(`
78
97
  Usage: npx agile-context-engineering [options]
@@ -82,9 +101,10 @@ Options:
82
101
  --opencode Install for Crush (formerly OpenCode)
83
102
  --all Install for all supported runtimes
84
103
  --global Install globally (~/.claude, ~/.opencode)
85
- --local Install locally (.claude, .opencode)
86
- -h, --help Show this help message
87
- -v, --version Show version number
104
+ --local Install locally (.claude, .opencode)
105
+ --force-statusline Replace existing statusline configuration
106
+ -h, --help Show this help message
107
+ -v, --version Show version number
88
108
 
89
109
  Examples:
90
110
  npx agile-context-engineering # Interactive installation
@@ -278,6 +298,26 @@ function installForRuntime(runtime, scope, packageDir) {
278
298
  log(` ✓ Tools installed`, colors.green);
279
299
  }
280
300
 
301
+ // Copy hooks
302
+ const srcHooks = path.join(packageDir, 'hooks');
303
+ const hooksPath = path.join(basePath, 'hooks');
304
+ if (fs.existsSync(srcHooks)) {
305
+ // Only copy ace-* hook files, preserve non-ACE hooks (e.g. GSD)
306
+ if (!fs.existsSync(hooksPath)) {
307
+ fs.mkdirSync(hooksPath, { recursive: true });
308
+ }
309
+ for (const f of fs.readdirSync(srcHooks)) {
310
+ if (f.startsWith('ace-')) {
311
+ fs.copyFileSync(path.join(srcHooks, f), path.join(hooksPath, f));
312
+ }
313
+ }
314
+ log(` ✓ Hooks installed`, colors.green);
315
+ }
316
+
317
+ // Write VERSION file for update checking
318
+ const versionFile = path.join(acePath, 'VERSION');
319
+ fs.writeFileSync(versionFile, VERSION, 'utf-8');
320
+
281
321
  return basePath;
282
322
  }
283
323
 
@@ -355,21 +395,92 @@ async function main() {
355
395
  installedPaths.push({ runtime, name: RUNTIMES[runtime].name, path: installedPath });
356
396
  }
357
397
 
398
+ // Configure hooks and statusline in settings.json (Claude Code only, not Crush)
399
+ for (const { runtime, path: basePath } of installedPaths) {
400
+ if (runtime !== 'claude') continue;
401
+
402
+ const settingsPath = path.join(basePath, 'settings.json');
403
+ const settings = readSettings(settingsPath);
404
+
405
+ const statuslineCommand = buildHookCommand(basePath, 'ace-statusline.js');
406
+ const updateCheckCommand = buildHookCommand(basePath, 'ace-check-update.js');
407
+
408
+ // Register SessionStart hook for background update checking
409
+ if (!settings.hooks) settings.hooks = {};
410
+ if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
411
+
412
+ const hasAceUpdateHook = settings.hooks.SessionStart.some(entry =>
413
+ entry.hooks && entry.hooks.some(h => h.command && h.command.includes('ace-check-update'))
414
+ );
415
+ if (!hasAceUpdateHook) {
416
+ settings.hooks.SessionStart.push({
417
+ hooks: [{ type: 'command', command: updateCheckCommand }]
418
+ });
419
+ log(` ✓ Configured update check hook`, colors.green);
420
+ }
421
+
422
+ // Handle statusline configuration
423
+ const hasExisting = settings.statusLine != null;
424
+ const isAceStatusline = hasExisting && settings.statusLine.command &&
425
+ settings.statusLine.command.includes('ace-statusline');
426
+
427
+ if (!hasExisting || flags.forceStatusline) {
428
+ // No existing statusline or force flag — install ACE statusline
429
+ settings.statusLine = { type: 'command', command: statuslineCommand };
430
+ log(` ✓ Configured statusline`, colors.green);
431
+ } else if (isAceStatusline) {
432
+ // Already ACE statusline — update path
433
+ settings.statusLine = { type: 'command', command: statuslineCommand };
434
+ log(` ✓ Updated statusline`, colors.green);
435
+ } else if (isInteractive) {
436
+ // Existing non-ACE statusline in interactive mode — ask user
437
+ const existingCmd = settings.statusLine.command || settings.statusLine.url || '(custom)';
438
+ log(`\n ⚠ Existing statusline detected`, colors.yellow);
439
+ log(` Current: ${existingCmd}`, colors.dim);
440
+ log(`\n ACE statusline shows:`, colors.cyan);
441
+ log(` • Model name`, colors.dim);
442
+ log(` • Current task (from todo list)`, colors.dim);
443
+ log(` • Context window usage (color-coded)`, colors.dim);
444
+ log(` • Update notifications`, colors.dim);
445
+
446
+ const rl = createPrompt();
447
+ const choice = await ask(rl, '\n What would you like to do?', [
448
+ { label: 'Keep existing statusline', value: 'keep' },
449
+ { label: 'Replace with ACE statusline', value: 'replace' },
450
+ ]);
451
+ rl.close();
452
+
453
+ if (choice === 'replace') {
454
+ settings.statusLine = { type: 'command', command: statuslineCommand };
455
+ log(` ✓ Configured statusline`, colors.green);
456
+ } else {
457
+ log(` ⚠ Skipping statusline (kept existing)`, colors.yellow);
458
+ }
459
+ } else {
460
+ // Non-interactive with existing statusline — skip
461
+ log(` ⚠ Skipping statusline (already configured, use --force-statusline to replace)`, colors.yellow);
462
+ }
463
+
464
+ // Write settings
465
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
466
+ }
467
+
358
468
  // Show success message
359
469
  log(`\n${'═'.repeat(50)}`, colors.green);
360
470
  log(` ACE installed successfully!`, colors.green + colors.bright);
361
471
  log(`${'═'.repeat(50)}`, colors.green);
362
472
 
363
473
  log(`\nInstalled locations:`, colors.cyan);
364
- for (const { name, path: p } of installedPaths) {
365
- log(` ${name}: ${p}`, colors.dim);
474
+ for (const { name: runtimeName, path: p } of installedPaths) {
475
+ log(` ${runtimeName}: ${p}`, colors.dim);
366
476
  }
367
477
 
368
478
  log(`\nInstalled structure:`, colors.cyan);
369
- for (const { name, path: p } of installedPaths) {
479
+ for (const { path: p } of installedPaths) {
370
480
  log(` ${p}/`, colors.dim);
371
481
  log(` commands/ace/ Slash commands`, colors.dim);
372
482
  log(` agents/ Agent definitions`, colors.dim);
483
+ log(` hooks/ Statusline & update hooks`, colors.dim);
373
484
  log(` ${ACE_DIR_NAME}/`, colors.dim);
374
485
  log(` templates/ Project & artifact templates`, colors.dim);
375
486
  log(` utils/ Formatting & utility guides`, colors.dim);
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: ace:update
3
+ description: Update ACE to latest version
4
+ argument-hint: ""
5
+ allowed-tools:
6
+ - Bash
7
+ - AskUserQuestion
8
+ ---
9
+
10
+ ```xml
11
+ <command>
12
+
13
+ <execution-time>
14
+ <runs-after>
15
+ <trigger>When statusline shows the update indicator</trigger>
16
+ <trigger>When user wants to check for or install ACE updates</trigger>
17
+ </runs-after>
18
+ </execution-time>
19
+
20
+ <input>
21
+ <parameters>
22
+ <required></required>
23
+ <optional></optional>
24
+ </parameters>
25
+ </input>
26
+
27
+ <execution-context>
28
+ <update-workflow>@~/.claude/agile-context-engineering/workflows/update.xml</update-workflow>
29
+ <ui-formatting>@~/.claude/agile-context-engineering/utils/ui-formatting.md</ui-formatting>
30
+ </execution-context>
31
+
32
+ <output>
33
+ <objective>
34
+ Check for ACE updates, install if available.
35
+ Automatically detects local vs global installation and Claude vs Crush runtime.
36
+ </objective>
37
+ </output>
38
+
39
+ <process>
40
+ Execute the update workflow from
41
+ `@~/.claude/agile-context-engineering/workflows/update.xml` end-to-end.
42
+
43
+ The workflow handles all logic including:
44
+ 1. Installation detection (local/global, Claude/Crush)
45
+ 2. Latest version checking via npm
46
+ 3. Version comparison
47
+ 4. Clean install warning display
48
+ 5. User confirmation
49
+ 6. Update execution
50
+ 7. Cache clearing and restart reminder
51
+ </process>
52
+
53
+ </command>
54
+ ```
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ // Check for ACE updates in background, write result to cache
3
+ // Called by SessionStart hook - runs once per session
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+ const { spawn } = require('child_process');
9
+
10
+ const homeDir = os.homedir();
11
+ const cwd = process.cwd();
12
+ const cacheDir = path.join(homeDir, '.claude', 'cache');
13
+ const cacheFile = path.join(cacheDir, 'ace-update-check.json');
14
+
15
+ // VERSION file locations (check project first, then global)
16
+ const projectVersionFile = path.join(cwd, '.claude', 'agile-context-engineering', 'VERSION');
17
+ const globalVersionFile = path.join(homeDir, '.claude', 'agile-context-engineering', 'VERSION');
18
+
19
+ // Ensure cache directory exists
20
+ if (!fs.existsSync(cacheDir)) {
21
+ fs.mkdirSync(cacheDir, { recursive: true });
22
+ }
23
+
24
+ // Run check in background (spawn detached process, windowsHide prevents console flash)
25
+ const child = spawn(process.execPath, ['-e', `
26
+ const fs = require('fs');
27
+ const { execSync } = require('child_process');
28
+
29
+ const cacheFile = ${JSON.stringify(cacheFile)};
30
+ const projectVersionFile = ${JSON.stringify(projectVersionFile)};
31
+ const globalVersionFile = ${JSON.stringify(globalVersionFile)};
32
+
33
+ // Check project directory first (local install), then global
34
+ let installed = '0.0.0';
35
+ try {
36
+ if (fs.existsSync(projectVersionFile)) {
37
+ installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
38
+ } else if (fs.existsSync(globalVersionFile)) {
39
+ installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
40
+ }
41
+ } catch (e) {}
42
+
43
+ let latest = null;
44
+ try {
45
+ latest = execSync('npm view agile-context-engineering version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
46
+ } catch (e) {}
47
+
48
+ const result = {
49
+ update_available: latest && installed !== latest,
50
+ installed,
51
+ latest: latest || 'unknown',
52
+ checked: Math.floor(Date.now() / 1000)
53
+ };
54
+
55
+ fs.writeFileSync(cacheFile, JSON.stringify(result));
56
+ `], {
57
+ stdio: 'ignore',
58
+ windowsHide: true,
59
+ detached: true
60
+ });
61
+
62
+ child.unref();
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code Statusline - ACE Edition
3
+ // Shows: update indicator | model | current task | directory | context usage
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+
9
+ // Read JSON from stdin
10
+ let input = '';
11
+ process.stdin.setEncoding('utf8');
12
+ process.stdin.on('data', chunk => input += chunk);
13
+ process.stdin.on('end', () => {
14
+ try {
15
+ const data = JSON.parse(input);
16
+ const model = data.model?.display_name || 'Claude';
17
+ const dir = data.workspace?.current_dir || process.cwd();
18
+ const session = data.session_id || '';
19
+ const remaining = data.context_window?.remaining_percentage;
20
+
21
+ // Context window display (shows USED percentage scaled to 80% limit)
22
+ // Claude Code enforces an 80% context limit, so we scale to show 100% at that point
23
+ let ctx = '';
24
+ if (remaining != null) {
25
+ const rem = Math.round(remaining);
26
+ const rawUsed = Math.max(0, Math.min(100, 100 - rem));
27
+ // Scale: 80% real usage = 100% displayed
28
+ const used = Math.min(100, Math.round((rawUsed / 80) * 100));
29
+
30
+ // Build progress bar (10 segments)
31
+ const filled = Math.floor(used / 10);
32
+ const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(10 - filled);
33
+
34
+ // Color based on scaled usage
35
+ if (used < 63) {
36
+ ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
37
+ } else if (used < 81) {
38
+ ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
39
+ } else if (used < 95) {
40
+ ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
41
+ } else {
42
+ ctx = ` \x1b[5;31m\u{1F480} ${bar} ${used}%\x1b[0m`;
43
+ }
44
+ }
45
+
46
+ // Current task from todos
47
+ let task = '';
48
+ const homeDir = os.homedir();
49
+ const todosDir = path.join(homeDir, '.claude', 'todos');
50
+ if (session && fs.existsSync(todosDir)) {
51
+ try {
52
+ const files = fs.readdirSync(todosDir)
53
+ .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
54
+ .map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
55
+ .sort((a, b) => b.mtime - a.mtime);
56
+
57
+ if (files.length > 0) {
58
+ try {
59
+ const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
60
+ const inProgress = todos.find(t => t.status === 'in_progress');
61
+ if (inProgress) task = inProgress.activeForm || '';
62
+ } catch (e) {}
63
+ }
64
+ } catch (e) {}
65
+ }
66
+
67
+ // ACE update available?
68
+ let aceUpdate = '';
69
+ const cacheFile = path.join(homeDir, '.claude', 'cache', 'ace-update-check.json');
70
+ if (fs.existsSync(cacheFile)) {
71
+ try {
72
+ const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
73
+ if (cache.update_available) {
74
+ aceUpdate = '\x1b[33m\u2B06 /ace:update\x1b[0m \u2502 ';
75
+ }
76
+ } catch (e) {}
77
+ }
78
+
79
+ // Output
80
+ const dirname = path.basename(dir);
81
+ if (task) {
82
+ process.stdout.write(`${aceUpdate}\x1b[2m${model}\x1b[0m \u2502 \x1b[1m${task}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`);
83
+ } else {
84
+ process.stdout.write(`${aceUpdate}\x1b[2m${model}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`);
85
+ }
86
+ } catch (e) {
87
+ // Silent fail - don't break statusline on parse errors
88
+ }
89
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agile-context-engineering",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "ACE - Agile Context Engineering: A spec-driven development system for Claude Code and Crush (formerly OpenCode) with Agile workflows",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "bin",
12
12
  "commands",
13
13
  "agents",
14
+ "hooks",
14
15
  "agile-context-engineering"
15
16
  ],
16
17
  "scripts": {