agile-context-engineering 0.5.0 → 0.5.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.
Files changed (102) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +7 -1
  4. package/README.md +16 -12
  5. package/agents/ace-code-discovery-analyst.md +245 -245
  6. package/agents/ace-code-integration-analyst.md +248 -248
  7. package/agents/ace-code-reviewer.md +375 -375
  8. package/agents/ace-product-owner.md +365 -361
  9. package/agents/ace-project-researcher.md +606 -606
  10. package/agents/ace-technical-application-architect.md +315 -315
  11. package/bin/install.js +587 -173
  12. package/hooks/ace-check-update.js +15 -14
  13. package/hooks/ace-statusline.js +30 -12
  14. package/hooks/hooks.json +14 -0
  15. package/package.json +3 -2
  16. package/shared/lib/ace-core.js +53 -0
  17. package/shared/lib/ace-core.test.js +308 -308
  18. package/shared/lib/ace-story.test.js +250 -250
  19. package/skills/execute-story/SKILL.md +116 -110
  20. package/skills/execute-story/script.js +13 -27
  21. package/skills/execute-story/script.test.js +261 -261
  22. package/skills/execute-story/story-template.xml +451 -451
  23. package/skills/execute-story/workflow.xml +3 -1
  24. package/skills/help/SKILL.md +71 -69
  25. package/skills/help/script.js +32 -35
  26. package/skills/help/script.test.js +183 -183
  27. package/skills/help/workflow.xml +14 -3
  28. package/skills/init-coding-standards/SKILL.md +91 -72
  29. package/skills/init-coding-standards/coding-standards-template.xml +531 -531
  30. package/skills/init-coding-standards/script.js +50 -59
  31. package/skills/init-coding-standards/script.test.js +70 -70
  32. package/skills/init-coding-standards/workflow.xml +1 -1
  33. package/skills/map-cross-cutting/SKILL.md +126 -89
  34. package/skills/map-cross-cutting/workflow.xml +1 -1
  35. package/skills/map-guide/SKILL.md +126 -89
  36. package/skills/map-guide/workflow.xml +1 -1
  37. package/skills/map-pattern/SKILL.md +125 -89
  38. package/skills/map-pattern/workflow.xml +1 -1
  39. package/skills/map-story/SKILL.md +180 -127
  40. package/skills/map-story/templates/tech-debt-index.xml +125 -125
  41. package/skills/map-story/workflow.xml +2 -2
  42. package/skills/map-subsystem/SKILL.md +155 -111
  43. package/skills/map-subsystem/script.js +51 -60
  44. package/skills/map-subsystem/script.test.js +68 -68
  45. package/skills/map-subsystem/templates/subsystem-architecture.xml +343 -343
  46. package/skills/map-subsystem/templates/subsystem-structure.xml +234 -234
  47. package/skills/map-subsystem/workflow.xml +1173 -1173
  48. package/skills/map-sys-doc/SKILL.md +125 -90
  49. package/skills/map-sys-doc/workflow.xml +1 -1
  50. package/skills/map-system/SKILL.md +103 -85
  51. package/skills/map-system/script.js +75 -84
  52. package/skills/map-system/script.test.js +73 -73
  53. package/skills/map-system/templates/system-structure.xml +177 -177
  54. package/skills/map-system/templates/testing-framework.xml +283 -283
  55. package/skills/map-system/workflow.xml +667 -667
  56. package/skills/map-walkthrough/SKILL.md +140 -92
  57. package/skills/map-walkthrough/workflow.xml +457 -457
  58. package/skills/plan-backlog/SKILL.md +93 -75
  59. package/skills/plan-backlog/script.js +121 -136
  60. package/skills/plan-backlog/script.test.js +83 -83
  61. package/skills/plan-backlog/workflow.xml +1348 -1348
  62. package/skills/plan-feature/SKILL.md +99 -76
  63. package/skills/plan-feature/feature-template.xml +361 -361
  64. package/skills/plan-feature/script.js +131 -148
  65. package/skills/plan-feature/script.test.js +80 -80
  66. package/skills/plan-feature/workflow.xml +1 -1
  67. package/skills/plan-product-vision/SKILL.md +91 -75
  68. package/skills/plan-product-vision/product-vision-template.xml +227 -227
  69. package/skills/plan-product-vision/script.js +51 -60
  70. package/skills/plan-product-vision/script.test.js +69 -69
  71. package/skills/plan-product-vision/workflow.xml +337 -337
  72. package/skills/plan-story/SKILL.md +125 -102
  73. package/skills/plan-story/script.js +18 -49
  74. package/skills/plan-story/story-template.xml +8 -1
  75. package/skills/plan-story/workflow.xml +17 -1
  76. package/skills/research-external-solution/SKILL.md +120 -107
  77. package/skills/research-external-solution/external-solution-template.xml +832 -832
  78. package/skills/research-external-solution/script.js +229 -238
  79. package/skills/research-external-solution/script.test.js +134 -134
  80. package/skills/research-external-solution/workflow.xml +657 -657
  81. package/skills/research-integration-solution/SKILL.md +121 -98
  82. package/skills/research-integration-solution/integration-solution-template.xml +1015 -1015
  83. package/skills/research-integration-solution/script.js +223 -231
  84. package/skills/research-integration-solution/script.test.js +134 -134
  85. package/skills/research-integration-solution/workflow.xml +711 -711
  86. package/skills/research-story-wiki/SKILL.md +101 -92
  87. package/skills/research-story-wiki/script.js +223 -231
  88. package/skills/research-story-wiki/script.test.js +138 -138
  89. package/skills/research-story-wiki/story-wiki-template.xml +194 -194
  90. package/skills/research-story-wiki/workflow.xml +473 -473
  91. package/skills/research-technical-solution/SKILL.md +131 -103
  92. package/skills/research-technical-solution/script.js +223 -231
  93. package/skills/research-technical-solution/script.test.js +134 -134
  94. package/skills/research-technical-solution/technical-solution-template.xml +1025 -1025
  95. package/skills/research-technical-solution/workflow.xml +761 -761
  96. package/skills/review-story/SKILL.md +99 -100
  97. package/skills/review-story/script.js +8 -16
  98. package/skills/review-story/script.test.js +169 -169
  99. package/skills/review-story/story-template.xml +451 -451
  100. package/skills/review-story/workflow.xml +1 -1
  101. package/skills/update/SKILL.md +65 -53
  102. package/skills/update/workflow.xml +21 -5
