freeharness 0.4.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 (375) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +108 -0
  3. package/README.md +134 -0
  4. package/canonical/HARVEST.yaml +858 -0
  5. package/canonical/PROVENANCE.yaml +740 -0
  6. package/canonical/agents/README.md +95 -0
  7. package/canonical/agents/agentic-architect.md +18 -0
  8. package/canonical/agents/database-reviewer.md +41 -0
  9. package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
  10. package/canonical/agents/pr-reviewer.md +96 -0
  11. package/canonical/agents/python-reviewer.md +55 -0
  12. package/canonical/agents/report-formatter.md +19 -0
  13. package/canonical/agents/security-reviewer.md +53 -0
  14. package/canonical/agents/test-writer.md +34 -0
  15. package/canonical/commands/fh-context.md +37 -0
  16. package/canonical/evals/promptfoo.redteam.yaml +108 -0
  17. package/canonical/hooks/cost-prices.json +14 -0
  18. package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
  19. package/canonical/hooks/freeharness-config-guard.mjs +162 -0
  20. package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
  21. package/canonical/hooks/freeharness-converge.mjs +227 -0
  22. package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
  23. package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
  24. package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
  25. package/canonical/hooks/freeharness-precompact.mjs +323 -0
  26. package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
  27. package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
  28. package/canonical/hooks/freeharness-session-start +583 -0
  29. package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
  30. package/canonical/hooks/hooks.claude-code.json +17 -0
  31. package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
  32. package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
  33. package/canonical/hooks/hooks.converge.claude-code.json +15 -0
  34. package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
  35. package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
  36. package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
  37. package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
  38. package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
  39. package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
  40. package/canonical/mcp/servers.json +20 -0
  41. package/canonical/openspec/config.base.yaml +89 -0
  42. package/canonical/openspec/schema.spec-driven.yaml +277 -0
  43. package/canonical/openspec/templates/data-contract.md +36 -0
  44. package/canonical/openspec/templates/design.md +84 -0
  45. package/canonical/openspec/templates/eval-plan.md +33 -0
  46. package/canonical/openspec/templates/follow-ups.md +2 -0
  47. package/canonical/openspec/templates/proposal.md +45 -0
  48. package/canonical/openspec/templates/spec.md +42 -0
  49. package/canonical/openspec/templates/tasks.md +38 -0
  50. package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
  51. package/canonical/profiles/local-llamacpp.json +27 -0
  52. package/canonical/profiles/local-ollama.json +20 -0
  53. package/canonical/profiles/mcp.json +91 -0
  54. package/canonical/rules/CLAUDE.md +78 -0
  55. package/canonical/rules/project-CLAUDE.template.md +62 -0
  56. package/canonical/rules/routing.md +20 -0
  57. package/canonical/rules/safety.md +41 -0
  58. package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
  59. package/canonical/skills/agent-evaluation/SKILL.md +102 -0
  60. package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
  61. package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
  62. package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
  63. package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
  64. package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
  65. package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
  66. package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
  67. package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
  68. package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
  69. package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
  70. package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
  71. package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
  72. package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
  73. package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
  74. package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
  75. package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
  76. package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
  77. package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
  78. package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
  79. package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
  80. package/canonical/skills/agentic-architecture/SKILL.md +41 -0
  81. package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
  82. package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
  83. package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
  84. package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
  85. package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
  86. package/canonical/skills/code-review/SKILL.md +52 -0
  87. package/canonical/skills/code-review/evals/cases.yaml +197 -0
  88. package/canonical/skills/git-workflow/SKILL.md +41 -0
  89. package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
  90. package/canonical/skills/local-code/SKILL.md +24 -0
  91. package/canonical/skills/local-code/evals/cases.yaml +85 -0
  92. package/canonical/skills/local-code/scripts/query_llama.py +68 -0
  93. package/canonical/skills/report-formatting/SKILL.md +62 -0
  94. package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
  95. package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
  96. package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
  97. package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
  98. package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
  99. package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
  100. package/canonical/skills/report-formatting/reference/authoring.md +66 -0
  101. package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
  102. package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
  103. package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
  104. package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
  105. package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
  106. package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
  107. package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
  108. package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
  109. package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
  110. package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
  111. package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
  112. package/canonical/skills/report-formatting/scripts/package.json +17 -0
  113. package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
  114. package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
  115. package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
  116. package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
  117. package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
  118. package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
  119. package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
  120. package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
  121. package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
  122. package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
  123. package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
  124. package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
  125. package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
  126. package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
  127. package/canonical/skills/systematic-debugging/SKILL.md +44 -0
  128. package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
  129. package/canonical/skills/test-driven-development/SKILL.md +42 -0
  130. package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
  131. package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
  132. package/canonical/skills/verification-before-completion/SKILL.md +53 -0
  133. package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
  134. package/dist/adapters/content/language-lint.d.ts +46 -0
  135. package/dist/adapters/content/language-lint.js +191 -0
  136. package/dist/adapters/harness/claude-code.d.ts +57 -0
  137. package/dist/adapters/harness/claude-code.js +385 -0
  138. package/dist/adapters/harness/index.d.ts +3 -0
  139. package/dist/adapters/harness/index.js +17 -0
  140. package/dist/adapters/harness/opencode.d.ts +7 -0
  141. package/dist/adapters/harness/opencode.js +166 -0
  142. package/dist/adapters/harness/plugin.d.ts +22 -0
  143. package/dist/adapters/harness/plugin.js +257 -0
  144. package/dist/adapters/memory/doctor.d.ts +480 -0
  145. package/dist/adapters/memory/doctor.js +1217 -0
  146. package/dist/adapters/memory/vendored.d.ts +150 -0
  147. package/dist/adapters/memory/vendored.js +487 -0
  148. package/dist/adapters/package/node.d.ts +9 -0
  149. package/dist/adapters/package/node.js +20 -0
  150. package/dist/adapters/prompt/readline.d.ts +19 -0
  151. package/dist/adapters/prompt/readline.js +53 -0
  152. package/dist/adapters/sync/diff.d.ts +43 -0
  153. package/dist/adapters/sync/diff.js +380 -0
  154. package/dist/cli/cleanup.d.ts +86 -0
  155. package/dist/cli/cleanup.js +382 -0
  156. package/dist/cli/cost.d.ts +304 -0
  157. package/dist/cli/cost.js +501 -0
  158. package/dist/cli/doctor.d.ts +205 -0
  159. package/dist/cli/doctor.js +654 -0
  160. package/dist/cli/executor.d.ts +5 -0
  161. package/dist/cli/executor.js +48 -0
  162. package/dist/cli/plugin-validate.d.ts +37 -0
  163. package/dist/cli/plugin-validate.js +256 -0
  164. package/dist/cli/prefix.d.ts +68 -0
  165. package/dist/cli/prefix.js +218 -0
  166. package/dist/cli/profile.d.ts +170 -0
  167. package/dist/cli/profile.js +285 -0
  168. package/dist/cli/runner.d.ts +10 -0
  169. package/dist/cli/runner.js +27 -0
  170. package/dist/cli/uninstall.d.ts +65 -0
  171. package/dist/cli/uninstall.js +147 -0
  172. package/dist/index.d.ts +8 -0
  173. package/dist/index.js +989 -0
  174. package/dist/infra/dogfood.d.ts +31 -0
  175. package/dist/infra/dogfood.js +51 -0
  176. package/dist/infra/fsutil.d.ts +40 -0
  177. package/dist/infra/fsutil.js +143 -0
  178. package/dist/infra/manifest.d.ts +76 -0
  179. package/dist/infra/manifest.js +92 -0
  180. package/dist/infra/paths.d.ts +19 -0
  181. package/dist/infra/paths.js +74 -0
  182. package/dist/infra/routing.d.ts +4 -0
  183. package/dist/infra/routing.js +7 -0
  184. package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
  185. package/node_modules/@freeharness/core/dist/context.js +1 -0
  186. package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
  187. package/node_modules/@freeharness/core/dist/index.js +6 -0
  188. package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
  189. package/node_modules/@freeharness/core/dist/planner.js +18 -0
  190. package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
  191. package/node_modules/@freeharness/core/dist/ports.js +1 -0
  192. package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
  193. package/node_modules/@freeharness/core/dist/registry.js +124 -0
  194. package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
  195. package/node_modules/@freeharness/core/dist/tiers.js +99 -0
  196. package/node_modules/@freeharness/core/package.json +34 -0
  197. package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
  198. package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
  199. package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
  200. package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
  201. package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
  202. package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
  203. package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
  204. package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
  205. package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
  206. package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
  207. package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
  208. package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
  209. package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
  210. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
  211. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
  212. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
  213. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
  214. package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
  215. package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
  216. package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
  217. package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
  218. package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
  219. package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
  220. package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
  221. package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
  222. package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
  223. package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
  224. package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
  225. package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
  226. package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
  227. package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
  228. package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
  229. package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
  230. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
  231. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
  232. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
  233. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
  234. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
  235. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
  236. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
  237. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
  238. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
  239. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
  240. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
  241. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
  242. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
  243. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
  244. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
  245. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
  246. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
  247. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
  248. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
  249. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
  250. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
  251. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
  252. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
  253. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
  254. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
  255. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
  256. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
  257. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
  258. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
  259. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
  260. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
  261. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
  262. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
  263. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
  264. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
  265. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
  266. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
  267. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
  268. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
  269. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
  270. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
  271. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
  272. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
  273. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
  274. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
  275. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
  276. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
  277. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
  278. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
  279. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
  280. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
  281. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
  282. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
  283. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
  284. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
  285. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
  286. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
  287. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
  288. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
  289. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
  290. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
  291. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
  292. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
  293. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
  294. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
  295. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
  296. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
  297. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
  298. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
  299. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
  300. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
  301. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
  302. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
  303. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
  304. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
  305. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
  306. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
  307. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
  308. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
  309. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
  310. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
  311. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
  312. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
  313. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
  314. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
  315. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
  316. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
  317. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
  318. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
  319. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
  320. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
  321. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
  322. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
  323. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
  324. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
  325. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
  326. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
  327. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
  328. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
  329. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
  330. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
  331. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
  332. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
  333. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
  334. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
  335. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
  336. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
  337. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
  338. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
  339. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
  340. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
  341. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
  342. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
  343. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
  344. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
  345. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
  346. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
  347. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
  348. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
  349. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
  350. package/node_modules/@freeharness/sdd/package.json +57 -0
  351. package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
  352. package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
  353. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
  354. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
  355. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
  356. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
  357. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
  358. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
  359. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
  360. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
  361. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
  362. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
  363. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
  364. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
  365. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
  366. package/package.json +70 -0
  367. package/provenance/canonical.PROVENANCE.yaml +740 -0
  368. package/provenance/claude-mem.LICENSE.upstream +202 -0
  369. package/provenance/memory.PROVENANCE.yaml +399 -0
  370. package/provenance/sdd.PROVENANCE.yaml +175 -0
  371. package/vendor-licenses/caveman.LICENSE +27 -0
  372. package/vendor-licenses/deepseek-harness.LICENSE +21 -0
  373. package/vendor-licenses/ecc.LICENSE +21 -0
  374. package/vendor-licenses/pi.LICENSE +21 -0
  375. package/vendor-licenses/superpowers.LICENSE +21 -0
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env python3
2
+ """Self-contained pptx office ops for report-formatting (no Anthropic container
3
+ dependency). A .pptx is an OOXML zip; this provides unpack/pack/clean/render.
4
+
5
+ Usage:
6
+ python pptx_office.py unpack <in.pptx> <dir>
7
+ python pptx_office.py pack <dir> <out.pptx>
8
+ python pptx_office.py clean <dir>
9
+ python pptx_office.py render <in.pptx> [outdir] # needs soffice + pdftoppm
10
+ """
11
+ import os
12
+ import re
13
+ import sys
14
+ import shutil
15
+ import zipfile
16
+ import subprocess
17
+
18
+
19
+ def unpack(pptx, out_dir):
20
+ """Extract a .pptx (OOXML zip) into out_dir, replacing it if it exists.
21
+
22
+ Args:
23
+ pptx: Path to the source .pptx file.
24
+ out_dir: Directory to extract into; removed first if present.
25
+ """
26
+ if os.path.isdir(out_dir):
27
+ shutil.rmtree(out_dir)
28
+ os.makedirs(out_dir, exist_ok=True)
29
+ with zipfile.ZipFile(pptx) as z:
30
+ z.extractall(out_dir)
31
+ print(f"unpacked {pptx} -> {out_dir}")
32
+
33
+
34
+ def pack(in_dir, out_pptx):
35
+ """Zip the OOXML tree in in_dir into out_pptx ([Content_Types].xml first).
36
+
37
+ Overwrites out_pptx if it exists.
38
+
39
+ Args:
40
+ in_dir: Directory holding the unpacked OOXML parts.
41
+ out_pptx: Destination .pptx path.
42
+ """
43
+ files = []
44
+ for root, _dirs, names in os.walk(in_dir):
45
+ for n in names:
46
+ full = os.path.join(root, n)
47
+ arc = os.path.relpath(full, in_dir).replace(os.sep, "/")
48
+ files.append((full, arc))
49
+ # [Content_Types].xml conventionally first.
50
+ files.sort(key=lambda fa: (fa[1] != "[Content_Types].xml", fa[1]))
51
+ if os.path.exists(out_pptx):
52
+ os.remove(out_pptx)
53
+ with zipfile.ZipFile(out_pptx, "w", zipfile.ZIP_DEFLATED) as z:
54
+ for full, arc in files:
55
+ z.write(full, arc)
56
+ print(f"packed {in_dir} -> {out_pptx} ({len(files)} parts)")
57
+
58
+
59
+ def clean(in_dir):
60
+ """Remove slide parts not referenced by presentation.xml.rels.
61
+
62
+ Also removes their rels and matching notesSlides. Minimal orphan sweep;
63
+ deletes files from in_dir in place.
64
+
65
+ Args:
66
+ in_dir: Directory holding the unpacked OOXML parts.
67
+ """
68
+ rels = os.path.join(in_dir, "ppt", "_rels", "presentation.xml.rels")
69
+ if not os.path.isfile(rels):
70
+ print("no presentation.xml.rels; nothing to clean")
71
+ return
72
+ txt = open(rels, encoding="utf-8").read()
73
+ referenced = set(re.findall(r'Target="(slides/slide\d+\.xml)"', txt))
74
+ slides_dir = os.path.join(in_dir, "ppt", "slides")
75
+ removed = 0
76
+ if os.path.isdir(slides_dir):
77
+ for n in os.listdir(slides_dir):
78
+ m = re.match(r"slide\d+\.xml$", n)
79
+ if not m:
80
+ continue
81
+ if f"slides/{n}" not in referenced:
82
+ os.remove(os.path.join(slides_dir, n))
83
+ rel = os.path.join(slides_dir, "_rels", n + ".rels")
84
+ if os.path.isfile(rel):
85
+ os.remove(rel)
86
+ removed += 1
87
+ print(f"clean: removed {removed} orphan slide part(s)")
88
+
89
+
90
+ def render(pptx, outdir="."):
91
+ """Render a .pptx to per-page JPEGs (soffice -> pdf -> pdftoppm).
92
+
93
+ Best-effort QA; prints the generated JPEG paths.
94
+
95
+ Args:
96
+ pptx: Path to the source .pptx.
97
+ outdir: Output directory for the pdf and jpegs.
98
+
99
+ Raises:
100
+ subprocess.CalledProcessError: If soffice or pdftoppm fails.
101
+ """
102
+ os.makedirs(outdir, exist_ok=True)
103
+ subprocess.run(
104
+ ["soffice", "--headless", "--convert-to", "pdf", "--outdir", outdir, pptx],
105
+ check=True,
106
+ )
107
+ pdf = os.path.join(outdir, os.path.splitext(os.path.basename(pptx))[0] + ".pdf")
108
+ subprocess.run(
109
+ ["pdftoppm", "-jpeg", "-r", "130", pdf, os.path.join(outdir, "slide")],
110
+ check=True,
111
+ )
112
+ jpegs = sorted(f for f in os.listdir(outdir) if f.startswith("slide") and f.endswith(".jpg"))
113
+ print("\n".join(os.path.join(outdir, j) for j in jpegs))
114
+
115
+
116
+ def main(argv):
117
+ """Dispatch the CLI subcommand and return a process exit code.
118
+
119
+ Args:
120
+ argv: Argument vector (argv[1] is the subcommand).
121
+
122
+ Returns:
123
+ 0 on success, 1 on usage error.
124
+ """
125
+ if len(argv) < 2:
126
+ print(__doc__)
127
+ return 1
128
+ cmd = argv[1]
129
+ if cmd == "unpack" and len(argv) == 4:
130
+ unpack(argv[2], argv[3])
131
+ elif cmd == "pack" and len(argv) == 4:
132
+ pack(argv[2], argv[3])
133
+ elif cmd == "clean" and len(argv) == 3:
134
+ clean(argv[2])
135
+ elif cmd == "render" and len(argv) in (3, 4):
136
+ render(argv[2], argv[3] if len(argv) == 4 else ".")
137
+ else:
138
+ print(__doc__)
139
+ return 1
140
+ return 0
141
+
142
+
143
+ if __name__ == "__main__":
144
+ sys.exit(main(sys.argv))
@@ -0,0 +1,7 @@
1
+ # Python deps for the .pptx track of report-formatting.
2
+ # Install: pip install -r requirements.txt --break-system-packages
3
+ # System tools (not pip): soffice (LibreOffice headless) + pdftoppm (poppler) for QA render.
4
+ python-pptx>=1.0.0
5
+ lxml>=5.0.0
6
+ Pillow>=10.0.0
7
+ defusedxml>=0.7.1
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env python3
2
+ """Reusable status-report slide builders (Claro theme), for the report-formatter
3
+ agent. Generic — no project-specific data. Import alongside theme_claro_pptx:
4
+
5
+ import theme_claro_pptx as T
6
+ import status_report_blocks as B
7
+ from pptx import Presentation
8
+
9
+ prs = Presentation("deck.pptx") # or Presentation() for a new deck
10
+ B.build_heatmap(prs.slides[i], title=..., rows=...) # clears + rebuilds slide i
11
+ B.build_gantt(prs.slides[j], title=..., activities=...)
12
+
13
+ Both functions CLEAR the target slide and rebuild it, so they work for new blank
14
+ slides and for in-place rebuilds. Tested against the STT status report (Jun/2026).
15
+
16
+ Two blocks:
17
+ - build_heatmap: período × estágio status grid (Concluído/Em Execução/Pendente/
18
+ Parcial/Backlog), optional trailing data column (e.g. "Backlog (TIDs)").
19
+ - build_gantt: Claro "Cronograma / Próximos Passos" — red header bar, dark week
20
+ columns, per-row accent + category chip + priority bar, category legend.
21
+ """
22
+ import os
23
+ import sys
24
+
25
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
26
+ import theme_claro_pptx as T # noqa: E402
27
+ from pptx.util import Inches # noqa: E402
28
+ from pptx.dml.color import RGBColor # noqa: E402
29
+ from pptx.enum.text import PP_ALIGN, MSO_ANCHOR # noqa: E402
30
+
31
+ # Status palette for the heatmap (key -> fill, icon, label).
32
+ PARCIAL = RGBColor(0xD4, 0xA0, 0x17) # gold — partial / incomplete data
33
+ STATUS = {
34
+ "done": (T.STATUS_DONE, "✓", "Concluído"),
35
+ "inprogress": (T.STATUS_INPROGRESS, "▶", "Em Execução"),
36
+ "pending": (T.STATUS_PENDING, "○", "Pendente"),
37
+ "parcial": (PARCIAL, "◑", "Parcial"),
38
+ "backlog": (T.STATUS_BACKLOG, "–", "Backlog"),
39
+ }
40
+ FULL_LEGEND = ["done", "inprogress", "pending", "parcial", "backlog"]
41
+ DEFAULT_STAGES = ["Download Áudio", "Transcrição", "Carga LakeHouse", "Validação"]
42
+ PRIO_DISPLAY = {"Alta": "Prioridade Alta", "Média": "Prioridade Média", "Baixa": "Prioridade Baixa"}
43
+
44
+
45
+ def build_heatmap(slide, *, title, subtitle, banner, rows, stages=None,
46
+ backlog_col=True, data_header="Backlog (TIDs)",
47
+ legend_keys=None, page=None, total=None):
48
+ """Build a período × estágio status heatmap; clears and rebuilds `slide`.
49
+
50
+ Args:
51
+ slide: Target slide; cleared and rebuilt in place.
52
+ title: Header title.
53
+ subtitle: Header subtitle.
54
+ banner: Banner strip text below the header.
55
+ rows: List of (label, [status_key per stage], data_str|None); data_str
56
+ fills the optional trailing column when backlog_col is True.
57
+ stages: Column captions (default: the four STT stages).
58
+ backlog_col: If True, add a trailing data column.
59
+ data_header: Caption for the trailing data column.
60
+ legend_keys: Subset/order of STATUS keys to show (default: FULL_LEGEND).
61
+ page: Footer page number, or None to omit the footer.
62
+ total: Footer total page count (defaults to `page`).
63
+ """
64
+ stages = stages or DEFAULT_STAGES
65
+ legend_keys = legend_keys or FULL_LEGEND
66
+ T.clear_slide_shapes(slide)
67
+ T.add_page_header(slide, title, subtitle)
68
+ T.add_rect(slide, Inches(0.45), Inches(1.32), Inches(12.4), Inches(0.4), T.VERY_LIGHT_GRAY)
69
+ T.add_text(slide, Inches(0.6), Inches(1.36), Inches(12.1), Inches(0.32), banner,
70
+ size=11, bold=True, color=T.CLARO_RED_DARK)
71
+ n = len(rows)
72
+ if backlog_col:
73
+ x_lab, w_lab = Inches(0.45), Inches(1.55)
74
+ x0, cw = Inches(2.05), Inches(2.0)
75
+ x_bk, w_bk = x0 + cw * len(stages) + Inches(0.05), Inches(2.45)
76
+ else:
77
+ x_lab, w_lab = Inches(0.45), Inches(1.9)
78
+ x0 = Inches(2.45)
79
+ cw = (Inches(12.85) - x0) / len(stages)
80
+ x_bk = None
81
+ y_hdr = Inches(1.95)
82
+ ch = Inches(0.45) if n <= 8 else Inches(0.33)
83
+ gap = Inches(0.08) if n <= 8 else Inches(0.035)
84
+ T.add_text(slide, x_lab, y_hdr, w_lab, Inches(0.3), "Período", size=10, bold=True, color=T.MID_GRAY)
85
+ for j, st in enumerate(stages):
86
+ T.add_text(slide, x0 + cw * j, y_hdr, cw, Inches(0.3), st, size=10, bold=True,
87
+ color=T.MID_GRAY, align=PP_ALIGN.CENTER)
88
+ if backlog_col:
89
+ T.add_text(slide, x_bk, y_hdr, w_bk, Inches(0.3), data_header, size=10,
90
+ bold=True, color=T.MID_GRAY, align=PP_ALIGN.CENTER)
91
+ y0 = y_hdr + Inches(0.35)
92
+ for i, (label, statuses, extra) in enumerate(rows):
93
+ y = y0 + i * (ch + gap)
94
+ T.add_rect(slide, x_lab, y, w_lab, ch, T.VERY_LIGHT_GRAY)
95
+ T.add_text(slide, x_lab + Inches(0.1), y, w_lab - Inches(0.1), ch, label,
96
+ size=10, bold=True, color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
97
+ for j, key in enumerate(statuses):
98
+ fill, icon, _ = STATUS[key]
99
+ T.add_filled_text(slide, x0 + cw * j, y, cw - Inches(0.1), ch, icon, fill=fill, size=13)
100
+ if backlog_col:
101
+ T.add_rect(slide, x_bk, y, w_bk, ch, T.LIGHT_GRAY)
102
+ T.add_text(slide, x_bk, y, w_bk, ch, extra or "—", size=11, bold=True,
103
+ color=T.DARK_GRAY, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
104
+ ly = y0 + n * (ch + gap) + Inches(0.12)
105
+ T.add_text(slide, Inches(0.45), ly, Inches(1.0), Inches(0.3), "Legenda:", size=9,
106
+ bold=True, color=T.MID_GRAY)
107
+ lx = Inches(0.45) + Inches(1.0)
108
+ for key in legend_keys:
109
+ fill, icon, lab = STATUS[key]
110
+ T.add_filled_text(slide, lx, ly, Inches(0.32), Inches(0.28), icon, fill=fill, size=10)
111
+ T.add_text(slide, lx + Inches(0.36), ly, Inches(2.0), Inches(0.3), lab, size=9,
112
+ color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
113
+ lx = lx + Inches(0.36) + Inches(min(len(lab) * 0.09 + 0.3, 2.0))
114
+ if page is not None:
115
+ T.add_page_footer(slide, page, total or page)
116
+
117
+
118
+ def build_gantt(slide, *, title, subtitle, activities, week_labels,
119
+ page=None, total=None, header_left="Atividade / Frente"):
120
+ """Build the Claro 'Cronograma / Próximos Passos' gantt on `slide`.
121
+
122
+ Clears and rebuilds the slide in place.
123
+
124
+ Args:
125
+ slide: Target slide; cleared and rebuilt in place.
126
+ title: Header title.
127
+ subtitle: Header subtitle.
128
+ activities: List of {name, cat, start, end, prio}; `cat` is a key in
129
+ T.CAT_COLOR, start/end are 1-based week indices, prio in {Alta,
130
+ Média, Baixa}.
131
+ week_labels: One label per week column (use "Mes\\nSn").
132
+ page: Footer page number, or None to omit the footer.
133
+ total: Footer total page count (defaults to `page`).
134
+ header_left: Caption for the top-left header cell.
135
+ """
136
+ n_weeks = len(week_labels)
137
+ HDR_X, HDR_Y, HDR_W, HDR_H = Inches(0.45), Inches(1.55), Inches(4.2), Inches(0.48)
138
+ ACT_X, ACT_W = Inches(0.6), Inches(2.8)
139
+ CAT_X, CAT_W, CAT_H = Inches(3.4), Inches(1.15), Inches(0.24)
140
+ ACC_X, ACC_W = Inches(0.45), Inches(0.08)
141
+ GRID_X = Inches(4.65)
142
+ GRID_W = Inches(13.333) - GRID_X - Inches(0.45)
143
+ COL_W = GRID_W / n_weeks
144
+ ROW_Y0 = HDR_Y + HDR_H + Inches(0.04)
145
+ ROW_H, ROW_GAP = Inches(0.38), Inches(0.07)
146
+ BAR_H = Inches(0.22)
147
+ BAR_PADY = (ROW_H - BAR_H) / 2
148
+
149
+ T.clear_slide_shapes(slide)
150
+ T.add_page_header(slide, title, subtitle)
151
+ T.add_filled_text(slide, HDR_X, HDR_Y, HDR_W, HDR_H, header_left,
152
+ fill=T.CLARO_RED, tcolor=T.WHITE, size=10, bold=True,
153
+ align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.MIDDLE)
154
+ for w in range(n_weeks):
155
+ cx = GRID_X + COL_W * w
156
+ T.add_filled_text(slide, cx, HDR_Y, COL_W - Inches(0.01), HDR_H, week_labels[w],
157
+ fill=T.DARK_GRAY, tcolor=T.WHITE, size=9, bold=True,
158
+ align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
159
+ for i, a in enumerate(activities):
160
+ y = ROW_Y0 + i * (ROW_H + ROW_GAP)
161
+ color = T.CAT_COLOR[a["cat"]]
162
+ for w in range(n_weeks):
163
+ cx = GRID_X + COL_W * w
164
+ T.add_rect(slide, cx, y, COL_W - Inches(0.01), ROW_H, T.VERY_LIGHT_GRAY)
165
+ T.add_rect(slide, HDR_X, y, HDR_W, ROW_H, T.WHITE)
166
+ T.add_rect(slide, ACC_X, y, ACC_W, ROW_H, color)
167
+ T.add_text(slide, ACT_X, y, ACT_W, ROW_H, a["name"], size=7.5,
168
+ color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
169
+ chip_y = y + (ROW_H - CAT_H) / 2
170
+ T.add_filled_text(slide, CAT_X, chip_y, CAT_W, CAT_H, a["cat"], fill=color,
171
+ tcolor=T.WHITE, size=7.5, bold=True, align=PP_ALIGN.CENTER,
172
+ anchor=MSO_ANCHOR.MIDDLE, corner=True)
173
+ bx = GRID_X + COL_W * (a["start"] - 1) + Inches(0.03)
174
+ bw = COL_W * (a["end"] - a["start"] + 1) - Inches(0.06)
175
+ T.add_filled_text(slide, bx, y + BAR_PADY, bw, BAR_H,
176
+ PRIO_DISPLAY.get(a["prio"], a["prio"]), fill=color,
177
+ tcolor=T.WHITE, size=7.5, bold=True, align=PP_ALIGN.CENTER,
178
+ anchor=MSO_ANCHOR.MIDDLE, corner=True)
179
+ ly = ROW_Y0 + len(activities) * (ROW_H + ROW_GAP) + Inches(0.14)
180
+ T.add_text(slide, Inches(0.45), ly, Inches(1.4), Inches(0.3), "Categorias:",
181
+ size=9, bold=True, color=T.MID_GRAY)
182
+ lx = Inches(1.5)
183
+ seen = []
184
+ for a in activities:
185
+ if a["cat"] not in seen:
186
+ seen.append(a["cat"])
187
+ for cat in seen:
188
+ T.add_rect(slide, lx, ly + Inches(0.05), Inches(0.2), Inches(0.2), T.CAT_COLOR[cat])
189
+ T.add_text(slide, lx + Inches(0.25), ly, Inches(1.6), Inches(0.3), cat, size=9,
190
+ color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
191
+ lx = lx + Inches(0.25 + min(len(cat) * 0.085 + 0.22, 1.6))
192
+ if page is not None:
193
+ T.add_page_footer(slide, page, total or page)