@pennyfarthing/core 7.4.1 → 7.6.0

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 (127) hide show
  1. package/package.json +1 -1
  2. package/packages/core/dist/cli/commands/doctor-legacy.test.d.ts +13 -0
  3. package/packages/core/dist/cli/commands/doctor-legacy.test.d.ts.map +1 -0
  4. package/packages/core/dist/cli/commands/doctor-legacy.test.js +207 -0
  5. package/packages/core/dist/cli/commands/doctor-legacy.test.js.map +1 -0
  6. package/packages/core/dist/cli/commands/doctor.d.ts +16 -0
  7. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  8. package/packages/core/dist/cli/commands/doctor.js +130 -2
  9. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  10. package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
  11. package/packages/core/dist/cli/commands/init.js +17 -27
  12. package/packages/core/dist/cli/commands/init.js.map +1 -1
  13. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  14. package/packages/core/dist/cli/commands/update.js +21 -52
  15. package/packages/core/dist/cli/commands/update.js.map +1 -1
  16. package/packages/core/dist/cli/utils/symlinks.d.ts +15 -0
  17. package/packages/core/dist/cli/utils/symlinks.d.ts.map +1 -1
  18. package/packages/core/dist/cli/utils/symlinks.js +148 -2
  19. package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
  20. package/packages/core/dist/cli/utils/themes.d.ts.map +1 -1
  21. package/packages/core/dist/cli/utils/themes.js +9 -0
  22. package/packages/core/dist/cli/utils/themes.js.map +1 -1
  23. package/pennyfarthing-dist/agents/dev.md +29 -24
  24. package/pennyfarthing-dist/agents/handoff.md +42 -119
  25. package/pennyfarthing-dist/agents/reviewer.md +32 -37
  26. package/pennyfarthing-dist/agents/sm-handoff.md +43 -66
  27. package/pennyfarthing-dist/agents/sm.md +52 -35
  28. package/pennyfarthing-dist/agents/tea.md +25 -8
  29. package/pennyfarthing-dist/agents/testing-runner.md +4 -4
  30. package/pennyfarthing-dist/commands/architect.md +0 -55
  31. package/pennyfarthing-dist/commands/dev.md +1 -54
  32. package/pennyfarthing-dist/commands/devops.md +0 -52
  33. package/pennyfarthing-dist/commands/health-check.md +33 -0
  34. package/pennyfarthing-dist/commands/orchestrator.md +0 -49
  35. package/pennyfarthing-dist/commands/pm.md +0 -53
  36. package/pennyfarthing-dist/commands/reviewer.md +1 -58
  37. package/pennyfarthing-dist/commands/sm.md +1 -64
  38. package/pennyfarthing-dist/commands/sprint.md +133 -0
  39. package/pennyfarthing-dist/commands/standalone.md +194 -0
  40. package/pennyfarthing-dist/commands/tea.md +1 -57
  41. package/pennyfarthing-dist/commands/tech-writer.md +0 -46
  42. package/pennyfarthing-dist/commands/theme-maker.md +10 -5
  43. package/pennyfarthing-dist/commands/ux-designer.md +0 -55
  44. package/pennyfarthing-dist/guides/XML-TAGS.md +156 -0
  45. package/pennyfarthing-dist/guides/agent-behavior.md +64 -38
  46. package/pennyfarthing-dist/guides/measurement-framework.md +210 -0
  47. package/pennyfarthing-dist/personas/themes/a-team.yaml +130 -0
  48. package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +1 -1
  49. package/pennyfarthing-dist/personas/themes/ancient-strategists.yaml +1 -1
  50. package/pennyfarthing-dist/personas/themes/arcane.yaml +1 -1
  51. package/pennyfarthing-dist/personas/themes/better-call-saul.yaml +1 -1
  52. package/pennyfarthing-dist/personas/themes/big-lebowski.yaml +1 -1
  53. package/pennyfarthing-dist/personas/themes/black-sails.yaml +1 -1
  54. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +1 -1
  55. package/pennyfarthing-dist/personas/themes/bobiverse.yaml +1 -1
  56. package/pennyfarthing-dist/personas/themes/breaking-bad.yaml +1 -1
  57. package/pennyfarthing-dist/personas/themes/count-of-monte-cristo.yaml +1 -1
  58. package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +1 -1
  59. package/pennyfarthing-dist/personas/themes/deadwood.yaml +1 -1
  60. package/pennyfarthing-dist/personas/themes/dickens.yaml +1 -1
  61. package/pennyfarthing-dist/personas/themes/discworld.yaml +1 -1
  62. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +1 -1
  63. package/pennyfarthing-dist/personas/themes/don-quixote.yaml +1 -1
  64. package/pennyfarthing-dist/personas/themes/dune.yaml +1 -1
  65. package/pennyfarthing-dist/personas/themes/enlightenment-thinkers.yaml +1 -1
  66. package/pennyfarthing-dist/personas/themes/expeditionary-force.yaml +1 -1
  67. package/pennyfarthing-dist/personas/themes/futurama.yaml +1 -1
  68. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +1 -1
  69. package/pennyfarthing-dist/personas/themes/gilligans-island.yaml +131 -1
  70. package/pennyfarthing-dist/personas/themes/gothic-literature.yaml +1 -1
  71. package/pennyfarthing-dist/personas/themes/great-gatsby.yaml +1 -1
  72. package/pennyfarthing-dist/personas/themes/hannibal.yaml +1 -1
  73. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +1 -1
  74. package/pennyfarthing-dist/personas/themes/his-dark-materials.yaml +1 -1
  75. package/pennyfarthing-dist/personas/themes/inspector-morse.yaml +1 -1
  76. package/pennyfarthing-dist/personas/themes/jane-austen.yaml +1 -1
  77. package/pennyfarthing-dist/personas/themes/legion-of-doom.yaml +130 -0
  78. package/pennyfarthing-dist/personas/themes/mad-max.yaml +1 -1
  79. package/pennyfarthing-dist/personas/themes/moby-dick.yaml +1 -1
  80. package/pennyfarthing-dist/personas/themes/neuromancer.yaml +1 -1
  81. package/pennyfarthing-dist/personas/themes/parks-and-rec.yaml +130 -0
  82. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +130 -0
  83. package/pennyfarthing-dist/personas/themes/renaissance-masters.yaml +1 -1
  84. package/pennyfarthing-dist/personas/themes/russian-masters.yaml +1 -1
  85. package/pennyfarthing-dist/personas/themes/sandman.yaml +1 -1
  86. package/pennyfarthing-dist/personas/themes/scientific-revolutionaries.yaml +1 -1
  87. package/pennyfarthing-dist/personas/themes/shakespeare.yaml +1 -1
  88. package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +139 -3
  89. package/pennyfarthing-dist/personas/themes/star-trek-tos.yaml +124 -0
  90. package/pennyfarthing-dist/personas/themes/star-wars.yaml +1 -1
  91. package/pennyfarthing-dist/personas/themes/succession.yaml +1 -1
  92. package/pennyfarthing-dist/personas/themes/superfriends.yaml +131 -1
  93. package/pennyfarthing-dist/personas/themes/ted-lasso.yaml +131 -1
  94. package/pennyfarthing-dist/personas/themes/the-americans.yaml +1 -1
  95. package/pennyfarthing-dist/personas/themes/the-expanse.yaml +131 -1
  96. package/pennyfarthing-dist/personas/themes/the-good-place.yaml +1 -1
  97. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +1 -1
  98. package/pennyfarthing-dist/personas/themes/the-sopranos.yaml +1 -1
  99. package/pennyfarthing-dist/personas/themes/west-wing.yaml +6 -6
  100. package/pennyfarthing-dist/personas/themes/world-explorers.yaml +1 -1
  101. package/pennyfarthing-dist/personas/themes/wwii-leaders.yaml +1 -1
  102. package/pennyfarthing-dist/scripts/core/check-context.sh +23 -6
  103. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +95 -0
  104. package/pennyfarthing-dist/scripts/git/release.sh +3 -2
  105. package/pennyfarthing-dist/scripts/health/drift-detection.sh +162 -0
  106. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +87 -0
  107. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +1 -1
  108. package/pennyfarthing-dist/scripts/misc/deploy.sh +1 -1
  109. package/pennyfarthing-dist/scripts/misc/statusline.sh +25 -32
  110. package/pennyfarthing-dist/scripts/sprint/import-epic-to-future.mjs +377 -0
  111. package/pennyfarthing-dist/scripts/sprint/import-epic-to-future.sh +9 -0
  112. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.js +492 -0
  113. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +8 -200
  114. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +38 -5
  115. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +40 -0
  116. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +12 -7
  117. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-04-final-validation.md +11 -3
  118. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +122 -0
  119. package/pennyfarthing-dist/workflows/epics-and-stories/workflow.yaml +3 -2
  120. package/packages/core/dist/workflow/generic-handoff.d.ts +0 -281
  121. package/packages/core/dist/workflow/generic-handoff.d.ts.map +0 -1
  122. package/packages/core/dist/workflow/generic-handoff.js +0 -411
  123. package/packages/core/dist/workflow/generic-handoff.js.map +0 -1
  124. package/packages/core/dist/workflow/generic-handoff.test.d.ts +0 -21
  125. package/packages/core/dist/workflow/generic-handoff.test.d.ts.map +0 -1
  126. package/packages/core/dist/workflow/generic-handoff.test.js +0 -499
  127. package/packages/core/dist/workflow/generic-handoff.test.js.map +0 -1
