@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.
Files changed (405) hide show
  1. package/README.md +1 -1
  2. package/package.json +17 -16
  3. package/packages/core/dist/public/css/react.css +1 -1
  4. package/packages/core/dist/public/js/react/react.js +24 -24
  5. package/packages/core/src/public/App.tsx +356 -0
  6. package/packages/core/src/public/components/AgentLoadDialog.tsx +202 -0
  7. package/packages/core/src/public/components/AgentPopup.tsx +308 -0
  8. package/packages/core/src/public/components/ApprovalModal/ApprovalModal.css +35 -0
  9. package/packages/core/src/public/components/ApprovalModal/index.tsx +632 -0
  10. package/packages/core/src/public/components/BikeRackIndex.tsx +53 -0
  11. package/packages/core/src/public/components/BikeRackWorkspace.tsx +217 -0
  12. package/packages/core/src/public/components/CommandPalette.tsx +554 -0
  13. package/packages/core/src/public/components/ConfirmDialog.tsx +168 -0
  14. package/packages/core/src/public/components/ContextIndicator/ContextIndicator.css +85 -0
  15. package/packages/core/src/public/components/ContextIndicator/index.tsx +330 -0
  16. package/packages/core/src/public/components/ContextSparkline.tsx +56 -0
  17. package/packages/core/src/public/components/ControlBar.tsx +636 -0
  18. package/packages/core/src/public/components/DeadCodeDialog.tsx +169 -0
  19. package/packages/core/src/public/components/DiffViewer.tsx +585 -0
  20. package/packages/core/src/public/components/DockviewWorkspace.tsx +749 -0
  21. package/packages/core/src/public/components/Editor.tsx +630 -0
  22. package/packages/core/src/public/components/ErrorBoundary.tsx +67 -0
  23. package/packages/core/src/public/components/FileTree.tsx +379 -0
  24. package/packages/core/src/public/components/FontPicker/FontPicker.css +276 -0
  25. package/packages/core/src/public/components/FontPicker/index.tsx +430 -0
  26. package/packages/core/src/public/components/FullFileTree.tsx +237 -0
  27. package/packages/core/src/public/components/HealthGauge.tsx +181 -0
  28. package/packages/core/src/public/components/Message.tsx +225 -0
  29. package/packages/core/src/public/components/MessageList.tsx +98 -0
  30. package/packages/core/src/public/components/MessageView.tsx +400 -0
  31. package/packages/core/src/public/components/ModeSwitch/ModeSwitch.css +165 -0
  32. package/packages/core/src/public/components/ModeSwitch/index.tsx +372 -0
  33. package/packages/core/src/public/components/PersonaHeader.tsx +242 -0
  34. package/packages/core/src/public/components/ProjectInfoBar.tsx +45 -0
  35. package/packages/core/src/public/components/QuickActions.tsx +267 -0
  36. package/packages/core/src/public/components/SpanTimeline.tsx +352 -0
  37. package/packages/core/src/public/components/StandalonePanel.tsx +82 -0
  38. package/packages/core/src/public/components/StatsStrip.tsx +162 -0
  39. package/packages/core/src/public/components/StreamingContent.tsx +77 -0
  40. package/packages/core/src/public/components/SubagentSpan.tsx +180 -0
  41. package/packages/core/src/public/components/TandemPortrait.tsx +72 -0
  42. package/packages/core/src/public/components/ThemePalette/ThemePalette.css +179 -0
  43. package/packages/core/src/public/components/ThemePalette/index.tsx +326 -0
  44. package/packages/core/src/public/components/ToolCallBlock.tsx +252 -0
  45. package/packages/core/src/public/components/ToolStack.tsx +209 -0
  46. package/packages/core/src/public/components/ToolStatus.tsx +57 -0
  47. package/packages/core/src/public/components/dialogs/CodeMarkersDialog.tsx +169 -0
  48. package/packages/core/src/public/components/dialogs/ComplexityDialog.tsx +163 -0
  49. package/packages/core/src/public/components/dialogs/DependenciesDialog.tsx +120 -0
  50. package/packages/core/src/public/components/dialogs/HotspotsDialog.tsx +451 -0
  51. package/packages/core/src/public/components/dialogs/ToolDialog.tsx +43 -0
  52. package/packages/core/src/public/components/panel-registry.ts +13 -0
  53. package/packages/core/src/public/components/panels/ACPanel.tsx +93 -0
  54. package/packages/core/src/public/components/panels/AcceptanceCriteriaPanel.tsx +104 -0
  55. package/packages/core/src/public/components/panels/AuditLogPanel.tsx +489 -0
  56. package/packages/core/src/public/components/panels/BackgroundPanel.tsx +115 -0
  57. package/packages/core/src/public/components/panels/BikeLanePanel.tsx +214 -0
  58. package/packages/core/src/public/components/panels/DebugPanel.tsx +344 -0
  59. package/packages/core/src/public/components/panels/DiffView.tsx +109 -0
  60. package/packages/core/src/public/components/panels/DiffsPanel.tsx +56 -0
  61. package/packages/core/src/public/components/panels/GitPanel.tsx +260 -0
  62. package/packages/core/src/public/components/panels/HotspotsPanel.tsx +365 -0
  63. package/packages/core/src/public/components/panels/MessageFeed.tsx +39 -0
  64. package/packages/core/src/public/components/panels/MessagePanel.tsx +497 -0
  65. package/packages/core/src/public/components/panels/ProgressPanel.tsx +189 -0
  66. package/packages/core/src/public/components/panels/SettingsPanel.tsx +361 -0
  67. package/packages/core/src/public/components/panels/SprintPanel.tsx +723 -0
  68. package/packages/core/src/public/components/panels/TandemPanel.tsx +104 -0
  69. package/packages/core/src/public/components/panels/TaskTracker.tsx +48 -0
  70. package/packages/core/src/public/components/panels/TeamPanel.tsx +64 -0
  71. package/packages/core/src/public/components/panels/TeamRoster.tsx +67 -0
  72. package/packages/core/src/public/components/panels/TodoPanel.tsx +142 -0
  73. package/packages/core/src/public/components/panels/WorkflowPanel.tsx +224 -0
  74. package/packages/core/src/public/components/panels/index.ts +24 -0
  75. package/packages/core/src/public/components/ui/alert-dialog.tsx +139 -0
  76. package/packages/core/src/public/components/ui/badge.tsx +36 -0
  77. package/packages/core/src/public/components/ui/button.tsx +57 -0
  78. package/packages/core/src/public/components/ui/checkbox.tsx +28 -0
  79. package/packages/core/src/public/components/ui/collapsible.tsx +9 -0
  80. package/packages/core/src/public/components/ui/command.tsx +151 -0
  81. package/packages/core/src/public/components/ui/dialog.tsx +120 -0
  82. package/packages/core/src/public/components/ui/popover.tsx +31 -0
  83. package/packages/core/src/public/components/ui/progress.tsx +28 -0
  84. package/packages/core/src/public/components/ui/scroll-area.tsx +46 -0
  85. package/packages/core/src/public/components/ui/select.tsx +157 -0
  86. package/packages/core/src/public/components/ui/separator.tsx +29 -0
  87. package/packages/core/src/public/components/ui/skeleton.tsx +15 -0
  88. package/packages/core/src/public/components/ui/switch.tsx +27 -0
  89. package/packages/core/src/public/components/ui/toggle-group.tsx +59 -0
  90. package/packages/core/src/public/components/ui/toggle.tsx +43 -0
  91. package/packages/core/src/public/components/ui/tooltip.tsx +30 -0
  92. package/packages/core/src/public/contexts/ClaudeContext.tsx +311 -0
  93. package/packages/core/src/public/contexts/MessageQueueContext.tsx +143 -0
  94. package/packages/core/src/public/css/theme-browser.css +550 -0
  95. package/packages/core/src/public/css/theme-system.css +630 -0
  96. package/packages/core/src/public/hooks/index.ts +49 -0
  97. package/packages/core/src/public/hooks/useAgentLoad.ts +105 -0
  98. package/packages/core/src/public/hooks/useBackgroundTasks.ts +131 -0
  99. package/packages/core/src/public/hooks/useClaude.ts +234 -0
  100. package/packages/core/src/public/hooks/useCodeMarkers.ts +101 -0
  101. package/packages/core/src/public/hooks/useColorScheme.ts +42 -0
  102. package/packages/core/src/public/hooks/useCommandHistory.ts +99 -0
  103. package/packages/core/src/public/hooks/useComplexity.ts +80 -0
  104. package/packages/core/src/public/hooks/useDeadCode.ts +99 -0
  105. package/packages/core/src/public/hooks/useDependencies.ts +82 -0
  106. package/packages/core/src/public/hooks/useDiffs.ts +143 -0
  107. package/packages/core/src/public/hooks/useFileBrowser.ts +73 -0
  108. package/packages/core/src/public/hooks/useFocusPanel.ts +137 -0
  109. package/packages/core/src/public/hooks/useGitStatus.ts +233 -0
  110. package/packages/core/src/public/hooks/useHealthScore.ts +71 -0
  111. package/packages/core/src/public/hooks/useHotspots.ts +123 -0
  112. package/packages/core/src/public/hooks/useLayoutPersistence.ts +141 -0
  113. package/packages/core/src/public/hooks/useMarkdownParser.ts +36 -0
  114. package/packages/core/src/public/hooks/useMarkerActions.ts +234 -0
  115. package/packages/core/src/public/hooks/useMessageQueue.ts +380 -0
  116. package/packages/core/src/public/hooks/useMessageStream.ts +131 -0
  117. package/packages/core/src/public/hooks/usePersona.ts +112 -0
  118. package/packages/core/src/public/hooks/usePlanModeExit.ts +105 -0
  119. package/packages/core/src/public/hooks/useResponsiveLayout.ts +173 -0
  120. package/packages/core/src/public/hooks/useSprint.ts +157 -0
  121. package/packages/core/src/public/hooks/useStatsStrip.ts +204 -0
  122. package/packages/core/src/public/hooks/useStory.ts +135 -0
  123. package/packages/core/src/public/hooks/useSubagentHelper.ts +64 -0
  124. package/packages/core/src/public/hooks/useSyntaxHighlighter.ts +52 -0
  125. package/packages/core/src/public/hooks/useTabCompletion.ts +124 -0
  126. package/packages/core/src/public/hooks/useTandemObservations.ts +165 -0
  127. package/packages/core/src/public/hooks/useTeamMembers.ts +273 -0
  128. package/packages/core/src/public/hooks/useTodos.ts +93 -0
  129. package/packages/core/src/public/hooks/useUserAvatar.ts +54 -0
  130. package/packages/core/src/public/images/cyclist-dark.png +0 -0
  131. package/packages/core/src/public/images/cyclist-light.png +0 -0
  132. package/packages/core/src/public/index.html +14 -0
  133. package/packages/core/src/public/index.tsx +10 -0
  134. package/packages/core/src/public/lib/utils.ts +6 -0
  135. package/packages/core/src/public/styles/dockview-theme.css +376 -0
  136. package/packages/core/src/public/styles/tailwind.css +4454 -0
  137. package/packages/core/src/public/types/message.ts +51 -0
  138. package/packages/core/src/public/utils/avatar-service.ts +73 -0
  139. package/packages/core/src/public/utils/color-presets.ts +940 -0
  140. package/packages/core/src/public/utils/font-presets.ts +362 -0
  141. package/packages/core/src/public/utils/formatDuration.ts +14 -0
  142. package/packages/core/src/public/utils/markdown.ts +249 -0
  143. package/packages/core/src/public/utils/messageFilters.ts +128 -0
  144. package/packages/core/src/public/utils/slash-commands.ts +341 -0
  145. package/packages/core/src/public/utils/subagent-display.ts +146 -0
  146. package/packages/core/src/public/utils/syntax.ts +219 -0
  147. package/packages/core/src/public/utils/toolIntentSummarizer.ts +199 -0
  148. package/packages/core/src/public/utils/toolStackGrouper.ts +106 -0
  149. package/packages/core/src/public/utils/toolTypeColors.ts +45 -0
  150. package/pennyfarthing-dist/pf/__pycache__/__init__.cpython-314.pyc +0 -0
  151. package/pennyfarthing-dist/pf/__pycache__/cli.cpython-314.pyc +0 -0
  152. package/pennyfarthing-dist/pf/__pycache__/context.cpython-314.pyc +0 -0
  153. package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-314.pyc +0 -0
  154. package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-314.pyc +0 -0
  155. package/pennyfarthing-dist/pf/bc/__pycache__/focus.cpython-314.pyc +0 -0
  156. package/pennyfarthing-dist/pf/bc/__pycache__/split.cpython-314.pyc +0 -0
  157. package/pennyfarthing-dist/pf/bc/cli.py +0 -1
  158. package/pennyfarthing-dist/pf/bc/focus.py +0 -1
  159. package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
  160. package/pennyfarthing-dist/pf/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  161. package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  162. package/pennyfarthing-dist/pf/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  163. package/pennyfarthing-dist/pf/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  164. package/pennyfarthing-dist/pf/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
  165. package/pennyfarthing-dist/pf/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  166. package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
  167. package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
  168. package/pennyfarthing-dist/pf/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  169. package/pennyfarthing-dist/pf/bikerack/base_panel.py +0 -1
  170. package/pennyfarthing-dist/pf/bikerack/events.py +1 -7
  171. package/pennyfarthing-dist/pf/bikerack/git_panel.py +273 -10
  172. package/pennyfarthing-dist/pf/bikerack/portrait_resolver.py +21 -0
  173. package/pennyfarthing-dist/pf/bikerack/sprint_panel.py +58 -1
  174. package/pennyfarthing-dist/pf/bikerack/tui.py +5 -20
  175. package/pennyfarthing-dist/pf/bmad/__pycache__/__init__.cpython-314.pyc +0 -0
  176. package/pennyfarthing-dist/pf/bmad/__pycache__/cli.cpython-314.pyc +0 -0
  177. package/pennyfarthing-dist/pf/bmad/__pycache__/parser.cpython-314.pyc +0 -0
  178. package/pennyfarthing-dist/pf/bmad/parser.py +15 -9
  179. package/pennyfarthing-dist/pf/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  180. package/pennyfarthing-dist/pf/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  181. package/pennyfarthing-dist/pf/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  182. package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-314.pyc +0 -0
  183. package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-314.pyc +0 -0
  184. package/pennyfarthing-dist/pf/common/__pycache__/output.cpython-314.pyc +0 -0
  185. package/pennyfarthing-dist/pf/common/__pycache__/pr_config.cpython-314.pyc +0 -0
  186. package/pennyfarthing-dist/pf/common/__pycache__/themes.cpython-314.pyc +0 -0
  187. package/pennyfarthing-dist/pf/common/pr_config.py +27 -2
  188. package/pennyfarthing-dist/pf/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  189. package/pennyfarthing-dist/pf/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  190. package/pennyfarthing-dist/pf/complexity/__pycache__/models.cpython-314.pyc +0 -0
  191. package/pennyfarthing-dist/pf/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  192. package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  193. package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  194. package/pennyfarthing-dist/pf/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  195. package/pennyfarthing-dist/pf/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  196. package/pennyfarthing-dist/pf/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  197. package/pennyfarthing-dist/pf/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  198. package/pennyfarthing-dist/pf/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  199. package/pennyfarthing-dist/pf/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  200. package/pennyfarthing-dist/pf/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  201. package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-314.pyc +0 -0
  202. package/pennyfarthing-dist/pf/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  203. package/pennyfarthing-dist/pf/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  204. package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  205. package/pennyfarthing-dist/pf/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  206. package/pennyfarthing-dist/pf/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  207. package/pennyfarthing-dist/pf/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  208. package/pennyfarthing-dist/pf/handoff/__pycache__/phase_check.cpython-314.pyc +0 -0
  209. package/pennyfarthing-dist/pf/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  210. package/pennyfarthing-dist/pf/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  211. package/pennyfarthing-dist/pf/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  212. package/pennyfarthing-dist/pf/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  213. package/pennyfarthing-dist/pf/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  214. package/pennyfarthing-dist/pf/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  215. package/pennyfarthing-dist/pf/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  216. package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  217. package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
  218. package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing-dist/pf/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
  220. package/pennyfarthing-dist/pf/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
  221. package/pennyfarthing-dist/pf/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
  222. package/pennyfarthing-dist/pf/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
  223. package/pennyfarthing-dist/pf/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
  224. package/pennyfarthing-dist/pf/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
  225. package/pennyfarthing-dist/pf/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
  226. package/pennyfarthing-dist/pf/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
  227. package/pennyfarthing-dist/pf/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
  228. package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
  229. package/pennyfarthing-dist/pf/hooks/cyclist-pretooluse-hook.sh +0 -0
  230. package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  231. package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  232. package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  233. package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  234. package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  235. package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  236. package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-314.pyc +0 -0
  237. package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-314.pyc +0 -0
  238. package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-314.pyc +0 -0
  239. package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-314.pyc +0 -0
  240. package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-314.pyc +0 -0
  241. package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-314.pyc +0 -0
  242. package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  243. package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-314.pyc +0 -0
  244. package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-314.pyc +0 -0
  245. package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-314.pyc +0 -0
  246. package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-314.pyc +0 -0
  247. package/pennyfarthing-dist/pf/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  248. package/pennyfarthing-dist/pf/prime/__pycache__/cli.cpython-314.pyc +0 -0
  249. package/pennyfarthing-dist/pf/prime/__pycache__/loader.cpython-314.pyc +0 -0
  250. package/pennyfarthing-dist/pf/prime/__pycache__/models.cpython-314.pyc +0 -0
  251. package/pennyfarthing-dist/pf/prime/__pycache__/persona.cpython-314.pyc +0 -0
  252. package/pennyfarthing-dist/pf/prime/__pycache__/session.cpython-314.pyc +0 -0
  253. package/pennyfarthing-dist/pf/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  254. package/pennyfarthing-dist/pf/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  255. package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-314.pyc +0 -0
  256. package/pennyfarthing-dist/pf/session/__pycache__/cli.cpython-314.pyc +0 -0
  257. package/pennyfarthing-dist/pf/settings/__pycache__/__init__.cpython-314.pyc +0 -0
  258. package/pennyfarthing-dist/pf/settings/__pycache__/cli.cpython-314.pyc +0 -0
  259. package/pennyfarthing-dist/pf/settings/__pycache__/settings.cpython-314.pyc +0 -0
  260. package/pennyfarthing-dist/pf/settings/settings.py +44 -8
  261. package/pennyfarthing-dist/pf/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  262. package/pennyfarthing-dist/pf/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  263. package/pennyfarthing-dist/pf/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  264. package/pennyfarthing-dist/pf/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  265. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  266. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
  267. package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  268. package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-314.pyc +0 -0
  269. package/pennyfarthing-dist/pf/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  270. package/pennyfarthing-dist/pf/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  271. package/pennyfarthing-dist/pf/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  272. package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  273. package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  274. package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-314.pyc +0 -0
  275. package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  276. package/pennyfarthing-dist/pf/sprint/story_finish.py +14 -2
  277. package/pennyfarthing-dist/pf/sprint/validator.py +7 -7
  278. package/pennyfarthing-dist/pf/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  279. package/pennyfarthing-dist/pf/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  280. package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  281. package/pennyfarthing-dist/pf/tests/test_sprint_validator.py +44 -0
  282. package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  283. package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-314.pyc +0 -0
  284. package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  285. package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-314.pyc +0 -0
  286. package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  287. package/pennyfarthing-dist/pf/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  288. package/pennyfarthing-dist/pf/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  289. package/pennyfarthing-dist/pf/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  290. package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-314.pyc +0 -0
  291. package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
  292. package/pennyfarthing-dist/scripts/core/check-context.sh +0 -0
  293. package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +0 -0
  294. package/pennyfarthing-dist/scripts/core/pf.sh +0 -0
  295. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  296. package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
  297. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  298. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +0 -0
  299. package/pennyfarthing-dist/scripts/git/git-status-all.sh +0 -0
  300. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +0 -0
  301. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  302. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +0 -0
  303. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  304. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +0 -0
  305. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  306. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  307. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  308. package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
  309. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +0 -0
  310. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
  311. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
  312. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  313. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
  314. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  315. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  316. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  317. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  318. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  319. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  320. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +0 -0
  321. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
  322. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
  323. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  324. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
  325. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  326. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  327. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  328. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  329. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  330. package/pennyfarthing-dist/scripts/lib/env.sh +0 -0
  331. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  332. package/pennyfarthing-dist/scripts/lib/find-root.sh +1 -1
  333. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  334. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  335. package/pennyfarthing-dist/scripts/lib/run-pf.sh +0 -0
  336. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  337. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  338. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  339. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  340. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  341. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  342. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  343. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  344. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  345. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  346. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -1
  347. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  348. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  349. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  350. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  351. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  352. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  353. package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
  354. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  355. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
  356. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +13 -13
  357. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  358. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +0 -0
  359. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  360. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  361. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  362. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  363. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  364. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  365. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
  366. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  367. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  368. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  369. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  370. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  371. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
  372. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  373. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  374. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  375. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  376. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  377. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
  378. package/pennyfarthing-dist/scripts/workflow/check.py +4 -6
  379. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  380. package/pennyfarthing-dist/scripts/workflow/complete-step.py +2 -2
  381. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
  382. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +0 -0
  383. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  384. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +0 -0
  385. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +0 -0
  386. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +0 -0
  387. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +0 -0
  388. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +0 -0
  389. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +0 -0
  390. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +0 -0
  391. package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
  392. package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
  393. package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
  394. package/pennyfarthing-dist/skills/skill-registry.yaml +19 -0
  395. package/pennyfarthing-dist/workflows/release/steps/step-10-publish.md +41 -9
  396. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +15 -2
  397. package/packages/core/dist/workflow/__test_context_watch__/.session/.tandem-turn-counter +0 -1
  398. package/packages/core/dist/workflow/__test_context_watch__/.session/95-6-session.md +0 -3
  399. package/packages/core/dist/workflow/__test_context_watch__/.session/95-6-tandem-architect.md +0 -6
  400. package/packages/core/dist/workflow/__test_file_watch__/.session/95-4-tandem-architect.md +0 -6
  401. package/packages/core/dist/workflow/__test_file_watch__/workdir/trigger.ts +0 -1
  402. package/packages/core/dist/workflow/__test_tool_watch__/.session/95-5-tandem-architect.md +0 -6
  403. package/packages/core/dist/workflow/__test_tool_watch__/.session/95-5-tandem-toolcalls.jsonl +0 -1
  404. package/pennyfarthing-dist/pf/bikerack/changed_panel.py +0 -201
  405. package/scripts/README.md +0 -41
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -21,8 +21,8 @@ import argparse
21
21
  import os
