@pennyfarthing/core 11.1.0 → 11.2.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/README.md +8 -8
- package/package.json +16 -14
- package/packages/core/dist/cli/utils/constants.d.ts +1 -1
- package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/constants.js +2 -1
- package/packages/core/dist/cli/utils/constants.js.map +1 -1
- package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
- package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.js +334 -0
- package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
- package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
- package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
- package/packages/core/dist/server/api/git.d.ts +13 -1
- package/packages/core/dist/server/api/git.d.ts.map +1 -1
- package/packages/core/dist/server/api/git.js +53 -34
- package/packages/core/dist/server/api/git.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
- package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
- package/packages/core/dist/server/otlp-receiver.js +185 -24
- package/packages/core/dist/server/otlp-receiver.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
- package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
- package/packages/core/dist/server/otlp-receiver.test.js +446 -0
- package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
- package/packages/core/dist/shared/portrait-resolver.js +27 -0
- package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
- package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
- package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
- package/packages/core/dist/shared/skill-search.test.js +2 -2
- package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
- package/pennyfarthing-dist/agents/dev.md +1 -1
- package/pennyfarthing-dist/agents/reviewer.md +1 -1
- package/pennyfarthing-dist/agents/sm-setup.md +1 -1
- package/pennyfarthing-dist/agents/sm.md +2 -2
- package/pennyfarthing-dist/agents/tea.md +1 -1
- package/pennyfarthing-dist/agents/testing-runner.md +2 -1
- package/pennyfarthing-dist/commands/pf-chore.md +2 -2
- package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
- package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
- package/pennyfarthing-dist/guides/bikerack.md +3 -3
- package/pennyfarthing-dist/guides/hooks.md +1 -1
- package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
- package/pennyfarthing-dist/guides/xml-tags.md +2 -2
- package/pennyfarthing-dist/scripts/README.md +1 -1
- package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
- package/pennyfarthing-dist/scripts/core/check-context.sh +1 -1
- package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
- package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
- package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
- package/pennyfarthing-dist/scripts/git/README.md +24 -14
- package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
- package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
- package/pennyfarthing-dist/scripts/git/release.sh +0 -0
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
- package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/README.md +1 -1
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
- package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
- package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
- package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
- package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
- package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
- package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
- package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
- package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
- package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
- package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
- package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
- package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
- package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
- package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
- package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
- package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
- package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
- package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
- package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
- package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
- package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
- package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
- package/pennyfarthing_scripts/CLAUDE.md +26 -4
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/cli.py +3 -5
- package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
- package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
- package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
- package/pennyfarthing_scripts/bikerack/cli.py +10 -11
- package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
- package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
- package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
- package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
- package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
- package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
- package/pennyfarthing_scripts/bikerack/tui.py +336 -30
- package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
- package/pennyfarthing_scripts/cli.py +37 -65
- package/pennyfarthing_scripts/consultation/__init__.py +1 -0
- package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/consultation/cli.py +149 -0
- package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
- package/pennyfarthing_scripts/context.py +3 -3
- package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__init__.py +12 -1
- 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__/hooks_installer.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/create_branches.py +3 -4
- package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
- package/pennyfarthing_scripts/git/repos.py +196 -0
- package/pennyfarthing_scripts/git/status_all.py +27 -11
- package/pennyfarthing_scripts/git/worktree.py +302 -0
- package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/cli.py +143 -40
- package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
- package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
- package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing_scripts/hooks.py +3 -17
- package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
- package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/heatmap.py +655 -0
- package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session_start_hook.py +1 -1
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/loader.py +15 -1
- package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.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/test_bikerack.py +51 -51
- package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
- package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
- package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
- package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
- package/pennyfarthing_scripts/validate/cli.py +17 -5
- package/pennyfarthing_scripts/workflow/__init__.py +40 -0
- package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/cli.py +1099 -0
- package/pennyfarthing_scripts/workflow/helpers.py +241 -0
- package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
- package/pennyfarthing_scripts/workflow/state.py +112 -0
- package/scripts/README.md +41 -0
- package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
- package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
- package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
- package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
- package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
|
@@ -5,15 +5,16 @@ Usage:
|
|
|
5
5
|
pf git [COMMAND] [ARGS]...
|
|
6
6
|
|
|
7
7
|
Commands:
|
|
8
|
-
status
|
|
9
|
-
cleanup
|
|
10
|
-
branches
|
|
11
|
-
|
|
8
|
+
status Check git status of all project repos
|
|
9
|
+
cleanup Organize changes into proper commits/branches
|
|
10
|
+
branches Create feature branches from a story
|
|
11
|
+
worktree Manage git worktrees for parallel work
|
|
12
|
+
install-hooks Install git hooks with .d/ dispatcher pattern
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
|
-
import
|
|
15
|
+
import asyncio
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
import click
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@click.group()
|
|
@@ -22,10 +23,11 @@ def git():
|
|
|
22
23
|
|
|
23
24
|
\b
|
|
24
25
|
Commands:
|
|
25
|
-
status
|
|
26
|
-
cleanup
|
|
27
|
-
branches
|
|
28
|
-
|
|
26
|
+
status - Check git status of all repos
|
|
27
|
+
cleanup - Organize changes into commits/branches
|
|
28
|
+
branches - Create feature branches from a story
|
|
29
|
+
worktree - Manage git worktrees for parallel work
|
|
30
|
+
install-hooks - Install git hooks with .d/ dispatcher
|
|
29
31
|
"""
|
|
30
32
|
pass
|
|
31
33
|
|
|
@@ -37,21 +39,38 @@ def status(brief: bool):
|
|
|
37
39
|
|
|
38
40
|
Shows branch, uncommitted changes, and ahead/behind status for each repo.
|
|
39
41
|
"""
|
|
40
|
-
import
|
|
42
|
+
from pennyfarthing_scripts.git.repos import get_repo_paths, load_repos_config
|
|
43
|
+
from pennyfarthing_scripts.git.status_all import (
|
|
44
|
+
format_status_brief,
|
|
45
|
+
format_status_full,
|
|
46
|
+
format_summary,
|
|
47
|
+
get_all_repo_status,
|
|
48
|
+
)
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
repo_paths = get_repo_paths()
|
|
51
|
+
config = load_repos_config()
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
# Build repo list with per-repo upstream refs
|
|
54
|
+
repos_with_upstream: list[tuple[str, object, str]] = []
|
|
55
|
+
for name, path in repo_paths:
|
|
56
|
+
upstream = config[name].upstream_ref if name in config else "origin/main"
|
|
57
|
+
repos_with_upstream.append((name, path, upstream))
|
|
58
|
+
|
|
59
|
+
statuses = asyncio.run(get_all_repo_status(repos_with_upstream))
|
|
48
60
|
|
|
49
|
-
cmd = [str(script)]
|
|
50
61
|
if brief:
|
|
51
|
-
|
|
62
|
+
click.echo(format_status_brief(statuses))
|
|
63
|
+
else:
|
|
64
|
+
click.echo("━" * 40)
|
|
65
|
+
click.echo(" Git Status - All Repos")
|
|
66
|
+
click.echo("━" * 40)
|
|
67
|
+
click.echo()
|
|
68
|
+
click.echo(format_status_full(statuses))
|
|
69
|
+
click.echo("━" * 40)
|
|
70
|
+
click.echo(format_summary(statuses))
|
|
52
71
|
|
|
53
|
-
|
|
54
|
-
raise SystemExit(
|
|
72
|
+
has_issues = any(not s.is_clean or s.has_unpushed for s in statuses)
|
|
73
|
+
raise SystemExit(1 if has_issues else 0)
|
|
55
74
|
|
|
56
75
|
|
|
57
76
|
@git.command()
|
|
@@ -67,34 +86,118 @@ def cleanup():
|
|
|
67
86
|
|
|
68
87
|
|
|
69
88
|
@git.command()
|
|
70
|
-
@click.argument("
|
|
71
|
-
|
|
72
|
-
""
|
|
89
|
+
@click.argument("branch_name")
|
|
90
|
+
@click.option(
|
|
91
|
+
"--repos",
|
|
92
|
+
type=click.Choice(["all", "api", "ui"]),
|
|
93
|
+
default="all",
|
|
94
|
+
help="Which repos to target",
|
|
95
|
+
)
|
|
96
|
+
def branches(branch_name: str, repos: str):
|
|
97
|
+
"""Create feature branches across all configured repos.
|
|
73
98
|
|
|
74
99
|
\b
|
|
75
100
|
Arguments:
|
|
76
|
-
|
|
101
|
+
BRANCH_NAME - The branch name to create (e.g., feat/86-3-file-upload)
|
|
77
102
|
"""
|
|
78
|
-
import
|
|
103
|
+
from pennyfarthing_scripts.git.create_branches import (
|
|
104
|
+
create_feature_branches,
|
|
105
|
+
detect_worktree,
|
|
106
|
+
filter_repos,
|
|
107
|
+
format_results,
|
|
108
|
+
)
|
|
109
|
+
from pennyfarthing_scripts.git.repos import get_repo_paths
|
|
110
|
+
|
|
111
|
+
is_worktree, worktree_name, _ = detect_worktree()
|
|
112
|
+
if is_worktree:
|
|
113
|
+
click.echo(f"📂 Detected worktree: {worktree_name}")
|
|
114
|
+
else:
|
|
115
|
+
click.echo("📂 Using main checkout")
|
|
116
|
+
|
|
117
|
+
all_repos = get_repo_paths()
|
|
118
|
+
filtered = filter_repos(all_repos, repos)
|
|
119
|
+
|
|
120
|
+
if not filtered:
|
|
121
|
+
click.echo(f"No repos match filter: {repos}", err=True)
|
|
122
|
+
raise SystemExit(1)
|
|
79
123
|
|
|
80
|
-
|
|
81
|
-
|
|
124
|
+
results = asyncio.run(create_feature_branches(filtered, branch_name))
|
|
125
|
+
click.echo(format_results(results, branch_name))
|
|
82
126
|
|
|
83
|
-
|
|
84
|
-
click.echo("Error: create-branches.sh not found", err=True)
|
|
85
|
-
raise SystemExit(1)
|
|
127
|
+
from pennyfarthing_scripts.git.create_branches import BranchAction
|
|
86
128
|
|
|
87
|
-
|
|
88
|
-
raise SystemExit(
|
|
129
|
+
has_errors = any(r.action == BranchAction.ERROR for r in results)
|
|
130
|
+
raise SystemExit(1 if has_errors else 0)
|
|
89
131
|
|
|
90
132
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
133
|
+
# Worktree subgroup
|
|
134
|
+
@git.group()
|
|
135
|
+
def worktree():
|
|
136
|
+
"""Manage git worktrees for parallel development.
|
|
137
|
+
|
|
138
|
+
\b
|
|
139
|
+
Commands:
|
|
140
|
+
create - Create worktree(s) for parallel work
|
|
141
|
+
remove - Remove worktree and clean up
|
|
142
|
+
list - List all active worktrees
|
|
143
|
+
status - Show detailed worktree status
|
|
144
|
+
"""
|
|
145
|
+
pass
|
|
94
146
|
|
|
95
|
-
|
|
96
|
-
|
|
147
|
+
|
|
148
|
+
@worktree.command("create")
|
|
149
|
+
@click.argument("name")
|
|
150
|
+
@click.argument("branch")
|
|
151
|
+
@click.option(
|
|
152
|
+
"--repos",
|
|
153
|
+
default="all",
|
|
154
|
+
help="Repos filter: all, api, ui, or comma-separated names",
|
|
155
|
+
)
|
|
156
|
+
def worktree_create(name: str, branch: str, repos: str):
|
|
157
|
+
"""Create worktree(s) for parallel work.
|
|
158
|
+
|
|
159
|
+
\b
|
|
160
|
+
Arguments:
|
|
161
|
+
NAME - Worktree name (e.g., wt-5-3a)
|
|
162
|
+
BRANCH - Branch name (e.g., feat/5-3a-file-upload)
|
|
97
163
|
"""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
164
|
+
from pennyfarthing_scripts.git.worktree import create_worktree
|
|
165
|
+
|
|
166
|
+
raise SystemExit(create_worktree(name, branch, repos))
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@worktree.command("remove")
|
|
170
|
+
@click.argument("name")
|
|
171
|
+
def worktree_remove(name: str):
|
|
172
|
+
"""Remove worktree and clean up."""
|
|
173
|
+
from pennyfarthing_scripts.git.worktree import remove_worktree
|
|
174
|
+
|
|
175
|
+
raise SystemExit(remove_worktree(name))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@worktree.command("list")
|
|
179
|
+
def worktree_list():
|
|
180
|
+
"""List all active worktrees."""
|
|
181
|
+
from pennyfarthing_scripts.git.worktree import list_worktrees
|
|
182
|
+
|
|
183
|
+
raise SystemExit(list_worktrees())
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@worktree.command("status")
|
|
187
|
+
def worktree_status():
|
|
188
|
+
"""Show detailed worktree status."""
|
|
189
|
+
from pennyfarthing_scripts.git.worktree import show_worktree_status
|
|
190
|
+
|
|
191
|
+
raise SystemExit(show_worktree_status())
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@git.command("install-hooks")
|
|
195
|
+
def install_hooks():
|
|
196
|
+
"""Install git hooks with .d/ dispatcher pattern.
|
|
197
|
+
|
|
198
|
+
Creates .d/ directories, symlinks pennyfarthing hooks, and
|
|
199
|
+
migrates existing user hooks.
|
|
200
|
+
"""
|
|
201
|
+
from pennyfarthing_scripts.git.hooks_installer import install_git_hooks
|
|
202
|
+
|
|
203
|
+
raise SystemExit(install_git_hooks())
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -53,6 +53,18 @@ def complete_phase(
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
content = session_path.read_text()
|
|
56
|
+
|
|
57
|
+
# Guard: require assessment section before allowing gated phase transitions.
|
|
58
|
+
# Skip/manual transitions (e.g. setup→implement) don't need assessments.
|
|
59
|
+
if gate_type not in ("skip", "manual", "-", None, "") and not re.search(
|
|
60
|
+
r"^##\s+.*Assessment", content, re.MULTILINE
|
|
61
|
+
):
|
|
62
|
+
return {
|
|
63
|
+
"status": "error",
|
|
64
|
+
"session_file": str(session_path),
|
|
65
|
+
"error": "No assessment found in session file. Write your assessment before completing the phase.",
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
57
69
|
|
|
58
70
|
from_agent = _get_phase_agent(project_root, workflow, from_phase)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""Resolve gate for current workflow phase.
|
|
2
2
|
|
|
3
|
-
Reads workflow YAML, finds current phase gate,
|
|
4
|
-
|
|
3
|
+
Reads workflow YAML, finds current phase gate, and returns gate info.
|
|
4
|
+
Assessment checks are enforced in complete_phase (not here) to avoid
|
|
5
|
+
race conditions where agents call resolve-gate before writing assessments.
|
|
5
6
|
|
|
6
7
|
Story: 105-1 (Script-First Handoff)
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
10
|
from __future__ import annotations
|
|
10
11
|
|
|
11
|
-
import re
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
import yaml
|
|
@@ -95,22 +95,13 @@ def resolve_gate(
|
|
|
95
95
|
assessment_found=True,
|
|
96
96
|
)
|
|
97
97
|
|
|
98
|
-
session_path = project_root / ".session" / f"{story_id}-session.md"
|
|
99
|
-
assessment_found = False
|
|
100
|
-
if session_path.exists():
|
|
101
|
-
content = session_path.read_text()
|
|
102
|
-
assessment_found = bool(
|
|
103
|
-
re.search(r"^##\s+.*Assessment", content, re.MULTILINE)
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
status = "ready" if assessment_found else "blocked"
|
|
107
98
|
return _result(
|
|
108
|
-
status=
|
|
99
|
+
status="ready",
|
|
109
100
|
gate_type=gate_type,
|
|
110
101
|
gate_file=gate_file,
|
|
111
102
|
next_agent=next_agent,
|
|
112
103
|
next_phase=next_phase,
|
|
113
|
-
assessment_found=
|
|
104
|
+
assessment_found=True,
|
|
114
105
|
)
|
|
115
106
|
|
|
116
107
|
|
|
File without changes
|
|
@@ -30,10 +30,7 @@ import yaml
|
|
|
30
30
|
|
|
31
31
|
# WheelHub port file - central coordination server for all communication
|
|
32
32
|
# Per ADR-0004: "the hub where all communication converges"
|
|
33
|
-
CYCLIST_PORT_FILE = ".
|
|
34
|
-
|
|
35
|
-
# Legacy approval port file (deprecated, for backwards compatibility during migration)
|
|
36
|
-
CYCLIST_APPROVAL_PORT_FILE_LEGACY = ".cyclist-approval-port"
|
|
33
|
+
CYCLIST_PORT_FILE = ".wheelhub-port"
|
|
37
34
|
|
|
38
35
|
# Default port if file not found
|
|
39
36
|
DEFAULT_CYCLIST_PORT = 7431
|
|
@@ -51,7 +48,7 @@ def find_project_root(start_dir: Path | None = None) -> Path | None:
|
|
|
51
48
|
"""Find the project root by looking for marker files.
|
|
52
49
|
|
|
53
50
|
Searches for (in order):
|
|
54
|
-
1. .
|
|
51
|
+
1. .wheelhub-port (WheelHub is running)
|
|
55
52
|
2. .pennyfarthing directory
|
|
56
53
|
3. .claude directory
|
|
57
54
|
|
|
@@ -68,8 +65,6 @@ def find_project_root(start_dir: Path | None = None) -> Path | None:
|
|
|
68
65
|
# Check for Cyclist port files first (indicates Cyclist is running)
|
|
69
66
|
if (current / CYCLIST_PORT_FILE).exists():
|
|
70
67
|
return current
|
|
71
|
-
if (current / CYCLIST_APPROVAL_PORT_FILE_LEGACY).exists():
|
|
72
|
-
return current
|
|
73
68
|
# Fall back to directory markers
|
|
74
69
|
if (current / ".pennyfarthing").is_dir():
|
|
75
70
|
return current
|
|
@@ -89,7 +84,7 @@ def read_port_file(file_name: str, project_root: Path | None = None) -> int | No
|
|
|
89
84
|
"""Read a port number from a Cyclist port file.
|
|
90
85
|
|
|
91
86
|
Args:
|
|
92
|
-
file_name: Name of the port file (.
|
|
87
|
+
file_name: Name of the port file (e.g. .wheelhub-port)
|
|
93
88
|
project_root: Project root directory (auto-detected if not provided)
|
|
94
89
|
|
|
95
90
|
Returns:
|
|
@@ -130,18 +125,9 @@ def get_cyclist_port(project_root: Path | None = None) -> int:
|
|
|
130
125
|
if port:
|
|
131
126
|
return port
|
|
132
127
|
|
|
133
|
-
# Fallback to legacy approval port file during migration
|
|
134
|
-
legacy_port = read_port_file(CYCLIST_APPROVAL_PORT_FILE_LEGACY, project_root)
|
|
135
|
-
if legacy_port:
|
|
136
|
-
return legacy_port
|
|
137
|
-
|
|
138
128
|
return DEFAULT_CYCLIST_PORT
|
|
139
129
|
|
|
140
130
|
|
|
141
|
-
# Alias for backwards compatibility
|
|
142
|
-
get_approval_port = get_cyclist_port
|
|
143
|
-
|
|
144
|
-
|
|
145
131
|
# =============================================================================
|
|
146
132
|
# Settings Loading
|
|
147
133
|
# =============================================================================
|
|
@@ -8,7 +8,7 @@ via HTTP to get approval decisions.
|
|
|
8
8
|
|
|
9
9
|
Flow:
|
|
10
10
|
1. Claude Code calls this script with tool info via stdin (JSON)
|
|
11
|
-
2. Script reads port from .
|
|
11
|
+
2. Script reads port from .wheelhub-port in project directory
|
|
12
12
|
3. Script sends request to WheelHub's /api/hook-request endpoint
|
|
13
13
|
4. WheelHub shows approval modal, user decides
|
|
14
14
|
5. Script receives response, outputs JSON decision to stdout
|
|
Binary file
|
|
Binary file
|