claude-autopm 3.0.0 → 3.0.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.
package/README.md CHANGED
@@ -268,9 +268,14 @@ autopm install
268
268
  autopm config set provider github
269
269
  autopm config set github.owner YOUR_USERNAME
270
270
  autopm config set github.repo YOUR_REPO
271
- export GITHUB_TOKEN=your_github_token
272
271
 
273
- # 5. Open Claude Code
272
+ # Add your token to .claude/.env (recommended) or export directly
273
+ echo "GITHUB_TOKEN=your_github_token" >> .claude/.env
274
+
275
+ # 5. Verify configuration
276
+ autopm config validate
277
+
278
+ # 6. Open Claude Code
274
279
  claude --dangerously-skip-permissions .
275
280
  ```
276
281
 
package/bin/autopm.js CHANGED
@@ -278,12 +278,22 @@ function main() {
278
278
  autopm config set provider github
279
279
  autopm config set github.owner <username>
280
280
  autopm config set github.repo <repository>
281
+
282
+ # Add token to .claude/.env (recommended)
283
+ echo "GITHUB_TOKEN=ghp_your_token_here" >> .claude/.env
284
+
285
+ # Or export as environment variable
281
286
  export GITHUB_TOKEN=ghp_your_token_here
282
287
 
283
288
  # Configure Azure DevOps provider
284
289
  autopm config set provider azure
285
290
  autopm config set azure.organization <org>
286
291
  autopm config set azure.project <project>
292
+
293
+ # Add token to .claude/.env (recommended)
294
+ echo "AZURE_DEVOPS_PAT=your_azure_pat" >> .claude/.env
295
+
296
+ # Or export as environment variable
287
297
  export AZURE_DEVOPS_PAT=your_azure_pat
288
298
 
289
299
  # Quick switch between providers
@@ -312,6 +322,13 @@ function main() {
312
322
  autopm mcp status # Show all MCP servers status
313
323
 
314
324
  šŸ”‘ Token Setup:
325
+ # RECOMMENDED: Store tokens in .claude/.env file
326
+ echo "GITHUB_TOKEN=ghp_your_token" >> .claude/.env
327
+ echo "AZURE_DEVOPS_PAT=your_pat" >> .claude/.env
328
+
329
+ # The .env file is automatically loaded during validation
330
+ autopm config validate
331
+
315
332
  # GitHub PAT (Settings → Developer settings → Personal access tokens)
316
333
  Scopes: repo, workflow, admin:repo_hook
317
334
 
@@ -7,11 +7,28 @@
7
7
 
8
8
  const fs = require('fs-extra');
9
9
  const path = require('path');
10
+ const dotenv = require('dotenv');
10
11
 
11
12
  class ConfigCommand {
12
13
  constructor() {
13
14
  this.configPath = path.join(process.cwd(), '.claude', 'config.json');
14
15
  this.envPath = path.join(process.cwd(), '.claude', '.env');
16
+
17
+ // Load .env file if it exists
18
+ this.loadEnv();
19
+ }
20
+
21
+ /**
22
+ * Load environment variables from .claude/.env
23
+ */
24
+ loadEnv() {
25
+ try {
26
+ if (fs.existsSync(this.envPath)) {
27
+ dotenv.config({ path: this.envPath });
28
+ }
29
+ } catch (error) {
30
+ // Silently ignore - env file is optional
31
+ }
15
32
  }
16
33
 
17
34
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-autopm",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Autonomous Project Management Framework for Claude Code - Advanced AI-powered development automation",
5
5
  "main": "bin/autopm.js",
6
6
  "workspaces": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-cloud",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Complete cloud infrastructure plugin with agents for AWS, Azure, GCP, Kubernetes, Terraform, and infrastructure automation for ClaudeAutoPM",
5
5
  "main": "plugin.json",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-core",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Core framework functionality for ClaudeAutoPM - universal agents, rules, hooks, and utilities",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-data",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Complete data engineering plugin with Airflow, Kedro, LangGraph, Kafka, dbt, pandas experts, data quality rules, and example scripts for ClaudeAutoPM",
5
5
  "main": "plugin.json",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-databases",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Complete database plugin with PostgreSQL, MongoDB, Redis, BigQuery, and Cosmos DB experts, database rules, and optimization scripts for ClaudeAutoPM",
5
5
  "main": "plugin.json",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-devops",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Complete DevOps plugin with agents, commands, rules, and scripts for CI/CD, Docker, GitHub, observability, and infrastructure automation for ClaudeAutoPM",
5
5
  "main": "plugin.json",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-ml",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Comprehensive Machine Learning plugin with 10 specialist agents: TensorFlow/Keras, PyTorch, RL, Scikit-learn, Neural Architecture, Gradient Boosting, Computer Vision, NLP Transformers, Time Series, and AutoML. Context7-verified patterns.",
5
5
  "main": "plugin.json",
6
6
  "scripts": {
@@ -45,75 +45,120 @@ See `.claude/rules/tdd.enforcement.md` for complete requirements.
45
45
 
46
46
  ### 1. Validate Prerequisites
47
47
 
48
- Check that epic exists and hasn't been processed:
49
48
  ```bash
