@pennyfarthing/core 11.3.7 → 11.4.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 +17 -16
- package/packages/core/dist/public/css/react.css +1 -1
- package/packages/core/dist/public/js/react/react.js +24 -24
- package/packages/core/src/public/App.tsx +356 -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 +217 -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 +749 -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/FontPicker/FontPicker.css +276 -0
- package/packages/core/src/public/components/FontPicker/index.tsx +430 -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 +82 -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/ThemePalette/ThemePalette.css +179 -0
- package/packages/core/src/public/components/ThemePalette/index.tsx +326 -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/BackgroundPanel.tsx +115 -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 +361 -0
- package/packages/core/src/public/components/panels/SprintPanel.tsx +723 -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 +24 -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/switch.tsx +27 -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 +49 -0
- package/packages/core/src/public/hooks/useAgentLoad.ts +105 -0
- package/packages/core/src/public/hooks/useBackgroundTasks.ts +131 -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 +157 -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/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 +4454 -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/pf/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/__pycache__/context.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-314.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 -1
- package/pennyfarthing-dist/pf/bc/focus.py +0 -1
- package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/__pycache__/portrait_resolver.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__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bikerack/base_panel.py +0 -1
- 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 +21 -0
- package/pennyfarthing-dist/pf/bikerack/sprint_panel.py +58 -1
- package/pennyfarthing-dist/pf/bikerack/tui.py +5 -20
- 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/__pycache__/parser.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/bmad/parser.py +15 -9
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-314.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/pr_config.py +27 -2
- package/pennyfarthing-dist/pf/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/complexity/__pycache__/analyze.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.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-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__/analyze.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-314.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__/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/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-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-314.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-314.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-314.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-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/prime/__pycache__/__init__.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__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-314.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-314.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-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/sprint/story_finish.py +14 -2
- package/pennyfarthing-dist/pf/sprint/validator.py +7 -7
- 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_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing-dist/pf/tests/test_sprint_validator.py +44 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
- package/pennyfarthing-dist/scripts/core/check-context.sh +0 -0
- package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +0 -0
- package/pennyfarthing-dist/scripts/core/pf.sh +0 -0
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
- package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
- package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
- package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +0 -0
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +0 -0
- package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +0 -0
- package/pennyfarthing-dist/scripts/git/release.sh +0 -0
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +0 -0
- package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
- package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
- package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/env.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/find-root.sh +1 -1
- package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
- package/pennyfarthing-dist/scripts/lib/run-pf.sh +0 -0
- package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
- package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
- package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -1
- package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
- package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +13 -13
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
- package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +0 -0
- package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
- package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
- package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
- package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
- package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/check.py +4 -6
- package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/complete-step.py +2 -2
- package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +0 -0
- package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
- package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
- package/pennyfarthing-dist/skills/skill-registry.yaml +19 -0
- package/pennyfarthing-dist/workflows/release/steps/step-10-publish.md +41 -9
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +15 -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/pennyfarthing-dist/pf/bikerack/changed_panel.py +0 -201
- package/scripts/README.md +0 -41
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message Filtering Utilities
|
|
3
|
+
*
|
|
4
|
+
* Story MSSCI-12783 - Bug: Skill Content Displayed as User Message
|
|
5
|
+
*
|
|
6
|
+
* Functions to detect and filter skill content from user messages.
|
|
7
|
+
* Skill content is meant for Claude's context, not for display in the UI.
|
|
8
|
+
* Detected skill invocations are replaced with a short label (e.g. "reviewer")
|
|
9
|
+
* so the user sees what happened without the raw skill dump.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Skill content markers that indicate a message contains skill/command output
|
|
14
|
+
* that should be filtered from user message display.
|
|
15
|
+
*/
|
|
16
|
+
const SKILL_CONTENT_MARKERS = [
|
|
17
|
+
'<command-message>',
|
|
18
|
+
'<command-name>',
|
|
19
|
+
'Base directory for this skill:',
|
|
20
|
+
'Launching skill:',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Patterns that detect skill body content leaked as separate user messages.
|
|
25
|
+
* These are the raw skill markdown bodies that Claude Code sends as user messages
|
|
26
|
+
* after the initial <command-message> wrapper.
|
|
27
|
+
*/
|
|
28
|
+
const SKILL_BODY_PATTERNS = [
|
|
29
|
+
/^```bash\s*\npf agent start\b/, // Agent activation bash block
|
|
30
|
+
/^pf agent start\b/, // Bare agent start command
|
|
31
|
+
/^<purpose>/, // Skill body XML tags
|
|
32
|
+
/^<when-to-use>/,
|
|
33
|
+
/^<execution>/,
|
|
34
|
+
/^<critical>\s*\n/, // Skill body starting with critical block
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Agent name to human-readable label mapping.
|
|
39
|
+
*/
|
|
40
|
+
const AGENT_LABELS: Record<string, string> = {
|
|
41
|
+
sm: 'Scrum Master',
|
|
42
|
+
tea: 'Test Engineer',
|
|
43
|
+
dev: 'Developer',
|
|
44
|
+
reviewer: 'Reviewer',
|
|
45
|
+
architect: 'Architect',
|
|
46
|
+
pm: 'Product Manager',
|
|
47
|
+
'tech-writer': 'Tech Writer',
|
|
48
|
+
'ux-designer': 'UX Designer',
|
|
49
|
+
devops: 'DevOps',
|
|
50
|
+
orchestrator: 'Orchestrator',
|
|
51
|
+
ba: 'Business Analyst',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Check if a message content string contains skill/command content
|
|
56
|
+
* that should be filtered from user message display.
|
|
57
|
+
*
|
|
58
|
+
* @param content - The message content to check
|
|
59
|
+
* @returns true if the content contains skill markers and should be filtered
|
|
60
|
+
*/
|
|
61
|
+
export function isSkillContent(content: string | null | undefined): boolean {
|
|
62
|
+
if (!content || typeof content !== 'string') {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (SKILL_CONTENT_MARKERS.some(marker => content.includes(marker))) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const trimmed = content.trimStart();
|
|
71
|
+
return SKILL_BODY_PATTERNS.some(pattern => pattern.test(trimmed));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Extract the skill/agent name from skill content for labeling.
|
|
76
|
+
* Returns a human-readable label like "Scrum Master" or the raw skill name.
|
|
77
|
+
*/
|
|
78
|
+
export function extractSkillLabel(content: string | null | undefined): string | null {
|
|
79
|
+
if (!content || typeof content !== 'string') return null;
|
|
80
|
+
|
|
81
|
+
// Match <command-name>/foo</command-name>
|
|
82
|
+
const cmdMatch = content.match(/<command-name>\/?([^<]+)<\/command-name>/);
|
|
83
|
+
if (cmdMatch) {
|
|
84
|
+
const name = cmdMatch[1].trim();
|
|
85
|
+
return AGENT_LABELS[name] || name;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Match <command-message>foo</command-message>
|
|
89
|
+
const msgMatch = content.match(/<command-message>([^<]+)<\/command-message>/);
|
|
90
|
+
if (msgMatch) {
|
|
91
|
+
const name = msgMatch[1].trim();
|
|
92
|
+
return AGENT_LABELS[name] || name;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Match pf agent start "foo"
|
|
96
|
+
const agentMatch = content.match(/pf agent start\s+"([^"]+)"/);
|
|
97
|
+
if (agentMatch) {
|
|
98
|
+
const name = agentMatch[1].trim();
|
|
99
|
+
return AGENT_LABELS[name] || name;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Match "Launching skill: foo"
|
|
103
|
+
const launchMatch = content.match(/Launching skill:\s*(\S+)/);
|
|
104
|
+
if (launchMatch) {
|
|
105
|
+
const name = launchMatch[1].trim();
|
|
106
|
+
return AGENT_LABELS[name] || name;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Filter an array of messages to remove skill content from user messages.
|
|
114
|
+
* Only user-type messages are filtered; assistant and tool messages pass through.
|
|
115
|
+
*
|
|
116
|
+
* @param messages - Array of messages to filter
|
|
117
|
+
* @returns Filtered array with skill content user messages removed
|
|
118
|
+
*/
|
|
119
|
+
export function filterSkillContentMessages<T extends { type: string; content?: string }>(
|
|
120
|
+
messages: T[]
|
|
121
|
+
): T[] {
|
|
122
|
+
return messages.filter(msg => {
|
|
123
|
+
if (msg.type !== 'user') {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return !isSkillContent(msg.content);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slash Commands Module
|
|
3
|
+
* Provides command definitions and filtering for tab completion (B-9.5)
|
|
4
|
+
*
|
|
5
|
+
* AUTO-GENERATED - Do not edit manually!
|
|
6
|
+
* Run: npm run build:commands (or npm run build)
|
|
7
|
+
* Source: pennyfarthing-dist/commands/*.md
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Types
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export interface SlashCommand {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type CommandFrequency = Record<string, number>;
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Command Definitions
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Array of available slash commands with name and description
|
|
27
|
+
* Generated from pennyfarthing-dist/commands/ at build time
|
|
28
|
+
* Sorted alphabetically by name
|
|
29
|
+
*/
|
|
30
|
+
export const SLASH_COMMANDS: SlashCommand[] = [
|
|
31
|
+
{
|
|
32
|
+
"name": "/add",
|
|
33
|
+
"description": "Add files to context"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "/bug",
|
|
37
|
+
"description": "Report a bug"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "/clear",
|
|
41
|
+
"description": "Clear conversation history"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "/compact",
|
|
45
|
+
"description": "Toggle compact mode"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "/config",
|
|
49
|
+
"description": "Show configuration"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "/cost",
|
|
53
|
+
"description": "Show session cost"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "/doctor",
|
|
57
|
+
"description": "Check system health"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "/help",
|
|
61
|
+
"description": "Show available commands"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "/init",
|
|
65
|
+
"description": "Initialize CLAUDE.md"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "/login",
|
|
69
|
+
"description": "Authenticate with Anthropic"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "/logout",
|
|
73
|
+
"description": "Clear authentication"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "/memory",
|
|
77
|
+
"description": "Edit CLAUDE.md memory"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "/model",
|
|
81
|
+
"description": "Switch Claude model"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "/permissions",
|
|
85
|
+
"description": "View/edit permissions"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "/pf-architect",
|
|
89
|
+
"description": "System Architect - Technical design and architecture"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "/pf-ba",
|
|
93
|
+
"description": "Business Analyst - Requirements discovery and stakeholder analysis"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "/pf-benchmark",
|
|
97
|
+
"description": "Compare an agent's performance against a stored baseline"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "/pf-benchmark-control",
|
|
101
|
+
"description": "Create control baseline for a scenario (shortcut for /benchmark control <agent>)"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "/pf-brainstorming",
|
|
105
|
+
"description": "Structured problem-solving brainstorm session"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "/pf-check",
|
|
109
|
+
"description": "Run quality gates (lint, type check, tests) before handoff"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "/pf-chore",
|
|
113
|
+
"description": "Quick commit for small changes without full git-cleanup ceremony"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "/pf-ci",
|
|
117
|
+
"description": "Detect and run CI locally"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "/pf-dev",
|
|
121
|
+
"description": "Developer - Feature implementation and coding"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"name": "/pf-devops",
|
|
125
|
+
"description": "DevOps Engineer - Infrastructure and deployment automation"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "/pf-docs",
|
|
129
|
+
"description": "Domain documentation management"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "/pf-epic",
|
|
133
|
+
"description": "Epic lifecycle - start epics for development and close completed epics"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"name": "/pf-fix-blocker",
|
|
137
|
+
"description": "Quick alias for /patch - fix blocking issue during story work"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "/pf-git",
|
|
141
|
+
"description": "Repository operations - status, cleanup, branches, and release management"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"name": "/pf-health-check",
|
|
145
|
+
"description": "Check Pennyfarthing installation health and apply updates"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "/pf-help",
|
|
149
|
+
"description": "Context-aware help for Pennyfarthing commands, agents, and workflows"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "/pf-job-fair",
|
|
153
|
+
"description": "Discover which characters in a theme excel at each role"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "/pf-orchestrator",
|
|
157
|
+
"description": "Orchestrator - Coordinator of all agents and meta operations"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"name": "/pf-party-mode",
|
|
161
|
+
"description": "Creative brainstorming and multi-agent discussion"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"name": "/pf-patch",
|
|
165
|
+
"description": "Interrupt-driven bug fix during active story work"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "/pf-permissions",
|
|
169
|
+
"description": "View and manage runtime permission grants - list, grant, revoke, or show details"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"name": "/pf-pm",
|
|
173
|
+
"description": "Product Manager - Strategic planning and prioritization"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "/pf-prime",
|
|
177
|
+
"description": "Load essential project context at agent activation"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "/pf-retro",
|
|
181
|
+
"description": "Facilitate a sprint retrospective"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"name": "/pf-reviewer",
|
|
185
|
+
"description": "Code Reviewer - Critical code review and quality enforcement"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "/pf-session",
|
|
189
|
+
"description": "Session lifecycle - start new work and resume checkpoints"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "/pf-setup",
|
|
193
|
+
"description": "/setup - Interactive Project Setup"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "/pf-sm",
|
|
197
|
+
"description": "Scrum Master - Story coordination and sprint management"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "/pf-solo",
|
|
201
|
+
"description": "Run a single agent on a scenario with absolute rubric scoring"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "/pf-sprint",
|
|
205
|
+
"description": "Sprint status, backlog, and story management - check status, find work, archive completed stories"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"name": "/pf-standalone",
|
|
209
|
+
"description": "Wrap current changes into a standalone Jira story, branch, PR, and merge"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "/pf-tea",
|
|
213
|
+
"description": "Test Engineer/Architect - Test strategy and TDD"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "/pf-tech-writer",
|
|
217
|
+
"description": "Technical Writer - Documentation creation and maintenance"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "/pf-theme",
|
|
221
|
+
"description": "Manage persona themes - list, show, set, create, or interactive wizard"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"name": "/pf-ux-designer",
|
|
225
|
+
"description": "UX Designer - User experience design and UI patterns"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "/pf-work",
|
|
229
|
+
"description": "Resume work or start new - smart entry point that picks up where you left off"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"name": "/pf-workflow",
|
|
233
|
+
"description": "List available workflows, show current workflow details, and switch workflows mid-session. Use when checking available workflow types (TDD, trivial, agent-docs), viewing current workflow phase, switching to a different workflow pattern, or managing BikeLane stepped workflows."
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"name": "/pr-comments",
|
|
237
|
+
"description": "View PR comments"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"name": "/review",
|
|
241
|
+
"description": "Start code review"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"name": "/status",
|
|
245
|
+
"description": "Show session status"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"name": "/terminal-setup",
|
|
249
|
+
"description": "Configure terminal"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"name": "/vim",
|
|
253
|
+
"description": "Toggle vim mode"
|
|
254
|
+
}
|
|
255
|
+
].sort((a, b) => a.name.localeCompare(b.name));
|
|
256
|
+
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Command Frequency Tracking (localStorage)
|
|
259
|
+
// ============================================================================
|
|
260
|
+
|
|
261
|
+
const COMMAND_FREQUENCY_KEY = 'cyclist:command-frequency';
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Get command usage frequency map from localStorage
|
|
265
|
+
*/
|
|
266
|
+
export function getCommandFrequency(): CommandFrequency {
|
|
267
|
+
if (typeof localStorage === 'undefined') return {};
|
|
268
|
+
try {
|
|
269
|
+
const stored = localStorage.getItem(COMMAND_FREQUENCY_KEY);
|
|
270
|
+
return stored ? JSON.parse(stored) : {};
|
|
271
|
+
} catch {
|
|
272
|
+
return {};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Track command usage - increment frequency counter
|
|
278
|
+
*/
|
|
279
|
+
export function trackCommandUsage(commandName: string): void {
|
|
280
|
+
if (typeof localStorage === 'undefined') return;
|
|
281
|
+
const freq = getCommandFrequency();
|
|
282
|
+
freq[commandName] = (freq[commandName] || 0) + 1;
|
|
283
|
+
localStorage.setItem(COMMAND_FREQUENCY_KEY, JSON.stringify(freq));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Clear command frequency data
|
|
288
|
+
*/
|
|
289
|
+
export function clearCommandFrequency(): void {
|
|
290
|
+
if (typeof localStorage === 'undefined') return;
|
|
291
|
+
localStorage.removeItem(COMMAND_FREQUENCY_KEY);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ============================================================================
|
|
295
|
+
// Filtering Functions
|
|
296
|
+
// ============================================================================
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Filter commands by prefix (case-insensitive)
|
|
300
|
+
* Sorted by usage frequency (most used first), then alphabetically
|
|
301
|
+
*/
|
|
302
|
+
export function filterCommands(prefix: string): SlashCommand[] {
|
|
303
|
+
const search = prefix.toLowerCase();
|
|
304
|
+
const freq = getCommandFrequency();
|
|
305
|
+
|
|
306
|
+
return SLASH_COMMANDS
|
|
307
|
+
.filter(cmd => cmd.name.toLowerCase().startsWith(search))
|
|
308
|
+
.sort((a, b) => {
|
|
309
|
+
const freqA = freq[a.name] || 0;
|
|
310
|
+
const freqB = freq[b.name] || 0;
|
|
311
|
+
// Sort by frequency descending, then alphabetically
|
|
312
|
+
if (freqB !== freqA) return freqB - freqA;
|
|
313
|
+
return a.name.localeCompare(b.name);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Trigger Detection
|
|
319
|
+
// ============================================================================
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Check if position in text is a valid completion trigger
|
|
323
|
+
* Valid triggers: "/" at start of line or after whitespace
|
|
324
|
+
*/
|
|
325
|
+
export function isCompletionTrigger(text: string, position: number): boolean {
|
|
326
|
+
// Support both: position AT the "/" or position AFTER the "/"
|
|
327
|
+
let slashPos = position;
|
|
328
|
+
if (text[position] !== '/') {
|
|
329
|
+
slashPos = position - 1;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// "/" must be at slashPos
|
|
333
|
+
if (slashPos < 0 || text[slashPos] !== '/') return false;
|
|
334
|
+
|
|
335
|
+
// Valid at start of text
|
|
336
|
+
if (slashPos === 0) return true;
|
|
337
|
+
|
|
338
|
+
// Valid after whitespace
|
|
339
|
+
const charBefore = text[slashPos - 1];
|
|
340
|
+
return charBefore === ' ' || charBefore === '\n' || charBefore === '\t';
|
|
341
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent Display Module
|
|
3
|
+
*
|
|
4
|
+
* Theme-aware subagent message display utilities.
|
|
5
|
+
* Story MSSCI-12776 - Theme-Aware Subagent Display Messages
|
|
6
|
+
*
|
|
7
|
+
* Transforms raw subagent prompts into friendly, themed messages
|
|
8
|
+
* using the current agent's Helper persona from the theme.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Types
|
|
12
|
+
export interface TaskInput {
|
|
13
|
+
prompt?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
subagent_type?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Helper {
|
|
19
|
+
name: string;
|
|
20
|
+
style: string;
|
|
21
|
+
plural?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Cache for helper lookups
|
|
25
|
+
const helperCache = new Map<string, Helper>();
|
|
26
|
+
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// AC1: Parse subagent type from Task tool invocation
|
|
29
|
+
// =============================================================================
|
|
30
|
+
|
|
31
|
+
export function parseSubagentType(input: TaskInput): string | null {
|
|
32
|
+
return input.subagent_type ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function parseSubagentDescription(input: TaskInput): string | null {
|
|
36
|
+
return input.description ?? null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// AC2: Look up current agent's helper persona from theme
|
|
41
|
+
// =============================================================================
|
|
42
|
+
|
|
43
|
+
// Theme data cache
|
|
44
|
+
let themeDataCache: { agents: Array<{ role: string; helper?: Helper }> } | null = null;
|
|
45
|
+
|
|
46
|
+
async function loadThemeData(): Promise<void> {
|
|
47
|
+
if (themeDataCache) return;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch('/api/theme-agents/full');
|
|
51
|
+
if (response.ok) {
|
|
52
|
+
themeDataCache = await response.json();
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
// Ignore errors, cache stays null
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function getAgentHelper(agentRole: string): Promise<Helper | null> {
|
|
60
|
+
// Check cache first
|
|
61
|
+
const cacheKey = `agent:${agentRole}`;
|
|
62
|
+
if (helperCache.has(cacheKey)) {
|
|
63
|
+
return helperCache.get(cacheKey)!;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// Load theme data if not cached
|
|
68
|
+
await loadThemeData();
|
|
69
|
+
|
|
70
|
+
if (themeDataCache?.agents) {
|
|
71
|
+
const agent = themeDataCache.agents.find(a => a.role === agentRole);
|
|
72
|
+
if (agent?.helper) {
|
|
73
|
+
helperCache.set(cacheKey, agent.helper);
|
|
74
|
+
return agent.helper;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function getSubagentHelper(subagentType: string): Promise<Helper | null> {
|
|
84
|
+
// Check cache first
|
|
85
|
+
const cacheKey = `subagent:${subagentType}`;
|
|
86
|
+
if (helperCache.has(cacheKey)) {
|
|
87
|
+
return helperCache.get(cacheKey)!;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Load theme data if not cached
|
|
92
|
+
await loadThemeData();
|
|
93
|
+
|
|
94
|
+
// Subagent helpers may be defined differently - for now just return null
|
|
95
|
+
// The theme data structure may need to be extended to support this
|
|
96
|
+
return null;
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function clearHelperCache(): void {
|
|
103
|
+
helperCache.clear();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// AC3: Generate friendly message from subagent context
|
|
108
|
+
// =============================================================================
|
|
109
|
+
|
|
110
|
+
// Mapping of subagent types to human-friendly action descriptions
|
|
111
|
+
const SUBAGENT_TYPE_MESSAGES: Record<string, string> = {
|
|
112
|
+
'testing-runner': 'Running tests',
|
|
113
|
+
'Explore': 'Exploring codebase',
|
|
114
|
+
'sm-setup': 'Setting up story',
|
|
115
|
+
'sm-finish': 'Finishing story',
|
|
116
|
+
'handoff': 'Handing off',
|
|
117
|
+
'workflow-status-check': 'Checking workflow status',
|
|
118
|
+
'general-purpose': 'Processing task',
|
|
119
|
+
'Plan': 'Planning implementation',
|
|
120
|
+
'Bash': 'Running commands',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export function generateFriendlyMessage(context: TaskInput, options?: { plural?: boolean }): string {
|
|
124
|
+
const verb = options?.plural ? 'are' : 'is';
|
|
125
|
+
// If we have a description, include it
|
|
126
|
+
const description = context.description;
|
|
127
|
+
|
|
128
|
+
// If we have a known subagent type, use its friendly message
|
|
129
|
+
const subagentType = context.subagent_type;
|
|
130
|
+
if (subagentType && SUBAGENT_TYPE_MESSAGES[subagentType]) {
|
|
131
|
+
const action = SUBAGENT_TYPE_MESSAGES[subagentType];
|
|
132
|
+
const lowerAction = action.charAt(0).toLowerCase() + action.slice(1);
|
|
133
|
+
if (description) {
|
|
134
|
+
return `${verb} ${lowerAction}: ${description}`;
|
|
135
|
+
}
|
|
136
|
+
return `${verb} ${lowerAction}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Fall back to description if available
|
|
140
|
+
if (description) {
|
|
141
|
+
return description;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Default fallback
|
|
145
|
+
return 'Working...';
|
|
146
|
+
}
|