agile-context-engineering 0.3.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 (139) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +10 -0
  3. package/CHANGELOG.md +7 -1
  4. package/LICENSE +51 -51
  5. package/README.md +330 -318
  6. package/agents/ace-code-discovery-analyst.md +245 -245
  7. package/agents/ace-code-integration-analyst.md +248 -248
  8. package/agents/ace-code-reviewer.md +375 -375
  9. package/agents/ace-product-owner.md +365 -361
  10. package/agents/ace-project-researcher.md +606 -606
  11. package/agents/ace-research-synthesizer.md +228 -228
  12. package/agents/ace-technical-application-architect.md +315 -315
  13. package/agents/ace-wiki-mapper.md +449 -445
  14. package/bin/install.js +605 -195
  15. package/hooks/ace-check-update.js +71 -62
  16. package/hooks/ace-statusline.js +107 -89
  17. package/hooks/hooks.json +14 -0
  18. package/package.json +7 -5
  19. package/shared/lib/ace-core.js +361 -0
  20. package/shared/lib/ace-core.test.js +308 -0
  21. package/shared/lib/ace-github.js +753 -0
  22. package/shared/lib/ace-story.js +400 -0
  23. package/shared/lib/ace-story.test.js +250 -0
  24. package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
  25. package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
  26. package/{commands/ace/execute-story.md → skills/execute-story/SKILL.md} +116 -138
  27. package/skills/execute-story/script.js +291 -0
  28. package/skills/execute-story/script.test.js +261 -0
  29. package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +451 -451
  30. package/skills/execute-story/walkthrough-template.xml +255 -0
  31. package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1221 -1219
  32. package/skills/help/SKILL.md +71 -0
  33. package/skills/help/script.js +315 -0
  34. package/skills/help/script.test.js +183 -0
  35. package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +544 -533
  36. package/{commands/ace/init-coding-standards.md → skills/init-coding-standards/SKILL.md} +91 -83
  37. package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +531 -531
  38. package/skills/init-coding-standards/script.js +50 -0
  39. package/skills/init-coding-standards/script.test.js +70 -0
  40. package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
  41. package/skills/map-cross-cutting/SKILL.md +126 -0
  42. package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
  43. package/skills/map-cross-cutting/workflow.xml +330 -0
  44. package/skills/map-guide/SKILL.md +126 -0
  45. package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
  46. package/skills/map-guide/workflow.xml +320 -0
  47. package/skills/map-pattern/SKILL.md +125 -0
  48. package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
  49. package/skills/map-pattern/workflow.xml +331 -0
  50. package/{commands/ace/map-story.md → skills/map-story/SKILL.md} +180 -165
  51. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
  52. package/skills/map-story/templates/guide.xml +137 -0
  53. package/skills/map-story/templates/pattern.xml +159 -0
  54. package/skills/map-story/templates/system-cross-cutting.xml +197 -0
  55. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
  56. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +125 -125
  57. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
  58. package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
  59. package/{commands/ace/map-subsystem.md → skills/map-subsystem/SKILL.md} +155 -140
  60. package/skills/map-subsystem/script.js +51 -0
  61. package/skills/map-subsystem/script.test.js +68 -0
  62. package/skills/map-subsystem/templates/decizions.xml +115 -0
  63. package/skills/map-subsystem/templates/guide.xml +137 -0
  64. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
  65. package/skills/map-subsystem/templates/pattern.xml +159 -0
  66. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +343 -343
  67. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +234 -234
  68. package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
  69. package/skills/map-subsystem/templates/system.xml +381 -0
  70. package/skills/map-subsystem/templates/walkthrough.xml +255 -0
  71. package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +1173 -1178
  72. package/skills/map-sys-doc/SKILL.md +125 -0
  73. package/skills/map-sys-doc/system.xml +381 -0
  74. package/skills/map-sys-doc/workflow.xml +336 -0
  75. package/{commands/ace/map-system.md → skills/map-system/SKILL.md} +103 -92
  76. package/skills/map-system/script.js +75 -0
  77. package/skills/map-system/script.test.js +73 -0
  78. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
  79. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +177 -177
  80. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +283 -283
  81. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
  82. package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +667 -672
  83. package/{commands/ace/map-walkthrough.md → skills/map-walkthrough/SKILL.md} +140 -127
  84. package/skills/map-walkthrough/walkthrough.xml +255 -0
  85. package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +457 -457
  86. package/{commands/ace/plan-backlog.md → skills/plan-backlog/SKILL.md} +93 -83
  87. package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
  88. package/skills/plan-backlog/script.js +121 -0
  89. package/skills/plan-backlog/script.test.js +83 -0
  90. package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +1348 -1356
  91. package/{commands/ace/plan-feature.md → skills/plan-feature/SKILL.md} +99 -89
  92. package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +361 -361
  93. package/skills/plan-feature/script.js +131 -0
  94. package/skills/plan-feature/script.test.js +80 -0
  95. package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
  96. package/{commands/ace/plan-product-vision.md → skills/plan-product-vision/SKILL.md} +91 -81
  97. package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +227 -227
  98. package/skills/plan-product-vision/script.js +51 -0
  99. package/skills/plan-product-vision/script.test.js +69 -0
  100. package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +337 -342
  101. package/{commands/ace/plan-story.md → skills/plan-story/SKILL.md} +139 -159
  102. package/skills/plan-story/script.js +295 -0
  103. package/skills/plan-story/script.test.js +240 -0
  104. package/skills/plan-story/story-template.xml +458 -0
  105. package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1301 -944
  106. package/{commands/ace/research-external-solution.md → skills/research-external-solution/SKILL.md} +120 -138
  107. package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +832 -832
  108. package/skills/research-external-solution/script.js +229 -0
  109. package/skills/research-external-solution/script.test.js +134 -0
  110. package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +657 -659
  111. package/{commands/ace/research-integration-solution.md → skills/research-integration-solution/SKILL.md} +121 -135
  112. package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +1015 -1015
  113. package/skills/research-integration-solution/script.js +223 -0
  114. package/skills/research-integration-solution/script.test.js +134 -0
  115. package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +711 -713
  116. package/{commands/ace/research-story-wiki.md → skills/research-story-wiki/SKILL.md} +101 -116
  117. package/skills/research-story-wiki/script.js +223 -0
  118. package/skills/research-story-wiki/script.test.js +138 -0
  119. package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +194 -194
  120. package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +473 -475
  121. package/{commands/ace/research-technical-solution.md → skills/research-technical-solution/SKILL.md} +131 -147
  122. package/skills/research-technical-solution/script.js +223 -0
  123. package/skills/research-technical-solution/script.test.js +134 -0
  124. package/{agile-context-engineering/templates/product/story-technical-solution.xml → skills/research-technical-solution/technical-solution-template.xml} +1025 -1025
  125. package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +761 -763
  126. package/{commands/ace/review-story.md → skills/review-story/SKILL.md} +99 -109
  127. package/skills/review-story/script.js +249 -0
  128. package/skills/review-story/script.test.js +169 -0
  129. package/skills/review-story/story-template.xml +451 -0
  130. package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
  131. package/{commands/ace/update.md → skills/update/SKILL.md} +65 -56
  132. package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +33 -18
  133. package/agile-context-engineering/src/ace-tools.js +0 -2881
  134. package/agile-context-engineering/src/ace-tools.test.js +0 -1089
  135. package/agile-context-engineering/templates/_command.md +0 -54
  136. package/agile-context-engineering/templates/_workflow.xml +0 -17
  137. package/agile-context-engineering/templates/config.json +0 -0
  138. package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
  139. package/commands/ace/help.md +0 -93
