@pennyfarthing/core 11.3.8 → 11.5.0-alpha.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 +1 -1
- package/package.json +4 -1
- package/packages/core/dist/cli/commands/cyclist.js +1 -1
- package/packages/core/dist/cli/commands/cyclist.js.map +1 -1
- package/packages/core/dist/cli/commands/cyclist.test.js +3 -3
- package/packages/core/dist/cli/commands/cyclist.test.js.map +1 -1
- package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.d.ts +22 -0
- package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.js +161 -0
- package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.js.map +1 -0
- package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/doctor.js +101 -33
- package/packages/core/dist/cli/commands/doctor.js.map +1 -1
- package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/init.js +33 -13
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts +17 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js +470 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js.map +1 -0
- package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/update.js +68 -17
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/packages/core/dist/cli/cyclist-migration.test.d.ts +16 -0
- package/packages/core/dist/cli/cyclist-migration.test.d.ts.map +1 -0
- package/packages/core/dist/cli/cyclist-migration.test.js +229 -0
- package/packages/core/dist/cli/cyclist-migration.test.js.map +1 -0
- package/packages/core/dist/cli/index.js +2 -21
- package/packages/core/dist/cli/index.js.map +1 -1
- package/packages/core/dist/cli/utils/node-modules.d.ts +7 -0
- package/packages/core/dist/cli/utils/node-modules.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/node-modules.js +39 -0
- package/packages/core/dist/cli/utils/node-modules.js.map +1 -1
- package/packages/core/dist/cli/utils/settings.d.ts +1 -1
- package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/settings.js +24 -21
- package/packages/core/dist/cli/utils/settings.js.map +1 -1
- package/packages/core/dist/cli/utils/stale-artifacts.d.ts +59 -0
- package/packages/core/dist/cli/utils/stale-artifacts.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/stale-artifacts.js +163 -0
- package/packages/core/dist/cli/utils/stale-artifacts.js.map +1 -0
- package/packages/core/dist/public/css/react.css +1 -1
- package/packages/core/dist/public/js/react/react.js +39 -39
- package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
- package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
- package/packages/core/dist/scripts/benchmark-integration.js +691 -0
- package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
- package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
- package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
- package/packages/core/dist/scripts/theme-detail.test.d.ts.map +1 -0
- package/packages/core/dist/scripts/theme-detail.test.js.map +1 -0
- package/packages/core/dist/server/api/context.d.ts.map +1 -1
- package/packages/core/dist/server/api/context.js +23 -5
- package/packages/core/dist/server/api/context.js.map +1 -1
- package/packages/core/dist/server/api/index.d.ts +0 -1
- package/packages/core/dist/server/api/index.d.ts.map +1 -1
- package/packages/core/dist/server/api/index.js +0 -2
- package/packages/core/dist/server/api/index.js.map +1 -1
- package/packages/core/dist/server/api/settings.d.ts.map +1 -1
- package/packages/core/dist/server/api/settings.js +6 -0
- package/packages/core/dist/server/api/settings.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.d.ts +0 -4
- package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
- package/packages/core/dist/server/otlp-receiver.js +0 -18
- package/packages/core/dist/server/otlp-receiver.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.test.js +0 -27
- package/packages/core/dist/server/otlp-receiver.test.js.map +1 -1
- package/packages/core/dist/server/server.d.ts +1 -1
- package/packages/core/dist/server/server.d.ts.map +1 -1
- package/packages/core/dist/server/server.js +2 -4
- package/packages/core/dist/server/server.js.map +1 -1
- package/packages/core/dist/workflow/cross-entity-validation.d.ts.map +1 -1
- package/packages/core/dist/workflow/cross-entity-validation.js.map +1 -1
- package/packages/core/src/public/App.tsx +354 -0
- package/packages/core/src/public/components/AgentLoadDialog.tsx +202 -0
- package/packages/core/src/public/components/AgentPopup.tsx +308 -0
- package/packages/core/src/public/components/ApprovalModal/ApprovalModal.css +35 -0
- package/packages/core/src/public/components/ApprovalModal/index.tsx +632 -0
- package/packages/core/src/public/components/BikeRackIndex.tsx +53 -0
- package/packages/core/src/public/components/BikeRackWorkspace.tsx +215 -0
- package/packages/core/src/public/components/CommandPalette.tsx +554 -0
- package/packages/core/src/public/components/ConfirmDialog.tsx +168 -0
- package/packages/core/src/public/components/ContextIndicator/ContextIndicator.css +85 -0
- package/packages/core/src/public/components/ContextIndicator/index.tsx +330 -0
- package/packages/core/src/public/components/ContextSparkline.tsx +56 -0
- package/packages/core/src/public/components/ControlBar.tsx +636 -0
- package/packages/core/src/public/components/DeadCodeDialog.tsx +169 -0
- package/packages/core/src/public/components/DiffViewer.tsx +585 -0
- package/packages/core/src/public/components/DockviewWorkspace.tsx +745 -0
- package/packages/core/src/public/components/Editor.tsx +630 -0
- package/packages/core/src/public/components/ErrorBoundary.tsx +67 -0
- package/packages/core/src/public/components/FileTree.tsx +379 -0
- package/packages/core/src/public/components/FullFileTree.tsx +237 -0
- package/packages/core/src/public/components/HealthGauge.tsx +181 -0
- package/packages/core/src/public/components/Message.tsx +225 -0
- package/packages/core/src/public/components/MessageList.tsx +98 -0
- package/packages/core/src/public/components/MessageView.tsx +400 -0
- package/packages/core/src/public/components/ModeSwitch/ModeSwitch.css +165 -0
- package/packages/core/src/public/components/ModeSwitch/index.tsx +372 -0
- package/packages/core/src/public/components/PersonaHeader.tsx +242 -0
- package/packages/core/src/public/components/ProjectInfoBar.tsx +45 -0
- package/packages/core/src/public/components/QuickActions.tsx +267 -0
- package/packages/core/src/public/components/SpanTimeline.tsx +352 -0
- package/packages/core/src/public/components/StandalonePanel.tsx +80 -0
- package/packages/core/src/public/components/StatsStrip.tsx +162 -0
- package/packages/core/src/public/components/StreamingContent.tsx +77 -0
- package/packages/core/src/public/components/SubagentSpan.tsx +180 -0
- package/packages/core/src/public/components/TandemPortrait.tsx +72 -0
- package/packages/core/src/public/components/ToolCallBlock.tsx +252 -0
- package/packages/core/src/public/components/ToolStack.tsx +209 -0
- package/packages/core/src/public/components/ToolStatus.tsx +57 -0
- package/packages/core/src/public/components/dialogs/CodeMarkersDialog.tsx +169 -0
- package/packages/core/src/public/components/dialogs/ComplexityDialog.tsx +163 -0
- package/packages/core/src/public/components/dialogs/DependenciesDialog.tsx +120 -0
- package/packages/core/src/public/components/dialogs/HotspotsDialog.tsx +451 -0
- package/packages/core/src/public/components/dialogs/ToolDialog.tsx +43 -0
- package/packages/core/src/public/components/panel-registry.ts +13 -0
- package/packages/core/src/public/components/panels/ACPanel.tsx +93 -0
- package/packages/core/src/public/components/panels/AcceptanceCriteriaPanel.tsx +104 -0
- package/packages/core/src/public/components/panels/AuditLogPanel.tsx +489 -0
- package/packages/core/src/public/components/panels/BikeLanePanel.tsx +214 -0
- package/packages/core/src/public/components/panels/DebugPanel.tsx +344 -0
- package/packages/core/src/public/components/panels/DiffView.tsx +109 -0
- package/packages/core/src/public/components/panels/DiffsPanel.tsx +56 -0
- package/packages/core/src/public/components/panels/GitPanel.tsx +260 -0
- package/packages/core/src/public/components/panels/HotspotsPanel.tsx +365 -0
- package/packages/core/src/public/components/panels/MessageFeed.tsx +39 -0
- package/packages/core/src/public/components/panels/MessagePanel.tsx +497 -0
- package/packages/core/src/public/components/panels/ProgressPanel.tsx +189 -0
- package/packages/core/src/public/components/panels/SettingsPanel.tsx +161 -0
- package/packages/core/src/public/components/panels/SprintPanel.tsx +731 -0
- package/packages/core/src/public/components/panels/TandemPanel.tsx +104 -0
- package/packages/core/src/public/components/panels/TaskTracker.tsx +48 -0
- package/packages/core/src/public/components/panels/TeamPanel.tsx +64 -0
- package/packages/core/src/public/components/panels/TeamRoster.tsx +67 -0
- package/packages/core/src/public/components/panels/TodoPanel.tsx +142 -0
- package/packages/core/src/public/components/panels/WorkflowPanel.tsx +224 -0
- package/packages/core/src/public/components/panels/index.ts +23 -0
- package/packages/core/src/public/components/ui/alert-dialog.tsx +139 -0
- package/packages/core/src/public/components/ui/badge.tsx +36 -0
- package/packages/core/src/public/components/ui/button.tsx +57 -0
- package/packages/core/src/public/components/ui/checkbox.tsx +28 -0
- package/packages/core/src/public/components/ui/collapsible.tsx +9 -0
- package/packages/core/src/public/components/ui/command.tsx +151 -0
- package/packages/core/src/public/components/ui/dialog.tsx +120 -0
- package/packages/core/src/public/components/ui/popover.tsx +31 -0
- package/packages/core/src/public/components/ui/progress.tsx +28 -0
- package/packages/core/src/public/components/ui/scroll-area.tsx +46 -0
- package/packages/core/src/public/components/ui/select.tsx +157 -0
- package/packages/core/src/public/components/ui/separator.tsx +29 -0
- package/packages/core/src/public/components/ui/skeleton.tsx +15 -0
- package/packages/core/src/public/components/ui/toggle-group.tsx +59 -0
- package/packages/core/src/public/components/ui/toggle.tsx +43 -0
- package/packages/core/src/public/components/ui/tooltip.tsx +30 -0
- package/packages/core/src/public/contexts/ClaudeContext.tsx +311 -0
- package/packages/core/src/public/contexts/MessageQueueContext.tsx +143 -0
- package/packages/core/src/public/css/theme-browser.css +550 -0
- package/packages/core/src/public/css/theme-system.css +630 -0
- package/packages/core/src/public/hooks/index.ts +46 -0
- package/packages/core/src/public/hooks/useAgentLoad.ts +105 -0
- package/packages/core/src/public/hooks/useClaude.ts +234 -0
- package/packages/core/src/public/hooks/useCodeMarkers.ts +101 -0
- package/packages/core/src/public/hooks/useColorScheme.ts +42 -0
- package/packages/core/src/public/hooks/useCommandHistory.ts +99 -0
- package/packages/core/src/public/hooks/useComplexity.ts +80 -0
- package/packages/core/src/public/hooks/useDeadCode.ts +99 -0
- package/packages/core/src/public/hooks/useDependencies.ts +82 -0
- package/packages/core/src/public/hooks/useDiffs.ts +143 -0
- package/packages/core/src/public/hooks/useFileBrowser.ts +73 -0
- package/packages/core/src/public/hooks/useFocusPanel.ts +137 -0
- package/packages/core/src/public/hooks/useGitStatus.ts +233 -0
- package/packages/core/src/public/hooks/useHealthScore.ts +71 -0
- package/packages/core/src/public/hooks/useHotspots.ts +123 -0
- package/packages/core/src/public/hooks/useLayoutPersistence.ts +141 -0
- package/packages/core/src/public/hooks/useMarkdownParser.ts +36 -0
- package/packages/core/src/public/hooks/useMarkerActions.ts +234 -0
- package/packages/core/src/public/hooks/useMessageQueue.ts +380 -0
- package/packages/core/src/public/hooks/useMessageStream.ts +131 -0
- package/packages/core/src/public/hooks/usePersona.ts +112 -0
- package/packages/core/src/public/hooks/usePlanModeExit.ts +105 -0
- package/packages/core/src/public/hooks/useResponsiveLayout.ts +173 -0
- package/packages/core/src/public/hooks/useSprint.ts +166 -0
- package/packages/core/src/public/hooks/useStatsStrip.ts +204 -0
- package/packages/core/src/public/hooks/useStory.ts +135 -0
- package/packages/core/src/public/hooks/useSubagentHelper.ts +64 -0
- package/packages/core/src/public/hooks/useSyntaxHighlighter.ts +52 -0
- package/packages/core/src/public/hooks/useTabCompletion.ts +124 -0
- package/packages/core/src/public/hooks/useTandemObservations.ts +165 -0
- package/packages/core/src/public/hooks/useTeamMembers.ts +273 -0
- package/packages/core/src/public/hooks/useTodos.ts +93 -0
- package/packages/core/src/public/hooks/useUserAvatar.ts +54 -0
- package/packages/core/src/public/images/cyclist-dark.png +0 -0
- package/packages/core/src/public/images/cyclist-light.png +0 -0
- package/packages/core/src/public/images/cyclist-tandem-source.png +0 -0
- package/packages/core/src/public/index.html +14 -0
- package/packages/core/src/public/index.tsx +10 -0
- package/packages/core/src/public/lib/utils.ts +6 -0
- package/packages/core/src/public/styles/dockview-theme.css +376 -0
- package/packages/core/src/public/styles/tailwind.css +4353 -0
- package/packages/core/src/public/types/message.ts +51 -0
- package/packages/core/src/public/utils/avatar-service.ts +73 -0
- package/packages/core/src/public/utils/color-presets.ts +940 -0
- package/packages/core/src/public/utils/font-presets.ts +362 -0
- package/packages/core/src/public/utils/formatDuration.ts +14 -0
- package/packages/core/src/public/utils/markdown.ts +249 -0
- package/packages/core/src/public/utils/messageFilters.ts +128 -0
- package/packages/core/src/public/utils/slash-commands.ts +341 -0
- package/packages/core/src/public/utils/subagent-display.ts +146 -0
- package/packages/core/src/public/utils/syntax.ts +219 -0
- package/packages/core/src/public/utils/toolIntentSummarizer.ts +199 -0
- package/packages/core/src/public/utils/toolStackGrouper.ts +106 -0
- package/packages/core/src/public/utils/toolTypeColors.ts +45 -0
- package/pennyfarthing-dist/guides/bikerack.md +94 -0
- package/pennyfarthing-dist/personas/themes/firefly.yaml +12 -12
- package/pennyfarthing-dist/pf/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/context.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/context.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/hooks.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/jira.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/jira_sync.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/patch_mode.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/session_start_hook.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/workflow.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/focus.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/focus.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/split.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/cli.py +0 -2
- package/pennyfarthing-dist/pf/bc/focus.py +0 -2
- package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/events.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/launcher.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_widget.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/base_panel.py +0 -1
- package/pennyfarthing-dist/pf/bikerack/context_meter_footer.py +115 -35
- package/pennyfarthing-dist/pf/bikerack/events.py +1 -7
- package/pennyfarthing-dist/pf/bikerack/git_panel.py +273 -10
- package/pennyfarthing-dist/pf/bikerack/portrait_resolver.py +35 -2
- package/pennyfarthing-dist/pf/bikerack/progress_panel.py +54 -0
- package/pennyfarthing-dist/pf/bikerack/sprint_panel.py +116 -1
- package/pennyfarthing-dist/pf/bikerack/story_detail_screen.py +10 -105
- package/pennyfarthing-dist/pf/bikerack/story_detail_widget.py +167 -0
- package/pennyfarthing-dist/pf/bikerack/tui.py +141 -66
- package/pennyfarthing-dist/pf/bmad/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bmad/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bmad/cli.py +0 -1
- package/pennyfarthing-dist/pf/bmad/importer.py +0 -1
- package/pennyfarthing-dist/pf/bmad/parser.py +15 -10
- package/pennyfarthing-dist/pf/bmad/sync.py +1 -3
- package/pennyfarthing-dist/pf/bmad/test_parser.py +0 -4
- package/pennyfarthing-dist/pf/bmad/test_sync.py +0 -3
- package/pennyfarthing-dist/pf/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/brownfield/cli.py +1 -1
- package/pennyfarthing-dist/pf/cli.py +145 -111
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__init__.py +2 -0
- package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/output.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/pr_config.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/themes.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/config.py +43 -0
- package/pennyfarthing-dist/pf/common/pr_config.py +27 -2
- package/pennyfarthing-dist/pf/common/themes.py +7 -5
- package/pennyfarthing-dist/pf/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/dialogue_manager.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/context.py +1 -1
- package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/dependencies/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/epic/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/epic/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/git/hooks_installer.py +7 -6
- package/pennyfarthing-dist/pf/git_group/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/git_group/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/git_group/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/marker.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/phase_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/gate_file.py +5 -1
- package/pennyfarthing-dist/pf/healthscore/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/analyze.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/models.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/healthscore/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/context_breaker.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/context_warning.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/cyclist_pretooluse.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/pre_edit_check.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/reflector_check.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/schema_validation.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/session_start.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/sprint_yaml_validation.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/statusline.py +11 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__init__.py +0 -6
- package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/compat.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/mappings.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/claim.py +14 -44
- package/pennyfarthing-dist/pf/jira/cli.py +124 -14
- package/pennyfarthing-dist/pf/jira/client.py +51 -87
- package/pennyfarthing-dist/pf/jira/reconcile.py +1 -1
- package/pennyfarthing-dist/pf/jira/story.py +6 -4
- package/pennyfarthing-dist/pf/jira/sync.py +2 -2
- package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__init__.py +1 -1
- package/pennyfarthing-dist/pf/migration/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/skill.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/step.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/__pycache__/validate.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/migration/cli.py +0 -1
- package/pennyfarthing-dist/pf/package/__init__.py +0 -0
- package/pennyfarthing-dist/pf/package/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/package/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/package/__pycache__/discovery.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/package/__pycache__/portraits.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/package/cli.py +186 -0
- package/pennyfarthing-dist/pf/package/discovery.py +130 -0
- package/pennyfarthing-dist/pf/package/portraits.py +243 -0
- package/pennyfarthing-dist/pf/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/preflight/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/preflight/__pycache__/finish.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/persona.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/tiers.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/loader.py +21 -7
- package/pennyfarthing-dist/pf/prime/workflow.py +11 -3
- package/pennyfarthing-dist/pf/release/__init__.py +0 -0
- package/pennyfarthing-dist/pf/release/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/release/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/release/__pycache__/deprecate.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/release/__pycache__/dry_run.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/release/cli.py +112 -0
- package/pennyfarthing-dist/pf/release/deprecate.py +187 -0
- package/pennyfarthing-dist/pf/release/dry_run.py +187 -0
- package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/session/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/session/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/settings/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/settings/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/settings/__pycache__/settings.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/settings/settings.py +44 -8
- package/pennyfarthing-dist/pf/sprint/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/archive.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/archive.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/epic_add.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/epic_update.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/shard_merge.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/story_add.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/story_update.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/cli.py +1 -1
- package/pennyfarthing-dist/pf/sprint/loader.py +6 -74
- package/pennyfarthing-dist/pf/sprint/shard_merge.py +126 -0
- package/pennyfarthing-dist/pf/sprint/story_finish.py +18 -4
- package/pennyfarthing-dist/pf/sprint/validator.py +7 -7
- package/pennyfarthing-dist/pf/sprint/yaml_io.py +8 -53
- package/pennyfarthing-dist/pf/story/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/story/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/story/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/story/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/story/__pycache__/size.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/story/__pycache__/template.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_108_1_gate_migration.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_dialogue_manager.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/test_cli_modules.py +32 -137
- package/pennyfarthing-dist/pf/tests/test_codemarkers.py +0 -15
- package/pennyfarthing-dist/pf/tests/test_dist_root.py +720 -0
- package/pennyfarthing-dist/pf/tests/test_package_structure.py +24 -70
- package/pennyfarthing-dist/pf/tests/test_sprint_validator.py +44 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/adapters/agent.py +11 -1
- package/pennyfarthing-dist/pf/validate/adapters/skill_command.py +15 -4
- package/pennyfarthing-dist/pf/validate/adapters/tandem_awareness.py +7 -1
- package/pennyfarthing-dist/pf/validate/adapters/team_mode.py +8 -2
- package/pennyfarthing-dist/pf/validate/adapters/workflow.py +12 -2
- package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/scale.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/scale.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-311.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pyproject.toml +1 -1
- package/pennyfarthing-dist/scripts/core/check-context.sh +2 -2
- package/pennyfarthing-dist/scripts/git/changelog-links.sh +216 -0
- package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/scripts/lib/README.md +0 -1
- package/pennyfarthing-dist/scripts/lib/find-root.sh +1 -1
- package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -1
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +67 -13
- package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +7 -3
- package/pennyfarthing-dist/scripts/workflow/check.py +4 -6
- package/pennyfarthing-dist/scripts/workflow/complete-step.py +2 -2
- package/pennyfarthing-dist/skills/skill-registry.yaml +19 -0
- package/pennyfarthing-dist/workflows/patch.yaml +5 -6
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +27 -2
- package/packages/core/dist/workflow/__test_context_watch__/.session/.tandem-turn-counter +0 -1
- package/packages/core/dist/workflow/__test_context_watch__/.session/95-6-session.md +0 -3
- package/packages/core/dist/workflow/__test_context_watch__/.session/95-6-tandem-architect.md +0 -6
- package/packages/core/dist/workflow/__test_file_watch__/.session/95-4-tandem-architect.md +0 -6
- package/packages/core/dist/workflow/__test_file_watch__/workdir/trigger.ts +0 -1
- package/packages/core/dist/workflow/__test_tool_watch__/.session/95-5-tandem-architect.md +0 -6
- package/packages/core/dist/workflow/__test_tool_watch__/.session/95-5-tandem-toolcalls.jsonl +0 -1
- package/packages/core/dist/workflow/team-lifecycle.d.ts +0 -169
- package/packages/core/dist/workflow/team-lifecycle.d.ts.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.js +0 -217
- package/packages/core/dist/workflow/team-lifecycle.js.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.test.d.ts +0 -20
- package/packages/core/dist/workflow/team-lifecycle.test.d.ts.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.test.js +0 -966
- package/packages/core/dist/workflow/team-lifecycle.test.js.map +0 -1
- package/pennyfarthing-dist/pf/bikerack/background_panel.py +0 -162
- package/pennyfarthing-dist/pf/bikerack/changed_panel.py +0 -201
- package/pennyfarthing-dist/pf/brownfield/__main__.py +0 -8
- package/pennyfarthing-dist/pf/config.py +0 -21
- package/pennyfarthing-dist/pf/hooks.py +0 -32
- package/pennyfarthing-dist/pf/jira_bidirectional_sync.py +0 -37
- package/pennyfarthing-dist/pf/jira_epic_creation.py +0 -30
- package/pennyfarthing-dist/pf/jira_sync.py +0 -36
- package/pennyfarthing-dist/pf/jira_sync_story.py +0 -30
- package/pennyfarthing-dist/pf/migration/__main__.py +0 -10
- package/pennyfarthing-dist/pf/output.py +0 -37
- package/pennyfarthing-dist/pf/theme/__main__.py +0 -6
- package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -177
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""StoryDetailScreen — Mission dossier detail view for BikeRack TUI.
|
|
2
2
|
|
|
3
3
|
Story 110-2: Story drill-through with dossier detail screen.
|
|
4
|
-
|
|
4
|
+
Story 120-8: Upgraded to use StoryDetailWidget with native Textual widgets.
|
|
5
|
+
Pushed via Screen.push() from SprintPanel or ProgressPanel.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from __future__ import annotations
|
|
@@ -9,17 +10,17 @@ from __future__ import annotations
|
|
|
9
10
|
import webbrowser
|
|
10
11
|
from typing import Any
|
|
11
12
|
|
|
12
|
-
from rich.text import Text
|
|
13
13
|
from textual.binding import Binding
|
|
14
|
+
from textual.containers import VerticalScroll
|
|
14
15
|
from textual.screen import Screen
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
from pf.bikerack.story_detail_widget import StoryDetailWidget
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class StoryDetailScreen(Screen):
|
|
19
21
|
"""Detail screen showing story dossier layout.
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
and session notes in a mission-dossier layout.
|
|
23
|
+
Delegates rendering to StoryDetailWidget inside a VerticalScroll.
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
BINDINGS = [
|
|
@@ -57,107 +58,11 @@ class StoryDetailScreen(Screen):
|
|
|
57
58
|
return merged
|
|
58
59
|
|
|
59
60
|
def compose(self):
|
|
60
|
-
"""Compose the dossier layout
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
data = self._story_data
|
|
65
|
-
|
|
66
|
-
# Header section
|
|
67
|
-
title = data.get("title", "Unknown Story")
|
|
68
|
-
points = data.get("points", "?")
|
|
69
|
-
status = data.get("status", "unknown")
|
|
70
|
-
jira_key = data.get("jiraKey", "")
|
|
71
|
-
assignee = data.get("assignee", "")
|
|
72
|
-
priority = data.get("priority", "")
|
|
73
|
-
|
|
74
|
-
header_text = Text()
|
|
75
|
-
if jira_key:
|
|
76
|
-
header_text.append(f"{jira_key}", style="bold cyan")
|
|
77
|
-
header_text.append(" ")
|
|
78
|
-
header_text.append(f"{title}", style="bold")
|
|
79
|
-
# Metadata line
|
|
80
|
-
meta_parts = [status]
|
|
81
|
-
if points and points != "?":
|
|
82
|
-
meta_parts.append(f"{points} pts")
|
|
83
|
-
if priority:
|
|
84
|
-
meta_parts.append(priority)
|
|
85
|
-
if assignee:
|
|
86
|
-
from pf.bikerack.sprint_panel import _format_assignee
|
|
87
|
-
|
|
88
|
-
name = _format_assignee(assignee)
|
|
89
|
-
if name:
|
|
90
|
-
meta_parts.append(name)
|
|
91
|
-
separator = " \u00b7 "
|
|
92
|
-
header_text.append(f"\n{separator.join(meta_parts)}", style="dim")
|
|
93
|
-
yield Static(header_text, id="dossier-header")
|
|
94
|
-
|
|
95
|
-
# Context section (only if context files exist)
|
|
96
|
-
has_epic_ctx = data.get("has_epic_context", False)
|
|
97
|
-
has_story_ctx = data.get("has_story_context", False)
|
|
98
|
-
if has_epic_ctx or has_story_ctx:
|
|
99
|
-
ctx_text = Text()
|
|
100
|
-
ctx_text.append("Context\n", style="bold underline")
|
|
101
|
-
if has_epic_ctx:
|
|
102
|
-
ctx_text.append(" \u2713 Epic context\n", style="green")
|
|
103
|
-
else:
|
|
104
|
-
ctx_text.append(" \u25cb Epic context\n", style="dim")
|
|
105
|
-
if has_story_ctx:
|
|
106
|
-
ctx_text.append(" \u2713 Story context\n", style="green")
|
|
107
|
-
else:
|
|
108
|
-
ctx_text.append(" \u25cb Story context\n", style="dim")
|
|
109
|
-
yield Static(ctx_text, id="dossier-context")
|
|
110
|
-
|
|
111
|
-
# Acceptance Criteria section
|
|
112
|
-
acs = data.get("acceptance_criteria", [])
|
|
113
|
-
if acs:
|
|
114
|
-
ac_text = Text()
|
|
115
|
-
done_count = sum(1 for ac in acs if ac.get("done"))
|
|
116
|
-
ac_text.append("Acceptance Criteria", style="bold underline")
|
|
117
|
-
ac_text.append(f" {done_count}/{len(acs)}\n", style="dim")
|
|
118
|
-
for ac in acs:
|
|
119
|
-
check = "\u2713" if ac.get("done") else "\u25cb"
|
|
120
|
-
style = "green" if ac.get("done") else ""
|
|
121
|
-
ac_text.append(f" {check} {ac.get('text', '')}\n", style=style)
|
|
122
|
-
yield Static(ac_text, id="dossier-ac")
|
|
123
|
-
|
|
124
|
-
# Workflow section
|
|
125
|
-
workflow = data.get("workflow", "")
|
|
126
|
-
phase = data.get("workflow_phase", "")
|
|
127
|
-
if workflow:
|
|
128
|
-
wf_text = Text()
|
|
129
|
-
wf_text.append("Workflow\n", style="bold underline")
|
|
130
|
-
wf_text.append(f" {workflow}", style="cyan")
|
|
131
|
-
if phase:
|
|
132
|
-
wf_text.append(f" Phase: {phase}", style="yellow")
|
|
133
|
-
wf_text.append("\n")
|
|
134
|
-
yield Static(wf_text, id="dossier-workflow")
|
|
135
|
-
|
|
136
|
-
# Git info section
|
|
137
|
-
branch = data.get("git_branch", "")
|
|
138
|
-
pr_url = data.get("pr_url")
|
|
139
|
-
if branch or pr_url:
|
|
140
|
-
git_text = Text()
|
|
141
|
-
git_text.append("Git\n", style="bold underline")
|
|
142
|
-
if branch:
|
|
143
|
-
git_text.append(f" Branch: {branch}\n")
|
|
144
|
-
if pr_url:
|
|
145
|
-
git_text.append(f" PR: {pr_url}\n", style="cyan")
|
|
146
|
-
yield Static(git_text, id="dossier-git")
|
|
147
|
-
|
|
148
|
-
# Session notes section
|
|
149
|
-
notes = data.get("session_notes", "")
|
|
150
|
-
if notes:
|
|
151
|
-
notes_text = Text()
|
|
152
|
-
notes_text.append("Session Notes\n", style="bold underline")
|
|
153
|
-
notes_text.append(f" {notes}\n")
|
|
154
|
-
yield Static(notes_text, id="dossier-notes")
|
|
155
|
-
|
|
156
|
-
# Keybinding hint
|
|
157
|
-
hint = Text.from_markup(
|
|
158
|
-
"\n[dim][Escape] Back [Enter] Open PR[/dim]"
|
|
61
|
+
"""Compose the dossier layout using StoryDetailWidget."""
|
|
62
|
+
yield VerticalScroll(
|
|
63
|
+
StoryDetailWidget(story_data=self._story_data),
|
|
64
|
+
id="detail-scroll",
|
|
159
65
|
)
|
|
160
|
-
yield Static(hint, id="dossier-hint")
|
|
161
66
|
|
|
162
67
|
def action_pop_screen(self) -> None:
|
|
163
68
|
"""Pop this screen off the stack."""
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""StoryDetailWidget — Reusable story detail view using native Textual widgets.
|
|
2
|
+
|
|
3
|
+
Story 120-8: Story details and progress page enrichment with native Textual widgets.
|
|
4
|
+
Renders story data inside Collapsible sections with Rule separators.
|
|
5
|
+
Used by both StoryDetailScreen and ProgressPanel drill-through.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from rich.text import Text
|
|
13
|
+
from textual.widget import Widget
|
|
14
|
+
from textual.widgets import Collapsible, Rule, Static
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StoryDetailWidget(Widget):
|
|
18
|
+
"""Reusable story detail view with native Textual widgets.
|
|
19
|
+
|
|
20
|
+
Renders story data as Collapsible sections for ACs, Workflow, Git,
|
|
21
|
+
Context, and Session Notes. Absent sections are omitted (Tufte pattern).
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, story_data: dict[str, Any] | None = None, **kwargs: Any) -> None:
|
|
25
|
+
super().__init__(**kwargs)
|
|
26
|
+
self._story_data: dict[str, Any] = story_data or {}
|
|
27
|
+
|
|
28
|
+
def compose(self):
|
|
29
|
+
"""Compose the detail layout with header and collapsible sections."""
|
|
30
|
+
data = self._story_data
|
|
31
|
+
|
|
32
|
+
# Header — always present
|
|
33
|
+
yield self._build_header(data)
|
|
34
|
+
|
|
35
|
+
# Sections — only yielded when data exists
|
|
36
|
+
sections_yielded = 0
|
|
37
|
+
|
|
38
|
+
# Acceptance Criteria
|
|
39
|
+
acs = data.get("acceptance_criteria", [])
|
|
40
|
+
if acs:
|
|
41
|
+
if sections_yielded > 0:
|
|
42
|
+
yield Rule()
|
|
43
|
+
done_count = sum(1 for ac in acs if ac.get("done"))
|
|
44
|
+
yield self._build_ac_section(acs, done_count)
|
|
45
|
+
sections_yielded += 1
|
|
46
|
+
|
|
47
|
+
# Workflow
|
|
48
|
+
workflow = data.get("workflow", "")
|
|
49
|
+
if workflow:
|
|
50
|
+
if sections_yielded > 0:
|
|
51
|
+
yield Rule()
|
|
52
|
+
phase = data.get("workflow_phase", "")
|
|
53
|
+
yield self._build_workflow_section(workflow, phase)
|
|
54
|
+
sections_yielded += 1
|
|
55
|
+
|
|
56
|
+
# Git
|
|
57
|
+
branch = data.get("git_branch", "")
|
|
58
|
+
pr_url = data.get("pr_url")
|
|
59
|
+
if branch or pr_url:
|
|
60
|
+
if sections_yielded > 0:
|
|
61
|
+
yield Rule()
|
|
62
|
+
yield self._build_git_section(branch, pr_url)
|
|
63
|
+
sections_yielded += 1
|
|
64
|
+
|
|
65
|
+
# Context
|
|
66
|
+
has_epic_ctx = data.get("has_epic_context", False)
|
|
67
|
+
has_story_ctx = data.get("has_story_context", False)
|
|
68
|
+
if has_epic_ctx or has_story_ctx:
|
|
69
|
+
if sections_yielded > 0:
|
|
70
|
+
yield Rule()
|
|
71
|
+
yield self._build_context_section(has_epic_ctx, has_story_ctx)
|
|
72
|
+
sections_yielded += 1
|
|
73
|
+
|
|
74
|
+
# Session Notes
|
|
75
|
+
notes = data.get("session_notes", "")
|
|
76
|
+
if notes:
|
|
77
|
+
if sections_yielded > 0:
|
|
78
|
+
yield Rule()
|
|
79
|
+
yield self._build_notes_section(notes)
|
|
80
|
+
sections_yielded += 1
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def _build_header(data: dict[str, Any]) -> Static:
|
|
84
|
+
"""Build the story header with title and metadata."""
|
|
85
|
+
title = data.get("title", "Unknown Story")
|
|
86
|
+
points = data.get("points", "?")
|
|
87
|
+
status = data.get("status", "unknown")
|
|
88
|
+
jira_key = data.get("jiraKey", "")
|
|
89
|
+
assignee = data.get("assignee", "")
|
|
90
|
+
priority = data.get("priority", "")
|
|
91
|
+
|
|
92
|
+
header_text = Text()
|
|
93
|
+
if jira_key:
|
|
94
|
+
header_text.append(f"{jira_key}", style="bold cyan")
|
|
95
|
+
header_text.append(" ")
|
|
96
|
+
header_text.append(f"{title}", style="bold")
|
|
97
|
+
if points and points != "?":
|
|
98
|
+
header_text.append(f" {points}pt", style="dim")
|
|
99
|
+
|
|
100
|
+
meta_parts = [status]
|
|
101
|
+
if priority:
|
|
102
|
+
meta_parts.append(priority)
|
|
103
|
+
if assignee:
|
|
104
|
+
meta_parts.append(assignee)
|
|
105
|
+
separator = " \u00b7 "
|
|
106
|
+
header_text.append(f"\n{separator.join(meta_parts)}", style="dim")
|
|
107
|
+
|
|
108
|
+
return Static(header_text, id="detail-header")
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def _build_ac_section(
|
|
112
|
+
acs: list[dict[str, Any]], done_count: int
|
|
113
|
+
) -> Collapsible:
|
|
114
|
+
"""Build the Acceptance Criteria collapsible section."""
|
|
115
|
+
ac_text = Text()
|
|
116
|
+
for ac in acs:
|
|
117
|
+
check = "\u2713" if ac.get("done") else "\u25cb"
|
|
118
|
+
style = "green" if ac.get("done") else ""
|
|
119
|
+
ac_text.append(f" {check} {ac.get('text', '')}\n", style=style)
|
|
120
|
+
|
|
121
|
+
return Collapsible(
|
|
122
|
+
Static(ac_text),
|
|
123
|
+
title=f"Acceptance Criteria {done_count}/{len(acs)}",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def _build_workflow_section(workflow: str, phase: str) -> Collapsible:
|
|
128
|
+
"""Build the Workflow collapsible section."""
|
|
129
|
+
wf_text = Text()
|
|
130
|
+
wf_text.append(f" [{workflow}]", style="cyan")
|
|
131
|
+
if phase:
|
|
132
|
+
wf_text.append(f" Phase: {phase}", style="yellow")
|
|
133
|
+
|
|
134
|
+
return Collapsible(Static(wf_text), title="Workflow")
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def _build_git_section(branch: str, pr_url: str | None) -> Collapsible:
|
|
138
|
+
"""Build the Git collapsible section."""
|
|
139
|
+
git_text = Text()
|
|
140
|
+
if branch:
|
|
141
|
+
git_text.append(f" Branch: {branch}\n")
|
|
142
|
+
if pr_url:
|
|
143
|
+
git_text.append(f" PR: {pr_url}\n", style="cyan")
|
|
144
|
+
|
|
145
|
+
return Collapsible(Static(git_text), title="Git")
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def _build_context_section(
|
|
149
|
+
has_epic: bool, has_story: bool
|
|
150
|
+
) -> Collapsible:
|
|
151
|
+
"""Build the Context collapsible section."""
|
|
152
|
+
ctx_text = Text()
|
|
153
|
+
if has_epic:
|
|
154
|
+
ctx_text.append(" \u2713 Epic context\n", style="green")
|
|
155
|
+
else:
|
|
156
|
+
ctx_text.append(" \u25cb Epic context\n", style="dim")
|
|
157
|
+
if has_story:
|
|
158
|
+
ctx_text.append(" \u2713 Story context\n", style="green")
|
|
159
|
+
else:
|
|
160
|
+
ctx_text.append(" \u25cb Story context\n", style="dim")
|
|
161
|
+
|
|
162
|
+
return Collapsible(Static(ctx_text), title="Context")
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def _build_notes_section(notes: str) -> Collapsible:
|
|
166
|
+
"""Build the Session Notes collapsible section."""
|
|
167
|
+
return Collapsible(Static(f" {notes}"), title="Session Notes")
|
|
@@ -21,17 +21,14 @@ from textual.command import Hit, Hits, Provider
|
|
|
21
21
|
from textual.containers import Horizontal, VerticalScroll
|
|
22
22
|
from textual.message import Message
|
|
23
23
|
from textual.reactive import reactive
|
|
24
|
-
from textual.widgets import
|
|
24
|
+
from textual.widgets import Header, Static, Tab, Tabs
|
|
25
25
|
|
|
26
26
|
from pf.bc.focus import get_last_panel, save_last_panel
|
|
27
27
|
from pf.bikerack.audit_log_panel import AuditLogPanel
|
|
28
|
-
from pf.bikerack.background_panel import BackgroundPanel
|
|
29
28
|
from pf.bikerack.base_panel import get_panel_icon
|
|
30
|
-
from pf.bikerack.
|
|
31
|
-
from pf.bikerack.context_meter_footer import ContextMeterFooter
|
|
29
|
+
from pf.bikerack.context_meter_footer import StatusFooter
|
|
32
30
|
from pf.bikerack.debug_panel import DebugPanel
|
|
33
31
|
from pf.bikerack.diffs_panel import DiffsPanel
|
|
34
|
-
from pf.bikerack.events import NavigateToFile
|
|
35
32
|
from pf.bikerack.git_panel import GitPanel
|
|
36
33
|
from pf.bikerack.progress_panel import ProgressPanel
|
|
37
34
|
from pf.bikerack.sprint_panel import SprintPanel
|
|
@@ -79,8 +76,6 @@ PANEL_REGISTRY: list[tuple[str, str]] = [
|
|
|
79
76
|
("sprint", "Sprint"),
|
|
80
77
|
("git", "Git"),
|
|
81
78
|
("diffs", "Diffs"),
|
|
82
|
-
("changed", "Changed"),
|
|
83
|
-
("background", "Background"),
|
|
84
79
|
("audit-log", "Audit Log"),
|
|
85
80
|
("debug", "Debug"),
|
|
86
81
|
("progress", "Progress"),
|
|
@@ -93,9 +88,7 @@ PANEL_DISPLAY_NAMES: dict[str, str] = {
|
|
|
93
88
|
"diffs": "Diffs",
|
|
94
89
|
"todo": "Todo",
|
|
95
90
|
"workflow": "Workflow",
|
|
96
|
-
"background": "Background",
|
|
97
91
|
"audit-log": "Audit Log",
|
|
98
|
-
"changed": "Changed",
|
|
99
92
|
"ac": "Acceptance Criteria",
|
|
100
93
|
"debug": "Debug",
|
|
101
94
|
"progress": "Progress",
|
|
@@ -110,33 +103,11 @@ _PANEL_KEYS = [key for key, _ in PANEL_REGISTRY]
|
|
|
110
103
|
# Story 110-4: Named presets for common side-by-side views.
|
|
111
104
|
SPLIT_PRESETS: dict[str, tuple[str, str]] = {
|
|
112
105
|
"sprint+diffs": ("sprint", "diffs"),
|
|
113
|
-
"
|
|
106
|
+
"git+diffs": ("git", "diffs"),
|
|
114
107
|
"progress+debug": ("progress", "debug"),
|
|
115
108
|
}
|
|
116
109
|
|
|
117
110
|
|
|
118
|
-
class BindingFooter(Footer):
|
|
119
|
-
"""Footer subclass that exposes active binding text via render().
|
|
120
|
-
|
|
121
|
-
Textual's Footer uses compose() for visual content, so render() returns
|
|
122
|
-
Blank. This override makes binding descriptions available through
|
|
123
|
-
str(footer.render()) for programmatic inspection.
|
|
124
|
-
"""
|
|
125
|
-
|
|
126
|
-
def render(self) -> Any:
|
|
127
|
-
try:
|
|
128
|
-
bindings = self.screen.active_bindings
|
|
129
|
-
parts: list[str] = []
|
|
130
|
-
for _, binding, _enabled, _tooltip in bindings.values():
|
|
131
|
-
if binding.show:
|
|
132
|
-
parts.append(f"{binding.key}:{binding.description}")
|
|
133
|
-
if parts:
|
|
134
|
-
return " ".join(parts)
|
|
135
|
-
except Exception:
|
|
136
|
-
pass
|
|
137
|
-
return super().render()
|
|
138
|
-
|
|
139
|
-
|
|
140
111
|
def _build_panel_tabs() -> list[Tab]:
|
|
141
112
|
"""Build Tab widgets for each panel in the registry."""
|
|
142
113
|
tabs: list[Tab] = []
|
|
@@ -402,11 +373,6 @@ class BikeRackApp(App):
|
|
|
402
373
|
height: auto;
|
|
403
374
|
width: 1fr;
|
|
404
375
|
}
|
|
405
|
-
#project-dir {
|
|
406
|
-
height: 1;
|
|
407
|
-
padding: 0 1;
|
|
408
|
-
color: $text-muted;
|
|
409
|
-
}
|
|
410
376
|
Tabs {
|
|
411
377
|
dock: top;
|
|
412
378
|
}
|
|
@@ -419,8 +385,9 @@ class BikeRackApp(App):
|
|
|
419
385
|
#connection-status {
|
|
420
386
|
height: 1;
|
|
421
387
|
}
|
|
422
|
-
|
|
388
|
+
StatusFooter {
|
|
423
389
|
height: 1;
|
|
390
|
+
dock: bottom;
|
|
424
391
|
}
|
|
425
392
|
#split-container {
|
|
426
393
|
display: none;
|
|
@@ -437,18 +404,16 @@ class BikeRackApp(App):
|
|
|
437
404
|
COMMANDS = App.COMMANDS | {PanelCommands}
|
|
438
405
|
|
|
439
406
|
BINDINGS = [
|
|
440
|
-
Binding("q", "quit", "Quit"),
|
|
441
|
-
Binding("shift+s", "toggle_split", "Split"),
|
|
407
|
+
Binding("q", "quit", "Quit", show=False),
|
|
408
|
+
Binding("shift+s", "toggle_split", "Split", show=False),
|
|
442
409
|
Binding("1", "switch_panel('sprint')", "Sprint", show=False),
|
|
443
410
|
Binding("2", "switch_panel('git')", "Git", show=False),
|
|
444
411
|
Binding("3", "switch_panel('diffs')", "Diffs", show=False),
|
|
445
|
-
Binding("4", "switch_panel('
|
|
446
|
-
Binding("5", "switch_panel('
|
|
447
|
-
Binding("6", "switch_panel('
|
|
448
|
-
Binding("
|
|
449
|
-
Binding("
|
|
450
|
-
Binding("bracketright", "next_panel", "]Next"),
|
|
451
|
-
Binding("bracketleft", "prev_panel", "[Prev"),
|
|
412
|
+
Binding("4", "switch_panel('audit-log')", "Audit Log", show=False),
|
|
413
|
+
Binding("5", "switch_panel('debug')", "Debug", show=False),
|
|
414
|
+
Binding("6", "switch_panel('progress')", "Progress", show=False),
|
|
415
|
+
Binding("bracketright", "next_panel", "Next panel", show=False),
|
|
416
|
+
Binding("bracketleft", "prev_panel", "Prev panel", show=False),
|
|
452
417
|
Binding("tab", "next_panel", show=False, priority=True),
|
|
453
418
|
Binding("shift+tab", "prev_panel", show=False, priority=True),
|
|
454
419
|
Binding("n", "next_diff_file", "Next file", show=False),
|
|
@@ -468,7 +433,7 @@ class BikeRackApp(App):
|
|
|
468
433
|
self._focused_panel: str = "sprint"
|
|
469
434
|
self._previous_panel: str | None = None
|
|
470
435
|
self._programmatic_tab_count: int = 0
|
|
471
|
-
self.
|
|
436
|
+
self._status_footer: StatusFooter | None = None
|
|
472
437
|
# Split-pane state (Story 110-4)
|
|
473
438
|
self._split_mode: bool = False
|
|
474
439
|
self._active_split_pane: str = "left"
|
|
@@ -481,7 +446,6 @@ class BikeRackApp(App):
|
|
|
481
446
|
).name
|
|
482
447
|
yield Header()
|
|
483
448
|
yield AgentHeader(id="agent-header")
|
|
484
|
-
yield Static(f"[dim]{project_dir_name}[/dim]", id="project-dir")
|
|
485
449
|
yield Tabs(*_build_panel_tabs(), id="tab-bar")
|
|
486
450
|
yield ConnectionStatus(
|
|
487
451
|
STATE_DISPLAY[ConnectionState.DISCONNECTED],
|
|
@@ -491,17 +455,17 @@ class BikeRackApp(App):
|
|
|
491
455
|
yield SprintPanel(client=self._client, id="panel-sprint")
|
|
492
456
|
yield GitPanel(client=self._client, id="panel-git")
|
|
493
457
|
yield DiffsPanel(client=self._client, id="panel-diffs")
|
|
494
|
-
yield ChangedPanel(client=self._client, id="panel-changed")
|
|
495
|
-
yield BackgroundPanel(client=self._client, id="panel-background")
|
|
496
458
|
yield AuditLogPanel(client=self._client, id="panel-audit-log")
|
|
497
459
|
yield DebugPanel(client=self._client, id="panel-debug")
|
|
498
460
|
yield ProgressPanel(client=self._client, id="panel-progress")
|
|
499
461
|
with Horizontal(id="split-container"):
|
|
500
462
|
yield VerticalScroll(id="split-left")
|
|
501
463
|
yield VerticalScroll(id="split-right")
|
|
502
|
-
self.
|
|
503
|
-
|
|
504
|
-
|
|
464
|
+
self._status_footer = StatusFooter(
|
|
465
|
+
project_dir=project_dir_name,
|
|
466
|
+
client=self._client,
|
|
467
|
+
)
|
|
468
|
+
yield self._status_footer
|
|
505
469
|
|
|
506
470
|
async def on_mount(self) -> None:
|
|
507
471
|
# Restore last panel or default to sprint
|
|
@@ -537,15 +501,6 @@ class BikeRackApp(App):
|
|
|
537
501
|
self._client.subscribe("persona", self._handle_persona_message)
|
|
538
502
|
self.run_worker(self._client.connect(), exclusive=True, name="ws-client")
|
|
539
503
|
|
|
540
|
-
def on_navigate_to_file(self, event: NavigateToFile) -> None:
|
|
541
|
-
"""Handle NavigateToFile — switch to diffs and navigate to file."""
|
|
542
|
-
self.action_switch_panel("diffs")
|
|
543
|
-
try:
|
|
544
|
-
diffs = self.query_one("#panel-diffs", DiffsPanel)
|
|
545
|
-
diffs.navigate_to_file(event.path)
|
|
546
|
-
except Exception:
|
|
547
|
-
pass
|
|
548
|
-
|
|
549
504
|
def action_switch_panel(self, key: str) -> None:
|
|
550
505
|
"""Switch to a panel by key."""
|
|
551
506
|
if key not in _PANEL_KEYS:
|
|
@@ -573,9 +528,9 @@ class BikeRackApp(App):
|
|
|
573
528
|
save_last_panel(key, project_dir=None)
|
|
574
529
|
self._update_tab_bar(key)
|
|
575
530
|
|
|
576
|
-
# Refresh
|
|
577
|
-
if self.
|
|
578
|
-
self.
|
|
531
|
+
# Refresh status footer on panel switch
|
|
532
|
+
if self._status_footer is not None:
|
|
533
|
+
self._status_footer.request_refresh()
|
|
579
534
|
|
|
580
535
|
def action_next_panel(self) -> None:
|
|
581
536
|
"""Cycle to the next panel, or toggle pane focus in split mode."""
|
|
@@ -890,6 +845,82 @@ class BikeRackApp(App):
|
|
|
890
845
|
DEFAULT_PORT = 2898
|
|
891
846
|
|
|
892
847
|
|
|
848
|
+
def get_watch_paths() -> list[Path]:
|
|
849
|
+
"""Return directories to watch for Python file changes in dev mode."""
|
|
850
|
+
base = Path(__file__).resolve().parent.parent # pf/
|
|
851
|
+
return [
|
|
852
|
+
base / "bikerack",
|
|
853
|
+
base / "bc",
|
|
854
|
+
]
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
def watch_filter(change: str, path: str) -> bool:
|
|
858
|
+
"""Filter file change events — only accept .py files, ignore caches."""
|
|
859
|
+
if "__pycache__" in path:
|
|
860
|
+
return False
|
|
861
|
+
if path.endswith(".pyc"):
|
|
862
|
+
return False
|
|
863
|
+
if not path.endswith(".py"):
|
|
864
|
+
return False
|
|
865
|
+
return True
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
def _run_with_reload(app: BikeRackApp, watch_paths: list[Path], filter_func) -> None:
|
|
869
|
+
"""Run the app with file watching and auto-reload via watchfiles."""
|
|
870
|
+
import sys
|
|
871
|
+
|
|
872
|
+
from watchfiles import run_process
|
|
873
|
+
|
|
874
|
+
# Build the command that launches the TUI normally
|
|
875
|
+
cmd = [sys.executable, "-m", "pf.bikerack.tui"]
|
|
876
|
+
if hasattr(app, "_client") and app._client is not None:
|
|
877
|
+
cmd.extend(["--port", str(app._client._port)])
|
|
878
|
+
|
|
879
|
+
run_process(
|
|
880
|
+
*watch_paths,
|
|
881
|
+
target=cmd,
|
|
882
|
+
callback=lambda changes: None,
|
|
883
|
+
watch_filter=filter_func,
|
|
884
|
+
)
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
def _patch_tgp_for_tmux() -> None:
|
|
888
|
+
"""Monkey-patch textual-image's TGP writer to wrap Kitty graphics
|
|
889
|
+
escapes in tmux DCS passthrough sequences.
|
|
890
|
+
|
|
891
|
+
tmux doesn't forward Kitty APC escapes (\\x1b_G...\\x1b\\\\) natively.
|
|
892
|
+
They must be wrapped: \\x1bPtmux;<escaped>\\x1b\\\\
|
|
893
|
+
with any \\x1b in the payload doubled to \\x1b\\x1b.
|
|
894
|
+
"""
|
|
895
|
+
try:
|
|
896
|
+
import textual_image.renderable.tgp as tgp
|
|
897
|
+
except ImportError:
|
|
898
|
+
return
|
|
899
|
+
|
|
900
|
+
_original_send = tgp._send_tgp_message
|
|
901
|
+
|
|
902
|
+
def _tmux_send(*, payload: str | None = None, **kwargs: int | str | None) -> None:
|
|
903
|
+
import sys
|
|
904
|
+
|
|
905
|
+
if not sys.__stdout__:
|
|
906
|
+
return
|
|
907
|
+
|
|
908
|
+
inner = [
|
|
909
|
+
tgp._TGP_MESSAGE_START,
|
|
910
|
+
",".join(f"{k}={v}" for k, v in kwargs.items() if v is not None),
|
|
911
|
+
f";{payload}" if payload else "",
|
|
912
|
+
tgp._TGP_MESSAGE_END,
|
|
913
|
+
]
|
|
914
|
+
sequence = "".join(inner)
|
|
915
|
+
|
|
916
|
+
# Wrap in tmux DCS passthrough: double any ESC inside the payload
|
|
917
|
+
wrapped = "\x1bPtmux;" + sequence.replace("\x1b", "\x1b\x1b") + "\x1b\\"
|
|
918
|
+
sys.__stdout__.write(wrapped)
|
|
919
|
+
sys.__stdout__.flush()
|
|
920
|
+
|
|
921
|
+
tgp._send_tgp_message = _tmux_send
|
|
922
|
+
|
|
923
|
+
|
|
893
924
|
def main(
|
|
894
925
|
port: int | None = None,
|
|
895
926
|
project_dir: Path | None = None,
|
|
@@ -905,6 +936,13 @@ def main(
|
|
|
905
936
|
|
|
906
937
|
portrait_resolver.detect_image_protocol()
|
|
907
938
|
|
|
939
|
+
# Patch textual-image to wrap Kitty graphics escapes in tmux passthrough.
|
|
940
|
+
# tmux doesn't natively forward Kitty's APC graphics escapes — they must
|
|
941
|
+
# be wrapped in DCS passthrough sequences (\x1bPtmux;...\x1b\\).
|
|
942
|
+
# See: https://github.com/tmux/tmux/wiki/FAQ
|
|
943
|
+
if os.environ.get("TMUX") and portrait_resolver.detect_image_protocol() == "kitty":
|
|
944
|
+
_patch_tgp_for_tmux()
|
|
945
|
+
|
|
908
946
|
if port is None:
|
|
909
947
|
if project_dir is not None:
|
|
910
948
|
port_file = project_dir / ".bikerack-port"
|
|
@@ -923,6 +961,43 @@ def main(
|
|
|
923
961
|
app.run()
|
|
924
962
|
|
|
925
963
|
|
|
964
|
+
def dev_main(
|
|
965
|
+
port: int | None = None,
|
|
966
|
+
project_dir: Path | None = None,
|
|
967
|
+
) -> None:
|
|
968
|
+
"""Launch BikeRack TUI in dev mode with auto-reload on Python file changes.
|
|
969
|
+
|
|
970
|
+
Sets TEXTUAL env var for CSS hot-reload and uses watchfiles for Python reload.
|
|
971
|
+
"""
|
|
972
|
+
os.environ["TEXTUAL"] = "devtools"
|
|
973
|
+
|
|
974
|
+
from pf.bikerack import portrait_resolver
|
|
975
|
+
|
|
976
|
+
portrait_resolver.detect_image_protocol()
|
|
977
|
+
|
|
978
|
+
if os.environ.get("TMUX") and portrait_resolver.detect_image_protocol() == "kitty":
|
|
979
|
+
_patch_tgp_for_tmux()
|
|
980
|
+
|
|
981
|
+
if port is None:
|
|
982
|
+
if project_dir is not None:
|
|
983
|
+
port_file = project_dir / ".bikerack-port"
|
|
984
|
+
if port_file.exists():
|
|
985
|
+
try:
|
|
986
|
+
port = int(port_file.read_text().strip())
|
|
987
|
+
except (ValueError, OSError):
|
|
988
|
+
port = DEFAULT_PORT
|
|
989
|
+
else:
|
|
990
|
+
port = DEFAULT_PORT
|
|
991
|
+
else:
|
|
992
|
+
port = DEFAULT_PORT
|
|
993
|
+
|
|
994
|
+
client = WheelHubClient(port=port)
|
|
995
|
+
app = BikeRackApp(client=client)
|
|
996
|
+
|
|
997
|
+
watch_paths = get_watch_paths()
|
|
998
|
+
_run_with_reload(app, watch_paths, watch_filter)
|
|
999
|
+
|
|
1000
|
+
|
|
926
1001
|
if __name__ == "__main__":
|
|
927
1002
|
import argparse
|
|
928
1003
|
|
|
Binary file
|
|
Binary file
|