22
22
  import sys
23
23
  import warnings
24
- from pathlib import Path
25
24
  from datetime import datetime
25
+ from pathlib import Path
26
26
 
27
27
  # Suppress progress bars before importing torch/diffusers
28
28
  os.environ["TQDM_DISABLE"] = "1"
@@ -38,7 +38,7 @@ except ImportError:
38
38
 
39
39
  try:
40
40
  import torch
41
- from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler
41
+ from diffusers import DPMSolverMultistepScheduler, StableDiffusionXLPipeline
42
42
  from diffusers.utils import logging as diffusers_logging
43
43
  from PIL import Image
44
44
  HAS_TORCH = True
@@ -188,7 +188,7 @@ def generate_portrait_filename(short_name: str, ocean: dict) -> str:
188
188
 
189
189
  def parse_theme_file(theme_path: Path) -> dict:
190
190
  """Parse theme YAML file to extract visual prompts for each agent."""
191
- with open(theme_path, "r", encoding="utf-8") as f:
191
+ with open(theme_path, encoding="utf-8") as f:
192
192
  data = yaml.safe_load(f)
193
193
 
194
194
  theme_metadata = data.get("theme", {})
@@ -310,7 +310,7 @@ def load_pipeline(engine_name: str):
310
310
  }
311
311
  else:
