prjct-cli 0.30.0 → 0.30.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.30.2] - 2026-01-13
4
+
5
+ ### Feature: PM Expert Auto-Enrichment
6
+
7
+ **Problem:** Claude could start coding without properly understanding the task, leading to solutions that didn't match user intent.
8
+
9
+ **Solution:** PM Expert enrichment now runs AUTOMATICALLY in `p. task` and `p. bug`:
10
+
11
+ **`p. task` - 5-Phase Enrichment:**
12
+ 1. Intelligent Classification (type, priority, complexity)
13
+ 2. Technical Analysis (affected files, existing patterns)
14
+ 3. Dependency Detection (code, API, blockers)
15
+ 4. User Story + AC Generation
16
+ 5. Verify Understanding (ask if unclear)
17
+
18
+ **`p. bug` - Quick Technical Analysis:**
19
+ - Finds related files and recent commits
20
+ - Assesses complexity (simple/medium/complex)
21
+ - Suggests approach before auto-starting
22
+ - For complex bugs, offers full PM Expert enrichment
23
+
24
+ ### Fix: Statusline Installation Issues
25
+
26
+ - **IFS Restoration**: Fixed bash associative array iteration breaking after `read`
27
+ - **Bash 4+ Detection**: Auto re-exec to Homebrew bash on macOS (ships with bash 3.2)
28
+ - **VERSION Patching**: All 3 installation paths now correctly patch CLI_VERSION
29
+ - **jq Boolean Fix**: `enabled: false` now correctly parsed (was treating as null)
30
+
31
+ **Files:**
32
+ - `templates/commands/task.md` - Added Step 3: PM Expert Enrichment
33
+ - `templates/commands/bug.md` - Added Step 4.5: Quick Technical Analysis
34
+ - `assets/statusline/lib/*.sh` - IFS restoration
35
+ - `assets/statusline/statusline.sh` - Bash 4+ detection, VERSION placeholder
36
+ - `scripts/postinstall.js` - VERSION patching
37
+ - `bin/prjct` - VERSION patching in self-healing
38
+
39
+ ---
40
+
3
41
  ## [0.30.0] - 2026-01-12
4
42
 
5
43
  ### Fix: Distribution System Overhaul (CRITICAL)
@@ -1,31 +1,25 @@
1
1
  #!/bin/bash
2
2
  # prjct statusline - Context component
3
- # Displays context window usage progress bar
3
+ # Displays context window usage (minimal - only when it matters)
4
4
 
5
5
  component_context() {
6
6
  component_enabled "context" || return
7
7
 
8
8
  # CTX_PERCENT is set by parse_stdin in cache.sh
9
- local bar_width="${CONFIG_CONTEXT_BAR_WIDTH:-10}"
10
- local filled=$((CTX_PERCENT * bar_width / 100))
11
- local empty=$((bar_width - filled))
9
+ local min_percent="${CONFIG_CONTEXT_MIN_PERCENT:-30}"
10
+
11
+ # Only show when usage is significant
12
+ [[ "$CTX_PERCENT" -lt "$min_percent" ]] && return
12
13
 
13
14
  # Determine color based on usage
14
- local bar_color
15
+ local color
15
16
  if [[ "$CTX_PERCENT" -ge 80 ]]; then
16
- bar_color="$ERROR"
17
+ color="$ERROR"
17
18
  elif [[ "$CTX_PERCENT" -ge 50 ]]; then
18
- bar_color="$ACCENT"
19
+ color="$ACCENT"
19
20
  else
20
- bar_color="$SUCCESS"
21
+ color="$MUTED"
21
22
  fi
22
23
 
23
- # Build progress bar
24
- local bar="${bar_color}"
25
- for ((i=0; i<filled; i++)); do bar+="█"; done
26
- bar+="${MUTED}"
27
- for ((i=0; i<empty; i++)); do bar+="░"; done
28
- bar+="${NC}"
29
-
30
- echo -e "${MUTED}ctx${NC} ${bar} ${MUTED}${CTX_PERCENT}%${NC}"
24
+ echo -e "${color}${CTX_PERCENT}%${NC}"
31
25
  }
@@ -7,5 +7,5 @@ component_dir() {
7
7
 
8
8
  local dir_name=$(basename "$CWD")
9
9
 
10
- echo -e "${ACCENT}${ICON_DIR} ${dir_name}${NC}"
10
+ echo -e "${ACCENT}${dir_name}${NC}"
11
11
  }
@@ -41,5 +41,5 @@ component_git() {
41
41
 
42
42
  [[ -z "$branch" ]] && return
43
43
 
44
- echo -e "${SECONDARY}${ICON_GIT} ${branch}${dirty}${NC}"
44
+ echo -e "${SECONDARY}${branch}${dirty}${NC}"
45
45
  }
@@ -36,10 +36,11 @@
36
36
  "context": {
37
37
  "enabled": true,
38
38
  "position": 6,
39
- "barWidth": 10
39
+ "barWidth": 10,
40
+ "minPercent": 30
40
41
  },
41
42
  "model": {
42
- "enabled": true,
43
+ "enabled": false,
43
44
  "position": 7
44
45
  }
45
46
  }
@@ -76,8 +76,10 @@ parse_stdin() {
76
76
  ] | @tsv
77
77
  ' 2>/dev/null)
78
78
 
79
- # Parse tab-separated values
79
+ # Parse tab-separated values (save/restore IFS to avoid breaking associative arrays)
80
+ local old_ifs="$IFS"
80
81
  IFS=$'\t' read -r MODEL CWD ADDED REMOVED CTX_SIZE INPUT_TOKENS CACHE_CREATE CACHE_READ <<< "$parsed"
82
+ IFS="$old_ifs"
81
83
 
82
84
  # Set defaults if parsing failed
83
85
  MODEL="${MODEL:-Claude}"
