@bastani/atomic 0.5.11 → 0.5.12-1

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 (507) hide show
  1. package/.agents/skills/adapt/SKILL.md +199 -0
  2. package/.agents/skills/advanced-evaluation/SKILL.md +402 -0
  3. package/.agents/skills/advanced-evaluation/references/bias-mitigation.md +288 -0
  4. package/.agents/skills/advanced-evaluation/references/evaluation-pipeline.md +43 -0
  5. package/.agents/skills/advanced-evaluation/references/implementation-patterns.md +315 -0
  6. package/.agents/skills/advanced-evaluation/references/metrics-guide.md +331 -0
  7. package/.agents/skills/advanced-evaluation/scripts/evaluation_example.py +392 -0
  8. package/.agents/skills/animate/SKILL.md +175 -0
  9. package/.agents/skills/arrange/SKILL.md +124 -0
  10. package/.agents/skills/audit/SKILL.md +148 -0
  11. package/.agents/skills/bdi-mental-states/SKILL.md +311 -0
  12. package/.agents/skills/bdi-mental-states/references/bdi-ontology-core.md +207 -0
  13. package/.agents/skills/bdi-mental-states/references/framework-integration.md +582 -0
  14. package/.agents/skills/bdi-mental-states/references/rdf-examples.md +315 -0
  15. package/.agents/skills/bdi-mental-states/references/sparql-competency.md +420 -0
  16. package/.agents/skills/bolder/SKILL.md +117 -0
  17. package/.agents/skills/bun/SKILL.md +199 -0
  18. package/.agents/skills/clarify/SKILL.md +183 -0
  19. package/.agents/skills/colorize/SKILL.md +143 -0
  20. package/.agents/skills/context-compression/SKILL.md +272 -0
  21. package/.agents/skills/context-compression/references/evaluation-framework.md +213 -0
  22. package/.agents/skills/context-compression/scripts/compression_evaluator.py +862 -0
  23. package/.agents/skills/context-compression/tests/test_compression_evaluator.py +56 -0
  24. package/.agents/skills/context-degradation/SKILL.md +206 -0
  25. package/.agents/skills/context-degradation/references/patterns.md +314 -0
  26. package/.agents/skills/context-degradation/scripts/degradation_detector.py +614 -0
  27. package/.agents/skills/context-fundamentals/SKILL.md +201 -0
  28. package/.agents/skills/context-fundamentals/references/context-components.md +283 -0
  29. package/.agents/skills/context-fundamentals/scripts/context_manager.py +533 -0
  30. package/.agents/skills/context-optimization/SKILL.md +195 -0
  31. package/.agents/skills/context-optimization/references/optimization_techniques.md +272 -0
  32. package/.agents/skills/context-optimization/scripts/compaction.py +562 -0
  33. package/.agents/skills/create-spec/SKILL.md +244 -0
  34. package/.agents/skills/critique/SKILL.md +225 -0
  35. package/.agents/skills/critique/reference/cognitive-load.md +106 -0
  36. package/.agents/skills/critique/reference/heuristics-scoring.md +234 -0
  37. package/.agents/skills/critique/reference/personas.md +178 -0
  38. package/.agents/skills/delight/SKILL.md +304 -0
  39. package/.agents/skills/distill/SKILL.md +122 -0
  40. package/.agents/skills/docx/LICENSE.txt +30 -0
  41. package/.agents/skills/docx/SKILL.md +590 -0
  42. package/.agents/skills/docx/scripts/__init__.py +1 -0
  43. package/.agents/skills/docx/scripts/accept_changes.py +135 -0
  44. package/.agents/skills/docx/scripts/comment.py +318 -0
  45. package/.agents/skills/docx/scripts/office/helpers/__init__.py +0 -0
  46. package/.agents/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
  47. package/.agents/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  48. package/.agents/skills/docx/scripts/office/pack.py +159 -0
  49. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  50. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  51. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  52. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  53. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  54. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  55. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  56. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  57. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  58. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  59. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  60. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  61. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  62. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  63. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  64. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  65. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  66. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  67. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  68. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  69. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  70. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  71. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  72. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  73. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  74. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  75. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  76. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  77. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  78. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  79. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  80. package/.agents/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  81. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  82. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  83. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  84. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  85. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  86. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  87. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  88. package/.agents/skills/docx/scripts/office/soffice.py +183 -0
  89. package/.agents/skills/docx/scripts/office/unpack.py +132 -0
  90. package/.agents/skills/docx/scripts/office/validate.py +111 -0
  91. package/.agents/skills/docx/scripts/office/validators/__init__.py +15 -0
  92. package/.agents/skills/docx/scripts/office/validators/base.py +847 -0
  93. package/.agents/skills/docx/scripts/office/validators/docx.py +446 -0
  94. package/.agents/skills/docx/scripts/office/validators/pptx.py +275 -0
  95. package/.agents/skills/docx/scripts/office/validators/redlining.py +247 -0
  96. package/.agents/skills/docx/scripts/templates/comments.xml +3 -0
  97. package/.agents/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  98. package/.agents/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  99. package/.agents/skills/docx/scripts/templates/commentsIds.xml +3 -0
  100. package/.agents/skills/docx/scripts/templates/people.xml +3 -0
  101. package/.agents/skills/evaluation/SKILL.md +251 -0
  102. package/.agents/skills/evaluation/references/metrics.md +339 -0
  103. package/.agents/skills/evaluation/scripts/evaluator.py +627 -0
  104. package/.agents/skills/explain-code/SKILL.md +230 -0
  105. package/.agents/skills/extract/SKILL.md +91 -0
  106. package/.agents/skills/filesystem-context/SKILL.md +287 -0
  107. package/.agents/skills/filesystem-context/references/implementation-patterns.md +549 -0
  108. package/.agents/skills/filesystem-context/scripts/filesystem_context.py +425 -0
  109. package/.agents/skills/find-skills/SKILL.md +142 -0
  110. package/.agents/skills/frontend-design/SKILL.md +147 -0
  111. package/.agents/skills/frontend-design/reference/color-and-contrast.md +132 -0
  112. package/.agents/skills/frontend-design/reference/interaction-design.md +195 -0
  113. package/.agents/skills/frontend-design/reference/motion-design.md +99 -0
  114. package/.agents/skills/frontend-design/reference/responsive-design.md +114 -0
  115. package/.agents/skills/frontend-design/reference/spatial-design.md +100 -0
  116. package/.agents/skills/frontend-design/reference/typography.md +133 -0
  117. package/.agents/skills/frontend-design/reference/ux-writing.md +107 -0
  118. package/.agents/skills/gh-commit/SKILL.md +243 -0
  119. package/.agents/skills/gh-create-pr/SKILL.md +93 -0
  120. package/.agents/skills/harden/SKILL.md +354 -0
  121. package/.agents/skills/hosted-agents/SKILL.md +260 -0
  122. package/.agents/skills/hosted-agents/references/infrastructure-patterns.md +700 -0
  123. package/.agents/skills/hosted-agents/scripts/sandbox_manager.py +590 -0
  124. package/.agents/skills/impeccable/SKILL.md +365 -0
  125. package/.agents/skills/impeccable/reference/color-and-contrast.md +105 -0
  126. package/.agents/skills/impeccable/reference/craft.md +70 -0
  127. package/.agents/skills/impeccable/reference/extract.md +70 -0
  128. package/.agents/skills/impeccable/reference/interaction-design.md +195 -0
  129. package/.agents/skills/impeccable/reference/motion-design.md +99 -0
  130. package/.agents/skills/impeccable/reference/responsive-design.md +114 -0
  131. package/.agents/skills/impeccable/reference/spatial-design.md +100 -0
  132. package/.agents/skills/impeccable/reference/typography.md +142 -0
  133. package/.agents/skills/impeccable/reference/ux-writing.md +107 -0
  134. package/.agents/skills/impeccable/scripts/cleanup-deprecated.mjs +214 -0
  135. package/.agents/skills/init/SKILL.md +138 -0
  136. package/.agents/skills/layout/SKILL.md +125 -0
  137. package/.agents/skills/liteparse/SKILL.md +222 -0
  138. package/.agents/skills/memory-systems/SKILL.md +219 -0
  139. package/.agents/skills/memory-systems/references/implementation.md +551 -0
  140. package/.agents/skills/memory-systems/scripts/memory_store.py +616 -0
  141. package/.agents/skills/multi-agent-patterns/SKILL.md +257 -0
  142. package/.agents/skills/multi-agent-patterns/references/frameworks.md +433 -0
  143. package/.agents/skills/multi-agent-patterns/scripts/coordination.py +613 -0
  144. package/.agents/skills/normalize/SKILL.md +70 -0
  145. package/.agents/skills/onboard/SKILL.md +245 -0
  146. package/.agents/skills/opentui/SKILL.md +201 -0
  147. package/.agents/skills/opentui/references/animation/REFERENCE.md +431 -0
  148. package/.agents/skills/opentui/references/components/REFERENCE.md +144 -0
  149. package/.agents/skills/opentui/references/components/code-diff.md +672 -0
  150. package/.agents/skills/opentui/references/components/containers.md +417 -0
  151. package/.agents/skills/opentui/references/components/inputs.md +531 -0
  152. package/.agents/skills/opentui/references/components/text-display.md +386 -0
  153. package/.agents/skills/opentui/references/core/REFERENCE.md +145 -0
  154. package/.agents/skills/opentui/references/core/api.md +543 -0
  155. package/.agents/skills/opentui/references/core/configuration.md +168 -0
  156. package/.agents/skills/opentui/references/core/gotchas.md +393 -0
  157. package/.agents/skills/opentui/references/core/patterns.md +449 -0
  158. package/.agents/skills/opentui/references/keyboard/REFERENCE.md +617 -0
  159. package/.agents/skills/opentui/references/layout/REFERENCE.md +337 -0
  160. package/.agents/skills/opentui/references/layout/patterns.md +444 -0
  161. package/.agents/skills/opentui/references/react/REFERENCE.md +174 -0
  162. package/.agents/skills/opentui/references/react/api.md +436 -0
  163. package/.agents/skills/opentui/references/react/configuration.md +302 -0
  164. package/.agents/skills/opentui/references/react/gotchas.md +443 -0
  165. package/.agents/skills/opentui/references/react/patterns.md +501 -0
  166. package/.agents/skills/opentui/references/solid/REFERENCE.md +201 -0
  167. package/.agents/skills/opentui/references/solid/api.md +564 -0
  168. package/.agents/skills/opentui/references/solid/configuration.md +316 -0
  169. package/.agents/skills/opentui/references/solid/gotchas.md +427 -0
  170. package/.agents/skills/opentui/references/solid/patterns.md +560 -0
  171. package/.agents/skills/opentui/references/testing/REFERENCE.md +614 -0
  172. package/.agents/skills/optimize/SKILL.md +266 -0
  173. package/.agents/skills/overdrive/SKILL.md +142 -0
  174. package/.agents/skills/pdf/LICENSE.txt +30 -0
  175. package/.agents/skills/pdf/SKILL.md +314 -0
  176. package/.agents/skills/pdf/forms.md +294 -0
  177. package/.agents/skills/pdf/reference.md +612 -0
  178. package/.agents/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  179. package/.agents/skills/pdf/scripts/check_fillable_fields.py +11 -0
  180. package/.agents/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  181. package/.agents/skills/pdf/scripts/create_validation_image.py +37 -0
  182. package/.agents/skills/pdf/scripts/extract_form_field_info.py +122 -0
  183. package/.agents/skills/pdf/scripts/extract_form_structure.py +115 -0
  184. package/.agents/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  185. package/.agents/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  186. package/.agents/skills/playwright-cli/SKILL.md +344 -0
  187. package/.agents/skills/playwright-cli/references/element-attributes.md +23 -0
  188. package/.agents/skills/playwright-cli/references/playwright-tests.md +39 -0
  189. package/.agents/skills/playwright-cli/references/request-mocking.md +87 -0
  190. package/.agents/skills/playwright-cli/references/running-code.md +231 -0
  191. package/.agents/skills/playwright-cli/references/session-management.md +169 -0
  192. package/.agents/skills/playwright-cli/references/storage-state.md +275 -0
  193. package/.agents/skills/playwright-cli/references/test-generation.md +88 -0
  194. package/.agents/skills/playwright-cli/references/tracing.md +139 -0
  195. package/.agents/skills/playwright-cli/references/video-recording.md +143 -0
  196. package/.agents/skills/polish/SKILL.md +224 -0
  197. package/.agents/skills/pptx/LICENSE.txt +30 -0
  198. package/.agents/skills/pptx/SKILL.md +232 -0
  199. package/.agents/skills/pptx/editing.md +205 -0
  200. package/.agents/skills/pptx/pptxgenjs.md +420 -0
  201. package/.agents/skills/pptx/scripts/__init__.py +0 -0
  202. package/.agents/skills/pptx/scripts/add_slide.py +195 -0
  203. package/.agents/skills/pptx/scripts/clean.py +286 -0
  204. package/.agents/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  205. package/.agents/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  206. package/.agents/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  207. package/.agents/skills/pptx/scripts/office/pack.py +159 -0
  208. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  209. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  210. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  211. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  212. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  213. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  214. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  215. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  216. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  217. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  218. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  219. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  220. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  221. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  222. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  223. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  224. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  225. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  226. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  227. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  228. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  229. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  230. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  231. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  232. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  233. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  234. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  235. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  236. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  237. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  238. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  239. package/.agents/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  240. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  241. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  242. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  243. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  244. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  245. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  246. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  247. package/.agents/skills/pptx/scripts/office/soffice.py +183 -0
  248. package/.agents/skills/pptx/scripts/office/unpack.py +132 -0
  249. package/.agents/skills/pptx/scripts/office/validate.py +111 -0
  250. package/.agents/skills/pptx/scripts/office/validators/__init__.py +15 -0
  251. package/.agents/skills/pptx/scripts/office/validators/base.py +847 -0
  252. package/.agents/skills/pptx/scripts/office/validators/docx.py +446 -0
  253. package/.agents/skills/pptx/scripts/office/validators/pptx.py +275 -0
  254. package/.agents/skills/pptx/scripts/office/validators/redlining.py +247 -0
  255. package/.agents/skills/pptx/scripts/thumbnail.py +289 -0
  256. package/.agents/skills/project-development/SKILL.md +291 -0
  257. package/.agents/skills/project-development/references/case-studies.md +388 -0
  258. package/.agents/skills/project-development/references/pipeline-patterns.md +610 -0
  259. package/.agents/skills/project-development/scripts/pipeline_template.py +796 -0
  260. package/.agents/skills/prompt-engineer/SKILL.md +263 -0
  261. package/.agents/skills/prompt-engineer/references/advanced_patterns.md +271 -0
  262. package/.agents/skills/prompt-engineer/references/core_prompting.md +137 -0
  263. package/.agents/skills/prompt-engineer/references/quality_improvement.md +193 -0
  264. package/.agents/skills/quieter/SKILL.md +103 -0
  265. package/.agents/skills/research-codebase/SKILL.md +227 -0
  266. package/.agents/skills/shape/SKILL.md +96 -0
  267. package/.agents/skills/skill-creator/LICENSE.txt +202 -0
  268. package/.agents/skills/skill-creator/SKILL.md +485 -0
  269. package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
  270. package/.agents/skills/skill-creator/agents/comparator.md +202 -0
  271. package/.agents/skills/skill-creator/agents/grader.md +223 -0
  272. package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
  273. package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  274. package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  275. package/.agents/skills/skill-creator/references/schemas.md +430 -0
  276. package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
  277. package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  278. package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
  279. package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
  280. package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
  281. package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
  282. package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
  283. package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
  284. package/.agents/skills/skill-creator/scripts/utils.py +47 -0
  285. package/.agents/skills/sl-commit/SKILL.md +51 -0
  286. package/.agents/skills/sl-submit-diff/SKILL.md +55 -0
  287. package/.agents/skills/teach-impeccable/SKILL.md +71 -0
  288. package/.agents/skills/test-driven-development/SKILL.md +371 -0
  289. package/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
  290. package/.agents/skills/tool-design/SKILL.md +271 -0
  291. package/.agents/skills/tool-design/references/architectural_reduction.md +210 -0
  292. package/.agents/skills/tool-design/references/best_practices.md +176 -0
  293. package/.agents/skills/tool-design/scripts/description_generator.py +528 -0
  294. package/.agents/skills/typescript-advanced-types/SKILL.md +719 -0
  295. package/.agents/skills/typescript-expert/SKILL.md +428 -0
  296. package/.agents/skills/typescript-expert/references/tsconfig-strict.json +92 -0
  297. package/.agents/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
  298. package/.agents/skills/typescript-expert/references/utility-types.ts +335 -0
  299. package/.agents/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
  300. package/.agents/skills/typescript-react-reviewer/SKILL.md +200 -0
  301. package/.agents/skills/typescript-react-reviewer/references/antipatterns.md +510 -0
  302. package/.agents/skills/typescript-react-reviewer/references/checklist.md +267 -0
  303. package/.agents/skills/typescript-react-reviewer/references/react19-patterns.md +305 -0
  304. package/.agents/skills/typeset/SKILL.md +116 -0
  305. package/.agents/skills/workflow-creator/SKILL.md +337 -0
  306. package/.agents/skills/workflow-creator/references/agent-sessions.md +789 -0
  307. package/.agents/skills/workflow-creator/references/computation-and-validation.md +224 -0
  308. package/.agents/skills/workflow-creator/references/control-flow.md +450 -0
  309. package/.agents/skills/workflow-creator/references/discovery-and-verification.md +156 -0
  310. package/.agents/skills/workflow-creator/references/failure-modes.md +732 -0
  311. package/.agents/skills/workflow-creator/references/getting-started.md +289 -0
  312. package/.agents/skills/workflow-creator/references/session-config.md +355 -0
  313. package/.agents/skills/workflow-creator/references/state-and-data-flow.md +374 -0
  314. package/.agents/skills/workflow-creator/references/user-input.md +206 -0
  315. package/.agents/skills/workflow-creator/references/workflow-inputs.md +274 -0
  316. package/.agents/skills/xlsx/LICENSE.txt +30 -0
  317. package/.agents/skills/xlsx/SKILL.md +292 -0
  318. package/.agents/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  319. package/.agents/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  320. package/.agents/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  321. package/.agents/skills/xlsx/scripts/office/pack.py +159 -0
  322. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  323. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  324. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  325. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  326. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  327. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  328. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  329. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  330. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  331. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  332. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  333. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  334. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  335. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  336. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  337. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  338. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  339. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  340. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  341. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  342. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  343. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  344. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  345. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  346. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  347. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  348. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  349. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  350. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  351. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  352. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  353. package/.agents/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  354. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  355. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  356. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  357. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  358. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  359. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  360. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  361. package/.agents/skills/xlsx/scripts/office/soffice.py +183 -0
  362. package/.agents/skills/xlsx/scripts/office/unpack.py +132 -0
  363. package/.agents/skills/xlsx/scripts/office/validate.py +111 -0
  364. package/.agents/skills/xlsx/scripts/office/validators/__init__.py +15 -0
  365. package/.agents/skills/xlsx/scripts/office/validators/base.py +847 -0
  366. package/.agents/skills/xlsx/scripts/office/validators/docx.py +446 -0
  367. package/.agents/skills/xlsx/scripts/office/validators/pptx.py +275 -0
  368. package/.agents/skills/xlsx/scripts/office/validators/redlining.py +247 -0
  369. package/.agents/skills/xlsx/scripts/recalc.py +184 -0
  370. package/.claude/agents/reviewer.md +1 -0
  371. package/.github/agents/reviewer.md +1 -0
  372. package/.opencode/agents/reviewer.md +1 -0
  373. package/README.md +274 -169
  374. package/package.json +6 -7
  375. package/src/commands/cli/init/index.ts +2 -2
  376. package/src/commands/cli/init/scm.ts +7 -8
  377. package/src/commands/cli/workflow-command.test.ts +74 -0
  378. package/src/commands/cli/workflow.ts +7 -2
  379. package/src/scripts/bundle-configs.ts +128 -0
  380. package/src/sdk/components/compact-switcher.tsx +1 -1
  381. package/src/sdk/components/orchestrator-panel-store.ts +13 -0
  382. package/src/sdk/components/orchestrator-panel.tsx +10 -0
  383. package/src/sdk/components/statusline.tsx +13 -1
  384. package/src/sdk/components/workflow-picker-panel.tsx +407 -296
  385. package/src/sdk/providers/claude.ts +50 -0
  386. package/src/sdk/runtime/executor.ts +111 -32
  387. package/src/sdk/types.ts +7 -0
  388. package/src/sdk/workflows/builtin/ralph/claude/index.ts +132 -76
  389. package/src/sdk/workflows/builtin/ralph/copilot/index.ts +129 -71
  390. package/src/sdk/workflows/builtin/ralph/helpers/git.ts +184 -17
  391. package/src/sdk/workflows/builtin/ralph/helpers/prompts.ts +463 -79
  392. package/src/sdk/workflows/builtin/ralph/opencode/index.ts +124 -80
  393. package/src/services/system/auto-sync.ts +31 -51
  394. package/src/services/system/skills.ts +56 -60
  395. package/dist/lib/path-root-guard.d.ts +0 -4
  396. package/dist/lib/path-root-guard.d.ts.map +0 -1
  397. package/dist/sdk/components/color-utils.d.ts +0 -4
  398. package/dist/sdk/components/color-utils.d.ts.map +0 -1
  399. package/dist/sdk/components/compact-switcher.d.ts +0 -10
  400. package/dist/sdk/components/compact-switcher.d.ts.map +0 -1
  401. package/dist/sdk/components/connectors.d.ts +0 -15
  402. package/dist/sdk/components/connectors.d.ts.map +0 -1
  403. package/dist/sdk/components/connectors.test.d.ts +0 -2
  404. package/dist/sdk/components/connectors.test.d.ts.map +0 -1
  405. package/dist/sdk/components/edge.d.ts +0 -4
  406. package/dist/sdk/components/edge.d.ts.map +0 -1
  407. package/dist/sdk/components/error-boundary.d.ts +0 -23
  408. package/dist/sdk/components/error-boundary.d.ts.map +0 -1
  409. package/dist/sdk/components/graph-theme.d.ts +0 -17
  410. package/dist/sdk/components/graph-theme.d.ts.map +0 -1
  411. package/dist/sdk/components/header.d.ts +0 -3
  412. package/dist/sdk/components/header.d.ts.map +0 -1
  413. package/dist/sdk/components/hooks.d.ts +0 -15
  414. package/dist/sdk/components/hooks.d.ts.map +0 -1
  415. package/dist/sdk/components/layout.d.ts +0 -27
  416. package/dist/sdk/components/layout.d.ts.map +0 -1
  417. package/dist/sdk/components/layout.test.d.ts +0 -2
  418. package/dist/sdk/components/layout.test.d.ts.map +0 -1
  419. package/dist/sdk/components/node-card.d.ts +0 -10
  420. package/dist/sdk/components/node-card.d.ts.map +0 -1
  421. package/dist/sdk/components/orchestrator-panel-contexts.d.ts +0 -16
  422. package/dist/sdk/components/orchestrator-panel-contexts.d.ts.map +0 -1
  423. package/dist/sdk/components/orchestrator-panel-store.d.ts +0 -46
  424. package/dist/sdk/components/orchestrator-panel-store.d.ts.map +0 -1
  425. package/dist/sdk/components/orchestrator-panel-store.test.d.ts +0 -2
  426. package/dist/sdk/components/orchestrator-panel-store.test.d.ts.map +0 -1
  427. package/dist/sdk/components/orchestrator-panel-types.d.ts +0 -18
  428. package/dist/sdk/components/orchestrator-panel-types.d.ts.map +0 -1
  429. package/dist/sdk/components/orchestrator-panel.d.ts +0 -52
  430. package/dist/sdk/components/orchestrator-panel.d.ts.map +0 -1
  431. package/dist/sdk/components/session-graph-panel.d.ts +0 -7
  432. package/dist/sdk/components/session-graph-panel.d.ts.map +0 -1
  433. package/dist/sdk/components/status-helpers.d.ts +0 -6
  434. package/dist/sdk/components/status-helpers.d.ts.map +0 -1
  435. package/dist/sdk/components/statusline.d.ts +0 -7
  436. package/dist/sdk/components/statusline.d.ts.map +0 -1
  437. package/dist/sdk/components/workflow-picker-panel.d.ts +0 -123
  438. package/dist/sdk/components/workflow-picker-panel.d.ts.map +0 -1
  439. package/dist/sdk/define-workflow.d.ts +0 -78
  440. package/dist/sdk/define-workflow.d.ts.map +0 -1
  441. package/dist/sdk/define-workflow.test.d.ts +0 -2
  442. package/dist/sdk/define-workflow.test.d.ts.map +0 -1
  443. package/dist/sdk/errors.d.ts +0 -24
  444. package/dist/sdk/errors.d.ts.map +0 -1
  445. package/dist/sdk/errors.test.d.ts +0 -2
  446. package/dist/sdk/errors.test.d.ts.map +0 -1
  447. package/dist/sdk/index.d.ts +0 -13
  448. package/dist/sdk/index.d.ts.map +0 -1
  449. package/dist/sdk/providers/claude.d.ts +0 -170
  450. package/dist/sdk/providers/claude.d.ts.map +0 -1
  451. package/dist/sdk/providers/copilot.d.ts +0 -11
  452. package/dist/sdk/providers/copilot.d.ts.map +0 -1
  453. package/dist/sdk/providers/opencode.d.ts +0 -11
  454. package/dist/sdk/providers/opencode.d.ts.map +0 -1
  455. package/dist/sdk/runtime/discovery.d.ts +0 -86
  456. package/dist/sdk/runtime/discovery.d.ts.map +0 -1
  457. package/dist/sdk/runtime/executor-entry.d.ts +0 -11
  458. package/dist/sdk/runtime/executor-entry.d.ts.map +0 -1
  459. package/dist/sdk/runtime/executor.d.ts +0 -72
  460. package/dist/sdk/runtime/executor.d.ts.map +0 -1
  461. package/dist/sdk/runtime/executor.test.d.ts +0 -2
  462. package/dist/sdk/runtime/executor.test.d.ts.map +0 -1
  463. package/dist/sdk/runtime/graph-inference.d.ts +0 -35
  464. package/dist/sdk/runtime/graph-inference.d.ts.map +0 -1
  465. package/dist/sdk/runtime/loader.d.ts +0 -70
  466. package/dist/sdk/runtime/loader.d.ts.map +0 -1
  467. package/dist/sdk/runtime/panel.d.ts +0 -9
  468. package/dist/sdk/runtime/panel.d.ts.map +0 -1
  469. package/dist/sdk/runtime/theme.d.ts +0 -28
  470. package/dist/sdk/runtime/theme.d.ts.map +0 -1
  471. package/dist/sdk/runtime/tmux.d.ts +0 -297
  472. package/dist/sdk/runtime/tmux.d.ts.map +0 -1
  473. package/dist/sdk/types.d.ts +0 -295
  474. package/dist/sdk/types.d.ts.map +0 -1
  475. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +0 -62
  476. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +0 -1
  477. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +0 -46
  478. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +0 -1
  479. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts +0 -26
  480. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts.map +0 -1
  481. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +0 -92
  482. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +0 -1
  483. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts +0 -57
  484. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts.map +0 -1
  485. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +0 -49
  486. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +0 -1
  487. package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts +0 -14
  488. package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +0 -1
  489. package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts +0 -14
  490. package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +0 -1
  491. package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts +0 -17
  492. package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts.map +0 -1
  493. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts +0 -119
  494. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts.map +0 -1
  495. package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts +0 -20
  496. package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts.map +0 -1
  497. package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts +0 -14
  498. package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +0 -1
  499. package/dist/sdk/workflows/index.d.ts +0 -24
  500. package/dist/sdk/workflows/index.d.ts.map +0 -1
  501. package/dist/services/config/definitions.d.ts +0 -85
  502. package/dist/services/config/definitions.d.ts.map +0 -1
  503. package/dist/services/system/copy.d.ts +0 -77
  504. package/dist/services/system/copy.d.ts.map +0 -1
  505. package/dist/services/system/detect.d.ts +0 -75
  506. package/dist/services/system/detect.d.ts.map +0 -1
  507. package/tsconfig.json +0 -33
