@pennyfarthing/core 6.6.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 (599) hide show
  1. package/README.md +293 -0
  2. package/package.json +58 -0
  3. package/packages/core/bin/pennyfarthing.js +14 -0
  4. package/packages/core/dist/bmad/context-reader.d.ts +71 -0
  5. package/packages/core/dist/bmad/context-reader.d.ts.map +1 -0
  6. package/packages/core/dist/bmad/context-reader.js +369 -0
  7. package/packages/core/dist/bmad/context-reader.js.map +1 -0
  8. package/packages/core/dist/bmad/context-reader.test.d.ts +71 -0
  9. package/packages/core/dist/bmad/context-reader.test.d.ts.map +1 -0
  10. package/packages/core/dist/bmad/context-reader.test.js +878 -0
  11. package/packages/core/dist/bmad/context-reader.test.js.map +1 -0
  12. package/packages/core/dist/bmad/epics-parser.d.ts +61 -0
  13. package/packages/core/dist/bmad/epics-parser.d.ts.map +1 -0
  14. package/packages/core/dist/bmad/epics-parser.js +331 -0
  15. package/packages/core/dist/bmad/epics-parser.js.map +1 -0
  16. package/packages/core/dist/bmad/epics-parser.test.d.ts +7 -0
  17. package/packages/core/dist/bmad/epics-parser.test.d.ts.map +1 -0
  18. package/packages/core/dist/bmad/epics-parser.test.js +449 -0
  19. package/packages/core/dist/bmad/epics-parser.test.js.map +1 -0
  20. package/packages/core/dist/bmad/index.d.ts +11 -0
  21. package/packages/core/dist/bmad/index.d.ts.map +1 -0
  22. package/packages/core/dist/bmad/index.js +24 -0
  23. package/packages/core/dist/bmad/index.js.map +1 -0
  24. package/packages/core/dist/bmad/status-sync.d.ts +173 -0
  25. package/packages/core/dist/bmad/status-sync.d.ts.map +1 -0
  26. package/packages/core/dist/bmad/status-sync.js +463 -0
  27. package/packages/core/dist/bmad/status-sync.js.map +1 -0
  28. package/packages/core/dist/bmad/status-sync.test.d.ts +7 -0
  29. package/packages/core/dist/bmad/status-sync.test.d.ts.map +1 -0
  30. package/packages/core/dist/bmad/status-sync.test.js +702 -0
  31. package/packages/core/dist/bmad/status-sync.test.js.map +1 -0
  32. package/packages/core/dist/bmad/story-exporter.d.ts +55 -0
  33. package/packages/core/dist/bmad/story-exporter.d.ts.map +1 -0
  34. package/packages/core/dist/bmad/story-exporter.js +170 -0
  35. package/packages/core/dist/bmad/story-exporter.js.map +1 -0
  36. package/packages/core/dist/bmad/story-exporter.test.d.ts +51 -0
  37. package/packages/core/dist/bmad/story-exporter.test.d.ts.map +1 -0
  38. package/packages/core/dist/bmad/story-exporter.test.js +603 -0
  39. package/packages/core/dist/bmad/story-exporter.test.js.map +1 -0
  40. package/packages/core/dist/bmad/story-parser.d.ts +44 -0
  41. package/packages/core/dist/bmad/story-parser.d.ts.map +1 -0
  42. package/packages/core/dist/bmad/story-parser.js +307 -0
  43. package/packages/core/dist/bmad/story-parser.js.map +1 -0
  44. package/packages/core/dist/bmad/story-parser.test.d.ts +44 -0
  45. package/packages/core/dist/bmad/story-parser.test.d.ts.map +1 -0
  46. package/packages/core/dist/bmad/story-parser.test.js +693 -0
  47. package/packages/core/dist/bmad/story-parser.test.js.map +1 -0
  48. package/packages/core/dist/cli/commands/command.d.ts +28 -0
  49. package/packages/core/dist/cli/commands/command.d.ts.map +1 -0
  50. package/packages/core/dist/cli/commands/command.js +399 -0
  51. package/packages/core/dist/cli/commands/command.js.map +1 -0
  52. package/packages/core/dist/cli/commands/cyclist.d.ts +46 -0
  53. package/packages/core/dist/cli/commands/cyclist.d.ts.map +1 -0
  54. package/packages/core/dist/cli/commands/cyclist.js +191 -0
  55. package/packages/core/dist/cli/commands/cyclist.js.map +1 -0
  56. package/packages/core/dist/cli/commands/cyclist.test.d.ts +13 -0
  57. package/packages/core/dist/cli/commands/cyclist.test.d.ts.map +1 -0
  58. package/packages/core/dist/cli/commands/cyclist.test.js +243 -0
  59. package/packages/core/dist/cli/commands/cyclist.test.js.map +1 -0
  60. package/packages/core/dist/cli/commands/doctor.d.ts +9 -0
  61. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -0
  62. package/packages/core/dist/cli/commands/doctor.js +652 -0
  63. package/packages/core/dist/cli/commands/doctor.js.map +1 -0
  64. package/packages/core/dist/cli/commands/init.d.ts +8 -0
  65. package/packages/core/dist/cli/commands/init.d.ts.map +1 -0
  66. package/packages/core/dist/cli/commands/init.js +524 -0
  67. package/packages/core/dist/cli/commands/init.js.map +1 -0
  68. package/packages/core/dist/cli/commands/skill.d.ts +28 -0
  69. package/packages/core/dist/cli/commands/skill.d.ts.map +1 -0
  70. package/packages/core/dist/cli/commands/skill.js +416 -0
  71. package/packages/core/dist/cli/commands/skill.js.map +1 -0
  72. package/packages/core/dist/cli/commands/theme.d.ts +21 -0
  73. package/packages/core/dist/cli/commands/theme.d.ts.map +1 -0
  74. package/packages/core/dist/cli/commands/theme.js +201 -0
  75. package/packages/core/dist/cli/commands/theme.js.map +1 -0
  76. package/packages/core/dist/cli/commands/uninstall.d.ts +8 -0
  77. package/packages/core/dist/cli/commands/uninstall.d.ts.map +1 -0
  78. package/packages/core/dist/cli/commands/uninstall.js +237 -0
  79. package/packages/core/dist/cli/commands/uninstall.js.map +1 -0
  80. package/packages/core/dist/cli/commands/update.d.ts +9 -0
  81. package/packages/core/dist/cli/commands/update.d.ts.map +1 -0
  82. package/packages/core/dist/cli/commands/update.js +545 -0
  83. package/packages/core/dist/cli/commands/update.js.map +1 -0
  84. package/packages/core/dist/cli/commands/version.d.ts +2 -0
  85. package/packages/core/dist/cli/commands/version.d.ts.map +1 -0
  86. package/packages/core/dist/cli/commands/version.js +28 -0
  87. package/packages/core/dist/cli/commands/version.js.map +1 -0
  88. package/packages/core/dist/cli/customization.test.d.ts +12 -0
  89. package/packages/core/dist/cli/customization.test.d.ts.map +1 -0
  90. package/packages/core/dist/cli/customization.test.js +84 -0
  91. package/packages/core/dist/cli/customization.test.js.map +1 -0
  92. package/packages/core/dist/cli/cyclist-migration.test.d.ts +16 -0
  93. package/packages/core/dist/cli/cyclist-migration.test.d.ts.map +1 -0
  94. package/packages/core/dist/cli/cyclist-migration.test.js +224 -0
  95. package/packages/core/dist/cli/cyclist-migration.test.js.map +1 -0
  96. package/packages/core/dist/cli/index.d.ts +3 -0
  97. package/packages/core/dist/cli/index.d.ts.map +1 -0
  98. package/packages/core/dist/cli/index.js +174 -0
  99. package/packages/core/dist/cli/index.js.map +1 -0
  100. package/packages/core/dist/cli/ocean-profiles.test.d.ts +13 -0
  101. package/packages/core/dist/cli/ocean-profiles.test.d.ts.map +1 -0
  102. package/packages/core/dist/cli/ocean-profiles.test.js +134 -0
  103. package/packages/core/dist/cli/ocean-profiles.test.js.map +1 -0
  104. package/packages/core/dist/cli/theme-maker.test.d.ts +11 -0
  105. package/packages/core/dist/cli/theme-maker.test.d.ts.map +1 -0
  106. package/packages/core/dist/cli/theme-maker.test.js +356 -0
  107. package/packages/core/dist/cli/theme-maker.test.js.map +1 -0
  108. package/packages/core/dist/cli/utils/constants.d.ts +60 -0
  109. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -0
  110. package/packages/core/dist/cli/utils/constants.js +52 -0
  111. package/packages/core/dist/cli/utils/constants.js.map +1 -0
  112. package/packages/core/dist/cli/utils/files.d.ts +71 -0
  113. package/packages/core/dist/cli/utils/files.d.ts.map +1 -0
  114. package/packages/core/dist/cli/utils/files.js +162 -0
  115. package/packages/core/dist/cli/utils/files.js.map +1 -0
  116. package/packages/core/dist/cli/utils/logger.d.ts +26 -0
  117. package/packages/core/dist/cli/utils/logger.d.ts.map +1 -0
  118. package/packages/core/dist/cli/utils/logger.js +88 -0
  119. package/packages/core/dist/cli/utils/logger.js.map +1 -0
  120. package/packages/core/dist/cli/utils/manifest.d.ts +47 -0
  121. package/packages/core/dist/cli/utils/manifest.d.ts.map +1 -0
  122. package/packages/core/dist/cli/utils/manifest.js +90 -0
  123. package/packages/core/dist/cli/utils/manifest.js.map +1 -0
  124. package/packages/core/dist/cli/utils/node-modules.d.ts +6 -0
  125. package/packages/core/dist/cli/utils/node-modules.d.ts.map +1 -0
  126. package/packages/core/dist/cli/utils/node-modules.js +22 -0
  127. package/packages/core/dist/cli/utils/node-modules.js.map +1 -0
  128. package/packages/core/dist/cli/utils/prompts.d.ts +34 -0
  129. package/packages/core/dist/cli/utils/prompts.d.ts.map +1 -0
  130. package/packages/core/dist/cli/utils/prompts.js +93 -0
  131. package/packages/core/dist/cli/utils/prompts.js.map +1 -0
  132. package/packages/core/dist/cli/utils/symlinks.d.ts +29 -0
  133. package/packages/core/dist/cli/utils/symlinks.d.ts.map +1 -0
  134. package/packages/core/dist/cli/utils/symlinks.js +181 -0
  135. package/packages/core/dist/cli/utils/symlinks.js.map +1 -0
  136. package/packages/core/dist/cli/utils/themes.d.ts +104 -0
  137. package/packages/core/dist/cli/utils/themes.d.ts.map +1 -0
  138. package/packages/core/dist/cli/utils/themes.js +393 -0
  139. package/packages/core/dist/cli/utils/themes.js.map +1 -0
  140. package/packages/core/dist/cli/utils/themes.test.d.ts +12 -0
  141. package/packages/core/dist/cli/utils/themes.test.d.ts.map +1 -0
  142. package/packages/core/dist/cli/utils/themes.test.js +144 -0
  143. package/packages/core/dist/cli/utils/themes.test.js.map +1 -0
  144. package/packages/core/dist/cli/utils/version.d.ts +10 -0
  145. package/packages/core/dist/cli/utils/version.d.ts.map +1 -0
  146. package/packages/core/dist/cli/utils/version.js +63 -0
  147. package/packages/core/dist/cli/utils/version.js.map +1 -0
  148. package/packages/core/dist/cli/workspace.test.d.ts +8 -0
  149. package/packages/core/dist/cli/workspace.test.d.ts.map +1 -0
  150. package/packages/core/dist/cli/workspace.test.js +154 -0
  151. package/packages/core/dist/cli/workspace.test.js.map +1 -0
  152. package/packages/core/dist/index.d.ts +6 -0
  153. package/packages/core/dist/index.d.ts.map +1 -0
  154. package/packages/core/dist/index.js +10 -0
  155. package/packages/core/dist/index.js.map +1 -0
  156. package/packages/core/dist/permissions/index.d.ts +9 -0
  157. package/packages/core/dist/permissions/index.d.ts.map +1 -0
  158. package/packages/core/dist/permissions/index.js +13 -0
  159. package/packages/core/dist/permissions/index.js.map +1 -0
  160. package/packages/core/dist/permissions/permission-schema.d.ts +89 -0
  161. package/packages/core/dist/permissions/permission-schema.d.ts.map +1 -0
  162. package/packages/core/dist/permissions/permission-schema.js +120 -0
  163. package/packages/core/dist/permissions/permission-schema.js.map +1 -0
  164. package/packages/core/dist/permissions/permission-schema.test.d.ts +40 -0
  165. package/packages/core/dist/permissions/permission-schema.test.d.ts.map +1 -0
  166. package/packages/core/dist/permissions/permission-schema.test.js +367 -0
  167. package/packages/core/dist/permissions/permission-schema.test.js.map +1 -0
  168. package/packages/core/dist/scripts/add-ocean-profiles.d.ts +9 -0
  169. package/packages/core/dist/scripts/add-ocean-profiles.d.ts.map +1 -0
  170. package/packages/core/dist/scripts/add-ocean-profiles.js +695 -0
  171. package/packages/core/dist/scripts/add-ocean-profiles.js.map +1 -0
  172. package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
  173. package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
  174. package/packages/core/dist/scripts/benchmark-integration.js +691 -0
  175. package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
  176. package/packages/core/dist/scripts/benchmark-integration.test.d.ts +13 -0
  177. package/packages/core/dist/scripts/benchmark-integration.test.d.ts.map +1 -0
  178. package/packages/core/dist/scripts/benchmark-integration.test.js +680 -0
  179. package/packages/core/dist/scripts/benchmark-integration.test.js.map +1 -0
  180. package/packages/core/dist/scripts/debugging-scenarios.test.d.ts +18 -0
  181. package/packages/core/dist/scripts/debugging-scenarios.test.d.ts.map +1 -0
  182. package/packages/core/dist/scripts/debugging-scenarios.test.js +317 -0
  183. package/packages/core/dist/scripts/debugging-scenarios.test.js.map +1 -0
  184. package/packages/core/dist/scripts/generate-all-faces.d.ts +10 -0
  185. package/packages/core/dist/scripts/generate-all-faces.d.ts.map +1 -0
  186. package/packages/core/dist/scripts/generate-all-faces.js +256 -0
  187. package/packages/core/dist/scripts/generate-all-faces.js.map +1 -0
  188. package/packages/core/dist/scripts/generate-all-faces.test.d.ts +17 -0
  189. package/packages/core/dist/scripts/generate-all-faces.test.d.ts.map +1 -0
  190. package/packages/core/dist/scripts/generate-all-faces.test.js +372 -0
  191. package/packages/core/dist/scripts/generate-all-faces.test.js.map +1 -0
  192. package/packages/core/dist/scripts/generate-all-spiders.d.ts +10 -0
  193. package/packages/core/dist/scripts/generate-all-spiders.d.ts.map +1 -0
  194. package/packages/core/dist/scripts/generate-all-spiders.js +306 -0
  195. package/packages/core/dist/scripts/generate-all-spiders.js.map +1 -0
  196. package/packages/core/dist/scripts/generate-ascii-face.d.ts +52 -0
  197. package/packages/core/dist/scripts/generate-ascii-face.d.ts.map +1 -0
  198. package/packages/core/dist/scripts/generate-ascii-face.js +155 -0
  199. package/packages/core/dist/scripts/generate-ascii-face.js.map +1 -0
  200. package/packages/core/dist/scripts/generate-face.d.ts +52 -0
  201. package/packages/core/dist/scripts/generate-face.d.ts.map +1 -0
  202. package/packages/core/dist/scripts/generate-face.js +199 -0
  203. package/packages/core/dist/scripts/generate-face.js.map +1 -0
  204. package/packages/core/dist/scripts/generate-face.test.d.ts +13 -0
  205. package/packages/core/dist/scripts/generate-face.test.d.ts.map +1 -0
  206. package/packages/core/dist/scripts/generate-face.test.js +301 -0
  207. package/packages/core/dist/scripts/generate-face.test.js.map +1 -0
  208. package/packages/core/dist/scripts/generate-report.d.ts +65 -0
  209. package/packages/core/dist/scripts/generate-report.d.ts.map +1 -0
  210. package/packages/core/dist/scripts/generate-report.js +378 -0
  211. package/packages/core/dist/scripts/generate-report.js.map +1 -0
  212. package/packages/core/dist/scripts/generate-report.test.d.ts +13 -0
  213. package/packages/core/dist/scripts/generate-report.test.d.ts.map +1 -0
  214. package/packages/core/dist/scripts/generate-report.test.js +363 -0
  215. package/packages/core/dist/scripts/generate-report.test.js.map +1 -0
  216. package/packages/core/dist/scripts/generate-spider-report.d.ts +65 -0
  217. package/packages/core/dist/scripts/generate-spider-report.d.ts.map +1 -0
  218. package/packages/core/dist/scripts/generate-spider-report.js +366 -0
  219. package/packages/core/dist/scripts/generate-spider-report.js.map +1 -0
  220. package/packages/core/dist/scripts/generate-spider-report.test.d.ts +13 -0
  221. package/packages/core/dist/scripts/generate-spider-report.test.d.ts.map +1 -0
  222. package/packages/core/dist/scripts/generate-spider-report.test.js +367 -0
  223. package/packages/core/dist/scripts/generate-spider-report.test.js.map +1 -0
  224. package/packages/core/dist/scripts/generate-spider.d.ts +37 -0
  225. package/packages/core/dist/scripts/generate-spider.d.ts.map +1 -0
  226. package/packages/core/dist/scripts/generate-spider.js +315 -0
  227. package/packages/core/dist/scripts/generate-spider.js.map +1 -0
  228. package/packages/core/dist/scripts/generate-spider.test.d.ts +14 -0
  229. package/packages/core/dist/scripts/generate-spider.test.d.ts.map +1 -0
  230. package/packages/core/dist/scripts/generate-spider.test.js +269 -0
  231. package/packages/core/dist/scripts/generate-spider.test.js.map +1 -0
  232. package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
  233. package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
  234. package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
  235. package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
  236. package/packages/core/dist/scripts/job-fair-aggregator.test.d.ts +14 -0
  237. package/packages/core/dist/scripts/job-fair-aggregator.test.d.ts.map +1 -0
  238. package/packages/core/dist/scripts/job-fair-aggregator.test.js +616 -0
  239. package/packages/core/dist/scripts/job-fair-aggregator.test.js.map +1 -0
  240. package/packages/core/dist/scripts/run-ci.test.d.ts +20 -0
  241. package/packages/core/dist/scripts/run-ci.test.d.ts.map +1 -0
  242. package/packages/core/dist/scripts/run-ci.test.js +127 -0
  243. package/packages/core/dist/scripts/run-ci.test.js.map +1 -0
  244. package/packages/core/dist/scripts/theme-detail.test.d.ts +10 -0
  245. package/packages/core/dist/scripts/theme-detail.test.d.ts.map +1 -0
  246. package/packages/core/dist/scripts/theme-detail.test.js +199 -0
  247. package/packages/core/dist/scripts/theme-detail.test.js.map +1 -0
  248. package/packages/core/dist/scripts/validate-ocean-profiles.d.ts +9 -0
  249. package/packages/core/dist/scripts/validate-ocean-profiles.d.ts.map +1 -0
  250. package/packages/core/dist/scripts/validate-ocean-profiles.js +130 -0
  251. package/packages/core/dist/scripts/validate-ocean-profiles.js.map +1 -0
  252. package/packages/core/dist/workflow/generic-handoff.d.ts +235 -0
  253. package/packages/core/dist/workflow/generic-handoff.d.ts.map +1 -0
  254. package/packages/core/dist/workflow/generic-handoff.js +358 -0
  255. package/packages/core/dist/workflow/generic-handoff.js.map +1 -0
  256. package/packages/core/dist/workflow/generic-handoff.test.d.ts +21 -0
  257. package/packages/core/dist/workflow/generic-handoff.test.d.ts.map +1 -0
  258. package/packages/core/dist/workflow/generic-handoff.test.js +499 -0
  259. package/packages/core/dist/workflow/generic-handoff.test.js.map +1 -0
  260. package/packages/core/dist/workflow/generic-sm-finish.d.ts +89 -0
  261. package/packages/core/dist/workflow/generic-sm-finish.d.ts.map +1 -0
  262. package/packages/core/dist/workflow/generic-sm-finish.js +157 -0
  263. package/packages/core/dist/workflow/generic-sm-finish.js.map +1 -0
  264. package/packages/core/dist/workflow/generic-sm-setup.d.ts +138 -0
  265. package/packages/core/dist/workflow/generic-sm-setup.d.ts.map +1 -0
  266. package/packages/core/dist/workflow/generic-sm-setup.js +382 -0
  267. package/packages/core/dist/workflow/generic-sm-setup.js.map +1 -0
  268. package/packages/core/dist/workflow/sm-subagents.test.d.ts +23 -0
  269. package/packages/core/dist/workflow/sm-subagents.test.d.ts.map +1 -0
  270. package/packages/core/dist/workflow/sm-subagents.test.js +727 -0
  271. package/packages/core/dist/workflow/sm-subagents.test.js.map +1 -0
  272. package/packages/core/dist/workflow/story-workflow-routing.test.d.ts +17 -0
  273. package/packages/core/dist/workflow/story-workflow-routing.test.d.ts.map +1 -0
  274. package/packages/core/dist/workflow/story-workflow-routing.test.js +559 -0
  275. package/packages/core/dist/workflow/story-workflow-routing.test.js.map +1 -0
  276. package/packages/core/dist/workflow/test-cache.d.ts +131 -0
  277. package/packages/core/dist/workflow/test-cache.d.ts.map +1 -0
  278. package/packages/core/dist/workflow/test-cache.js +226 -0
  279. package/packages/core/dist/workflow/test-cache.js.map +1 -0
  280. package/packages/core/dist/workflow/test-cache.test.d.ts +17 -0
  281. package/packages/core/dist/workflow/test-cache.test.d.ts.map +1 -0
  282. package/packages/core/dist/workflow/test-cache.test.js +438 -0
  283. package/packages/core/dist/workflow/test-cache.test.js.map +1 -0
  284. package/packages/core/dist/workflow/workflow-loader.d.ts +76 -0
  285. package/packages/core/dist/workflow/workflow-loader.d.ts.map +1 -0
  286. package/packages/core/dist/workflow/workflow-loader.js +133 -0
  287. package/packages/core/dist/workflow/workflow-loader.js.map +1 -0
  288. package/packages/core/dist/workflow/workflow-loader.test.d.ts +15 -0
  289. package/packages/core/dist/workflow/workflow-loader.test.d.ts.map +1 -0
  290. package/packages/core/dist/workflow/workflow-loader.test.js +354 -0
  291. package/packages/core/dist/workflow/workflow-loader.test.js.map +1 -0
  292. package/packages/core/dist/workflow/workflow-migration.test.d.ts +17 -0
  293. package/packages/core/dist/workflow/workflow-migration.test.d.ts.map +1 -0
  294. package/packages/core/dist/workflow/workflow-migration.test.js +372 -0
  295. package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -0
  296. package/packages/core/dist/workflow/workflow-router.d.ts +55 -0
  297. package/packages/core/dist/workflow/workflow-router.d.ts.map +1 -0
  298. package/packages/core/dist/workflow/workflow-router.js +245 -0
  299. package/packages/core/dist/workflow/workflow-router.js.map +1 -0
  300. package/packages/core/dist/workflow/workflow-router.test.d.ts +20 -0
  301. package/packages/core/dist/workflow/workflow-router.test.d.ts.map +1 -0
  302. package/packages/core/dist/workflow/workflow-router.test.js +607 -0
  303. package/packages/core/dist/workflow/workflow-router.test.js.map +1 -0
  304. package/packages/core/dist/workflow/workflow-schema.d.ts +98 -0
  305. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -0
  306. package/packages/core/dist/workflow/workflow-schema.js +230 -0
  307. package/packages/core/dist/workflow/workflow-schema.js.map +1 -0
  308. package/packages/core/dist/workflow/workflow-schema.test.d.ts +45 -0
  309. package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -0
  310. package/packages/core/dist/workflow/workflow-schema.test.js +512 -0
  311. package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -0
  312. package/pennyfarthing-dist/agents/README.md +397 -0
  313. package/pennyfarthing-dist/agents/architect.md +171 -0
  314. package/pennyfarthing-dist/agents/dev.md +225 -0
  315. package/pennyfarthing-dist/agents/devops.md +183 -0
  316. package/pennyfarthing-dist/agents/generic-handoff.md +451 -0
  317. package/pennyfarthing-dist/agents/generic-sm-finish.md +261 -0
  318. package/pennyfarthing-dist/agents/generic-sm-setup.md +214 -0
  319. package/pennyfarthing-dist/agents/orchestrator.md +316 -0
  320. package/pennyfarthing-dist/agents/pm.md +153 -0
  321. package/pennyfarthing-dist/agents/reviewer-preflight.md +224 -0
  322. package/pennyfarthing-dist/agents/reviewer.md +315 -0
  323. package/pennyfarthing-dist/agents/sm-file-summary.md +109 -0
  324. package/pennyfarthing-dist/agents/sm-handoff.md +97 -0
  325. package/pennyfarthing-dist/agents/sm.md +480 -0
  326. package/pennyfarthing-dist/agents/tea.md +191 -0
  327. package/pennyfarthing-dist/agents/tech-writer.md +148 -0
  328. package/pennyfarthing-dist/agents/testing-runner.md +420 -0
  329. package/pennyfarthing-dist/agents/ux-designer.md +158 -0
  330. package/pennyfarthing-dist/agents/workflow-status-check.md +332 -0
  331. package/pennyfarthing-dist/commands/architect.md +62 -0
  332. package/pennyfarthing-dist/commands/benchmark-control.md +69 -0
  333. package/pennyfarthing-dist/commands/benchmark.md +467 -0
  334. package/pennyfarthing-dist/commands/brainstorm.md +91 -0
  335. package/pennyfarthing-dist/commands/check.md +156 -0
  336. package/pennyfarthing-dist/commands/chore.md +178 -0
  337. package/pennyfarthing-dist/commands/close-epic.md +136 -0
  338. package/pennyfarthing-dist/commands/continue-session.md +184 -0
  339. package/pennyfarthing-dist/commands/create-branches-from-story.md +374 -0
  340. package/pennyfarthing-dist/commands/create-theme.md +29 -0
  341. package/pennyfarthing-dist/commands/dev.md +60 -0
  342. package/pennyfarthing-dist/commands/devops.md +59 -0
  343. package/pennyfarthing-dist/commands/git-cleanup.md +340 -0
  344. package/pennyfarthing-dist/commands/health-check.md +108 -0
  345. package/pennyfarthing-dist/commands/help.md +264 -0
  346. package/pennyfarthing-dist/commands/job-fair.md +102 -0
  347. package/pennyfarthing-dist/commands/list-themes.md +17 -0
  348. package/pennyfarthing-dist/commands/new-work.md +127 -0
  349. package/pennyfarthing-dist/commands/orchestrator.md +56 -0
  350. package/pennyfarthing-dist/commands/parallel-work.md +71 -0
  351. package/pennyfarthing-dist/commands/party-mode.md +67 -0
  352. package/pennyfarthing-dist/commands/permissions.md +193 -0
  353. package/pennyfarthing-dist/commands/pm.md +60 -0
  354. package/pennyfarthing-dist/commands/prime.md +140 -0
  355. package/pennyfarthing-dist/commands/release.md +58 -0
  356. package/pennyfarthing-dist/commands/repo-status.md +49 -0
  357. package/pennyfarthing-dist/commands/retro.md +200 -0
  358. package/pennyfarthing-dist/commands/reviewer.md +64 -0
  359. package/pennyfarthing-dist/commands/run-ci.md +116 -0
  360. package/pennyfarthing-dist/commands/set-theme.md +52 -0
  361. package/pennyfarthing-dist/commands/show-theme.md +21 -0
  362. package/pennyfarthing-dist/commands/sm.md +70 -0
  363. package/pennyfarthing-dist/commands/solo.md +411 -0
  364. package/pennyfarthing-dist/commands/sprint-planning.md +109 -0
  365. package/pennyfarthing-dist/commands/start-epic.md +156 -0
  366. package/pennyfarthing-dist/commands/sync-epic-to-jira.md +184 -0
  367. package/pennyfarthing-dist/commands/sync-work-with-sprint.md +376 -0
  368. package/pennyfarthing-dist/commands/tea.md +63 -0
  369. package/pennyfarthing-dist/commands/tech-writer.md +53 -0
  370. package/pennyfarthing-dist/commands/theme-maker.md +671 -0
  371. package/pennyfarthing-dist/commands/update-domain-docs.md +83 -0
  372. package/pennyfarthing-dist/commands/ux-designer.md +62 -0
  373. package/pennyfarthing-dist/commands/work.md +111 -0
  374. package/pennyfarthing-dist/guides/AGENT-COORDINATION.md +480 -0
  375. package/pennyfarthing-dist/guides/AGENT-SCOPES.md +201 -0
  376. package/pennyfarthing-dist/guides/HOOKS.md +230 -0
  377. package/pennyfarthing-dist/guides/PROMPT-PATTERNS.md +338 -0
  378. package/pennyfarthing-dist/guides/SESSION-ARTIFACTS.md +193 -0
  379. package/pennyfarthing-dist/guides/agent-template-strategic.md +148 -0
  380. package/pennyfarthing-dist/guides/agent-template-tactical.md +162 -0
  381. package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +746 -0
  382. package/pennyfarthing-dist/guides/patterns/fan-out-fan-in-pattern.md +574 -0
  383. package/pennyfarthing-dist/guides/patterns/helper-delegation-pattern.md +488 -0
  384. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +402 -0
  385. package/pennyfarthing-dist/guides/permission-protocol.md +188 -0
  386. package/pennyfarthing-dist/guides/persona-loading.md +46 -0
  387. package/pennyfarthing-dist/guides/persona-system.md +294 -0
  388. package/pennyfarthing-dist/guides/shared-agent-behavior.md +388 -0
  389. package/pennyfarthing-dist/guides/shared-context.md +147 -0
  390. package/pennyfarthing-dist/guides/strategic-agent-behavior.md +348 -0
  391. package/pennyfarthing-dist/guides/tactical-agent-behavior.md +1041 -0
  392. package/pennyfarthing-dist/guides/workflow-schema.md +195 -0
  393. package/pennyfarthing-dist/guides/worktree-mode.md +113 -0
  394. package/pennyfarthing-dist/output-styles/teaching.md +33 -0
  395. package/pennyfarthing-dist/output-styles/terse.md +20 -0
  396. package/pennyfarthing-dist/output-styles/verbose.md +28 -0
  397. package/pennyfarthing-dist/personas/themes/1984.yaml +312 -0
  398. package/pennyfarthing-dist/personas/themes/a-team.yaml +207 -0
  399. package/pennyfarthing-dist/personas/themes/agatha-christie.yaml +300 -0
  400. package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +330 -0
  401. package/pennyfarthing-dist/personas/themes/all-stars.yaml +332 -0
  402. package/pennyfarthing-dist/personas/themes/ancient-philosophers.yaml +320 -0
  403. package/pennyfarthing-dist/personas/themes/ancient-strategists.yaml +306 -0
  404. package/pennyfarthing-dist/personas/themes/arcane.yaml +288 -0
  405. package/pennyfarthing-dist/personas/themes/arthurian-mythos.yaml +331 -0
  406. package/pennyfarthing-dist/personas/themes/avatar-the-last-airbender.yaml +288 -0
  407. package/pennyfarthing-dist/personas/themes/babylon-5.yaml +288 -0
  408. package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +288 -0
  409. package/pennyfarthing-dist/personas/themes/better-call-saul.yaml +288 -0
  410. package/pennyfarthing-dist/personas/themes/big-lebowski.yaml +300 -0
  411. package/pennyfarthing-dist/personas/themes/black-sails.yaml +300 -0
  412. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +295 -0
  413. package/pennyfarthing-dist/personas/themes/bobiverse.yaml +288 -0
  414. package/pennyfarthing-dist/personas/themes/breaking-bad.yaml +327 -0
  415. package/pennyfarthing-dist/personas/themes/catch-22.yaml +316 -0
  416. package/pennyfarthing-dist/personas/themes/classical-composers.yaml +310 -0
  417. package/pennyfarthing-dist/personas/themes/control.yaml +197 -0
  418. package/pennyfarthing-dist/personas/themes/count-of-monte-cristo.yaml +320 -0
  419. package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +323 -0
  420. package/pennyfarthing-dist/personas/themes/deadwood.yaml +300 -0
  421. package/pennyfarthing-dist/personas/themes/dickens.yaml +320 -0
  422. package/pennyfarthing-dist/personas/themes/discworld.yaml +332 -0
  423. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +290 -0
  424. package/pennyfarthing-dist/personas/themes/don-quixote.yaml +320 -0
  425. package/pennyfarthing-dist/personas/themes/dune.yaml +307 -0
  426. package/pennyfarthing-dist/personas/themes/enlightenment-thinkers.yaml +320 -0
  427. package/pennyfarthing-dist/personas/themes/expeditionary-force.yaml +288 -0
  428. package/pennyfarthing-dist/personas/themes/fargo.yaml +330 -0
  429. package/pennyfarthing-dist/personas/themes/film-auteurs.yaml +312 -0
  430. package/pennyfarthing-dist/personas/themes/firefly.yaml +328 -0
  431. package/pennyfarthing-dist/personas/themes/foundation.yaml +290 -0
  432. package/pennyfarthing-dist/personas/themes/futurama.yaml +321 -0
  433. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +290 -0
  434. package/pennyfarthing-dist/personas/themes/gilligans-island.yaml +243 -0
  435. package/pennyfarthing-dist/personas/themes/gothic-literature.yaml +308 -0
  436. package/pennyfarthing-dist/personas/themes/great-gatsby.yaml +308 -0
  437. package/pennyfarthing-dist/personas/themes/greek-mythology.yaml +330 -0
  438. package/pennyfarthing-dist/personas/themes/hannibal.yaml +300 -0
  439. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +324 -0
  440. package/pennyfarthing-dist/personas/themes/his-dark-materials.yaml +291 -0
  441. package/pennyfarthing-dist/personas/themes/historical-figures.yaml +288 -0
  442. package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +331 -0
  443. package/pennyfarthing-dist/personas/themes/house-md.yaml +321 -0
  444. package/pennyfarthing-dist/personas/themes/imperial-radch.yaml +289 -0
  445. package/pennyfarthing-dist/personas/themes/inspector-morse.yaml +300 -0
  446. package/pennyfarthing-dist/personas/themes/jane-austen.yaml +287 -0
  447. package/pennyfarthing-dist/personas/themes/jazz-legends.yaml +320 -0
  448. package/pennyfarthing-dist/personas/themes/justified.yaml +300 -0
  449. package/pennyfarthing-dist/personas/themes/legion-of-doom.yaml +219 -0
  450. package/pennyfarthing-dist/personas/themes/les-miserables.yaml +299 -0
  451. package/pennyfarthing-dist/personas/themes/lord-of-the-rings.yaml +334 -0
  452. package/pennyfarthing-dist/personas/themes/lovecraft-mythos.yaml +334 -0
  453. package/pennyfarthing-dist/personas/themes/mad-max.yaml +355 -0
  454. package/pennyfarthing-dist/personas/themes/mad-men.yaml +289 -0
  455. package/pennyfarthing-dist/personas/themes/marvel-mcu.yaml +300 -0
  456. package/pennyfarthing-dist/personas/themes/mash.yaml +334 -0
  457. package/pennyfarthing-dist/personas/themes/mass-effect.yaml +289 -0
  458. package/pennyfarthing-dist/personas/themes/military-commanders.yaml +306 -0
  459. package/pennyfarthing-dist/personas/themes/moby-dick.yaml +320 -0
  460. package/pennyfarthing-dist/personas/themes/monty-python.yaml +303 -0
  461. package/pennyfarthing-dist/personas/themes/neuromancer.yaml +300 -0
  462. package/pennyfarthing-dist/personas/themes/norse-mythology.yaml +329 -0
  463. package/pennyfarthing-dist/personas/themes/parks-and-rec.yaml +242 -0
  464. package/pennyfarthing-dist/personas/themes/peaky-blinders.yaml +298 -0
  465. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +220 -0
  466. package/pennyfarthing-dist/personas/themes/renaissance-masters.yaml +320 -0
  467. package/pennyfarthing-dist/personas/themes/rome.yaml +300 -0
  468. package/pennyfarthing-dist/personas/themes/russian-masters.yaml +318 -0
  469. package/pennyfarthing-dist/personas/themes/sandman.yaml +288 -0
  470. package/pennyfarthing-dist/personas/themes/scientific-revolutionaries.yaml +320 -0
  471. package/pennyfarthing-dist/personas/themes/shakespeare.yaml +301 -0
  472. package/pennyfarthing-dist/personas/themes/sherlock-holmes.yaml +289 -0
  473. package/pennyfarthing-dist/personas/themes/snow-crash.yaml +288 -0
  474. package/pennyfarthing-dist/personas/themes/software-pioneers.yaml +300 -0
  475. package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +230 -0
  476. package/pennyfarthing-dist/personas/themes/star-trek-tos.yaml +210 -0
  477. package/pennyfarthing-dist/personas/themes/star-wars.yaml +303 -0
  478. package/pennyfarthing-dist/personas/themes/succession.yaml +300 -0
  479. package/pennyfarthing-dist/personas/themes/superfriends.yaml +208 -0
  480. package/pennyfarthing-dist/personas/themes/ted-lasso.yaml +236 -0
  481. package/pennyfarthing-dist/personas/themes/the-americans.yaml +300 -0
  482. package/pennyfarthing-dist/personas/themes/the-crown.yaml +300 -0
  483. package/pennyfarthing-dist/personas/themes/the-expanse.yaml +213 -0
  484. package/pennyfarthing-dist/personas/themes/the-good-place.yaml +322 -0
  485. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +353 -0
  486. package/pennyfarthing-dist/personas/themes/the-odyssey.yaml +300 -0
  487. package/pennyfarthing-dist/personas/themes/the-office.yaml +330 -0
  488. package/pennyfarthing-dist/personas/themes/the-simpsons.yaml +308 -0
  489. package/pennyfarthing-dist/personas/themes/the-sopranos.yaml +300 -0
  490. package/pennyfarthing-dist/personas/themes/the-wire.yaml +311 -0
  491. package/pennyfarthing-dist/personas/themes/the-witcher.yaml +300 -0
  492. package/pennyfarthing-dist/personas/themes/twin-peaks.yaml +302 -0
  493. package/pennyfarthing-dist/personas/themes/vorkosigan-saga.yaml +300 -0
  494. package/pennyfarthing-dist/personas/themes/watchmen.yaml +291 -0
  495. package/pennyfarthing-dist/personas/themes/west-wing.yaml +291 -0
  496. package/pennyfarthing-dist/personas/themes/world-explorers.yaml +320 -0
  497. package/pennyfarthing-dist/personas/themes/wwii-leaders.yaml +307 -0
  498. package/pennyfarthing-dist/personas/themes/x-files.yaml +302 -0
  499. package/pennyfarthing-dist/scripts/add-short-names.mjs +264 -0
  500. package/pennyfarthing-dist/scripts/agent-session.sh +367 -0
  501. package/pennyfarthing-dist/scripts/check-context.sh +187 -0
  502. package/pennyfarthing-dist/scripts/check.sh +497 -0
  503. package/pennyfarthing-dist/scripts/deploy.sh +284 -0
  504. package/pennyfarthing-dist/scripts/doctor-dogfood.sh +360 -0
  505. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +61 -0
  506. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +66 -0
  507. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +35 -0
  508. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +166 -0
  509. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +50 -0
  510. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +71 -0
  511. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +54 -0
  512. package/pennyfarthing-dist/scripts/hooks/session-start.sh +98 -0
  513. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +59 -0
  514. package/pennyfarthing-dist/scripts/install-git-hooks.sh +91 -0
  515. package/pennyfarthing-dist/scripts/prime.sh +161 -0
  516. package/pennyfarthing-dist/scripts/release.sh +198 -0
  517. package/pennyfarthing-dist/scripts/repo-utils.sh +778 -0
  518. package/pennyfarthing-dist/scripts/run-ci.sh +219 -0
  519. package/pennyfarthing-dist/scripts/run.sh +65 -0
  520. package/pennyfarthing-dist/scripts/statusline.sh +264 -0
  521. package/pennyfarthing-dist/scripts/tests/check.test.sh +582 -0
  522. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +107 -0
  523. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +597 -0
  524. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +514 -0
  525. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +517 -0
  526. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +331 -0
  527. package/pennyfarthing-dist/scripts/uninstall.sh +271 -0
  528. package/pennyfarthing-dist/scripts/utils/background-tasks.sh +177 -0
  529. package/pennyfarthing-dist/scripts/utils/check-status.sh +251 -0
  530. package/pennyfarthing-dist/scripts/utils/checkpoint.sh +136 -0
  531. package/pennyfarthing-dist/scripts/utils/common.sh +157 -0
  532. package/pennyfarthing-dist/scripts/utils/create-feature-branches.sh +230 -0
  533. package/pennyfarthing-dist/scripts/utils/file-lock.sh +269 -0
  534. package/pennyfarthing-dist/scripts/utils/find-related-work.sh +231 -0
  535. package/pennyfarthing-dist/scripts/utils/find-root.sh +33 -0
  536. package/pennyfarthing-dist/scripts/utils/generate-skill-docs.sh +110 -0
  537. package/pennyfarthing-dist/scripts/utils/git-status-all.sh +127 -0
  538. package/pennyfarthing-dist/scripts/utils/ground-truth-judge.py +289 -0
  539. package/pennyfarthing-dist/scripts/utils/jira/jira-lib.mjs +443 -0
  540. package/pennyfarthing-dist/scripts/utils/jira/jira-sync-story.mjs +208 -0
  541. package/pennyfarthing-dist/scripts/utils/jira/jira-sync.mjs +198 -0
  542. package/pennyfarthing-dist/scripts/utils/jira-claim-story.sh +162 -0
  543. package/pennyfarthing-dist/scripts/utils/jira-lib.sh +463 -0
  544. package/pennyfarthing-dist/scripts/utils/jira-sync-story.sh +8 -0
  545. package/pennyfarthing-dist/scripts/utils/jira-sync.sh +8 -0
  546. package/pennyfarthing-dist/scripts/utils/log-skill-usage.sh +74 -0
  547. package/pennyfarthing-dist/scripts/utils/logging.sh +186 -0
  548. package/pennyfarthing-dist/scripts/utils/repo-scan.sh +141 -0
  549. package/pennyfarthing-dist/scripts/utils/retry.sh +76 -0
  550. package/pennyfarthing-dist/scripts/utils/run-timestamp.sh +7 -0
  551. package/pennyfarthing-dist/scripts/utils/session-cleanup.sh +319 -0
  552. package/pennyfarthing-dist/scripts/utils/skill-usage-report.sh +193 -0
  553. package/pennyfarthing-dist/scripts/utils/sprint-common.sh +286 -0
  554. package/pennyfarthing-dist/scripts/utils/sprint-metrics.sh +241 -0
  555. package/pennyfarthing-dist/scripts/utils/swebench-judge.py +400 -0
  556. package/pennyfarthing-dist/scripts/utils/sync-epic-to-jira.sh +16 -0
  557. package/pennyfarthing-dist/scripts/utils/test-setup.sh +337 -0
  558. package/pennyfarthing-dist/scripts/utils/validate-subagent-frontmatter.sh +160 -0
  559. package/pennyfarthing-dist/scripts/worktree-manager.sh +498 -0
  560. package/pennyfarthing-dist/skills/agentic-patterns/SKILL.md +236 -0
  561. package/pennyfarthing-dist/skills/changelog/SKILL.md +367 -0
  562. package/pennyfarthing-dist/skills/code-review/SKILL.md +168 -0
  563. package/pennyfarthing-dist/skills/context-engineering/SKILL.md +268 -0
  564. package/pennyfarthing-dist/skills/cyclist/SKILL.md +117 -0
  565. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +421 -0
  566. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +258 -0
  567. package/pennyfarthing-dist/skills/jira/SKILL.md +281 -0
  568. package/pennyfarthing-dist/skills/judge/SKILL.md +524 -0
  569. package/pennyfarthing-dist/skills/just/SKILL.md +160 -0
  570. package/pennyfarthing-dist/skills/mermaid/SKILL.md +240 -0
  571. package/pennyfarthing-dist/skills/otel/skill.md +222 -0
  572. package/pennyfarthing-dist/skills/permissions/skill.md +172 -0
  573. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +173 -0
  574. package/pennyfarthing-dist/skills/skill-registry.schema.json +102 -0
  575. package/pennyfarthing-dist/skills/skill-registry.yaml +335 -0
  576. package/pennyfarthing-dist/skills/sprint-context/SKILL.md +120 -0
  577. package/pennyfarthing-dist/skills/story-management/SKILL.md +208 -0
  578. package/pennyfarthing-dist/skills/testing/SKILL.md +99 -0
  579. package/pennyfarthing-dist/skills/testing/references/troubleshooting.md +124 -0
  580. package/pennyfarthing-dist/skills/theme/skill.md +129 -0
  581. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +169 -0
  582. package/pennyfarthing-dist/skills/workflow/SKILL.md +160 -0
  583. package/pennyfarthing-dist/skills/yq/SKILL.md +264 -0
  584. package/pennyfarthing-dist/templates/LEADERBOARD.schema.yaml +187 -0
  585. package/pennyfarthing-dist/templates/LEADERBOARD.template.md +59 -0
  586. package/pennyfarthing-dist/templates/agent-scopes.yaml.template +276 -0
  587. package/pennyfarthing-dist/templates/pennyfarthing-settings.yaml.template +61 -0
  588. package/pennyfarthing-dist/templates/persona-config.yaml.template +22 -0
  589. package/pennyfarthing-dist/templates/preferences.yaml.template +15 -0
  590. package/pennyfarthing-dist/templates/settings.local.json.template +90 -0
  591. package/pennyfarthing-dist/templates/setup-env.sh.template +18 -0
  592. package/pennyfarthing-dist/templates/shared-context.md.template +70 -0
  593. package/pennyfarthing-dist/templates/sidecar/decisions.md.template +40 -0
  594. package/pennyfarthing-dist/templates/sidecar/gotchas.md.template +37 -0
  595. package/pennyfarthing-dist/templates/sidecar/patterns.md.template +34 -0
  596. package/pennyfarthing-dist/workflows/agent-docs.yaml +70 -0
  597. package/pennyfarthing-dist/workflows/bdd.yaml +58 -0
  598. package/pennyfarthing-dist/workflows/tdd.yaml +50 -0
  599. package/pennyfarthing-dist/workflows/trivial.yaml +40 -0
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env zsh
2
+ # Common utility functions for Pennyfarthing scripts
3
+ # Source this file: source "${SCRIPT_DIR}/utils/common.sh"
4
+ #
5
+ # Provides:
6
+ # - Output helpers: success, info, warn, error
7
+ # - Dry-run check: dry_run_check
8
+ # - JQL escaping: escape_for_jql
9
+ # - Jira JSON helpers: get_issue_json, get_jira_field
10
+
11
+ #############################################
12
+ # Output Helpers
13
+ #############################################
14
+
15
+ # Color codes
16
+ _RED='\033[31m'
17
+ _GREEN='\033[32m'
18
+ _YELLOW='\033[33m'
19
+ _BLUE='\033[34m'
20
+ _NC='\033[0m' # No Color
21
+
22
+ # success MESSAGE
23
+ # Print a success message in green (to stderr for visibility)
24
+ success() {
25
+ echo -e "${_GREEN}[OK]${_NC} $1" >&2
26
+ }
27
+
28
+ # info MESSAGE
29
+ # Print an info message in blue (to stderr for visibility)
30
+ info() {
31
+ echo -e "${_BLUE}[INFO]${_NC} $1" >&2
32
+ }
33
+
34
+ # warn MESSAGE
35
+ # Print a warning message in yellow (to stderr for visibility)
36
+ warn() {
37
+ echo -e "${_YELLOW}[WARN]${_NC} $1" >&2
38
+ }
39
+
40
+ # error MESSAGE
41
+ # Print an error message in red (to stderr, does NOT exit)
42
+ error() {
43
+ echo -e "${_RED}[ERROR]${_NC} $1" >&2
44
+ }
45
+
46
+ #############################################
47
+ # Dry-Run Support
48
+ #############################################
49
+
50
+ # dry_run_check ACTION
51
+ # Check if DRY_RUN is enabled and print a warning
52
+ # Returns 0 if dry-run is active (caller should skip the action)
53
+ # Returns 1 if dry-run is NOT active (caller should proceed)
54
+ #
55
+ # Usage:
56
+ # if dry_run_check "create epic: $summary"; then
57
+ # echo "DRYRUN-EPIC-001"
58
+ # return
59
+ # fi
60
+ # # ... actual implementation
61
+ #
62
+ dry_run_check() {
63
+ local action="$1"
64
+ if [ "$DRY_RUN" = true ]; then
65
+ warn "[DRY-RUN] Would ${action}"
66
+ return 0
67
+ fi
68
+ return 1
69
+ }
70
+
71
+ #############################################
72
+ # JQL Helpers
73
+ #############################################
74
+
75
+ # escape_for_jql STRING
76
+ # Escape a string for use in JQL queries
77
+ # Escapes double quotes and other special characters
78
+ #
79
+ # Usage:
80
+ # local escaped=$(escape_for_jql "$summary")
81
+ # jira issue list --jql "summary~'${escaped}'"
82
+ #
83
+ escape_for_jql() {
84
+ echo "$1" | sed 's/"/\\"/g'
85
+ }
86
+
87
+ #############################################
88
+ # Jira JSON Helpers
89
+ #############################################
90
+
91
+ # get_issue_json ISSUE_KEY
92
+ # Fetch Jira issue as JSON with error handling
93
+ # Returns empty object {} if issue not found
94
+ # Sets exit code 1 if fetch failed
95
+ #
96
+ # Usage:
97
+ # local json=$(get_issue_json "PROJ-123")
98
+ # if [ -z "$json" ] || [ "$json" = "{}" ]; then
99
+ # warn "Could not fetch issue"
100
+ # fi
101
+ #
102
+ get_issue_json() {
103
+ local key="$1"
104
+ local json
105
+ json=$(jira issue view "$key" --raw 2>/dev/null)
106
+ if [ -z "$json" ]; then
107
+ echo "{}"
108
+ return 1
109
+ fi
110
+ echo "$json"
111
+ }
112
+
113
+ # get_jira_field JSON FIELD_PATH [DEFAULT]
114
+ # Extract a field from Jira issue JSON using jq
115
+ #
116
+ # Arguments:
117
+ # JSON - The JSON string to parse
118
+ # FIELD_PATH - jq path expression (e.g., '.fields.summary')
119
+ # DEFAULT - Optional default value if field is null/empty
120
+ #
121
+ # Usage:
122
+ # local summary=$(get_jira_field "$json" '.fields.summary')
123
+ # local points=$(get_jira_field "$json" '.fields.customfield_10031' '0')
124
+ #
125
+ get_jira_field() {
126
+ local json="$1"
127
+ local field_path="$2"
128
+ local default="${3:-}"
129
+
130
+ if [ -n "$default" ]; then
131
+ echo "$json" | jq -r "${field_path} // \"${default}\""
132
+ else
133
+ echo "$json" | jq -r "${field_path} // empty"
134
+ fi
135
+ }
136
+
137
+ #############################################
138
+ # Dependency Checks
139
+ #############################################
140
+
141
+ # check_dependencies
142
+ # Check for common required tools
143
+ # Can be extended with optional checks
144
+ check_dependencies() {
145
+ local missing=()
146
+
147
+ # Check for jq (required for JSON parsing)
148
+ if ! command -v jq &> /dev/null; then
149
+ missing+=("jq")
150
+ error "jq not found - install with: brew install jq"
151
+ fi
152
+
153
+ if [ ${#missing[@]} -gt 0 ]; then
154
+ return 1
155
+ fi
156
+ return 0
157
+ }
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env zsh
2
+ # Create or checkout feature branches in conductor repos
3
+ # Idempotent, worktree-aware, branches from develop
4
+
5
+ set -e
6
+
7
+ # Load environment
8
+ if [ -f .env ]; then
9
+ set -a; source .env; set +a
10
+ elif [ -f ../.env ]; then
11
+ set -a; source ../.env; set +a
12
+ fi
13
+
14
+ # Find project root
15
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
16
+ source "$SCRIPT_DIR/find-root.sh"
17
+
18
+ show_help() {
19
+ cat << EOF
20
+ Create Feature Branches - Idempotent branch creation/checkout
21
+
22
+ Usage: ./create-feature-branches.sh <branch-name> [repos]
23
+
24
+ Arguments:
25
+ branch-name Branch name (e.g., feat/11-2-file-preview)
26
+ repos Which repos to branch (default: all)
27
+ Options: api, ui, all
28
+
29
+ Repo Options:
30
+ api - conductor-api only
31
+ ui - conductor-ui only
32
+ all - both repos (default)
33
+
34
+ Examples:
35
+ # All repos (default)
36
+ ./create-feature-branches.sh feat/cross-repo-feature
37
+
38
+ # Conductor UI only
39
+ ./create-feature-branches.sh feat/11-2-ui-component ui
40
+
41
+ # Conductor API only
42
+ ./create-feature-branches.sh fix/validation-bug api
43
+
44
+ Behavior:
45
+ - Idempotent: Checks out existing branches or creates new ones
46
+ - Worktree-aware: Detects main checkout vs worktree
47
+ - Always branches from develop
48
+ - Fetches latest develop before branching
49
+
50
+ EOF
51
+ }
52
+
53
+ if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
54
+ show_help
55
+ exit 0
56
+ fi
57
+
58
+ BRANCH_NAME="$1"
59
+ REPOS="${2:-all}"
60
+
61
+ # Validate repos parameter
62
+ if [[ ! "$REPOS" =~ ^(api|ui|all)$ ]]; then
63
+ echo "❌ Error: repos must be one of: api, ui, all"
64
+ echo " Got: $REPOS"
65
+ echo ""
66
+ echo "Options:"
67
+ echo " api - conductor-api only"
68
+ echo " ui - conductor-ui only"
69
+ echo " all - both repos (default)"
70
+ exit 1
71
+ fi
72
+
73
+ # Detect if we're in a worktree
74
+ CURRENT_DIR=$(pwd)
75
+ if [[ "$CURRENT_DIR" == *"/worktrees/"* ]]; then
76
+ # Extract worktree name from path
77
+ WORKTREE_NAME=$(echo "$CURRENT_DIR" | sed -E 's|.*/worktrees/([^/]+).*|\1|')
78
+ REPO_BASE="$PROJECT_ROOT/worktrees/$WORKTREE_NAME"
79
+ echo "📂 Detected worktree: $WORKTREE_NAME"
80
+ else
81
+ REPO_BASE="$PROJECT_ROOT"
82
+ echo "📂 Using main checkout"
83
+ fi
84
+
85
+ # Array to track processed repos for verification
86
+ declare -a PROCESSED_REPOS
87
+
88
+ # Function to create or checkout branch in a repo
89
+ create_or_checkout_branch() {
90
+ local repo_path=$1
91
+ local repo_name=$2
92
+
93
+ if [ ! -d "$repo_path" ]; then
94
+ echo "⚠️ Skipping $repo_name: directory not found at $repo_path"
95
+ return
96
+ fi
97
+
98
+ cd "$repo_path"
99
+
100
+ echo ""
101
+ echo "🔧 Processing $repo_name..."
102
+
103
+ # Fetch latest from remote
104
+ echo " Fetching from origin..."
105
+ git fetch origin --quiet
106
+
107
+ # Check if branch exists locally
108
+ if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
109
+ echo " ✅ Branch exists locally, checking out: $BRANCH_NAME"
110
+ git checkout "$BRANCH_NAME"
111
+ # Check if branch exists on remote
112
+ elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
113
+ echo " ✅ Branch exists on remote, checking out and tracking: $BRANCH_NAME"
114
+ git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
115
+ else
116
+ # Branch doesn't exist, create from develop
117
+ echo " 🌿 Creating new branch from develop: $BRANCH_NAME"
118
+
119
+ # Make sure we have latest develop
120
+ git fetch origin develop:develop --quiet 2>/dev/null || true
121
+
122
+ # Checkout develop first
123
+ if git show-ref --verify --quiet "refs/heads/develop"; then
124
+ git checkout develop --quiet
125
+ git pull origin develop --quiet
126
+ else
127
+ echo " ⚠️ Local develop doesn't exist, fetching from remote"
128
+ git fetch origin develop:develop --quiet
129
+ git checkout develop --quiet
130
+ fi
131
+
132
+ # Create new branch
133
+ git checkout -b "$BRANCH_NAME"
134
+ echo " ✅ Created: $BRANCH_NAME"
135
+ fi
136
+
137
+ # Show current status
138
+ CURRENT_BRANCH=$(git branch --show-current)
139
+ echo " 📍 Now on: $CURRENT_BRANCH"
140
+
141
+ # Track this repo for verification
142
+ PROCESSED_REPOS+=("$repo_path:$repo_name")
143
+ }
144
+
145
+ echo "🌿 Creating/checking out feature branches..."
146
+ echo " Branch: $BRANCH_NAME"
147
+ echo " Repos: $REPOS"
148
+
149
+ # Process repos based on selection
150
+ case "$REPOS" in
151
+ api)
152
+ create_or_checkout_branch "$REPO_BASE/conductor-api" "conductor-api"
153
+ ;;
154
+ ui)
155
+ create_or_checkout_branch "$REPO_BASE/conductor-ui" "conductor-ui"
156
+ ;;
157
+ all)
158
+ create_or_checkout_branch "$REPO_BASE/conductor-api" "conductor-api"
159
+ create_or_checkout_branch "$REPO_BASE/conductor-ui" "conductor-ui"
160
+ ;;
161
+ esac
162
+
163
+ echo ""
164
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
165
+ echo "🔍 Verification Summary"
166
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
167
+
168
+ # Verify each processed repo
169
+ for repo_info in "${PROCESSED_REPOS[@]}"; do
170
+ repo_path="${repo_info%%:*}"
171
+ repo_name="${repo_info##*:}"
172
+
173
+ if [ -d "$repo_path" ]; then
174
+ cd "$repo_path"
175
+
176
+ echo ""
177
+ echo "📦 $repo_name"
178
+ echo " Path: $repo_path"
179
+
180
+ # Current branch
181
+ CURRENT_BRANCH=$(git branch --show-current)
182
+ echo " Branch: $CURRENT_BRANCH"
183
+
184
+ # Check if branch matches expected
185
+ if [ "$CURRENT_BRANCH" = "$BRANCH_NAME" ]; then
186
+ echo " ✅ Branch matches: $BRANCH_NAME"
187
+ else
188
+ echo " ⚠️ Branch mismatch! Expected: $BRANCH_NAME, Got: $CURRENT_BRANCH"
189
+ fi
190
+
191
+ # Latest commit
192
+ COMMIT_INFO=$(git log -1 --format="%h - %s" 2>/dev/null)
193
+ echo " Commit: $COMMIT_INFO"
194
+
195
+ # Check remote tracking
196
+ UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "none")
197
+ if [ "$UPSTREAM" != "none" ]; then
198
+ echo " Remote: $UPSTREAM"
199
+
200
+ # Check if up to date with remote
201
+ git fetch origin "$CURRENT_BRANCH" --quiet 2>/dev/null || true
202
+ LOCAL=$(git rev-parse @ 2>/dev/null)
203
+ REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "none")
204
+
205
+ if [ "$LOCAL" = "$REMOTE" ]; then
206
+ echo " Status: ✅ Up to date with remote"
207
+ elif [ "$REMOTE" = "none" ]; then
208
+ echo " Status: ⚠️ No remote branch yet (push needed)"
209
+ else
210
+ BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo "0")
211
+ AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo "0")
212
+ if [ "$AHEAD" -gt 0 ] && [ "$BEHIND" -gt 0 ]; then
213
+ echo " Status: ⚠️ Diverged ($AHEAD ahead, $BEHIND behind)"
214
+ elif [ "$AHEAD" -gt 0 ]; then
215
+ echo " Status: ⬆️ $AHEAD commit(s) ahead of remote"
216
+ elif [ "$BEHIND" -gt 0 ]; then
217
+ echo " Status: ⬇️ $BEHIND commit(s) behind remote"
218
+ fi
219
+ fi
220
+ else
221
+ echo " Remote: none (local branch only)"
222
+ echo " Status: ⚠️ Not tracking remote (push with -u needed)"
223
+ fi
224
+ fi
225
+ done
226
+
227
+ echo ""
228
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
229
+ echo "✅ Done! All branches verified and ready."
230
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env zsh
2
+ # File locking utilities for session file concurrency protection
3
+ # Dev: Fanny Price - "We have all a better guide in ourselves."
4
+
5
+ # Default timeout in seconds
6
+ DEFAULT_LOCK_TIMEOUT=10
7
+
8
+ # Stale lock threshold in seconds (5 minutes)
9
+ STALE_LOCK_THRESHOLD=300
10
+
11
+ # _get_lock_dir
12
+ # Internal function to get lock directory (evaluated at call time)
13
+ _get_lock_dir() {
14
+ echo "${PROJECT_ROOT:-.}/.session/.locks"
15
+ }
16
+
17
+ # _get_lock_file FILEPATH
18
+ # Internal function to derive lock file path from target file
19
+ #
20
+ # Arguments:
21
+ # FILEPATH - Path to the file to lock
22
+ #
23
+ # Returns:
24
+ # Outputs the lock file path
25
+ #
26
+ _get_lock_file() {
27
+ local filepath="$1"
28
+ local filename
29
+ local lock_dir
30
+ filename=$(basename "$filepath")
31
+ lock_dir=$(_get_lock_dir)
32
+ echo "${lock_dir}/.${filename}.lock"
33
+ }
34
+
35
+ # _check_stale_lock LOCKFILE
36
+ # Internal function to check and remove stale locks
37
+ #
38
+ # Arguments:
39
+ # LOCKFILE - Path to lock file to check
40
+ #
41
+ # Returns:
42
+ # 0 if lock was stale and removed, 1 if lock is valid
43
+ #
44
+ _check_stale_lock() {
45
+ local lockfile="$1"
46
+
47
+ if [[ ! -f "$lockfile" ]]; then
48
+ return 1
49
+ fi
50
+
51
+ # Get lock file age in seconds
52
+ local now lock_mtime age
53
+ now=$(date +%s)
54
+
55
+ # macOS stat vs Linux stat differ
56
+ if [[ "$(uname)" == "Darwin" ]]; then
57
+ lock_mtime=$(stat -f %m "$lockfile" 2>/dev/null || echo 0)
58
+ else
59
+ lock_mtime=$(stat -c %Y "$lockfile" 2>/dev/null || echo 0)
60
+ fi
61
+
62
+ age=$((now - lock_mtime))
63
+
64
+ if ((age > STALE_LOCK_THRESHOLD)); then
65
+ # Log warning about stale lock
66
+ echo "[WARN] Removing stale lock: $lockfile (age: ${age}s)" >&2
67
+ rm -f "$lockfile"
68
+ return 0
69
+ fi
70
+
71
+ return 1
72
+ }
73
+
74
+ # lock_acquire FILEPATH [LOCK_TYPE] [TIMEOUT]
75
+ # Acquire a lock on a file
76
+ #
77
+ # Arguments:
78
+ # FILEPATH - Path to the file to lock
79
+ # LOCK_TYPE - "exclusive" (default) or "shared"
80
+ # TIMEOUT - Timeout in seconds (default: 10)
81
+ #
82
+ # Returns:
83
+ # 0 on success, 1 on timeout/failure
84
+ #
85
+ # Example:
86
+ # lock_acquire ".session/checkpoints.log"
87
+ # lock_acquire ".session/agent-logs.jsonl" "exclusive" 5
88
+ #
89
+ lock_acquire() {
90
+ local filepath="$1"
91
+ local lock_type="${2:-exclusive}"
92
+ local timeout="${3:-$DEFAULT_LOCK_TIMEOUT}"
93
+ local lockfile
94
+ local flock_opts
95
+ local start_time
96
+ local elapsed
97
+
98
+ lockfile=$(_get_lock_file "$filepath")
99
+ local lock_dir
100
+ lock_dir=$(_get_lock_dir)
101
+
102
+ # Ensure lock directory exists
103
+ mkdir -p "$lock_dir"
104
+
105
+ # Check for stale lock first (ignore return value)
106
+ _check_stale_lock "$lockfile" || true
107
+
108
+ # Set flock options based on lock type
109
+ case "$lock_type" in
110
+ shared)
111
+ flock_opts="-s"
112
+ ;;
113
+ exclusive|*)
114
+ flock_opts="-x"
115
+ ;;
116
+ esac
117
+
118
+ # Try to acquire lock with timeout
119
+ start_time=$(date +%s)
120
+ local my_pid="$$"
121
+
122
+ while true; do
123
+ # Try to create lock file atomically using ln (atomic on POSIX)
124
+ # Create a temp file with our PID, then try to hard-link it
125
+ local temp_lock="${lockfile}.${my_pid}"
126
+ echo "$my_pid" > "$temp_lock"
127
+
128
+ if ln "$temp_lock" "$lockfile" 2>/dev/null; then
129
+ rm -f "$temp_lock"
130
+ return 0
131
+ fi
132
+ rm -f "$temp_lock"
133
+
134
+ # Check if we've exceeded timeout
135
+ elapsed=$(( $(date +%s) - start_time ))
136
+ if ((elapsed >= timeout)); then
137
+ echo "[WARN] Lock timeout on $filepath after ${timeout}s" >&2
138
+ return 1
139
+ fi
140
+
141
+ # Check for stale lock
142
+ if _check_stale_lock "$lockfile" 2>/dev/null; then
143
+ continue # Try again now that stale lock is removed
144
+ fi
145
+
146
+ # Wait a bit before retrying (100ms)
147
+ sleep 0.1
148
+ done
149
+ }
150
+
151
+ # lock_release FILEPATH
152
+ # Release a lock on a file
153
+ #
154
+ # Arguments:
155
+ # FILEPATH - Path to the file to unlock
156
+ #
157
+ # Returns:
158
+ # 0 on success
159
+ #
160
+ # Example:
161
+ # lock_release ".session/checkpoints.log"
162
+ #
163
+ lock_release() {
164
+ local filepath="$1"
165
+ local lockfile
166
+
167
+ lockfile=$(_get_lock_file "$filepath")
168
+
169
+ # Only remove if we own the lock (PID matches)
170
+ if [[ -f "$lockfile" ]]; then
171
+ local lock_pid
172
+ lock_pid=$(cat "$lockfile" 2>/dev/null || echo "")
173
+ if [[ "$lock_pid" == "$$" ]]; then
174
+ rm -f "$lockfile"
175
+ fi
176
+ fi
177
+
178
+ return 0
179
+ }
180
+
181
+ # with_lock FILEPATH LOCK_TYPE COMMAND...
182
+ # Execute a command while holding a lock
183
+ #
184
+ # Arguments:
185
+ # FILEPATH - Path to the file to lock
186
+ # LOCK_TYPE - "exclusive" or "shared"
187
+ # COMMAND - Command and arguments to execute
188
+ #
189
+ # Returns:
190
+ # Exit code of the command, or 1 if lock failed
191
+ #
192
+ # Example:
193
+ # with_lock ".session/checkpoints.log" "exclusive" echo "data" >> file
194
+ # with_lock ".session/data.json" "shared" cat file
195
+ #
196
+ with_lock() {
197
+ local filepath="$1"
198
+ local lock_type="$2"
199
+ shift 2
200
+
201
+ if ! lock_acquire "$filepath" "$lock_type"; then
202
+ return 1
203
+ fi
204
+
205
+ # Execute command and capture exit code
206
+ local exit_code
207
+ "$@"
208
+ exit_code=$?
209
+
210
+ lock_release "$filepath"
211
+
212
+ return $exit_code
213
+ }
214
+
215
+ # lock_status FILEPATH
216
+ # Check if a file is currently locked
217
+ #
218
+ # Arguments:
219
+ # FILEPATH - Path to the file to check
220
+ #
221
+ # Returns:
222
+ # 0 if locked, 1 if not locked
223
+ # Outputs lock holder PID if locked
224
+ #
225
+ # Example:
226
+ # if lock_status ".session/checkpoints.log"; then
227
+ # echo "File is locked"
228
+ # fi
229
+ #
230
+ lock_status() {
231
+ local filepath="$1"
232
+ local lockfile
233
+
234
+ lockfile=$(_get_lock_file "$filepath")
235
+
236
+ if [[ -f "$lockfile" ]]; then
237
+ # Check for stale lock
238
+ if _check_stale_lock "$lockfile"; then
239
+ return 1
240
+ fi
241
+ cat "$lockfile"
242
+ return 0
243
+ fi
244
+
245
+ return 1
246
+ }
247
+
248
+ # lock_cleanup
249
+ # Remove all stale locks in the lock directory
250
+ #
251
+ # Example:
252
+ # lock_cleanup
253
+ #
254
+ lock_cleanup() {
255
+ local lock_dir
256
+ lock_dir=$(_get_lock_dir)
257
+
258
+ if [[ ! -d "$lock_dir" ]]; then
259
+ return 0
260
+ fi
261
+
262
+ local lockfile
263
+ for lockfile in "$lock_dir"/.*.lock; do
264
+ [[ -f "$lockfile" ]] || continue
265
+ _check_stale_lock "$lockfile"
266
+ done
267
+ }
268
+
269
+ # Functions available when sourced