@@ -1,159 +1,139 @@
1
- ---
2
- name: ace:plan-story
3
- description: Plan a story through deep questioning to create CRYSTAL-CLEAR acceptance criteria with ZERO assumptions, then dispatch wiki research, external analysis, integration analysis, and technical solution design
4
- argument-hint: "story=<file-path|github-url> [external-codebase=<source-path|github-url>] [external-docs=<weblink|filepath>] [lib-docs=<weblinks-and-filepaths>]"
5
- allowed-tools:
6
- - Read
7
- - Bash
8
- - Write
9
- - Edit
10
- - AskUserQuestion
11
- - Glob
12
- - Grep
13
- - Agent
14
- ---
15
-
16
- ```xml
17
- <command>
18
-
19
- <execution-time>
20
- <runs-after>
21
- <trigger>After /ace:plan-feature — once a feature's story breakdown exists with stub story files</trigger>
22
- <trigger>Anytime — to create or refine a story specification from a description or GitHub issue</trigger>
23
- </runs-after>
24
- <use-when>
25
- <condition>A story stub exists (from plan-feature) and needs formal specification</condition>
26
- <condition>A GitHub issue describes work that needs INVEST-compliant acceptance criteria</condition>
27
- <condition>An existing story needs refinement — scope changed, AC gaps found</condition>
28
- <condition>You want to create a complete story specification from any text description</condition>
29
- </use-when>
30
- </execution-time>
31
-
32
- <input>
33
- <flags>
34
- </flags>
35
-
36
- <parameters>
37
- <required>
38
- <param name="story" type="file | github-url">
39
- Story source — can be either:
40
- - **File path**: Path to a markdown file containing the story seed
41
- (typically a stub from plan-feature, or any markdown with a description)
42
- - **GitHub URL or issue number**: GitHub story reference
43
- Must be a valid, accessible file or GitHub issue.
44
- Contains the story description that will be refined through deep questioning.
45
- If not valid, stop and prompt the user.
46
- </param>
47
- </required>
48
-
49
- <optional>
50
- <param name="external-codebase" type="filepath | github-url">
51
- Path or GitHub repo to an external industry-standard system to analyze.
52
- When provided, pass 3 (external analysis) runs automatically.
53
- When NOT provided, the user is offered the option to provide it or skip.
54
- </param>
55
- <param name="external-docs" type="weblink | filepath">
56
- Link or path to external system documentation.
57
- Only used when external-codebase is also provided.
58
- Provides supplementary context for external analysis.
59
- </param>
60
- <param name="lib-docs" type="weblinks and/or filepaths">
61
- Space-separated string of weblinks and/or file paths to library or API documentation.
62
- These are injected into the story's Relevant Wiki section as a
63
- `### Library Documentation` subsection after pass 2 completes,
64
- so that passes 4-5 (integration analysis, technical solution) can
65
- reference them when designing the implementation.
66
- Useful for third-party libraries, SDK docs, or API references
67
- that inform how the story should be built.
68
- </param>
69
- </optional>
70
- </parameters>
71
- </input>
72
-
73
- <execution-context>
74
- <plan-story-workflow>@~/.claude/agile-context-engineering/workflows/plan-story.xml</plan-story-workflow>
75
- <story-template>@~/.claude/agile-context-engineering/templates/product/story.xml</story-template>
76
- <questioning>@~/.claude/agile-context-engineering/utils/questioning.xml</questioning>
77
- <ui-formatting>@~/.claude/agile-context-engineering/utils/ui-formatting.md</ui-formatting>
78
- </execution-context>
79
-
80
- <output>
81
- <objective>
82
- Take a story seed (stub file, GitHub issue, or any text description) and produce
83
- a COMPLETE story specification through deep questioning that ensures:
84
- - ZERO ASSUMPTIONS — every behavior is explicitly specified
85
- - CRYSTAL-CLEAR acceptance criteria with exact triggers, preconditions, outcomes
86
- - INVEST compliance — Independent, Negotiable, Valuable, Estimable, Small, Testable
87
- - Gherkin scenarios cover happy paths, edge cases, AND error paths
88
-
89
- After story requirements are defined (pass 1), dispatch research passes 2-5
90
- as background agents:
91
- - Pass 2: Wiki research (updates story file with Relevant Wiki section)
92
- - Pass 3: External analysis (OPTIONAL — creates external-analysis.md)
93
- - Pass 4: Integration analysis (creates integration-analysis.md)
94
- - Pass 5: Technical solution (appends to story file)
95
-
96
- Each research pass writes directly to disk. The orchestrator context window
97
- contains ONLY story requirements research outputs do NOT flow back.
98
- </objective>
99
-
100
- <artifacts>
101
- .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/&lt;id-story_name&gt;.md
102
- .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/external-analysis.md (OPTIONAL)
103
- .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/integration-analysis.md
104
- </artifacts>
105
- </output>
106
-
107
- <process>
108
- For this command use the `ace-product-owner` agent
109
- that's specialized in requirements gathering, deep questioning, and story specification.
110
-
111
- Execute the plan-story workflow from
112
- `@~/.claude/agile-context-engineering/workflows/plan-story.xml` end-to-end.
113
- Preserve all workflow gates (validation, approvals, commits).
114
-
115
- **CRITICAL — Context Window Protection:**
116
- Passes 2-5 run as background agents. Each agent writes output directly to files.
117
- The orchestrator MUST NOT call TaskOutput on any background agent.
118
- The orchestrator only needs to know when each pass finishes to start the next one.
119
-
120
- **Pass execution order:**
121
- Pass 2 + Pass 3 (if applicable) → wait → Pass 4 → wait → Pass 5 → wait → done
122
- </process>
123
-
124
- <example-usage>
125
- ```
126
- # From a plan-feature stub file
127
- /ace:plan-story \
128
- story=.ace/artifacts/product/e1-auth/f3-oauth/s1-buttons/s1-buttons.md
129
-
130
- # From a GitHub issue
131
- /ace:plan-story \
132
- story=https://github.com/owner/repo/issues/95
133
-
134
- # With external system analysis
135
- /ace:plan-story \
136
- story=.ace/artifacts/product/e1-charts/f2-rendering/s3-canvas/s3-canvas.md \
137
- external-codebase=src/external/lightweight-charts/ \
138
- external-docs=https://tradingview.github.io/lightweight-charts/
139
-
140
- # With library documentation references
141
- /ace:plan-story \
142
- story=.ace/artifacts/product/e1-charts/f2-rendering/s3-canvas/s3-canvas.md \
143
- lib-docs="https://docs.some-lib.io/api src/vendor/some-lib/README.md"
144
-
145
- # With just an issue number (uses configured repo)
146
- /ace:plan-story story=#95
147
- ```
148
- </example-usage>
149
-
150
- <next-steps>
151
- **After this command:**
152
- - `/ace:execute-story story=...` — Execute the story implementation
153
- - `/ace:plan-story story=...` — Plan the next story in the feature
154
- - `/ace:verify-story story=...` — Verify a completed story
155
- - `/ace:help` — Check project initialization status
156
- </next-steps>
157
-
158
- </command>
159
- ```
1
+ ---
2
+ name: plan-story
3
+ description: Plan a story through deep questioning to create CRYSTAL-CLEAR acceptance criteria with ZERO assumptions, then dispatch wiki research, external analysis, integration analysis, and technical solution design. Use this whenever the user wants to plan a story, specify a story, create acceptance criteria, refine story requirements, or take a story stub and turn it into a full specification — whether from a feature stub, GitHub issue, inline text, or from scratch.
4
+ argument-hint: "[story=<file-path|github-url>] [text=<inline-description>] [external-codebase=<source-path|github-url>] [external-docs=<weblink|filepath>] [lib-docs=<weblinks-and-filepaths>]"
5
+ disable-model-invocation: true
6
+ allowed-tools: Read, Bash, Write, Edit, AskUserQuestion, Glob, Grep, Agent
7
+ model: opus
8
+ effort: high
9
+ ---
10
+
11
+ ## Environment Context (preprocessed)
12
+
13
+ !`node "${CLAUDE_SKILL_DIR}/script.js" init "$ARGUMENTS" 2>/dev/null`
14
+
15
+ ## Supporting Resources (auto-loaded)
16
+
17
+ !`cat "${CLAUDE_SKILL_DIR}/workflow.xml"`
18
+
19
+ !`cat "${CLAUDE_SKILL_DIR}/story-template.xml"`
20
+
21
+ !`cat "${CLAUDE_SKILL_DIR}/../../shared/utils/questioning.xml"`
22
+
23
+ !`cat "${CLAUDE_SKILL_DIR}/../../shared/utils/ui-formatting.md"`
24
+
25
+ ```xml
26
+ <command>
27
+
28
+ <execution-time>
29
+ <runs-after>
30
+ <trigger>After /ace:plan-feature — once a feature's story breakdown exists with stub story files</trigger>
31
+ <trigger>Anytime — to create or refine a story specification from a description or GitHub issue</trigger>
32
+ </runs-after>
33
+ <use-when>
34
+ <condition>A story stub exists (from plan-feature) and needs formal specification</condition>
35
+ <condition>A GitHub issue describes work that needs INVEST-compliant acceptance criteria</condition>
36
+ <condition>An existing story needs refinement — scope changed, AC gaps found</condition>
37
+ <condition>You want to create a complete story specification from any text description</condition>
38
+ <condition>You have a new story idea (text or no input) and need it placed in the backlog</condition>
39
+ </use-when>
40
+ </execution-time>
41
+
42
+ <input>
43
+ <flags>
44
+ </flags>
45
+
46
+ <parameters>
47
+ <required>
48
+ </required>
49
+
50
+ <optional>
51
+ <param name="story" type="file | github-url">
52
+ Story source can be either:
53
+ - **File path**: Path to an existing markdown file containing the story seed
54
+ (typically a stub from plan-feature, or any markdown with a description)
55
+ - **GitHub URL or issue number**: GitHub story reference
56
+ When omitted, the workflow enters "new story" mode and guides the user
57
+ through backlog placement before proceeding to specification.
58
+ If provided but invalid, stop and prompt the user.
59
+ </param>
60
+ <param name="text" type="text">
61
+ Inline story description to seed the planning session.
62
+ Used when no story file exists yet — the text becomes the initial description
63
+ and the workflow asks where in the backlog this story belongs.
64
+ Ignored if `story` is provided.
65
+ </param>
66
+ <param name="external-codebase" type="filepath | github-url">
67
+ Path or GitHub repo to an external industry-standard system to analyze.
68
+ When provided, pass 3 (external analysis) runs automatically.
69
+ When NOT provided, the user is offered the option to provide it or skip.
70
+ </param>
71
+ <param name="external-docs" type="weblink | filepath">
72
+ Link or path to external system documentation.
73
+ Only used when external-codebase is also provided.
74
+ Provides supplementary context for external analysis.
75
+ </param>
76
+ <param name="lib-docs" type="weblinks and/or filepaths">
77
+ Space-separated string of weblinks and/or file paths to library or API documentation.
78
+ These are injected into the story's Relevant Wiki section as a
79
+ `### Library Documentation` subsection after pass 2 completes,
80
+ so that passes 4-5 (integration analysis, technical solution) can
81
+ reference them when designing the implementation.
82
+ Useful for third-party libraries, SDK docs, or API references
83
+ that inform how the story should be built.
84
+ </param>
85
+ </optional>
86
+ </parameters>
87
+ </input>
88
+
89
+ <execution-context>
90
+ <!-- All supporting files are auto-loaded in the Supporting Resources section above.
91
+ The model does NOT need to Read these files they are already in context. -->
92
+ </execution-context>
93
+
94
+ <output>
95
+ <objective>
96
+ Take a story seed (stub file, GitHub issue, or any text description) and produce
97
+ a COMPLETE story specification through deep questioning that ensures:
98
+ - ZERO ASSUMPTIONS — every behavior is explicitly specified
99
+ - CRYSTAL-CLEAR acceptance criteria with exact triggers, preconditions, outcomes
100
+ - INVEST compliance — Independent, Negotiable, Valuable, Estimable, Small, Testable
101
+ - Gherkin scenarios cover happy paths, edge cases, AND error paths
102
+
103
+ After story requirements are defined (pass 1), dispatch research passes 2-5
104
+ as background agents:
105
+ - Pass 2: Wiki research (updates story file with Relevant Wiki section)
106
+ - Pass 3: External analysis (OPTIONAL — creates external-analysis.md)
107
+ - Pass 4: Integration analysis (creates integration-analysis.md)
108
+ - Pass 5: Technical solution (appends to story file)
109
+
110
+ Each research pass writes directly to disk. The orchestrator context window
111
+ contains ONLY story requirements — research outputs do NOT flow back.
112
+ </objective>
113
+
114
+ <artifacts>
115
+ .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/&lt;id-story_name&gt;.md
116
+ .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/external-analysis.md (OPTIONAL)
117
+ .ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/integration-analysis.md
118
+ </artifacts>
119
+ </output>
120
+
121
+ <process>
122
+ For this command use the `ace-product-owner` agent
123
+ that's specialized in requirements gathering, deep questioning, and story specification.
124
+
125
+ Execute the plan-story workflow from
126
+ `workflow.xml` end-to-end.
127
+ Preserve all workflow gates (validation, approvals, commits).
128
+
129
+ **CRITICAL — Context Window Protection:**
130
+ Passes 2-5 run as background agents. Each agent writes output directly to files.
131
+ The orchestrator MUST NOT call TaskOutput on any background agent.
132
+ The orchestrator only needs to know when each pass finishes to start the next one.
133
+
134
+ **Pass execution order:**
135
+ Pass 2 + Pass 3 (if applicable) → wait → Pass 4 → wait → Pass 5 → wait → done
136
+ </process>
137
+
138
+ <example-usage>
139
+ ```
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * plan-story skill script — Entry point for all ace-tools operations
5
+ * needed by the plan-story skill.
6
+ *
7
+ * Subcommands:
8
+ * init [story-param] Environment detection for plan-story workflow
9
+ * update-state story=X status=Y Update story status across files
10
+ * sync-github repo=X story_file=Y Sync story/feature to GitHub
11
+ * resolve-model <agent-type> Get model for agent based on profile
12
+ *
13
+ * Usage: node script.js <subcommand> [args] [--raw]
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const {
20
+ loadConfig, pathExists, safeReadFile, generateSlug, resolveModel,
21
+ detectBrownfieldStatus, loadSettings, execCommand,
22
+ output, error, runSkillScript,
23
+ } = require('../../shared/lib/ace-core');
24
+
25
+ const {
26
+ classifyStoryParam, extractStoryMetadata, extractStoryRequirements,
27
+ extractIssueNumber, extractIssueNumberFromFile, computeStoryPaths,
28
+ updateState,
29
+ } = require('../../shared/lib/ace-story');
30
+
31
+ const { syncStory, resolveFields, createIssue } = require('../../shared/lib/ace-github');
32
+
33
+ // ─── CLI Dispatch ────────────────────────────────────────────────────────────
34
+
35
+ runSkillScript({
36
+ init: cmdInit,
37
+ 'update-state': (cwd, raw, args) => updateState(cwd, raw, args),
38
+ 'sync-github': (cwd, raw, args) => syncStory(cwd, raw, args),
39
+ 'resolve-model': (cwd, raw, args, parsed) => {
40
+ const agentType = parsed._positional || args[0];
41
+ if (!agentType) error('resolve-model requires agent-type argument');
42
+ const model = resolveModel(cwd, agentType);
43
+ output({ model, agent: agentType }, raw, model);
44
+ },
45
+ 'generate-slug': (cwd, raw, args, parsed) => {
46
+ const text = parsed._positional || args.join(' ');
47
+ if (!text) error('generate-slug requires text argument');
48
+ const slug = generateSlug(text);
49
+ output({ slug }, raw, slug);
50
+ },
51
+ 'resolve-fields': (cwd, raw, args) => resolveFields(cwd, raw, args),
52
+ 'create-issue': (cwd, raw, args) => createIssue(cwd, raw, args),
53
+ });
54
+
55
+ // ─── Init: Plan Story ────────────────────────────────────────────────────────
56
+
57
+ /**
58
+ * Environment detection for the plan-story workflow.
59
+ *
60
+ * Detects: git, gh CLI, GitHub project, brownfield status, wiki state,
61
+ * product artifacts, and story source/content/metadata.
62
+ *
63
+ * Supports three input modes:
64
+ * - story param provided → loads existing file or fetches GitHub issue
65
+ * - text param provided (no story) → uses inline text as seed description
66
+ * - neither → new story mode, workflow handles placement
67
+ *
68
+ * initArgs: array of arguments — either a single positional path/URL,
69
+ * or key=value pairs (story=X text=Y)
70
+ */
71
+ function cmdInit(cwd, raw, args, parsed) {
72
+ const config = loadConfig(cwd);
73
+ const brownfield = detectBrownfieldStatus(cwd);
74
+
75
+ // ── Environment detection ──
76
+ const has_git = pathExists(cwd, '.git');
77
+ const has_gh_cli = (() => {
78
+ try {
79
+ const { execSync } = require('child_process');
80
+ execSync('gh --version', { stdio: 'pipe' });
81
+ return true;
82
+ } catch { return false; }
83
+ })();
84
+ const github_project = loadSettings(cwd).github_project;
85
+
86
+ // Wiki detection
87
+ const wikiSystemDir = '.docs/wiki/system-wide';
88
+ const has_wiki_system_wide = pathExists(cwd, wikiSystemDir);
89
+ const wikiSubsystemsDir = '.docs/wiki/subsystems';
90
+ const has_wiki_subsystems = pathExists(cwd, wikiSubsystemsDir);
91
+ let wiki_subsystem_names = [];
92
+ if (has_wiki_subsystems) {
93
+ try {
94
+ const entries = fs.readdirSync(path.join(cwd, wikiSubsystemsDir), { withFileTypes: true });
95
+ wiki_subsystem_names = entries.filter(e => e.isDirectory()).map(e => e.name);
96
+ } catch {}
97
+ }
98
+ const has_wiki = has_wiki_system_wide || has_wiki_subsystems;
99
+
100
+ // ── Parse input from shared parsed args ──
101
+ const resolvedStoryParam = parsed.story || parsed._positional || null;
102
+ const textParam = parsed.text || null;
103
+
104
+ // ── Base result (shared across all modes) ──
105
+ const baseResult = {
106
+ product_owner_model: resolveModel(cwd, 'ace-product-owner'),
107
+ commit_docs: config.commit_docs,
108
+ has_git, has_gh_cli, github_project,
109
+ ...brownfield,
110
+ has_wiki, has_wiki_system_wide, has_wiki_subsystems, wiki_subsystem_names,
111
+ has_product_vision: pathExists(cwd, '.docs/product/product-vision.md'),
112
+ has_product_backlog: pathExists(cwd, '.ace/artifacts/product/product-backlog.md'),
113
+ };
114
+
115
+ // ── Mode 1: No story param and no text → new story mode ──
116
+ if (!resolvedStoryParam && !textParam) {
117
+ output({
118
+ ...baseResult,
119
+ story_source: 'new',
120
+ story_valid: true,
121
+ story_error: null,
122
+ story_content: null,
123
+ story: { id: null, title: null, status: null, size: null, issue_number: null },
124
+ feature: { id: null, title: null, issue_number: null },
125
+ epic: { id: null, title: null },
126
+ user_story: null, description: null, acceptance_criteria_count: 0,
127
+ paths: null,
128
+ has_external_analysis: false, has_integration_analysis: false,
129
+ has_feature_file: false, has_story_file: false,
130
+ }, raw);
131
+ return;
132
+ }
133
+
134
+ // ── Mode 2: Text param only → use text as seed description ──
135
+ if (!resolvedStoryParam && textParam) {
136
+ output({
137
+ ...baseResult,
138
+ story_source: 'text',
139
+ story_valid: true,
140
+ story_error: null,
141
+ story_content: textParam,
142
+ story: { id: null, title: null, status: null, size: null, issue_number: null },
143
+ feature: { id: null, title: null, issue_number: null },
144
+ epic: { id: null, title: null },
145
+ user_story: null, description: textParam, acceptance_criteria_count: 0,
146
+ paths: null,
147
+ has_external_analysis: false, has_integration_analysis: false,
148
+ has_feature_file: false, has_story_file: false,
149
+ }, raw);
150
+ return;
151
+ }
152
+
153
+ // ── Mode 3: Story param provided → classify and load ──
154
+ const classified = classifyStoryParam(resolvedStoryParam);
155
+
156
+ // Invalid param
157
+ if (classified.type === null || classified.type === 'invalid') {
158
+ output({
159
+ ...baseResult,
160
+ story_source: null,
161
+ story_valid: false,
162
+ story_error: classified.reason || 'No story parameter provided',
163
+ story_content: null,
164
+ story: { id: null, title: null, status: null, size: null, issue_number: null },
165
+ feature: { id: null, title: null, issue_number: null },
166
+ epic: { id: null, title: null },
167
+ user_story: null, description: null, acceptance_criteria_count: 0,
168
+ paths: null,
169
+ has_external_analysis: false, has_integration_analysis: false,
170
+ has_feature_file: false, has_story_file: false,
171
+ }, raw);
172
+ return;
173
+ }
174
+
175
+ // ── Load story content ──
176
+ let storyContent = null;
177
+ let storySource = classified.type === 'file' ? 'file' : 'github';
178
+ let storyError = null;
179
+ let storyFilePath = null;
180
+
181
+ if (classified.type === 'file') {
182
+ const resolvedPath = path.isAbsolute(classified.filePath)
183
+ ? classified.filePath
184
+ : path.join(cwd, classified.filePath);
185
+ if (!pathExists(cwd, classified.filePath)) {
186
+ storyError = `Story file not found: ${classified.filePath}`;
187
+ } else {
188
+ storyContent = safeReadFile(resolvedPath);
189
+ storyFilePath = classified.filePath;
190
+ if (!storyContent) storyError = `Could not read story file: ${classified.filePath}`;
191
+ }
192
+ } else {
193
+ // github-url or issue-number
194
+ if (!has_gh_cli) {
195
+ storyError = 'GitHub CLI (gh) not installed. Cannot fetch GitHub issues.';
196
+ } else {
197
+ const repo = classified.repo || (github_project.repo || null);
198
+ if (!repo) {
199
+ storyError = 'No repository configured. Provide a full GitHub URL or configure github_project.repo in settings.';
200
+ } else {
201
+ const ghResult = execCommand(
202
+ `gh issue view ${classified.issueNumber} --repo ${repo} --json title,body,labels,state`,
203
+ cwd
204
+ );
205
+ if (!ghResult) {
206
+ storyError = `Could not fetch GitHub issue #${classified.issueNumber} from ${repo}.`;
207
+ } else {
208
+ try {
209
+ const issue = JSON.parse(ghResult);
210
+ storyContent = issue.body || '';
211
+ if (storyContent && !storyContent.match(/^#\s+/m)) {
212
+ storyContent = `# ${issue.title}\n\n${storyContent}`;
213
+ }
214
+ } catch {
215
+ storyError = `Failed to parse GitHub issue response for #${classified.issueNumber}.`;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
221
+
222
+ // ── Extract metadata & requirements ──
223
+ const metadata = extractStoryMetadata(storyContent);
224
+ const requirements = extractStoryRequirements(storyContent);
225
+
226
+ // ── Compute paths ──
227
+ let paths = null;
228
+ let has_story_file = false;
229
+
230
+ if (storyFilePath) {
231
+ const resolvedPath = path.isAbsolute(storyFilePath)
232
+ ? storyFilePath
233
+ : path.join(cwd, storyFilePath);
234
+ const storyDir = path.dirname(resolvedPath);
235
+ const relStoryDir = path.relative(cwd, storyDir).replace(/\\/g, '/');
236
+ const storySlug = path.basename(storyDir);
237
+ const featureDir = path.dirname(storyDir);
238
+ const relFeatureDir = path.relative(cwd, featureDir).replace(/\\/g, '/');
239
+ const featureSlug = path.basename(featureDir);
240
+
241
+ paths = {
242
+ epic_slug: null,
243
+ feature_slug: featureSlug,
244
+ story_slug: storySlug,
245
+ story_dir: relStoryDir,
246
+ story_file: storyFilePath.replace(/\\/g, '/'),
247
+ external_analysis_file: `${relStoryDir}/external-analysis.md`,
248
+ integration_analysis_file: `${relStoryDir}/integration-analysis.md`,
249
+ feature_dir: relFeatureDir,
250
+ feature_file: `${relFeatureDir}/${featureSlug}.md`,
251
+ };
252
+ has_story_file = true;
253
+ } else if (metadata.epic.id && metadata.feature.id && metadata.id) {
254
+ paths = computeStoryPaths(
255
+ metadata.epic.id, metadata.epic.title || '',
256
+ metadata.feature.id, metadata.feature.title || '',
257
+ metadata.id, metadata.title || ''
258
+ );
259
+ has_story_file = paths ? pathExists(cwd, paths.story_file) : false;
260
+ }
261
+
262
+ // ── Check artifact existence ──
263
+ const has_external_analysis = paths ? pathExists(cwd, paths.external_analysis_file) : false;
264
+ const has_integration_analysis = paths ? pathExists(cwd, paths.integration_analysis_file) : false;
265
+ const has_feature_file = paths ? pathExists(cwd, paths.feature_file) : false;
266
+
267
+ // ── Build result ──
268
+ output({
269
+ ...baseResult,
270
+ story_source: storySource,
271
+ story_valid: storyContent !== null && storyError === null,
272
+ story_error: storyError,
273
+ story_content: storyContent,
274
+ story: {
275
+ id: metadata.id,
276
+ title: metadata.title,
277
+ status: metadata.status,
278
+ size: metadata.size,
279
+ issue_number: extractIssueNumber(metadata.link),
280
+ },
281
+ feature: {
282
+ ...metadata.feature,
283
+ issue_number: paths ? extractIssueNumberFromFile(cwd, paths.feature_file) : null,
284
+ },
285
+ epic: metadata.epic,
286
+ user_story: requirements.user_story,
287
+ description: requirements.description,
288
+ acceptance_criteria_count: requirements.acceptance_criteria_count,
289
+ paths,
290
+ has_external_analysis,
291
+ has_integration_analysis,
292
+ has_feature_file,
293
+ has_story_file,
294
+ }, raw);
295
+ }