@pennyfarthing/core 11.1.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/README.md +8 -8
  2. package/package.json +16 -14
  3. package/packages/core/dist/cli/utils/constants.d.ts +1 -1
  4. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  5. package/packages/core/dist/cli/utils/constants.js +2 -1
  6. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  7. package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
  8. package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
  9. package/packages/core/dist/consultation/dialogue-manager.js +334 -0
  10. package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
  11. package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
  12. package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
  13. package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
  14. package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
  15. package/packages/core/dist/server/api/git.d.ts +13 -1
  16. package/packages/core/dist/server/api/git.d.ts.map +1 -1
  17. package/packages/core/dist/server/api/git.js +53 -34
  18. package/packages/core/dist/server/api/git.js.map +1 -1
  19. package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
  20. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  21. package/packages/core/dist/server/otlp-receiver.js +185 -24
  22. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  23. package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
  24. package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
  25. package/packages/core/dist/server/otlp-receiver.test.js +446 -0
  26. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
  27. package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
  28. package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
  29. package/packages/core/dist/shared/portrait-resolver.js +27 -0
  30. package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
  31. package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
  32. package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
  33. package/packages/core/dist/shared/skill-search.test.js +2 -2
  34. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
  35. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
  36. package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
  37. package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
  38. package/pennyfarthing-dist/agents/dev.md +1 -1
  39. package/pennyfarthing-dist/agents/reviewer.md +1 -1
  40. package/pennyfarthing-dist/agents/sm-setup.md +1 -1
  41. package/pennyfarthing-dist/agents/sm.md +2 -2
  42. package/pennyfarthing-dist/agents/tea.md +1 -1
  43. package/pennyfarthing-dist/agents/testing-runner.md +2 -1
  44. package/pennyfarthing-dist/commands/pf-chore.md +2 -2
  45. package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
  46. package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
  47. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
  48. package/pennyfarthing-dist/guides/bikerack.md +3 -3
  49. package/pennyfarthing-dist/guides/hooks.md +1 -1
  50. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  51. package/pennyfarthing-dist/guides/xml-tags.md +2 -2
  52. package/pennyfarthing-dist/scripts/README.md +1 -1
  53. package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
  54. package/pennyfarthing-dist/scripts/core/check-context.sh +1 -1
  55. package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
  56. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  57. package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
  58. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  59. package/pennyfarthing-dist/scripts/git/README.md +24 -14
  60. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
  61. package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
  62. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
  63. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  64. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
  65. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  66. package/pennyfarthing-dist/scripts/hooks/README.md +1 -1
  67. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
  68. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  69. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  70. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  71. package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
  72. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
  73. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
  74. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
  75. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  76. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
  77. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  78. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  79. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  80. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  81. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  82. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  83. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
  84. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
  85. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
  86. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  87. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
  88. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  89. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  90. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  91. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  92. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  93. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  94. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  95. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  96. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  97. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  98. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  99. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  100. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  101. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  102. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  103. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  104. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  105. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  106. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
  107. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  108. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  109. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  110. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  111. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  112. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  113. package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
  114. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  115. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
  116. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  117. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
  118. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  119. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  120. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  121. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  122. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  123. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  124. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
  125. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  126. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  127. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  128. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  129. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  130. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
  131. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  132. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  133. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  134. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  135. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  136. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
  137. package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
  138. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  139. package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
  140. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
  141. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
  142. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  143. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
  144. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
  145. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
  146. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
  147. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
  148. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
  149. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
  150. package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
  151. package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
  152. package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
  153. package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
  154. package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
  155. package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
  156. package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
  157. package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
  158. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
  159. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
  160. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
  161. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
  162. package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
  163. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
  164. package/pennyfarthing_scripts/CLAUDE.md +26 -4
  165. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  166. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  167. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/bc/cli.py +3 -5
  171. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  172. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  183. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
  185. package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
  186. package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
  187. package/pennyfarthing_scripts/bikerack/cli.py +10 -11
  188. package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
  189. package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
  190. package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
  191. package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
  192. package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
  193. package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
  194. package/pennyfarthing_scripts/bikerack/tui.py +336 -30
  195. package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
  196. package/pennyfarthing_scripts/cli.py +37 -65
  197. package/pennyfarthing_scripts/consultation/__init__.py +1 -0
  198. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/consultation/cli.py +149 -0
  201. package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
  202. package/pennyfarthing_scripts/context.py +3 -3
  203. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/git/__init__.py +12 -1
  206. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
  212. package/pennyfarthing_scripts/git/create_branches.py +3 -4
  213. package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
  214. package/pennyfarthing_scripts/git/repos.py +196 -0
  215. package/pennyfarthing_scripts/git/status_all.py +27 -11
  216. package/pennyfarthing_scripts/git/worktree.py +302 -0
  217. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing_scripts/git_group/cli.py +143 -40
  220. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  221. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  222. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  223. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
  225. package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
  226. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  227. package/pennyfarthing_scripts/hooks.py +3 -17
  228. package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
  229. package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
  230. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/prime/heatmap.py +655 -0
  232. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  233. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/session_start_hook.py +1 -1
  235. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/sprint/loader.py +15 -1
  237. package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
  238. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  239. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  240. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  241. package/pennyfarthing_scripts/tests/test_bikerack.py +51 -51
  242. package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
  243. package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
  244. package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
  245. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
  247. package/pennyfarthing_scripts/validate/cli.py +17 -5
  248. package/pennyfarthing_scripts/workflow/__init__.py +40 -0
  249. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/workflow/cli.py +1099 -0
  255. package/pennyfarthing_scripts/workflow/helpers.py +241 -0
  256. package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
  257. package/pennyfarthing_scripts/workflow/state.py +112 -0
  258. package/scripts/README.md +41 -0
  259. package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
  260. package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
  261. package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
  262. package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
  263. package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-receiver.test.d.ts","sourceRoot":"","sources":["../../src/server/otlp-receiver.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
