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.
- package/LICENSE +21 -0
- package/NOTICE +108 -0
- package/README.md +134 -0
- package/canonical/HARVEST.yaml +858 -0
- package/canonical/PROVENANCE.yaml +740 -0
- package/canonical/agents/README.md +95 -0
- package/canonical/agents/agentic-architect.md +18 -0
- package/canonical/agents/database-reviewer.md +41 -0
- package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
- package/canonical/agents/pr-reviewer.md +96 -0
- package/canonical/agents/python-reviewer.md +55 -0
- package/canonical/agents/report-formatter.md +19 -0
- package/canonical/agents/security-reviewer.md +53 -0
- package/canonical/agents/test-writer.md +34 -0
- package/canonical/commands/fh-context.md +37 -0
- package/canonical/evals/promptfoo.redteam.yaml +108 -0
- package/canonical/hooks/cost-prices.json +14 -0
- package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
- package/canonical/hooks/freeharness-config-guard.mjs +162 -0
- package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
- package/canonical/hooks/freeharness-converge.mjs +227 -0
- package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
- package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
- package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
- package/canonical/hooks/freeharness-precompact.mjs +323 -0
- package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
- package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
- package/canonical/hooks/freeharness-session-start +583 -0
- package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
- package/canonical/hooks/hooks.claude-code.json +17 -0
- package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
- package/canonical/hooks/hooks.converge.claude-code.json +15 -0
- package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
- package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
- package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
- package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
- package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
- package/canonical/mcp/servers.json +20 -0
- package/canonical/openspec/config.base.yaml +89 -0
- package/canonical/openspec/schema.spec-driven.yaml +277 -0
- package/canonical/openspec/templates/data-contract.md +36 -0
- package/canonical/openspec/templates/design.md +84 -0
- package/canonical/openspec/templates/eval-plan.md +33 -0
- package/canonical/openspec/templates/follow-ups.md +2 -0
- package/canonical/openspec/templates/proposal.md +45 -0
- package/canonical/openspec/templates/spec.md +42 -0
- package/canonical/openspec/templates/tasks.md +38 -0
- package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
- package/canonical/profiles/local-llamacpp.json +27 -0
- package/canonical/profiles/local-ollama.json +20 -0
- package/canonical/profiles/mcp.json +91 -0
- package/canonical/rules/CLAUDE.md +78 -0
- package/canonical/rules/project-CLAUDE.template.md +62 -0
- package/canonical/rules/routing.md +20 -0
- package/canonical/rules/safety.md +41 -0
- package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
- package/canonical/skills/agent-evaluation/SKILL.md +102 -0
- package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
- package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
- package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
- package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
- package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
- package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
- package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
- package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
- package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
- package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
- package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
- package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
- package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
- package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
- package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
- package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
- package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
- package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
- package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
- package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
- package/canonical/skills/agentic-architecture/SKILL.md +41 -0
- package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
- package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
- package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
- package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
- package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
- package/canonical/skills/code-review/SKILL.md +52 -0
- package/canonical/skills/code-review/evals/cases.yaml +197 -0
- package/canonical/skills/git-workflow/SKILL.md +41 -0
- package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
- package/canonical/skills/local-code/SKILL.md +24 -0
- package/canonical/skills/local-code/evals/cases.yaml +85 -0
- package/canonical/skills/local-code/scripts/query_llama.py +68 -0
- package/canonical/skills/report-formatting/SKILL.md +62 -0
- package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
- package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
- package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
- package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
- package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
- package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
- package/canonical/skills/report-formatting/reference/authoring.md +66 -0
- package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
- package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
- package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
- package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
- package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
- package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
- package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
- package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
- package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
- package/canonical/skills/report-formatting/scripts/package.json +17 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
- package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
- package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
- package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
- package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
- package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
- package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
- package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
- package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
- package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
- package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
- package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
- package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
- package/canonical/skills/systematic-debugging/SKILL.md +44 -0
- package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
- package/canonical/skills/test-driven-development/SKILL.md +42 -0
- package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
- package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
- package/canonical/skills/verification-before-completion/SKILL.md +53 -0
- package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
- package/dist/adapters/content/language-lint.d.ts +46 -0
- package/dist/adapters/content/language-lint.js +191 -0
- package/dist/adapters/harness/claude-code.d.ts +57 -0
- package/dist/adapters/harness/claude-code.js +385 -0
- package/dist/adapters/harness/index.d.ts +3 -0
- package/dist/adapters/harness/index.js +17 -0
- package/dist/adapters/harness/opencode.d.ts +7 -0
- package/dist/adapters/harness/opencode.js +166 -0
- package/dist/adapters/harness/plugin.d.ts +22 -0
- package/dist/adapters/harness/plugin.js +257 -0
- package/dist/adapters/memory/doctor.d.ts +480 -0
- package/dist/adapters/memory/doctor.js +1217 -0
- package/dist/adapters/memory/vendored.d.ts +150 -0
- package/dist/adapters/memory/vendored.js +487 -0
- package/dist/adapters/package/node.d.ts +9 -0
- package/dist/adapters/package/node.js +20 -0
- package/dist/adapters/prompt/readline.d.ts +19 -0
- package/dist/adapters/prompt/readline.js +53 -0
- package/dist/adapters/sync/diff.d.ts +43 -0
- package/dist/adapters/sync/diff.js +380 -0
- package/dist/cli/cleanup.d.ts +86 -0
- package/dist/cli/cleanup.js +382 -0
- package/dist/cli/cost.d.ts +304 -0
- package/dist/cli/cost.js +501 -0
- package/dist/cli/doctor.d.ts +205 -0
- package/dist/cli/doctor.js +654 -0
- package/dist/cli/executor.d.ts +5 -0
- package/dist/cli/executor.js +48 -0
- package/dist/cli/plugin-validate.d.ts +37 -0
- package/dist/cli/plugin-validate.js +256 -0
- package/dist/cli/prefix.d.ts +68 -0
- package/dist/cli/prefix.js +218 -0
- package/dist/cli/profile.d.ts +170 -0
- package/dist/cli/profile.js +285 -0
- package/dist/cli/runner.d.ts +10 -0
- package/dist/cli/runner.js +27 -0
- package/dist/cli/uninstall.d.ts +65 -0
- package/dist/cli/uninstall.js +147 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +989 -0
- package/dist/infra/dogfood.d.ts +31 -0
- package/dist/infra/dogfood.js +51 -0
- package/dist/infra/fsutil.d.ts +40 -0
- package/dist/infra/fsutil.js +143 -0
- package/dist/infra/manifest.d.ts +76 -0
- package/dist/infra/manifest.js +92 -0
- package/dist/infra/paths.d.ts +19 -0
- package/dist/infra/paths.js +74 -0
- package/dist/infra/routing.d.ts +4 -0
- package/dist/infra/routing.js +7 -0
- package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/context.js +1 -0
- package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
- package/node_modules/@freeharness/core/dist/index.js +6 -0
- package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
- package/node_modules/@freeharness/core/dist/planner.js +18 -0
- package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
- package/node_modules/@freeharness/core/dist/ports.js +1 -0
- package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
- package/node_modules/@freeharness/core/dist/registry.js +124 -0
- package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/tiers.js +99 -0
- package/node_modules/@freeharness/core/package.json +34 -0
- package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
- package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
- package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
- package/node_modules/@freeharness/sdd/package.json +57 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
- package/package.json +70 -0
- package/provenance/canonical.PROVENANCE.yaml +740 -0
- package/provenance/claude-mem.LICENSE.upstream +202 -0
- package/provenance/memory.PROVENANCE.yaml +399 -0
- package/provenance/sdd.PROVENANCE.yaml +175 -0
- package/vendor-licenses/caveman.LICENSE +27 -0
- package/vendor-licenses/deepseek-harness.LICENSE +21 -0
- package/vendor-licenses/ecc.LICENSE +21 -0
- package/vendor-licenses/pi.LICENSE +21 -0
- package/vendor-licenses/superpowers.LICENSE +21 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Template: Executive report (.docx, Claro theme).
|
|
5
|
+
*
|
|
6
|
+
* For leadership readers with little time and no technical background. Goal:
|
|
7
|
+
* high-level storytelling (tension -> evidence -> resolution), statistics
|
|
8
|
+
* translated into business language, a decision panel, and a one-page closing.
|
|
9
|
+
* Copy this file, rename (build-<slug>.js), and fill `children` with the real
|
|
10
|
+
* content using the ./theme-claro.js helpers. Content placeholders are PT-BR
|
|
11
|
+
* (client-facing); comments are English.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node example_build_ExecutiveReport_docx.js # ./out/Relatorio_Executivo.docx
|
|
15
|
+
* node example_build_ExecutiveReport_docx.js /path/out.docx
|
|
16
|
+
*/
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
const path = require("path");
|
|
19
|
+
const { Packer, AlignmentType } = require("docx");
|
|
20
|
+
const T = require("./theme-claro");
|
|
21
|
+
|
|
22
|
+
const children = [];
|
|
23
|
+
|
|
24
|
+
// ---- COVER (rich) ----
|
|
25
|
+
children.push(...T.coverBlock({
|
|
26
|
+
title: "Título Executivo — uma frase que vende a história",
|
|
27
|
+
subtitle: "STT — Claro (Projeto Speech-to-Text)",
|
|
28
|
+
tagline: "O que mudou, por que importa, e a decisão que pedimos",
|
|
29
|
+
org: "Projeto STT — Claro | DADOS & IA",
|
|
30
|
+
metaLines: ["Para: Diretoria / Liderança", "Data: 22/06/2026"],
|
|
31
|
+
}));
|
|
32
|
+
children.push(T.spacer(240));
|
|
33
|
+
|
|
34
|
+
// ---- EXECUTIVE SUMMARY (the whole story in 8 lines) ----
|
|
35
|
+
children.push(T.h1("Resumo executivo"));
|
|
36
|
+
children.push(T.body([
|
|
37
|
+
T.t("Em uma frase: ", { size: 22, bold: true }),
|
|
38
|
+
T.t("a tese central, dita como impacto de negócio, não como detalhe técnico.", { size: 22, color: T.C.body }),
|
|
39
|
+
]));
|
|
40
|
+
children.push(T.statCards([
|
|
41
|
+
{ value: "+38%", label: "ganho que importa", color: T.C.green, fill: T.C.successFill },
|
|
42
|
+
{ value: "R$ X", label: "custo evitado / mês", color: T.C.deepRed, fill: "FFEDED" },
|
|
43
|
+
{ value: "2 sem", label: "prazo para a decisão", color: T.C.amber, fill: T.C.noteFill },
|
|
44
|
+
]));
|
|
45
|
+
children.push(T.spacer(140));
|
|
46
|
+
children.push(T.bullet([T.t("Mensagem-âncora 1. ", { size: 22, bold: true }), T.t("em linguagem de negócio.", { size: 22, color: T.C.body })]));
|
|
47
|
+
children.push(T.bullet([T.t("Mensagem-âncora 2. ", { size: 22, bold: true }), T.t("o risco, traduzido.", { size: 22, color: T.C.body })]));
|
|
48
|
+
children.push(T.calloutLine("Decisão que pedimos:", "a ação principal, em uma frase, com o prazo.", "success"));
|
|
49
|
+
children.push(T.spacer(200));
|
|
50
|
+
|
|
51
|
+
// ---- NARRATIVE (tension -> evidence -> resolution) ----
|
|
52
|
+
children.push(T.h1("1. O problema (tensão)"));
|
|
53
|
+
children.push(T.body("O contexto e o que estava em risco, sem jargão. Por que isto chegou à mesa da liderança."));
|
|
54
|
+
children.push(T.calloutLine("Leitura executiva:", "o que isso significava para o negócio se nada mudasse.", "danger"));
|
|
55
|
+
children.push(T.spacer(140));
|
|
56
|
+
|
|
57
|
+
children.push(T.h1("2. O que descobrimos (evidência)"));
|
|
58
|
+
children.push(T.body("A evidência central, com 1-2 números traduzidos. Estatística vira frase de negócio."));
|
|
59
|
+
children.push(T.makeTable(
|
|
60
|
+
[4200, 2200, 3240],
|
|
61
|
+
["Indicador", "Antes / Depois", "O que significa"],
|
|
62
|
+
[
|
|
63
|
+
[{ runs: "Métrica-chave" }, { runs: [T.t("X → Y", { size: 20, bold: true, color: T.C.green })], align: AlignmentType.RIGHT }, { runs: "tradução em 1 linha" }],
|
|
64
|
+
[{ runs: "Custo / risco" }, { runs: "Z", align: AlignmentType.RIGHT }, { runs: [T.t("impacto direto", { size: 20, color: T.C.deepRed })] }],
|
|
65
|
+
]
|
|
66
|
+
));
|
|
67
|
+
children.push(T.caption("Tabela 1 – Só os números que mudam a decisão."));
|
|
68
|
+
children.push(T.spacer(140));
|
|
69
|
+
|
|
70
|
+
children.push(T.h1("3. O caminho (resolução)"));
|
|
71
|
+
children.push(T.body("A recomendação e o plano em poucos passos, com o ganho esperado e o que é preciso da liderança."));
|
|
72
|
+
|
|
73
|
+
// ---- DECISION PANEL (semaphore) ----
|
|
74
|
+
children.push(T.h2("Painel de decisão"));
|
|
75
|
+
children.push(T.makeTable(
|
|
76
|
+
[4600, 2000, 3040],
|
|
77
|
+
["Decisão", "Status", "Próximo passo"],
|
|
78
|
+
[
|
|
79
|
+
[{ runs: "Aprovar X" }, { runs: [T.t("Recomendado", { size: 20, bold: true, color: T.C.green })], fill: T.C.successFill }, { runs: "quem / quando" }],
|
|
80
|
+
[{ runs: "Avaliar Y" }, { runs: [T.t("Atenção", { size: 20, color: T.C.amber })], fill: T.C.noteFill }, { runs: "dado a validar" }],
|
|
81
|
+
[{ runs: "Não fazer Z" }, { runs: [T.t("Bloqueado", { size: 20, color: T.C.deepRed })], fill: T.C.dangerFill }, { runs: "motivo" }],
|
|
82
|
+
]
|
|
83
|
+
));
|
|
84
|
+
children.push(T.spacer(160));
|
|
85
|
+
|
|
86
|
+
// ---- ONE-PAGE CLOSING ----
|
|
87
|
+
children.push(T.h1("Em uma página para a diretoria"));
|
|
88
|
+
children.push(T.callout([
|
|
89
|
+
T.body([T.t("O essencial: ", { size: 22, bold: true }), T.t("a história em 3 frases — situação, ação, ganho.", { size: 22, color: T.C.body })]),
|
|
90
|
+
T.bullet([T.t("Pedimos: ", { size: 22, bold: true }), T.t("a decisão.", { size: 22, color: T.C.body })]),
|
|
91
|
+
T.bullet([T.t("Ganho: ", { size: 22, bold: true }), T.t("o resultado de negócio.", { size: 22, color: T.C.body })]),
|
|
92
|
+
T.bullet([T.t("Prazo: ", { size: 22, bold: true }), T.t("a janela.", { size: 22, color: T.C.body })]),
|
|
93
|
+
], "info"));
|
|
94
|
+
|
|
95
|
+
// ---- AUTHORSHIP ----
|
|
96
|
+
children.push(...T.authorBlock({
|
|
97
|
+
name: "André Negrelli",
|
|
98
|
+
role: "Tech Lead — AI Data Engineer",
|
|
99
|
+
area: "DADOS & IA | Tech Dados & IA — Aquisição e Transformação de Dados & IA",
|
|
100
|
+
project: "Projeto STT — Claro · 22/06/2026",
|
|
101
|
+
}));
|
|
102
|
+
|
|
103
|
+
const doc = T.buildDocument({
|
|
104
|
+
children,
|
|
105
|
+
headerText: "Relatório Executivo | STT Claro",
|
|
106
|
+
footerAuthor: "André Negrelli — DADOS & IA",
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const outPath = process.argv[2] || path.join(process.cwd(), "out", "Relatorio_Executivo.docx");
|
|
110
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
111
|
+
Packer.toBuffer(doc).then((buf) => {
|
|
112
|
+
fs.writeFileSync(outPath, buf);
|
|
113
|
+
console.log("Gerado:", outPath, `(${buf.length} bytes)`);
|
|
114
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "report-formatting-skill",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Theme library and scripts (default theme: Claro) to generate .docx reports.",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"check": "node check-env.js",
|
|
8
|
+
"example": "node example-build.js"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"docx": "^9.0.0",
|
|
12
|
+
"image-size": "^1.1.1"
|
|
13
|
+
},
|
|
14
|
+
"optionalDependencies": {
|
|
15
|
+
"@mermaid-js/mermaid-cli": "^11.0.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Template: Status Report deck (.pptx, Claro theme).
|
|
3
|
+
|
|
4
|
+
Base template for the STT-style status report. Copy this file, rename
|
|
5
|
+
(build_<slug>.py), and fill the data dicts with the real period content, using
|
|
6
|
+
the theme_claro_pptx helpers. Also a smoke test of the pptx track.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python example_build_StatusReport_pptx.py # ./out/Status_Report_exemplo.pptx
|
|
10
|
+
python example_build_StatusReport_pptx.py /path/out.pptx
|
|
11
|
+
|
|
12
|
+
Note on timelines: the rich "Status até DD/MM" timeline slides are NOT rebuilt
|
|
13
|
+
here — they are cloned from the original Claro template and edited via lxml (see
|
|
14
|
+
reference/PPTX.md). This template builds the python-pptx slides: cover, summary,
|
|
15
|
+
Gantt, heatmap, ROAM. Content is PT-BR (client-facing); instructions are English.
|
|
16
|
+
|
|
17
|
+
Reusable, refined blocks: `status_report_blocks.py` provides build_heatmap
|
|
18
|
+
(período × estágio status grid with a Parcial category + optional data column +
|
|
19
|
+
full legend) and build_gantt (Claro red/dark header, per-row accent + category
|
|
20
|
+
chip + priority bar). Both CLEAR and rebuild a given slide — prefer them over the
|
|
21
|
+
simplified build_heatmap/build_gantt below for status-report decks.
|
|
22
|
+
"""
|
|
23
|
+
import os
|
|
24
|
+
import sys
|
|
25
|
+
|
|
26
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
27
|
+
import theme_claro_pptx as T # noqa: E402
|
|
28
|
+
from pptx import Presentation # noqa: E402
|
|
29
|
+
from pptx.util import Inches # noqa: E402
|
|
30
|
+
from pptx.enum.text import PP_ALIGN # noqa: E402
|
|
31
|
+
|
|
32
|
+
prs = Presentation()
|
|
33
|
+
prs.slide_width = Inches(13.333)
|
|
34
|
+
prs.slide_height = Inches(7.5)
|
|
35
|
+
BLANK = prs.slide_layouts[6]
|
|
36
|
+
TOTAL = 5
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def new_slide():
|
|
40
|
+
"""Add a blank slide to the deck and return it."""
|
|
41
|
+
return prs.slides.add_slide(BLANK)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def build_cover(period_label):
|
|
45
|
+
"""Add the cover slide with logo, title, subtitle, and period.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
period_label: Reporting-period caption shown under the subtitle.
|
|
49
|
+
"""
|
|
50
|
+
s = new_slide()
|
|
51
|
+
T.add_logo(s, x=Inches(0.5), y=Inches(0.7), height=Inches(1.3))
|
|
52
|
+
T.add_rect(s, Inches(0.5), Inches(2.6), Inches(0.9), Inches(0.12), T.CLARO_RED)
|
|
53
|
+
T.add_text(s, Inches(0.5), Inches(2.8), Inches(12), Inches(1.0),
|
|
54
|
+
"Status Report — Pipeline STT", size=34, bold=True, color=T.DARK_GRAY)
|
|
55
|
+
T.add_text(s, Inches(0.5), Inches(3.7), Inches(12), Inches(0.5),
|
|
56
|
+
"Dados & IA — Projeto Speech-to-Text (Claro)", size=16,
|
|
57
|
+
color=T.MID_GRAY, italic=True)
|
|
58
|
+
T.add_text(s, Inches(0.5), Inches(4.25), Inches(12), Inches(0.4),
|
|
59
|
+
period_label, size=13, color=T.MID_GRAY)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def build_summary(rows):
|
|
63
|
+
"""Add the deliveries-summary slide (one table row per delivery).
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
rows: List of dicts with keys theme, subtitle, deliveries, maturity,
|
|
67
|
+
maturity_color, maturity_detail, impact.
|
|
68
|
+
"""
|
|
69
|
+
s = new_slide()
|
|
70
|
+
T.add_page_header(s, "Resumo | Entregas do Período",
|
|
71
|
+
"Principais realizações do período")
|
|
72
|
+
headers = ["Entrega estratégica", "Principais entregues",
|
|
73
|
+
"Maturidade", "Impacto no negócio"]
|
|
74
|
+
widths = [Inches(3.0), Inches(3.8), Inches(2.6), Inches(3.0)]
|
|
75
|
+
xs = [Inches(0.45)]
|
|
76
|
+
for w in widths[:-1]:
|
|
77
|
+
xs.append(xs[-1] + w)
|
|
78
|
+
hy, hh = Inches(1.45), Inches(0.42)
|
|
79
|
+
for i, h in enumerate(headers):
|
|
80
|
+
T.add_filled_text(s, xs[i], hy, widths[i], hh, h, fill=T.CLARO_RED, size=11)
|
|
81
|
+
ry, rh, gap = hy + hh + Inches(0.08), Inches(1.5), Inches(0.12)
|
|
82
|
+
for ri, row in enumerate(rows):
|
|
83
|
+
y = ry + ri * (rh + gap)
|
|
84
|
+
T.add_rect(s, xs[0], y, Inches(0.08), rh, T.CLARO_RED)
|
|
85
|
+
T.add_rect(s, xs[0] + Inches(0.08), y, widths[0] - Inches(0.08), rh, T.VERY_LIGHT_GRAY)
|
|
86
|
+
T.add_text(s, xs[0] + Inches(0.2), y + Inches(0.1), widths[0] - Inches(0.3),
|
|
87
|
+
Inches(0.45), row["theme"], size=13, bold=True, color=T.CLARO_RED_DARK)
|
|
88
|
+
T.add_text(s, xs[0] + Inches(0.2), y + Inches(0.55), widths[0] - Inches(0.3),
|
|
89
|
+
Inches(0.85), row["subtitle"], size=10, color=T.MID_GRAY, italic=True)
|
|
90
|
+
T.add_rect(s, xs[1], y, widths[1], rh, T.VERY_LIGHT_GRAY)
|
|
91
|
+
T.build_bullet_list(s, xs[1] + Inches(0.1), y + Inches(0.08),
|
|
92
|
+
widths[1] - Inches(0.2), rh - Inches(0.16), row["deliveries"])
|
|
93
|
+
T.add_rect(s, xs[2], y, widths[2], rh, T.VERY_LIGHT_GRAY)
|
|
94
|
+
T.add_filled_text(s, xs[2] + Inches(0.15), y + Inches(0.15), widths[2] - Inches(0.3),
|
|
95
|
+
Inches(0.35), row["maturity"], fill=row["maturity_color"], size=9, corner=True)
|
|
96
|
+
T.add_text(s, xs[2] + Inches(0.15), y + Inches(0.6), widths[2] - Inches(0.3),
|
|
97
|
+
Inches(0.8), row["maturity_detail"], size=9, color=T.DARK_GRAY)
|
|
98
|
+
T.add_rect(s, xs[3], y, widths[3], rh, T.VERY_LIGHT_GRAY)
|
|
99
|
+
T.build_bullet_list(s, xs[3] + Inches(0.1), y + Inches(0.08),
|
|
100
|
+
widths[3] - Inches(0.2), rh - Inches(0.16), row["impact"])
|
|
101
|
+
T.add_page_footer(s, 2, TOTAL)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def build_gantt(activities, weeks):
|
|
105
|
+
"""Add a simplified gantt slide (one bar per activity).
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
activities: List of {name, cat, start, end, priority}; start/end are
|
|
109
|
+
1-based week indices.
|
|
110
|
+
weeks: Number of week columns.
|
|
111
|
+
"""
|
|
112
|
+
s = new_slide()
|
|
113
|
+
T.add_page_header(s, "Cronograma de Execução", "Próximos passos por semana")
|
|
114
|
+
x0, y0 = Inches(3.6), Inches(1.55)
|
|
115
|
+
col_w = (Inches(13.333) - x0 - Inches(0.45)) / weeks
|
|
116
|
+
for w in range(weeks):
|
|
117
|
+
T.add_text(s, x0 + col_w * w, y0, col_w, Inches(0.3), f"S{w + 1}",
|
|
118
|
+
size=9, bold=True, color=T.MID_GRAY, align=PP_ALIGN.CENTER)
|
|
119
|
+
ry, rh = y0 + Inches(0.35), Inches(0.42)
|
|
120
|
+
for i, a in enumerate(activities):
|
|
121
|
+
y = ry + i * (rh + Inches(0.08))
|
|
122
|
+
color = T.CAT_COLOR.get(a["cat"], T.STATUS_BACKLOG)
|
|
123
|
+
T.add_rect(s, Inches(0.45), y, Inches(0.08), rh, color)
|
|
124
|
+
T.add_text(s, Inches(0.6), y, Inches(2.0), rh, a["name"], size=9, color=T.DARK_GRAY)
|
|
125
|
+
bx = x0 + col_w * (a["start"] - 1)
|
|
126
|
+
bw = col_w * (a["end"] - a["start"] + 1)
|
|
127
|
+
T.add_filled_text(s, bx, y + Inches(0.05), bw, rh - Inches(0.1),
|
|
128
|
+
f"Prioridade {a['priority']}", fill=color, size=8, corner=True)
|
|
129
|
+
T.add_page_footer(s, 3, TOTAL)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def build_heatmap(periods, stages):
|
|
133
|
+
"""Add a simplified period × stage status heatmap slide.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
periods: List of (label, [status_key per stage]).
|
|
137
|
+
stages: Column captions.
|
|
138
|
+
"""
|
|
139
|
+
s = new_slide()
|
|
140
|
+
T.add_page_header(s, "Cronograma de Processamento", "Status por período x estágio")
|
|
141
|
+
x0, y0 = Inches(2.0), Inches(1.6)
|
|
142
|
+
cw, ch = Inches(2.4), Inches(0.42)
|
|
143
|
+
for j, st in enumerate(stages):
|
|
144
|
+
T.add_text(s, x0 + cw * j, y0, cw, Inches(0.3), st, size=9, bold=True,
|
|
145
|
+
color=T.MID_GRAY, align=PP_ALIGN.CENTER)
|
|
146
|
+
for i, (label, statuses) in enumerate(periods):
|
|
147
|
+
y = y0 + Inches(0.35) + i * (ch + Inches(0.06))
|
|
148
|
+
T.add_text(s, Inches(0.45), y, Inches(1.5), ch, label, size=9, color=T.DARK_GRAY)
|
|
149
|
+
for j, key in enumerate(statuses):
|
|
150
|
+
cfg = T.STATUS_CFG.get(key, T.STATUS_CFG["backlog"])
|
|
151
|
+
T.add_filled_text(s, x0 + cw * j, y, cw - Inches(0.1), ch, cfg[3],
|
|
152
|
+
fill=cfg[1], tcolor=cfg[2], size=12)
|
|
153
|
+
T.add_page_footer(s, 4, TOTAL)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def build_roam(risks):
|
|
157
|
+
"""Add the ROAM risk-map slide (one row per risk).
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
risks: List of dicts with keys theme, risk, roam, impact, owner,
|
|
161
|
+
action, due.
|
|
162
|
+
"""
|
|
163
|
+
s = new_slide()
|
|
164
|
+
T.add_page_header(s, "Mapa de Riscos (ROAM)", "Resolved / Owned / Accepted / Mitigated")
|
|
165
|
+
cols = ["Tema", "Risco", "ROAM", "Impacto", "Responsável", "Ação", "Prazo"]
|
|
166
|
+
widths = [Inches(1.6), Inches(3.0), Inches(0.9), Inches(1.4), Inches(1.6), Inches(2.6), Inches(1.1)]
|
|
167
|
+
xs = [Inches(0.45)]
|
|
168
|
+
for w in widths[:-1]:
|
|
169
|
+
xs.append(xs[-1] + w)
|
|
170
|
+
hy, hh = Inches(1.5), Inches(0.4)
|
|
171
|
+
for i, c in enumerate(cols):
|
|
172
|
+
T.add_filled_text(s, xs[i], hy, widths[i], hh, c, fill=T.CLARO_RED, size=9)
|
|
173
|
+
ROAM = {"R": T.STATUS_DONE, "O": T.CAT_COLOR["Pipeline"], "A": T.STATUS_INPROGRESS, "M": T.CAT_COLOR["Data Core"]}
|
|
174
|
+
ry, rh = hy + hh + Inches(0.06), Inches(0.6)
|
|
175
|
+
for ri, r in enumerate(risks):
|
|
176
|
+
y = ry + ri * (rh + Inches(0.06))
|
|
177
|
+
fill = T.WHITE if ri % 2 else T.VERY_LIGHT_GRAY
|
|
178
|
+
for j in range(len(cols)):
|
|
179
|
+
T.add_rect(s, xs[j], y, widths[j], rh, fill)
|
|
180
|
+
T.add_text(s, xs[0] + Inches(0.05), y, widths[0], rh, r["theme"], size=8, color=T.DARK_GRAY)
|
|
181
|
+
T.add_text(s, xs[1] + Inches(0.05), y, widths[1], rh, r["risk"], size=8, color=T.DARK_GRAY)
|
|
182
|
+
T.add_filled_text(s, xs[2] + Inches(0.25), y + Inches(0.12), Inches(0.4), Inches(0.36),
|
|
183
|
+
r["roam"], fill=ROAM.get(r["roam"], T.STATUS_BACKLOG), size=10, corner=True)
|
|
184
|
+
T.add_text(s, xs[3] + Inches(0.05), y, widths[3], rh, r["impact"], size=8, color=T.DARK_GRAY)
|
|
185
|
+
T.add_text(s, xs[4] + Inches(0.05), y, widths[4], rh, r["owner"], size=8, color=T.DARK_GRAY)
|
|
186
|
+
T.add_text(s, xs[5] + Inches(0.05), y, widths[5], rh, r["action"], size=8, color=T.DARK_GRAY)
|
|
187
|
+
T.add_text(s, xs[6] + Inches(0.05), y, widths[6], rh, r["due"], size=8, color=T.CLARO_RED_DARK)
|
|
188
|
+
T.add_page_footer(s, 5, TOTAL)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# ---- example data (replace with real period content) ----
|
|
192
|
+
build_cover("Status até 22/06/2026")
|
|
193
|
+
build_summary([
|
|
194
|
+
{"theme": "Pipeline D-0", "subtitle": "Estabilização do ciclo horário",
|
|
195
|
+
"deliveries": ["Circuit breaker", "Idle sentinel"], "maturity": "Produção",
|
|
196
|
+
"maturity_color": T.STATUS_DONE, "maturity_detail": "Em operação estável",
|
|
197
|
+
"impact": ["Menos incidentes", "Recuperação automática"]},
|
|
198
|
+
{"theme": "Backlog histórico", "subtitle": "Processamento mensal",
|
|
199
|
+
"deliveries": ["10/16 períodos"], "maturity": "Em andamento",
|
|
200
|
+
"maturity_color": T.STATUS_INPROGRESS, "maturity_detail": "62% concluído",
|
|
201
|
+
"impact": ["Cobertura crescente"]},
|
|
202
|
+
])
|
|
203
|
+
build_gantt([
|
|
204
|
+
{"name": "Deploy pipeline", "cat": "Pipeline", "start": 1, "end": 2, "priority": "Alta"},
|
|
205
|
+
{"name": "Backlog jan-mar", "cat": "Backlog", "start": 2, "end": 5, "priority": "Média"},
|
|
206
|
+
{"name": "Doc arquitetura", "cat": "Documentação", "start": 3, "end": 4, "priority": "Baixa"},
|
|
207
|
+
], weeks=6)
|
|
208
|
+
build_heatmap([
|
|
209
|
+
("Jan/2026", ["done", "done", "done", "done"]),
|
|
210
|
+
("Fev/2026", ["done", "done", "inprogress", "pending"]),
|
|
211
|
+
("Mar/2026", ["done", "inprogress", "backlog", "backlog"]),
|
|
212
|
+
], ["Download", "Transcrição", "Carga", "Validação"])
|
|
213
|
+
build_roam([
|
|
214
|
+
{"theme": "WhisperX", "risk": "Fila GPU saturada", "roam": "M", "impact": "Atraso",
|
|
215
|
+
"owner": "HubGPU", "action": "Nova QUEUE dedicada", "due": "30/06"},
|
|
216
|
+
{"theme": "Data Core", "risk": "Schema ADW", "roam": "O", "impact": "Médio",
|
|
217
|
+
"owner": "Data Core", "action": "Alinhar contrato", "due": "15/07"},
|
|
218
|
+
])
|
|
219
|
+
|
|
220
|
+
out = sys.argv[1] if len(sys.argv) > 1 else os.path.join(os.getcwd(), "out", "Status_Report_exemplo.pptx")
|
|
221
|
+
os.makedirs(os.path.dirname(out), exist_ok=True)
|
|
222
|
+
prs.save(out)
|
|
223
|
+
print("Gerado:", out)
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Template: Weekly Status deck (.pptx, Claro theme).
|
|
3
|
+
|
|
4
|
+
Lighter, weekly variant of the status report: one short deck the squad sends every
|
|
5
|
+
Friday. Six slides: cover, week highlights (done / in progress / blocked), processing
|
|
6
|
+
heatmap, execution Gantt, ROAM risks, next week. The heatmap and Gantt slides are
|
|
7
|
+
built by the refined, reusable builders in status_report_blocks.py (build_heatmap,
|
|
8
|
+
build_gantt), which clear and rebuild the slide they receive. Copy this file, rename
|
|
9
|
+
(build_<slug>.py), and fill the data at the bottom with the real week content.
|
|
10
|
+
Content is PT-BR (client-facing); instructions and docstrings are English.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
python example_build_WeeklyStatus_pptx.py # ./out/Weekly_Status_exemplo.pptx
|
|
14
|
+
python example_build_WeeklyStatus_pptx.py /path/out.pptx
|
|
15
|
+
|
|
16
|
+
Compared with example_build_StatusReport_pptx.py (biweekly/monthly): no deliverables
|
|
17
|
+
summary table and no cloned timeline slides; highlights replace the summary, and a
|
|
18
|
+
"next week" slide replaces the long-range plan.
|
|
19
|
+
"""
|
|
20
|
+
import os
|
|
21
|
+
import sys
|
|
22
|
+
|
|
23
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
24
|
+
import theme_claro_pptx as T # noqa: E402
|
|
25
|
+
import status_report_blocks as B # noqa: E402
|
|
26
|
+
from pptx import Presentation # noqa: E402
|
|
27
|
+
from pptx.util import Inches # noqa: E402
|
|
28
|
+
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR # noqa: E402
|
|
29
|
+
|
|
30
|
+
prs = Presentation()
|
|
31
|
+
prs.slide_width = Inches(13.333)
|
|
32
|
+
prs.slide_height = Inches(7.5)
|
|
33
|
+
BLANK = prs.slide_layouts[6]
|
|
34
|
+
TOTAL = 6
|
|
35
|
+
|
|
36
|
+
# Highlight lanes: key -> (caption, fill color).
|
|
37
|
+
LANES = {
|
|
38
|
+
"done": ("Entregue na semana", T.STATUS_DONE),
|
|
39
|
+
"inprogress": ("Em andamento", T.STATUS_INPROGRESS),
|
|
40
|
+
"blocked": ("Bloqueado / precisa de decisão", T.STATUS_RISK),
|
|
41
|
+
}
|
|
42
|
+
ROAM_COLOR = {
|
|
43
|
+
"R": T.STATUS_DONE,
|
|
44
|
+
"O": T.CAT_COLOR["Pipeline"],
|
|
45
|
+
"A": T.STATUS_INPROGRESS,
|
|
46
|
+
"M": T.CAT_COLOR["Data Core"],
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def new_slide():
|
|
51
|
+
"""Add a blank slide to the deck and return it."""
|
|
52
|
+
return prs.slides.add_slide(BLANK)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def build_cover(project, week_label, squad):
|
|
56
|
+
"""Add the cover slide with logo, title, project line, and the week caption.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
project: Project title shown under the accent bar.
|
|
60
|
+
week_label: Week caption, e.g. "Semana 36 — 31/08 a 04/09/2026".
|
|
61
|
+
squad: Team / area line shown in italics.
|
|
62
|
+
"""
|
|
63
|
+
s = new_slide()
|
|
64
|
+
T.add_logo(s, x=Inches(0.5), y=Inches(0.7), height=Inches(1.3))
|
|
65
|
+
T.add_rect(s, Inches(0.5), Inches(2.6), Inches(0.9), Inches(0.12), T.CLARO_RED)
|
|
66
|
+
T.add_text(s, Inches(0.5), Inches(2.8), Inches(12), Inches(1.0),
|
|
67
|
+
f"Weekly Status — {project}", size=34, bold=True, color=T.DARK_GRAY)
|
|
68
|
+
T.add_text(s, Inches(0.5), Inches(3.7), Inches(12), Inches(0.5),
|
|
69
|
+
squad, size=16, color=T.MID_GRAY, italic=True)
|
|
70
|
+
T.add_text(s, Inches(0.5), Inches(4.25), Inches(12), Inches(0.4),
|
|
71
|
+
week_label, size=13, color=T.MID_GRAY)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def build_highlights(week_label, lanes):
|
|
75
|
+
"""Add the week-highlights slide: three columns (done / in progress / blocked).
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
week_label: Subtitle caption with the week range.
|
|
79
|
+
lanes: Dict key -> list of short bullet strings; keys are LANES keys.
|
|
80
|
+
"""
|
|
81
|
+
s = new_slide()
|
|
82
|
+
T.add_page_header(s, "Destaques da Semana", week_label)
|
|
83
|
+
keys = list(LANES.keys())
|
|
84
|
+
x0, y0 = Inches(0.45), Inches(1.5)
|
|
85
|
+
gap = Inches(0.2)
|
|
86
|
+
col_w = (Inches(13.333) - x0 * 2 - gap * (len(keys) - 1)) / len(keys)
|
|
87
|
+
hh, body_h = Inches(0.42), Inches(4.6)
|
|
88
|
+
for i, key in enumerate(keys):
|
|
89
|
+
caption, fill = LANES[key]
|
|
90
|
+
x = x0 + (col_w + gap) * i
|
|
91
|
+
T.add_filled_text(s, x, y0, col_w, hh, caption, fill=fill, size=11, bold=True)
|
|
92
|
+
T.add_rect(s, x, y0 + hh, col_w, body_h, T.VERY_LIGHT_GRAY)
|
|
93
|
+
items = lanes.get(key) or ["—"]
|
|
94
|
+
T.build_bullet_list(s, x + Inches(0.15), y0 + hh + Inches(0.15),
|
|
95
|
+
col_w - Inches(0.3), body_h - Inches(0.3), items, size=11)
|
|
96
|
+
T.add_filled_text(s, x + col_w - Inches(0.7), y0 + hh + body_h - Inches(0.45),
|
|
97
|
+
Inches(0.55), Inches(0.3), str(len(lanes.get(key) or [])),
|
|
98
|
+
fill=fill, size=10, corner=True)
|
|
99
|
+
T.add_page_footer(s, 2, TOTAL)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def build_heatmap_slide(rows, stages, banner):
|
|
103
|
+
"""Add the processing heatmap slide via status_report_blocks.build_heatmap.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
rows: List of (label, [status_key per stage], data_str|None).
|
|
107
|
+
stages: Column captions, one per stage.
|
|
108
|
+
banner: Banner strip text below the header.
|
|
109
|
+
"""
|
|
110
|
+
s = new_slide()
|
|
111
|
+
B.build_heatmap(s, title="Cronograma de Processamento",
|
|
112
|
+
subtitle="Status por período x estágio", banner=banner,
|
|
113
|
+
rows=rows, stages=stages, page=3, total=TOTAL)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def build_gantt_slide(activities, week_labels):
|
|
117
|
+
"""Add the execution Gantt slide via status_report_blocks.build_gantt.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
activities: List of {name, cat, start, end, prio}; cat is a T.CAT_COLOR
|
|
121
|
+
key, start/end are 1-based week indices, prio in {Alta, Média, Baixa}.
|
|
122
|
+
week_labels: One label per week column (use "Mes\\nSn").
|
|
123
|
+
"""
|
|
124
|
+
s = new_slide()
|
|
125
|
+
B.build_gantt(s, title="Cronograma de Execução",
|
|
126
|
+
subtitle="Semana atual e as próximas", activities=activities,
|
|
127
|
+
week_labels=week_labels, page=4, total=TOTAL)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def build_roam(risks):
|
|
131
|
+
"""Add the ROAM risk slide (one row per risk).
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
risks: List of dicts with keys theme, risk, roam, impact, owner, action, due.
|
|
135
|
+
"""
|
|
136
|
+
s = new_slide()
|
|
137
|
+
T.add_page_header(s, "Riscos da Semana (ROAM)", "Resolved / Owned / Accepted / Mitigated")
|
|
138
|
+
cols = ["Tema", "Risco", "ROAM", "Impacto", "Responsável", "Ação", "Prazo"]
|
|
139
|
+
widths = [Inches(1.6), Inches(3.0), Inches(0.9), Inches(1.4), Inches(1.6), Inches(2.6), Inches(1.1)]
|
|
140
|
+
xs = [Inches(0.45)]
|
|
141
|
+
for w in widths[:-1]:
|
|
142
|
+
xs.append(xs[-1] + w)
|
|
143
|
+
hy, hh = Inches(1.5), Inches(0.4)
|
|
144
|
+
for i, c in enumerate(cols):
|
|
145
|
+
T.add_filled_text(s, xs[i], hy, widths[i], hh, c, fill=T.CLARO_RED, size=9)
|
|
146
|
+
ry, rh = hy + hh + Inches(0.06), Inches(0.6)
|
|
147
|
+
for ri, r in enumerate(risks):
|
|
148
|
+
y = ry + ri * (rh + Inches(0.06))
|
|
149
|
+
fill = T.WHITE if ri % 2 else T.VERY_LIGHT_GRAY
|
|
150
|
+
for j in range(len(cols)):
|
|
151
|
+
T.add_rect(s, xs[j], y, widths[j], rh, fill)
|
|
152
|
+
for j, key in enumerate(["theme", "risk"]):
|
|
153
|
+
T.add_text(s, xs[j] + Inches(0.05), y, widths[j], rh, r[key], size=8,
|
|
154
|
+
color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
|
|
155
|
+
T.add_filled_text(s, xs[2] + Inches(0.25), y + Inches(0.12), Inches(0.4), Inches(0.36),
|
|
156
|
+
r["roam"], fill=ROAM_COLOR.get(r["roam"], T.STATUS_BACKLOG),
|
|
157
|
+
size=10, corner=True)
|
|
158
|
+
for j, key in zip((3, 4, 5), ("impact", "owner", "action")):
|
|
159
|
+
T.add_text(s, xs[j] + Inches(0.05), y, widths[j], rh, r[key], size=8,
|
|
160
|
+
color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
|
|
161
|
+
T.add_text(s, xs[6] + Inches(0.05), y, widths[6], rh, r["due"], size=8,
|
|
162
|
+
color=T.CLARO_RED_DARK, anchor=MSO_ANCHOR.MIDDLE)
|
|
163
|
+
T.add_page_footer(s, 5, TOTAL)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def build_next_week(items, decisions):
|
|
167
|
+
"""Add the closing slide: next-week plan on the left, decisions needed on the right.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
items: List of {what, owner, due} for next week.
|
|
171
|
+
decisions: List of short strings the squad needs from the audience.
|
|
172
|
+
"""
|
|
173
|
+
s = new_slide()
|
|
174
|
+
T.add_page_header(s, "Próxima Semana", "Plano e decisões necessárias")
|
|
175
|
+
x_left, x_right = Inches(0.45), Inches(8.2)
|
|
176
|
+
y0 = Inches(1.5)
|
|
177
|
+
w_left = x_right - x_left - Inches(0.25)
|
|
178
|
+
w_right = Inches(13.333) - x_right - Inches(0.45)
|
|
179
|
+
T.add_filled_text(s, x_left, y0, w_left, Inches(0.42), "Plano da semana",
|
|
180
|
+
fill=T.CLARO_RED, size=11, bold=True, align=PP_ALIGN.LEFT)
|
|
181
|
+
rh = Inches(0.5)
|
|
182
|
+
for i, it in enumerate(items):
|
|
183
|
+
y = y0 + Inches(0.5) + i * (rh + Inches(0.06))
|
|
184
|
+
T.add_rect(s, x_left, y, w_left, rh, T.WHITE if i % 2 else T.VERY_LIGHT_GRAY)
|
|
185
|
+
T.add_rect(s, x_left, y, Inches(0.08), rh, T.CLARO_RED)
|
|
186
|
+
T.add_text(s, x_left + Inches(0.2), y, w_left - Inches(3.2), rh, it["what"],
|
|
187
|
+
size=10, color=T.DARK_GRAY, anchor=MSO_ANCHOR.MIDDLE)
|
|
188
|
+
T.add_text(s, x_left + w_left - Inches(3.0), y, Inches(1.9), rh, it["owner"],
|
|
189
|
+
size=9, color=T.MID_GRAY, anchor=MSO_ANCHOR.MIDDLE)
|
|
190
|
+
T.add_text(s, x_left + w_left - Inches(1.0), y, Inches(0.95), rh, it["due"],
|
|
191
|
+
size=9, bold=True, color=T.CLARO_RED_DARK, anchor=MSO_ANCHOR.MIDDLE,
|
|
192
|
+
align=PP_ALIGN.RIGHT)
|
|
193
|
+
T.add_filled_text(s, x_right, y0, w_right, Inches(0.42), "Decisões necessárias",
|
|
194
|
+
fill=T.DARK_GRAY, size=11, bold=True, align=PP_ALIGN.LEFT)
|
|
195
|
+
T.add_rect(s, x_right, y0 + Inches(0.42), w_right, Inches(4.0), T.VERY_LIGHT_GRAY)
|
|
196
|
+
T.build_bullet_list(s, x_right + Inches(0.15), y0 + Inches(0.6), w_right - Inches(0.3),
|
|
197
|
+
Inches(3.7), decisions or ["Nenhuma decisão pendente."], size=11)
|
|
198
|
+
T.add_page_footer(s, 6, TOTAL)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# ---- example data (replace with the real week content) ----
|
|
202
|
+
WEEK = "Semana 36 — 31/08 a 04/09/2026"
|
|
203
|
+
build_cover("Pipeline STT", WEEK, "Dados & IA — Projeto Speech-to-Text (Claro)")
|
|
204
|
+
build_highlights(WEEK, {
|
|
205
|
+
"done": ["Circuit breaker em produção", "Backlog Fev/2026 carregado"],
|
|
206
|
+
"inprogress": ["Transcrição Mar/2026 (62%)", "Doc de arquitetura v2"],
|
|
207
|
+
"blocked": ["Schema ADW aguardando Data Core"],
|
|
208
|
+
})
|
|
209
|
+
build_heatmap_slide(
|
|
210
|
+
rows=[
|
|
211
|
+
("Jan/2026", ["done", "done", "done", "done"], "0"),
|
|
212
|
+
("Fev/2026", ["done", "done", "done", "parcial"], "1.2k"),
|
|
213
|
+
("Mar/2026", ["done", "inprogress", "backlog", "backlog"], "8.4k"),
|
|
214
|
+
],
|
|
215
|
+
stages=["Download Áudio", "Transcrição", "Carga LakeHouse", "Validação"],
|
|
216
|
+
banner="Semana 36: Fev/2026 concluído; Mar/2026 em transcrição",
|
|
217
|
+
)
|
|
218
|
+
build_gantt_slide(
|
|
219
|
+
activities=[
|
|
220
|
+
{"name": "Deploy pipeline D-0", "cat": "Pipeline", "start": 1, "end": 1, "prio": "Alta"},
|
|
221
|
+
{"name": "Backlog Mar/2026", "cat": "Backlog", "start": 1, "end": 3, "prio": "Média"},
|
|
222
|
+
{"name": "Contrato ADW", "cat": "Data Core", "start": 2, "end": 3, "prio": "Alta"},
|
|
223
|
+
{"name": "Doc arquitetura v2", "cat": "Documentação", "start": 2, "end": 4, "prio": "Baixa"},
|
|
224
|
+
],
|
|
225
|
+
week_labels=["Set\nS36", "Set\nS37", "Set\nS38", "Set\nS39"],
|
|
226
|
+
)
|
|
227
|
+
build_roam([
|
|
228
|
+
{"theme": "WhisperX", "risk": "Fila GPU saturada no pico", "roam": "M", "impact": "Atraso 1 sem",
|
|
229
|
+
"owner": "HubGPU", "action": "Fila dedicada", "due": "11/09"},
|
|
230
|
+
{"theme": "Data Core", "risk": "Schema ADW sem contrato", "roam": "O", "impact": "Bloqueia carga",
|
|
231
|
+
"owner": "Data Core", "action": "Alinhar contrato", "due": "09/09"},
|
|
232
|
+
])
|
|
233
|
+
build_next_week(
|
|
234
|
+
items=[
|
|
235
|
+
{"what": "Concluir transcrição Mar/2026", "owner": "Squad STT", "due": "11/09"},
|
|
236
|
+
{"what": "Fechar contrato ADW com Data Core", "owner": "Tech Lead", "due": "09/09"},
|
|
237
|
+
{"what": "Revisar doc de arquitetura v2", "owner": "Arquitetura", "due": "12/09"},
|
|
238
|
+
],
|
|
239
|
+
decisions=["Aprovar fila GPU dedicada (custo mensal)", "Definir dono do schema ADW"],
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
out = sys.argv[1] if len(sys.argv) > 1 else os.path.join(os.getcwd(), "out", "Weekly_Status_exemplo.pptx")
|
|
243
|
+
os.makedirs(os.path.dirname(out), exist_ok=True)
|
|
244
|
+
prs.save(out)
|
|
245
|
+
print("Gerado:", out)
|