@pennyfarthing/core 8.0.2 → 8.1.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.
- package/package.json +1 -1
- package/pennyfarthing-dist/agents/reviewer.md +21 -4
- package/pennyfarthing-dist/agents/sm.md +10 -0
- package/pennyfarthing-dist/commands/architect.md +1 -1
- package/pennyfarthing-dist/commands/dev.md +1 -1
- package/pennyfarthing-dist/commands/devops.md +1 -1
- package/pennyfarthing-dist/commands/health-check.md +1 -1
- package/pennyfarthing-dist/commands/orchestrator.md +1 -1
- package/pennyfarthing-dist/commands/parallel-work.md +2 -2
- package/pennyfarthing-dist/commands/pm.md +1 -1
- package/pennyfarthing-dist/commands/prime.md +18 -22
- package/pennyfarthing-dist/commands/reviewer.md +1 -1
- package/pennyfarthing-dist/commands/set-theme.md +1 -1
- package/pennyfarthing-dist/commands/sm.md +1 -1
- package/pennyfarthing-dist/commands/sprint.md +13 -4
- package/pennyfarthing-dist/commands/tea.md +1 -1
- package/pennyfarthing-dist/commands/tech-writer.md +1 -1
- package/pennyfarthing-dist/commands/ux-designer.md +1 -1
- package/pennyfarthing-dist/commands/work.md +2 -2
- package/pennyfarthing-dist/guides/agent-behavior.md +15 -1
- package/pennyfarthing-dist/personas/themes/rome.yaml +11 -11
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/cli.py +168 -0
- package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/cli.py +8 -1
- package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/cli.py +144 -84
- package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
- package/pennyfarthing_scripts/workflow.py +104 -0
package/package.json
CHANGED
|
@@ -124,6 +124,7 @@ OWNER=$(.pennyfarthing/scripts/workflow/phase-owner.sh {workflow} {phase})
|
|
|
124
124
|
## MANDATORY: Complete Before Exiting
|
|
125
125
|
|
|
126
126
|
- [ ] Write Reviewer Assessment to session file
|
|
127
|
+
- [ ] **If APPROVED:** Merge PR directly with `gh pr merge {PR_NUMBER} --merge --delete-branch`
|
|
127
128
|
- [ ] Spawn `handoff` subagent with VERDICT (approved/rejected)
|
|
128
129
|
- [ ] Verify handoff completed (subagent emits marker)
|
|
129
130
|
</handoff-gate>
|
|
@@ -158,16 +159,32 @@ OWNER=$(.pennyfarthing/scripts/workflow/phase-owner.sh {workflow} {phase})
|
|
|
158
159
|
<exit-sequence>
|
|
159
160
|
## Exit Sequence
|
|
160
161
|
|
|
162
|
+
### If APPROVED:
|
|
161
163
|
1. Write Reviewer Assessment to session file
|
|
162
|
-
2.
|
|
163
|
-
|
|
164
|
+
2. **Merge the PR directly** (don't wait for SM):
|
|
165
|
+
```bash
|
|
166
|
+
gh pr merge {PR_NUMBER} --merge --delete-branch
|
|
167
|
+
```
|
|
168
|
+
3. Update session phase to `finish`
|
|
169
|
+
4. Spawn `handoff` subagent with VERDICT=approved
|
|
170
|
+
5. Await `HANDOFF_RESULT` with `next_agent` (will be `sm`)
|
|
171
|
+
6. **ABSOLUTE LAST ACTION:**
|
|
172
|
+
```bash
|
|
173
|
+
.pennyfarthing/scripts/core/handoff-marker.sh sm
|
|
174
|
+
```
|
|
175
|
+
7. Output result verbatim and EXIT
|
|
176
|
+
|
|
177
|
+
### If REJECTED:
|
|
178
|
+
1. Write Reviewer Assessment to session file
|
|
179
|
+
2. Spawn `handoff` subagent with VERDICT=rejected
|
|
180
|
+
3. Await `HANDOFF_RESULT` with `next_agent` (will be `dev`)
|
|
164
181
|
4. **ABSOLUTE LAST ACTION:**
|
|
165
182
|
```bash
|
|
166
|
-
.pennyfarthing/scripts/
|
|
183
|
+
.pennyfarthing/scripts/core/handoff-marker.sh dev
|
|
167
184
|
```
|
|
168
185
|
5. Output result verbatim and EXIT
|
|
169
186
|
|
|
170
|
-
**Verdict routing:** APPROVED → sm | REJECTED → dev
|
|
187
|
+
**Verdict routing:** APPROVED → merge PR, then sm | REJECTED → dev
|
|
171
188
|
</exit-sequence>
|
|
172
189
|
|
|
173
190
|
<skills>
|
|
@@ -175,6 +175,16 @@ Present to user:
|
|
|
175
175
|
- **Stepped workflow** → Tell user to run `/workflow start {workflow}` (no handoff)
|
|
176
176
|
</new-work-flow>
|
|
177
177
|
|
|
178
|
+
<merge-gate>
|
|
179
|
+
## Merge Gate (BLOCKING)
|
|
180
|
+
|
|
181
|
+
Before starting new work: `gh pr list --state open` - BLOCKS if any exist.
|
|
182
|
+
|
|
183
|
+
Open PRs → incomplete work → merge conflicts, stale branches, CI failures.
|
|
184
|
+
|
|
185
|
+
**Resolution:** Merge/close all PRs first. Use `/reviewer` to complete reviews.
|
|
186
|
+
</merge-gate>
|
|
187
|
+
|
|
178
188
|
<gate>
|
|
179
189
|
## Pre-Handoff Checklist (BLOCKING)
|
|
180
190
|
|
|
@@ -3,5 +3,5 @@ description: System Architect - Technical design and architecture
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "architect"
|
|
7
7
|
```
|
|
@@ -3,5 +3,5 @@ description: Developer - Feature implementation and coding
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "dev"
|
|
7
7
|
```
|
|
@@ -3,5 +3,5 @@ description: DevOps Engineer - Infrastructure and deployment automation
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "devops"
|
|
7
7
|
```
|
|
@@ -3,5 +3,5 @@ description: Orchestrator - Coordinator of all agents and meta operations
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "orchestrator"
|
|
7
7
|
```
|
|
@@ -3,7 +3,7 @@ description: Start parallel work in a new worktree
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm"
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
<parallel-work-flow>
|
|
@@ -67,5 +67,5 @@ Invoke SM to complete story setup in the worktree context.
|
|
|
67
67
|
</agent-activation>
|
|
68
68
|
|
|
69
69
|
<agent-exit>
|
|
70
|
-
On exit: Capture learnings to sidecar
|
|
70
|
+
On exit: Capture learnings to sidecar.
|
|
71
71
|
</agent-exit>
|
|
@@ -3,5 +3,5 @@ description: Product Manager - Strategic planning and prioritization
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "pm"
|
|
7
7
|
```
|
|
@@ -4,7 +4,7 @@ description: Load essential project context at agent activation
|
|
|
4
4
|
|
|
5
5
|
<purpose>
|
|
6
6
|
Quickly load essential context files to reduce agent cold-start overhead.
|
|
7
|
-
Automatically invoked on agent activation via agent
|
|
7
|
+
Automatically invoked on agent activation via `pf agent start`.
|
|
8
8
|
</purpose>
|
|
9
9
|
|
|
10
10
|
<when-to-use>
|
|
@@ -17,23 +17,23 @@ Automatically invoked on agent activation via agent-session.sh.
|
|
|
17
17
|
|
|
18
18
|
## Running /prime
|
|
19
19
|
|
|
20
|
-
Use the
|
|
20
|
+
Use the Python CLI:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
# Load all essential context (default)
|
|
24
|
-
|
|
24
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm"
|
|
25
25
|
|
|
26
|
-
# Minimal mode -
|
|
27
|
-
|
|
26
|
+
# Minimal mode - fastest startup
|
|
27
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm" --minimal
|
|
28
28
|
|
|
29
29
|
# Full mode - include domain docs
|
|
30
|
-
|
|
30
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm" --full
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
|
|
32
|
+
# Skip persona loading
|
|
33
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm" --no-persona
|
|
34
34
|
|
|
35
|
-
#
|
|
36
|
-
|
|
35
|
+
# JSON output (for Cyclist integration)
|
|
36
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm" --json
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
## Options
|
|
@@ -106,17 +106,16 @@ With `--quiet`, section headers are suppressed.
|
|
|
106
106
|
|
|
107
107
|
<integration>
|
|
108
108
|
|
|
109
|
-
##
|
|
109
|
+
## Python CLI Integration
|
|
110
110
|
|
|
111
111
|
The `/prime` command is automatically invoked when agents activate:
|
|
112
112
|
|
|
113
113
|
1. User invokes `/sm`, `/tea`, `/dev`, or `/reviewer`
|
|
114
|
-
2. `agent
|
|
115
|
-
3.
|
|
116
|
-
4.
|
|
117
|
-
5. Agent starts with full context AND their learned patterns loaded
|
|
114
|
+
2. `pf agent start <name>` runs
|
|
115
|
+
3. Context is loaded: workflow state, agent definition, persona, behavior guide, sprint context, session, sidecars
|
|
116
|
+
4. Agent starts with full context AND their learned patterns loaded
|
|
118
117
|
|
|
119
|
-
This reduces the "cold start" problem where agents must discover context through multiple file reads.
|
|
118
|
+
This reduces the "cold start" problem where agents must discover context through multiple file reads.
|
|
120
119
|
|
|
121
120
|
## Manual Refresh
|
|
122
121
|
|
|
@@ -130,11 +129,8 @@ If context becomes stale mid-session, run `/prime` manually:
|
|
|
130
129
|
</integration>
|
|
131
130
|
|
|
132
131
|
<reference>
|
|
133
|
-
- **
|
|
134
|
-
- **
|
|
135
|
-
- **Loads:** CLAUDE.md, sprint, session, sidecar, shared context, shared behavior, tactical guide
|
|
132
|
+
- **CLI:** `pf agent start <name>` or `python3 -m pennyfarthing_scripts.cli agent start <name>`
|
|
133
|
+
- **Loads:** Workflow state, agent definition, persona, behavior guide, sprint context, session, sidecars
|
|
136
134
|
- **Sidecar location:** `.pennyfarthing/sidecars/{agent}/*.md`
|
|
137
|
-
- **
|
|
138
|
-
- **Shared behavior:** `.pennyfarthing/guides/agent-behavior.md` (all agents)
|
|
139
|
-
- **Tactical guide:** `.pennyfarthing/guides/agent-behavior.md` (sm, tea, dev, reviewer only)
|
|
135
|
+
- **Behavior guide:** `.pennyfarthing/guides/agent-behavior.md` (all agents)
|
|
140
136
|
</reference>
|
|
@@ -3,5 +3,5 @@ description: Code Reviewer - Critical code review and quality enforcement
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "reviewer"
|
|
7
7
|
```
|
|
@@ -51,6 +51,6 @@ Change the active persona theme for all agents.
|
|
|
51
51
|
|
|
52
52
|
6. Refresh the current agent's persona to apply the new theme:
|
|
53
53
|
```bash
|
|
54
|
-
|
|
54
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm"
|
|
55
55
|
```
|
|
56
56
|
This outputs the updated persona. **Adopt the new character immediately** - do not continue using the old persona.
|
|
@@ -3,5 +3,5 @@ description: Scrum Master - Story coordination and sprint management
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm"
|
|
7
7
|
```
|
|
@@ -50,6 +50,14 @@ Start work on a story. Primary entry point for development.
|
|
|
50
50
|
| `next` | Auto-select highest priority story |
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
+
# MERGE GATE: Check for open PRs first (blocks if any exist)
|
|
54
|
+
OPEN_PRS=$(gh pr list --state open --json number --jq 'length' 2>/dev/null || echo "0")
|
|
55
|
+
if [[ "$OPEN_PRS" -gt 0 ]]; then
|
|
56
|
+
echo "⛔ BLOCKED: $OPEN_PRS open PR(s) - merge or close before starting new work"
|
|
57
|
+
gh pr list --state open
|
|
58
|
+
# Don't proceed until PRs are cleared
|
|
59
|
+
fi
|
|
60
|
+
|
|
53
61
|
# Check if story is available
|
|
54
62
|
.pennyfarthing/scripts/sprint/check-story.sh <story-id>
|
|
55
63
|
|
|
@@ -58,10 +66,11 @@ Start work on a story. Primary entry point for development.
|
|
|
58
66
|
|
|
59
67
|
<workflow>
|
|
60
68
|
When starting work, this command:
|
|
61
|
-
1.
|
|
62
|
-
2.
|
|
63
|
-
3. SM
|
|
64
|
-
4.
|
|
69
|
+
1. **Checks merge gate** - blocks if open PRs exist
|
|
70
|
+
2. Validates story availability
|
|
71
|
+
3. Loads SM agent
|
|
72
|
+
4. SM creates context and claims Jira
|
|
73
|
+
5. Hands off to TEA (tdd) or Dev (trivial)
|
|
65
74
|
</workflow>
|
|
66
75
|
|
|
67
76
|
### `/sprint archive <story-id> [pr-number] [--apply]`
|
|
@@ -3,5 +3,5 @@ description: Test Engineer/Architect - Test strategy and TDD
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "tea"
|
|
7
7
|
```
|
|
@@ -3,5 +3,5 @@ description: Technical Writer - Documentation creation and maintenance
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "tech-writer"
|
|
7
7
|
```
|
|
@@ -3,5 +3,5 @@ description: UX Designer - User experience design and UI patterns
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
6
|
+
python3 -m pennyfarthing_scripts.cli agent start "ux-designer"
|
|
7
7
|
```
|
|
@@ -7,9 +7,9 @@ description: Resume work or start new - smart entry point that picks up where yo
|
|
|
7
7
|
<agent-activation>
|
|
8
8
|
**FIRST:** Use Bash tool to run:
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
python3 -m pennyfarthing_scripts.cli agent start "sm"
|
|
11
11
|
```
|
|
12
|
-
This
|
|
12
|
+
This loads your persona. Adopt the character shown in the output.
|
|
13
13
|
</agent-activation>
|
|
14
14
|
|
|
15
15
|
<purpose>
|
|
@@ -43,12 +43,26 @@ $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/foo.sh # BROKEN!
|
|
|
43
43
|
**Sidecar memory:** Capture learnings BEFORE spawning handoff subagent. Don't wait until exit.
|
|
44
44
|
</critical>
|
|
45
45
|
|
|
46
|
+
<critical>
|
|
47
|
+
**Story completion is MANDATORY.** A story is NOT done until:
|
|
48
|
+
1. Reviewer approves and merges the PR
|
|
49
|
+
2. SM runs `finish-story.sh` (archive session, update Jira, clean up)
|
|
50
|
+
|
|
51
|
+
**Never** start new work while stories have open PRs. The merge gate blocks `/sprint work` if open PRs exist.
|
|
52
|
+
|
|
53
|
+
**If stuck in incomplete state:**
|
|
54
|
+
- Open PRs? → Run `/reviewer` to complete reviews and merge
|
|
55
|
+
- Merged but not finished? → Run `/sm` to trigger finish flow
|
|
56
|
+
</critical>
|
|
57
|
+
|
|
46
58
|
---
|
|
47
59
|
|
|
48
60
|
## Reference
|
|
49
61
|
|
|
50
62
|
<info>
|
|
51
|
-
**Workflow:** SM → TEA → Dev → Reviewer → SM (finish). Trivial (1-2 pts) skips TEA.
|
|
63
|
+
**Workflow:** SM → TEA → Dev → Reviewer (merge PR) → SM (finish). Trivial (1-2 pts) skips TEA.
|
|
64
|
+
|
|
65
|
+
**Story completion:** Reviewer merges PR on approval. SM runs `finish-story.sh` to archive and update Jira. A story is NOT complete until SM runs finish.
|
|
52
66
|
|
|
53
67
|
**Confidence:** HIGH=proceed, MEDIUM=ask before risky, LOW=always ask.
|
|
54
68
|
|
|
@@ -13,7 +13,7 @@ theme:
|
|
|
13
13
|
default_humor: subtle
|
|
14
14
|
character_immersion: high
|
|
15
15
|
user_title: Citizen
|
|
16
|
-
portrait_style: ",
|
|
16
|
+
portrait_style: ", ancient Roman mosaic portrait, tessera tile fragments, scratched graffito details, Pompeii wall art style, geometric earth tones, stone texture"
|
|
17
17
|
tier: A
|
|
18
18
|
|
|
19
19
|
zeitgeist:
|
|
@@ -23,7 +23,7 @@ zeitgeist:
|
|
|
23
23
|
agents:
|
|
24
24
|
orchestrator:
|
|
25
25
|
character: Gaius Julius Caesar
|
|
26
|
-
visual: "
|
|
26
|
+
visual: "Clean-shaven Roman man in profile, laurel wreath, purple-bordered toga, aquiline nose, balding, imperial bearing"
|
|
27
27
|
ocean:
|
|
28
28
|
O: 4 # Strategic vision
|
|
29
29
|
C: 5 # Roman discipline
|
|
@@ -50,7 +50,7 @@ agents:
|
|
|
50
50
|
|
|
51
51
|
sm:
|
|
52
52
|
character: Titus Pullo
|
|
53
|
-
visual: "
|
|
53
|
+
visual: "Rough Roman soldier, short stubble, leather armor straps, battle-scarred face, simple military tunic, burly build"
|
|
54
54
|
# JOB FAIR OPTIMIZED: Pullo moved here; Vorenus excels at dev (+6.88)
|
|
55
55
|
ocean:
|
|
56
56
|
O: 3 # Practical soldier
|
|
@@ -78,7 +78,7 @@ agents:
|
|
|
78
78
|
|
|
79
79
|
tea:
|
|
80
80
|
character: Atia of the Julii
|
|
81
|
-
visual: "
|
|
81
|
+
visual: "Roman noblewoman, elaborate curled dark hair with gold pins, draped stola and palla, arched eyebrow, patrician features"
|
|
82
82
|
ocean:
|
|
83
83
|
O: 3 # Street wisdom
|
|
84
84
|
C: 4 # Survival discipline
|
|
@@ -105,7 +105,7 @@ agents:
|
|
|
105
105
|
|
|
106
106
|
dev:
|
|
107
107
|
character: Lucius Vorenus
|
|
108
|
-
visual: "
|
|
108
|
+
visual: "Flat 2D mosaic portrait, clean-shaven Roman centurion in profile, crested helmet, stern face, dark hair"
|
|
109
109
|
# JOB FAIR OPTIMIZED: Vorenus scored best as dev (+6.88 over Pullo)
|
|
110
110
|
ocean:
|
|
111
111
|
O: 2 # Traditional soldier
|
|
@@ -133,7 +133,7 @@ agents:
|
|
|
133
133
|
|
|
134
134
|
reviewer:
|
|
135
135
|
character: Marcus Tullius Cicero
|
|
136
|
-
visual: "
|
|
136
|
+
visual: "Flat 2D mosaic portrait, Roman senator on senate floor, white toga, holding scroll, orating to crowd, marble columns"
|
|
137
137
|
ocean:
|
|
138
138
|
O: 4 # Political insight
|
|
139
139
|
C: 5 # Senatorial discipline
|
|
@@ -160,7 +160,7 @@ agents:
|
|
|
160
160
|
|
|
161
161
|
architect:
|
|
162
162
|
character: Gaius Octavian
|
|
163
|
-
visual: "
|
|
163
|
+
visual: "Flat 2D mosaic portrait, young clean-shaven Roman man, simple toga, youthful face, distant expression"
|
|
164
164
|
ocean:
|
|
165
165
|
O: 4 # Imperial vision
|
|
166
166
|
C: 5 # Strategic discipline
|
|
@@ -187,7 +187,7 @@ agents:
|
|
|
187
187
|
|
|
188
188
|
pm:
|
|
189
189
|
character: Servilia of the Junii
|
|
190
|
-
visual: "
|
|
190
|
+
visual: "Flat 2D mosaic portrait, mature Roman widow, dark hair pulled back, dark stola, strong jaw, severe expression"
|
|
191
191
|
ocean:
|
|
192
192
|
O: 4 # Political survival
|
|
193
193
|
C: 4 # Patrician discipline
|
|
@@ -214,7 +214,7 @@ agents:
|
|
|
214
214
|
|
|
215
215
|
tech-writer:
|
|
216
216
|
character: Posca
|
|
217
|
-
visual: "
|
|
217
|
+
visual: "Flat 2D mosaic portrait, thin Greek freedman, receding hairline, simple tunic, wax tablet, tired eyes"
|
|
218
218
|
ocean:
|
|
219
219
|
O: 4 # Historical perspective
|
|
220
220
|
C: 4 # Scholarly discipline
|
|
@@ -241,7 +241,7 @@ agents:
|
|
|
241
241
|
|
|
242
242
|
ux-designer:
|
|
243
243
|
character: Cleopatra
|
|
244
|
-
visual: "
|
|
244
|
+
visual: "Ancient Egyptian tomb painting style, Queen Cleopatra, black braided hair, golden uraeus crown, heavy kohl eyes, hieroglyphic border, Nile blue and gold"
|
|
245
245
|
ocean:
|
|
246
246
|
O: 4 # Cultural adaptation
|
|
247
247
|
C: 3 # Survival skills
|
|
@@ -268,7 +268,7 @@ agents:
|
|
|
268
268
|
|
|
269
269
|
devops:
|
|
270
270
|
character: Mark Antony
|
|
271
|
-
visual: "
|
|
271
|
+
visual: "Flat 2D mosaic portrait, clean-shaven Roman general, curly dark hair, red cloak, strong jaw"
|
|
272
272
|
ocean:
|
|
273
273
|
O: 2 # Military engineering
|
|
274
274
|
C: 5 # Legion discipline
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pennyfarthing CLI - Command line interface for agent orchestration.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python -m pennyfarthing_scripts.cli [OPTIONS] COMMAND [ARGS]...
|
|
6
|
+
pf [OPTIONS] COMMAND [ARGS]...
|
|
7
|
+
|
|
8
|
+
This module uses lazy loading to keep startup time under 200ms.
|
|
9
|
+
Heavy imports (httpx, workflow modules) are deferred until needed.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
# Get version from package - this is a fast import
|
|
15
|
+
from pennyfarthing_scripts import __version__
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.group()
|
|
19
|
+
@click.version_option(version=__version__, prog_name="pf")
|
|
20
|
+
def cli():
|
|
21
|
+
"""Pennyfarthing CLI - Agent orchestration utilities.
|
|
22
|
+
|
|
23
|
+
Commands are organized into groups:
|
|
24
|
+
|
|
25
|
+
\b
|
|
26
|
+
workflow - Workflow state and phase management
|
|
27
|
+
agent - Agent session management
|
|
28
|
+
sprint - Sprint status and story operations
|
|
29
|
+
"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Import and register sprint group (lazy registration preserves startup time)
|
|
34
|
+
from pennyfarthing_scripts.sprint.cli import sprint
|
|
35
|
+
|
|
36
|
+
cli.add_command(sprint)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@cli.group()
|
|
40
|
+
def agent():
|
|
41
|
+
"""Agent session management.
|
|
42
|
+
|
|
43
|
+
\b
|
|
44
|
+
Commands:
|
|
45
|
+
start - Start an agent session with context
|
|
46
|
+
"""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@agent.command("start")
|
|
51
|
+
@click.argument("name")
|
|
52
|
+
@click.option("--session-id", help="Use explicit session ID")
|
|
53
|
+
@click.option("--no-persona", is_flag=True, help="Skip persona loading")
|
|
54
|
+
@click.option("--json", "json_output", is_flag=True, help="Output as JSON")
|
|
55
|
+
@click.option("--minimal", is_flag=True, help="Skip all context (fastest)")
|
|
56
|
+
@click.option("--full", is_flag=True, help="Include domain docs")
|
|
57
|
+
def agent_start(
|
|
58
|
+
name: str,
|
|
59
|
+
session_id: str | None,
|
|
60
|
+
no_persona: bool,
|
|
61
|
+
json_output: bool,
|
|
62
|
+
minimal: bool,
|
|
63
|
+
full: bool,
|
|
64
|
+
):
|
|
65
|
+
"""Start an agent session with full context.
|
|
66
|
+
|
|
67
|
+
Loads agent definition, persona, behavior guide, sprint context,
|
|
68
|
+
session context, and sidecar memory.
|
|
69
|
+
|
|
70
|
+
\b
|
|
71
|
+
Arguments:
|
|
72
|
+
NAME - Agent name (sm, tea, dev, reviewer, etc.)
|
|
73
|
+
"""
|
|
74
|
+
# Lazy import - only load when command is actually invoked
|
|
75
|
+
from pennyfarthing_scripts.prime import prime
|
|
76
|
+
|
|
77
|
+
exit_code = prime(
|
|
78
|
+
agent_name=name,
|
|
79
|
+
session_id=session_id,
|
|
80
|
+
no_persona=no_persona,
|
|
81
|
+
json_output=json_output,
|
|
82
|
+
minimal=minimal,
|
|
83
|
+
full=full,
|
|
84
|
+
)
|
|
85
|
+
raise SystemExit(exit_code)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@cli.group()
|
|
89
|
+
def workflow():
|
|
90
|
+
"""Workflow state and phase management.
|
|
91
|
+
|
|
92
|
+
\b
|
|
93
|
+
Commands:
|
|
94
|
+
check - Check current workflow state
|
|
95
|
+
phase-check - Verify phase ownership
|
|
96
|
+
handoff - Emit handoff marker
|
|
97
|
+
"""
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@workflow.command("check")
|
|
102
|
+
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
|
|
103
|
+
def workflow_check(output_json: bool):
|
|
104
|
+
"""Check current workflow state.
|
|
105
|
+
|
|
106
|
+
Returns the current story ID, phase, and workflow state.
|
|
107
|
+
"""
|
|
108
|
+
# Lazy import - only load when command is actually invoked
|
|
109
|
+
from pennyfarthing_scripts.workflow import get_workflow_state
|
|
110
|
+
|
|
111
|
+
state = get_workflow_state()
|
|
112
|
+
|
|
113
|
+
if output_json:
|
|
114
|
+
import json
|
|
115
|
+
|
|
116
|
+
click.echo(json.dumps(state, indent=2))
|
|
117
|
+
else:
|
|
118
|
+
click.echo(f"State: {state.get('state', 'unknown')}")
|
|
119
|
+
if state.get("story_id"):
|
|
120
|
+
click.echo(f"Story: {state['story_id']}")
|
|
121
|
+
if state.get("workflow"):
|
|
122
|
+
click.echo(f"Workflow: {state['workflow']}")
|
|
123
|
+
if state.get("phase"):
|
|
124
|
+
click.echo(f"Phase: {state['phase']}")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@workflow.command("phase-check")
|
|
128
|
+
@click.argument("workflow_name")
|
|
129
|
+
@click.argument("phase")
|
|
130
|
+
def workflow_phase_check(workflow_name: str, phase: str):
|
|
131
|
+
"""Check which agent owns a workflow phase.
|
|
132
|
+
|
|
133
|
+
\b
|
|
134
|
+
Arguments:
|
|
135
|
+
WORKFLOW_NAME - The workflow type (tdd, trivial, etc.)
|
|
136
|
+
PHASE - The phase to check (red, implement, review, etc.)
|
|
137
|
+
"""
|
|
138
|
+
# Lazy import
|
|
139
|
+
from pennyfarthing_scripts.workflow import get_phase_owner
|
|
140
|
+
|
|
141
|
+
owner = get_phase_owner(workflow_name, phase)
|
|
142
|
+
click.echo(owner)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@workflow.command("handoff")
|
|
146
|
+
@click.argument("next_agent")
|
|
147
|
+
def workflow_handoff(next_agent: str):
|
|
148
|
+
"""Emit a handoff marker for Cyclist.
|
|
149
|
+
|
|
150
|
+
\b
|
|
151
|
+
Arguments:
|
|
152
|
+
NEXT_AGENT - The agent to hand off to (tea, dev, reviewer, etc.)
|
|
153
|
+
"""
|
|
154
|
+
# Output the marker format expected by Cyclist
|
|
155
|
+
click.echo("---")
|
|
156
|
+
click.echo("AGENT_COMMAND:")
|
|
157
|
+
click.echo(f' marker: "<!-- CYCLIST:HANDOFF:/{next_agent} -->"')
|
|
158
|
+
click.echo(f' fallback: "Run `/{next_agent}` to continue"')
|
|
159
|
+
click.echo("---")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def main():
|
|
163
|
+
"""Entry point for the CLI."""
|
|
164
|
+
cli()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__main__":
|
|
168
|
+
main()
|
|
Binary file
|
|
Binary file
|