@@ -0,0 +1,446 @@
1
+ /**
2
+ * Tests for Story 98-23: Implement real OTLP integrations for core server stubs
3
+ *
4
+ * Core's otlp-receiver module must provide real OTLP processing without
5
+ * requiring Cyclist's provider. WheelHub standalone (BikeRack mode) needs
6
+ * working telemetry ingestion.
7
+ *
8
+ * Acceptance Criteria:
9
+ * AC1: parseOTLPMetrics extracts token usage from OTLP JSON payloads
10
+ * AC2: aggregateTokenStats accumulates stats and notifies listeners
11
+ * AC3: parseOTLPLogs extracts structured events from OTLP log payloads
12
+ * AC4: processLogEvents categorizes and records tool/prompt events
13
+ * AC5: Background task lifecycle — track, complete, retrieve, callbacks
14
+ * AC6: Tool event listeners fire when events are recorded
15
+ * AC7: Session state management — reset clears stores, email extracted
16
+ * AC8: Delegating stubs work standalone (no provider required)
17
+ *
18
+ * Run with: cd packages/core && npm test
19
+ */
20
+ import { describe, it, beforeEach } from 'node:test';
21
+ import assert from 'node:assert';
22
+ // =============================================================================
23
+ // Test Fixtures — valid OTLP payloads matching Claude Code's format
24
+ // =============================================================================
25
+ function createMetricsPayload(tokens) {
26
+ const dataPoints = [];
27
+ const tokenMap = {
28
+ input: tokens.input,
29
+ output: tokens.output,
30
+ cacheRead: tokens.cacheRead,
31
+ cacheCreation: tokens.cacheCreation,
32
+ };
33
+ for (const [type, value] of Object.entries(tokenMap)) {
34
+ if (value !== undefined) {
35
+ dataPoints.push({
36
+ asInt: value,
37
+ attributes: [{ key: 'type', value: { stringValue: type } }],
38
+ });
39
+ }
40
+ }
41
+ return {
42
+ resourceMetrics: [{
43
+ scopeMetrics: [{
44
+ metrics: [{
45
+ name: 'claude_code.token.usage',
46
+ sum: { dataPoints },
47
+ }],
48
+ }],
49
+ }],
50
+ };
51
+ }
52
+ function createLogsPayload(events) {
53
+ return {
54
+ resourceLogs: [{
55
+ scopeLogs: [{
56
+ logRecords: events.map(event => ({
57
+ timeUnixNano: event.timestamp || String(Date.now() * 1_000_000),
58
+ body: { stringValue: event.name },
59
+ attributes: Object.entries(event.attributes || {}).map(([key, value]) => ({
60
+ key,
61
+ value: typeof value === 'string'
62
+ ? { stringValue: value }
63
+ : typeof value === 'number'
64
+ ? { intValue: value }
65
+ : { boolValue: value },
66
+ })),
67
+ })),
68
+ }],
69
+ }],
70
+ };
71
+ }
72
+ // =============================================================================
73
+ // AC1: OTLP Metrics Parsing
74
+ // =============================================================================
75
+ describe('AC1: parseOTLPMetrics — real implementation', () => {
76
+ it('parses token usage from valid OTLP metrics payload', async () => {
77
+ const { parseOTLPMetrics } = await import('./otlp-receiver.js');
78
+ const payload = createMetricsPayload({ input: 100, output: 50 });
79
+ const result = parseOTLPMetrics(payload);
80
+ // Current stub returns null — should return an object with parsed stats
81
+ assert.ok(result !== null && result !== undefined, 'parseOTLPMetrics should return a result object, not null');
82
+ const stats = result;
83
+ assert.strictEqual(stats.inputTokens, 100, 'Should parse input token count');
84
+ assert.strictEqual(stats.outputTokens, 50, 'Should parse output token count');
85
+ });
86
+ it('parses all four token types', async () => {
87
+ const { parseOTLPMetrics } = await import('./otlp-receiver.js');
88
+ const payload = createMetricsPayload({
89
+ input: 200, output: 100, cacheRead: 50, cacheCreation: 25,
90
+ });
91
+ const result = parseOTLPMetrics(payload);
92
+ assert.ok(result !== null, 'Should not return null');
93
+ assert.strictEqual(result.inputTokens, 200);
94
+ assert.strictEqual(result.outputTokens, 100);
95
+ assert.strictEqual(result.cacheReadTokens, 50);
96
+ assert.strictEqual(result.cacheCreationTokens, 25);
97
+ });
98
+ it('returns empty object (not null) for empty payload', async () => {
99
+ const { parseOTLPMetrics } = await import('./otlp-receiver.js');
100
+ const result = parseOTLPMetrics({});
101
+ assert.ok(result !== null, 'Should return object, not null, for empty payload');
102
+ assert.strictEqual(typeof result, 'object');
103
+ });
104
+ it('ignores non-token-usage metrics', async () => {
105
+ const { parseOTLPMetrics } = await import('./otlp-receiver.js');
106
+ const payload = {
107
+ resourceMetrics: [{
108
+ scopeMetrics: [{
109
+ metrics: [{
110
+ name: 'other.metric.name',
111
+ sum: { dataPoints: [{ asInt: 999 }] },
112
+ }],
113
+ }],
114
+ }],
115
+ };
116
+ const result = parseOTLPMetrics(payload);
117
+ assert.ok(result !== null);
118
+ assert.strictEqual(result.inputTokens, undefined, 'Should not extract from non-token metrics');
119
+ });
120
+ });
121
+ // =============================================================================
122
+ // AC2: Token Stats Aggregation
123
+ // =============================================================================
124
+ describe('AC2: aggregateTokenStats + getTokenStats', () => {
125
+ beforeEach(async () => {
126
+ const mod = await import('./otlp-receiver.js');
127
+ mod.resetEventStore();
128
+ });
129
+ it('accumulates token stats across multiple calls', async () => {
130
+ const { aggregateTokenStats, getTokenStats } = await import('./otlp-receiver.js');
131
+ // After real implementation, these should modify internal state
132
+ aggregateTokenStats({ inputTokens: 50, outputTokens: 20 });
133
+ aggregateTokenStats({ inputTokens: 30, outputTokens: 10 });
134
+ const stats = getTokenStats();
135
+ // Current stub getTokenStats returns {inputTokens:0,...} always
136
+ assert.strictEqual(stats.inputTokens, 80, 'Input tokens should accumulate (50 + 30 = 80)');
137
+ assert.strictEqual(stats.outputTokens, 30, 'Output tokens should accumulate (20 + 10 = 30)');
138
+ });
139
+ it('notifies registered listener on aggregation', async () => {
140
+ const { aggregateTokenStats, addTokenStatsListener } = await import('./otlp-receiver.js');
141
+ let notified = false;
142
+ addTokenStatsListener(() => { notified = true; });
143
+ aggregateTokenStats({ inputTokens: 100 });
144
+ // Current stubs: addTokenStatsListener is no-op, aggregateTokenStats doesn't notify
145
+ assert.strictEqual(notified, true, 'Token stats listener should fire on aggregation');
146
+ });
147
+ });
148
+ // =============================================================================
149
+ // AC3: OTLP Logs Parsing
150
+ // =============================================================================
151
+ describe('AC3: parseOTLPLogs — real implementation', () => {
152
+ it('parses log records into structured event array', async () => {
153
+ const { parseOTLPLogs } = await import('./otlp-receiver.js');
154
+ const payload = createLogsPayload([{
155
+ name: 'claude_code.tool_result',
156
+ attributes: { tool_name: 'Read', success: 'true', duration_ms: '42' },
157
+ }]);
158
+ const events = parseOTLPLogs(payload);
159
+ // Current stub returns null — should return array
160
+ assert.ok(Array.isArray(events), 'Should return an array, not null');
161
+ assert.strictEqual(events.length, 1, 'Should parse one event');
162
+ const event = events[0];
163
+ assert.strictEqual(event.name, 'claude_code.tool_result');
164
+ assert.ok(event.timestamp > 0, 'Should have a valid timestamp');
165
+ const attrs = event.attributes;
166
+ assert.strictEqual(attrs.tool_name, 'Read');
167
+ });
168
+ it('returns empty array for empty payload', async () => {
169
+ const { parseOTLPLogs } = await import('./otlp-receiver.js');
170
+ const result = parseOTLPLogs({});
171
+ assert.ok(Array.isArray(result), 'Empty payload should return empty array');
172
+ assert.strictEqual(result.length, 0);
173
+ });
174
+ it('parses multiple events', async () => {
175
+ const { parseOTLPLogs } = await import('./otlp-receiver.js');
176
+ const payload = createLogsPayload([
177
+ { name: 'claude_code.tool_result', attributes: { tool_name: 'Read' } },
178
+ { name: 'claude_code.user_prompt', attributes: { 'prompt.text': 'hello' } },
179
+ { name: 'claude_code.tool_result', attributes: { tool_name: 'Bash' } },
180
+ ]);
181
+ const events = parseOTLPLogs(payload);
182
+ assert.ok(Array.isArray(events));
183
+ assert.strictEqual(events.length, 3, 'Should parse all three log records');
184
+ });
185
+ it('converts nanosecond timestamps to milliseconds', async () => {
186
+ const { parseOTLPLogs } = await import('./otlp-receiver.js');
187
+ const knownMs = 1700000000000;
188
+ const payload = createLogsPayload([{
189
+ name: 'test_event',
190
+ timestamp: String(knownMs * 1_000_000),
191
+ }]);
192
+ const events = parseOTLPLogs(payload);
193
+ assert.ok(Array.isArray(events) && events.length === 1);
194
+ assert.strictEqual(events[0].timestamp, knownMs, 'Should convert nanoseconds to milliseconds');
195
+ });
196
+ });
197
+ // =============================================================================
198
+ // AC4: Log Event Processing
199
+ // =============================================================================
200
+ describe('AC4: processLogEvents — core implementation', () => {
201
+ beforeEach(async () => {
202
+ const mod = await import('./otlp-receiver.js');
203
+ mod.resetEventStore();
204
+ });
205
+ it('records tool events from tool_result log events', async () => {
206
+ const { processLogEvents, getAuditLog } = await import('./otlp-receiver.js');
207
+ processLogEvents([{
208
+ name: 'claude_code.tool_result',
209
+ timestamp: Date.now(),
210
+ attributes: {
211
+ tool_name: 'Read',
212
+ success: 'true',
213
+ duration_ms: '150',
214
+ },
215
+ }]);
216
+ const audit = getAuditLog();
217
+ // Current stubs: processLogEvents is no-op, getAuditLog returns []
218
+ assert.ok(audit.length > 0, 'Should record tool events to audit log');
219
+ });
220
+ it('extracts tool_name and success from attributes', async () => {
221
+ const { processLogEvents, getAuditLog } = await import('./otlp-receiver.js');
222
+ processLogEvents([{
223
+ name: 'claude_code.tool_result',
224
+ timestamp: Date.now(),
225
+ attributes: {
226
+ tool_name: 'Bash',
227
+ success: 'false',
228
+ duration_ms: '300',
229
+ },
230
+ }]);
231
+ const audit = getAuditLog();
232
+ assert.ok(audit.length === 1);
233
+ const entry = audit[0];
234
+ assert.strictEqual(entry.toolName, 'Bash', 'Should record tool name');
235
+ assert.strictEqual(entry.success, false, 'Should parse success as boolean');
236
+ });
237
+ });
238
+ // =============================================================================
239
+ // AC5: Background Task Lifecycle
240
+ // =============================================================================
241
+ describe('AC5: Background task lifecycle', () => {
242
+ beforeEach(async () => {
243
+ const mod = await import('./otlp-receiver.js');
244
+ mod.resetEventStore();
245
+ });
246
+ it('trackBackgroundTask stores a pending task', async () => {
247
+ const { trackBackgroundTask, getBackgroundTasks } = await import('./otlp-receiver.js');
248
+ trackBackgroundTask({
249
+ taskId: 'task-1',
250
+ description: 'Test task',
251
+ subagentType: 'general-purpose',
252
+ startedAt: Date.now(),
253
+ });
254
+ const tasks = getBackgroundTasks();
255
+ // Current stub: trackBackgroundTask is no-op, getBackgroundTasks returns []
256
+ assert.ok(tasks.length > 0, 'Should have stored the task');
257
+ const task = tasks.find(t => t.taskId === 'task-1');
258
+ assert.ok(task, 'Should find task by ID');
259
+ assert.strictEqual(task.status, 'pending');
260
+ });
261
+ it('getBackgroundTaskByToolId finds tracked task', async () => {
262
+ const { trackBackgroundTask, getBackgroundTaskByToolId } = await import('./otlp-receiver.js');
263
+ trackBackgroundTask({
264
+ taskId: 'lookup-1',
265
+ description: 'Lookup test',
266
+ subagentType: 'Explore',
267
+ startedAt: Date.now(),
268
+ });
269
+ const found = getBackgroundTaskByToolId('lookup-1');
270
+ // Current stub always returns undefined
271
+ assert.ok(found !== null && found !== undefined, 'Should find task by tool ID');
272
+ assert.strictEqual(found.taskId, 'lookup-1');
273
+ });
274
+ it('completeBackgroundTask marks task completed with metadata', async () => {
275
+ const { trackBackgroundTask, completeBackgroundTask, getBackgroundTasks, } = await import('./otlp-receiver.js');
276
+ trackBackgroundTask({
277
+ taskId: 'complete-1',
278
+ description: 'Complete test',
279
+ subagentType: 'general-purpose',
280
+ startedAt: Date.now(),
281
+ });
282
+ const completed = completeBackgroundTask('complete-1', true, 'done');
283
+ // Current stub always returns undefined
284
+ assert.ok(completed !== null && completed !== undefined, 'Should return the completed task');
285
+ assert.strictEqual(completed.status, 'completed');
286
+ assert.strictEqual(completed.success, true);
287
+ assert.ok(completed.completedAt > 0, 'Should have completedAt timestamp');
288
+ assert.ok(completed.durationMs >= 0, 'Should have durationMs');
289
+ });
290
+ it('setBackgroundTaskCallback fires on task completion', async () => {
291
+ const { trackBackgroundTask, completeBackgroundTask, setBackgroundTaskCallback, } = await import('./otlp-receiver.js');
292
+ let callbackFired = false;
293
+ setBackgroundTaskCallback(() => { callbackFired = true; });
294
+ trackBackgroundTask({
295
+ taskId: 'cb-1',
296
+ description: 'Callback test',
297
+ subagentType: 'general-purpose',
298
+ startedAt: Date.now(),
299
+ });
300
+ completeBackgroundTask('cb-1', true, 'result');
301
+ // Current stub: setBackgroundTaskCallback is delegating (no-op without provider)
302
+ // trackBackgroundTask/completeBackgroundTask are plain no-ops
303
+ assert.strictEqual(callbackFired, true, 'Completion callback should fire');
304
+ });
305
+ it('setBackgroundTaskStartCallback fires on task tracking', async () => {
306
+ const { trackBackgroundTask, setBackgroundTaskStartCallback } = await import('./otlp-receiver.js');
307
+ let startFired = false;
308
+ setBackgroundTaskStartCallback(() => { startFired = true; });
309
+ trackBackgroundTask({
310
+ taskId: 'start-cb-1',
311
+ description: 'Start callback test',
312
+ subagentType: 'general-purpose',
313
+ startedAt: Date.now(),
314
+ });
315
+ assert.strictEqual(startFired, true, 'Start callback should fire when task is tracked');
316
+ });
317
+ });
318
+ // =============================================================================
319
+ // AC6: Tool Event Listeners
320
+ // =============================================================================
321
+ describe('AC6: addToolEventListener', () => {
322
+ beforeEach(async () => {
323
+ const mod = await import('./otlp-receiver.js');
324
+ mod.resetEventStore();
325
+ });
326
+ it('listener fires when tool event is recorded via processLogEvents', async () => {
327
+ const { addToolEventListener, processLogEvents } = await import('./otlp-receiver.js');
328
+ let listenerFired = false;
329
+ let receivedToolName;
330
+ addToolEventListener((event) => {
331
+ listenerFired = true;
332
+ receivedToolName = event.toolName;
333
+ });
334
+ processLogEvents([{
335
+ name: 'claude_code.tool_result',
336
+ timestamp: Date.now(),
337
+ attributes: { tool_name: 'Read', success: 'true' },
338
+ }]);
339
+ // Current stub: addToolEventListener is no-op
340
+ assert.strictEqual(listenerFired, true, 'Tool event listener should fire');
341
+ assert.strictEqual(receivedToolName, 'Read', 'Listener should receive the tool event');
342
+ });
343
+ });
344
+ // =============================================================================
345
+ // AC7: Session State Management
346
+ // =============================================================================
347
+ describe('AC7: Session state management', () => {
348
+ it('resetEventStore clears all in-memory stores', async () => {
349
+ const { trackBackgroundTask, getBackgroundTasks, processLogEvents, getAuditLog, aggregateTokenStats, getTokenStats, resetEventStore, } = await import('./otlp-receiver.js');
350
+ // Populate stores
351
+ trackBackgroundTask({
352
+ taskId: 'reset-1', description: 'r', subagentType: 'x', startedAt: Date.now(),
353
+ });
354
+ processLogEvents([{
355
+ name: 'claude_code.tool_result',
356
+ timestamp: Date.now(),
357
+ attributes: { tool_name: 'Read', success: 'true' },
358
+ }]);
359
+ aggregateTokenStats({ inputTokens: 100 });
360
+ // Reset
361
+ resetEventStore();
362
+ // Current stub: resetEventStore is delegating (no-op without provider)
363
+ // After implementation, should clear all stores
364
+ assert.strictEqual(getBackgroundTasks().length, 0, 'Background tasks should be cleared');
365
+ assert.strictEqual(getAuditLog().length, 0, 'Audit log should be cleared');
366
+ assert.strictEqual(getTokenStats().inputTokens, 0, 'Token stats should be reset to zero');
367
+ });
368
+ it('getUserEmail returns email extracted from OTLP log events', async () => {
369
+ const { getUserEmail, processLogEvents, resetEventStore } = await import('./otlp-receiver.js');
370
+ resetEventStore();
371
+ processLogEvents([{
372
+ name: 'claude_code.tool_result',
373
+ timestamp: Date.now(),
374
+ attributes: {
375
+ tool_name: 'Read',
376
+ success: 'true',
377
+ 'user.email': 'test@example.com',
378
+ },
379
+ }]);
380
+ // Current stub: getUserEmail always returns null
381
+ assert.strictEqual(getUserEmail(), 'test@example.com', 'Should extract user email from OTLP event attributes');
382
+ });
383
+ });
384
+ // =============================================================================
385
+ // AC8: Delegating Stubs Work Standalone (No Provider)
386
+ // =============================================================================
387
+ describe('AC8: Standalone mode — delegating stubs without provider', () => {
388
+ beforeEach(async () => {
389
+ const mod = await import('./otlp-receiver.js');
390
+ mod.resetEventStore();
391
+ });
392
+ it('processOTLPMetrics parses and aggregates without provider', async () => {
393
+ const { processOTLPMetrics, getTokenStats } = await import('./otlp-receiver.js');
394
+ const payload = createMetricsPayload({ input: 200, output: 100 });
395
+ processOTLPMetrics(payload);
396
+ const stats = getTokenStats();
397
+ // Without provider, current stub does nothing — getTokenStats returns zeros
398
+ assert.strictEqual(stats.inputTokens, 200, 'Should parse and aggregate metrics without Cyclist provider');
399
+ assert.strictEqual(stats.outputTokens, 100);
400
+ });
401
+ it('processOTLPLogs parses and records events without provider', async () => {
402
+ const { processOTLPLogs, getAuditLog } = await import('./otlp-receiver.js');
403
+ const payload = createLogsPayload([{
404
+ name: 'claude_code.tool_result',
405
+ attributes: { tool_name: 'Bash', success: 'true' },
406
+ }]);
407
+ processOTLPLogs(payload);
408
+ const audit = getAuditLog();
409
+ // Without provider, current stubs do nothing
410
+ assert.ok(audit.length > 0, 'Should record events without Cyclist provider');
411
+ });
412
+ it('full standalone pipeline: ingest → query audit log + stats + types', async () => {
413
+ const { processOTLPLogs, processOTLPMetrics, getAuditLog, getTokenStats, getToolTypes, getAuditLogStats, exportAuditLogAsJSON, exportAuditLogAsCSV, } = await import('./otlp-receiver.js');
414
+ // Ingest metrics
415
+ processOTLPMetrics(createMetricsPayload({ input: 500, output: 250 }));
416
+ // Ingest logs with two tool events
417
+ processOTLPLogs(createLogsPayload([
418
+ { name: 'claude_code.tool_result', attributes: { tool_name: 'Read', success: 'true' } },
419
+ { name: 'claude_code.tool_result', attributes: { tool_name: 'Bash', success: 'false' } },
420
+ ]));
421
+ // Token stats
422
+ const stats = getTokenStats();
423
+ assert.strictEqual(stats.inputTokens, 500);
424
+ assert.strictEqual(stats.outputTokens, 250);
425
+ // Audit log
426
+ const log = getAuditLog();
427
+ assert.strictEqual(log.length, 2, 'Should have 2 audit entries');
428
+ // Tool types
429
+ const types = getToolTypes();
430
+ assert.ok(types.includes('Read'), 'Types should include Read');
431
+ assert.ok(types.includes('Bash'), 'Types should include Bash');
432
+ // Audit stats
433
+ const auditStats = getAuditLogStats();
434
+ assert.strictEqual(auditStats.total, 2);
435
+ // JSON export
436
+ const json = exportAuditLogAsJSON();
437
+ assert.ok(json.length > 2, 'JSON export should have content');
438
+ const parsed = JSON.parse(json);
439
+ assert.ok(Array.isArray(parsed), 'JSON export should be array');
440
+ // CSV export
441
+ const csv = exportAuditLogAsCSV();
442
+ assert.ok(csv.includes('toolName'), 'CSV should have header');
443
+ assert.ok(csv.includes('Read'), 'CSV should contain tool data');
444
+ });
445
+ });
446
+ //# sourceMappingURL=otlp-receiver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-receiver.test.js","sourceRoot":"","sources":["../../src/server/otlp-receiver.test.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,15 @@ export declare function resolvePennyfarthingDist(): string | null;
28
28
  * @returns Full path to portrait file, or null if not found