50
- # Epic must exist
51
- test -f .claude/epics/$ARGUMENTS/epic.md || echo "āŒ Epic not found. Run: /pm:prd-parse $ARGUMENTS"
52
-
53
- # Check for existing tasks
54
- if ls .claude/epics/$ARGUMENTS/[0-9]*.md 2>/dev/null | grep -q .; then
55
- echo "āš ļø Tasks already exist. This will create duplicates."
56
- echo "Delete existing tasks or use /pm:epic-sync instead."
49
+ # Check if PRD exists
50
+ if [ ! -f ".claude/prds/$ARGUMENTS.md" ]; then
51
+ echo "āŒ PRD not found: $ARGUMENTS.md"
52
+ echo "šŸ’” Create it first with: /pm:prd-new $ARGUMENTS"
57
53
  exit 1
58
54
  fi
59
55
 
60
- # Check if already synced
61
- if grep -q "github:" .claude/epics/$ARGUMENTS/epic.md; then
62
- echo "āš ļø Epic already synced to GitHub."
63
- echo "Use /pm:epic-sync to update."
56
+ echo "āœ… PRD found"
57
+
58
+ # Check if epic already exists
59
+ if [ -f ".claude/epics/$ARGUMENTS/epic.md" ]; then
60
+ echo "āš ļø Epic already exists: $ARGUMENTS"
61
+ echo "šŸ’” View it with: /pm:epic-show $ARGUMENTS"
62
+ echo "šŸ’” Or use a different name"
64
63
  exit 1
65
64
  fi
65
+
66
+ echo "āœ… Ready to create epic"
66
67
  ```
67
68
 
68
- ### 2. Execute Decompose
69
+ ### 2. Execute Epic Oneshot Script
69
70
 
70
- Simply run the decompose command:
71
+ Run the all-in-one script that handles:
72
+ - PRD parsing
73
+ - Task decomposition
74
+ - GitHub/Azure sync
75
+
76
+ ```bash
77
+ node .claude/scripts/pm/epic-oneshot.cjs $ARGUMENTS
71
78
  ```
72
- Running: /pm:epic-decompose $ARGUMENTS
79
+
80
+ ### 3. Verify Success
81
+
82
+ ```bash
83
+ # Check epic was created
84
+ if [ -f ".claude/epics/$ARGUMENTS/epic.md" ]; then
85
+ echo ""
86
+ echo "āœ… Epic Oneshot Complete!"
87
+ echo ""
88
+ echo "šŸ“‹ Next steps:"
89
+ echo " • View epic: /pm:epic-show $ARGUMENTS"
90
+ echo " • Start work: /pm:epic-start $ARGUMENTS"
91
+ echo " • Get next task: /pm:next"
92
+ echo ""
93
+ else
94
+ echo "āŒ Epic creation failed. Check output above for errors."
95
+ exit 1
96
+ fi
73
97
  ```
74
98
 
75
- This will:
76
- - Read the epic
77
- - Create task files (using parallel agents if appropriate)
78
- - Update epic with task summary
99
+ ## What It Does
79
100
 
80
- ### 3. Execute Sync
101
+ This command executes a complete workflow in one operation:
81
102
 
82
- Immediately follow with sync:
83
- ```
84
- Running: /pm:epic-sync $ARGUMENTS
85
- ```
103
+ **Step 1: Parse PRD**
104
+ - Reads `.claude/prds/$ARGUMENTS.md`
105
+ - Extracts features, requirements, technical details
106
+ - Creates epic structure
107
+
108
+ **Step 2: Decompose Tasks**
109
+ - Analyzes epic content
110
+ - Generates implementation tasks
111
+ - Adds tasks to epic.md
86
112
 
87
- This will:
88
- - Create epic issue on GitHub
89
- - Create sub-issues (using parallel agents if appropriate)
90
- - Rename task files to issue IDs
91
- - Create epic branch
113
+ **Step 3: Sync to Provider**
114
+ - Creates epic issue on GitHub/Azure
115
+ - Creates sub-issues for each task
116
+ - Links everything together
92
117
 
93
- ### 4. Output
118
+ ## Output Structure
119
+
120
+ After successful execution:
94
121
 
95
122
  ```