312
312
  model_id = engine["model_id"]
313
- print(f"\nLoading SDXL model on MPS...")
313
+ print("\nLoading SDXL model on MPS...")
314
314
  print(f" Model: {model_id}")
315
315
  print(" (First run downloads ~6.5GB model)")
316
316
 
@@ -369,14 +369,14 @@ def generate_portrait(pipeline_components: dict, prompt: str, engine_name: str,
369
369
  pipe = pipeline_components["pipe"]
370
370
  generator = torch.Generator().manual_seed(seed)
371
371
 
372
- kwargs = dict(
373
- prompt=prompt,
374
- width=gen_size,
375
- height=gen_size,
376
- num_inference_steps=engine["num_inference_steps"],
377
- guidance_scale=engine["guidance_scale"],
378
- generator=generator,
379
- )
372
+ kwargs = {
373
+ "prompt": prompt,
374
+ "width": gen_size,
375
+ "height": gen_size,
376
+ "num_inference_steps": engine["num_inference_steps"],
377
+ "guidance_scale": engine["guidance_scale"],
378
+ "generator": generator,
379
+ }
380
380
  if engine["supports_negative_prompt"]:
381
381
  kwargs["negative_prompt"] = "color, grayscale, photorealistic, blurry, deformed"
382
382
 
@@ -445,7 +445,7 @@ def main():
445
445
  print(f" Searched: {CUSTOM_THEMES_DIR}")
446
446
  sys.exit(1)
447
447
 
448
- print(f"Theme sources:")
448
+ print("Theme sources:")
449
449
  print(f" Built-in: {BUILTIN_THEMES_DIR}")
450
450
  for src in pkg_sources:
451
451
  print(f" Package: {src}")
File without changes
File without changes
File without changes
File without changes
@@ -22,13 +22,11 @@ Returns exit code 0 on all passing, non-zero on any failure.
22
22
  import argparse
23
23
  import asyncio
24
24
  import json
25
- import os
26
25
  import shutil
27
26
  import sys
28
27
  from dataclasses import dataclass, field
29
28
  from enum import Enum
30
29
  from pathlib import Path
31
- from typing import Optional
32
30
 
33
31
 
34
32
  class CheckStatus(Enum):
@@ -41,8 +39,8 @@ class CheckStatus(Enum):
41
39
  class CheckResult:
42
40
  name: str
43
41
  status: CheckStatus
44
- command: Optional[str] = None
45
- message: Optional[str] = None
42
+ command: str | None = None
43
+ message: str | None = None
46
44
 
47
45
 
48
46
  @dataclass
@@ -105,12 +103,12 @@ class Colors:
105
103
  COLORS = Colors()
106
104
 
107
105
 
108
- def print_pass(name: str, command: Optional[str] = None) -> None:
106
+ def print_pass(name: str, command: str | None = None) -> None:
109
107
  suffix = f" ({command})" if command else ""
110
108
  print(f" {COLORS.GREEN}[PASS]{COLORS.NC} {name}{suffix}")
111
109
 
112
110
 
113
- def print_fail(name: str, command: Optional[str] = None) -> None:
111
+ def print_fail(name: str, command: str | None = None) -> None:
114
112
  suffix = f" ({command})" if command else ""
115
113
  print(f" {COLORS.RED}[FAIL]{COLORS.NC} {name}{suffix}")
116
114
 
File without changes
@@ -15,7 +15,7 @@ If --step N provided, completes that specific step instead of current step.
15
15
  import argparse
16
16
  import re
17
17
  import sys
18
- from datetime import datetime, timezone
18
+ from datetime import UTC, datetime
19
19
  from pathlib import Path
20
20
 
21
21
  try:
@@ -231,7 +231,7 @@ def main() -> int:
231
231
  new_status = "completed" if completed_count >= step_count else "in_progress"
232
232
 
233
233
  # Update timestamp
234
- now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
234
+ now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
235
235
 
236
236
  # Update session file content
237
237
  content = re.sub(
@@ -23,6 +23,25 @@ skills:
23
23
  keywords: [react, reflection, planning, tool-use, chain-of-thought]
24
24
  allowed_tools: [Read, Glob, Grep, Task] # Reference material - read-only
25
25
 
26
+ pf-bc:
27
+ name: pf-bc
28
+ description: Panel focus management for Cyclist — set, clear, save, and load panel layouts
29
+ category: tools
30
+ tags: [cyclist, panels, layout, bikerack]
31
+ version: "1.0.0"
32
+ prerequisites: []
33
+ examples:
34
+ - context: Focusing the Sprint panel
35
+ invocation: /bc sprint
36
+ - context: Saving current layout
37
+ invocation: /bc save my-layout
38
+ - context: Resetting panel focus
39
+ invocation: /bc reset
40
+ anti_patterns:
41
+ - Don't manually edit config.local.yaml to set panel focus — use this skill
42
+ related_skills: [pf-cyclist]
43
+ keywords: [bikerack, cyclist, panel, focus, layout, dockview]
44
+
26
45
  pf-changelog:
27
46
  name: pf-changelog
28
47
  description: Maintain changelogs following Keep a Changelog format with conventional commits
@@ -1,20 +1,29 @@
1
1
  # Step 10: Publish to npm
2
2
 
3
3
  <purpose>
4
- Publish all Pennyfarthing packages to the npm registry. Verifies authentication, checks for conflicts, publishes each package, and verifies registry state.
4
+ Publish all Pennyfarthing packages to the npm registry. Uses `pnpm publish` to
5
+ resolve `workspace:*` dependencies to real version numbers. Verifies authentication,
6
+ checks for conflicts, publishes each package, and verifies registry state.
5
7
  </purpose>
6
8
 
9
+ <critical>
10
+ **MUST use `pnpm publish`** — not `npm publish`. Packages use `workspace:*` protocol
11
+ for inter-package dependencies. `pnpm publish` resolves these to actual version numbers
12
+ at publish time. `npm publish` does NOT — it publishes the literal `workspace:*` string,
13
+ which breaks consumer installs.
14
+ </critical>
15
+
7
16
  <instructions>
8
17
  1. Verify npm authentication
9
18
  2. Check that versions aren't already published
10
- 3. Publish @pennyfarthing/core (root package)
11
- 4. Publish @pennyfarthing/cyclist
12
- 5. Publish all theme packs
13
- 6. Verify published versions on registry
19
+ 3. Publish @pennyfarthing/core (root package) via pnpm
20
+ 4. Publish workspace packages via pnpm
21
+ 5. Verify published versions and resolved dependencies on registry
14
22
  </instructions>
15
23
 
16
24
  <output>
17
- npm publish results for each package, plus registry verification.
25
+ pnpm publish results for each package, plus registry verification including
26
+ dependency resolution check (no workspace:* in published metadata).
18
27
  </output>
19
28
 
20
29
  ## Execution
@@ -69,7 +78,7 @@ fi
69
78
 
70
79
  ```bash
71
80
  echo "Publishing @pennyfarthing/core@{new_version}..."
72
- npm publish --access public $NPM_TAG
81
+ pnpm publish --access public --no-git-checks $NPM_TAG
73
82
  ```
74
83
 
75
84
  ### 10.5 Publish Workspace Packages
@@ -79,17 +88,20 @@ for pkg_dir in packages/cyclist packages/shared packages/themes-*; do
79
88
  if [[ -f "$pkg_dir/package.json" ]]; then
80
89
  PKG_NAME=$(node -e "console.log(require('./$pkg_dir/package.json').name)")
81
90
  echo "Publishing $PKG_NAME@{new_version}..."
82
- (cd "$pkg_dir" && npm publish --access public $NPM_TAG) || echo "WARNING: Failed to publish $PKG_NAME"
91
+ (cd "$pkg_dir" && pnpm publish --access public --no-git-checks $NPM_TAG) || echo "WARNING: Failed to publish $PKG_NAME"
83
92
  fi
84
93
  done
85
94
  ```
86
95
 
87
- ### 10.6 Verify Published
96
+ ### 10.6 Verify Published (including workspace:* resolution)
88
97
 
89
98
  ```bash
90
99
  echo "=== Registry Verification ==="
91
100
  echo "Waiting 10s for registry propagation..."
92
101
  sleep 10
102
+
103
+ echo ""
104
+ echo "=== Version Check ==="
93
105
  for PKG_JSON in package.json packages/*/package.json; do
94
106
  PKG_NAME=$(node -e "console.log(require('./$PKG_JSON').name)")
95
107
  npm view "$PKG_NAME@{new_version}" version 2>/dev/null \
@@ -97,6 +109,26 @@ for PKG_JSON in package.json packages/*/package.json; do
97
109
  || echo " ✗ $PKG_NAME@{new_version} NOT FOUND"
98
110
  done
99
111
 
112
+ echo ""
113
+ echo "=== Dependency Resolution Check ==="
114
+ echo "Verifying no workspace:* references leaked to npm..."
115
+ LEAKED=0
116
+ for PKG_JSON in package.json packages/*/package.json; do
117
+ PKG_NAME=$(node -e "console.log(require('./$PKG_JSON').name)")
118
+ DEPS=$(npm view "$PKG_NAME@{new_version}" dependencies --json 2>/dev/null || echo "{}")
119
+ if echo "$DEPS" | grep -q "workspace:"; then
120
+ echo " ✗ $PKG_NAME has workspace: refs in published dependencies!"
121
+ echo "$DEPS" | grep "workspace:"
122
+ LEAKED=1
123
+ else
124
+ echo " ✓ $PKG_NAME — no workspace: refs"
125
+ fi
126
+ done
127
+ if [[ $LEAKED -eq 1 ]]; then
128
+ echo ""
129
+ echo "ERROR: workspace:* references leaked to npm. Deprecate affected versions and re-publish."
130
+ fi
131
+
100
132
  if [[ "$IS_PRERELEASE" == "true" ]]; then
101
133
  echo ""
102
134
  echo "=== Dist-Tag Verification ==="
@@ -7,12 +7,13 @@
7
7
  # Tandem pairings:
8
8
  # - RED phase: TEA + Architect (file-watch) — Architect reviews test strategy
9
9
  # - GREEN phase: Dev + Architect (file-watch) — Architect guides implementation patterns
10
+ # - VERIFY phase: TEA + Architect (file-watch) — Architect reviews implementation quality
10
11
  # - REVIEW phase: Reviewer + PM (file-watch) — PM validates business requirements
11
12
  #
12
13
  # Compared to base tdd: Adds tandem observers on every working phase.
13
14
  # The extra context from partner agents helps catch architectural drift early.
14
15
  #
15
- # Flow: SM → TEA (+Architect) → Dev (+Architect) → Reviewer (+PM) → SM
16
+ # Flow: SM → TEA (+Architect) → Dev (+Architect) → TEA (+Architect, verify) → Reviewer (+PM) → SM
16
17
 
17
18
  workflow:
18
19
  name: tdd-tandem
@@ -52,9 +53,21 @@ workflow:
52
53
  partner: architect
53
54
  scope: file-watch
54
55
 
56
+ - name: verify
57
+ agent: tea
58
+ input: [implementation, passing_tests]
59
+ output: [quality_verified]
60
+ gate:
61
+ file: gates/quality-pass
62
+ type: quality_pass
63
+ condition: Lint, typecheck, and all tests passing
64
+ tandem:
65
+ partner: architect
66
+ scope: file-watch
67
+
55
68
  - name: review
56
69
  agent: reviewer
57
- input: [implementation, passing_tests]
70
+ input: [implementation, passing_tests, quality_verified]
58
71
  output: [approval]
59
72
  gate:
60
73
  file: gates/approval
@@ -1,3 +0,0 @@
1
- # Session
2
- ## Dev Assessment
3
- Working on feature X
@@ -1,6 +0,0 @@
1
- # Tandem Observations: 95-6
2
- **Observer:** architect (Will Bailey)
3
- **Phase:** implement
4
- **Started:** 2026-02-19T20:04:47.898Z
5
-
6
- ---
@@ -1,6 +0,0 @@
1
- # Tandem Observations: 95-4
2
- **Observer:** architect (Will Bailey)
3
- **Phase:** implement
4
- **Started:** 2026-02-19T20:04:47.943Z
5
-
6
- ---
@@ -1 +0,0 @@
1
- export const trigger = true;
@@ -1,6 +0,0 @@
1
- # Tandem Observations: 95-5
2
- **Observer:** architect (Will Bailey)
3
- **Phase:** implement
4
- **Started:** 2026-02-19T20:04:48.283Z
5
-
6
- ---
@@ -1 +0,0 @@
1
- {"timestamp":"2026-02-19T20:04:48.284Z","toolName":"Bash","params":{"command":"npm test"},"resultPreview":"All 42 tests passed","resultSize":19}
@@ -1,201 +0,0 @@
1
- """ChangedPanel — Changed file list with status for BikeRack TUI.
2
-
3
- Story 103-14: Subscribes to /ws/git, extracts dirtyFiles from all repos,
4
- renders Rich table with file path, change type icon, and status.
5
-
6
- Story 110-1: Selectable file list with arrow navigation and Enter to navigate.
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- from typing import Any
12
-
13
- from rich.text import Text
14
- from textual.binding import Binding
15
-
16
- from pf.bikerack.base_panel import PANEL_ICONS, BasePanel
17
-
18
- # Status code → (icon, label, style)
19
- _STATUS_MAP: dict[str, tuple[str, str, str]] = {
20
- "M": ("~", "Modified", "yellow"),
21
- "A": ("+", "Added", "green"),
22
- "D": ("-", "Deleted", "red"),
23
- "?": ("?", "Untracked", "dim"),
24
- "R": ("→", "Renamed", "cyan"),
25
- }
26
-
27
- _DEFAULT_STATUS: tuple[str, str, str] = ("·", "Changed", "yellow")
28
-
29
-
30
- def _parse_status(status: str) -> tuple[str, str, str]:
31
- """Parse 2-char git status code into (icon, label, style).
32
-
33
- First char = index (staging area), second char = working tree.
34
- Uses the most significant non-space character.
35
- """
36
- if len(status) < 2:
37
- return _STATUS_MAP.get(status[:1], _DEFAULT_STATUS)
38
-
39
- idx, wt = status[0], status[1]
40
-
41
- # Untracked: both chars are '?'
42
- if idx == "?" and wt == "?":
43
- return _STATUS_MAP["?"]
44
-
45
- # Index change takes priority if present
46
- if idx not in (" ", "?"):
47
- return _STATUS_MAP.get(idx, _DEFAULT_STATUS)
48
-
49
- # Working tree change
50
- if wt not in (" ", "?"):
51
- return _STATUS_MAP.get(wt, _DEFAULT_STATUS)
52
-
53
- return _DEFAULT_STATUS
54
-
55
-
56
- class ChangedPanel(BasePanel):
57
- """Changed file list panel.
58
-
59
- Subscribes to the ``git`` WebSocket channel and renders
60
- dirty files from all repos as a Rich table with file path,
61
- change type icon, and status. Supports arrow-key selection
62
- and Enter to navigate to diffs.
63
- """
64
-
65
- channel: str = "git"
66
- panel_name: str = "Changed"
67
- icon: str = PANEL_ICONS["changed"][0]
68
- can_focus = True
69
-
70
- BINDINGS = [
71
- Binding("up", "select_prev_key", "Up"),
72
- Binding("down", "select_next_key", "Down"),
73
- Binding("enter", "select_file", "Select file"),
74
- ]
75
-
76
- def __init__(self, client=None, **kwargs):
77
- super().__init__(client=client, **kwargs)
78
- self._selected_index: int = 0
79
- self._file_paths: list[str] = []
80
-
81
- def handle_message(self, message: dict[str, Any] | None) -> None:
82
- """Handle incoming message — build file path index then render."""
83
- if message is not None:
84
- self._build_file_paths(message)
85
- super().handle_message(message)
86
-
87
- def _build_file_paths(self, payload: dict[str, Any]) -> None:
88
- """Extract flat list of file paths from repos payload."""
89
- paths: list[str] = []
90
- repos = payload.get("repos", [])
91
- if isinstance(repos, list):
92
- for repo in repos:
93
- if not isinstance(repo, dict):
94
- continue
95
- dirty_files = repo.get("dirtyFiles", [])
96
- if not isinstance(dirty_files, list):
97
- continue
98
- for f in dirty_files:
99
- if isinstance(f, dict):
100
- path = f.get("path", "")
101
- if path:
102
- paths.append(path)
103
- self._file_paths = paths
104
- if self._selected_index >= len(paths):
105
- self._selected_index = max(0, len(paths) - 1)
106
-
107
- def select_next(self) -> None:
108
- """Move selection to the next file."""
109
- if self._file_paths and self._selected_index < len(self._file_paths) - 1:
110
- self._selected_index += 1
111
- self._rerender()
112
-
113
- def select_prev(self) -> None:
114
- """Move selection to the previous file."""
115
- if self._selected_index > 0:
116
- self._selected_index -= 1
117
- self._rerender()
118
-
119
- def action_select_next_key(self) -> None:
120
- """Binding action: move selection down."""
121
- self.select_next()
122
-
123
- def action_select_prev_key(self) -> None:
124
- """Binding action: move selection up."""
125
- self.select_prev()
126
-
127
- def _rerender(self) -> None:
128
- """Re-render panel with current payload after selection change."""
129
- if self._last_payload:
130
- try:
131
- self.update(self.render_panel(self._last_payload))
132
- except Exception:
133
- pass
134
-
135
- def get_selected_path(self) -> str | None:
136
- """Return the currently selected file path, or None if empty."""
137
- if not self._file_paths:
138
- return None
139
- if self._selected_index >= len(self._file_paths):
140
- return None
141
- return self._file_paths[self._selected_index]
142
-
143
- def action_select_file(self) -> None:
144
- """Post NavigateToFile event for the selected file."""
145
- path = self.get_selected_path()
146
- if path is not None:
147
- from pf.bikerack.events import NavigateToFile
148
-
149
- self.post_message(NavigateToFile(path=path))
150
-
151
- def render_panel(self, payload: dict[str, Any]) -> Any:
152
- """Render changed files grouped by repository with selection highlight."""
153
- repos = payload.get("repos", [])
154
- if not isinstance(repos, list):
155
- return Text("No changed files", style="dim italic")
156
-
157
- # Group files by repo
158
- repo_files: dict[str, list[dict[str, Any]]] = {}
159
- for repo in repos:
160
- if not isinstance(repo, dict):
161
- continue
162
- repo_name = repo.get("name", "unknown")
163
- dirty_files = repo.get("dirtyFiles", [])
164
- if not isinstance(dirty_files, list) or not dirty_files:
165
- continue
166
- repo_files[repo_name] = [f for f in dirty_files if isinstance(f, dict)]
167
-
168
- if not repo_files:
169
- return Text("No changed files", style="dim italic")
170
-
171
- from rich.console import Group as RichGroup
172
-
173
- parts: list[Any] = []
174
- flat_idx = 0
175
- for repo_name, files in repo_files.items():
176
- count = len(files)
177
- label = "file" if count == 1 else "files"
178
- header = Text()
179
- header.append(repo_name, style="bold cyan")
180
- header.append(f" ({count} {label})", style="dim")
181
- parts.append(header)
182
-
183
- for f in files:
184
- status_code = f.get("status", " ")
185
- path = f.get("path", "")
186
- icon, label_text, style = _parse_status(status_code)
187
- is_selected = flat_idx == self._selected_index
188
- line = Text()
189
- if is_selected:
190
- line.append("› ", style="bold reverse")
191
- else:
192
- line.append(" ")
193
- line.append(icon, style=f"bold {style}")
194
- line.append(f" {path}", style="bold cyan reverse" if is_selected else "cyan")
195
- line.append(f" {label_text}", style=style)
196
- parts.append(line)
197
- flat_idx += 1
198
-
199
- parts.append(Text("")) # spacer between repos
200
-
201
- return RichGroup(*parts)