@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
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# dialogue-manager.sh — Dialogue file management for tandem agent consultation
|
|
3
|
+
#
|
|
4
|
+
# Creates, appends to, and archives dialogue files recording consultation exchanges
|
|
5
|
+
# between tandem agents. Format defined in ADR-0012 (lines 156-195).
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# dialogue-manager.sh init <story-id> <workflow> <leader> <partner>
|
|
9
|
+
# dialogue-manager.sh append <story-id> <question> <recommendation> <confidence>
|
|
10
|
+
# dialogue-manager.sh outcome <story-id> <exchange-num> <applied|deferred|rejected> [note]
|
|
11
|
+
# dialogue-manager.sh summarize <story-id>
|
|
12
|
+
# dialogue-manager.sh archive <story-id> [jira-key]
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
# Self-locate and set up PROJECT_ROOT
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
18
|
+
source "$SCRIPT_DIR/../lib/find-root.sh"
|
|
19
|
+
|
|
20
|
+
SESSION_DIR="$PROJECT_ROOT/.session"
|
|
21
|
+
ARCHIVE_DIR="$PROJECT_ROOT/sprint/archive"
|
|
22
|
+
SUMMARY_MARKER="## Summary"
|
|
23
|
+
|
|
24
|
+
# =============================================================================
|
|
25
|
+
# Helpers
|
|
26
|
+
# =============================================================================
|
|
27
|
+
|
|
28
|
+
usage() {
|
|
29
|
+
echo "Usage:"
|
|
30
|
+
echo " dialogue-manager.sh init <story-id> <workflow> <leader> <partner>"
|
|
31
|
+
echo " dialogue-manager.sh append <story-id> <question> <recommendation> <confidence>"
|
|
32
|
+
echo " dialogue-manager.sh outcome <story-id> <exchange-num> <applied|deferred|rejected> [note]"
|
|
33
|
+
echo " dialogue-manager.sh summarize <story-id>"
|
|
34
|
+
echo " dialogue-manager.sh archive <story-id> [jira-key]"
|
|
35
|
+
exit 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
dialogue_path() {
|
|
39
|
+
echo "$SESSION_DIR/${1}-dialogue.md"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
now_iso() {
|
|
43
|
+
date -u +"%Y-%m-%dT%H:%M:%SZ"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
now_hhmm() {
|
|
47
|
+
date -u +"%H:%M"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Count existing exchanges in a dialogue file
|
|
51
|
+
count_exchanges() {
|
|
52
|
+
local file="$1"
|
|
53
|
+
grep -c '^## Exchange ' "$file" 2>/dev/null || echo "0"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# =============================================================================
|
|
57
|
+
# Commands
|
|
58
|
+
# =============================================================================
|
|
59
|
+
|
|
60
|
+
cmd_init() {
|
|
61
|
+
local story_id="${1:?Missing story-id}"
|
|
62
|
+
local workflow="${2:?Missing workflow}"
|
|
63
|
+
local leader="${3:?Missing leader}"
|
|
64
|
+
local partner="${4:?Missing partner}"
|
|
65
|
+
local file
|
|
66
|
+
file="$(dialogue_path "$story_id")"
|
|
67
|
+
|
|
68
|
+
if [[ -f "$file" ]]; then
|
|
69
|
+
echo "Dialogue file already exists: $file"
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
mkdir -p "$SESSION_DIR"
|
|
74
|
+
|
|
75
|
+
cat > "$file" <<EOF
|
|
76
|
+
# Tandem Dialogue: ${story_id}
|
|
77
|
+
|
|
78
|
+
**Workflow:** ${workflow}
|
|
79
|
+
**Leader:** ${leader} | **Partner:** ${partner}
|
|
80
|
+
**Started:** $(now_iso)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
${SUMMARY_MARKER}
|
|
85
|
+
- **Total exchanges:** 0
|
|
86
|
+
- **Key decisions:** None
|
|
87
|
+
- **Time in tandem:** 0m
|
|
88
|
+
EOF
|
|
89
|
+
|
|
90
|
+
echo "Created dialogue file: $file"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
cmd_append() {
|
|
94
|
+
local story_id="${1:?Missing story-id}"
|
|
95
|
+
local question="${2:?Missing question}"
|
|
96
|
+
local recommendation="${3:?Missing recommendation}"
|
|
97
|
+
local confidence="${4:?Missing confidence}"
|
|
98
|
+
local file
|
|
99
|
+
file="$(dialogue_path "$story_id")"
|
|
100
|
+
|
|
101
|
+
# Auto-init if file missing
|
|
102
|
+
if [[ ! -f "$file" ]]; then
|
|
103
|
+
echo "Error: Dialogue file not found. Run 'init' first: $file" >&2
|
|
104
|
+
exit 1
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
local num
|
|
108
|
+
num=$(( $(count_exchanges "$file") + 1 ))
|
|
109
|
+
local ts
|
|
110
|
+
ts="$(now_hhmm)"
|
|
111
|
+
|
|
112
|
+
# Extract leader and partner from header
|
|
113
|
+
local leader partner
|
|
114
|
+
leader=$(grep '^\*\*Leader:\*\*' "$file" | sed 's/.*\*\*Leader:\*\* \([^ ]*\).*/\1/' | head -1)
|
|
115
|
+
partner=$(grep '^\*\*Leader:\*\*' "$file" | sed 's/.*\*\*Partner:\*\* \([^ ]*\).*/\1/' | head -1)
|
|
116
|
+
|
|
117
|
+
# Fallback if parsing fails
|
|
118
|
+
leader="${leader:-leader}"
|
|
119
|
+
partner="${partner:-partner}"
|
|
120
|
+
|
|
121
|
+
local exchange_block
|
|
122
|
+
exchange_block="## Exchange ${num}
|
|
123
|
+
**[${ts}] ${leader} → ${partner}**
|
|
124
|
+
|
|
125
|
+
> ${question}
|
|
126
|
+
|
|
127
|
+
**[${ts}] ${partner}:**
|
|
128
|
+
|
|
129
|
+
${recommendation}
|
|
130
|
+
|
|
131
|
+
**Confidence:** ${confidence}
|
|
132
|
+
|
|
133
|
+
**Outcome:** _pending_
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
"
|
|
137
|
+
|
|
138
|
+
# Insert before summary marker
|
|
139
|
+
if grep -q "^${SUMMARY_MARKER}" "$file"; then
|
|
140
|
+
# Use awk to insert before summary
|
|
141
|
+
local tmpfile
|
|
142
|
+
tmpfile="$(mktemp)"
|
|
143
|
+
awk -v block="$exchange_block" -v marker="$SUMMARY_MARKER" '
|
|
144
|
+
$0 == marker { printf "%s\n\n", block }
|
|
145
|
+
{ print }
|
|
146
|
+
' "$file" > "$tmpfile"
|
|
147
|
+
mv "$tmpfile" "$file"
|
|
148
|
+
else
|
|
149
|
+
echo "" >> "$file"
|
|
150
|
+
echo "$exchange_block" >> "$file"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
echo "Appended exchange #${num} to $file"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
cmd_outcome() {
|
|
157
|
+
local story_id="${1:?Missing story-id}"
|
|
158
|
+
local exchange_num="${2:?Missing exchange-num}"
|
|
159
|
+
local outcome="${3:?Missing outcome (applied|deferred|rejected)}"
|
|
160
|
+
local note="${4:-}"
|
|
161
|
+
local file
|
|
162
|
+
file="$(dialogue_path "$story_id")"
|
|
163
|
+
|
|
164
|
+
if [[ ! -f "$file" ]]; then
|
|
165
|
+
echo "Error: Dialogue file not found: $file" >&2
|
|
166
|
+
exit 1
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Validate outcome
|
|
170
|
+
case "$outcome" in
|
|
171
|
+
applied|deferred|rejected) ;;
|
|
172
|
+
*) echo "Error: outcome must be applied, deferred, or rejected" >&2; exit 1 ;;
|
|
173
|
+
esac
|
|
174
|
+
|
|
175
|
+
local outcome_text
|
|
176
|
+
if [[ -n "$note" ]]; then
|
|
177
|
+
outcome_text="**Outcome:** ${outcome} - ${note}"
|
|
178
|
+
else
|
|
179
|
+
outcome_text="**Outcome:** ${outcome}"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# Find the exchange and update its outcome line
|
|
183
|
+
local in_target=false
|
|
184
|
+
local found=false
|
|
185
|
+
local tmpfile
|
|
186
|
+
tmpfile="$(mktemp)"
|
|
187
|
+
|
|
188
|
+
while IFS= read -r line; do
|
|
189
|
+
if [[ "$line" =~ ^##\ Exchange\ ([0-9]+) ]]; then
|
|
190
|
+
if [[ "${BASH_REMATCH[1]}" == "$exchange_num" ]]; then
|
|
191
|
+
in_target=true
|
|
192
|
+
else
|
|
193
|
+
in_target=false
|
|
194
|
+
fi
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
if $in_target && [[ "$line" =~ ^\*\*Outcome:\*\* ]]; then
|
|
198
|
+
echo "$outcome_text" >> "$tmpfile"
|
|
199
|
+
found=true
|
|
200
|
+
in_target=false
|
|
201
|
+
else
|
|
202
|
+
echo "$line" >> "$tmpfile"
|
|
203
|
+
fi
|
|
204
|
+
done < "$file"
|
|
205
|
+
|
|
206
|
+
if $found; then
|
|
207
|
+
mv "$tmpfile" "$file"
|
|
208
|
+
echo "Updated exchange #${exchange_num} outcome to: ${outcome}"
|
|
209
|
+
else
|
|
210
|
+
rm -f "$tmpfile"
|
|
211
|
+
echo "Error: Exchange #${exchange_num} not found" >&2
|
|
212
|
+
exit 1
|
|
213
|
+
fi
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
cmd_summarize() {
|
|
217
|
+
local story_id="${1:?Missing story-id}"
|
|
218
|
+
local file
|
|
219
|
+
file="$(dialogue_path "$story_id")"
|
|
220
|
+
|
|
221
|
+
if [[ ! -f "$file" ]]; then
|
|
222
|
+
echo "Error: Dialogue file not found: $file" >&2
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
local total
|
|
227
|
+
total="$(count_exchanges "$file")"
|
|
228
|
+
|
|
229
|
+
# Collect applied decisions
|
|
230
|
+
local decisions=""
|
|
231
|
+
local in_exchange=false
|
|
232
|
+
local current_outcome=""
|
|
233
|
+
local current_note=""
|
|
234
|
+
|
|
235
|
+
while IFS= read -r line; do
|
|
236
|
+
if [[ "$line" =~ ^\*\*Outcome:\*\*\ applied ]]; then
|
|
237
|
+
local note_part="${line#*applied}"
|
|
238
|
+
note_part="${note_part# - }"
|
|
239
|
+
if [[ -n "$note_part" ]]; then
|
|
240
|
+
decisions="${decisions} - ${note_part}\n"
|
|
241
|
+
fi
|
|
242
|
+
fi
|
|
243
|
+
done < "$file"
|
|
244
|
+
|
|
245
|
+
if [[ -z "$decisions" ]]; then
|
|
246
|
+
decisions="None"
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
# Calculate time span from first and last exchange timestamps
|
|
250
|
+
local first_ts last_ts duration="0m"
|
|
251
|
+
first_ts=$(grep -m 1 '^\*\*\[' "$file" | sed 's/.*\*\*\[\([0-9]*:[0-9]*\)\].*/\1/' || echo "")
|
|
252
|
+
last_ts=$(grep '^\*\*\[' "$file" | tail -1 | sed 's/.*\*\*\[\([0-9]*:[0-9]*\)\].*/\1/' || echo "")
|
|
253
|
+
|
|
254
|
+
if [[ -n "$first_ts" && -n "$last_ts" ]]; then
|
|
255
|
+
local first_mins last_mins
|
|
256
|
+
first_mins=$(( 10#${first_ts%%:*} * 60 + 10#${first_ts##*:} ))
|
|
257
|
+
last_mins=$(( 10#${last_ts%%:*} * 60 + 10#${last_ts##*:} ))
|
|
258
|
+
local diff=$(( last_mins - first_mins ))
|
|
259
|
+
if (( diff > 0 )); then
|
|
260
|
+
duration="${diff}m"
|
|
261
|
+
fi
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
# Build new summary
|
|
265
|
+
local new_summary="${SUMMARY_MARKER}
|
|
266
|
+
- **Total exchanges:** ${total}
|
|
267
|
+
- **Key decisions:**
|
|
268
|
+
$(echo -e "$decisions")- **Time in tandem:** ${duration}"
|
|
269
|
+
|
|
270
|
+
# Replace summary section (everything from marker to end)
|
|
271
|
+
if grep -q "^${SUMMARY_MARKER}" "$file"; then
|
|
272
|
+
local tmpfile
|
|
273
|
+
tmpfile="$(mktemp)"
|
|
274
|
+
awk -v marker="$SUMMARY_MARKER" '
|
|
275
|
+
$0 == marker { found=1; next }
|
|
276
|
+
!found { print }
|
|
277
|
+
' "$file" > "$tmpfile"
|
|
278
|
+
echo "$new_summary" >> "$tmpfile"
|
|
279
|
+
mv "$tmpfile" "$file"
|
|
280
|
+
else
|
|
281
|
+
echo "" >> "$file"
|
|
282
|
+
echo "$new_summary" >> "$file"
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
echo "Summary refreshed for $file (${total} exchanges)"
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
cmd_archive() {
|
|
289
|
+
local story_id="${1:?Missing story-id}"
|
|
290
|
+
local jira_key="${2:-}"
|
|
291
|
+
local file
|
|
292
|
+
file="$(dialogue_path "$story_id")"
|
|
293
|
+
|
|
294
|
+
if [[ ! -f "$file" ]]; then
|
|
295
|
+
echo "No dialogue file to archive: $file"
|
|
296
|
+
exit 0
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
mkdir -p "$ARCHIVE_DIR"
|
|
300
|
+
|
|
301
|
+
local prefix="${jira_key:-$story_id}"
|
|
302
|
+
local dest="$ARCHIVE_DIR/${prefix}-dialogue.md"
|
|
303
|
+
|
|
304
|
+
cp "$file" "$dest"
|
|
305
|
+
echo "Archived dialogue to: $dest"
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
# =============================================================================
|
|
309
|
+
# Dispatch
|
|
310
|
+
# =============================================================================
|
|
311
|
+
|
|
312
|
+
CMD="${1:-}"
|
|
313
|
+
shift || true
|
|
314
|
+
|
|
315
|
+
case "$CMD" in
|
|
316
|
+
init) cmd_init "$@" ;;
|
|
317
|
+
append) cmd_append "$@" ;;
|
|
318
|
+
outcome) cmd_outcome "$@" ;;
|
|
319
|
+
summarize) cmd_summarize "$@" ;;
|
|
320
|
+
archive) cmd_archive "$@" ;;
|
|
321
|
+
*) usage ;;
|
|
322
|
+
esac
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
# Git Scripts
|
|
2
2
|
|
|
3
|
-
Scripts for Git operations, branching, and
|
|
3
|
+
Scripts for Git operations, branching, and worktree management.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## CLI Commands (preferred)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|--------|---------|
|
|
9
|
-
| `create-feature-branches.sh` | Create feature branches in repos |
|
|
10
|
-
| `git-status-all.sh` | Show git status across all repos |
|
|
11
|
-
| `worktree-manager.sh` | Manage git worktrees for parallel work |
|
|
12
|
-
| `install-git-hooks.sh` | Install git hooks in project |
|
|
13
|
-
| `release.sh` | Release workflow (merge develop to main) |
|
|
7
|
+
All git operations are available via the `pf git` CLI:
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
| Command | Purpose |
|
|
10
|
+
|---------|---------|
|
|
11
|
+
| `pf git status [--brief]` | Show git status across all repos |
|
|
12
|
+
| `pf git branches <name> [--repos all\|api\|ui]` | Create feature branches in repos |
|
|
13
|
+
| `pf git worktree create <name> <branch>` | Create worktrees for parallel work |
|
|
14
|
+
| `pf git worktree remove <name>` | Remove worktree and clean up |
|
|
15
|
+
| `pf git worktree list` | List all active worktrees |
|
|
16
|
+
| `pf git worktree status` | Show detailed worktree status |
|
|
17
|
+
| `pf git install-hooks` | Install git hooks with .d/ dispatcher |
|
|
18
|
+
| `pf git cleanup` | Organize changes into commits/branches |
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
## Legacy Scripts (deprecated shims)
|
|
21
|
+
|
|
22
|
+
These scripts now forward to `pf git` commands:
|
|
23
|
+
|
|
24
|
+
| Script | Forwards to |
|
|
25
|
+
|--------|-------------|
|
|
26
|
+
| `git-status-all.sh` | `pf git status` |
|
|
27
|
+
| `create-feature-branches.sh` | `pf git branches` |
|
|
28
|
+
| `worktree-manager.sh` | `pf git worktree` |
|
|
29
|
+
| `install-git-hooks.sh` | `pf git install-hooks` |
|
|
30
|
+
| `release.sh` | Release workflow (use `/pf-workflow start release`) |
|
|
21
31
|
|
|
22
32
|
## Ownership
|
|
23
33
|
|
|
@@ -1,267 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DEPRECATED: Use `pf git branches` instead.
|
|
3
|
+
# This shim forwards to the Python CLI.
|
|
5
4
|
set -e
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if [ -f .env ]; then
|
|
9
|
-
set -a; source .env; set +a
|
|
10
|
-
elif [ -f ../.env ]; then
|
|
11
|
-
set -a; source ../.env; set +a
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
show_help() {
|
|
15
|
-
cat << EOF
|
|
16
|
-
Create Feature Branches - Idempotent branch creation/checkout
|
|
17
|
-
|
|
18
|
-
Usage: ./create-feature-branches.sh <branch-name> [repos]
|
|
19
|
-
|
|
20
|
-
Arguments:
|
|
21
|
-
branch-name Branch name (e.g., feat/11-2-file-preview)
|
|
22
|
-
repos Which repos to branch (default: all)
|
|
23
|
-
Options: api, ui, all
|
|
24
|
-
|
|
25
|
-
Repo Options:
|
|
26
|
-
api - Pennyfarthing-api only
|
|
27
|
-
ui - Pennyfarthing-ui only
|
|
28
|
-
all - both repos (default)
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
# All repos (default)
|
|
32
|
-
./create-feature-branches.sh feat/cross-repo-feature
|
|
33
|
-
|
|
34
|
-
# Pennyfarthing UI only
|
|
35
|
-
./create-feature-branches.sh feat/11-2-ui-component ui
|
|
36
|
-
|
|
37
|
-
# Pennyfarthing API only
|
|
38
|
-
./create-feature-branches.sh fix/validation-bug api
|
|
39
|
-
|
|
40
|
-
Behavior:
|
|
41
|
-
- Idempotent: Checks out existing branches or creates new ones
|
|
42
|
-
- Worktree-aware: Detects main checkout vs worktree
|
|
43
|
-
- Always branches from develop
|
|
44
|
-
- Fetches latest develop before branching
|
|
45
|
-
|
|
46
|
-
EOF
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
|
50
|
-
show_help
|
|
51
|
-
exit 0
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
BRANCH_NAME="$1"
|
|
55
|
-
REPOS="${2:-all}"
|
|
56
|
-
|
|
57
|
-
# Validate repos parameter
|
|
58
|
-
if [[ ! "$REPOS" =~ ^(api|ui|all)$ ]]; then
|
|
59
|
-
echo "❌ Error: repos must be one of: api, ui, all"
|
|
60
|
-
echo " Got: $REPOS"
|
|
61
|
-
echo ""
|
|
62
|
-
echo "Options:"
|
|
63
|
-
echo " api - Pennyfarthing-api only"
|
|
64
|
-
echo " ui - Pennyfarthing-ui only"
|
|
65
|
-
echo " all - both repos (default)"
|
|
66
|
-
exit 1
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# Detect if we're in a worktree
|
|
70
|
-
CURRENT_DIR=$(pwd)
|
|
71
|
-
if [[ "$CURRENT_DIR" == *"/worktrees/"* ]]; then
|
|
72
|
-
# Extract worktree name from path
|
|
73
|
-
WORKTREE_NAME=$(echo "$CURRENT_DIR" | sed -E 's|.*/worktrees/([^/]+).*|\1|')
|
|
74
|
-
REPO_BASE="$PROJECT_ROOT/worktrees/$WORKTREE_NAME"
|
|
75
|
-
echo "📂 Detected worktree: $WORKTREE_NAME"
|
|
76
|
-
else
|
|
77
|
-
REPO_BASE="$PROJECT_ROOT"
|
|
78
|
-
echo "📂 Using main checkout"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# Array to track processed repos for verification
|
|
82
|
-
declare -a PROCESSED_REPOS
|
|
83
|
-
|
|
84
|
-
# Function to create or checkout branch in a repo
|
|
85
|
-
create_or_checkout_branch() {
|
|
86
|
-
local repo_path=$1
|
|
87
|
-
local repo_name=$2
|
|
88
|
-
|
|
89
|
-
if [ ! -d "$repo_path" ]; then
|
|
90
|
-
echo "⚠️ Skipping $repo_name: directory not found at $repo_path"
|
|
91
|
-
return
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
cd "$repo_path"
|
|
95
|
-
|
|
96
|
-
echo ""
|
|
97
|
-
echo "🔧 Processing $repo_name..."
|
|
98
|
-
|
|
99
|
-
# Fetch latest from remote
|
|
100
|
-
echo " Fetching from origin..."
|
|
101
|
-
git fetch origin --quiet
|
|
102
|
-
|
|
103
|
-
# Check if branch exists locally
|
|
104
|
-
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
|
|
105
|
-
echo " ✅ Branch exists locally, checking out: $BRANCH_NAME"
|
|
106
|
-
git checkout "$BRANCH_NAME"
|
|
107
|
-
# Check if branch exists on remote
|
|
108
|
-
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
|
|
109
|
-
echo " ✅ Branch exists on remote, checking out and tracking: $BRANCH_NAME"
|
|
110
|
-
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
|
|
111
|
-
else
|
|
112
|
-
# Branch doesn't exist, create from develop
|
|
113
|
-
echo " 🌿 Creating new branch from develop: $BRANCH_NAME"
|
|
114
|
-
|
|
115
|
-
# Make sure we have latest develop
|
|
116
|
-
git fetch origin develop:develop --quiet 2>/dev/null || true
|
|
117
|
-
|
|
118
|
-
# Checkout develop first
|
|
119
|
-
if git show-ref --verify --quiet "refs/heads/develop"; then
|
|
120
|
-
git checkout develop --quiet
|
|
121
|
-
git pull origin develop --quiet
|
|
122
|
-
else
|
|
123
|
-
echo " ⚠️ Local develop doesn't exist, fetching from remote"
|
|
124
|
-
git fetch origin develop:develop --quiet
|
|
125
|
-
git checkout develop --quiet
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
# Create new branch
|
|
129
|
-
git checkout -b "$BRANCH_NAME"
|
|
130
|
-
echo " ✅ Created: $BRANCH_NAME"
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
# Show current status
|
|
134
|
-
CURRENT_BRANCH=$(git branch --show-current)
|
|
135
|
-
echo " 📍 Now on: $CURRENT_BRANCH"
|
|
136
|
-
|
|
137
|
-
# Track this repo for verification
|
|
138
|
-
PROCESSED_REPOS+=("$repo_path:$repo_name")
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
echo "🌿 Creating/checking out feature branches..."
|
|
142
|
-
echo " Branch: $BRANCH_NAME"
|
|
143
|
-
echo " Repos: $REPOS"
|
|
144
|
-
|
|
145
|
-
# Process repos based on selection
|
|
146
|
-
# When processing multiple repos, run in parallel for faster network I/O
|
|
147
|
-
case "$REPOS" in
|
|
148
|
-
api)
|
|
149
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-api" "Pennyfarthing-api"
|
|
150
|
-
;;
|
|
151
|
-
ui)
|
|
152
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-ui" "Pennyfarthing-ui"
|
|
153
|
-
;;
|
|
154
|
-
all)
|
|
155
|
-
# Parallel execution for both repos
|
|
156
|
-
tmpdir=$(mktemp -d)
|
|
157
|
-
trap "rm -rf '$tmpdir'" EXIT
|
|
158
|
-
HAD_ERRORS=false
|
|
159
|
-
|
|
160
|
-
# Run both in parallel, capturing output
|
|
161
|
-
# Write to separate files to avoid race condition on shared file
|
|
162
|
-
(
|
|
163
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-api" "Pennyfarthing-api"
|
|
164
|
-
echo "$REPO_BASE/Pennyfarthing-api:Pennyfarthing-api" > "$tmpdir/api.processed"
|
|
165
|
-
) > "$tmpdir/api.out" 2>&1 &
|
|
166
|
-
pid_api=$!
|
|
167
|
-
|
|
168
|
-
(
|
|
169
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-ui" "Pennyfarthing-ui"
|
|
170
|
-
echo "$REPO_BASE/Pennyfarthing-ui:Pennyfarthing-ui" > "$tmpdir/ui.processed"
|
|
171
|
-
) > "$tmpdir/ui.out" 2>&1 &
|
|
172
|
-
pid_ui=$!
|
|
173
|
-
|
|
174
|
-
# Wait for both and capture exit codes
|
|
175
|
-
wait $pid_api; rc_api=$?
|
|
176
|
-
wait $pid_ui; rc_ui=$?
|
|
177
|
-
|
|
178
|
-
# Show output in order
|
|
179
|
-
[ -f "$tmpdir/api.out" ] && cat "$tmpdir/api.out"
|
|
180
|
-
[ -f "$tmpdir/ui.out" ] && cat "$tmpdir/ui.out"
|
|
181
|
-
|
|
182
|
-
# Rebuild PROCESSED_REPOS from separate files (avoids race condition)
|
|
183
|
-
[ -f "$tmpdir/api.processed" ] && PROCESSED_REPOS+=("$(cat "$tmpdir/api.processed")")
|
|
184
|
-
[ -f "$tmpdir/ui.processed" ] && PROCESSED_REPOS+=("$(cat "$tmpdir/ui.processed")")
|
|
185
|
-
|
|
186
|
-
# Check for failures
|
|
187
|
-
if [ $rc_api -ne 0 ] || [ $rc_ui -ne 0 ]; then
|
|
188
|
-
echo "⚠️ Some repos had errors"
|
|
189
|
-
HAD_ERRORS=true
|
|
190
|
-
fi
|
|
191
|
-
;;
|
|
192
|
-
esac
|
|
193
|
-
|
|
194
|
-
echo ""
|
|
195
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
196
|
-
echo "🔍 Verification Summary"
|
|
197
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
198
|
-
|
|
199
|
-
# Verify each processed repo
|
|
200
|
-
for repo_info in "${PROCESSED_REPOS[@]}"; do
|
|
201
|
-
repo_path="${repo_info%%:*}"
|
|
202
|
-
repo_name="${repo_info##*:}"
|
|
203
|
-
|
|
204
|
-
if [ -d "$repo_path" ]; then
|
|
205
|
-
cd "$repo_path"
|
|
206
|
-
|
|
207
|
-
echo ""
|
|
208
|
-
echo "📦 $repo_name"
|
|
209
|
-
echo " Path: $repo_path"
|
|
210
|
-
|
|
211
|
-
# Current branch
|
|
212
|
-
CURRENT_BRANCH=$(git branch --show-current)
|
|
213
|
-
echo " Branch: $CURRENT_BRANCH"
|
|
214
|
-
|
|
215
|
-
# Check if branch matches expected
|
|
216
|
-
if [ "$CURRENT_BRANCH" = "$BRANCH_NAME" ]; then
|
|
217
|
-
echo " ✅ Branch matches: $BRANCH_NAME"
|
|
218
|
-
else
|
|
219
|
-
echo " ⚠️ Branch mismatch! Expected: $BRANCH_NAME, Got: $CURRENT_BRANCH"
|
|
220
|
-
fi
|
|
221
|
-
|
|
222
|
-
# Latest commit
|
|
223
|
-
COMMIT_INFO=$(git log -1 --format="%h - %s" 2>/dev/null)
|
|
224
|
-
echo " Commit: $COMMIT_INFO"
|
|
225
|
-
|
|
226
|
-
# Check remote tracking
|
|
227
|
-
UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "none")
|
|
228
|
-
if [ "$UPSTREAM" != "none" ]; then
|
|
229
|
-
echo " Remote: $UPSTREAM"
|
|
230
|
-
|
|
231
|
-
# Check if up to date with remote
|
|
232
|
-
git fetch origin "$CURRENT_BRANCH" --quiet 2>/dev/null || true
|
|
233
|
-
LOCAL=$(git rev-parse @ 2>/dev/null)
|
|
234
|
-
REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "none")
|
|
235
|
-
|
|
236
|
-
if [ "$LOCAL" = "$REMOTE" ]; then
|
|
237
|
-
echo " Status: ✅ Up to date with remote"
|
|
238
|
-
elif [ "$REMOTE" = "none" ]; then
|
|
239
|
-
echo " Status: ⚠️ No remote branch yet (push needed)"
|
|
240
|
-
else
|
|
241
|
-
BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo "0")
|
|
242
|
-
AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo "0")
|
|
243
|
-
if [ "$AHEAD" -gt 0 ] && [ "$BEHIND" -gt 0 ]; then
|
|
244
|
-
echo " Status: ⚠️ Diverged ($AHEAD ahead, $BEHIND behind)"
|
|
245
|
-
elif [ "$AHEAD" -gt 0 ]; then
|
|
246
|
-
echo " Status: ⬆️ $AHEAD commit(s) ahead of remote"
|
|
247
|
-
elif [ "$BEHIND" -gt 0 ]; then
|
|
248
|
-
echo " Status: ⬇️ $BEHIND commit(s) behind remote"
|
|
249
|
-
fi
|
|
250
|
-
fi
|
|
251
|
-
else
|
|
252
|
-
echo " Remote: none (local branch only)"
|
|
253
|
-
echo " Status: ⚠️ Not tracking remote (push with -u needed)"
|
|
254
|
-
fi
|
|
255
|
-
fi
|
|
256
|
-
done
|
|
257
|
-
|
|
258
|
-
echo ""
|
|
259
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
260
|
-
if [ "$HAD_ERRORS" = true ]; then
|
|
261
|
-
echo "⚠️ Done with errors. Check output above."
|
|
262
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
263
|
-
exit 1
|
|
264
|
-
else
|
|
265
|
-
echo "✅ Done! All branches verified and ready."
|
|
266
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
267
|
-
fi
|
|
5
|
+
echo "DEPRECATED: create-feature-branches.sh — use 'pf git branches' instead" >&2
|
|
6
|
+
exec pf git branches "$@"
|