agile-context-engineering 0.3.0 → 0.5.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 (147) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +51 -51
  3. package/README.md +332 -324
  4. package/agents/ace-product-owner.md +1 -1
  5. package/agents/ace-research-synthesizer.md +228 -228
  6. package/agents/ace-wiki-mapper.md +449 -445
  7. package/bin/install.js +60 -64
  8. package/hooks/ace-check-update.js +70 -62
  9. package/hooks/ace-statusline.js +89 -89
  10. package/package.json +5 -4
  11. package/shared/lib/ace-core.js +308 -0
  12. package/shared/lib/ace-core.test.js +308 -0
  13. package/shared/lib/ace-github.js +753 -0
  14. package/shared/lib/ace-story.js +400 -0
  15. package/shared/lib/ace-story.test.js +250 -0
  16. package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
  17. package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
  18. package/skills/execute-story/SKILL.md +110 -0
  19. package/skills/execute-story/script.js +305 -0
  20. package/skills/execute-story/script.test.js +261 -0
  21. package/skills/execute-story/walkthrough-template.xml +255 -0
  22. package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1219 -1219
  23. package/skills/help/SKILL.md +69 -0
  24. package/skills/help/script.js +318 -0
  25. package/skills/help/script.test.js +183 -0
  26. package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +540 -540
  27. package/skills/init-coding-standards/SKILL.md +72 -0
  28. package/skills/init-coding-standards/script.js +59 -0
  29. package/skills/init-coding-standards/script.test.js +70 -0
  30. package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
  31. package/skills/map-cross-cutting/SKILL.md +89 -0
  32. package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
  33. package/skills/map-cross-cutting/workflow.xml +330 -0
  34. package/skills/map-guide/SKILL.md +89 -0
  35. package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
  36. package/skills/map-guide/workflow.xml +320 -0
  37. package/skills/map-pattern/SKILL.md +89 -0
  38. package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
  39. package/skills/map-pattern/workflow.xml +331 -0
  40. package/skills/map-story/SKILL.md +127 -0
  41. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
  42. package/skills/map-story/templates/guide.xml +137 -0
  43. package/skills/map-story/templates/pattern.xml +159 -0
  44. package/skills/map-story/templates/system-cross-cutting.xml +197 -0
  45. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
  46. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
  47. package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
  48. package/skills/map-subsystem/SKILL.md +111 -0
  49. package/skills/map-subsystem/script.js +60 -0
  50. package/skills/map-subsystem/script.test.js +68 -0
  51. package/skills/map-subsystem/templates/decizions.xml +115 -0
  52. package/skills/map-subsystem/templates/guide.xml +137 -0
  53. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
  54. package/skills/map-subsystem/templates/pattern.xml +159 -0
  55. package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
  56. package/skills/map-subsystem/templates/system.xml +381 -0
  57. package/skills/map-subsystem/templates/walkthrough.xml +255 -0
  58. package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +15 -20
  59. package/skills/map-sys-doc/SKILL.md +90 -0
  60. package/skills/map-sys-doc/system.xml +381 -0
  61. package/skills/map-sys-doc/workflow.xml +336 -0
  62. package/skills/map-system/SKILL.md +85 -0
  63. package/skills/map-system/script.js +84 -0
  64. package/skills/map-system/script.test.js +73 -0
  65. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
  66. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
  67. package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +11 -16
  68. package/skills/map-walkthrough/SKILL.md +92 -0
  69. package/skills/map-walkthrough/walkthrough.xml +255 -0
  70. package/skills/plan-backlog/SKILL.md +75 -0
  71. package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
  72. package/skills/plan-backlog/script.js +136 -0
  73. package/skills/plan-backlog/script.test.js +83 -0
  74. package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +13 -21
  75. package/skills/plan-feature/SKILL.md +76 -0
  76. package/skills/plan-feature/script.js +148 -0
  77. package/skills/plan-feature/script.test.js +80 -0
  78. package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
  79. package/skills/plan-product-vision/SKILL.md +75 -0
  80. package/skills/plan-product-vision/script.js +60 -0
  81. package/skills/plan-product-vision/script.test.js +69 -0
  82. package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +4 -9
  83. package/skills/plan-story/SKILL.md +116 -0
  84. package/skills/plan-story/script.js +326 -0
  85. package/skills/plan-story/script.test.js +240 -0
  86. package/skills/plan-story/story-template.xml +451 -0
  87. package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1285 -944
  88. package/skills/research-external-solution/SKILL.md +107 -0
  89. package/skills/research-external-solution/script.js +238 -0
  90. package/skills/research-external-solution/script.test.js +134 -0
  91. package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +4 -6
  92. package/skills/research-integration-solution/SKILL.md +98 -0
  93. package/skills/research-integration-solution/script.js +231 -0
  94. package/skills/research-integration-solution/script.test.js +134 -0
  95. package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +3 -5
  96. package/skills/research-story-wiki/SKILL.md +92 -0
  97. package/skills/research-story-wiki/script.js +231 -0
  98. package/skills/research-story-wiki/script.test.js +138 -0
  99. package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +3 -5
  100. package/skills/research-technical-solution/SKILL.md +103 -0
  101. package/skills/research-technical-solution/script.js +231 -0
  102. package/skills/research-technical-solution/script.test.js +134 -0
  103. package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +3 -5
  104. package/skills/review-story/SKILL.md +100 -0
  105. package/skills/review-story/script.js +257 -0
  106. package/skills/review-story/script.test.js +169 -0
  107. package/skills/review-story/story-template.xml +451 -0
  108. package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
  109. package/skills/update/SKILL.md +53 -0
  110. package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +12 -13
  111. package/agile-context-engineering/src/ace-tools.js +0 -2881
  112. package/agile-context-engineering/src/ace-tools.test.js +0 -1089
  113. package/agile-context-engineering/templates/_command.md +0 -54
  114. package/agile-context-engineering/templates/_workflow.xml +0 -17
  115. package/agile-context-engineering/templates/config.json +0 -0
  116. package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
  117. package/commands/ace/execute-story.md +0 -138
  118. package/commands/ace/help.md +0 -93
  119. package/commands/ace/init-coding-standards.md +0 -83
  120. package/commands/ace/map-story.md +0 -165
  121. package/commands/ace/map-subsystem.md +0 -140
  122. package/commands/ace/map-system.md +0 -92
  123. package/commands/ace/map-walkthrough.md +0 -127
  124. package/commands/ace/plan-backlog.md +0 -83
  125. package/commands/ace/plan-feature.md +0 -89
  126. package/commands/ace/plan-product-vision.md +0 -81
  127. package/commands/ace/plan-story.md +0 -159
  128. package/commands/ace/research-external-solution.md +0 -138
  129. package/commands/ace/research-integration-solution.md +0 -135
  130. package/commands/ace/research-story-wiki.md +0 -116
  131. package/commands/ace/research-technical-solution.md +0 -147
  132. package/commands/ace/review-story.md +0 -109
  133. package/commands/ace/update.md +0 -56
  134. /package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +0 -0
  135. /package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +0 -0
  136. /package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +0 -0
  137. /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +0 -0
  138. /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +0 -0
  139. /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +0 -0
  140. /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +0 -0
  141. /package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +0 -0
  142. /package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +0 -0
  143. /package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +0 -0
  144. /package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +0 -0
  145. /package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +0 -0
  146. /package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +0 -0
  147. /package/{agile-context-engineering/templates/product/story-technical-solution.xml → skills/research-technical-solution/technical-solution-template.xml} +0 -0