96
- šŸš€ Epic Oneshot Complete: $ARGUMENTS
97
-
98
- Step 1: Decomposition āœ“
99
- - Tasks created: {count}
100
-
101
- Step 2: GitHub Sync āœ“
102
- - Epic: #{number}
103
- - Sub-issues created: {count}
104
- - Branch: epic/$ARGUMENTS
105
-
106
- Ready for development!
107
- Start work: /pm:epic-start $ARGUMENTS
108
- Or single task: /pm:issue-start {task_number}
123
+ .claude/
124
+ epics/
125
+ <feature-name>/
126
+ epic.md # Main epic with embedded tasks
127
+ metadata.json # Epic metadata
128
+ tasks/ # Individual task files (if created)
129
+ ```
130
+
131
+ ## Example Usage
132
+
133
+ ```bash
134
+ # Complete workflow in one command
135
+ /pm:epic-oneshot gym-trading-env
136
+
137
+ # What happens:
138
+ # 1. Parses .claude/prds/gym-trading-env.md
139
+ # 2. Creates .claude/epics/gym-trading-env/epic.md
140
+ # 3. Generates implementation tasks
141
+ # 4. Syncs to GitHub/Azure DevOps
142
+ # 5. Ready to start work!
109
143
  ```
110
144
 
111
145
  ## Important Notes
112
146
 
113
- This is simply a convenience wrapper that runs:
114
- 1. `/pm:epic-decompose`
115
- 2. `/pm:epic-sync`
147
+ **Advantages of Oneshot:**
148
+ - āœ… Fastest way from PRD to implementation
149
+ - āœ… No manual intervention needed
150
+ - āœ… Automatic task generation
151
+ - āœ… Immediate GitHub sync
116
152
 
117
- Both commands handle their own error checking, parallel execution, and validation. This command just orchestrates them in sequence.
153
+ **When NOT to use:**
154
+ - āŒ Complex PRDs needing manual review between steps
155
+ - āŒ Custom task decomposition required
156
+ - āŒ Learning the PM workflow (use step-by-step instead)
118
157
 
119
- Use this when you're confident the epic is ready and want to go from epic to GitHub issues in one step.
158
+ **Alternative: Step-by-Step**
159
+ ```bash
160
+ # If you prefer manual control:
161
+ /pm:prd-parse <feature> # Step 1: Create epic
162
+ /pm:epic-decompose <feature> # Step 2: Add tasks (if available)
163
+ /pm:epic-sync <feature> # Step 3: Sync to provider
164
+ ```
@@ -0,0 +1,345 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Epic Oneshot - One-command workflow: Parse PRD → Decompose → Sync
4
+ *
5
+ * Usage: node epic-oneshot.js <feature-name> [options]
6
+ *
7
+ * This script combines three operations:
8
+ * 1. Parse PRD into epic structure
9
+ * 2. Decompose epic into implementation tasks
10
+ * 3. Sync to GitHub/Azure DevOps
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { execSync } = require('child_process');
16
+
17
+ class EpicOneshot {
18
+ constructor() {
19
+ this.scriptsDir = __dirname;
20
+ this.claudeDir = path.join(process.cwd(), '.claude');
21
+ this.prdsDir = path.join(this.claudeDir, 'prds');
22
+ this.epicsDir = path.join(this.claudeDir, 'epics');
23
+ }
24
+
25
+ log(message, emoji = 'šŸ“‹') {
26
+ console.log(`${emoji} ${message}`);
27
+ }
28
+
29
+ error(message) {
30
+ console.error(`āŒ ${message}`);
31
+ }
32
+
33
+ success(message) {
34
+ console.log(`āœ… ${message}`);
35
+ }
36
+
37
+ async step1ParsePRD(featureName) {
38
+ this.log('Step 1/3: Parsing PRD into epic...', 'šŸ”„');
39
+ console.log(`${'═'.repeat(50)}\n`);
40
+
41
+ const prdParseScript = path.join(this.scriptsDir, 'prd-parse.js');
42
+
43
+ if (!fs.existsSync(prdParseScript)) {
44
+ this.error('PRD parse script not found');
45
+ return false;
46
+ }
47
+
48
+ try {
49
+ execSync(`node "${prdParseScript}" ${featureName}`, {
50
+ stdio: 'inherit',
51
+ cwd: process.cwd()
52
+ });
53
+
54
+ // Verify epic was created
55
+ const epicFile = path.join(this.epicsDir, featureName, 'epic.md');
56
+ if (fs.existsSync(epicFile)) {
57
+ this.success('Epic created successfully');
58
+ return true;
59
+ } else {
60
+ this.error('Epic file not created');
61
+ return false;
62
+ }
63
+ } catch (error) {
64
+ this.error(`Failed to parse PRD: ${error.message}`);
65
+ return false;
66
+ }
67
+ }
68
+
69
+ async step2DecomposeTasks(featureName) {
70
+ this.log('Step 2/3: Decomposing epic into tasks...', 'šŸ”Ø');
71
+ console.log(`${'═'.repeat(50)}\n`);
72
+
73
+ const epicFile = path.join(this.epicsDir, featureName, 'epic.md');
74
+
75
+ if (!fs.existsSync(epicFile)) {
76
+ this.error('Epic file not found');
77
+ return false;
78
+ }
79
+
80
+ try {
81
+ // Read epic file
82
+ const epicContent = fs.readFileSync(epicFile, 'utf8');
83
+
84
+ // Check if tasks already exist
85
+ if (epicContent.includes('## Tasks') || epicContent.includes('## Implementation Tasks')) {
86
+ this.log('Tasks already exist in epic', 'ā„¹ļø');
87
+ return true;
88
+ }
89
+
90
+ // Generate tasks section
91
+ const tasksSection = this.generateTasksFromEpic(epicContent, featureName);
92
+
93
+ // Append tasks to epic
94
+ const updatedContent = epicContent + '\n\n' + tasksSection;
95
+ fs.writeFileSync(epicFile, updatedContent, 'utf8');
96
+
97
+ this.success('Tasks decomposed successfully');
98
+ return true;
99
+ } catch (error) {
100
+ this.error(`Failed to decompose tasks: ${error.message}`);
101
+ return false;
102
+ }
103
+ }
104
+
105
+ generateTasksFromEpic(epicContent, featureName) {
106
+ // Extract features and requirements from epic
107
+ const features = this.extractListItems(epicContent, 'Features');
108
+ const requirements = this.extractListItems(epicContent, 'Requirements');
109
+
110
+ let tasks = [];
111
+ let taskId = 1;
112
+
113
+ // Setup task
114
+ tasks.push({
115
+ id: taskId++,
116
+ title: 'Project setup and configuration',
117
+ description: 'Initialize project structure, dependencies, and development environment',
118
+ effort: '2h',
119
+ type: 'setup'
120
+ });
121
+
122
+ // Feature implementation tasks
123
+ features.forEach(feature => {
124
+ tasks.push({
125
+ id: taskId++,
126
+ title: `Implement: ${feature}`,
127
+ description: `Implementation for ${feature}`,
128
+ effort: '1d',
129
+ type: 'feature'
130
+ });
131
+ });
132
+
133
+ // Requirements implementation tasks
134
+ requirements.forEach(req => {
135
+ tasks.push({
136
+ id: taskId++,
137
+ title: `Requirement: ${req}`,
138
+ description: `Implementation for ${req}`,
139
+ effort: '1d',
140
+ type: 'requirement'
141
+ });
142
+ });
143
+
144
+ // Integration tasks
145
+ tasks.push({
146
+ id: taskId++,
147
+ title: 'Integration and API connections',
148
+ description: 'Connect components and integrate APIs',
149
+ effort: '1d',
150
+ type: 'integration'
151
+ });
152
+
153
+ // Testing task
154
+ tasks.push({
155
+ id: taskId++,
156
+ title: 'Testing and quality assurance',
157
+ description: 'Write tests, perform QA, and fix bugs',
158
+ effort: '1d',
159
+ type: 'testing'
160
+ });
161
+
162
+ // Deployment task
163
+ tasks.push({
164
+ id: taskId++,
165
+ title: 'Deployment and documentation',
166
+ description: 'Deploy to production and update documentation',
167
+ effort: '4h',
168
+ type: 'deployment'
169
+ });
170
+
171
+ // Format tasks as markdown
172
+ let tasksMarkdown = '## Implementation Tasks\n\n';
173
+ tasksMarkdown += '### Task Breakdown\n\n';
174
+
175
+ tasks.forEach(task => {
176
+ tasksMarkdown += `#### TASK-${String(task.id).padStart(3, '0')}: ${task.title}\n\n`;
177
+ tasksMarkdown += `**Type:** ${task.type}\n`;
178
+ tasksMarkdown += `**Effort:** ${task.effort}\n`;
179
+ tasksMarkdown += `**Description:** ${task.description}\n\n`;
180
+ });
181
+
182
+ return tasksMarkdown;
183
+ }
184
+
185
+ extractListItems(content, sectionName) {
186
+ const items = [];
187
+ const regex = new RegExp(`## ${sectionName}[\\s\\S]*?(?=##|$)`, 'i');
188
+ const match = content.match(regex);
189
+
190
+ if (match) {
191
+ const section = match[0];
192
+ const lines = section.split('\n');
193
+
194
+ lines.forEach(line => {
195
+ const trimmed = line.trim();
196
+ if (trimmed.match(/^[-*•]\s/) || trimmed.match(/^\d+\.\s/)) {
197
+ // Remove bullet points or numbers
198
+ let item = trimmed.replace(/^[-*•]\s+/, '').trim();
199
+ item = item.replace(/^\d+\.\s+/, '').trim();
200
+ if (item) items.push(item);
201
+ }
202
+ });
203
+ }
204
+
205
+ return items;
206
+ }
207
+
208
+ async step3SyncToProvider(featureName) {
209
+ this.log('Step 3/3: Syncing to GitHub/Azure DevOps...', 'šŸ”„');
210
+ console.log(`${'═'.repeat(50)}\n`);
211
+
212
+ // Check if sync script exists
213
+ const syncScript = path.join(this.scriptsDir, 'sync.js');
214
+ const epicSyncScript = path.join(this.scriptsDir, 'epic-sync.sh');
215
+
216
+ if (fs.existsSync(epicSyncScript)) {
217
+ try {
218
+ execSync(`bash "${epicSyncScript}" ${featureName}`, {
219
+ stdio: 'inherit',
220
+ cwd: process.cwd()
221
+ });
222
+ this.success('Epic synced to provider');
223
+ return true;
224
+ } catch (error) {
225
+ this.error(`Failed to sync: ${error.message}`);
226
+ return false;
227
+ }
228
+ } else if (fs.existsSync(syncScript)) {
229
+ try {
230
+ execSync(`node "${syncScript}" epic ${featureName}`, {
231
+ stdio: 'inherit',
232
+ cwd: process.cwd()
233
+ });
234
+ this.success('Epic synced to provider');
235
+ return true;
236
+ } catch (error) {
237
+ this.error(`Failed to sync: ${error.message}`);
238
+ return false;
239
+ }
240
+ } else {
241
+ this.log('Sync script not found - skipping provider sync', 'āš ļø');
242
+ this.log('Epic is ready locally. Use /pm:epic-sync to sync manually', 'ā„¹ļø');
243
+ return true; // Don't fail if sync not available
244
+ }
245
+ }
246
+
247
+ async run(featureName, options = {}) {
248
+ console.log('\n╔════════════════════════════════════════════════╗');
249
+ console.log('ā•‘ Epic Oneshot Workflow ā•‘');
250
+ console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n');
251
+
252
+ this.log(`Feature: ${featureName}`, 'šŸŽÆ');
253
+ console.log('\n');
254
+
255
+ // Validate PRD exists
256
+ const prdFile = path.join(this.prdsDir, `${featureName}.md`);
257
+ if (!fs.existsSync(prdFile)) {
258
+ this.error(`PRD not found: ${featureName}.md`);
259
+ this.log('Create it first with: /pm:prd-new ' + featureName, 'šŸ’”');
260
+ process.exit(1);
261
+ }
262
+
263
+ // Step 1: Parse PRD
264
+ const parseSuccess = await this.step1ParsePRD(featureName);
265
+ if (!parseSuccess) {
266
+ this.error('Failed at step 1 (Parse PRD)');
267
+ process.exit(1);
268
+ }
269
+ console.log('\n');
270
+
271
+ // Step 2: Decompose tasks
272
+ const decomposeSuccess = await this.step2DecomposeTasks(featureName);
273
+ if (!decomposeSuccess) {
274
+ this.error('Failed at step 2 (Decompose tasks)');
275
+ process.exit(1);
276
+ }
277
+ console.log('\n');
278
+
279
+ // Step 3: Sync to provider (optional)
280
+ if (!options.noSync) {
281
+ await this.step3SyncToProvider(featureName);
282
+ } else {
283
+ this.log('Skipping sync (--no-sync flag)', 'ā„¹ļø');
284
+ }
285
+
286
+ console.log('\n╔════════════════════════════════════════════════╗');
287
+ console.log('ā•‘ Epic Oneshot Complete! ✨ ā•‘');
288
+ console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n');
289
+
290
+ this.log('Next steps:', 'šŸ“‹');
291
+ console.log(` • View epic: /pm:epic-show ${featureName}`);
292
+ console.log(` • Get next task: /pm:next`);
293
+ console.log(` • View status: /pm:status`);
294
+ console.log('');
295
+ }
296
+ }
297
+
298
+ // CLI execution
299
+ if (require.main === module) {
300
+ const args = process.argv.slice(2);
301
+
302
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
303
+ console.log(`
304
+ ╔════════════════════════════════════════════════╗
305
+ ā•‘ Epic Oneshot - Quick Start ā•‘
306
+ ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•
307
+
308
+ Usage: node epic-oneshot.js <feature-name> [options]
309
+
310
+ Options:
311
+ --no-sync Skip syncing to GitHub/Azure DevOps
312
+ --help Show this help message
313
+
314
+ Example:
315
+ node epic-oneshot.js user-authentication
316
+ node epic-oneshot.js my-feature --no-sync
317
+
318
+ What it does:
319
+ 1. šŸ”„ Parses PRD into epic structure
320
+ 2. šŸ”Ø Decomposes epic into implementation tasks
321
+ 3. šŸ”„ Syncs to GitHub/Azure DevOps
322
+
323
+ Prerequisites:
324
+ • PRD must exist in .claude/prds/<feature-name>.md
325
+ • Create with: /pm:prd-new <feature-name>
326
+ `);
327
+ process.exit(0);
328
+ }
329
+
330
+ const featureName = args[0];
331
+ const options = {
332
+ noSync: args.includes('--no-sync')
333
+ };
334
+
335
+ const oneshot = new EpicOneshot();
336
+ oneshot.run(featureName, options).catch(error => {
337
+ console.error('āŒ Fatal error:', error.message);
338
+ if (process.env.DEBUG) {
339
+ console.error(error.stack);
340
+ }
341
+ process.exit(1);
342
+ });
343
+ }
344
+
345
+ module.exports = EpicOneshot;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-testing",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Testing frameworks, E2E testing, and quality assurance specialists",
5
5
  "keywords": [
6
6
  "claudeautopm",