@@ -0,0 +1,796 @@
1
+ """
2
+ LLM Batch Processing Pipeline Template.
3
+
4
+ A composable, staged pipeline architecture for LLM batch processing.
5
+ Each stage is discrete, idempotent, and cacheable. Customize the acquire,
6
+ prepare, process, parse, and render functions for your use case.
7
+
8
+ Use when:
9
+ - Building a new batch processing pipeline with structured LLM outputs
10
+ - Prototyping an acquire -> prepare -> process -> parse -> render workflow
11
+ - Need a file-system-based state machine for pipeline stage tracking
12
+
13
+ Usage:
14
+ python pipeline_template.py acquire --batch-id 2025-01-15
15
+ python pipeline_template.py prepare --batch-id 2025-01-15
16
+ python pipeline_template.py process --batch-id 2025-01-15 --workers 10
17
+ python pipeline_template.py parse --batch-id 2025-01-15
18
+ python pipeline_template.py render --batch-id 2025-01-15
19
+ python pipeline_template.py all --batch-id 2025-01-15
20
+ python pipeline_template.py clean --batch-id 2025-01-15 --clean-stage process
21
+ python pipeline_template.py estimate --batch-id 2025-01-15
22
+
23
+ Programmatic usage:
24
+ from pipeline_template import stage_acquire, stage_prepare, stage_process
25
+ stage_acquire("2025-01-15", limit=5)
26
+ stage_prepare("2025-01-15")
27
+ stage_process("2025-01-15", model="claude-sonnet-4-20250514", max_workers=3)
28
+ """
29
+
30
+ import argparse
31
+ import json
32
+ import re
33
+ import time
34
+ from concurrent.futures import ThreadPoolExecutor, as_completed
35
+ from dataclasses import dataclass, field, asdict
36
+ from datetime import date
37
+ from pathlib import Path
38
+ from typing import Any
39
+
40
+ __all__ = [
41
+ "Item",
42
+ "ParsedResult",
43
+ "stage_acquire",
44
+ "stage_prepare",
45
+ "stage_process",
46
+ "stage_parse",
47
+ "stage_render",
48
+ "stage_clean",
49
+ "stage_estimate",
50
+ "parse_response",
51
+ "get_batch_dir",
52
+ "get_item_dir",
53
+ "get_output_dir",
54
+ ]
55
+
56
+
57
+ # -----------------------------------------------------------------------------
58
+ # Configuration - Customize for your use case
59
+ # -----------------------------------------------------------------------------
60
+
61
+ DATA_DIR = Path("data")
62
+ OUTPUT_DIR = Path("output")
63
+
64
+ # Prompt template with structured output requirements
65
+ PROMPT_TEMPLATE = """Analyze the following content and provide your response in exactly this format.
66
+
67
+ ## Summary
68
+ [2-3 sentence summary of the content]
69
+
70
+ ## Key Points
71
+ - [Point 1]
72
+ - [Point 2]
73
+ - [Point 3]
74
+
75
+ ## Score
76
+ Rating: [1-10]
77
+ Confidence: [low/medium/high]
78
+
79
+ ## Reasoning
80
+ [Explanation of your analysis]
81
+
82
+ Follow this format exactly because I will be parsing it programmatically.
83
+
84
+ ---
85
+
86
+ # Content to Analyze
87
+
88
+ Title: {title}
89
+
90
+ {content}
91
+ """
92
+
93
+
94
+ # -----------------------------------------------------------------------------
95
+ # Data Structures
96
+ # -----------------------------------------------------------------------------
97
+
98
+ @dataclass
99
+ class Item:
100
+ """Represents a single item to process through the pipeline.
101
+
102
+ Use when: creating items during the acquire stage or loading raw data
103
+ from any source (API, database, file system).
104
+ """
105
+
106
+ id: str
107
+ title: str
108
+ content: str
109
+ metadata: dict[str, Any] = field(default_factory=dict)
110
+
111
+
112
+ @dataclass
113
+ class ParsedResult:
114
+ """Structured result from LLM response parsing.
115
+
116
+ Use when: extracting structured data from free-text LLM responses
117
+ during the parse stage.
118
+ """
119
+
120
+ summary: str = ""
121
+ key_points: list[str] = field(default_factory=list)
122
+ score: int | None = None
123
+ confidence: str = ""
124
+ reasoning: str = ""
125
+ parse_errors: list[str] = field(default_factory=list)
126
+
127
+
128
+ # -----------------------------------------------------------------------------
129
+ # Path Utilities
130
+ # -----------------------------------------------------------------------------
131
+
132
+ def get_batch_dir(batch_id: str) -> Path:
133
+ """Get the data directory for a batch.
134
+
135
+ Use when: resolving the root directory for a specific batch run.
136
+ """
137
+ return DATA_DIR / batch_id
138
+
139
+
140
+ def get_item_dir(batch_id: str, item_id: str) -> Path:
141
+ """Get the directory for a specific item.
142
+
143
+ Use when: locating stage output files for a single pipeline item.
144
+ """
145
+ return get_batch_dir(batch_id) / item_id
146
+
147
+
148
+ def get_output_dir(batch_id: str) -> Path:
149
+ """Get the output directory for a batch.
150
+
151
+ Use when: writing final rendered outputs (HTML, reports, etc.).
152
+ """
153
+ return OUTPUT_DIR / batch_id
154
+
155
+
156
+ # -----------------------------------------------------------------------------
157
+ # Stage: Acquire
158
+ # -----------------------------------------------------------------------------
159
+
160
+ def stage_acquire(batch_id: str, limit: int | None = None) -> list[Path]:
161
+ """Stage 1: Acquire raw data from sources.
162
+
163
+ Use when: fetching data from APIs, databases, or file systems
164
+ and persisting it as raw.json per item for downstream stages.
165
+
166
+ Output: {batch_dir}/{item_id}/raw.json
167
+ Returns: List of item directories that were acquired.
168
+ """
169
+ batch_dir = get_batch_dir(batch_id)
170
+ batch_dir.mkdir(parents=True, exist_ok=True)
171
+
172
+ # CUSTOMIZE: Replace with your data acquisition logic
173
+ items = fetch_items_from_source(limit)
174
+
175
+ acquired_dirs: list[Path] = []
176
+ for item in items:
177
+ item_dir = get_item_dir(batch_id, item.id)
178
+ item_dir.mkdir(exist_ok=True)
179
+
180
+ raw_file = item_dir / "raw.json"
181
+ if not raw_file.exists():
182
+ with open(raw_file, "w") as f:
183
+ json.dump(asdict(item), f, indent=2)
184
+ print(f"Acquired: {item.id}")
185
+ else:
186
+ print(f"Cached: {item.id}")
187
+
188
+ acquired_dirs.append(item_dir)
189
+
190
+ print(f"\nAcquire complete. {len(items)} items in {batch_dir}")
191
+ return acquired_dirs
192
+
193
+
194
+ def fetch_items_from_source(limit: int | None = None) -> list[Item]:
195
+ """CUSTOMIZE: Implement your data fetching logic here.
196
+
197
+ Use when: pulling raw items from your specific data source.
198
+ Replace this with actual API calls, database queries, etc.
199
+ """
200
+ # Example: Generate sample items
201
+ items: list[Item] = []
202
+ for i in range(limit or 10):
203
+ items.append(Item(
204
+ id=f"item-{i:04d}",
205
+ title=f"Sample Item {i}",
206
+ content=f"This is sample content for item {i}. " * 10,
207
+ metadata={"source": "example", "index": i},
208
+ ))
209
+ return items
210
+
211
+
212
+ # -----------------------------------------------------------------------------
213
+ # Stage: Prepare
214
+ # -----------------------------------------------------------------------------
215
+
216
+ def stage_prepare(batch_id: str) -> int:
217
+ """Stage 2: Generate prompts from raw data.
218
+
219
+ Use when: transforming raw acquired data into LLM-ready prompts
220
+ using the configured PROMPT_TEMPLATE.
221
+
222
+ Output: {batch_dir}/{item_id}/prompt.md
223
+ Returns: Number of items prepared.
224
+ """
225
+ batch_dir = get_batch_dir(batch_id)
226
+ prepared_count = 0
227
+
228
+ for item_dir in sorted(batch_dir.iterdir()):
229
+ if not item_dir.is_dir():
230
+ continue
231
+
232
+ raw_file = item_dir / "raw.json"
233
+ prompt_file = item_dir / "prompt.md"
234
+
235
+ if not raw_file.exists():
236
+ continue
237
+
238
+ if prompt_file.exists():
239
+ continue
240
+
241
+ with open(raw_file) as f:
242
+ item_data: dict[str, Any] = json.load(f)
243
+
244
+ prompt = generate_prompt(item_data)
245
+
246
+ with open(prompt_file, "w") as f:
247
+ f.write(prompt)
248
+
249
+ prepared_count += 1
250
+ print(f"Prepared: {item_dir.name}")
251
+
252
+ print(f"\nPrepare complete. {prepared_count} items prepared.")
253
+ return prepared_count
254
+
255
+
256
+ def generate_prompt(item_data: dict[str, Any]) -> str:
257
+ """Generate prompt from item data using template.
258
+
259
+ Use when: converting a raw item dict into a formatted prompt string.
260
+ """
261
+ return PROMPT_TEMPLATE.format(
262
+ title=item_data.get("title", "Untitled"),
263
+ content=item_data.get("content", ""),
264
+ )
265
+
266
+
267
+ # -----------------------------------------------------------------------------
268
+ # Stage: Process
269
+ # -----------------------------------------------------------------------------
270
+
271
+ def stage_process(
272
+ batch_id: str,
273
+ model: str = "claude-sonnet-4-20250514",
274
+ max_workers: int = 5,
275
+ ) -> list[tuple[str, int, str | None]]:
276
+ """Stage 3: Execute LLM calls (the expensive, non-deterministic stage).
277
+
278
+ Use when: sending prepared prompts to the LLM API and caching
279
+ responses. This is the only non-deterministic stage.
280
+
281
+ Output: {batch_dir}/{item_id}/response.md
282
+ Returns: List of (item_id, char_count, error_or_none) tuples.
283
+ """
284
+ batch_dir = get_batch_dir(batch_id)
285
+
286
+ # Collect items needing processing
287
+ to_process: list[tuple[Path, str]] = []
288
+ for item_dir in sorted(batch_dir.iterdir()):
289
+ if not item_dir.is_dir():
290
+ continue
291
+
292
+ prompt_file = item_dir / "prompt.md"
293
+ response_file = item_dir / "response.md"
294
+
295
+ if prompt_file.exists() and not response_file.exists():
296
+ to_process.append((item_dir, prompt_file.read_text()))
297
+
298
+ if not to_process:
299
+ print("No items to process.")
300
+ return []
301
+
302
+ print(f"Processing {len(to_process)} items with {max_workers} workers...")
303
+
304
+ results: list[tuple[str, int, str | None]] = []
305
+
306
+ def process_one(args: tuple[Path, str]) -> tuple[str, int, str | None]:
307
+ item_dir, prompt = args
308
+ response_file = item_dir / "response.md"
309
+
310
+ try:
311
+ # CUSTOMIZE: Replace with your LLM API call
312
+ response = call_llm(prompt, model)
313
+
314
+ with open(response_file, "w") as f:
315
+ f.write(response)
316
+
317
+ return (item_dir.name, len(response), None)
318
+ except Exception as e:
319
+ return (item_dir.name, 0, str(e))
320
+
321
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
322
+ futures = {executor.submit(process_one, item): item for item in to_process}
323
+
324
+ for future in as_completed(futures):
325
+ item_id, chars, error = future.result()
326
+ results.append((item_id, chars, error))
327
+ if error:
328
+ print(f" {item_id}: Error - {error}")
329
+ else:
330
+ print(f" {item_id}: Done ({chars} chars)")
331
+
332
+ print(f"\nProcess complete. {len(results)} items processed.")
333
+ return results
334
+
335
+
336
+ def call_llm(prompt: str, model: str) -> str:
337
+ """CUSTOMIZE: Implement your LLM API call here.
338
+
339
+ Use when: sending a single prompt to the LLM and returning the response.
340
+ Replace with actual OpenAI, Anthropic, etc. API calls.
341
+ """
342
+ # Example mock response - replace with actual API call
343
+ #
344
+ # import anthropic
345
+ # client = anthropic.Anthropic()
346
+ # message = client.messages.create(
347
+ # model=model,
348
+ # max_tokens=1024,
349
+ # messages=[{"role": "user", "content": prompt}],
350
+ # )
351
+ # return message.content[0].text
352
+
353
+ # Simulate API delay
354
+ time.sleep(0.1)
355
+
356
+ # Return mock structured response
357
+ return """## Summary
358
+ This is a sample summary of the analyzed content.
359
+
360
+ ## Key Points
361
+ - First key observation from the content
362
+ - Second important finding
363
+ - Third notable aspect
364
+
365
+ ## Score
366
+ Rating: 7
367
+ Confidence: medium
368
+
369
+ ## Reasoning
370
+ The content demonstrates several characteristics that merit this rating.
371
+ The analysis considered multiple factors including relevance and clarity.
372
+ """
373
+
374
+
375
+ # -----------------------------------------------------------------------------
376
+ # Stage: Parse
377
+ # -----------------------------------------------------------------------------
378
+
379
+ def stage_parse(batch_id: str) -> list[dict[str, Any]]:
380
+ """Stage 4: Extract structured data from LLM responses.
381
+
382
+ Use when: converting free-text LLM responses into structured
383
+ ParsedResult objects for aggregation and rendering.
384
+
385
+ Output: {batch_dir}/{item_id}/parsed.json
386
+ Returns: List of parsed result dicts with item IDs.
387
+ """
388
+ batch_dir = get_batch_dir(batch_id)
389
+ all_results: list[dict[str, Any]] = []
390
+
391
+ for item_dir in sorted(batch_dir.iterdir()):
392
+ if not item_dir.is_dir():
393
+ continue
394
+
395
+ response_file = item_dir / "response.md"
396
+ parsed_file = item_dir / "parsed.json"
397
+
398
+ if not response_file.exists():
399
+ continue
400
+
401
+ response = response_file.read_text()
402
+ result = parse_response(response)
403
+
404
+ with open(parsed_file, "w") as f:
405
+ json.dump(asdict(result), f, indent=2)
406
+
407
+ all_results.append({
408
+ "id": item_dir.name,
409
+ **asdict(result),
410
+ })
411
+
412
+ error_count = len(result.parse_errors)
413
+ print(f"Parsed: {item_dir.name} (score={result.score}, errors={error_count})")
414
+
415
+ # Save aggregated results
416
+ agg_file = batch_dir / "all_results.json"
417
+ with open(agg_file, "w") as f:
418
+ json.dump(all_results, f, indent=2)
419
+
420
+ print(f"\nParse complete. Results saved to {agg_file}")
421
+ return all_results
422
+
423
+
424
+ def parse_response(text: str) -> ParsedResult:
425
+ """Parse structured LLM response with graceful error handling.
426
+
427
+ Use when: extracting sections, scores, and lists from a formatted
428
+ LLM response. Logs parse errors rather than raising exceptions.
429
+ """
430
+ result = ParsedResult()
431
+
432
+ # Extract summary
433
+ try:
434
+ result.summary = extract_section(text, "Summary") or ""
435
+ except Exception as e:
436
+ result.parse_errors.append(f"Summary: {e}")
437
+
438
+ # Extract key points
439
+ try:
440
+ result.key_points = extract_list_items(text, "Key Points")
441
+ except Exception as e:
442
+ result.parse_errors.append(f"Key Points: {e}")
443
+
444
+ # Extract score
445
+ try:
446
+ result.score = extract_score(text, "Rating", 1, 10)
447
+ except Exception as e:
448
+ result.parse_errors.append(f"Score: {e}")
449
+
450
+ # Extract confidence
451
+ try:
452
+ result.confidence = extract_field(text, "Confidence") or ""
453
+ except Exception as e:
454
+ result.parse_errors.append(f"Confidence: {e}")
455
+
456
+ # Extract reasoning
457
+ try:
458
+ result.reasoning = extract_section(text, "Reasoning") or ""
459
+ except Exception as e:
460
+ result.parse_errors.append(f"Reasoning: {e}")
461
+
462
+ return result
463
+
464
+
465
+ def extract_section(text: str, section_name: str) -> str | None:
466
+ """Extract content between section headers.
467
+
468
+ Use when: pulling a named markdown section from LLM output.
469
+ """
470
+ pattern = rf'(?:^|\n)(?:#+ *)?{re.escape(section_name)}[:\s]*\n(.*?)(?=\n#|\Z)'
471
+ match = re.search(pattern, text, re.IGNORECASE | re.DOTALL)
472
+ return match.group(1).strip() if match else None
473
+
474
+
475
+ def extract_field(text: str, field_name: str) -> str | None:
476
+ """Extract value after field label.
477
+
478
+ Use when: pulling a single key-value field (e.g., "Confidence: high").
479
+ """
480
+ pattern = rf'(?:\*\*)?{re.escape(field_name)}(?:\*\*)?[\s:\-]+([^\n]+)'
481
+ match = re.search(pattern, text, re.IGNORECASE)
482
+ return match.group(1).strip() if match else None
483
+
484
+
485
+ def extract_list_items(text: str, section_name: str) -> list[str]:
486
+ """Extract bullet points from a section.
487
+
488
+ Use when: parsing a markdown list under a named section header.
489
+ """
490
+ section = extract_section(text, section_name)
491
+ if not section:
492
+ return []
493
+
494
+ items = re.findall(r'^[\-\*]\s*(.+)$', section, re.MULTILINE)
495
+ return [item.strip() for item in items]
496
+
497
+
498
+ def extract_score(
499
+ text: str, field_name: str, min_val: int, max_val: int
500
+ ) -> int | None:
501
+ """Extract and validate numeric score.
502
+
503
+ Use when: pulling a bounded integer score from LLM output.
504
+ """
505
+ raw = extract_field(text, field_name)
506
+ if not raw:
507
+ return None
508
+
509
+ match = re.search(r'\d+', raw)
510
+ if not match:
511
+ return None
512
+
513
+ score = int(match.group())
514
+ return max(min_val, min(max_val, score))
515
+
516
+
517
+ # -----------------------------------------------------------------------------
518
+ # Stage: Render
519
+ # -----------------------------------------------------------------------------
520
+
521
+ def stage_render(batch_id: str) -> Path | None:
522
+ """Stage 5: Generate final outputs from parsed results.
523
+
524
+ Use when: producing human-readable output (HTML, reports)
525
+ from aggregated parsed results.
526
+
527
+ Output: {output_dir}/index.html
528
+ Returns: Path to the rendered output file, or None if no results.
529
+ """
530
+ batch_dir = get_batch_dir(batch_id)
531
+ output_dir = get_output_dir(batch_id)
532
+ output_dir.mkdir(parents=True, exist_ok=True)
533
+
534
+ # Load aggregated results
535
+ results_file = batch_dir / "all_results.json"
536
+ if not results_file.exists():
537
+ print("No results to render. Run parse stage first.")
538
+ return None
539
+
540
+ with open(results_file) as f:
541
+ results: list[dict[str, Any]] = json.load(f)
542
+
543
+ # CUSTOMIZE: Replace with your rendering logic
544
+ html = render_html(results, batch_id)
545
+
546
+ output_file = output_dir / "index.html"
547
+ with open(output_file, "w") as f:
548
+ f.write(html)
549
+
550
+ print(f"Rendered: {output_file}")
551
+ return output_file
552
+
553
+
554
+ def render_html(results: list[dict[str, Any]], batch_id: str) -> str:
555
+ """Generate HTML output from results.
556
+
557
+ Use when: creating a summary HTML table from parsed pipeline results.
558
+ """
559
+ import html as html_lib
560
+
561
+ rows = ""
562
+ for r in results:
563
+ rows += f"""
564
+ <tr>
565
+ <td>{html_lib.escape(r.get('id', ''))}</td>
566
+ <td>{html_lib.escape(r.get('summary', '')[:100])}...</td>
567
+ <td>{r.get('score', 'N/A')}</td>
568
+ <td>{html_lib.escape(r.get('confidence', ''))}</td>
569
+ </tr>"""
570
+
571
+ return f"""<!DOCTYPE html>
572
+ <html>
573
+ <head>
574
+ <meta charset="utf-8">
575
+ <title>Results - {batch_id}</title>
576
+ <style>
577
+ body {{ font-family: system-ui, sans-serif; max-width: 1000px; margin: 0 auto; padding: 20px; }}
578
+ table {{ width: 100%; border-collapse: collapse; }}
579
+ th, td {{ text-align: left; padding: 10px; border-bottom: 1px solid #ddd; }}
580
+ th {{ background: #f5f5f5; }}
581
+ </style>
582
+ </head>
583
+ <body>
584
+ <h1>Results: {batch_id}</h1>
585
+ <p>{len(results)} items processed</p>
586
+ <table>
587
+ <tr>
588
+ <th>ID</th>
589
+ <th>Summary</th>
590
+ <th>Score</th>
591
+ <th>Confidence</th>
592
+ </tr>
593
+ {rows}
594
+ </table>
595
+ </body>
596
+ </html>"""
597
+
598
+
599
+ # -----------------------------------------------------------------------------
600
+ # Clean Stage
601
+ # -----------------------------------------------------------------------------
602
+
603
+ def stage_clean(batch_id: str, from_stage: str | None = None) -> int:
604
+ """Remove stage outputs to enable re-processing.
605
+
606
+ Use when: a stage produced bad results and needs to be re-run,
607
+ or when clearing all intermediate files for a fresh pipeline run.
608
+
609
+ Returns: Number of files deleted.
610
+ """
611
+ batch_dir = get_batch_dir(batch_id)
612
+
613
+ if not batch_dir.exists():
614
+ print(f"No data directory for {batch_id}")
615
+ return 0
616
+
617
+ stage_outputs: dict[str, list[str]] = {
618
+ "acquire": ["raw.json"],
619
+ "prepare": ["prompt.md"],
620
+ "process": ["response.md"],
621
+ "parse": ["parsed.json"],
622
+ }
623
+
624
+ stage_order = ["acquire", "prepare", "process", "parse", "render"]
625
+
626
+ if from_stage:
627
+ start_idx = stage_order.index(from_stage)
628
+ stages_to_clean = stage_order[start_idx:]
629
+ else:
630
+ stages_to_clean = stage_order
631
+
632
+ files_to_delete: set[str] = set()
633
+ for s in stages_to_clean:
634
+ files_to_delete.update(stage_outputs.get(s, []))
635
+
636
+ deleted_count = 0
637
+ for item_dir in batch_dir.iterdir():
638
+ if not item_dir.is_dir():
639
+ continue
640
+
641
+ for filename in files_to_delete:
642
+ filepath = item_dir / filename
643
+ if filepath.exists():
644
+ filepath.unlink()
645
+ deleted_count += 1
646
+
647
+ # Clean aggregated results
648
+ if "parse" in stages_to_clean:
649
+ agg_file = batch_dir / "all_results.json"
650
+ if agg_file.exists():
651
+ agg_file.unlink()
652
+ deleted_count += 1
653
+
654
+ print(f"Cleaned {deleted_count} files from stage '{from_stage or 'all'}' onwards")
655
+ return deleted_count
656
+
657
+
658
+ # -----------------------------------------------------------------------------
659
+ # Cost Estimation
660
+ # -----------------------------------------------------------------------------
661
+
662
+ def stage_estimate(batch_id: str) -> dict[str, Any] | None:
663
+ """Estimate processing costs before running the process stage.
664
+
665
+ Use when: projecting token costs and budget requirements before
666
+ committing to expensive LLM API calls.
667
+
668
+ Returns: Dict with item_count, token estimates, and cost projection,
669
+ or None if no prompts are available.
670
+ """
671
+ batch_dir = get_batch_dir(batch_id)
672
+
673
+ if not batch_dir.exists():
674
+ print(f"No data directory for {batch_id}. Run acquire first.")
675
+ return None
676
+
677
+ # Count items and estimate tokens
678
+ item_count = 0
679
+ total_prompt_chars = 0
680
+
681
+ for item_dir in batch_dir.iterdir():
682
+ if not item_dir.is_dir():
683
+ continue
684
+
685
+ prompt_file = item_dir / "prompt.md"
686
+ if prompt_file.exists():
687
+ total_prompt_chars += len(prompt_file.read_text())
688
+ item_count += 1
689
+
690
+ if item_count == 0:
691
+ print("No prompts found. Run prepare first.")
692
+ return None
693
+
694
+ # Rough token estimation (1 token ~ 4 chars)
695
+ est_input_tokens = total_prompt_chars / 4
696
+ est_output_tokens = item_count * 500 # Assume 500 tokens per response
697
+
698
+ # Example pricing (adjust for your model)
699
+ input_price = 3.0 / 1_000_000 # $3 per MTok
700
+ output_price = 15.0 / 1_000_000 # $15 per MTok
701
+
702
+ est_cost = (est_input_tokens * input_price) + (est_output_tokens * output_price)
703
+
704
+ estimate: dict[str, Any] = {
705
+ "batch_id": batch_id,
706
+ "item_count": item_count,
707
+ "est_input_tokens": int(est_input_tokens),
708
+ "est_output_tokens": int(est_output_tokens),
709
+ "est_cost_usd": round(est_cost, 2),
710
+ }
711
+
712
+ print(f"Cost Estimate for {batch_id}")
713
+ print(f" Items: {item_count}")
714
+ print(f" Estimated input tokens: {int(est_input_tokens):,}")
715
+ print(f" Estimated output tokens: {int(est_output_tokens):,}")
716
+ print(f" Estimated cost: ${est_cost:.2f}")
717
+ print(f"\nNote: Actual costs may vary. Add 20-30% buffer for retries.")
718
+
719
+ return estimate
720
+
721
+
722
+ # -----------------------------------------------------------------------------
723
+ # CLI
724
+ # -----------------------------------------------------------------------------
725
+
726
+ def main() -> None:
727
+ """Entry point for CLI usage. Parses arguments and dispatches to stages."""
728
+ parser = argparse.ArgumentParser(
729
+ description="LLM Batch Processing Pipeline",
730
+ formatter_class=argparse.RawDescriptionHelpFormatter,
731
+ epilog=__doc__,
732
+ )
733
+
734
+ parser.add_argument(
735
+ "stage",
736
+ choices=["acquire", "prepare", "process", "parse", "render", "all", "clean", "estimate"],
737
+ help="Pipeline stage to run",
738
+ )
739
+ parser.add_argument(
740
+ "--batch-id",
741
+ default=None,
742
+ help="Batch identifier (default: today's date)",
743
+ )
744
+ parser.add_argument(
745
+ "--limit",
746
+ type=int,
747
+ default=None,
748
+ help="Limit number of items (for testing)",
749
+ )
750
+ parser.add_argument(
751
+ "--workers",
752
+ type=int,
753
+ default=5,
754
+ help="Number of parallel workers for processing",
755
+ )
756
+ parser.add_argument(
757
+ "--model",
758
+ default="claude-sonnet-4-20250514",
759
+ help="Model to use for processing",
760
+ )
761
+ parser.add_argument(
762
+ "--clean-stage",
763
+ choices=["acquire", "prepare", "process", "parse"],
764
+ help="For clean: only clean this stage and downstream",
765
+ )
766
+
767
+ args = parser.parse_args()
768
+
769
+ batch_id = args.batch_id or date.today().isoformat()
770
+ print(f"Batch ID: {batch_id}\n")
771
+
772
+ if args.stage == "clean":
773
+ stage_clean(batch_id, args.clean_stage)
774
+ elif args.stage == "estimate":
775
+ stage_estimate(batch_id)
776
+ elif args.stage == "all":
777
+ stage_acquire(batch_id, args.limit)
778
+ stage_prepare(batch_id)
779
+ stage_process(batch_id, args.model, args.workers)
780
+ stage_parse(batch_id)
781
+ stage_render(batch_id)
782
+ else:
783
+ if args.stage == "acquire":
784
+ stage_acquire(batch_id, args.limit)
785
+ elif args.stage == "prepare":
786
+ stage_prepare(batch_id)
787
+ elif args.stage == "process":
788
+ stage_process(batch_id, args.model, args.workers)
789
+ elif args.stage == "parse":
790
+ stage_parse(batch_id)
791
+ elif args.stage == "render":
792
+ stage_render(batch_id)
793
+
794
+
795
+ if __name__ == "__main__":
796
+ main()