@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
|
@@ -12,7 +12,7 @@ Commands:
|
|
|
12
12
|
move Transition issue status
|
|
13
13
|
assign Assign issue to user
|
|
14
14
|
link Link two issues
|
|
15
|
-
search Search issues
|
|
15
|
+
search Search issues (plain text or JQL)
|
|
16
16
|
create epic Create epic + stories from YAML
|
|
17
17
|
create story Create single story from YAML
|
|
18
18
|
sync Sync epic to Jira
|
|
@@ -90,7 +90,7 @@ def move(key, status, dry_run):
|
|
|
90
90
|
elif result.get("success"):
|
|
91
91
|
click.echo(f"Moved {key} to '{status}'")
|
|
92
92
|
else:
|
|
93
|
-
click.echo(f"Failed: {result.get('
|
|
93
|
+
click.echo(f"Failed: {result.get('error', 'unknown')}", err=True)
|
|
94
94
|
raise SystemExit(1)
|
|
95
95
|
|
|
96
96
|
|
|
@@ -108,7 +108,7 @@ def assign(key, user, dry_run):
|
|
|
108
108
|
elif result.get("success"):
|
|
109
109
|
click.echo(f"Assigned {key} to {user}")
|
|
110
110
|
else:
|
|
111
|
-
click.echo(f"Failed: {result.get('
|
|
111
|
+
click.echo(f"Failed: {result.get('error', 'unknown')}", err=True)
|
|
112
112
|
raise SystemExit(1)
|
|
113
113
|
|
|
114
114
|
|
|
@@ -129,21 +129,131 @@ def link(parent_key, child_key, link_type, dry_run):
|
|
|
129
129
|
if result.get("success"):
|
|
130
130
|
click.echo(f"Linked {parent_key} -> {child_key} ({link_type})")
|
|
131
131
|
else:
|
|
132
|
-
click.echo(f"Failed: {result.get('
|
|
132
|
+
click.echo(f"Failed: {result.get('error', 'unknown')}", err=True)
|
|
133
133
|
raise SystemExit(1)
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
@jira.command()
|
|
137
|
-
@click.argument("
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
@click.argument("query")
|
|
138
|
+
@click.option("--project", "-p", default=None, help="Jira project key (default: from config)")
|
|
139
|
+
@click.option("--max-results", "-n", default=50, type=int, help="Maximum results (default: 50)")
|
|
140
|
+
@click.option("--status", "-s", default=None, help="Filter by status (e.g. 'In Progress', 'Done')")
|
|
141
|
+
@click.option("--type", "-t", "issue_type", default=None, help="Filter by issue type (e.g. Story, Epic, Bug)")
|
|
142
|
+
@click.option("--json-output", "--json", "json_out", is_flag=True, help="Output as JSON")
|
|
143
|
+
def search(query, project, max_results, status, issue_type, json_out):
|
|
144
|
+
"""Search issues using plain text or JQL.
|
|
141
145
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
\b
|
|
147
|
+
Plain text queries search summary, description, and comments.
|
|
148
|
+
JQL queries (detected automatically) are passed through directly.
|
|
149
|
+
|
|
150
|
+
\b
|
|
151
|
+
Examples:
|
|
152
|
+
pf jira search "BikeRack reconnect"
|
|
153
|
+
pf jira search "sprint fix" --project MSSCI
|
|
154
|
+
pf jira search "status = 'In Progress' AND assignee = currentUser()"
|
|
155
|
+
pf jira search "install" --status "To Do" --type Story
|
|
156
|
+
"""
|
|
157
|
+
import json as json_mod
|
|
158
|
+
|
|
159
|
+
from pf.jira.client import JIRA_PROJECT, get_client
|
|
160
|
+
|
|
161
|
+
client = get_client()
|
|
162
|
+
proj = project or JIRA_PROJECT
|
|
163
|
+
|
|
164
|
+
jql = _build_search_jql(query, proj, status, issue_type)
|
|
165
|
+
|
|
166
|
+
issues = client.search_issues_sync(
|
|
167
|
+
jql,
|
|
168
|
+
fields=["key", "summary", "status", "assignee", "customfield_10031", "issuetype"],
|
|
169
|
+
max_results=max_results,
|
|
145
170
|
)
|
|
146
|
-
|
|
171
|
+
|
|
172
|
+
if json_out:
|
|
173
|
+
click.echo(json_mod.dumps(issues, indent=2))
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
if not issues:
|
|
177
|
+
click.echo(f"No issues found. JQL: {jql}")
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
click.echo(f"Found {len(issues)} issue(s):\n")
|
|
181
|
+
_print_search_results(issues)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _is_jql(query: str) -> bool:
|
|
185
|
+
"""Detect if a query string looks like JQL rather than plain text."""
|
|
186
|
+
jql_keywords = [
|
|
187
|
+
" = ", " != ", " ~ ", " !~ ", " IN ", " NOT IN ",
|
|
188
|
+
" AND ", " OR ", " ORDER BY ", " >= ", " <= ",
|
|
189
|
+
" IS ", " WAS ", " CHANGED ",
|
|
190
|
+
]
|
|
191
|
+
upper = f" {query} ".upper()
|
|
192
|
+
return any(kw.upper() in upper for kw in jql_keywords)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _build_search_jql(
|
|
196
|
+
query: str,
|
|
197
|
+
project: str,
|
|
198
|
+
status: str | None,
|
|
199
|
+
issue_type: str | None,
|
|
200
|
+
) -> str:
|
|
201
|
+
"""Build JQL from query string, project, and optional filters."""
|
|
202
|
+
if _is_jql(query):
|
|
203
|
+
jql = query
|
|
204
|
+
if project and "project" not in query.lower():
|
|
205
|
+
jql = f"project = {project} AND ({jql})"
|
|
206
|
+
else:
|
|
207
|
+
jql = f'project = {project} AND text ~ "{query}"'
|
|
208
|
+
|
|
209
|
+
if status:
|
|
210
|
+
jql += f' AND status = "{status}"'
|
|
211
|
+
if issue_type:
|
|
212
|
+
jql += f' AND issuetype = "{issue_type}"'
|
|
213
|
+
|
|
214
|
+
jql += " ORDER BY updated DESC"
|
|
215
|
+
return jql
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _print_search_results(issues: list) -> None:
|
|
219
|
+
"""Format and print search results as a table."""
|
|
220
|
+
from pf.jira.client import get_jira_field
|
|
221
|
+
|
|
222
|
+
rows = []
|
|
223
|
+
for issue in issues:
|
|
224
|
+
key = issue.get("key", "?")
|
|
225
|
+
summary = get_jira_field(issue, "fields.summary", "")
|
|
226
|
+
status_name = get_jira_field(issue, "fields.status.name", "?")
|
|
227
|
+
issue_type = get_jira_field(issue, "fields.issuetype.name", "?")
|
|
228
|
+
assignee = get_jira_field(issue, "fields.assignee.displayName", "Unassigned")
|
|
229
|
+
points = get_jira_field(issue, "fields.customfield_10031")
|
|
230
|
+
pts_str = str(int(points)) if points else "-"
|
|
231
|
+
rows.append((key, issue_type, summary, status_name, pts_str, assignee))
|
|
232
|
+
|
|
233
|
+
if not rows:
|
|
234
|
+
return
|
|
235
|
+
|
|
236
|
+
# Column widths
|
|
237
|
+
key_w = max(len(r[0]) for r in rows)
|
|
238
|
+
type_w = max(len(r[1]) for r in rows)
|
|
239
|
+
status_w = max(len(r[3]) for r in rows)
|
|
240
|
+
pts_w = 3
|
|
241
|
+
# Summary gets the rest, capped at 50
|
|
242
|
+
sum_w = 50
|
|
243
|
+
|
|
244
|
+
header = (
|
|
245
|
+
f"{'Key':<{key_w}} {'Type':<{type_w}} {'Summary':<{sum_w}} "
|
|
246
|
+
f"{'Status':<{status_w}} {'Pts':<{pts_w}} Assignee"
|
|
247
|
+
)
|
|
248
|
+
click.echo(header)
|
|
249
|
+
click.echo("-" * len(header))
|
|
250
|
+
|
|
251
|
+
for key, itype, summary, st, pts, assignee in rows:
|
|
252
|
+
trunc = (summary[:sum_w - 1] + "…") if len(summary) > sum_w else summary
|
|
253
|
+
click.echo(
|
|
254
|
+
f"{key:<{key_w}} {itype:<{type_w}} {trunc:<{sum_w}} "
|
|
255
|
+
f"{st:<{status_w}} {pts:<{pts_w}} {assignee}"
|
|
256
|
+
)
|
|
147
257
|
|
|
148
258
|
|
|
149
259
|
@jira.group()
|
|
@@ -247,7 +357,7 @@ def create_standalone(title, points, description, dry_run):
|
|
|
247
357
|
if result.get("success"):
|
|
248
358
|
click.echo("Transitioned to Done")
|
|
249
359
|
else:
|
|
250
|
-
click.echo(f"Warning: could not transition to Done: {result.get('
|
|
360
|
+
click.echo(f"Warning: could not transition to Done: {result.get('error')}")
|
|
251
361
|
|
|
252
362
|
click.echo(f"\n{jira_key}: {title}")
|
|
253
363
|
click.echo(f"https://1898andco.atlassian.net/browse/{jira_key}")
|
|
@@ -337,7 +447,7 @@ def sprint_add(sprint_id, issue_key, dry_run):
|
|
|
337
447
|
if result.get("success"):
|
|
338
448
|
click.echo(f"Added {issue_key} to sprint {sprint_id}")
|
|
339
449
|
else:
|
|
340
|
-
click.echo(f"Failed: {result.get('
|
|
450
|
+
click.echo(f"Failed: {result.get('error', 'unknown')}", err=True)
|
|
341
451
|
raise SystemExit(1)
|
|
342
452
|
|
|
343
453
|
|
|
@@ -122,76 +122,6 @@ def is_jira_cli_available() -> bool:
|
|
|
122
122
|
return shutil.which("jira") is not None
|
|
123
123
|
|
|
124
124
|
|
|
125
|
-
def get_issue(issue_key: str) -> dict[str, Any] | None:
|
|
126
|
-
"""Fetch issue details from Jira.
|
|
127
|
-
|
|
128
|
-
Args:
|
|
129
|
-
issue_key: Jira issue key (e.g., "MSSCI-12398")
|
|
130
|
-
|
|
131
|
-
Returns:
|
|
132
|
-
Issue data as dict, or None if not found
|
|
133
|
-
"""
|
|
134
|
-
if not is_jira_cli_available():
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
result = subprocess.run(
|
|
138
|
-
["jira", "issue", "view", issue_key, "--raw"],
|
|
139
|
-
capture_output=True,
|
|
140
|
-
text=True,
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
if result.returncode != 0:
|
|
144
|
-
return None
|
|
145
|
-
|
|
146
|
-
try:
|
|
147
|
-
return json.loads(result.stdout)
|
|
148
|
-
except json.JSONDecodeError:
|
|
149
|
-
return None
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def update_issue_status(issue_key: str, status: str) -> bool:
|
|
153
|
-
"""Transition an issue to a new status.
|
|
154
|
-
|
|
155
|
-
Args:
|
|
156
|
-
issue_key: Jira issue key
|
|
157
|
-
status: Target status name
|
|
158
|
-
|
|
159
|
-
Returns:
|
|
160
|
-
True if successful, False otherwise
|
|
161
|
-
"""
|
|
162
|
-
if not is_jira_cli_available():
|
|
163
|
-
return False
|
|
164
|
-
|
|
165
|
-
result = subprocess.run(
|
|
166
|
-
["jira", "issue", "move", issue_key, status],
|
|
167
|
-
capture_output=True,
|
|
168
|
-
text=True,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
return result.returncode == 0
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def add_comment(issue_key: str, comment: str) -> bool:
|
|
175
|
-
"""Add a comment to an issue.
|
|
176
|
-
|
|
177
|
-
Args:
|
|
178
|
-
issue_key: Jira issue key
|
|
179
|
-
comment: Comment text
|
|
180
|
-
|
|
181
|
-
Returns:
|
|
182
|
-
True if successful, False otherwise
|
|
183
|
-
"""
|
|
184
|
-
if not is_jira_cli_available():
|
|
185
|
-
return False
|
|
186
|
-
|
|
187
|
-
result = subprocess.run(
|
|
188
|
-
["jira", "issue", "comment", "add", issue_key, "--body", comment],
|
|
189
|
-
capture_output=True,
|
|
190
|
-
text=True,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
return result.returncode == 0
|
|
194
|
-
|
|
195
125
|
|
|
196
126
|
def get_jira_field(issue_json: dict[str, Any], field_path: str, default: Any = None) -> Any:
|
|
197
127
|
"""Extract field from Jira issue JSON using dot notation.
|
|
@@ -226,13 +156,13 @@ def get_story_points(issue_key: str, issue_json: dict[str, Any] | None = None) -
|
|
|
226
156
|
|
|
227
157
|
Args:
|
|
228
158
|
issue_key: Jira issue key
|
|
229
|
-
issue_json: Optional pre-fetched issue JSON
|
|
159
|
+
issue_json: Optional pre-fetched issue JSON (required if no default client)
|
|
230
160
|
|
|
231
161
|
Returns:
|
|
232
162
|
Story points as int, or None if not set
|
|
233
163
|
"""
|
|
234
164
|
if issue_json is None:
|
|
235
|
-
issue_json =
|
|
165
|
+
issue_json = get_client().get_issue_sync(issue_key)
|
|
236
166
|
if not issue_json:
|
|
237
167
|
return None
|
|
238
168
|
|
|
@@ -349,13 +279,11 @@ def get_current_user_email() -> str:
|
|
|
349
279
|
class JiraClient:
|
|
350
280
|
"""Unified Jira REST API client with sync and async support.
|
|
351
281
|
|
|
352
|
-
Consolidates REST API access
|
|
353
|
-
- jira_sync.py (httpx async)
|
|
354
|
-
- jira_epic_creation.py (curl subprocess)
|
|
282
|
+
Consolidates all Jira REST API access.
|
|
355
283
|
|
|
356
284
|
Usage (sync):
|
|
357
285
|
client = JiraClient()
|
|
358
|
-
issue = client.
|
|
286
|
+
issue = client.get_issue_sync("MSSCI-12345")
|
|
359
287
|
|
|
360
288
|
Usage (async):
|
|
361
289
|
client = JiraClient()
|
|
@@ -510,7 +438,7 @@ class JiraClient:
|
|
|
510
438
|
"GET", f"/rest/api/3/issue/{issue_key}/transitions"
|
|
511
439
|
)
|
|
512
440
|
if not transitions_data:
|
|
513
|
-
return {"success": False, "
|
|
441
|
+
return {"success": False, "error": "Could not get transitions"}
|
|
514
442
|
|
|
515
443
|
transitions = transitions_data.get("transitions", [])
|
|
516
444
|
transition_id = None
|
|
@@ -523,7 +451,7 @@ class JiraClient:
|
|
|
523
451
|
available = [t.get("name") for t in transitions]
|
|
524
452
|
return {
|
|
525
453
|
"success": False,
|
|
526
|
-
"
|
|
454
|
+
"error": f"No transition to '{target_status}' available. "
|
|
527
455
|
f"Available: {available}",
|
|
528
456
|
}
|
|
529
457
|
|
|
@@ -558,7 +486,7 @@ class JiraClient:
|
|
|
558
486
|
if not users or not isinstance(users, list) or len(users) == 0:
|
|
559
487
|
return {
|
|
560
488
|
"success": False,
|
|
561
|
-
"
|
|
489
|
+
"error": f"User not found: {assignee_email}",
|
|
562
490
|
}
|
|
563
491
|
account_id = users[0].get("accountId")
|
|
564
492
|
else:
|
|
@@ -571,6 +499,41 @@ class JiraClient:
|
|
|
571
499
|
# Assign PUT returns empty body on success (204)
|
|
572
500
|
return {"success": True}
|
|
573
501
|
|
|
502
|
+
def add_comment_sync(self, issue_key: str, comment: str) -> dict[str, Any]:
|
|
503
|
+
"""Add a comment to a Jira issue via REST API.
|
|
504
|
+
|
|
505
|
+
Args:
|
|
506
|
+
issue_key: Jira issue key
|
|
507
|
+
comment: Comment body text
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
Result dict with success status
|
|
511
|
+
"""
|
|
512
|
+
payload = {
|
|
513
|
+
"body": {
|
|
514
|
+
"type": "doc",
|
|
515
|
+
"version": 1,
|
|
516
|
+
"content": [
|
|
517
|
+
{
|
|
518
|
+
"type": "paragraph",
|
|
519
|
+
"content": [{"type": "text", "text": comment}],
|
|
520
|
+
}
|
|
521
|
+
],
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
result = self._call_api_sync(
|
|
525
|
+
"POST",
|
|
526
|
+
f"/rest/api/3/issue/{issue_key}/comment",
|
|
527
|
+
payload,
|
|
528
|
+
)
|
|
529
|
+
if result is None:
|
|
530
|
+
# POST comment returns the created comment on success;
|
|
531
|
+
# _call_api_sync returns None on empty/failed response
|
|
532
|
+
# but also returns None on JSON decode failure for 201 with empty body.
|
|
533
|
+
# Treat None as success since the API may return 201 with no body.
|
|
534
|
+
pass
|
|
535
|
+
return {"success": True}
|
|
536
|
+
|
|
574
537
|
def add_to_sprint_sync(self, sprint_id: int | str, issue_key: str) -> dict[str, Any]:
|
|
575
538
|
"""Add issue to a sprint via Agile REST API.
|
|
576
539
|
|
|
@@ -609,9 +572,10 @@ class JiraClient:
|
|
|
609
572
|
|
|
610
573
|
encoded_jql = urllib.parse.quote(jql)
|
|
611
574
|
fields_param = ",".join(fields)
|
|
575
|
+
# Jira Cloud deprecated /rest/api/3/search — use /rest/api/3/search/jql
|
|
612
576
|
result = self._call_api_sync(
|
|
613
577
|
"GET",
|
|
614
|
-
f"/rest/api/3/search?jql={encoded_jql}&fields={fields_param}"
|
|
578
|
+
f"/rest/api/3/search/jql?jql={encoded_jql}&fields={fields_param}"
|
|
615
579
|
f"&maxResults={max_results}",
|
|
616
580
|
)
|
|
617
581
|
if not result:
|
|
@@ -680,7 +644,7 @@ class JiraClient:
|
|
|
680
644
|
target_status: Target status name (e.g., "In Progress", "Done")
|
|
681
645
|
|
|
682
646
|
Returns:
|
|
683
|
-
Result dict with success status and optional
|
|
647
|
+
Result dict with success status and optional error
|
|
684
648
|
"""
|
|
685
649
|
import httpx
|
|
686
650
|
|
|
@@ -694,7 +658,7 @@ class JiraClient:
|
|
|
694
658
|
if response.status_code != 200:
|
|
695
659
|
return {
|
|
696
660
|
"success": False,
|
|
697
|
-
"
|
|
661
|
+
"error": f"Could not get transitions: {response.status_code}",
|
|
698
662
|
}
|
|
699
663
|
|
|
700
664
|
transitions = response.json().get("transitions", [])
|
|
@@ -707,7 +671,7 @@ class JiraClient:
|
|
|
707
671
|
if not transition_id:
|
|
708
672
|
return {
|
|
709
673
|
"success": False,
|
|
710
|
-
"
|
|
674
|
+
"error": f"No transition to '{target_status}' available",
|
|
711
675
|
}
|
|
712
676
|
|
|
713
677
|
# Execute transition
|
|
@@ -722,11 +686,11 @@ class JiraClient:
|
|
|
722
686
|
return {"success": True}
|
|
723
687
|
return {
|
|
724
688
|
"success": False,
|
|
725
|
-
"
|
|
689
|
+
"error": f"Transition failed: {response.status_code}",
|
|
726
690
|
}
|
|
727
691
|
|
|
728
692
|
except httpx.HTTPError as e:
|
|
729
|
-
return {"success": False, "
|
|
693
|
+
return {"success": False, "error": str(e)}
|
|
730
694
|
|
|
731
695
|
async def update_fields_async(
|
|
732
696
|
self, issue_key: str, fields: dict[str, Any]
|
|
@@ -756,10 +720,10 @@ class JiraClient:
|
|
|
756
720
|
|
|
757
721
|
if response.status_code in (200, 204):
|
|
758
722
|
return {"success": True}
|
|
759
|
-
return {"success": False, "
|
|
723
|
+
return {"success": False, "error": f"HTTP {response.status_code}"}
|
|
760
724
|
|
|
761
725
|
except httpx.HTTPError as e:
|
|
762
|
-
return {"success": False, "
|
|
726
|
+
return {"success": False, "error": str(e)}
|
|
763
727
|
|
|
764
728
|
async def sync_story_points_async(
|
|
765
729
|
self,
|
|
@@ -88,7 +88,7 @@ def fetch_jira_issue(jira_key: str) -> dict[str, Any] | None:
|
|
|
88
88
|
Returns:
|
|
89
89
|
Issue JSON if found, None otherwise
|
|
90
90
|
"""
|
|
91
|
-
return jira_client.
|
|
91
|
+
return jira_client.get_client().get_issue_sync(jira_key)
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
def sync_story(
|
|
@@ -147,10 +147,11 @@ def sync_story(
|
|
|
147
147
|
if dry_run:
|
|
148
148
|
actions.append(f"[DRY-RUN] {action}")
|
|
149
149
|
else:
|
|
150
|
-
|
|
150
|
+
result = jira_client.get_client().transition_sync(jira_key, target_status)
|
|
151
|
+
if result.get("success"):
|
|
151
152
|
actions.append(action)
|
|
152
153
|
else:
|
|
153
|
-
errors.append(f"Failed to transition {jira_key}")
|
|
154
|
+
errors.append(f"Failed to transition {jira_key}: {result.get('error', 'unknown')}")
|
|
154
155
|
else:
|
|
155
156
|
actions.append(f"status already {current_jira_status}")
|
|
156
157
|
|
|
@@ -173,7 +174,8 @@ def sync_story(
|
|
|
173
174
|
if dry_run:
|
|
174
175
|
actions.append(f"[DRY-RUN] {action}")
|
|
175
176
|
else:
|
|
176
|
-
|
|
177
|
+
result = jira_client.get_client().add_comment_sync(jira_key, comment)
|
|
178
|
+
if result.get("success"):
|
|
177
179
|
actions.append(action)
|
|
178
180
|
else:
|
|
179
181
|
errors.append(f"Failed to add comment to {jira_key}")
|
|
@@ -150,7 +150,7 @@ async def sync_story(
|
|
|
150
150
|
if result.get("success"):
|
|
151
151
|
actions.append(f"transitioned: {current_status} -> {target_status}")
|
|
152
152
|
else:
|
|
153
|
-
actions.append(f"transition failed: {result.get('
|
|
153
|
+
actions.append(f"transition failed: {result.get('error')}")
|
|
154
154
|
|
|
155
155
|
# Sync points if requested
|
|
156
156
|
story_points = story.get("points")
|
|
@@ -167,7 +167,7 @@ async def sync_story(
|
|
|
167
167
|
else:
|
|
168
168
|
actions.append(f"synced points: {story_points}")
|
|
169
169
|
else:
|
|
170
|
-
actions.append(f"points sync failed: {result.get('
|
|
170
|
+
actions.append(f"points sync failed: {result.get('error')}")
|
|
171
171
|
|
|
172
172
|
return SyncResult(
|
|
173
173
|
story_id=story_id,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|