@@ -1,134 +1,134 @@
1
- const { describe, it, before, after } = require('node:test');
2
- const assert = require('node:assert');
3
- const { execSync } = require('child_process');
4
- const fs = require('fs');
5
- const path = require('path');
6
- const os = require('os');
7
-
8
- const SCRIPT = path.join(__dirname, 'script.js');
9
-
10
- /**
11
- * Create a minimal ACE project structure in a temp directory.
12
- */
13
- function createTestProject() {
14
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ace-test-'));
15
-
16
- // .ace/config.json
17
- const aceDir = path.join(tmpDir, '.ace');
18
- fs.mkdirSync(aceDir, { recursive: true });
19
- fs.writeFileSync(path.join(aceDir, 'config.json'), JSON.stringify({
20
- version: '0.1.0',
21
- projectName: 'test-project',
22
- model_profile: 'quality',
23
- commit_docs: true,
24
- github: { enabled: false },
25
- }, null, 2));
26
-
27
- // .ace/settings.json
28
- fs.writeFileSync(path.join(aceDir, 'settings.json'), JSON.stringify({
29
- model_profile: 'quality',
30
- commit_docs: true,
31
- agent_teams: false,
32
- github_project: { enabled: false, gh_installed: false, repo: '', project_number: null, owner: '' },
33
- }, null, 2));
34
-
35
- return tmpDir;
36
- }
37
-
38
- /**
39
- * Create a story file in the test project.
40
- */
41
- function createStoryFile(tmpDir, relPath, content) {
42
- const fullPath = path.join(tmpDir, relPath);
43
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
44
- fs.writeFileSync(fullPath, content, 'utf-8');
45
- return relPath;
46
- }
47
-
48
- function runScript(subcommand, args, cwd) {
49
- return execSync(`node "${SCRIPT}" ${subcommand} ${args}`, {
50
- cwd,
51
- encoding: 'utf-8',
52
- timeout: 10000,
53
- });
54
- }
55
-
56
- function cleanup(tmpDir) {
57
- fs.rmSync(tmpDir, { recursive: true, force: true });
58
- }
59
-
60
- // ─── Tests ───────────────────────────────────────────────────────────────────
61
-
62
- describe('research-integration-solution script', () => {
63
-
64
- describe('init', () => {
65
- let tmpDir;
66
-
67
- before(() => { tmpDir = createTestProject(); });
68
- after(() => { cleanup(tmpDir); });
69
-
70
- it('returns valid JSON with environment detection for a story file', () => {
71
- const storyContent = [
72
- '# S1: Add Login Button',
73
- '**Feature**: F1 User Auth | **Epic**: E1 Platform',
74
- '**Status**: Todo | **Size**: 3 | **Sprint**: — | **Link**: —',
75
- '',
76
- '## User Story',
77
- '',
78
- '> As a user,',
79
- '> I want to click a login button,',
80
- '> so that I can access my account.',
81
- '',
82
- '## Description',
83
- '',
84
- 'Adds a login button to the header.',
85
- '',
86
- '## Acceptance Criteria',
87
- '',
88
- '### Scenario: Click login button',
89
- '',
90
- '**Given** the user is on the homepage',
91
- '**When** they click "Login"',
92
- '**Then** they see the login form',
93
- ].join('\n');
94
-
95
- const storyPath = createStoryFile(
96
- tmpDir,
97
- '.ace/artifacts/product/e1-platform/f1-user-auth/s1-add-login-button/s1-add-login-button.md',
98
- storyContent
99
- );
100
-
101
- const result = JSON.parse(runScript('init', storyPath, tmpDir));
102
-
103
- assert.ok(result.analyst_model, 'should have analyst_model');
104
- assert.ok(result.mapper_model, 'should have mapper_model');
105
- assert.strictEqual(result.story_valid, true, 'story should be valid');
106
- assert.strictEqual(result.story_source, 'file');
107
- assert.strictEqual(result.story.id, 'S1');
108
- assert.strictEqual(result.story.title, 'Add Login Button');
109
- assert.strictEqual(result.acceptance_criteria_count, 1);
110
- assert.ok(result.paths, 'should have computed paths');
111
- assert.ok(result.wiki_references, 'should have wiki_references');
112
- assert.ok(result.wiki_docs_exist, 'should have wiki_docs_exist');
113
- });
114
-
115
- it('errors on init without story param', () => {
116
- const result = JSON.parse(runScript('init', '', tmpDir));
117
- assert.strictEqual(result.story_valid, false);
118
- });
119
-
120
- it('handles non-existent story file gracefully', () => {
121
- const result = JSON.parse(runScript('init', 'nonexistent/story.md', tmpDir));
122
- assert.strictEqual(result.story_valid, false);
123
- assert.ok(result.story_error.includes('not found'));
124
- });
125
- });
126
-
127
- describe('error handling', () => {
128
- it('errors on unknown command', () => {
129
- assert.throws(() => {
130
- execSync(`node "${SCRIPT}" bogus`, { encoding: 'utf-8', stdio: 'pipe' });
131
- });
132
- });
133
- });
134
- });
1
+ const { describe, it, before, after } = require('node:test');
2
+ const assert = require('node:assert');
3
+ const { execSync } = require('child_process');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const os = require('os');
7
+
8
+ const SCRIPT = path.join(__dirname, 'script.js');
9
+
10
+ /**
11
+ * Create a minimal ACE project structure in a temp directory.
12
+ */
13
+ function createTestProject() {
14
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ace-test-'));
15
+
16
+ // .ace/config.json
17
+ const aceDir = path.join(tmpDir, '.ace');
18
+ fs.mkdirSync(aceDir, { recursive: true });
19
+ fs.writeFileSync(path.join(aceDir, 'config.json'), JSON.stringify({
20
+ version: '0.1.0',
21
+ projectName: 'test-project',
22
+ model_profile: 'quality',
23
+ commit_docs: true,
24
+ github: { enabled: false },
25
+ }, null, 2));
26
+
27
+ // .ace/settings.json
28
+ fs.writeFileSync(path.join(aceDir, 'settings.json'), JSON.stringify({
29
+ model_profile: 'quality',
30
+ commit_docs: true,
31
+ agent_teams: false,
32
+ github_project: { enabled: false, gh_installed: false, repo: '', project_number: null, owner: '' },
33
+ }, null, 2));
34
+
35
+ return tmpDir;
36
+ }
37
+
38
+ /**
39
+ * Create a story file in the test project.
40
+ */
41
+ function createStoryFile(tmpDir, relPath, content) {
42
+ const fullPath = path.join(tmpDir, relPath);
43
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
44
+ fs.writeFileSync(fullPath, content, 'utf-8');
45
+ return relPath;
46
+ }
47
+
48
+ function runScript(subcommand, args, cwd) {
49
+ return execSync(`node "${SCRIPT}" ${subcommand} ${args}`, {
50
+ cwd,
51
+ encoding: 'utf-8',
52
+ timeout: 10000,
53
+ });
54
+ }
55
+
56
+ function cleanup(tmpDir) {
57
+ fs.rmSync(tmpDir, { recursive: true, force: true });
58
+ }
59
+
60
+ // ─── Tests ───────────────────────────────────────────────────────────────────
61
+
62
+ describe('research-integration-solution script', () => {
63
+
64
+ describe('init', () => {
65
+ let tmpDir;
66
+
67
+ before(() => { tmpDir = createTestProject(); });
68
+ after(() => { cleanup(tmpDir); });
69
+
70
+ it('returns valid JSON with environment detection for a story file', () => {
71
+ const storyContent = [
72
+ '# S1: Add Login Button',
73
+ '**Feature**: F1 User Auth | **Epic**: E1 Platform',
74
+ '**Status**: Todo | **Size**: 3 | **Sprint**: — | **Link**: —',
75
+ '',
76
+ '## User Story',
77
+ '',
78
+ '> As a user,',
79
+ '> I want to click a login button,',
80
+ '> so that I can access my account.',
81
+ '',
82
+ '## Description',
83
+ '',
84
+ 'Adds a login button to the header.',
85
+ '',
86
+ '## Acceptance Criteria',
87
+ '',
88
+ '### Scenario: Click login button',
89
+ '',
90
+ '**Given** the user is on the homepage',
91
+ '**When** they click "Login"',
92
+ '**Then** they see the login form',
93
+ ].join('\n');
94
+
95
+ const storyPath = createStoryFile(
96
+ tmpDir,
97
+ '.ace/artifacts/product/e1-platform/f1-user-auth/s1-add-login-button/s1-add-login-button.md',
98
+ storyContent
99
+ );
100
+
101
+ const result = JSON.parse(runScript('init', storyPath, tmpDir));
102
+
103
+ assert.ok(result.analyst_model, 'should have analyst_model');
104
+ assert.ok(result.mapper_model, 'should have mapper_model');
105
+ assert.strictEqual(result.story_valid, true, 'story should be valid');
106
+ assert.strictEqual(result.story_source, 'file');
107
+ assert.strictEqual(result.story.id, 'S1');
108
+ assert.strictEqual(result.story.title, 'Add Login Button');
109
+ assert.strictEqual(result.acceptance_criteria_count, 1);
110
+ assert.ok(result.paths, 'should have computed paths');
111
+ assert.ok(result.wiki_references, 'should have wiki_references');
112
+ assert.ok(result.wiki_docs_exist, 'should have wiki_docs_exist');
113
+ });
114
+
115
+ it('errors on init without story param', () => {
116
+ const result = JSON.parse(runScript('init', '', tmpDir));
117
+ assert.strictEqual(result.story_valid, false);
118
+ });
119
+
120
+ it('handles non-existent story file gracefully', () => {
121
+ const result = JSON.parse(runScript('init', 'nonexistent/story.md', tmpDir));
122
+ assert.strictEqual(result.story_valid, false);
123
+ assert.ok(result.story_error.includes('not found'));
124
+ });
125
+ });
126
+
127
+ describe('error handling', () => {
128
+ it('errors on unknown command', () => {
129
+ assert.throws(() => {
130
+ execSync(`node "${SCRIPT}" bogus`, { encoding: 'utf-8', stdio: 'pipe' });
131
+ });
132
+ });
133
+ });
134
+ });