@@ -34,15 +34,29 @@ echo ""
34
34
  echo "| Workflow | Type | Default | Steps/Phases | Modes | Description |"
35
35
  echo "|----------|------|---------|--------------|-------|-------------|"
36
36
 
37
- for f in "$WORKFLOWS_DIR"/*.yaml; do
37
+ # Find all workflow YAML files: top-level *.yaml and subdirectory workflow.yaml files
38
+ workflow_files=()
39
+ while IFS= read -r -d '' f; do
40
+ workflow_files+=("$f")
41
+ done < <(find "$WORKFLOWS_DIR" -maxdepth 1 -name "*.yaml" -print0 2>/dev/null)
42
+ while IFS= read -r -d '' f; do
43
+ workflow_files+=("$f")
44
+ done < <(find "$WORKFLOWS_DIR" -mindepth 2 -name "workflow.yaml" -print0 2>/dev/null)
45
+
46
+ # Sort by workflow name for consistent output
47
+ IFS=$'\n' sorted_files=($(for f in "${workflow_files[@]}"; do echo "$f"; done | sort))
48
+ unset IFS
49
+
50
+ for f in "${sorted_files[@]}"; do
38
51
  [[ -f "$f" ]] || continue
39
52
 
40
53
  name=$(yq eval '.workflow.name' "$f")
41
54
  desc=$(yq eval '.workflow.description' "$f" | head -1)
42
55
  is_default=$(yq eval '.workflow.triggers.default // false' "$f")
43
56
 
44
- # Detect workflow type (stepped vs phased)
57
+ # Detect workflow type (stepped, phased, or procedural)
45
58
  # Stepped workflows have .workflow.type == "stepped" or .workflow.steps
59
+ # Procedural workflows have .workflow.type == "procedural" (BMAD reference workflows)
46
60
  workflow_type=$(yq eval '.workflow.type // "phased"' "$f")
47
61
  has_steps=$(yq eval '.workflow.steps != null' "$f")
48
62
 
@@ -51,12 +65,30 @@ for f in "$WORKFLOWS_DIR"/*.yaml; do
51
65
  # Count step files if steps.path is defined
52
66
  steps_path=$(yq eval '.workflow.steps.path // ""' "$f")
53
67
  steps_pattern=$(yq eval '.workflow.steps.pattern // "step-*.md"' "$f")
54
- if [[ -n "$steps_path" ]] && [[ -d "$PROJECT_ROOT/$steps_path" ]]; then
55
- step_count=$(find "$PROJECT_ROOT/$steps_path" -name "$steps_pattern" 2>/dev/null | wc -l | tr -d ' ')
56
- steps_col="${step_count} steps"
68
+ # Resolve steps_path relative to the workflow file's directory
69
+ workflow_dir=$(dirname "$f")
70
+ if [[ -n "$steps_path" ]]; then
71
+ # Handle relative paths (./steps/ or steps/)
72
+ if [[ "$steps_path" == ./* ]]; then
73
+ resolved_path="$workflow_dir/${steps_path#./}"
74
+ elif [[ "$steps_path" != /* ]]; then
75
+ resolved_path="$workflow_dir/$steps_path"
76
+ else
77
+ resolved_path="$steps_path"
78
+ fi
79
+ if [[ -d "$resolved_path" ]]; then
80
+ step_count=$(find "$resolved_path" -maxdepth 1 -name "step-*.md" 2>/dev/null | wc -l | tr -d ' ')
81
+ steps_col="${step_count} steps"
82
+ else
83
+ steps_col="-"
84
+ fi
57
85
  else
58
86
  steps_col="-"
59
87
  fi
88
+ elif [[ "$workflow_type" == "procedural" ]]; then
89
+ type_col="procedural"
90
+ # Procedural workflows use instructions.md instead of phases/steps
91
+ steps_col="instructions"
60
92
  else
61
93
  type_col="phased"
62
94
  # Count phases for phased workflows
@@ -87,5 +119,6 @@ echo ""
87
119
  echo "**Legend:**"
88
120
  echo "- **phased**: Agent-driven workflow (SM → TEA → Dev → Reviewer)"
89
121
  echo "- **stepped**: Step-by-step guided workflow with progressive disclosure"
122
+ echo "- **procedural**: BMAD reference workflow with instructions file"
90
123
  echo ""
91
124
  echo "Use \`/workflow show <name>\` for workflow details."
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # Get the agent that owns a phase in a workflow
3
+ # Usage: phase-owner.sh <workflow> <phase>
4
+ # Returns: agent name (e.g., "dev", "tea", "reviewer", "sm")
5
+
6
+ set -euo pipefail
7
+
8
+ WORKFLOW="${1:-}"
9
+ PHASE="${2:-}"
10
+
11
+ if [[ -z "$WORKFLOW" || -z "$PHASE" ]]; then
12
+ echo "Usage: phase-owner.sh <workflow> <phase>" >&2
13
+ exit 1
14
+ fi
15
+
16
+ # Find project root
17
+ if [[ -z "${PROJECT_ROOT:-}" ]]; then
18
+ d="$PWD"
19
+ while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do
20
+ d="$(dirname "$d")"
21
+ done
22
+ PROJECT_ROOT="$d"
23
+ fi
24
+
25
+ WORKFLOW_FILE="$PROJECT_ROOT/pennyfarthing-dist/workflows/${WORKFLOW}.yaml"
26
+
27
+ if [[ ! -f "$WORKFLOW_FILE" ]]; then
28
+ echo "Error: Workflow '$WORKFLOW' not found" >&2
29
+ exit 1
30
+ fi
31
+
32
+ # Query the agent for this phase
33
+ AGENT=$(yq eval ".workflow.phases[] | select(.name == \"$PHASE\") | .agent" "$WORKFLOW_FILE" 2>/dev/null)
34
+
35
+ if [[ -z "$AGENT" || "$AGENT" == "null" ]]; then
36
+ echo "Error: Phase '$PHASE' not found in workflow '$WORKFLOW'" >&2
37
+ exit 1
38
+ fi
39
+
40
+ echo "$AGENT"
@@ -143,27 +143,32 @@ Each agent gets an OCEAN profile (Big Five personality traits):
143
143
 
144
144
  Each agent can have a `visual` field that describes their appearance for portrait generation.
145
145
 
146
- **Generate portraits:**
146
+ **Generate all portraits for a theme:**
147
147
  ```bash
148
- python3 scripts/generate-portraits.py --theme {name}
148
+ ./scripts/generate-portraits.sh --theme {name}
149
+ ```
150
+
151
+ **Generate a single agent's portrait:**
152
+ ```bash
153
+ ./scripts/generate-portraits.sh --theme {name} --role {role}
149
154
  ```
150
155
 
151
156
  **Dry run (preview):**
152
157
  ```bash
153
- python3 scripts/generate-portraits.py --theme {name} --dry-run
158
+ ./scripts/generate-portraits.sh --theme {name} --dry-run
154
159
  ```
155
160
 
156
161
  **Requirements:**
157
- - Python 3 with diffusers, torch, pillow, pyyaml
158
- - Apple Silicon Mac (MPS) or NVIDIA GPU
162
+ - Python 3 venv at `.venv/` with: `pip install diffusers transformers accelerate torch pillow pyyaml tqdm`
163
+ - Apple Silicon Mac (MPS) or NVIDIA GPU (CUDA)
159
164
  - ~6.5GB model download on first run
160
165
 
161
- **Output:** `pennyfarthing-dist/personas/portraits/{theme}/{role}.png` (100x100px woodcut style)
166
+ **Output:** `pennyfarthing-dist/personas/portraits/{theme}/{shortName}-{OCEAN}.png`
162
167
 
163
168
  ## Post-Creation Steps
164
169
 
165
170
  After creating a theme:
166
171
  1. Theme file at `.claude/pennyfarthing/themes/{name}.yaml`
167
172
  2. Activate with `/set-theme {name}`
168
- 3. Generate portraits with `python3 scripts/generate-portraits.py --theme {name}`
173
+ 3. Generate portraits with `./scripts/generate-portraits.sh --theme {name}`
169
174
  4. Edit YAML directly for fine-tuning
@@ -7,6 +7,7 @@ workflow_path: '{project_root}/.pennyfarthing/workflows/epics-and-stories'
7
7
 
8
8
  # File References
9
9
  thisStepFile: './step-04-final-validation.md'
10
+ nextStepFile: './step-05-import-to-future.md'
10
11
  workflowFile: '{workflow_path}/workflow.yaml'
11
12
  outputFile: '{planning_artifacts}/epics.md'
12
13
 
@@ -139,7 +140,14 @@ If all validations pass:
139
140
  - Ensure proper formatting
140
141
  - Save the final epics.md
141
142
 
142
- **Present Final Menu:**
143
- **All validations complete!** [C] Complete Workflow
143
+ **Present Menu:**
144
+ **All validations complete!** [C] Continue to import to future.yaml
144
145
 
145
- When C is selected, the workflow is complete and the epics.md is ready for development.
146
+ #### Menu Handling Logic:
147
+
148
+ - IF C: Save final document, update frontmatter, then load, read entire file, then execute {nextStepFile}
149
+ - IF Any other comments or queries: help user respond then redisplay menu
150
+
151
+ ## CRITICAL STEP COMPLETION NOTE
152
+
153
+ ONLY WHEN C is selected and validations are complete, will you then load, read entire file, then execute {nextStepFile} to import epics to future.yaml.
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: 'step-05-import-to-future'
3
+ description: 'Import validated epics and stories into sprint/future.yaml backlog'
4
+
5
+ # Path Definitions
6
+ workflow_path: '{project_root}/.pennyfarthing/workflows/epics-and-stories'
7
+
8
+ # File References
9
+ thisStepFile: './step-05-import-to-future.md'
10
+ workflowFile: '{workflow_path}/workflow.yaml'
11
+ outputFile: '{planning_artifacts}/epics.md'
12
+ futureYaml: '{project_root}/sprint/future.yaml'
13
+
14
+ # Script References
15
+ importScript: '{project_root}/.pennyfarthing/scripts/sprint/import-epic-to-future.sh'
16
+ ---
17
+
18
+ # Step 5: Import to Future Backlog
19
+
20
+ ## STEP GOAL:
21
+
22
+ To import the validated epics and stories into `sprint/future.yaml` so they appear in the backlog and can be promoted to sprints.
23
+
24
+ ## MANDATORY EXECUTION RULES (READ FIRST):
25
+
26
+ ### Universal Rules:
27
+
28
+ - 🛑 NEVER skip this step - epics must be in future.yaml to be scheduled
29
+ - 📖 CRITICAL: Read the complete step file before taking any action
30
+ - 📋 YOU ARE A FACILITATOR, confirming import with user
31
+ - ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style
32
+
33
+ ### Step-Specific Rules:
34
+
35
+ - 🎯 Focus ONLY on importing to future.yaml
36
+ - 💬 Ask user for initiative name if not obvious from document
37
+ - 🚫 FORBIDDEN to modify the validated epics document
38
+ - ✅ Show dry-run output before applying
39
+
40
+ ## IMPORT PROCESS:
41
+
42
+ ### 1. Determine Initiative Name
43
+
44
+ Look at the epics document title and ask user:
45
+
46
+ > "What should this initiative be called in future.yaml?"
47
+ >
48
+ > Suggested: `{extracted_title}`
49
+
50
+ Wait for user confirmation or alternative name.
51
+
52
+ ### 2. Preview Import (Dry Run)
53
+
54
+ Run the import script with `--dry-run` to show what will be added:
55
+
56
+ ```bash
57
+ .pennyfarthing/scripts/core/run.sh sprint/import-epic-to-future.sh {outputFile} "{initiative_name}" --dry-run
58
+ ```
59
+
60
+ Display the preview output to the user showing:
61
+ - Next epic number that will be assigned
62
+ - Initiative structure
63
+ - All stories with IDs
64
+
65
+ ### 3. Confirm and Apply
66
+
67
+ Ask user: "Does this look correct? [Y] Yes, import to future.yaml / [N] No, make changes"
68
+
69
+ **If Y:**
70
+ Run the import without `--dry-run`:
71
+
72
+ ```bash
73
+ .pennyfarthing/scripts/core/run.sh sprint/import-epic-to-future.sh {outputFile} "{initiative_name}"
74
+ ```
75
+
76
+ **If N:**
77
+ Ask what changes are needed and help user adjust before re-running.
78
+
79
+ ### 4. Verify Import
80
+
81
+ After successful import, verify by showing:
82
+
83
+ ```bash
84
+ grep -A3 "{initiative_name}" sprint/future.yaml
85
+ ```
86
+
87
+ Confirm:
88
+ - Epic appears in future.yaml
89
+ - Epic number is correct
90
+ - Stories have proper IDs
91
+
92
+ ### 5. Complete Workflow
93
+
94
+ Display completion message:
95
+
96
+ ```
97
+ ## Workflow Complete!
98
+
99
+ **Epic imported:** epic-{N}
100
+ **Initiative:** {initiative_name}
101
+ **Stories:** {count} stories ready for sprint planning
102
+ **Location:** sprint/future.yaml
103
+
104
+ Next steps:
105
+ - Use `/sprint` to view the backlog
106
+ - Use `promote-epic.sh` to move to a sprint when ready
107
+ ```
108
+
109
+ ## SUCCESS CRITERIA:
110
+
111
+ - ✅ Initiative appears in future.yaml
112
+ - ✅ Epic has correct sequential number
113
+ - ✅ All stories have proper IDs (epic-story format)
114
+ - ✅ User confirms import is correct
115
+
116
+ ## FAILURE MODES:
117
+
118
+ - ❌ Import script not found - check .pennyfarthing symlinks
119
+ - ❌ future.yaml not found - ensure sprint/ directory exists
120
+ - ❌ Duplicate epic number - script should handle this automatically
121
+
122
+ **Master Rule:** The workflow is not complete until epics are in future.yaml and accessible via sprint commands.
@@ -1,10 +1,11 @@
1
1
  # create-epics-and-stories Workflow - Migrated from BMAD format
2
2
  # Generated by migrate-bmad-workflow.mjs
3
+ # Updated: Added step-05 for automatic import to future.yaml
3
4
 
4
5
  workflow:
5
6
  name: create-epics-and-stories
6
- description: Transform PRD requirements and Architecture decisions into comprehensive stories organized by user value. This workflow requires completed PRD + Architecture documents (UX recommended if UI exists) and breaks down requirements into implementation-ready epics and user stories that incorporate all available technical and design context. Creates detailed, actionable stories with complete acceptance criteria for development teams.
7
- version: "1.0.0"
7
+ description: Transform PRD requirements and Architecture decisions into comprehensive stories organized by user value. This workflow requires completed PRD + Architecture documents (UX recommended if UI exists) and breaks down requirements into implementation-ready epics and user stories that incorporate all available technical and design context. Creates detailed, actionable stories with complete acceptance criteria for development teams. Automatically imports validated epics to sprint/future.yaml backlog.
8
+ version: "1.1.0"
8
9
  type: stepped
9
10
 
10
11
  # Step configuration
@@ -1,281 +0,0 @@
1
- /**
2
- * Generic Workflow-Driven Handoff
3
- *
4
- * Replaces hardcoded handoff files with workflow-driven logic.
5
- * Reads phase requirements from workflow definitions.
6
- *
7
- * Provides functions to:
8
- * - Find current phase in a workflow
9
- * - Determine next phase (forward or rejection loop)
10
- * - Check gate conditions based on gate type
11
- * - Format session file updates for phase transitions
12
- */
13
- import type { WorkflowDefinition, WorkflowPhase } from './workflow-schema.js';
14
- /**
15
- * Context for gate checks - provides test results, verdicts, etc.
16
- */
17
- export interface GateContext {
18
- /** For tests_fail gate: are tests currently failing? */
19
- testsRed?: boolean;
20
- /** For tests_pass gate: are all tests passing? */
21
- testsGreen?: boolean;
22
- /** Number of passing tests */
23
- testPassCount?: number;
24
- /** Number of failing tests */
25
- testFailCount?: number;
26
- /** For approval gate: approved or rejected */
27
- verdict?: 'approved' | 'rejected';
28
- }
29
- /**
30
- * Options for getNextPhase to handle rejection loops
31
- */
32
- export interface NextPhaseOptions {
33
- /** For approval gates: determines forward vs loop-back */
34
- verdict?: 'approved' | 'rejected';
35
- }
36
- /**
37
- * Result of checking a gate condition
38
- */
39
- export interface GateCheckResult {
40
- /** Whether the gate check passed */
41
- passed: boolean;
42
- /** Gate type that was checked (undefined if phase has no gate) */
43
- gateType?: string;
44
- /** Human-readable message (especially on failure) */
45
- message?: string;
46
- }
47
- /**
48
- * Context for handoff operations
49
- */
50
- export interface HandoffContext {
51
- /** Story ID being worked on */
52
- storyId: string;
53
- /** Current workflow name */
54
- workflowName: string;
55
- /** Current phase name */
56
- currentPhase: string;
57
- /** Session file path */
58
- sessionFile: string;
59
- }
60
- /**
61
- * Result of a handoff operation
62
- */
63
- export interface HandoffResult {
64
- /** Whether handoff succeeded */
65
- success: boolean;
66
- /** Next phase to transition to */
67
- nextPhase?: string;
68
- /** Next agent to invoke */
69
- nextAgent?: string;
70
- /** Error message if failed */
71
- error?: string;
72
- }
73
- /**
74
- * Parameters for formatting phase transition
75
- */
76
- export interface PhaseTransitionParams {
77
- workflowName: string;
78
- fromPhase: string;
79
- toPhase: string;
80
- startedAt: string;
81
- endedAt: string;
82
- isRejection?: boolean;
83
- }
84
- /**
85
- * Find a phase by name in a workflow definition
86
- *
87
- * @param workflow - The workflow definition to search
88
- * @param phaseName - Name of the phase to find
89
- * @returns The phase definition or null if not found
90
- *
91
- * @example
92
- * ```typescript
93
- * const phase = findCurrentPhase(workflow, 'red');
94
- * if (phase) {
95
- * console.log(`Found phase: ${phase.name}, agent: ${phase.agent}`);
96
- * }
97
- * ```
98
- */
99
- export declare function findCurrentPhase(workflow: WorkflowDefinition, phaseName: string): WorkflowPhase | null;
100
- /**
101
- * Get the next phase in the workflow
102
- *
103
- * For normal progression, returns the next phase in sequence.
104
- * For rejection (verdict='rejected'), returns the phase to loop back to
105
- * (typically the most recent phase with a tests_pass gate).
106
- *
107
- * @param workflow - The workflow definition
108
- * @param currentPhaseName - Name of the current phase
109
- * @param options - Options for handling rejection loops
110
- * @returns The next phase or null if at end/not found
111
- *
112
- * @example
113
- * ```typescript
114
- * // Normal progression
115
- * const next = getNextPhase(workflow, 'red');
116
- *
117
- * // Rejection loop
118
- * const next = getNextPhase(workflow, 'review', { verdict: 'rejected' });
119
- * ```
120
- */
121
- export declare function getNextPhase(workflow: WorkflowDefinition, currentPhaseName: string, options?: NextPhaseOptions): WorkflowPhase | null;
122
- /**
123
- * Check if a gate condition is satisfied
124
- *
125
- * Gate types:
126
- * - tests_fail: testsRed must be true
127
- * - tests_pass: testsGreen must be true
128
- * - approval: verdict must be provided (approved or rejected)
129
- * - manual: always passes
130
- * - (none): always passes
131
- *
132
- * @param workflow - The workflow definition
133
- * @param phaseName - Name of the phase to check
134
- * @param context - Gate check context with test results, verdicts, etc.
135
- * @returns Gate check result
136
- *
137
- * @example
138
- * ```typescript
139
- * const result = checkGate(workflow, 'red', { testsRed: true });
140
- * if (result.passed) {
141
- * // Proceed with handoff
142
- * }
143
- * ```
144
- */
145
- export declare function checkGate(workflow: WorkflowDefinition, phaseName: string, context: GateContext): GateCheckResult;
146
- /**
147
- * Format the workflow tracking section for a session file update
148
- *
149
- * @param params - Phase transition parameters
150
- * @returns Markdown string for the workflow tracking section
151
- *
152
- * @example
153
- * ```typescript
154
- * const markdown = formatPhaseTransition({
155
- * workflowName: 'tdd',
156
- * fromPhase: 'red',
157
- * toPhase: 'green',
158
- * startedAt: '2026-01-13T14:00:00Z',
159
- * endedAt: '2026-01-13T14:30:00Z'
160
- * });
161
- * ```
162
- */
163
- export declare function formatPhaseTransition(params: PhaseTransitionParams): string;
164
- /**
165
- * Calculate duration between two ISO 8601 timestamps
166
- *
167
- * @param startedAt - Start timestamp
168
- * @param endedAt - End timestamp
169
- * @returns Formatted duration string (e.g., "30m", "2h 30m", "45s")
170
- */
171
- export declare function calculateDuration(startedAt: string, endedAt: string): string;
172
- /**
173
- * Handoff mode type - auto triggers immediately, manual prompts first
174
- */
175
- export type HandoffMode = 'auto' | 'manual';
176
- /**
177
- * Handoff behavior based on mode
178
- */
179
- export interface HandoffBehavior {
180
- /** What action to take */
181
- action: 'immediate' | 'prompt';
182
- /** Whether user confirmation is required */
183
- requiresConfirmation: boolean;
184
- /** Message to show user (for prompt action) */
185
- message?: string;
186
- }
187
- /**
188
- * Entry for handoff history tracking
189
- */
190
- export interface HandoffHistoryEntry {
191
- phase: string;
192
- agent: string;
193
- timestamp: string;
194
- handoffMode: HandoffMode;
195
- }
196
- /**
197
- * Read handoff mode from Cyclist settings file
198
- * Returns 'manual' as default if file doesn't exist or is invalid
199
- *
200
- * @param settingsPath - Path to the settings file (JSON or YAML)
201
- * @returns The handoff mode setting
202
- */
203
- export declare function readHandoffMode(settingsPath: string): HandoffMode;
204
- /**
205
- * Parse handoff mode from JSON string
206
- * Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
207
- *
208
- * @param jsonContent - JSON string containing settings
209
- * @returns The handoff mode setting
210
- */
211
- export declare function parseHandoffModeFromJson(jsonContent: string): HandoffMode;
212
- /**
213
- * Parse handoff mode from YAML string
214
- * Handles both new format (handoff_mode) and legacy format (auto_handoff boolean)
215
- *
216
- * @param yamlContent - YAML string containing settings
217
- * @returns The handoff mode setting
218
- */
219
- export declare function parseHandoffModeFromYaml(yamlContent: string): HandoffMode;
220
- /**
221
- * Get handoff behavior based on mode
222
- *
223
- * @param mode - The handoff mode setting
224
- * @returns Behavior configuration for the mode
225
- */
226
- export declare function getHandoffBehavior(mode: HandoffMode): HandoffBehavior;
227
- /**
228
- * Format handoff history entry for session file
229
- * Creates a markdown section with table row for the handoff
230
- *
231
- * @param entry - Handoff history entry to format
232
- * @returns Markdown string for the handoff history section
233
- */
234
- export declare function formatHandoffHistory(entry: HandoffHistoryEntry): string;
235
- /**
236
- * Threshold for context percentage to trigger context clear
237
- * When auto mode is enabled and context exceeds this threshold, emit CONTEXT_CLEAR
238
- */
239
- export declare const CONTEXT_CLEAR_THRESHOLD = 60;
240
- /**
241
- * Parameters for context clear marker decision
242
- */
243
- export interface ContextClearParams {
244
- /** Current handoff mode from settings */
245
- handoffMode: HandoffMode;
246
- /** Current context usage percentage (0-100) */
247
- contextPercent: number;
248
- /** Next agent to load after clear (for marker value) */
249
- nextAgent?: string;
250
- }
251
- /**
252
- * Determine if CONTEXT_CLEAR marker should be emitted
253
- *
254
- * Returns true when:
255
- * - handoffMode is 'auto'
256
- * - contextPercent exceeds CONTEXT_CLEAR_THRESHOLD
257
- *
258
- * @param params - Context clear parameters
259
- * @returns true if CONTEXT_CLEAR should be emitted
260
- */
261
- export declare function shouldEmitContextClear(params: ContextClearParams): boolean;
262
- /**
263
- * Format the CYCLIST marker for context clear or regular handoff
264
- *
265
- * When auto mode and high context: returns CONTEXT_CLEAR marker
266
- * Otherwise: returns regular HANDOFF marker
267
- *
268
- * @param params - Context clear parameters including nextAgent
269
- * @returns Marker string (<!-- CYCLIST:CONTEXT_CLEAR:/agent --> or <!-- CYCLIST:HANDOFF:/agent -->)
270
- */
271
- export declare function formatContextClearMarker(params: ContextClearParams): string;
272
- /**
273
- * Format a human-readable output message for context clear handoffs
274
- *
275
- * Includes context percentage and the marker for Cyclist to detect
276
- *
277
- * @param params - Context clear parameters
278
- * @returns Formatted output string for display
279
- */
280
- export declare function formatContextClearOutput(params: ContextClearParams): string;
281
- //# sourceMappingURL=generic-handoff.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generic-handoff.d.ts","sourceRoot":"","sources":["../../src/workflow/generic-handoff.ts"],"names":[],"mappings":"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"}