claude-autopm 2.11.1 → 2.12.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 (26) hide show
  1. package/autopm/.claude/hooks/pre-action-agent-reminder.js +222 -0
  2. package/autopm/.claude/hooks/pre-commit-clear-reminder.sh +68 -0
  3. package/autopm/.claude/rules/agent-mandatory.md +80 -1
  4. package/autopm/.claude/rules/context-hygiene.md +270 -0
  5. package/autopm/.claude/scripts/check-clear-reminder.sh +42 -0
  6. package/autopm/.claude/templates/claude-templates/addons/task-workflow.md +40 -537
  7. package/package.json +1 -1
  8. package/packages/plugin-pm/commands/pm:blocked.md +4 -0
  9. package/packages/plugin-pm/commands/pm:context.md +4 -0
  10. package/packages/plugin-pm/commands/pm:epic-list.md +4 -0
  11. package/packages/plugin-pm/commands/pm:epic-show.md +4 -0
  12. package/packages/plugin-pm/commands/pm:epic-split.md +12 -1
  13. package/packages/plugin-pm/commands/pm:epic-status.md +4 -0
  14. package/packages/plugin-pm/commands/pm:help.md +4 -0
  15. package/packages/plugin-pm/commands/pm:in-progress.md +4 -0
  16. package/packages/plugin-pm/commands/pm:init.md +4 -0
  17. package/packages/plugin-pm/commands/pm:next.md +4 -0
  18. package/packages/plugin-pm/commands/pm:prd-list.md +4 -0
  19. package/packages/plugin-pm/commands/pm:prd-status.md +4 -0
  20. package/packages/plugin-pm/commands/pm:search.md +4 -0
  21. package/packages/plugin-pm/commands/pm:standup.md +4 -0
  22. package/packages/plugin-pm/commands/pm:status.md +4 -0
  23. package/packages/plugin-pm/commands/pm:validate.md +4 -0
  24. package/packages/plugin-pm/commands/pm:what-next.md +4 -0
  25. package/packages/plugin-pm/package.json +1 -1
  26. package/scripts/fix-command-instructions.js +221 -0
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/epic-status.js $ARGUMENTS` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/help.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/in-progress.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/init.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/next.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/prd-list.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/prd-status.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/search.js $ARGUMENTS` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/standup.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/status.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/validate.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -2,6 +2,10 @@
2
2
  allowed-tools: Bash
3
3
  ---
4
4
 
5
+ ---
6
+
7
+ ## Instructions
8
+
5
9
  Run `node .claude/scripts/pm/what-next.js` using the Bash tool and show me the complete output.
6
10
 
7
11
  - DO NOT truncate.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudeautopm/plugin-pm",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Complete project management plugin with PM workflows, epic management, issue tracking, and release automation for ClaudeAutoPM",
5
5
  "main": "plugin.json",