package/bin/install.js CHANGED
@@ -39,8 +39,8 @@ const RUNTIMES = {
39
39
  },
40
40
  };
41
41
 
42
- // The folder name installed inside the config directory (e.g. ~/.claude/agile-context-engineering/)
43
- const ACE_DIR_NAME = 'agile-context-engineering';
42
+ // Legacy folder name only used for cleanup of pre-plugin installations
43
+ const ACE_LEGACY_DIR_NAME = 'agile-context-engineering';
44
44
 
45
45
  function log(message, color = '') {
46
46
  console.log(`${color}${message}${colors.reset}`);
@@ -184,7 +184,7 @@ function getBasePath(runtime, scope) {
184
184
  }
185
185
 
186
186
  // File extensions that contain path references needing runtime transformation
187
- const TRANSFORMABLE_EXTENSIONS = new Set(['.md', '.xml']);
187
+ const TRANSFORMABLE_EXTENSIONS = new Set(['.md', '.xml', '.js']);
188
188
 
189
189
  // Transform file content for a target runtime (replaces .claude/ paths with target runtime paths)
190
190
  function transformForRuntime(content, runtime) {
@@ -225,77 +225,73 @@ function copyDir(src, dest, runtime) {
225
225
  function installForRuntime(runtime, scope, packageDir) {
226
226
  const config = RUNTIMES[runtime];
227
227
  const basePath = getBasePath(runtime, scope);
228
- const commandsPath = path.join(basePath, config.commandsDir);
229
228
  const agentsPath = path.join(basePath, config.agentsDir);
230
- const acePath = path.join(basePath, ACE_DIR_NAME);
231
229
 
232
- // Source directories
233
- const srcCommands = path.join(packageDir, 'commands');
230
+ // Source directories (plugin structure)
231
+ const srcSkills = path.join(packageDir, 'skills');
232
+ const srcShared = path.join(packageDir, 'shared');
233
+ const srcPlugin = path.join(packageDir, '.claude-plugin');
234
234
  const srcAgents = path.join(packageDir, 'agents');
235
- const srcTemplates = path.join(packageDir, 'agile-context-engineering', 'templates');
236
- const srcUtils = path.join(packageDir, 'agile-context-engineering', 'utils');
237
- const srcWorkflows = path.join(packageDir, 'agile-context-engineering', 'workflows');
238
- const srcTools = path.join(packageDir, 'agile-context-engineering', 'src');
239
235
 
240
236
  log(`\nInstalling ACE for ${config.name}...`, colors.cyan);
241
237
  log(` Target: ${basePath}`, colors.dim);
242
238
 
243
- // Clean previous ACE installation to remove stale files from renamed/deleted commands
244
- const aceCommandsPath = path.join(commandsPath, 'ace');
239
+ // Clean previous ACE installation to remove stale files
240
+ const aceCommandsPath = path.join(basePath, config.commandsDir, 'ace');
245
241
  if (fs.existsSync(aceCommandsPath)) {
246
242
  fs.rmSync(aceCommandsPath, { recursive: true });
247
243
  }
248
244
  if (fs.existsSync(agentsPath)) {
249
- // Only remove ace-* agent files, preserve non-ACE agents
250
245
  for (const f of fs.readdirSync(agentsPath)) {
251
246
  if (f.startsWith('ace-')) {
252
247
  fs.rmSync(path.join(agentsPath, f), { recursive: true });
253
248
  }
254
249
  }
255
250
  }
256
- if (fs.existsSync(acePath)) {
257
- fs.rmSync(acePath, { recursive: true });
251
+ // Clean old agile-context-engineering directory from pre-plugin installs
252
+ const legacyAcePath = path.join(basePath, ACE_LEGACY_DIR_NAME);
253
+ if (fs.existsSync(legacyAcePath)) {
254
+ fs.rmSync(legacyAcePath, { recursive: true });
255
+ }
256
+ // Clean skills/shared directories from previous plugin installs
257
+ const skillsPath = path.join(basePath, 'skills');
258
+ const sharedPath = path.join(basePath, 'shared');
259
+ const pluginPath = path.join(basePath, '.claude-plugin');
260
+ if (fs.existsSync(skillsPath)) {
261
+ fs.rmSync(skillsPath, { recursive: true });
262
+ }
263
+ if (fs.existsSync(sharedPath)) {
264
+ fs.rmSync(sharedPath, { recursive: true });
265
+ }
266
+ if (fs.existsSync(pluginPath)) {
267
+ fs.rmSync(pluginPath, { recursive: true });
258
268
  }
259
269
 
260
270
  // Create directories
261
- fs.mkdirSync(commandsPath, { recursive: true });
262
271
  fs.mkdirSync(agentsPath, { recursive: true });
263
- fs.mkdirSync(acePath, { recursive: true });
264
272
 
265
- // Copy commands (transform paths for target runtime)
266
- if (fs.existsSync(srcCommands)) {
267
- copyDir(srcCommands, commandsPath, runtime);
268
- log(` ✓ Commands installed`, colors.green);
273
+ // Copy skills (plugin skill directories)
274
+ if (fs.existsSync(srcSkills)) {
275
+ copyDir(srcSkills, skillsPath, runtime);
276
+ log(` ✓ Skills installed`, colors.green);
269
277
  }
270
278
 
271
- // Copy agents (transform paths for target runtime)
272
- if (fs.existsSync(srcAgents)) {
273
- copyDir(srcAgents, agentsPath, runtime);
274
- log(` ✓ Agents installed`, colors.green);
279
+ // Copy shared libs (ace-core.js, ace-story.js, ace-github.js, utils)
280
+ if (fs.existsSync(srcShared)) {
281
+ copyDir(srcShared, sharedPath, runtime);
282
+ log(` ✓ Shared libs installed`, colors.green);
275
283
  }
276
284
 
277
- // Copy templates into agile-context-engineering/
278
- if (fs.existsSync(srcTemplates)) {
279
- copyDir(srcTemplates, path.join(acePath, 'templates'), runtime);
280
- log(` ✓ Templates installed`, colors.green);
285
+ // Copy plugin manifest
286
+ if (fs.existsSync(srcPlugin)) {
287
+ copyDir(srcPlugin, pluginPath, runtime);
288
+ log(` ✓ Plugin manifest installed`, colors.green);
281
289
  }
282
290
 
283
- // Copy utils into agile-context-engineering/
284
- if (fs.existsSync(srcUtils)) {
285
- copyDir(srcUtils, path.join(acePath, 'utils'), runtime);
286
- log(` ✓ Utils installed`, colors.green);
287
- }
288
-
289
- // Copy workflows into agile-context-engineering/
290
- if (fs.existsSync(srcWorkflows)) {
291
- copyDir(srcWorkflows, path.join(acePath, 'workflows'), runtime);
292
- log(` ✓ Workflows installed`, colors.green);
293
- }
294
-
295
- // Copy src (ace-tools) into agile-context-engineering/
296
- if (fs.existsSync(srcTools)) {
297
- copyDir(srcTools, path.join(acePath, 'src'), runtime);
298
- log(` ✓ Tools installed`, colors.green);
291
+ // Copy agents (transform paths for target runtime)
292
+ if (fs.existsSync(srcAgents)) {
293
+ copyDir(srcAgents, agentsPath, runtime);
294
+ log(` ✓ Agents installed`, colors.green);
299
295
  }
300
296
 
301
297
  // Copy hooks
@@ -314,13 +310,14 @@ function installForRuntime(runtime, scope, packageDir) {
314
310
  log(` ✓ Hooks installed`, colors.green);
315
311
  }
316
312
 
317
- // Write VERSION file for update checking
318
- const versionFile = path.join(acePath, 'VERSION');
313
+ // Write VERSION file for update checking (in shared/ alongside libs)
314
+ const versionFile = path.join(sharedPath, 'VERSION');
315
+ if (!fs.existsSync(sharedPath)) fs.mkdirSync(sharedPath, { recursive: true });
319
316
  fs.writeFileSync(versionFile, VERSION, 'utf-8');
320
317
 
321
318
  // Copy CHANGELOG.md
322
319
  const changelogSrc = path.join(packageDir, 'CHANGELOG.md');
323
- const changelogDest = path.join(acePath, 'CHANGELOG.md');
320
+ const changelogDest = path.join(sharedPath, 'CHANGELOG.md');
324
321
  if (fs.existsSync(changelogSrc)) {
325
322
  fs.copyFileSync(changelogSrc, changelogDest);
326
323
  log(` ✓ CHANGELOG.md installed`, colors.green);
@@ -486,29 +483,28 @@ async function main() {
486
483
  log(`\nInstalled structure:`, colors.cyan);
487
484
  for (const { path: p } of installedPaths) {
488
485
  log(` ${p}/`, colors.dim);
489
- log(` commands/ace/ Slash commands`, colors.dim);
486
+ log(` skills/ Skill directories (SKILL.md + workflow + templates + script.js)`, colors.dim);
487
+ log(` shared/ Shared libraries (ace-core.js, ace-story.js, ace-github.js)`, colors.dim);
490
488
  log(` agents/ Agent definitions`, colors.dim);
491
489
  log(` hooks/ Statusline & update hooks`, colors.dim);
492
- log(` ${ACE_DIR_NAME}/`, colors.dim);
493
- log(` templates/ Project & artifact templates`, colors.dim);
494
- log(` utils/ Formatting & utility guides`, colors.dim);
495
- log(` workflows/ Workflow definitions`, colors.dim);
490
+ log(` .claude-plugin/ Plugin manifest`, colors.dim);
496
491
  }
497
492
 
498
- log(`\nAvailable commands:`, colors.cyan);
499
- log(` /ace:help Check project status and next steps`, colors.dim);
500
- log(` /ace:plan-project Plan your project with epics and features`, colors.dim);
501
- log(` /ace:plan-epic Plan an epic with features and stories`, colors.dim);
502
- log(` /ace:plan-feature Plan a feature with stories`, colors.dim);
503
- log(` /ace:plan-story Plan a story with tasks`, colors.dim);
504
- log(` /ace:refine-story Refine a story for execution`, colors.dim);
505
- log(` /ace:execute-story Execute a story`, colors.dim);
506
- log(` /ace:verify-story Verify a completed story`, colors.dim);
493
+ log(`\nAvailable skills:`, colors.cyan);
494
+ log(` /ace:help Check project status and next steps`, colors.dim);
495
+ log(` /ace:plan-product-vision Create or update the product vision`, colors.dim);
496
+ log(` /ace:plan-backlog Plan the product backlog`, colors.dim);
497
+ log(` /ace:plan-feature Plan a feature with stories`, colors.dim);
498
+ log(` /ace:plan-story Plan a story specification`, colors.dim);
499
+ log(` /ace:execute-story Execute a planned story`, colors.dim);
500
+ log(` /ace:map-system Map system-wide architecture`, colors.dim);
501
+ log(` /ace:map-subsystem Map a subsystem's internals`, colors.dim);
502
+ log(` /ace:init-coding-standards Generate coding standards`, colors.dim);
507
503
 
508
504
  log(`\nGet started:`, colors.cyan);
509
505
  log(` 1. Navigate to your project directory`, colors.dim);
510
506
  log(` 2. Run /ace:help to initialize ACE`, colors.dim);
511
- log(` 3. Run /ace:plan-project to start planning\n`, colors.dim);
507
+ log(` 3. Run /ace:plan-product-vision to define your product\n`, colors.dim);
512
508
  }
513
509
 
514
510
  main().catch((err) => {
@@ -1,62 +1,70 @@
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();
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
+ // New plugin structure: shared/VERSION; legacy: agile-context-engineering/VERSION
17
+ const projectVersionFile = path.join(cwd, '.claude', 'shared', 'VERSION');
18
+ const globalVersionFile = path.join(homeDir, '.claude', 'shared', 'VERSION');
19
+ const legacyProjectVersionFile = path.join(cwd, '.claude', 'agile-context-engineering', 'VERSION');
20
+ const legacyGlobalVersionFile = path.join(homeDir, '.claude', 'agile-context-engineering', 'VERSION');
21
+
22
+ // Ensure cache directory exists
23
+ if (!fs.existsSync(cacheDir)) {
24
+ fs.mkdirSync(cacheDir, { recursive: true });
25
+ }
26
+
27
+ // Run check in background (spawn detached process, windowsHide prevents console flash)
28
+ const child = spawn(process.execPath, ['-e', `
29
+ const fs = require('fs');
30
+ const { execSync } = require('child_process');
31
+
32
+ const cacheFile = ${JSON.stringify(cacheFile)};
33
+ const versionFiles = [
34
+ ${JSON.stringify(projectVersionFile)},
35
+ ${JSON.stringify(globalVersionFile)},
36
+ ${JSON.stringify(legacyProjectVersionFile)},
37
+ ${JSON.stringify(legacyGlobalVersionFile)},
38
+ ];
39
+
40
+ // Check new paths first, then legacy
41
+ let installed = '0.0.0';
42
+ try {
43
+ for (const vf of versionFiles) {
44
+ if (fs.existsSync(vf)) {
45
+ installed = fs.readFileSync(vf, 'utf8').trim();
46
+ break;
47
+ }
48
+ }
49
+ } catch (e) {}
50
+
51
+ let latest = null;
52
+ try {
53
+ latest = execSync('npm view agile-context-engineering version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
54
+ } catch (e) {}
55
+
56
+ const result = {
57
+ update_available: latest && installed !== latest,
58
+ installed,
59
+ latest: latest || 'unknown',
60
+ checked: Math.floor(Date.now() / 1000)
61
+ };
62
+
63
+ fs.writeFileSync(cacheFile, JSON.stringify(result));
64
+ `], {
65
+ stdio: 'ignore',
66
+ windowsHide: true,
67
+ detached: true
68
+ });
69
+
70
+ child.unref();
@@ -1,89 +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
- });
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.3.0",
3
+ "version": "0.5.0",
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": {
@@ -9,14 +9,15 @@
9
9
  },
10
10
  "files": [
11
11
  "bin",
12
- "commands",
12
+ "skills",
13
+ "shared",
13
14
  "agents",
14
15
  "hooks",
15
- "agile-context-engineering",
16
+ ".claude-plugin",
16
17
  "CHANGELOG.md"
17
18
  ],
18
19
  "scripts": {
19
- "test": "node --test agile-context-engineering/src/ace-tools.test.js"
20
+ "test": "node --test shared/lib/*.test.js skills/*/script.test.js"
20
21
  },
21
22
  "keywords": [
22
23
  "claude-code",