@rpamis/comet 0.4.0-beta.2 → 0.4.0-beta.4

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 (509) hide show
  1. package/README.md +27 -18
  2. package/assets/manifest.json +2 -1
  3. package/assets/skills/comet/SKILL.md +25 -1
  4. package/assets/skills/comet/reference/comet-yaml-fields.md +6 -4
  5. package/assets/skills/comet/reference/context-recovery.md +10 -0
  6. package/assets/skills/comet/reference/scripts.md +47 -15
  7. package/assets/skills/comet/rules/comet-phase-guard.en.md +8 -0
  8. package/assets/skills/comet/rules/comet-phase-guard.md +9 -1
  9. package/assets/skills/comet/scripts/comet-resume-probe.mjs +3 -0
  10. package/assets/skills/comet/scripts/comet-runtime.mjs +1664 -512
  11. package/assets/skills/comet-archive/SKILL.md +24 -11
  12. package/assets/skills/comet-build/SKILL.md +40 -31
  13. package/assets/skills/comet-design/SKILL.md +1 -0
  14. package/assets/skills/comet-hotfix/SKILL.md +3 -1
  15. package/assets/skills/comet-open/SKILL.md +11 -1
  16. package/assets/skills/comet-tweak/SKILL.md +3 -1
  17. package/assets/skills/comet-verify/SKILL.md +29 -20
  18. package/assets/skills-zh/comet/SKILL.md +25 -1
  19. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +5 -4
  20. package/assets/skills-zh/comet/reference/context-recovery.md +10 -0
  21. package/assets/skills-zh/comet/reference/scripts.md +47 -15
  22. package/assets/skills-zh/comet-archive/SKILL.md +24 -11
  23. package/assets/skills-zh/comet-build/SKILL.md +40 -31
  24. package/assets/skills-zh/comet-design/SKILL.md +1 -0
  25. package/assets/skills-zh/comet-hotfix/SKILL.md +3 -1
  26. package/assets/skills-zh/comet-open/SKILL.md +11 -1
  27. package/assets/skills-zh/comet-tweak/SKILL.md +3 -1
  28. package/assets/skills-zh/comet-verify/SKILL.md +30 -21
  29. package/dist/app/cli/comet-banner.d.ts +25 -0
  30. package/dist/app/cli/comet-banner.d.ts.map +1 -0
  31. package/dist/app/cli/comet-banner.js +265 -0
  32. package/dist/app/cli/comet-banner.js.map +1 -0
  33. package/dist/app/cli/index.js +37 -3
  34. package/dist/app/cli/index.js.map +1 -1
  35. package/dist/app/commands/classic.d.ts +4 -0
  36. package/dist/app/commands/classic.d.ts.map +1 -0
  37. package/dist/app/commands/classic.js +11 -0
  38. package/dist/app/commands/classic.js.map +1 -0
  39. package/dist/app/commands/doctor.d.ts +1 -0
  40. package/dist/app/commands/doctor.d.ts.map +1 -1
  41. package/dist/app/commands/doctor.js +100 -35
  42. package/dist/app/commands/doctor.js.map +1 -1
  43. package/dist/app/commands/eval.d.ts.map +1 -1
  44. package/dist/app/commands/eval.js +57 -20
  45. package/dist/app/commands/eval.js.map +1 -1
  46. package/dist/app/commands/i18n.d.ts +1 -1
  47. package/dist/app/commands/i18n.d.ts.map +1 -1
  48. package/dist/app/commands/i18n.js +12 -4
  49. package/dist/app/commands/i18n.js.map +1 -1
  50. package/dist/app/commands/init.d.ts.map +1 -1
  51. package/dist/app/commands/init.js +16 -13
  52. package/dist/app/commands/init.js.map +1 -1
  53. package/dist/app/commands/project-scope-selection.d.ts +13 -0
  54. package/dist/app/commands/project-scope-selection.d.ts.map +1 -0
  55. package/dist/app/commands/project-scope-selection.js +33 -0
  56. package/dist/app/commands/project-scope-selection.js.map +1 -0
  57. package/dist/app/commands/resume-probe.d.ts +11 -0
  58. package/dist/app/commands/resume-probe.d.ts.map +1 -0
  59. package/dist/app/commands/resume-probe.js +63 -0
  60. package/dist/app/commands/resume-probe.js.map +1 -0
  61. package/dist/app/commands/status.d.ts +31 -0
  62. package/dist/app/commands/status.d.ts.map +1 -1
  63. package/dist/app/commands/status.js +109 -20
  64. package/dist/app/commands/status.js.map +1 -1
  65. package/dist/app/commands/uninstall.d.ts +2 -0
  66. package/dist/app/commands/uninstall.d.ts.map +1 -1
  67. package/dist/app/commands/uninstall.js +217 -40
  68. package/dist/app/commands/uninstall.js.map +1 -1
  69. package/dist/app/commands/update.d.ts +6 -0
  70. package/dist/app/commands/update.d.ts.map +1 -1
  71. package/dist/app/commands/update.js +361 -68
  72. package/dist/app/commands/update.js.map +1 -1
  73. package/dist/config/repository-layout.json +4 -2
  74. package/dist/domains/bundle/bundle-platform.d.ts.map +1 -1
  75. package/dist/domains/bundle/bundle-platform.js +3 -1
  76. package/dist/domains/bundle/bundle-platform.js.map +1 -1
  77. package/dist/domains/bundle/eval-manifest-runtime.d.ts +6 -0
  78. package/dist/domains/bundle/eval-manifest-runtime.d.ts.map +1 -0
  79. package/dist/domains/bundle/eval-manifest-runtime.js +58 -0
  80. package/dist/domains/bundle/eval-manifest-runtime.js.map +1 -0
  81. package/dist/domains/bundle/types.d.ts +1 -1
  82. package/dist/domains/bundle/types.d.ts.map +1 -1
  83. package/dist/domains/comet-classic/classic-archive.d.ts +1 -0
  84. package/dist/domains/comet-classic/classic-archive.d.ts.map +1 -1
  85. package/dist/domains/comet-classic/classic-archive.js +35 -38
  86. package/dist/domains/comet-classic/classic-archive.js.map +1 -1
  87. package/dist/domains/comet-classic/classic-cli.d.ts +1 -1
  88. package/dist/domains/comet-classic/classic-cli.d.ts.map +1 -1
  89. package/dist/domains/comet-classic/classic-cli.js +3 -0
  90. package/dist/domains/comet-classic/classic-cli.js.map +1 -1
  91. package/dist/domains/comet-classic/classic-command-checks.d.ts +20 -0
  92. package/dist/domains/comet-classic/classic-command-checks.d.ts.map +1 -0
  93. package/dist/domains/comet-classic/classic-command-checks.js +97 -0
  94. package/dist/domains/comet-classic/classic-command-checks.js.map +1 -0
  95. package/dist/domains/comet-classic/classic-current-change.d.ts +19 -0
  96. package/dist/domains/comet-classic/classic-current-change.d.ts.map +1 -0
  97. package/dist/domains/comet-classic/classic-current-change.js +132 -0
  98. package/dist/domains/comet-classic/classic-current-change.js.map +1 -0
  99. package/dist/domains/comet-classic/classic-diagnostics.d.ts +2 -1
  100. package/dist/domains/comet-classic/classic-diagnostics.d.ts.map +1 -1
  101. package/dist/domains/comet-classic/classic-diagnostics.js +54 -1
  102. package/dist/domains/comet-classic/classic-diagnostics.js.map +1 -1
  103. package/dist/domains/comet-classic/classic-evidence.d.ts.map +1 -1
  104. package/dist/domains/comet-classic/classic-evidence.js +4 -0
  105. package/dist/domains/comet-classic/classic-evidence.js.map +1 -1
  106. package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
  107. package/dist/domains/comet-classic/classic-guard.js +101 -141
  108. package/dist/domains/comet-classic/classic-guard.js.map +1 -1
  109. package/dist/domains/comet-classic/classic-hook-guard.d.ts.map +1 -1
  110. package/dist/domains/comet-classic/classic-hook-guard.js +67 -29
  111. package/dist/domains/comet-classic/classic-hook-guard.js.map +1 -1
  112. package/dist/domains/comet-classic/classic-project-config.d.ts +16 -0
  113. package/dist/domains/comet-classic/classic-project-config.d.ts.map +1 -0
  114. package/dist/domains/comet-classic/classic-project-config.js +40 -0
  115. package/dist/domains/comet-classic/classic-project-config.js.map +1 -0
  116. package/dist/domains/comet-classic/classic-resolver.d.ts.map +1 -1
  117. package/dist/domains/comet-classic/classic-resolver.js +3 -3
  118. package/dist/domains/comet-classic/classic-resolver.js.map +1 -1
  119. package/dist/domains/comet-classic/classic-resume-probe-command.d.ts +3 -0
  120. package/dist/domains/comet-classic/classic-resume-probe-command.d.ts.map +1 -0
  121. package/dist/domains/comet-classic/classic-resume-probe-command.js +58 -0
  122. package/dist/domains/comet-classic/classic-resume-probe-command.js.map +1 -0
  123. package/dist/domains/comet-classic/classic-resume-probe-entry.d.ts +2 -0
  124. package/dist/domains/comet-classic/classic-resume-probe-entry.d.ts.map +1 -0
  125. package/dist/domains/comet-classic/classic-resume-probe-entry.js +4 -0
  126. package/dist/domains/comet-classic/classic-resume-probe-entry.js.map +1 -0
  127. package/dist/domains/comet-classic/classic-resume-probe.d.ts +29 -0
  128. package/dist/domains/comet-classic/classic-resume-probe.d.ts.map +1 -0
  129. package/dist/domains/comet-classic/classic-resume-probe.js +386 -0
  130. package/dist/domains/comet-classic/classic-resume-probe.js.map +1 -0
  131. package/dist/domains/comet-classic/classic-runtime-run.d.ts +2 -1
  132. package/dist/domains/comet-classic/classic-runtime-run.d.ts.map +1 -1
  133. package/dist/domains/comet-classic/classic-runtime-run.js +269 -4
  134. package/dist/domains/comet-classic/classic-runtime-run.js.map +1 -1
  135. package/dist/domains/comet-classic/classic-state-command.d.ts.map +1 -1
  136. package/dist/domains/comet-classic/classic-state-command.js +129 -15
  137. package/dist/domains/comet-classic/classic-state-command.js.map +1 -1
  138. package/dist/domains/comet-classic/classic-state.d.ts +3 -3
  139. package/dist/domains/comet-classic/classic-state.d.ts.map +1 -1
  140. package/dist/domains/comet-classic/classic-state.js +4 -6
  141. package/dist/domains/comet-classic/classic-state.js.map +1 -1
  142. package/dist/domains/comet-classic/classic-store.d.ts +4 -1
  143. package/dist/domains/comet-classic/classic-store.d.ts.map +1 -1
  144. package/dist/domains/comet-classic/classic-store.js +27 -9
  145. package/dist/domains/comet-classic/classic-store.js.map +1 -1
  146. package/dist/domains/comet-classic/classic-transitions.d.ts +1 -1
  147. package/dist/domains/comet-classic/classic-transitions.d.ts.map +1 -1
  148. package/dist/domains/comet-classic/classic-transitions.js +20 -1
  149. package/dist/domains/comet-classic/classic-transitions.js.map +1 -1
  150. package/dist/domains/comet-classic/classic-validate-command.d.ts.map +1 -1
  151. package/dist/domains/comet-classic/classic-validate-command.js +1 -0
  152. package/dist/domains/comet-classic/classic-validate-command.js.map +1 -1
  153. package/dist/domains/comet-classic/index.d.ts +3 -0
  154. package/dist/domains/comet-classic/index.d.ts.map +1 -1
  155. package/dist/domains/comet-classic/index.js +3 -0
  156. package/dist/domains/comet-classic/index.js.map +1 -1
  157. package/dist/domains/dashboard/collector.js +10 -2
  158. package/dist/domains/dashboard/collector.js.map +1 -1
  159. package/dist/domains/dashboard/web/assets/{index-CjU3VXVu.js → index-CIvN-PL8.js} +11 -11
  160. package/dist/domains/dashboard/web/assets/{index-BcO3_QlT.css → index-DcyRPBnT.css} +1 -1
  161. package/dist/domains/dashboard/web/index.html +16 -16
  162. package/dist/domains/engine/types.d.ts +1 -1
  163. package/dist/domains/engine/types.d.ts.map +1 -1
  164. package/dist/domains/integrations/openspec.d.ts.map +1 -1
  165. package/dist/domains/integrations/openspec.js +6 -6
  166. package/dist/domains/integrations/openspec.js.map +1 -1
  167. package/dist/domains/skill/find.d.ts.map +1 -1
  168. package/dist/domains/skill/find.js +1 -6
  169. package/dist/domains/skill/find.js.map +1 -1
  170. package/dist/domains/skill/managed-markdown.d.ts +14 -0
  171. package/dist/domains/skill/managed-markdown.d.ts.map +1 -0
  172. package/dist/domains/skill/managed-markdown.js +126 -0
  173. package/dist/domains/skill/managed-markdown.js.map +1 -0
  174. package/dist/domains/skill/platform-install.d.ts +4 -3
  175. package/dist/domains/skill/platform-install.d.ts.map +1 -1
  176. package/dist/domains/skill/platform-install.js +96 -26
  177. package/dist/domains/skill/platform-install.js.map +1 -1
  178. package/dist/domains/skill/project-instructions.d.ts +22 -0
  179. package/dist/domains/skill/project-instructions.d.ts.map +1 -0
  180. package/dist/domains/skill/project-instructions.js +61 -0
  181. package/dist/domains/skill/project-instructions.js.map +1 -0
  182. package/dist/domains/skill/uninstall.d.ts +3 -1
  183. package/dist/domains/skill/uninstall.d.ts.map +1 -1
  184. package/dist/domains/skill/uninstall.js +86 -39
  185. package/dist/domains/skill/uninstall.js.map +1 -1
  186. package/dist/platform/install/detect.d.ts +2 -1
  187. package/dist/platform/install/detect.d.ts.map +1 -1
  188. package/dist/platform/install/detect.js +10 -1
  189. package/dist/platform/install/detect.js.map +1 -1
  190. package/dist/platform/install/platforms.d.ts +5 -1
  191. package/dist/platform/install/platforms.d.ts.map +1 -1
  192. package/dist/platform/install/platforms.js +21 -4
  193. package/dist/platform/install/platforms.js.map +1 -1
  194. package/dist/platform/install/project-registry.d.ts +37 -0
  195. package/dist/platform/install/project-registry.d.ts.map +1 -0
  196. package/dist/platform/install/project-registry.js +205 -0
  197. package/dist/platform/install/project-registry.js.map +1 -0
  198. package/eval/.env +28 -0
  199. package/eval/.env.example +52 -0
  200. package/eval/CLAUDE.md +43 -0
  201. package/eval/README.md +538 -0
  202. package/eval/langsmith/.env.example +16 -0
  203. package/eval/langsmith/README.md +93 -0
  204. package/eval/langsmith/skills/README.md +5 -0
  205. package/eval/langsmith/tasks/README.md +5 -0
  206. package/eval/langsmith/tests/conftest.py +187 -0
  207. package/eval/langsmith/tests/tasks/test_tasks.py +287 -0
  208. package/eval/langsmith/treatments/README.md +5 -0
  209. package/eval/local/README.md +80 -0
  210. package/eval/local/regression_baseline.json +13 -0
  211. package/eval/local/report-style-demo-assets/quality_cost.en.svg +41 -0
  212. package/eval/local/report-style-demo-assets/quality_cost.zh.svg +41 -0
  213. package/eval/local/report-style-demo-assets/rubric_delta.en.svg +56 -0
  214. package/eval/local/report-style-demo-assets/rubric_delta.zh.svg +56 -0
  215. package/eval/local/report-style-demo-assets/task_outcomes.en.svg +46 -0
  216. package/eval/local/report-style-demo-assets/task_outcomes.zh.svg +46 -0
  217. package/eval/local/report-style-demo.html +867 -0
  218. package/eval/local/scripts/compare_baselines.py +1018 -0
  219. package/eval/local/scripts/generate_report_style_demo_charts.py +322 -0
  220. package/eval/local/scripts/regression_check.py +171 -0
  221. package/eval/local/scripts/render_readme_benchmark_figures.py +416 -0
  222. package/eval/local/scripts/rescore_rubric.py +120 -0
  223. package/eval/local/skills/benchmarks/039-release/comet-classic-039/SKILL.md +282 -0
  224. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/auto-transition.md +27 -0
  225. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/comet-yaml-fields.md +68 -0
  226. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/context-recovery.md +35 -0
  227. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/debug-gate.md +17 -0
  228. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/decision-point.md +20 -0
  229. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/dirty-worktree.md +59 -0
  230. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/file-structure.md +28 -0
  231. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/subagent-dispatch.md +113 -0
  232. package/eval/local/skills/benchmarks/039-release/comet-classic-039/rules/comet-phase-guard.md +125 -0
  233. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-archive.sh +311 -0
  234. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-env.sh +110 -0
  235. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-guard.sh +778 -0
  236. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-handoff.sh +390 -0
  237. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-hook-guard.sh +336 -0
  238. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-state.sh +1338 -0
  239. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-yaml-validate.sh +225 -0
  240. package/eval/local/skills/benchmarks/039-release/comet-classic-039-archive/SKILL.md +100 -0
  241. package/eval/local/skills/benchmarks/039-release/comet-classic-039-build/SKILL.md +304 -0
  242. package/eval/local/skills/benchmarks/039-release/comet-classic-039-design/SKILL.md +263 -0
  243. package/eval/local/skills/benchmarks/039-release/comet-classic-039-hotfix/SKILL.md +204 -0
  244. package/eval/local/skills/benchmarks/039-release/comet-classic-039-open/SKILL.md +220 -0
  245. package/eval/local/skills/benchmarks/039-release/comet-classic-039-tweak/SKILL.md +180 -0
  246. package/eval/local/skills/benchmarks/039-release/comet-classic-039-verify/SKILL.md +234 -0
  247. package/eval/local/skills/benchmarks/040-beta/comet/SKILL.md +261 -0
  248. package/eval/local/skills/benchmarks/040-beta/comet/reference/auto-transition.md +27 -0
  249. package/eval/local/skills/benchmarks/040-beta/comet/reference/comet-yaml-fields.md +73 -0
  250. package/eval/local/skills/benchmarks/040-beta/comet/reference/context-recovery.md +45 -0
  251. package/eval/local/skills/benchmarks/040-beta/comet/reference/debug-gate.md +33 -0
  252. package/eval/local/skills/benchmarks/040-beta/comet/reference/decision-point.md +31 -0
  253. package/eval/local/skills/benchmarks/040-beta/comet/reference/dirty-worktree.md +59 -0
  254. package/eval/local/skills/benchmarks/040-beta/comet/reference/file-structure.md +28 -0
  255. package/eval/local/skills/benchmarks/040-beta/comet/reference/intent-frame.md +74 -0
  256. package/eval/local/skills/benchmarks/040-beta/comet/reference/scripts.md +69 -0
  257. package/eval/local/skills/benchmarks/040-beta/comet/reference/subagent-dispatch.md +169 -0
  258. package/eval/local/skills/benchmarks/040-beta/comet/rules/comet-phase-guard.md +130 -0
  259. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/checks.yaml +6 -0
  260. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/guardrails.yaml +13 -0
  261. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/skill.yaml +122 -0
  262. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-archive.mjs +9515 -0
  263. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-env.mjs +15 -0
  264. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-guard.mjs +10173 -0
  265. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-handoff.mjs +9491 -0
  266. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-hook-guard.mjs +9175 -0
  267. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-intent.mjs +404 -0
  268. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-state.mjs +9273 -0
  269. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-yaml-validate.mjs +7627 -0
  270. package/eval/local/skills/benchmarks/040-beta/comet-archive/SKILL.md +110 -0
  271. package/eval/local/skills/benchmarks/040-beta/comet-build/SKILL.md +315 -0
  272. package/eval/local/skills/benchmarks/040-beta/comet-design/SKILL.md +260 -0
  273. package/eval/local/skills/benchmarks/040-beta/comet-hotfix/SKILL.md +190 -0
  274. package/eval/local/skills/benchmarks/040-beta/comet-open/SKILL.md +210 -0
  275. package/eval/local/skills/benchmarks/040-beta/comet-tweak/SKILL.md +183 -0
  276. package/eval/local/skills/benchmarks/040-beta/comet-verify/SKILL.md +230 -0
  277. package/eval/local/skills/benchmarks/dependency/claude-md/comet-workflow/CLAUDE.md +12 -0
  278. package/eval/local/skills/benchmarks/dependency/openspec/openspec-apply-change/SKILL.md +156 -0
  279. package/eval/local/skills/benchmarks/dependency/openspec/openspec-archive-change/SKILL.md +114 -0
  280. package/eval/local/skills/benchmarks/dependency/openspec/openspec-bulk-archive-change/SKILL.md +246 -0
  281. package/eval/local/skills/benchmarks/dependency/openspec/openspec-continue-change/SKILL.md +118 -0
  282. package/eval/local/skills/benchmarks/dependency/openspec/openspec-explore/SKILL.md +288 -0
  283. package/eval/local/skills/benchmarks/dependency/openspec/openspec-ff-change/SKILL.md +101 -0
  284. package/eval/local/skills/benchmarks/dependency/openspec/openspec-new-change/SKILL.md +74 -0
  285. package/eval/local/skills/benchmarks/dependency/openspec/openspec-onboard/SKILL.md +554 -0
  286. package/eval/local/skills/benchmarks/dependency/openspec/openspec-propose/SKILL.md +110 -0
  287. package/eval/local/skills/benchmarks/dependency/openspec/openspec-sync-specs/SKILL.md +138 -0
  288. package/eval/local/skills/benchmarks/dependency/openspec/openspec-verify-change/SKILL.md +168 -0
  289. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/SKILL.md +159 -0
  290. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/frame-template.html +213 -0
  291. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/helper.js +167 -0
  292. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/server.cjs +723 -0
  293. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/start-server.sh +209 -0
  294. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/stop-server.sh +120 -0
  295. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/spec-document-reviewer-prompt.md +49 -0
  296. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/visual-companion.md +291 -0
  297. package/eval/local/skills/benchmarks/dependency/superpowers/dispatching-parallel-agents/SKILL.md +185 -0
  298. package/eval/local/skills/benchmarks/dependency/superpowers/executing-plans/SKILL.md +70 -0
  299. package/eval/local/skills/benchmarks/dependency/superpowers/finishing-a-development-branch/SKILL.md +241 -0
  300. package/eval/local/skills/benchmarks/dependency/superpowers/receiving-code-review/SKILL.md +213 -0
  301. package/eval/local/skills/benchmarks/dependency/superpowers/requesting-code-review/SKILL.md +103 -0
  302. package/eval/local/skills/benchmarks/dependency/superpowers/requesting-code-review/code-reviewer.md +172 -0
  303. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/SKILL.md +418 -0
  304. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/implementer-prompt.md +139 -0
  305. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/review-package +44 -0
  306. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/sdd-workspace +22 -0
  307. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/task-brief +40 -0
  308. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/task-reviewer-prompt.md +188 -0
  309. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/CREATION-LOG.md +119 -0
  310. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/SKILL.md +296 -0
  311. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/condition-based-waiting-example.ts +158 -0
  312. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/condition-based-waiting.md +115 -0
  313. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/defense-in-depth.md +122 -0
  314. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/find-polluter.sh +63 -0
  315. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/root-cause-tracing.md +169 -0
  316. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-academic.md +14 -0
  317. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-1.md +58 -0
  318. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-2.md +68 -0
  319. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-3.md +69 -0
  320. package/eval/local/skills/benchmarks/dependency/superpowers/test-driven-development/SKILL.md +371 -0
  321. package/eval/local/skills/benchmarks/dependency/superpowers/test-driven-development/testing-anti-patterns.md +299 -0
  322. package/eval/local/skills/benchmarks/dependency/superpowers/using-git-worktrees/SKILL.md +202 -0
  323. package/eval/local/skills/benchmarks/dependency/superpowers/verification-before-completion/SKILL.md +139 -0
  324. package/eval/local/skills/benchmarks/dependency/superpowers/writing-plans/SKILL.md +174 -0
  325. package/eval/local/skills/benchmarks/dependency/superpowers/writing-plans/plan-document-reviewer-prompt.md +49 -0
  326. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/SKILL.md +689 -0
  327. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/anthropic-best-practices.md +1150 -0
  328. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  329. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/graphviz-conventions.dot +172 -0
  330. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/persuasion-principles.md +187 -0
  331. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/render-graphs.js +168 -0
  332. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/testing-skills-with-subagents.md +384 -0
  333. package/eval/local/tasks/authoring-skill-smoke/environment/Dockerfile +2 -0
  334. package/eval/local/tasks/authoring-skill-smoke/instruction.md +4 -0
  335. package/eval/local/tasks/authoring-skill-smoke/task.toml +21 -0
  336. package/eval/local/tasks/authoring-skill-smoke/validation/test_authoring_skill_smoke.py +54 -0
  337. package/eval/local/tasks/comet-agent-memory-routing/environment/Dockerfile +28 -0
  338. package/eval/local/tasks/comet-agent-memory-routing/environment/agent_system.py +40 -0
  339. package/eval/local/tasks/comet-agent-memory-routing/environment/test_agent_system.py +29 -0
  340. package/eval/local/tasks/comet-agent-memory-routing/instruction.md +20 -0
  341. package/eval/local/tasks/comet-agent-memory-routing/task.toml +24 -0
  342. package/eval/local/tasks/comet-agent-memory-routing/validation/test_agent_memory_routing.py +24 -0
  343. package/eval/local/tasks/comet-api-cache-ttl/environment/Dockerfile +39 -0
  344. package/eval/local/tasks/comet-api-cache-ttl/environment/cache.py +39 -0
  345. package/eval/local/tasks/comet-api-cache-ttl/environment/test_cache.py +81 -0
  346. package/eval/local/tasks/comet-api-cache-ttl/instruction.md +33 -0
  347. package/eval/local/tasks/comet-api-cache-ttl/task.toml +24 -0
  348. package/eval/local/tasks/comet-api-cache-ttl/validation/test_api_cache_ttl.py +58 -0
  349. package/eval/local/tasks/comet-cross-file-refactor/environment/Dockerfile +15 -0
  350. package/eval/local/tasks/comet-cross-file-refactor/environment/cli.py +13 -0
  351. package/eval/local/tasks/comet-cross-file-refactor/environment/counting.py +13 -0
  352. package/eval/local/tasks/comet-cross-file-refactor/environment/test_textkit.py +21 -0
  353. package/eval/local/tasks/comet-cross-file-refactor/instruction.md +16 -0
  354. package/eval/local/tasks/comet-cross-file-refactor/task.toml +20 -0
  355. package/eval/local/tasks/comet-cross-file-refactor/validation/test_cross_file_refactor.py +20 -0
  356. package/eval/local/tasks/comet-dependency-confusion/environment/Dockerfile +28 -0
  357. package/eval/local/tasks/comet-dependency-confusion/environment/app.py +8 -0
  358. package/eval/local/tasks/comet-dependency-confusion/environment/settings_loader.py +14 -0
  359. package/eval/local/tasks/comet-dependency-confusion/environment/test_settings_service.py +19 -0
  360. package/eval/local/tasks/comet-dependency-confusion/instruction.md +18 -0
  361. package/eval/local/tasks/comet-dependency-confusion/task.toml +24 -0
  362. package/eval/local/tasks/comet-dependency-confusion/validation/test_dependency_confusion.py +24 -0
  363. package/eval/local/tasks/comet-fix-median/environment/Dockerfile +50 -0
  364. package/eval/local/tasks/comet-fix-median/environment/stats.py +54 -0
  365. package/eval/local/tasks/comet-fix-median/environment/test_stats.py +68 -0
  366. package/eval/local/tasks/comet-fix-median/instruction.md +25 -0
  367. package/eval/local/tasks/comet-fix-median/task.toml +24 -0
  368. package/eval/local/tasks/comet-fix-median/validation/test_fix_median.py +60 -0
  369. package/eval/local/tasks/comet-framework-selection/environment/Dockerfile +28 -0
  370. package/eval/local/tasks/comet-framework-selection/environment/architecture.py +12 -0
  371. package/eval/local/tasks/comet-framework-selection/environment/test_architecture.py +30 -0
  372. package/eval/local/tasks/comet-framework-selection/instruction.md +22 -0
  373. package/eval/local/tasks/comet-framework-selection/task.toml +24 -0
  374. package/eval/local/tasks/comet-framework-selection/validation/test_framework_selection.py +24 -0
  375. package/eval/local/tasks/comet-full-workflow/environment/Dockerfile +53 -0
  376. package/eval/local/tasks/comet-full-workflow/environment/test_wordcount.py +29 -0
  377. package/eval/local/tasks/comet-full-workflow/environment/wordcount.py +40 -0
  378. package/eval/local/tasks/comet-full-workflow/instruction.md +18 -0
  379. package/eval/local/tasks/comet-full-workflow/task.toml +24 -0
  380. package/eval/local/tasks/comet-full-workflow/validation/test_full_workflow.py +171 -0
  381. package/eval/local/tasks/comet-graph-execution-review/environment/Dockerfile +28 -0
  382. package/eval/local/tasks/comet-graph-execution-review/environment/pipeline.py +19 -0
  383. package/eval/local/tasks/comet-graph-execution-review/environment/test_pipeline.py +53 -0
  384. package/eval/local/tasks/comet-graph-execution-review/instruction.md +21 -0
  385. package/eval/local/tasks/comet-graph-execution-review/task.toml +24 -0
  386. package/eval/local/tasks/comet-graph-execution-review/validation/test_graph_execution_review.py +24 -0
  387. package/eval/local/tasks/comet-human-approval-flow/environment/Dockerfile +15 -0
  388. package/eval/local/tasks/comet-human-approval-flow/environment/approvals.py +17 -0
  389. package/eval/local/tasks/comet-human-approval-flow/environment/test_approvals.py +30 -0
  390. package/eval/local/tasks/comet-human-approval-flow/instruction.md +15 -0
  391. package/eval/local/tasks/comet-human-approval-flow/task.toml +20 -0
  392. package/eval/local/tasks/comet-human-approval-flow/validation/test_human_approval_flow.py +20 -0
  393. package/eval/local/tasks/comet-layered-streaming-fix/environment/Dockerfile +20 -0
  394. package/eval/local/tasks/comet-layered-streaming-fix/environment/chat_app.py +19 -0
  395. package/eval/local/tasks/comet-layered-streaming-fix/environment/test_chat_app.py +15 -0
  396. package/eval/local/tasks/comet-layered-streaming-fix/instruction.md +14 -0
  397. package/eval/local/tasks/comet-layered-streaming-fix/task.toml +20 -0
  398. package/eval/local/tasks/comet-layered-streaming-fix/validation/test_layered_streaming_fix.py +20 -0
  399. package/eval/local/tasks/comet-noise-distractor/environment/Dockerfile +15 -0
  400. package/eval/local/tasks/comet-noise-distractor/environment/distractor.md +4 -0
  401. package/eval/local/tasks/comet-noise-distractor/environment/invoice.py +5 -0
  402. package/eval/local/tasks/comet-noise-distractor/environment/test_invoice.py +18 -0
  403. package/eval/local/tasks/comet-noise-distractor/instruction.md +17 -0
  404. package/eval/local/tasks/comet-noise-distractor/task.toml +20 -0
  405. package/eval/local/tasks/comet-noise-distractor/validation/test_noise_distractor.py +20 -0
  406. package/eval/local/tasks/comet-observability-env-template/environment/Dockerfile +15 -0
  407. package/eval/local/tasks/comet-observability-env-template/environment/env_writer.py +17 -0
  408. package/eval/local/tasks/comet-observability-env-template/environment/test_env_writer.py +17 -0
  409. package/eval/local/tasks/comet-observability-env-template/instruction.md +20 -0
  410. package/eval/local/tasks/comet-observability-env-template/task.toml +20 -0
  411. package/eval/local/tasks/comet-observability-env-template/validation/test_observability_env_template.py +46 -0
  412. package/eval/local/tasks/comet-perf-dedupe/environment/Dockerfile +39 -0
  413. package/eval/local/tasks/comet-perf-dedupe/environment/dedupe.py +22 -0
  414. package/eval/local/tasks/comet-perf-dedupe/environment/test_dedupe.py +43 -0
  415. package/eval/local/tasks/comet-perf-dedupe/instruction.md +25 -0
  416. package/eval/local/tasks/comet-perf-dedupe/task.toml +24 -0
  417. package/eval/local/tasks/comet-perf-dedupe/validation/test_perf_dedupe.py +40 -0
  418. package/eval/local/tasks/comet-persistence-threading/environment/Dockerfile +15 -0
  419. package/eval/local/tasks/comet-persistence-threading/environment/session_store.py +15 -0
  420. package/eval/local/tasks/comet-persistence-threading/environment/test_session_store.py +21 -0
  421. package/eval/local/tasks/comet-persistence-threading/instruction.md +14 -0
  422. package/eval/local/tasks/comet-persistence-threading/task.toml +20 -0
  423. package/eval/local/tasks/comet-persistence-threading/validation/test_persistence_threading.py +20 -0
  424. package/eval/local/tasks/comet-refactor-counter/environment/Dockerfile +39 -0
  425. package/eval/local/tasks/comet-refactor-counter/environment/test_text_processor.py +57 -0
  426. package/eval/local/tasks/comet-refactor-counter/environment/text_processor.py +49 -0
  427. package/eval/local/tasks/comet-refactor-counter/instruction.md +31 -0
  428. package/eval/local/tasks/comet-refactor-counter/task.toml +24 -0
  429. package/eval/local/tasks/comet-refactor-counter/validation/test_refactor_counter.py +75 -0
  430. package/eval/local/tasks/comet-robust-config/environment/Dockerfile +39 -0
  431. package/eval/local/tasks/comet-robust-config/environment/config_loader.py +56 -0
  432. package/eval/local/tasks/comet-robust-config/environment/test_config_loader.py +72 -0
  433. package/eval/local/tasks/comet-robust-config/instruction.md +30 -0
  434. package/eval/local/tasks/comet-robust-config/task.toml +24 -0
  435. package/eval/local/tasks/comet-robust-config/validation/test_robust_config.py +37 -0
  436. package/eval/local/tasks/generic-skill-smoke/environment/Dockerfile +2 -0
  437. package/eval/local/tasks/generic-skill-smoke/instruction.md +7 -0
  438. package/eval/local/tasks/generic-skill-smoke/task.toml +21 -0
  439. package/eval/local/tasks/generic-skill-smoke/validation/test_generic_skill_smoke.py +36 -0
  440. package/eval/local/tasks/index.yaml +155 -0
  441. package/eval/local/tasks/workflow-overlay-contract/environment/Dockerfile +5 -0
  442. package/eval/local/tasks/workflow-overlay-contract/instruction.md +5 -0
  443. package/eval/local/tasks/workflow-overlay-contract/task.toml +21 -0
  444. package/eval/local/tasks/workflow-overlay-contract/validation/test_workflow_overlay_contract.py +235 -0
  445. package/eval/local/tasks/workflow-route-conformance/environment/Dockerfile +2 -0
  446. package/eval/local/tasks/workflow-route-conformance/instruction.md +5 -0
  447. package/eval/local/tasks/workflow-route-conformance/task.toml +21 -0
  448. package/eval/local/tasks/workflow-route-conformance/validation/test_workflow_route_conformance.py +84 -0
  449. package/eval/local/tests/conftest.py +1148 -0
  450. package/eval/local/tests/scaffold/test_attribution.py +48 -0
  451. package/eval/local/tests/scaffold/test_compare_baselines.py +999 -0
  452. package/eval/local/tests/scaffold/test_conftest_helpers.py +534 -0
  453. package/eval/local/tests/scaffold/test_evidence.py +15 -0
  454. package/eval/local/tests/scaffold/test_langsmith_conftest.py +244 -0
  455. package/eval/local/tests/scaffold/test_logging.py +243 -0
  456. package/eval/local/tests/scaffold/test_manifests.py +132 -0
  457. package/eval/local/tests/scaffold/test_profiles.py +866 -0
  458. package/eval/local/tests/scaffold/test_regression_check.py +19 -0
  459. package/eval/local/tests/scaffold/test_report_style_demo_charts.py +45 -0
  460. package/eval/local/tests/scaffold/test_sample_quality.py +211 -0
  461. package/eval/local/tests/scaffold/test_tasks.py +168 -0
  462. package/eval/local/tests/scaffold/test_treatments.py +244 -0
  463. package/eval/local/tests/scaffold/test_utils.py +139 -0
  464. package/eval/local/tests/tasks/test_tasks.py +445 -0
  465. package/eval/local/tests/tasks/test_validation_scripts.py +143 -0
  466. package/eval/local/treatments/comet/comet_full_039.yaml +141 -0
  467. package/eval/local/treatments/comet/comet_full_040_beta.yaml +140 -0
  468. package/eval/local/treatments/common/control.yaml +4 -0
  469. package/eval/pyproject.toml +41 -0
  470. package/eval/report-html-config.json +6 -0
  471. package/eval/scaffold/__init__.py +67 -0
  472. package/eval/scaffold/python/__init__.py +95 -0
  473. package/eval/scaffold/python/attribution.py +43 -0
  474. package/eval/scaffold/python/evidence.py +38 -0
  475. package/eval/scaffold/python/external_data_handler.py +18 -0
  476. package/eval/scaffold/python/generic_llm_judge.py +235 -0
  477. package/eval/scaffold/python/judge_config.py +168 -0
  478. package/eval/scaffold/python/llm_judge.py +191 -0
  479. package/eval/scaffold/python/logging.py +705 -0
  480. package/eval/scaffold/python/manifests.py +129 -0
  481. package/eval/scaffold/python/paper_charts.py +25 -0
  482. package/eval/scaffold/python/pass_at_k.py +107 -0
  483. package/eval/scaffold/python/paths.py +56 -0
  484. package/eval/scaffold/python/profiles.py +127 -0
  485. package/eval/scaffold/python/report_outputs.py +1391 -0
  486. package/eval/scaffold/python/sample_quality.py +339 -0
  487. package/eval/scaffold/python/schema.py +39 -0
  488. package/eval/scaffold/python/skill_parser.py +469 -0
  489. package/eval/scaffold/python/tasks.py +330 -0
  490. package/eval/scaffold/python/treatments.py +271 -0
  491. package/eval/scaffold/python/utils.py +366 -0
  492. package/eval/scaffold/python/validation/__init__.py +21 -0
  493. package/eval/scaffold/python/validation/authoring_rubric.py +326 -0
  494. package/eval/scaffold/python/validation/comet_workflow.py +187 -0
  495. package/eval/scaffold/python/validation/core.py +264 -0
  496. package/eval/scaffold/python/validation/dataset.py +337 -0
  497. package/eval/scaffold/python/validation/docker.py +106 -0
  498. package/eval/scaffold/python/validation/evaluator.py +549 -0
  499. package/eval/scaffold/python/validation/generic_rubric.py +169 -0
  500. package/eval/scaffold/python/validation/rubric.py +740 -0
  501. package/eval/scaffold/python/validation/runner.py +237 -0
  502. package/eval/scaffold/python/validation/scripts.py +58 -0
  503. package/eval/scaffold/python/validation/tracing.py +313 -0
  504. package/eval/scaffold/shell/common.sh +126 -0
  505. package/eval/scaffold/shell/docker.sh +482 -0
  506. package/eval/scaffold/shell/run-claude-loop.sh +181 -0
  507. package/eval/scaffold/shell/setup.sh +259 -0
  508. package/eval/simulator-instruction.md +9 -0
  509. package/package.json +24 -2
