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.
- package/.claude-plugin/plugin.json +10 -0
- package/LICENSE +51 -51
- package/README.md +332 -324
- package/agents/ace-product-owner.md +1 -1
- package/agents/ace-research-synthesizer.md +228 -228
- package/agents/ace-wiki-mapper.md +449 -445
- package/bin/install.js +60 -64
- package/hooks/ace-check-update.js +70 -62
- package/hooks/ace-statusline.js +89 -89
- package/package.json +5 -4
- package/shared/lib/ace-core.js +308 -0
- package/shared/lib/ace-core.test.js +308 -0
- package/shared/lib/ace-github.js +753 -0
- package/shared/lib/ace-story.js +400 -0
- package/shared/lib/ace-story.test.js +250 -0
- package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
- package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
- package/skills/execute-story/SKILL.md +110 -0
- package/skills/execute-story/script.js +305 -0
- package/skills/execute-story/script.test.js +261 -0
- package/skills/execute-story/walkthrough-template.xml +255 -0
- package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1219 -1219
- package/skills/help/SKILL.md +69 -0
- package/skills/help/script.js +318 -0
- package/skills/help/script.test.js +183 -0
- package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +540 -540
- package/skills/init-coding-standards/SKILL.md +72 -0
- package/skills/init-coding-standards/script.js +59 -0
- package/skills/init-coding-standards/script.test.js +70 -0
- package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
- package/skills/map-cross-cutting/SKILL.md +89 -0
- package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
- package/skills/map-cross-cutting/workflow.xml +330 -0
- package/skills/map-guide/SKILL.md +89 -0
- package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
- package/skills/map-guide/workflow.xml +320 -0
- package/skills/map-pattern/SKILL.md +89 -0
- package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
- package/skills/map-pattern/workflow.xml +331 -0
- package/skills/map-story/SKILL.md +127 -0
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
- package/skills/map-story/templates/guide.xml +137 -0
- package/skills/map-story/templates/pattern.xml +159 -0
- package/skills/map-story/templates/system-cross-cutting.xml +197 -0
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
- package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
- package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
- package/skills/map-subsystem/SKILL.md +111 -0
- package/skills/map-subsystem/script.js +60 -0
- package/skills/map-subsystem/script.test.js +68 -0
- package/skills/map-subsystem/templates/decizions.xml +115 -0
- package/skills/map-subsystem/templates/guide.xml +137 -0
- package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
- package/skills/map-subsystem/templates/pattern.xml +159 -0
- package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
- package/skills/map-subsystem/templates/system.xml +381 -0
- package/skills/map-subsystem/templates/walkthrough.xml +255 -0
- package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +15 -20
- package/skills/map-sys-doc/SKILL.md +90 -0
- package/skills/map-sys-doc/system.xml +381 -0
- package/skills/map-sys-doc/workflow.xml +336 -0
- package/skills/map-system/SKILL.md +85 -0
- package/skills/map-system/script.js +84 -0
- package/skills/map-system/script.test.js +73 -0
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
- package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
- package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +11 -16
- package/skills/map-walkthrough/SKILL.md +92 -0
- package/skills/map-walkthrough/walkthrough.xml +255 -0
- package/skills/plan-backlog/SKILL.md +75 -0
- package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
- package/skills/plan-backlog/script.js +136 -0
- package/skills/plan-backlog/script.test.js +83 -0
- package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +13 -21
- package/skills/plan-feature/SKILL.md +76 -0
- package/skills/plan-feature/script.js +148 -0
- package/skills/plan-feature/script.test.js +80 -0
- package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
- package/skills/plan-product-vision/SKILL.md +75 -0
- package/skills/plan-product-vision/script.js +60 -0
- package/skills/plan-product-vision/script.test.js +69 -0
- package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +4 -9
- package/skills/plan-story/SKILL.md +116 -0
- package/skills/plan-story/script.js +326 -0
- package/skills/plan-story/script.test.js +240 -0
- package/skills/plan-story/story-template.xml +451 -0
- package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1285 -944
- package/skills/research-external-solution/SKILL.md +107 -0
- package/skills/research-external-solution/script.js +238 -0
- package/skills/research-external-solution/script.test.js +134 -0
- package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +4 -6
- package/skills/research-integration-solution/SKILL.md +98 -0
- package/skills/research-integration-solution/script.js +231 -0
- package/skills/research-integration-solution/script.test.js +134 -0
- package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +3 -5
- package/skills/research-story-wiki/SKILL.md +92 -0
- package/skills/research-story-wiki/script.js +231 -0
- package/skills/research-story-wiki/script.test.js +138 -0
- package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +3 -5
- package/skills/research-technical-solution/SKILL.md +103 -0
- package/skills/research-technical-solution/script.js +231 -0
- package/skills/research-technical-solution/script.test.js +134 -0
- package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +3 -5
- package/skills/review-story/SKILL.md +100 -0
- package/skills/review-story/script.js +257 -0
- package/skills/review-story/script.test.js +169 -0
- package/skills/review-story/story-template.xml +451 -0
- package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
- package/skills/update/SKILL.md +53 -0
- package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +12 -13
- package/agile-context-engineering/src/ace-tools.js +0 -2881
- package/agile-context-engineering/src/ace-tools.test.js +0 -1089
- package/agile-context-engineering/templates/_command.md +0 -54
- package/agile-context-engineering/templates/_workflow.xml +0 -17
- package/agile-context-engineering/templates/config.json +0 -0
- package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
- package/commands/ace/execute-story.md +0 -138
- package/commands/ace/help.md +0 -93
- package/commands/ace/init-coding-standards.md +0 -83
- package/commands/ace/map-story.md +0 -165
- package/commands/ace/map-subsystem.md +0 -140
- package/commands/ace/map-system.md +0 -92
- package/commands/ace/map-walkthrough.md +0 -127
- package/commands/ace/plan-backlog.md +0 -83
- package/commands/ace/plan-feature.md +0 -89
- package/commands/ace/plan-product-vision.md +0 -81
- package/commands/ace/plan-story.md +0 -159
- package/commands/ace/research-external-solution.md +0 -138
- package/commands/ace/research-integration-solution.md +0 -135
- package/commands/ace/research-story-wiki.md +0 -116
- package/commands/ace/research-technical-solution.md +0 -147
- package/commands/ace/review-story.md +0 -109
- package/commands/ace/update.md +0 -56
- /package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +0 -0
- /package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +0 -0
- /package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +0 -0
- /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +0 -0
- /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +0 -0
- /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +0 -0
- /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +0 -0
- /package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +0 -0
- /package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +0 -0
- /package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +0 -0
- /package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +0 -0
- /package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +0 -0
- /package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +0 -0
- /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
|
-
//
|
|
43
|
-
const
|
|
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
|
|
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
|
|
244
|
-
const aceCommandsPath = path.join(
|
|
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
|
-
|
|
257
|
-
|
|
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
|
|
266
|
-
if (fs.existsSync(
|
|
267
|
-
copyDir(
|
|
268
|
-
log(` ✓
|
|
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
|
|
272
|
-
if (fs.existsSync(
|
|
273
|
-
copyDir(
|
|
274
|
-
log(` ✓
|
|
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
|
|
278
|
-
if (fs.existsSync(
|
|
279
|
-
copyDir(
|
|
280
|
-
log(` ✓
|
|
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
|
|
284
|
-
if (fs.existsSync(
|
|
285
|
-
copyDir(
|
|
286
|
-
log(` ✓
|
|
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(
|
|
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(
|
|
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(`
|
|
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(`
|
|
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
|
|
499
|
-
log(` /ace:help
|
|
500
|
-
log(` /ace:plan-
|
|
501
|
-
log(` /ace:plan-
|
|
502
|
-
log(` /ace:plan-feature
|
|
503
|
-
log(` /ace:plan-story
|
|
504
|
-
log(` /ace:
|
|
505
|
-
log(` /ace:
|
|
506
|
-
log(` /ace:
|
|
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-
|
|
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
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
+
// 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();
|
package/hooks/ace-statusline.js
CHANGED
|
@@ -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
|
+
"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
|
-
"
|
|
12
|
+
"skills",
|
|
13
|
+
"shared",
|
|
13
14
|
"agents",
|
|
14
15
|
"hooks",
|
|
15
|
-
"
|
|
16
|
+
".claude-plugin",
|
|
16
17
|
"CHANGELOG.md"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
|
19
|
-
"test": "node --test
|
|
20
|
+
"test": "node --test shared/lib/*.test.js skills/*/script.test.js"
|
|
20
21
|
},
|
|
21
22
|
"keywords": [
|
|
22
23
|
"claude-code",
|