29
29
  */
30
30
  export declare function resolvePortraitPath(theme: string, agent: string): string | null;
31
+ /**
32
+ * Resolve the path to a tandem branding image for a given theme.
33
+ * Looks for cyclist-tandem.png in the theme's portrait directory.
34
+ *
35
+ * @param theme - Theme name (e.g., 'monty-python', 'stephen-king')
36
+ * @param size - Portrait size directory ('medium' or 'large')
37
+ * @returns Full path to tandem branding image, or null if not found
38
+ */
39
+ export declare function resolveTandemBrandingPath(theme: string, size?: 'medium' | 'large'): string | null;
31
40
  /**
32
41
  * Get all portrait-related paths for a resolved dist directory
33
42
  */
@@ -1 +1 @@
1
- {"version":3,"file":"portrait-resolver.d.ts","sourceRoot":"","sources":["../../src/shared/portrait-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAgDxD;AA2ID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkC/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAShE"}
1
+ {"version":3,"file":"portrait-resolver.d.ts","sourceRoot":"","sources":["../../src/shared/portrait-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAgDxD;AA2ID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkC/E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,QAAQ,GAAG,OAAkB,GAAG,MAAM,GAAG,IAAI,CAmB3G;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAShE"}
@@ -244,6 +244,33 @@ export function resolvePortraitPath(theme, agent) {
244
244
  }
245
245
  return null;
246
246
  }
247
+ /**
248
+ * Resolve the path to a tandem branding image for a given theme.
249
+ * Looks for cyclist-tandem.png in the theme's portrait directory.
250
+ *
251
+ * @param theme - Theme name (e.g., 'monty-python', 'stephen-king')
252
+ * @param size - Portrait size directory ('medium' or 'large')
253
+ * @returns Full path to tandem branding image, or null if not found
254
+ */
255
+ export function resolveTandemBrandingPath(theme, size = 'medium') {
256
+ const filename = 'cyclist-tandem.png';
257
+ // Check core portraits
258
+ const distPath = resolvePennyfarthingDist();
259
+ if (distPath) {
260
+ const paths = getPortraitPaths(distPath);
261
+ const corePath = join(paths.portraitsDir, theme, size, filename);
262
+ if (existsSync(corePath))
263
+ return corePath;
264
+ }
265
+ // Check theme package portraits
266
+ const themePackages = discoverThemePackagePortraitDirs();
267
+ for (const pkg of themePackages) {
268
+ const pkgPath = join(pkg.portraitsDir, theme, size, filename);
269
+ if (existsSync(pkgPath))
270
+ return pkgPath;
271
+ }
272
+ return null;
273
+ }
247
274
  /**
248
275
  * Get all portrait-related paths for a resolved dist directory
249
276
  */
@@ -1 +1 @@
1
- {"version":3,"file":"portrait-resolver.js","sourceRoot":"","sources":["../../src/shared/portrait-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"portrait-resolver.js","sourceRoot":"","sources":["../../src/shared/portrait-resolver.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { describe, it, afterEach } from 'node:test';
2
2
  import assert from 'node:assert';
3
3
  import path from 'node:path';
4
- import { resolvePennyfarthingDist, resolvePortraitPath, getPortraitPaths, } from './portrait-resolver.js';
4
+ import { resolvePennyfarthingDist, resolvePortraitPath, resolveTandemBrandingPath, getPortraitPaths, } from './portrait-resolver.js';
5
5
  describe('portrait-resolver', () => {
6
6
  describe('resolvePennyfarthingDist', () => {
7
7
  const originalEnv = process.env.PENNYFARTHING_DIST;
@@ -153,5 +153,51 @@ describe('portrait-resolver', () => {
153
153
  assert.ok(!result.portraitsDir.includes('//'), 'Should not have double slashes');
154
154
  });
155
155
  });
156
+ // ==========================================================================
157
+ // Story 86-17: resolveTandemBrandingPath
158
+ // ==========================================================================
159
+ describe('resolveTandemBrandingPath', () => {
160
+ // AC3: Portrait resolver detects tandem mode and returns tandem variant path
161
+ it('should return a path containing cyclist-tandem for a theme with tandem portraits', () => {
162
+ // Once tandem portraits are generated, a-team should have one
163
+ const result = resolveTandemBrandingPath('a-team');
164
+ assert.ok(result !== null, 'Should find tandem branding for a-team theme');
165
+ assert.ok(result.includes('cyclist-tandem'), 'Path should include cyclist-tandem');
166
+ assert.ok(result.includes('a-team'), 'Path should include theme name');
167
+ });
168
+ it('should return path in the medium size directory by default', () => {
169
+ const result = resolveTandemBrandingPath('a-team');
170
+ assert.ok(result !== null, 'Should find tandem branding');
171
+ assert.ok(result.includes('/medium/'), 'Default should use medium size');
172
+ });
173
+ it('should return path in the large size directory when requested', () => {
174
+ // AC6: Tandem portraits properly sized (large 300x300)
175
+ const result = resolveTandemBrandingPath('a-team', 'large');
176
+ assert.ok(result !== null, 'Should find large tandem branding');
177
+ assert.ok(result.includes('/large/'), 'Should use large size directory');
178
+ });
179
+ // AC5: Falls back to standard portrait when tandem mode is inactive
180
+ it('should return null for a theme without tandem portraits', () => {
181
+ const result = resolveTandemBrandingPath('nonexistent-theme');
182
+ assert.strictEqual(result, null, 'Should return null for unknown theme');
183
+ });
184
+ it('should return a .png file path', () => {
185
+ const result = resolveTandemBrandingPath('a-team');
186
+ assert.ok(result !== null, 'Should find tandem branding');
187
+ assert.ok(result.endsWith('.png'), 'Should be a PNG file');
188
+ });
189
+ it('should work for stephen-king theme', () => {
190
+ // Verify multiple themes work, not just one
191
+ const result = resolveTandemBrandingPath('stephen-king');
192
+ assert.ok(result !== null, 'Should find tandem branding for stephen-king');
193
+ assert.ok(result.includes('stephen-king'), 'Path should include theme');
194
+ assert.ok(result.includes('cyclist-tandem'), 'Path should include cyclist-tandem');
195
+ });
196
+ it('should work for monty-python theme', () => {
197
+ const result = resolveTandemBrandingPath('monty-python');
198
+ assert.ok(result !== null, 'Should find tandem branding for monty-python');
199
+ assert.ok(result.includes('monty-python'), 'Path should include theme');
200
+ });
201
+ });
156
202
  });
157
203
  //# sourceMappingURL=portrait-resolver.test.js.map