@@ -11,7 +11,7 @@ DEFAULT_CACHE_TTL_PRJCT=30
11
11
  DEFAULT_CACHE_TTL_GIT=5
12
12
  DEFAULT_CACHE_TTL_LINEAR=60
13
13
  DEFAULT_TASK_MAX_LENGTH=25
14
- DEFAULT_CONTEXT_BAR_WIDTH=10
14
+ DEFAULT_CONTEXT_MIN_PERCENT=30
15
15
 
16
16
  # Component configuration (will be populated by load_config)
17
17
  declare -A COMPONENT_ENABLED
@@ -26,7 +26,7 @@ load_config() {
26
26
  CONFIG_CACHE_TTL_GIT="$DEFAULT_CACHE_TTL_GIT"
27
27
  CONFIG_CACHE_TTL_LINEAR="$DEFAULT_CACHE_TTL_LINEAR"
28
28
  CONFIG_TASK_MAX_LENGTH="$DEFAULT_TASK_MAX_LENGTH"
29
- CONFIG_CONTEXT_BAR_WIDTH="$DEFAULT_CONTEXT_BAR_WIDTH"
29
+ CONFIG_CONTEXT_MIN_PERCENT="$DEFAULT_CONTEXT_MIN_PERCENT"
30
30
  CONFIG_LINEAR_ENABLED="true"
31
31
  CONFIG_LINEAR_SHOW_PRIORITY="true"
32
32
 
@@ -53,6 +53,7 @@ load_config() {
53
53
  [[ ! -f "$CONFIG_FILE" ]] && return
54
54
 
55
55
  # Parse config in a single jq call
56
+ # Note: Use "if .x == null then default else .x end" for booleans since // treats false as null
56
57
  local config_data
57
58
  config_data=$(jq -r '
58
59
  [
@@ -61,16 +62,16 @@ load_config() {
61
62
  (.cacheTTL.git // 5),
62
63
  (.cacheTTL.linear // 60),
63
64
  (.components.task.maxLength // 25),
64
- (.components.context.barWidth // 10),
65
- (.components.linear.showPriority // true),
66
- (.components.prjct_icon.enabled // true),
67
- (.components.task.enabled // true),
68
- (.components.linear.enabled // true),
69
- (.components.dir.enabled // true),
70
- (.components.git.enabled // true),
71
- (.components.changes.enabled // true),
72
- (.components.context.enabled // true),
73
- (.components.model.enabled // true),
65
+ (.components.context.minPercent // 30),
66
+ (if .components.linear.showPriority == null then true else .components.linear.showPriority end),
67
+ (if .components.prjct_icon.enabled == null then true else .components.prjct_icon.enabled end),
68
+ (if .components.task.enabled == null then true else .components.task.enabled end),
69
+ (if .components.linear.enabled == null then true else .components.linear.enabled end),
70
+ (if .components.dir.enabled == null then true else .components.dir.enabled end),
71
+ (if .components.git.enabled == null then true else .components.git.enabled end),
72
+ (if .components.changes.enabled == null then true else .components.changes.enabled end),
73
+ (if .components.context.enabled == null then true else .components.context.enabled end),
74
+ (if .components.model.enabled == null then false else .components.model.enabled end),
74
75
  (.components.prjct_icon.position // 0),
75
76
  (.components.task.position // 1),
76
77
  (.components.linear.position // 2),
@@ -84,14 +85,16 @@ load_config() {
84
85
 
85
86
  [[ -z "$config_data" ]] && return
86
87
 
87
- # Parse tab-separated values
88
+ # Parse tab-separated values (save/restore IFS to avoid breaking associative arrays)
89
+ local old_ifs="$IFS"
88
90
  IFS=$'\t' read -r \
89
91
  CONFIG_THEME \
90
92
  CONFIG_CACHE_TTL_PRJCT CONFIG_CACHE_TTL_GIT CONFIG_CACHE_TTL_LINEAR \
91
- CONFIG_TASK_MAX_LENGTH CONFIG_CONTEXT_BAR_WIDTH CONFIG_LINEAR_SHOW_PRIORITY \
93
+ CONFIG_TASK_MAX_LENGTH CONFIG_CONTEXT_MIN_PERCENT CONFIG_LINEAR_SHOW_PRIORITY \
92
94
  E_PRJCT_ICON E_TASK E_LINEAR E_DIR E_GIT E_CHANGES E_CONTEXT E_MODEL \
93
95
  P_PRJCT_ICON P_TASK P_LINEAR P_DIR P_GIT P_CHANGES P_CONTEXT P_MODEL \
94
96
  <<< "$config_data"
97
+ IFS="$old_ifs"
95
98
 
96
99
  # Set component enabled states
97
100
  COMPONENT_ENABLED["prjct_icon"]="$E_PRJCT_ICON"
@@ -89,11 +89,13 @@ load_theme() {
89
89
  return
90
90
  fi
91
91
 
92
- # Parse theme data
92
+ # Parse theme data (save/restore IFS to avoid breaking associative arrays)
93
+ local old_ifs="$IFS"
93
94
  IFS=$'\t' read -r \
94
95
  C_PRIMARY C_ACCENT C_SECONDARY C_MUTED C_SUCCESS C_ERROR C_WARNING C_PURPLE \
95
96
  ICON_PRJCT ICON_DIR ICON_GIT ICON_SEPARATOR ICON_OPUS ICON_SONNET ICON_HAIKU ICON_DEFAULT ICON_PRIORITY_URGENT ICON_PRIORITY_HIGH ICON_PRIORITY_MEDIUM \
96
97
  <<< "$theme_data"
98
+ IFS="$old_ifs"
97
99
 
98
100
  # Convert color codes to escape sequences
99
101
  PRIMARY=$(color_to_escape "$C_PRIMARY")
@@ -1,11 +1,24 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # ============================================================================
3
3
  # prjct statusline v2 for Claude Code
4
4
  # Modular component system with graceful degradation
5
5
  # ============================================================================
6
6
 
7
- # Current CLI version (updated by postinstall/sync)
8
- CLI_VERSION="0.29.0"
7
+ # Require bash 4.0+ for associative arrays
8
+ if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then
9
+ # Try to find a modern bash and re-exec
10
+ for bash_path in /opt/homebrew/bin/bash /usr/local/bin/bash; do
11
+ if [[ -x "$bash_path" ]] && "$bash_path" -c '[[ ${BASH_VERSINFO[0]} -ge 4 ]]' 2>/dev/null; then
12
+ exec "$bash_path" "$0" "$@"
13
+ fi
14
+ done
15
+ # Fallback: simple output without components
16
+ echo "prjct"
17
+ exit 0
18
+ fi
19
+
20
+ # Current CLI version (replaced by postinstall/setup with actual version)
21
+ CLI_VERSION="__VERSION__"
9
22
 
10
23
  # Base paths
11
24
  STATUSLINE_DIR="${HOME}/.prjct-cli/statusline"
@@ -56,7 +69,7 @@ parse_stdin "$INPUT"
56
69
  # ============================================================================
57
70
  build_statusline() {
58
71
  local line=""
59
- local sep=" ${MUTED}${ICON_SEPARATOR}${NC} "
72
+ local sep=" ${MUTED}│${NC} "
60
73
  local first=true
61
74
 
62
75
  # Get sorted list of enabled components
@@ -2,17 +2,17 @@
2
2
  "name": "prjct-default",
3
3
  "description": "Default prjct theme for Claude Code statusline",
4
4
  "colors": {
5
- "primary": "51",
6
- "accent": "220",
7
- "secondary": "147",
8
- "muted": "242",
9
- "success": "114",
10
- "error": "204",
11
- "warning": "214",
12
- "purple": "183"
5
+ "primary": "75",
6
+ "accent": "252",
7
+ "secondary": "248",
8
+ "muted": "245",
9
+ "success": "108",
10
+ "error": "174",
11
+ "warning": "180",
12
+ "purple": "182"
13
13
  },
14
14
  "icons": {
15
- "prjct": "",
15
+ "prjct": "p/",
16
16
  "dir": "󰉋",
17
17
  "git": "",
18
18
  "separator": "│",
package/bin/prjct CHANGED
@@ -5,7 +5,9 @@
5
5
  # Detects available runtime (bun preferred, node fallback)
6
6
  # and executes the appropriate entry point.
7
7
  #
8
- # @version 1.1.0
8
+ # CRITICAL: Also ensures p.md is installed (self-healing)
9
+ #
10
+ # @version 1.2.0
9
11
 
10
12
  # Resolve symlinks to get the actual script location
11
13
  resolve_symlink() {
@@ -41,6 +43,63 @@ SCRIPT_PATH="$(resolve_symlink "$0")"
41
43
  SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
42
44
  ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
43
45
 
46
+ # CRITICAL: Ensure p.md is installed (self-healing)
47
+ # This runs EVERY time prjct is called, ensuring setup even if postinstall failed
48
+ ensure_setup() {
49
+ CLAUDE_COMMANDS="$HOME/.claude/commands"
50
+ PMD_SRC="$ROOT_DIR/templates/commands/p.md"
51
+ PMD_DEST="$CLAUDE_COMMANDS/p.md"
52
+
53
+ # Create dir if needed
54
+ if [ ! -d "$CLAUDE_COMMANDS" ]; then
55
+ mkdir -p "$CLAUDE_COMMANDS" 2>/dev/null
56
+ fi
57
+
58
+ # Copy p.md if source exists and dest doesn't OR dest is older
59
+ if [ -f "$PMD_SRC" ]; then
60
+ if [ ! -f "$PMD_DEST" ]; then
61
+ cp "$PMD_SRC" "$PMD_DEST" 2>/dev/null
62
+ elif [ "$PMD_SRC" -nt "$PMD_DEST" ]; then
63
+ # Source is newer, update
64
+ cp "$PMD_SRC" "$PMD_DEST" 2>/dev/null
65
+ fi
66
+ fi
67
+
68
+ # Also ensure statusline (best effort)
69
+ STATUSLINE_SRC="$ROOT_DIR/assets/statusline/statusline.sh"
70
+ STATUSLINE_DIR="$HOME/.prjct-cli/statusline"
71
+ STATUSLINE_DEST="$STATUSLINE_DIR/statusline.sh"
72
+ CLAUDE_STATUSLINE="$HOME/.claude/prjct-statusline.sh"
73
+
74
+ if [ -f "$STATUSLINE_SRC" ]; then
75
+ mkdir -p "$STATUSLINE_DIR" 2>/dev/null
76
+ if [ ! -f "$STATUSLINE_DEST" ] || [ "$STATUSLINE_SRC" -nt "$STATUSLINE_DEST" ]; then
77
+ cp "$STATUSLINE_SRC" "$STATUSLINE_DEST" 2>/dev/null
78
+ chmod +x "$STATUSLINE_DEST" 2>/dev/null
79
+
80
+ # Patch CLI_VERSION with actual version from package.json
81
+ PKG_VERSION=$(grep '"version"' "$ROOT_DIR/package.json" 2>/dev/null | head -1 | sed 's/.*"version": *"\([^"]*\)".*/\1/')
82
+ if [ -n "$PKG_VERSION" ]; then
83
+ sed -i.bak "s/CLI_VERSION=\"[^\"]*\"/CLI_VERSION=\"$PKG_VERSION\"/" "$STATUSLINE_DEST" 2>/dev/null
84
+ rm -f "$STATUSLINE_DEST.bak" 2>/dev/null
85
+ fi
86
+
87
+ # Copy lib, components, themes
88
+ for subdir in lib components themes; do
89
+ if [ -d "$ROOT_DIR/assets/statusline/$subdir" ]; then
90
+ mkdir -p "$STATUSLINE_DIR/$subdir" 2>/dev/null
91
+ cp "$ROOT_DIR/assets/statusline/$subdir"/* "$STATUSLINE_DIR/$subdir/" 2>/dev/null
92
+ fi
93
+ done
94
+
95
+ # Symlink to ~/.claude
96
+ rm -f "$CLAUDE_STATUSLINE" 2>/dev/null
97
+ ln -s "$STATUSLINE_DEST" "$CLAUDE_STATUSLINE" 2>/dev/null || cp "$STATUSLINE_DEST" "$CLAUDE_STATUSLINE" 2>/dev/null
98
+ chmod +x "$CLAUDE_STATUSLINE" 2>/dev/null
99
+ fi
100
+ fi
101
+ }
102
+
44
103
  # Check if bun is available
45
104
  check_bun() {
46
105
  command -v bun >/dev/null 2>&1
@@ -74,6 +133,9 @@ run_with_node() {
74
133
 
75
134
  # Main execution
76
135
  main() {
136
+ # ALWAYS ensure setup first (self-healing)
137
+ ensure_setup
138
+
77
139
  # Prefer bun if available (faster, native TS support)
78
140
  if check_bun; then
79
141
  run_with_bun "$@"
@@ -12541,7 +12541,7 @@ var require_package = __commonJS({
12541
12541
  "package.json"(exports, module) {
12542
12542
  module.exports = {
12543
12543
  name: "prjct-cli",
12544
- version: "0.29.10",
12544
+ version: "0.30.1",
12545
12545
  description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
12546
12546
  main: "core/index.ts",
12547
12547
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "description": "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {
@@ -17,6 +17,10 @@ const HOME = os.homedir()
17
17
  const CLAUDE_DIR = path.join(HOME, '.claude')
18
18
  const COMMANDS_DIR = path.join(CLAUDE_DIR, 'commands')
19
19
 
20
+ // Read version from package.json
21
+ const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf-8'))
22
+ const VERSION = pkg.version
23
+
20
24
  console.log('\n prjct-cli postinstall\n')
21
25
 
22
26
  // 1. Copy p.md router (CRITICAL - this is the only essential file)
@@ -48,11 +52,12 @@ try {
48
52
  fs.mkdirSync(path.join(STATUSLINE_DEST, 'components'), { recursive: true })
49
53
  fs.mkdirSync(path.join(STATUSLINE_DEST, 'themes'), { recursive: true })
50
54
 
51
- // Copy main script
55
+ // Copy main script with version patched
52
56
  const mainScript = path.join(STATUSLINE_SRC, 'statusline.sh')
53
57
  if (fs.existsSync(mainScript)) {
54
- fs.copyFileSync(mainScript, path.join(STATUSLINE_DEST, 'statusline.sh'))
55
- fs.chmodSync(path.join(STATUSLINE_DEST, 'statusline.sh'), 0o755)
58
+ let content = fs.readFileSync(mainScript, 'utf-8')
59
+ content = content.replace(/CLI_VERSION="[^"]*"/, `CLI_VERSION="${VERSION}"`)
60
+ fs.writeFileSync(path.join(STATUSLINE_DEST, 'statusline.sh'), content, { mode: 0o755 })
56
61
  }
57
62
 
58
63
  // Copy subdirs
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  allowed-tools: [Read, Write, Bash, Task, Glob, AskUserQuestion]
3
- description: 'Report bug with auto-priority and auto-start'
3
+ description: 'Report bug with technical analysis and auto-start'
4
4
  architecture: 'Write-Through (JSON → MD → Events)'
5
5
  storage-layer: true
6
6
  source-of-truth: 'storage/queue.json + storage/state.json'
@@ -19,6 +19,8 @@ backend-sync: 'sync/pending.json'
19
19
  - `description`: Bug description
20
20
  - `--later`: Only queue, don't auto-start (default: auto-starts)
21
21
 
22
+ **NEW**: Before auto-starting, Claude analyzes the codebase to understand the bug context.
23
+
22
24
  ## Architecture: Write-Through Pattern
23
25
 
24
26
  ```
@@ -110,6 +112,84 @@ WRITE: `{queuePath}`
110
112
  ### Calculate queue position
111
113
  {position} = index of task in array + 1
112
114
 
115
+ ## Step 4.5: Quick Technical Analysis (AUTOMÁTICO)
116
+
117
+ **CRITICAL**: Before auto-starting a bug fix, ALWAYS analyze the codebase to understand context.
118
+
119
+ ### 4.5.1 Find Related Code
120
+
121
+ ```
122
+ USE Task(Explore) to find:
123
+ - Files likely related to the bug description
124
+ - Recent commits touching those files
125
+ - Test files for the affected area
126
+
127
+ BASH: git log --oneline -10 -- {related_files}
128
+
129
+ OUTPUT:
130
+ ## Bug Analysis
131
+
132
+ Likely Affected Files:
133
+ - `{file1}` - {reason it's likely involved}
134
+ - `{file2}` - {reason it's likely involved}
135
+
136
+ Related Commits:
137
+ - {hash}: {message}
138
+ - {hash}: {message}
139
+
140
+ Test Files:
141
+ - `{test_file}` - {what it tests}
142
+ ```
143
+
144
+ ### 4.5.2 Assess Complexity
145
+
146
+ Based on analysis, determine if this is:
147
+
148
+ | Complexity | Criteria | Action |
149
+ |------------|----------|--------|
150
+ | `simple` | 1-2 files, clear cause | Auto-start ✓ |
151
+ | `medium` | 3-5 files, needs investigation | Ask user |
152
+ | `complex` | Many files, unclear root cause | Suggest full enrichment |
153
+
154
+ ```
155
+ IF complexity == "complex":
156
+ USE AskUserQuestion:
157
+ question: "This bug may be complex (multiple files, unclear cause). How to proceed?"
158
+ options:
159
+ - label: "Full PM Expert analysis"
160
+ description: "Run complete enrichment before fixing"
161
+ - label: "Start investigating"
162
+ description: "Begin fix now, analyze as you go"
163
+ - label: "Queue for later"
164
+ description: "Add to queue without starting"
165
+
166
+ IF "Full PM Expert analysis":
167
+ OUTPUT: "Running full enrichment..."
168
+ # Execute PM Expert 5-phase enrichment (from enrich.md)
169
+ CONTINUE with enrichment
170
+
171
+ IF "Queue for later":
172
+ SET: {laterFlag} = true
173
+ {autoStarted} = false
174
+ → Skip to Step 6
175
+ ```
176
+
177
+ ### 4.5.3 Suggest Approach
178
+
179
+ ```
180
+ OUTPUT:
181
+ ## Suggested Approach
182
+
183
+ Root cause hypothesis: {based on code analysis}
184
+
185
+ Steps to fix:
186
+ 1. {first step}
187
+ 2. {second step}
188
+ 3. {verification}
189
+
190
+ Ready to start fixing? [Continue / Ask questions]
191
+ ```
192
+
113
193
  ## Step 5: Handle Active Task (AGENTIC)
114
194
 
115
195
  READ: `{statePath}`
@@ -327,10 +407,18 @@ ELSE:
327
407
  ```
328
408
  🐛 [{severity}] {description}
329
409
 
410
+ ## Bug Analysis
411
+ Affected: {file1}, {file2}
412
+ Hypothesis: {root_cause_hypothesis}
413
+
330
414
  Branch: {branchName}
331
415
  Session: {sessionId}
332
416
 
333
- /p:done when fixed
417
+ Approach:
418
+ 1. {step1}
419
+ 2. {step2}
420
+
421
+ Next: Fix the bug, then `p. done`
334
422
  ```
335
423
 
336
424
  ### Queue Only (--later flag)
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  allowed-tools: [Read, Write, Bash, Task, Glob, Grep, AskUserQuestion]
3
- description: 'Unified task workflow with intelligent classification'
3
+ description: 'Unified task workflow with PM Expert enrichment'
4
4
  ---
5
5
 
6
6
  # p. task - Start Any Task
7
7
 
8
- Start any work with automatic classification and intelligent breakdown.
8
+ Start any work with **automatic PM Expert enrichment** to ensure proper understanding before coding.
9
9
 
10
10
  ## Context Variables
11
11
 
@@ -19,13 +19,21 @@ Start any work with automatic classification and intelligent breakdown.
19
19
 
20
20
  ```
21
21
  1. Validate project exists
22
- 2. Handle active task conflict (if any)
23
- 3. Classify task type (agentic reasoning)
24
- 4. Create git branch (if on main)
25
- 5. Run 5-phase workflow
26
- 6. Update storage + context
27
- 7. Output summary
28
- ```
22
+ 2. Handle no task / active task conflict
23
+ 3. PM EXPERT ENRICHMENT (5 phases - ALWAYS runs)
24
+ 3.1 Intelligent Classification
25
+ 3.2 Technical Analysis
26
+ 3.3 Dependency Detection
27
+ 3.4 User Story + AC Generation
28
+ 3.5 Verify Understanding
29
+ 4. PRD Check (informed by enrichment)
30
+ 5. Git branch management
31
+ 6. Design + Task Breakdown
32
+ 7. Update storage + context
33
+ 8. Output summary
34
+ ```
35
+
36
+ **CRITICAL**: PM Expert Enrichment runs AUTOMATICALLY before any coding starts.
29
37
 
30
38
  ---
31
39
 
@@ -43,104 +51,7 @@ IF file not found:
43
51
 
44
52
  ---
45
53
 
46
- ## Step 1.5: PRD Check (AI Orchestration)
47
-
48
- **CRITICAL**: Check if a PRD exists for significant features.
49
-
50
- ```
51
- # Skip PRD check if no task provided (handled in Step 2)
52
- IF no task provided:
53
- SKIP to Step 2
54
-
55
- # Read orchestration config
56
- READ: .prjct/prjct.config.json
57
- SET: prdRequired = config.orchestration?.prdRequired || "standard"
58
-
59
- # Skip for off mode
60
- IF prdRequired == "off":
61
- CONTINUE to Step 2
62
-
63
- # Quick classification (before full classification)
64
- SET: isSignificantWork = FALSE
65
-
66
- # Significant if:
67
- # - Contains "feature", "add", "create", "build", "implement"
68
- # - NOT a bug fix, chore, or small improvement
69
- # - Estimated > 4 hours of work
70
-
71
- IF task likely requires significant effort:
72
- SET: isSignificantWork = TRUE
73
-
74
- # Check for existing PRD
75
- IF isSignificantWork:
76
- READ: {globalPath}/storage/prds.json
77
-
78
- # Search for matching PRD
79
- SET: matchingPRD = null
80
- FOR EACH prd in prds:
81
- IF prd.title matches task (fuzzy):
82
- SET: matchingPRD = prd
83
- BREAK
84
-
85
- IF matchingPRD exists:
86
- # PRD found - link to it
87
- OUTPUT: "📋 Found PRD: {matchingPRD.title} (status: {matchingPRD.status})"
88
- SET: linkedPRDId = matchingPRD.id
89
-
90
- ELSE:
91
- # No PRD found - handle based on enforcement level
92
- IF prdRequired == "strict":
93
- OUTPUT: "⛔ PRD Required"
94
- OUTPUT: "This task requires a PRD before starting."
95
- OUTPUT: "Run `p. prd \"{task}\"` to create one."
96
- STOP
97
-
98
- ELSE IF prdRequired == "standard":
99
- OUTPUT: "⚠️ No PRD found for this task"
100
- OUTPUT: ""
101
- OUTPUT: "For better tracking and planning, consider creating a PRD first."
102
- OUTPUT: ""
103
-
104
- USE AskUserQuestion:
105
- question: "How would you like to proceed?"
106
- options:
107
- - label: "Create PRD first (recommended)"
108
- description: "Run Chief Architect to document requirements"
109
- - label: "Continue without PRD"
110
- description: "Start working now, skip documentation"
111
- - label: "This is a small task"
112
- description: "Mark as not needing PRD"
113
-
114
- IF "Create PRD first":
115
- OUTPUT: "Running `p. prd \"{task}\"`..."
116
- # Invoke PRD command
117
- STOP (prd command will continue)
118
-
119
- IF "This is a small task":
120
- # Continue but don't warn again for this task
121
- SET: skipPRDCheck = TRUE
122
-
123
- ELSE IF prdRequired == "relaxed":
124
- OUTPUT: "💡 Tip: Run `p. prd \"{task}\"` for better tracking"
125
- # Continue without blocking
126
- ```
127
-
128
- ### Legacy Work Exemption
129
-
130
- ```
131
- # Check if this is part of a legacy feature
132
- READ: {globalPath}/storage/roadmap.json
133
-
134
- FOR EACH feature in roadmap.features:
135
- IF feature.legacy == TRUE AND feature matches task:
136
- OUTPUT: "ℹ️ This is part of legacy feature '{feature.name}' - no PRD required"
137
- SET: skipPRDCheck = TRUE
138
- BREAK
139
- ```
140
-
141
- ---
142
-
143
- ## Step 2: Handle No Task Description
54
+ ## Step 2: Handle No Task / Active Task Conflict
144
55
 
145
56
  ```
146
57
  IF no task provided:
@@ -152,14 +63,6 @@ IF no task provided:
152
63
  ELSE:
153
64
  OUTPUT: "No current task. Use `p. task <description>` to start one."
154
65
  STOP
155
- ```
156
-
157
- ---
158
-
159
- ## Step 3: Handle Active Task Conflict
160
-
161
- ```
162
- READ: {globalPath}/storage/state.json
163
66
 
164
67
  IF currentTask exists AND status == "active" AND description != {task}:
165
68
  USE AskUserQuestion:
@@ -172,11 +75,13 @@ IF currentTask exists AND status == "active" AND description != {task}:
172
75
 
173
76
  ---
174
77
 
175
- ## Step 4: Agentic Classification
78
+ ## Step 3: PM Expert Enrichment (AUTOMÁTICO)
176
79
 
177
- **CRITICAL: Use reasoning, NOT keyword matching.**
80
+ **CRITICAL**: Before ANY coding, ALWAYS run PM Expert enrichment to ensure proper understanding.
178
81
 
179
- Analyze the task holistically:
82
+ ### 3.1 Intelligent Classification
83
+
84
+ Analyze the task using REASONING, not keyword matching:
180
85
 
181
86
  | Type | When to Use |
182
87
  |------|-------------|
@@ -186,154 +91,282 @@ Analyze the task holistically:
186
91
  | `refactor` | Reorganizes code, same behavior |
187
92
  | `chore` | Maintenance, deps, docs, config |
188
93
 
189
- **Reasoning Examples:**
190
- - "add error handling to login" → Reasoning: Adding new functionality → `feature`
191
- - "fix button that doesn't submit" Reasoning: Broken behavior → `bug`
192
- - "make dashboard load faster" Reasoning: Enhancing performance → `improvement`
193
- - "split UserService into modules" Reasoning: Reorganizing code → `refactor`
94
+ | Priority | Criteria |
95
+ |----------|----------|
96
+ | `critical` | Production broken, data loss risk |
97
+ | `high` | Blocks users, security issue |
98
+ | `medium` | Important but not blocking |
99
+ | `low` | Nice to have, cosmetic |
100
+
101
+ | Complexity | Hours | Files |
102
+ |------------|-------|-------|
103
+ | `trivial` | < 1h | 1-2 |
104
+ | `small` | 1-4h | 2-5 |
105
+ | `medium` | 4-16h | 5-15 |
106
+ | `large` | 16-40h | 15+ |
107
+ | `epic` | > 40h | Many |
194
108
 
195
109
  ```
196
110
  OUTPUT:
197
- Analyzing: {task}
198
- Intent: {your reasoning}
199
- Classification: {taskType}
111
+ ## Classification
112
+
113
+ Task: {task}
114
+ Type: {taskType} | Priority: {priority} | Complexity: {complexity}
115
+
116
+ Reasoning: {why this classification}
200
117
  ```
201
118
 
202
- ---
119
+ ### 3.2 Technical Analysis
203
120
 
204
- ## Step 5: Git Branch Management
121
+ **ALWAYS use Task(Explore) to understand the codebase BEFORE proposing solutions.**
205
122
 
206
123
  ```
207
- BASH: git branch --show-current
208
- SET: currentBranch = result
124
+ USE Task(Explore) to find:
125
+ - Similar existing code patterns
126
+ - Related files that would be affected
127
+ - API endpoints involved
128
+ - Database schemas touched
129
+ - Test files related
209
130
 
210
- IF currentBranch == "main" OR currentBranch == "master":
211
- # Handle uncommitted changes first
212
- IF git status shows changes:
213
- USE AskUserQuestion: "Uncommitted changes. Stash, commit, or abort?"
131
+ OUTPUT:
132
+ ## Technical Analysis
214
133
 
215
- # Create branch
216
- SET: branchName = {taskType}/{slugify(task)}
217
- BASH: git checkout -b {branchName}
218
- OUTPUT: "Created branch: {branchName}"
219
- ```
134
+ Affected Files:
135
+ - `{file1}` - {expected changes}
136
+ - `{file2}` - {expected changes}
137
+ - `{file3}` - {expected changes}
220
138
 
221
- ---
139
+ Existing Patterns:
140
+ - {pattern} in `{file}` - {how to follow it}
222
141
 
223
- ## 5-Phase Workflow
142
+ Suggested Approach:
143
+ {high-level implementation strategy based on codebase patterns}
144
+ ```
145
+
146
+ ### 3.3 Dependency Detection
224
147
 
225
- ### Phase 1: Discovery
226
- Summarize what you understand:
227
148
  ```
228
- Building: {one-sentence summary}
229
- Type: {taskType}
149
+ ANALYZE:
150
+ - Code imports/exports (what files depend on what)
151
+ - API calls (fetch, axios, internal services)
152
+ - Database queries (tables, schemas affected)
153
+ - Other tasks in queue (potential blockers)
154
+ - External services (third-party APIs)
155
+
156
+ OUTPUT:
157
+ ## Dependencies
158
+
159
+ Code Dependencies:
160
+ - `{file}` - {reason} ({low|medium|high} risk)
230
161
 
231
- Requirements:
232
- - {req 1}
233
- - {req 2}
162
+ API Dependencies:
163
+ - {endpoint} - {status}
234
164
 
235
- Success looks like:
236
- - {criteria 1}
237
- - {criteria 2}
165
+ Blocking Tasks:
166
+ - {taskId}: {title} ({status}) OR "None"
167
+
168
+ External:
169
+ - {service} - {purpose} OR "None"
238
170
  ```
239
171
 
240
- ### Phase 2: Exploration
241
- Use Task(Explore) agent to find:
242
- - Similar existing code
243
- - Patterns used in this codebase
244
- - Key files that would be affected
172
+ ### 3.4 User Story + Acceptance Criteria
245
173
 
246
- **Load skills based on task type:**
247
174
  ```
248
- READ: {globalPath}/config/skills.json (if exists)
175
+ GENERATE user story in format:
176
+ "As a {role}, I want to {action} so that {benefit}."
177
+
178
+ GENERATE 3-7 acceptance criteria based on technical analysis:
179
+
180
+ OUTPUT:
181
+ ## User Story
249
182
 
250
- IF task involves UI/frontend:
251
- Invoke Skill("frontend-design") for design patterns
252
- OUTPUT: "🎨 Using frontend-design skill"
183
+ As a **{role}**, I want to **{action}** so that **{benefit}**.
253
184
 
254
- IF task involves backend/API:
255
- Invoke Skill("javascript-typescript") OR Skill("python-development")
256
- OUTPUT: "⚙️ Using {skill} skill"
185
+ ## Acceptance Criteria
186
+
187
+ - [ ] {AC-1}: When {action}, then {expected result}
188
+ - [ ] {AC-2}: When {action}, then {expected result}
189
+ - [ ] {AC-3}: When {action}, then {expected result}
190
+ ...
191
+
192
+ ## Definition of Done
193
+
194
+ - [ ] All acceptance criteria pass
195
+ - [ ] Tests written and passing
196
+ - [ ] Code reviewed (if team)
197
+ - [ ] No regressions introduced
257
198
  ```
258
199
 
200
+ ### 3.5 Verify Understanding
201
+
259
202
  ```
203
+ IF anything is UNCLEAR about:
204
+ - What the user wants to achieve
205
+ - How it should behave
206
+ - Edge cases to handle
207
+ - Priority of different aspects
208
+
209
+ THEN:
210
+ USE AskUserQuestion to clarify BEFORE proceeding
211
+ DO NOT assume or invent requirements
212
+
260
213
  OUTPUT:
261
- Found similar:
262
- - {code} in {file}
214
+ ## Enrichment Complete
215
+
216
+ Type: {type} | Priority: {priority} | Complexity: {complexity}
217
+ Affected: {count} files | Dependencies: {count}
218
+
219
+ User Story: As a {role}, I want to {action}...
220
+
221
+ AC: {count} criteria defined
222
+
223
+ Questions: {any_remaining_questions OR "All clear ✓"}
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Step 4: PRD Check (Informed by Enrichment)
229
+
230
+ Now that we have enrichment data, check if PRD is needed:
231
+
232
+ ```
233
+ # Read orchestration config
234
+ READ: .prjct/prjct.config.json
235
+ SET: prdRequired = config.orchestration?.prdRequired || "standard"
236
+
237
+ # Skip for off mode or trivial/small tasks
238
+ IF prdRequired == "off" OR complexity in ["trivial", "small"]:
239
+ CONTINUE to Step 5
240
+
241
+ # Check for existing PRD
242
+ IF complexity in ["medium", "large", "epic"]:
243
+ READ: {globalPath}/storage/prds.json
244
+
245
+ # Search for matching PRD
246
+ SET: matchingPRD = null
247
+ FOR EACH prd in prds:
248
+ IF prd.title matches task (fuzzy):
249
+ SET: matchingPRD = prd
250
+ BREAK
251
+
252
+ IF matchingPRD exists:
253
+ OUTPUT: "📋 Found PRD: {matchingPRD.title} (status: {matchingPRD.status})"
254
+ SET: linkedPRDId = matchingPRD.id
255
+
256
+ ELSE IF prdRequired == "strict":
257
+ OUTPUT: "⛔ PRD Required for {complexity} tasks"
258
+ OUTPUT: "Run `p. prd \"{task}\"` to create one."
259
+ STOP
260
+
261
+ ELSE IF prdRequired == "standard" AND complexity in ["large", "epic"]:
262
+ USE AskUserQuestion:
263
+ question: "This is a {complexity} task. Create PRD first?"
264
+ options:
265
+ - label: "Create PRD (recommended)"
266
+ description: "Document requirements properly"
267
+ - label: "Continue without PRD"
268
+ description: "I understand the risks"
263
269
 
264
- Patterns used:
265
- - {pattern}: {where}
270
+ IF "Create PRD":
271
+ OUTPUT: "Running `p. prd \"{task}\"`..."
272
+ STOP (prd command will continue)
273
+ ```
274
+
275
+ ### Legacy Work Exemption
266
276
 
267
- Key files:
268
- - {file}: {what changes}
277
+ ```
278
+ READ: {globalPath}/storage/roadmap.json
269
279
 
270
- Skills activated: {skills used}
280
+ FOR EACH feature in roadmap.features:
281
+ IF feature.legacy == TRUE AND feature matches task:
282
+ OUTPUT: "ℹ️ Legacy feature - no PRD required"
283
+ BREAK
271
284
  ```
272
285
 
273
- ### Phase 3: Questions
274
- If anything is unclear, use AskUserQuestion.
275
- If everything is clear, say so and continue.
286
+ ---
276
287
 
277
- ### Phase 4: Design
278
- Load relevant agents from `{globalPath}/agents/` and their linked skills:
288
+ ## Step 5: Git Branch Management
279
289
 
280
- **Agent + Skill Loading:**
281
290
  ```
282
- FOR EACH relevant agent in {globalPath}/agents/:
291
+ BASH: git branch --show-current
292
+ SET: currentBranch = result
293
+
294
+ IF currentBranch == "main" OR currentBranch == "master":
295
+ # Handle uncommitted changes first
296
+ IF git status shows changes:
297
+ USE AskUserQuestion: "Uncommitted changes. Stash, commit, or abort?"
298
+
299
+ # Create branch
300
+ SET: branchName = {taskType}/{slugify(task)}
301
+ BASH: git checkout -b {branchName}
302
+ OUTPUT: "Created branch: {branchName}"
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Step 6: Design + Task Breakdown
308
+
309
+ Now that enrichment is complete, design the solution and break into subtasks.
310
+
311
+ ### Load Domain Agents + Skills
312
+
313
+ ```
314
+ READ: {globalPath}/agents/ → find relevant agents for task type
315
+
316
+ FOR EACH relevant agent:
283
317
  READ agent file
284
318
  PARSE frontmatter → get `skills` array
285
319
 
286
320
  IF skills exist:
287
- FOR EACH skill in skills:
288
- Invoke Skill(skill) for domain expertise
289
- OUTPUT: "📚 {agent} using /{skill}"
321
+ Invoke Skill(skill) for domain expertise
322
+ OUTPUT: "📚 {agent} using /{skill}"
323
+
324
+ Example:
325
+ - UI feature → Load uxui.md → Invoke /frontend-design
326
+ - Backend → Load backend.md → Invoke /javascript-typescript
290
327
  ```
291
328
 
292
- **Example flow for UI feature:**
293
- 1. Load `uxui.md` agent (has `skills: [frontend-design]`)
294
- 2. Invoke `/frontend-design` skill
295
- 3. Skill provides anti-AI-slop patterns, typography guidelines
296
- 4. Agent applies them to design options
329
+ ### Propose 2-3 Approaches
297
330
 
298
- Propose 2-3 approaches:
331
+ Based on enrichment Technical Analysis, propose options:
299
332
 
300
333
  ```
301
334
  ### Option 1: Minimal
302
335
  - Approach: {desc}
303
- - Files: {count}
304
- - Pros/Cons: ...
336
+ - Files: {count from enrichment}
337
+ - Pros: Fast, low risk
338
+ - Cons: May need refactor later
305
339
 
306
340
  ### Option 2: Clean Architecture
307
341
  - Approach: {desc}
308
342
  - Files: {count}
309
- - Pros/Cons: ...
343
+ - Pros: Maintainable
344
+ - Cons: More initial work
310
345
 
311
- ### Option 3: Recommended (Skill-informed)
312
- - Approach: {desc}
313
- - Files: {count}
314
- - Pros/Cons: ...
315
- - Skills applied: {skills}
346
+ ### Recommended: Option {N}
347
+ Reason: {based on codebase patterns found in enrichment}
316
348
  ```
317
349
 
318
- Use AskUserQuestion to get approval.
350
+ USE AskUserQuestion to get approval if options differ significantly.
351
+
352
+ ### Task Breakdown
319
353
 
320
- ### Phase 5: Task Breakdown
321
354
  Break into actionable subtasks:
322
355
  - Each task: 30min - 2h
323
- - Ordered by dependency
356
+ - Ordered by dependency (from Dependency Detection)
324
357
  - Include testing as final task
325
358
 
326
359
  ```
327
360
  Tasks for {task}:
328
- 1. {subtask 1}
329
- 2. {subtask 2}
361
+ 1. {subtask 1} - {file(s)}
362
+ 2. {subtask 2} - {file(s)}
330
363
  ...
331
- n. Write tests and verify
364
+ n. Write tests and verify AC
332
365
  ```
333
366
 
334
367
  ---
335
368
 
336
- ## Step 6: Update Storage
369
+ ## Step 7: Update Storage
337
370
 
338
371
  ### Write state.json
339
372
  ```json
@@ -374,7 +407,7 @@ Branch: {branchName}
374
407
 
375
408
  ---
376
409
 
377
- ## Step 7: Log to Memory
410
+ ## Step 8: Log to Memory
378
411
 
379
412
  ```
380
413
  APPEND to {globalPath}/memory/events.jsonl:
@@ -386,10 +419,14 @@ APPEND to {globalPath}/memory/events.jsonl:
386
419
  ## Output
387
420
 
388
421
  ```
389
- {task}
390
- Type: {taskType}
422
+ ## {task}
391
423
 
424
+ Type: {taskType} | Priority: {priority} | Complexity: {complexity}
392
425
  Branch: {branchName}
426
+
427
+ User Story: As a {role}, I want to {action}...
428
+
429
+ Affected: {count} files
393
430
  Subtasks: {count}
394
431
 
395
432
  Started: {firstSubtask}