6
6
  "type": "module",
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs').promises;
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Fix PM commands missing proper ## Instructions sections
8
+ *
9
+ * This script:
10
+ * 1. Scans all PM commands
11
+ * 2. Identifies commands with corresponding .js scripts
12
+ * 3. Adds proper ## Instructions sections where missing
13
+ * 4. Fixes malformed instruction sections
14
+ */
15
+
16
+ const colors = {
17
+ reset: '\x1b[0m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ red: '\x1b[31m',
21
+ cyan: '\x1b[36m',
22
+ gray: '\x1b[90m'
23
+ };
24
+
25
+ // Template for Instructions section
26
+ function generateInstructionsSection(scriptName, commandName) {
27
+ return `
28
+
29
+ ---
30
+
31
+ ## Instructions
32
+
33
+ Run \`node .claude/scripts/pm/${scriptName}.js $ARGUMENTS\` using the Bash tool and show me the complete output.
34
+
35
+ - You MUST display the complete output.
36
+ - DO NOT truncate.
37
+ - DO NOT collapse.
38
+ - DO NOT abbreviate.`;
39
+ }
40
+
41
+ // Check if file has proper ## Instructions section
42
+ async function hasProperInstructions(filePath) {
43
+ const content = await fs.readFile(filePath, 'utf8');
44
+
45
+ // Check for ## Instructions header
46
+ const hasHeader = /^## Instructions$/m.test(content);
47
+
48
+ // Check for node .claude/scripts/pm/ call
49
+ const hasNodeCall = /node \.claude\/scripts\/pm\//.test(content);
50
+
51
+ return { hasHeader, hasNodeCall, content };
52
+ }
53
+
54
+ // Fix command file by adding Instructions section
55
+ async function fixCommandFile(commandPath, scriptName, dryRun = false) {
56
+ const { hasHeader, hasNodeCall, content } = await hasProperInstructions(commandPath);
57
+
58
+ if (hasHeader && hasNodeCall) {
59
+ return { status: 'ok', message: 'Already has proper Instructions section' };
60
+ }
61
+
62
+ let newContent = content;
63
+
64
+ if (!hasHeader && !hasNodeCall) {
65
+ // No instructions at all - add at the end
66
+ const commandName = path.basename(commandPath, '.md').replace('pm:', '');
67
+ const instructions = generateInstructionsSection(scriptName, commandName);
68
+ newContent = content.trimEnd() + instructions + '\n';
69
+
70
+ if (!dryRun) {
71
+ await fs.writeFile(commandPath, newContent);
72
+ }
73
+
74
+ return { status: 'added', message: 'Added missing Instructions section' };
75
+ } else if (hasNodeCall && !hasHeader) {
76
+ // Has instructions but no proper header - fix structure
77
+ // Find where the node call is and add header before it
78
+ const nodeCallMatch = content.match(/(Run `node \.claude\/scripts\/pm\/.*?`)/);
79
+ if (nodeCallMatch) {
80
+ const nodeCallLine = nodeCallMatch[0];
81
+ newContent = content.replace(
82
+ nodeCallLine,
83
+ `---\n\n## Instructions\n\n${nodeCallLine}`
84
+ );
85
+
86
+ if (!dryRun) {
87
+ await fs.writeFile(commandPath, newContent);
88
+ }
89
+
90
+ return { status: 'fixed', message: 'Added missing ## Instructions header' };
91
+ }
92
+ }
93
+
94
+ return { status: 'skip', message: 'No action needed' };
95
+ }
96
+
97
+ async function main() {
98
+ const dryRun = process.argv.includes('--dry-run');
99
+ const targetDir = process.argv.find(arg => !arg.startsWith('--') && arg !== process.argv[0] && arg !== process.argv[1]);
100
+
101
+ console.log(`${colors.cyan}🔧 Fixing PM Command Instructions Sections${colors.reset}`);
102
+ console.log(`Mode: ${dryRun ? colors.yellow + 'DRY RUN' : colors.green + 'LIVE'}${colors.reset}\n`);
103
+
104
+ // Determine project root
105
+ let projectRoot;
106
+ if (targetDir) {
107
+ projectRoot = path.resolve(targetDir);
108
+ } else {
109
+ // Try to auto-detect: check if we're in AUTOPM dev project or installed project
110
+ const cwd = process.cwd();
111
+ if (await fs.access(path.join(cwd, 'autopm', '.claude')).then(() => true).catch(() => false)) {
112
+ projectRoot = cwd; // AUTOPM dev project
113
+ } else {
114
+ projectRoot = cwd; // Installed project (commands are in .claude/)
115
+ }
116
+ }
117
+
118
+ // Detect project structure
119
+ let commandsDir, scriptsDir;
120
+
121
+ // Try plugin structure first (packages/plugin-pm/)
122
+ if (await fs.access(path.join(projectRoot, 'commands')).then(() => true).catch(() => false)) {
123
+ commandsDir = path.join(projectRoot, 'commands');
124
+ scriptsDir = path.join(projectRoot, 'scripts', 'pm');
125
+ }
126
+ // Try dev project (autopm/.claude/)
127
+ else if (await fs.access(path.join(projectRoot, 'autopm', '.claude', 'commands')).then(() => true).catch(() => false)) {
128
+ commandsDir = path.join(projectRoot, 'autopm', '.claude', 'commands');
129
+ scriptsDir = path.join(projectRoot, 'autopm', '.claude', 'scripts', 'pm');
130
+ }
131
+ // Try installed project (.claude/)
132
+ else {
133
+ commandsDir = path.join(projectRoot, '.claude', 'commands');
134
+ scriptsDir = path.join(projectRoot, '.claude', 'scripts', 'pm');
135
+ }
136
+
137
+ console.log(`${colors.gray}Commands dir: ${commandsDir}${colors.reset}`);
138
+ console.log(`${colors.gray}Scripts dir: ${scriptsDir}${colors.reset}\n`);
139
+
140
+ try {
141
+ // Get all PM scripts
142
+ const scriptFiles = await fs.readdir(scriptsDir);
143
+ const scripts = scriptFiles
144
+ .filter(f => f.endsWith('.js'))
145
+ .map(f => path.basename(f, '.js'));
146
+
147
+ console.log(`${colors.gray}Found ${scripts.length} PM scripts${colors.reset}\n`);
148
+
149
+ let stats = {
150
+ ok: 0,
151
+ added: 0,
152
+ fixed: 0,
153
+ skip: 0,
154
+ error: 0
155
+ };
156
+
157
+ // Process each script
158
+ for (const scriptName of scripts) {
159
+ const commandFile = `pm:${scriptName}.md`;
160
+ const commandPath = path.join(commandsDir, commandFile);
161
+
162
+ try {
163
+ // Check if command file exists
164
+ await fs.access(commandPath);
165
+
166
+ // Fix the command file
167
+ const result = await fixCommandFile(commandPath, scriptName, dryRun);
168
+ stats[result.status]++;
169
+
170
+ const statusIcon = {
171
+ ok: '✅',
172
+ added: '➕',
173
+ fixed: '🔧',
174
+ skip: '⏭️',
175
+ error: '❌'
176
+ }[result.status];
177
+
178
+ const statusColor = {
179
+ ok: colors.green,
180
+ added: colors.cyan,
181
+ fixed: colors.yellow,
182
+ skip: colors.gray,
183
+ error: colors.red
184
+ }[result.status];
185
+
186
+ console.log(`${statusIcon} ${statusColor}${commandFile.padEnd(30)}${colors.reset} ${result.message}`);
187
+
188
+ } catch (error) {
189
+ if (error.code === 'ENOENT') {
190
+ console.log(`${colors.gray}⚠️ ${commandFile.padEnd(30)} No command file found${colors.reset}`);
191
+ } else {
192
+ stats.error++;
193
+ console.log(`${colors.red}❌ ${commandFile.padEnd(30)} Error: ${error.message}${colors.reset}`);
194
+ }
195
+ }
196
+ }
197
+
198
+ // Summary
199
+ console.log(`\n${colors.cyan}═══════════════════════════════════════════════════${colors.reset}`);
200
+ console.log(`${colors.green}✅ OK:${colors.reset} ${stats.ok} commands already correct`);
201
+ console.log(`${colors.cyan}➕ Added:${colors.reset} ${stats.added} commands had Instructions section added`);
202
+ console.log(`${colors.yellow}🔧 Fixed:${colors.reset} ${stats.fixed} commands had header added`);
203
+ console.log(`${colors.gray}⏭️ Skip:${colors.reset} ${stats.skip} commands skipped`);
204
+ if (stats.error > 0) {
205
+ console.log(`${colors.red}❌ Errors:${colors.reset} ${stats.error} commands had errors`);
206
+ }
207
+ console.log(`${colors.cyan}═══════════════════════════════════════════════════${colors.reset}`);
208
+
209
+ if (dryRun) {
210
+ console.log(`\n${colors.yellow}This was a dry run. Run without --dry-run to apply changes.${colors.reset}`);
211
+ } else {
212
+ console.log(`\n${colors.green}✅ All fixes applied successfully!${colors.reset}`);
213
+ }
214
+
215
+ } catch (error) {
216
+ console.error(`${colors.red}Fatal error: ${error.message}${colors.reset}`);
217
+ process.exit(1);
218
+ }
219
+ }
220
+
221
+ main();