@@ -0,0 +1,469 @@
1
+ """
2
+ Skill Parser - Parse and manipulate skill.md files.
3
+
4
+ This module provides utilities for reading, parsing, and transforming skill
5
+ markdown files used in the benchmarks. Skill files use XML-tagged sections
6
+ to organize content, with optional language-specific blocks (<python>, <typescript>).
7
+
8
+ ## Core Concepts
9
+
10
+ ### Skill File Structure
11
+ Skill files (skill.md, skill_py.md, skill_ts.md, skill_all.md) contain:
12
+ - YAML frontmatter (between --- delimiters)
13
+ - XML-tagged sections (<overview>, <ex-basic>, <fix-common-error>, etc.)
14
+ - Language-specific code blocks (<python>...</python>, <typescript>...</typescript>)
15
+
16
+ ### Variants
17
+ Skills can have multiple variants:
18
+ - skill.md: Default/combined skill
19
+ - skill_py.md: Python-specific content
20
+ - skill_ts.md: TypeScript-specific content
21
+ - skill_all.md: All languages combined
22
+
23
+ ## Usage Examples
24
+
25
+ ### Load and parse a skill:
26
+ ```python
27
+ from scaffold.python.skill_parser import load_skill, load_skill_variant
28
+
29
+ # Load default skill.md
30
+ skill = load_skill(Path("skills/benchmarks/langsmith_trace"))
31
+ print(skill["sections"]["overview"])
32
+
33
+ # Load Python-specific variant
34
+ skill_py = load_skill_variant(Path("skills/benchmarks/langsmith_trace"), "py")
35
+ ```
36
+
37
+ ### Extract language-specific content:
38
+ ```python
39
+ from scaffold.python.skill_parser import load_skill_content, strip_lang_tags
40
+
41
+ content = load_skill_content(Path("skills/benchmarks/oss_split/lc_agents/skill_all.md"))
42
+
43
+ # Get Python-only content (remove TypeScript blocks)
44
+ py_only = strip_lang_tags(content, exclude=["typescript"])
45
+
46
+ # Get TypeScript-only content (remove Python blocks)
47
+ ts_only = strip_lang_tags(content, exclude=["python"])
48
+ ```
49
+
50
+ ### Filter specific sections by tag:
51
+ ```python
52
+ from scaffold.python.skill_parser import strip_by_tags
53
+
54
+ # Remove specific gotchas or examples by their tag attribute
55
+ filtered = strip_by_tags(content, exclude=["gotcha-faiss", "example-advanced"])
56
+ ```
57
+
58
+ ### Build custom skill configs for treatments:
59
+ ```python
60
+ from scaffold.python.skill_parser import load_skill, skill_config
61
+
62
+ skill = load_skill(Path("skills/benchmarks/langsmith_trace"))
63
+
64
+ # Select specific sections
65
+ my_config = skill_config(
66
+ sections=[
67
+ skill["sections"]["frontmatter"],
68
+ skill["sections"]["overview"],
69
+ skill["sections"]["ex-basic"],
70
+ ],
71
+ scripts_dir=skill["scripts_dir"],
72
+ script_filter="py",
73
+ )
74
+ ```
75
+ """
76
+
77
+ import re
78
+ from pathlib import Path
79
+
80
+ # Regex patterns for skill parsing
81
+ FRONTMATTER_PATTERN = re.compile(r"^---\n(.*?)\n---", re.DOTALL)
82
+ XML_TAG_PATTERN = re.compile(r"<(\w+)>(.*?)</\1>", re.DOTALL)
83
+ EXCESS_NEWLINES_PATTERN = re.compile(r"\n{3,}")
84
+
85
+
86
+ def _cleanup_whitespace(content: str) -> str:
87
+ """Collapse 3+ consecutive newlines to 2."""
88
+ return EXCESS_NEWLINES_PATTERN.sub("\n\n", content)
89
+
90
+
91
+ def parse_skill_md(skill_md_path: Path, keep_tags: bool = True) -> dict[str, str]:
92
+ """Parse skill.md and return sections dict keyed by tag name.
93
+
94
+ Frontmatter is extracted using --- delimiters (no XML tag needed).
95
+ All other sections preserve their XML tags for delineation.
96
+
97
+ Args:
98
+ skill_md_path: Path to skill.md file
99
+ keep_tags: If True, preserve XML tags around content (except frontmatter).
100
+
101
+ Returns:
102
+ Dict mapping tag names to their content
103
+
104
+ Example:
105
+ >>> sections = parse_skill_md(Path("skill.md"))
106
+ >>> print(sections["overview"])
107
+ '<overview>\\nBuild RAG systems...\\n</overview>'
108
+ """
109
+ content = skill_md_path.read_text(encoding="utf-8")
110
+ sections = {}
111
+
112
+ # Extract frontmatter using --- delimiters
113
+ fm_match = FRONTMATTER_PATTERN.search(content)
114
+ if fm_match:
115
+ sections["frontmatter"] = f"---\n{fm_match.group(1).strip()}\n---"
116
+
117
+ # Find all XML tags and their content (skip frontmatter if present)
118
+ for match in XML_TAG_PATTERN.finditer(content):
119
+ tag_name = match.group(1)
120
+ if tag_name == "frontmatter":
121
+ continue # Already handled above
122
+ tag_content = match.group(2).strip()
123
+
124
+ if keep_tags:
125
+ sections[tag_name] = f"<{tag_name}>\n{tag_content}\n</{tag_name}>"
126
+ else:
127
+ sections[tag_name] = tag_content
128
+
129
+ return sections
130
+
131
+
132
+ def parse_skill_md_ordered(skill_md_path: Path, keep_tags: bool = True) -> list[tuple[str, str]]:
133
+ """Parse skill.md and return sections as ordered list of (tag, content) tuples.
134
+
135
+ Preserves the order of sections as they appear in the file.
136
+ Frontmatter is extracted using --- delimiters and placed first.
137
+
138
+ Args:
139
+ skill_md_path: Path to skill.md file
140
+ keep_tags: If True, preserve XML tags around content (except frontmatter).
141
+
142
+ Returns:
143
+ List of (tag_name, content) tuples in document order
144
+
145
+ Example:
146
+ >>> sections = parse_skill_md_ordered(Path("skill.md"))
147
+ >>> for tag, content in sections[:3]:
148
+ ... print(f"{tag}: {len(content)} chars")
149
+ frontmatter: 150 chars
150
+ overview: 500 chars
151
+ ex-basic: 1200 chars
152
+ """
153
+ content = skill_md_path.read_text(encoding="utf-8")
154
+ sections = []
155
+
156
+ # Extract frontmatter using --- delimiters (always first)
157
+ fm_match = FRONTMATTER_PATTERN.search(content)
158
+ if fm_match:
159
+ sections.append(("frontmatter", f"---\n{fm_match.group(1).strip()}\n---"))
160
+
161
+ # Find all XML tags and their content (skip frontmatter if present)
162
+ for match in XML_TAG_PATTERN.finditer(content):
163
+ tag_name = match.group(1)
164
+ if tag_name == "frontmatter":
165
+ continue # Already handled above
166
+ tag_content = match.group(2).strip()
167
+
168
+ if keep_tags:
169
+ sections.append((tag_name, f"<{tag_name}>\n{tag_content}\n</{tag_name}>"))
170
+ else:
171
+ sections.append((tag_name, tag_content))
172
+
173
+ return sections
174
+
175
+
176
+ def load_skill_content(skill_md_path: Path) -> str:
177
+ """Load full skill content from skill.md.
178
+
179
+ Returns the raw file content. Useful for getting the complete skill
180
+ as a single string for filtering or transformation.
181
+
182
+ Args:
183
+ skill_md_path: Path to skill.md file
184
+
185
+ Returns:
186
+ Full file content as string
187
+
188
+ Example:
189
+ >>> content = load_skill_content(Path("skill_all.md"))
190
+ >>> py_only = strip_lang_tags(content, exclude=["typescript"])
191
+ """
192
+ return skill_md_path.read_text(encoding="utf-8")
193
+
194
+
195
+ def get_section_list(
196
+ skill_md_path: Path, exclude_tags: list[str] = None, keep_tags: bool = True
197
+ ) -> list[str]:
198
+ """Get ordered list of section contents.
199
+
200
+ This is useful for building FULL_SECTIONS-style lists where you want
201
+ all section contents joined together.
202
+
203
+ Args:
204
+ skill_md_path: Path to skill.md file
205
+ exclude_tags: Optional list of tag names to exclude (e.g., ['frontmatter'])
206
+ keep_tags: If True, preserve XML tags around content (except frontmatter).
207
+
208
+ Returns:
209
+ List of section content strings in document order
210
+
211
+ Example:
212
+ >>> sections = get_section_list(Path("skill.md"), exclude_tags=["frontmatter"])
213
+ >>> full_content = "\\n\\n".join(sections)
214
+ """
215
+ exclude_tags = exclude_tags or []
216
+ sections = parse_skill_md_ordered(skill_md_path, keep_tags=keep_tags)
217
+ return [content for tag, content in sections if tag not in exclude_tags]
218
+
219
+
220
+ def format_section_with_tags(tag: str, content: str) -> str:
221
+ """Format content with XML tags for output.
222
+
223
+ Useful when you need to reconstruct skill.md format.
224
+
225
+ Args:
226
+ tag: XML tag name
227
+ content: Section content
228
+
229
+ Returns:
230
+ Formatted string with opening and closing tags
231
+
232
+ Example:
233
+ >>> formatted = format_section_with_tags("overview", "This is the overview.")
234
+ >>> print(formatted)
235
+ <overview>
236
+ This is the overview.
237
+ </overview>
238
+ """
239
+ return f"<{tag}>\n{content}\n</{tag}>"
240
+
241
+
242
+ # Script extension mapping for variant-based filtering
243
+ SCRIPT_EXTENSIONS = {
244
+ "py": [".py"],
245
+ "ts": [".ts", ".js", ".mjs", ".mts"],
246
+ "all": None, # No filtering - copy all scripts
247
+ }
248
+
249
+
250
+ def load_skill(skill_dir: Path) -> dict:
251
+ """Load skill from a skill directory containing skill.md.
252
+
253
+ Provides a convenient interface for tests to load and select sections.
254
+
255
+ Args:
256
+ skill_dir: Path to skill directory (contains skill.md and optionally scripts/)
257
+
258
+ Returns:
259
+ Dict with:
260
+ - sections: dict mapping tag names to content
261
+ - all: list of all section contents in document order
262
+ - scripts_dir: Path to scripts/ subdirectory (or None if doesn't exist)
263
+
264
+ Example:
265
+ >>> trace = load_skill(Path("skills/benchmarks/langsmith_trace"))
266
+ >>> # Get specific sections
267
+ >>> my_sections = [
268
+ ... trace["sections"]["frontmatter"],
269
+ ... trace["sections"]["oneliner"],
270
+ ... trace["sections"]["setup"],
271
+ ... ]
272
+ >>> # Or get all sections
273
+ >>> full_sections = trace["all"]
274
+ """
275
+ skill_md_path = skill_dir / "skill.md"
276
+ sections = parse_skill_md(skill_md_path)
277
+ all_sections = get_section_list(skill_md_path)
278
+ scripts_dir = skill_dir / "scripts"
279
+
280
+ return {
281
+ "sections": sections,
282
+ "all": all_sections,
283
+ "scripts_dir": scripts_dir if scripts_dir.exists() else None,
284
+ }
285
+
286
+
287
+ def load_skill_variant(skill_dir: Path, variant: str = None) -> dict:
288
+ """Load skill from a specific .md file variant.
289
+
290
+ Supports loading language-specific skill files (skill_py.md, skill_ts.md)
291
+ or combined files (skill_all.md). The variant also determines which scripts
292
+ get copied during test setup.
293
+
294
+ Args:
295
+ skill_dir: Path to skill directory
296
+ variant: Variant name ("py", "ts", "all") or None for default skill.md
297
+
298
+ Returns:
299
+ Dict with:
300
+ - sections: dict mapping tag names to content
301
+ - all: list of all section contents in document order
302
+ - scripts_dir: Path to scripts/ subdirectory (or None if doesn't exist)
303
+ - script_filter: variant name (used to filter scripts during setup)
304
+
305
+ Example:
306
+ >>> # Load Python variant - will filter to .py scripts during setup
307
+ >>> trace_py = load_skill_variant(Path("skills/benchmarks/langsmith_trace"), "py")
308
+ >>>
309
+ >>> # Load TypeScript variant - will filter to .ts/.js scripts during setup
310
+ >>> trace_ts = load_skill_variant(Path("skills/benchmarks/langsmith_trace"), "ts")
311
+ >>>
312
+ >>> # Load combined variant - will copy all scripts during setup
313
+ >>> trace_all = load_skill_variant(Path("skills/benchmarks/langsmith_trace"), "all")
314
+ """
315
+ if variant:
316
+ skill_md_path = skill_dir / f"skill_{variant}.md"
317
+ else:
318
+ skill_md_path = skill_dir / "skill.md"
319
+
320
+ if not skill_md_path.exists():
321
+ raise FileNotFoundError(f"Skill file not found: {skill_md_path}")
322
+
323
+ sections = parse_skill_md(skill_md_path)
324
+ all_sections = get_section_list(skill_md_path)
325
+ scripts_dir = skill_dir / "scripts"
326
+
327
+ return {
328
+ "sections": sections,
329
+ "all": all_sections,
330
+ "scripts_dir": scripts_dir if scripts_dir.exists() else None,
331
+ "script_filter": variant,
332
+ }
333
+
334
+
335
+ def split_skill(
336
+ skill: dict, splits: dict[str, list[str]], base_name: str = None
337
+ ) -> dict[str, dict]:
338
+ """Split one skill into multiple skill configs by section groups.
339
+
340
+ Useful for experiments testing whether smaller, focused skills improve
341
+ Claude's performance vs one large skill.
342
+
343
+ Args:
344
+ skill: Result from load_skill()
345
+ splits: Dict mapping new skill names to lists of section tags to include
346
+ base_name: Optional base name for frontmatter rewrite (e.g., "langsmith-trace")
347
+
348
+ Returns:
349
+ Dict mapping skill names to skill configs (sections list + scripts_dir)
350
+
351
+ Example:
352
+ >>> trace = load_skill(Path("skills/benchmarks/langsmith_trace"))
353
+ >>> # Split into setup + querying skills
354
+ >>> split_skills = split_skill(trace, {
355
+ ... "langsmith-trace-setup": ["frontmatter", "oneliner", "setup"],
356
+ ... "langsmith-trace-query": ["frontmatter", "oneliner", "querying_traces"],
357
+ ... }, base_name="langsmith-trace")
358
+ """
359
+ result = {}
360
+ for skill_name, tags in splits.items():
361
+ sections = []
362
+ for tag in tags:
363
+ content = skill.get("sections", {}).get(tag, "")
364
+ if content:
365
+ # Optionally rewrite frontmatter name for the split skill
366
+ if tag == "frontmatter" and base_name and skill_name != base_name:
367
+ content = content.replace(f"name: {base_name}", f"name: {skill_name}")
368
+ sections.append(content)
369
+ result[skill_name] = {
370
+ "sections": sections,
371
+ "scripts_dir": skill.get("scripts_dir"),
372
+ }
373
+ return result
374
+
375
+
376
+ def skill_config(sections: list[str], scripts_dir: Path = None, script_filter: str = None) -> dict:
377
+ """Create a skill config dict for use in treatments.
378
+
379
+ Convenience function for creating skill configs inline.
380
+
381
+ Args:
382
+ sections: List of section content strings
383
+ scripts_dir: Optional path to scripts directory
384
+ script_filter: Optional filter for scripts ("py", "ts", "all")
385
+
386
+ Returns:
387
+ Dict with "sections", "scripts_dir", and "script_filter" keys
388
+
389
+ Example:
390
+ >>> treatment = Treatment(
391
+ ... skills={
392
+ ... "my-skill": skill_config([HEADER, SETUP, EXAMPLES], scripts_dir, "py"),
393
+ ... },
394
+ ... ...
395
+ ... )
396
+ """
397
+ return {"sections": sections, "scripts_dir": scripts_dir, "script_filter": script_filter}
398
+
399
+
400
+ def strip_lang_tags(content: str, exclude: list[str] | None = None) -> str:
401
+ """Strip language-specific XML tags from skill content.
402
+
403
+ Removes <python> and/or <typescript> tagged sections from content.
404
+ Tags may have attributes like <python tag="section-name">.
405
+
406
+ This is useful for creating language-specific versions of skill_all.md
407
+ files that contain both Python and TypeScript examples.
408
+
409
+ Args:
410
+ content: Skill markdown content
411
+ exclude: List of languages to exclude ("python", "typescript").
412
+ If None or empty, returns content unchanged.
413
+
414
+ Returns:
415
+ Content with specified language sections removed
416
+
417
+ Example:
418
+ >>> content = load_skill_content(Path("skill_all.md"))
419
+ >>> # Remove Python examples, keep TypeScript
420
+ >>> ts_only = strip_lang_tags(content, exclude=["python"])
421
+ >>> # Remove TypeScript examples, keep Python
422
+ >>> py_only = strip_lang_tags(content, exclude=["typescript"])
423
+ """
424
+ if not exclude:
425
+ return content
426
+
427
+ result = content
428
+ for lang in exclude:
429
+ # Match tags with optional attributes: <python> or <python tag="...">
430
+ pattern = rf"<{lang}(?:\s+[^>]*)?>.*?</{lang}>"
431
+ result = re.sub(pattern, "", result, flags=re.DOTALL)
432
+
433
+ return _cleanup_whitespace(result)
434
+
435
+
436
+ def strip_by_tags(content: str, exclude: list[str] | None = None) -> str:
437
+ """Strip content blocks by their tag attribute value.
438
+
439
+ Removes <python tag="name"> or <typescript tag="name"> blocks where
440
+ the tag attribute matches one of the excluded names.
441
+
442
+ This is useful for filtering out specific examples, gotchas, or other
443
+ tagged content without removing all content of that language.
444
+
445
+ Args:
446
+ content: Skill markdown content
447
+ exclude: List of tag attribute values to exclude.
448
+ If None or empty, returns content unchanged.
449
+
450
+ Returns:
451
+ Content with specified tagged sections removed
452
+
453
+ Example:
454
+ >>> # Remove specific gotchas by tag name
455
+ >>> filtered = strip_by_tags(content, exclude=["faiss-deserialize", "import-packages"])
456
+ >>> # Works with any tag attribute value
457
+ >>> filtered = strip_by_tags(content, exclude=["basic-setup", "advanced-config"])
458
+ """
459
+ if not exclude:
460
+ return content
461
+
462
+ result = content
463
+ for tag_name in exclude:
464
+ # Match <python tag="name">...</python> or <typescript tag="name">...</typescript>
465
+ # The tag attribute value must match exactly
466
+ pattern = rf'<(python|typescript)\s+tag="{re.escape(tag_name)}"[^>]*>.*?</\1>'
467
+ result = re.sub(pattern, "", result, flags=re.DOTALL)
468
+
469
+ return _cleanup_whitespace(result)