@caoscompanybr/merlin 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +216 -0
- package/.claude/hooks/README-license-gate.md +45 -0
- package/.claude/hooks/auto-summarize.js +47 -0
- package/.claude/hooks/context-monitor.js +60 -0
- package/.claude/hooks/doc-sync.js +111 -0
- package/.claude/hooks/license-gate.cjs +59 -0
- package/.claude/hooks/session-reset.js +27 -0
- package/.claude/hooks/thoughts-indexer.js +80 -0
- package/.claude/rules/merlin-constitution.md +27 -0
- package/.merlin-core/commands/README.md +19 -0
- package/.merlin-core/commands/founder-mode.md +51 -0
- package/.merlin-core/commands/git/commit.md +35 -0
- package/.merlin-core/commands/git/describe-pr.md +43 -0
- package/.merlin-core/commands/git/safe-commit.md +182 -0
- package/.merlin-core/commands/implementation/implement-plan.md +129 -0
- package/.merlin-core/commands/implementation/oneshot.md +63 -0
- package/.merlin-core/commands/implementation/tdd.md +152 -0
- package/.merlin-core/commands/planning/create-plan.md +184 -0
- package/.merlin-core/commands/planning/iterate-plan.md +45 -0
- package/.merlin-core/commands/planning/validate-plan.md +48 -0
- package/.merlin-core/commands/research/analyze-issue.md +155 -0
- package/.merlin-core/commands/research/research-codebase.md +157 -0
- package/.merlin-core/commands/review/adversarial-review.md +112 -0
- package/.merlin-core/commands/review/check.md +91 -0
- package/.merlin-core/commands/review/debug.md +135 -0
- package/.merlin-core/commands/review/doubts.md +178 -0
- package/.merlin-core/commands/review/engineering-audit.md +87 -0
- package/.merlin-core/commands/review/local-review.md +48 -0
- package/.merlin-core/commands/review/verify-goals.md +83 -0
- package/.merlin-core/commands/session/capture-feedback.md +74 -0
- package/.merlin-core/commands/session/capture-learning.md +155 -0
- package/.merlin-core/commands/session/check-objectives.md +85 -0
- package/.merlin-core/commands/session/conclude.md +125 -0
- package/.merlin-core/commands/session/create-handoff.md +88 -0
- package/.merlin-core/commands/session/create-objective.md +111 -0
- package/.merlin-core/commands/session/create-process.md +105 -0
- package/.merlin-core/commands/session/create-reminder.md +86 -0
- package/.merlin-core/commands/session/fast-start.md +261 -0
- package/.merlin-core/commands/session/recall-learnings.md +79 -0
- package/.merlin-core/commands/session/recall-processes.md +74 -0
- package/.merlin-core/commands/session/resume-handoff.md +51 -0
- package/.merlin-core/commands/session/run-process.md +53 -0
- package/.merlin-core/commands/special/beauty.md +89 -0
- package/.merlin-core/commands/special/common-ground.md +114 -0
- package/.merlin-core/commands/special/elicit.md +98 -0
- package/.merlin-core/commands/special/party.md +66 -0
- package/.merlin-core/commands/special/scrape.md +78 -0
- package/.merlin-core/commands/special/skill-audit.md +128 -0
- package/.merlin-core/commands/special/start-here.md +132 -0
- package/.merlin-core/constitution.md +442 -0
- package/.merlin-core/core/README.md +19 -0
- package/.merlin-core/core/alkimia/README.md +20 -0
- package/.merlin-core/core/alkimia/context/context-tracker.js +209 -0
- package/.merlin-core/core/alkimia/domain/domain-loader.js +215 -0
- package/.merlin-core/core/alkimia/engine.js +284 -0
- package/.merlin-core/core/alkimia/layers/l0-constitution.js +47 -0
- package/.merlin-core/core/alkimia/layers/l1-global.js +58 -0
- package/.merlin-core/core/alkimia/layers/l2-agent.js +58 -0
- package/.merlin-core/core/alkimia/layers/l3-workflow.js +54 -0
- package/.merlin-core/core/alkimia/layers/l4-task.js +45 -0
- package/.merlin-core/core/alkimia/layers/l5-squad.js +161 -0
- package/.merlin-core/core/alkimia/layers/l6-skill.js +520 -0
- package/.merlin-core/core/alkimia/layers/l7-star-command.js +87 -0
- package/.merlin-core/core/alkimia/layers/layer-processor.js +78 -0
- package/.merlin-core/core/alkimia/mandate.js +46 -0
- package/.merlin-core/core/alkimia/memory/doc-sync.js +201 -0
- package/.merlin-core/core/alkimia/memory/document-sharder.js +272 -0
- package/.merlin-core/core/alkimia/memory/git-history-retriever.js +225 -0
- package/.merlin-core/core/alkimia/memory/memory-bridge.js +97 -0
- package/.merlin-core/core/alkimia/memory/session-analyzer.js +400 -0
- package/.merlin-core/core/alkimia/memory/thoughts-indexer.js +477 -0
- package/.merlin-core/core/alkimia/memory/thoughts-provider.js +603 -0
- package/.merlin-core/core/alkimia/output/formatter.js +464 -0
- package/.merlin-core/core/alkimia/security/content-sanitizer.js +140 -0
- package/.merlin-core/core/alkimia/skill-importer.js +440 -0
- package/.merlin-core/core/alkimia/squads/default/.synapse/manifest +17 -0
- package/.merlin-core/core/alkimia/utils/frontmatter.js +321 -0
- package/.merlin-core/core/alkimia/utils/tokens.js +24 -0
- package/.merlin-core/core/approval/README.md +16 -0
- package/.merlin-core/core/approval/approval-engine.js +380 -0
- package/.merlin-core/core/approval/channels/cli-channel.js +50 -0
- package/.merlin-core/core/config/README.md +17 -0
- package/.merlin-core/core/config/config-cache.js +182 -0
- package/.merlin-core/core/config/config-loader.js +279 -0
- package/.merlin-core/core/config/config-resolver.js +411 -0
- package/.merlin-core/core/config/env-interpolator.js +123 -0
- package/.merlin-core/core/config/merge-utils.js +102 -0
- package/.merlin-core/core/config/schemas/core-config.schema.json +41 -0
- package/.merlin-core/core/config/schemas/framework-config.schema.json +24 -0
- package/.merlin-core/core/config/schemas/local-config.schema.json +23 -0
- package/.merlin-core/core/config/schemas/project-config.schema.json +189 -0
- package/.merlin-core/core/docs-consistency.js +140 -0
- package/.merlin-core/core/events/event-bus.js +344 -0
- package/.merlin-core/core/events/hook-handler.js +419 -0
- package/.merlin-core/core/execution/README.md +17 -0
- package/.merlin-core/core/execution/attempt-journal.js +380 -0
- package/.merlin-core/core/execution/autonomous-build-loop.js +637 -0
- package/.merlin-core/core/execution/build-orchestrator.js +296 -0
- package/.merlin-core/core/execution/build-state-manager.js +196 -0
- package/.merlin-core/core/execution/context-injector.js +204 -0
- package/.merlin-core/core/execution/cron-engine.js +247 -0
- package/.merlin-core/core/execution/cron-expression.js +148 -0
- package/.merlin-core/core/execution/env-preflight.js +423 -0
- package/.merlin-core/core/execution/guardrail-engine.js +745 -0
- package/.merlin-core/core/execution/heartbeat-engine.js +198 -0
- package/.merlin-core/core/execution/model-router.js +282 -0
- package/.merlin-core/core/execution/parallel-executor.js +378 -0
- package/.merlin-core/core/execution/parallel-monitor.js +201 -0
- package/.merlin-core/core/execution/party-session.js +311 -0
- package/.merlin-core/core/execution/rate-limit-manager.js +152 -0
- package/.merlin-core/core/execution/result-aggregator.js +215 -0
- package/.merlin-core/core/execution/semantic-merge-engine.js +320 -0
- package/.merlin-core/core/execution/subagent-dispatcher.js +721 -0
- package/.merlin-core/core/execution/success-verifier.js +227 -0
- package/.merlin-core/core/execution/task-metadata.js +105 -0
- package/.merlin-core/core/execution/team-executor.js +195 -0
- package/.merlin-core/core/execution/two-tier-editor.js +290 -0
- package/.merlin-core/core/execution/version-snapshot.js +294 -0
- package/.merlin-core/core/execution/wave-executor.js +224 -0
- package/.merlin-core/core/health-check/health-engine.js +415 -0
- package/.merlin-core/core/licensing/activation.js +281 -0
- package/.merlin-core/core/licensing/crc.js +103 -0
- package/.merlin-core/core/licensing/entitlement.js +99 -0
- package/.merlin-core/core/licensing/fingerprint.js +104 -0
- package/.merlin-core/core/licensing/gate.js +133 -0
- package/.merlin-core/core/licensing/hmac.js +42 -0
- package/.merlin-core/core/licensing/key.js +144 -0
- package/.merlin-core/core/licensing/license.js +212 -0
- package/.merlin-core/core/mcp/README.md +16 -0
- package/.merlin-core/core/mcp/browser-capability.js +191 -0
- package/.merlin-core/core/mcp/capability-mapper.js +92 -0
- package/.merlin-core/core/mcp/mcp-connector.js +278 -0
- package/.merlin-core/core/mcp/mcp-registry.js +101 -0
- package/.merlin-core/core/orchestration/README.md +17 -0
- package/.merlin-core/core/orchestration/agent-invoker.js +456 -0
- package/.merlin-core/core/orchestration/condition-evaluator.js +250 -0
- package/.merlin-core/core/orchestration/decision-tree.js +192 -0
- package/.merlin-core/core/orchestration/executor-assignment.js +372 -0
- package/.merlin-core/core/orchestration/gate-evaluator.js +653 -0
- package/.merlin-core/core/orchestration/intent-classifier.js +579 -0
- package/.merlin-core/core/orchestration/lock-manager.js +308 -0
- package/.merlin-core/core/orchestration/master-orchestrator.js +363 -0
- package/.merlin-core/core/orchestration/phase-tool-masks.js +194 -0
- package/.merlin-core/core/orchestration/recovery-handler.js +402 -0
- package/.merlin-core/core/orchestration/reflect-checkpoint.js +431 -0
- package/.merlin-core/core/orchestration/session-state.js +430 -0
- package/.merlin-core/core/orchestration/skill-dispatcher.js +255 -0
- package/.merlin-core/core/orchestration/step-loader.js +226 -0
- package/.merlin-core/core/orchestration/workflow-executor.js +864 -0
- package/.merlin-core/core/process/executor.js +231 -0
- package/.merlin-core/core/process/process-file.js +50 -0
- package/.merlin-core/core/process/secret-scan.js +86 -0
- package/.merlin-core/core/process/signature.js +77 -0
- package/.merlin-core/core/quality-gates/README.md +17 -0
- package/.merlin-core/core/quality-gates/layer1-precommit.js +110 -0
- package/.merlin-core/core/quality-gates/layer2-pr-automation.js +116 -0
- package/.merlin-core/core/quality-gates/layer3-human-review.js +133 -0
- package/.merlin-core/core/registry/service-registry.js +140 -0
- package/.merlin-core/core-config.yaml +159 -0
- package/.merlin-core/development/README.md +17 -0
- package/.merlin-core/development/agents/README.md +16 -0
- package/.merlin-core/development/agents/analyst.md +214 -0
- package/.merlin-core/development/agents/architect.md +166 -0
- package/.merlin-core/development/agents/data-engineer.md +154 -0
- package/.merlin-core/development/agents/dev.md +203 -0
- package/.merlin-core/development/agents/devops.md +236 -0
- package/.merlin-core/development/agents/grimorio.md +125 -0
- package/.merlin-core/development/agents/merlin-master.md +173 -0
- package/.merlin-core/development/agents/meta.md +190 -0
- package/.merlin-core/development/agents/pm.md +145 -0
- package/.merlin-core/development/agents/po.md +172 -0
- package/.merlin-core/development/agents/qa.md +275 -0
- package/.merlin-core/development/agents/researcher.md +218 -0
- package/.merlin-core/development/agents/scout.md +179 -0
- package/.merlin-core/development/agents/sm.md +148 -0
- package/.merlin-core/development/agents/ux.md +169 -0
- package/.merlin-core/development/agents/web-researcher.md +203 -0
- package/.merlin-core/development/checklists/adversarial-review-checklist.md +70 -0
- package/.merlin-core/development/checklists/operations-ci-checklist.md +40 -0
- package/.merlin-core/development/checklists/operations-deploy-checklist.md +54 -0
- package/.merlin-core/development/checklists/operations-publish-checklist.md +47 -0
- package/.merlin-core/development/checklists/source-verification-checklist.md +38 -0
- package/.merlin-core/development/templates/HEARTBEAT-template.md +46 -0
- package/.merlin-core/development/templates/ears-requirements-template.md +93 -0
- package/.merlin-core/development/templates/handoff-template.md +50 -0
- package/.merlin-core/development/templates/prd-template.md +62 -0
- package/.merlin-core/development/templates/research-template.md +53 -0
- package/.merlin-core/development/templates/spec-template.md +84 -0
- package/.merlin-core/development/workflows/brownfield-discovery.yaml +166 -0
- package/.merlin-core/development/workflows/brownfield-service.yaml +52 -0
- package/.merlin-core/development/workflows/development-cycle.yaml +57 -0
- package/.merlin-core/development/workflows/epic-orchestration.yaml +47 -0
- package/.merlin-core/development/workflows/folloni-funnel.yaml +177 -0
- package/.merlin-core/development/workflows/greenfield-fullstack.yaml +167 -0
- package/.merlin-core/development/workflows/greenfield-service.yaml +56 -0
- package/.merlin-core/development/workflows/qa-loop.yaml +115 -0
- package/.merlin-core/development/workflows/spec-pipeline.yaml +185 -0
- package/.merlin-core/development/workflows/steps/folloni-01-research.yaml +35 -0
- package/.merlin-core/development/workflows/steps/folloni-02-architecture.yaml +41 -0
- package/.merlin-core/development/workflows/steps/folloni-03-implementation.yaml +52 -0
- package/.merlin-core/development/workflows/story-development-cycle.yaml +67 -0
- package/.merlin-core/docs/GUIDE.md +413 -0
- package/.merlin-core/docs/merlin-commands-guide-pt.md +183 -0
- package/.merlin-core/framework-config.yaml +148 -0
- package/.merlin-core/hooks/README.md +16 -0
- package/.merlin-core/hooks/precompact-memory-flush.js +69 -0
- package/.merlin-core/hooks/pretooluse-remote-approve.js +113 -0
- package/.merlin-core/hooks/spikes/spike-b-hook.js +70 -0
- package/.merlin-core/hooks/spikes/spike-b-stub.js +70 -0
- package/.merlin-core/index.js +91 -0
- package/.merlin-core/local-config.yaml.template +31 -0
- package/.merlin-core/mcp-servers/lsp-bridge/index.js +397 -0
- package/.merlin-core/modules/scraping/module.json +23 -0
- package/.merlin-core/project-config.yaml +89 -0
- package/.merlin-core/schemas/README.md +18 -0
- package/.merlin-core/schemas/agent-hook-schema.json +152 -0
- package/.merlin-core/schemas/agent-schema.json +31 -0
- package/.merlin-core/schemas/command-schema.json +18 -0
- package/.merlin-core/schemas/feedback-schema.json +36 -0
- package/.merlin-core/schemas/handoff-schema.json +19 -0
- package/.merlin-core/schemas/learning-schema.json +51 -0
- package/.merlin-core/schemas/module.schema.json +124 -0
- package/.merlin-core/schemas/must-haves-schema.json +95 -0
- package/.merlin-core/schemas/objective-schema.json +23 -0
- package/.merlin-core/schemas/plan-schema.json +20 -0
- package/.merlin-core/schemas/process-schema.json +82 -0
- package/.merlin-core/schemas/reminder-schema.json +20 -0
- package/.merlin-core/schemas/skill-eval-schema.json +92 -0
- package/.merlin-core/schemas/skill-schema.json +77 -0
- package/.merlin-core/schemas/workflow-schema.json +38 -0
- package/.merlin-core/skills/README.md +16 -0
- package/.merlin-core/skills/domain/azure-cloud/SKILL.md +211 -0
- package/.merlin-core/skills/domain/azure-cloud/references/appinsights-instrumentation.md +63 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-compliance.md +99 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-cost-optimization.md +419 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-deploy.md +82 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-diagnostics.md +130 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-prepare.md +134 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-quotas.md +290 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-rbac.md +11 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-resource-lookup.md +97 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-resource-visualizer.md +178 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-storage.md +91 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-validate.md +58 -0
- package/.merlin-core/skills/domain/azure-cloud/references/entra-app-registration.md +192 -0
- package/.merlin-core/skills/domain/browser-automation/SKILL.md +311 -0
- package/.merlin-core/skills/domain/browser-automation/references/agent-browser-skill.md +632 -0
- package/.merlin-core/skills/domain/browser-automation/references/authentication.md +308 -0
- package/.merlin-core/skills/domain/browser-automation/references/commands.md +266 -0
- package/.merlin-core/skills/domain/browser-automation/references/profiling.md +120 -0
- package/.merlin-core/skills/domain/browser-automation/references/proxy-support.md +194 -0
- package/.merlin-core/skills/domain/browser-automation/references/session-management.md +194 -0
- package/.merlin-core/skills/domain/browser-automation/references/snapshot-refs.md +196 -0
- package/.merlin-core/skills/domain/browser-automation/references/video-recording.md +173 -0
- package/.merlin-core/skills/domain/browser-automation/templates/authenticated-session.sh +105 -0
- package/.merlin-core/skills/domain/browser-automation/templates/capture-workflow.sh +69 -0
- package/.merlin-core/skills/domain/browser-automation/templates/form-automation.sh +62 -0
- package/.merlin-core/skills/domain/digital-marketing/SKILL.md +292 -0
- package/.merlin-core/skills/domain/digital-marketing/references/content-strategy.md +320 -0
- package/.merlin-core/skills/domain/digital-marketing/references/copy-formats.md +298 -0
- package/.merlin-core/skills/domain/digital-marketing/references/copy-methodology.md +180 -0
- package/.merlin-core/skills/domain/digital-marketing/references/email-sequences.md +135 -0
- package/.merlin-core/skills/domain/digital-marketing/references/launch-strategy.md +213 -0
- package/.merlin-core/skills/domain/digital-marketing/references/pricing-strategy.md +160 -0
- package/.merlin-core/skills/domain/digital-marketing/references/programmatic-seo.md +237 -0
- package/.merlin-core/skills/domain/digital-marketing/references/revops-lifecycle.md +170 -0
- package/.merlin-core/skills/domain/digital-marketing/references/revops-operations.md +167 -0
- package/.merlin-core/skills/domain/digital-marketing/references/schema-markup.md +190 -0
- package/.merlin-core/skills/domain/digital-marketing/references/strategy-frameworks.md +324 -0
- package/.merlin-core/skills/domain/digital-marketing/references/traffic-management.md +350 -0
- package/.merlin-core/skills/domain/expo-native-ui/SKILL.md +348 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/animations.md +220 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/api-routes.md +361 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/cicd-workflows.md +84 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/controls.md +266 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/data-fetching.md +553 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/deployment-stores.md +1353 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/deployment.md +183 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/dev-client.md +166 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/dom-components.md +410 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/form-sheet.md +253 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/gradients.md +117 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/icons.md +218 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/media.md +245 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/platform-native.md +75 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/route-structure.md +229 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/search.md +249 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/storage.md +121 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/tabs.md +433 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/tailwind-native.md +473 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/toolbar-and-headers.md +284 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/upgrading-guides.md +674 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/upgrading.md +127 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/visual-effects.md +199 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/webgpu-three.md +605 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/zoom-transitions.md +161 -0
- package/.merlin-core/skills/domain/marketing-ops/SKILL.md +117 -0
- package/.merlin-core/skills/domain/marketing-ops/references/_index.md +78 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative/references/generative-tools.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative/references/platform-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative.md +251 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/ad-copy-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/audience-targeting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/conversion-tracking.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/platform-setup-checklists.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads.md +322 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/content-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/content-types.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/platform-ranking-factors.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo.md +388 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/apple-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/benchmarks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/google-play-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/report-template.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/scoring-criteria.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso.md +316 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/co-marketing.md +305 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/community-marketing.md +169 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling/references/templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling/references/tool-reference.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling.md +442 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors/references/content-architecture.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors/references/templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors.md +281 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/content-strategy.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/directory-list.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/positioning-variations.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/submission-tracker-template.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions.md +396 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/free-tools/references/tool-types.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/free-tools.md +196 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/image/references/ai-image-prompting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/image.md +352 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/launch.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets/references/benchmarks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets/references/format-guide.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets.md +333 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/programmatic-seo.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/schema.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit/references/ai-writing-detection.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit/references/international-seo.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit.md +546 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/mermaid-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/navigation-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/site-type-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture.md +371 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/platform-limits.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/platforms.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/post-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/reverse-engineering.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/short-form-video.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social.md +431 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/video/references/ai-video-prompting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/video.md +353 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing/references/sample-size-guide.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing/references/test-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing.md +379 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/event-library.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/ga4-implementation.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/gtm-implementation.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics.md +323 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/copy-editing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/copywriting.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro/references/form.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro.md +211 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/emails.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/paywalls/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/paywalls.md +255 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/popups.md +518 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/pricing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/deck-frameworks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/demo-scripts.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/objection-library.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/one-pager-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement.md +371 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/signup.md +406 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/co-marketing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/community-marketing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals/references/affiliate-programs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals/references/program-examples.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals.md +278 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/customer-research/references/source-guides.md +425 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/customer-research.md +284 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-ideas/references/ideas-by-category.md +216 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-ideas.md +188 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-psychology.md +532 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/product-marketing.md +276 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention/references/cancel-flow-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention/references/dunning-playbook.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention.md +442 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/onboarding/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/onboarding.md +243 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/revops-lifecycle.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/revops-operations.md +18 -0
- package/.merlin-core/skills/domain/n8n-automation/SKILL.md +149 -0
- package/.merlin-core/skills/domain/n8n-automation/references/code-javascript.md +3744 -0
- package/.merlin-core/skills/domain/n8n-automation/references/code-python.md +3293 -0
- package/.merlin-core/skills/domain/n8n-automation/references/expression-syntax.md +1662 -0
- package/.merlin-core/skills/domain/n8n-automation/references/mcp-tools-expert.md +2111 -0
- package/.merlin-core/skills/domain/n8n-automation/references/node-configuration.md +2523 -0
- package/.merlin-core/skills/domain/n8n-automation/references/validation-expert.md +2491 -0
- package/.merlin-core/skills/domain/n8n-automation/references/workflow-patterns.md +4624 -0
- package/.merlin-core/skills/domain/ops-manual/SKILL.md +225 -0
- package/.merlin-core/skills/domain/ops-manual/references/elicitation-questions.md +141 -0
- package/.merlin-core/skills/domain/ops-manual/references/external-skills-registry.md +63 -0
- package/.merlin-core/skills/domain/ops-manual/references/operations-template.yaml +132 -0
- package/.merlin-core/skills/domain/remotion-best-practices/SKILL.md +99 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/3d.md +86 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/animations.md +27 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets.md +78 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/audio.md +172 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/calculate-metadata.md +131 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/can-decode.md +75 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/charts.md +68 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/compositions.md +154 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/display-captions.md +126 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/extract-frames.md +229 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/fonts.md +152 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/gifs.md +144 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/images.md +134 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/lottie.md +70 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/maps.md +414 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/measuring-text.md +143 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/parameters.md +109 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/sequencing.md +118 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/tailwind.md +11 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/text-animations.md +20 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/timing.md +179 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transitions.md +137 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/trimming.md +51 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/videos.md +171 -0
- package/.merlin-core/skills/domain/resend-email/SKILL.md +377 -0
- package/.merlin-core/skills/general/adversarial-review/SKILL.md +144 -0
- package/.merlin-core/skills/general/api-design/SKILL.md +513 -0
- package/.merlin-core/skills/general/apify-scrape/SKILL.md +137 -0
- package/.merlin-core/skills/general/apify-scrape/scripts/apify-scrape.sh +68 -0
- package/.merlin-core/skills/general/backup/SKILL.md +87 -0
- package/.merlin-core/skills/general/blkskrn/SKILL.md +392 -0
- package/.merlin-core/skills/general/blkskrn/references/animation-patterns.md +521 -0
- package/.merlin-core/skills/general/blkskrn/references/design-system.md +637 -0
- package/.merlin-core/skills/general/blkskrn/references/html-templates.md +440 -0
- package/.merlin-core/skills/general/blkskrn/references/presenter-template.md +45 -0
- package/.merlin-core/skills/general/blkskrn/references/slide-types.md +424 -0
- package/.merlin-core/skills/general/blkskrn/scripts/canvas-manager.js +502 -0
- package/.merlin-core/skills/general/blkskrn/scripts/presenter.js +90 -0
- package/.merlin-core/skills/general/blkskrn/templates/presenter.html +273 -0
- package/.merlin-core/skills/general/blkskrn/templates/slide-base.html +277 -0
- package/.merlin-core/skills/general/blkskrn/templates/viewer.html +165 -0
- package/.merlin-core/skills/general/browser-takeover/SKILL.md +53 -0
- package/.merlin-core/skills/general/claude-api/SKILL.md +90 -0
- package/.merlin-core/skills/general/code-javascript/SKILL.md +268 -0
- package/.merlin-core/skills/general/code-python/SKILL.md +424 -0
- package/.merlin-core/skills/general/code-style/SKILL.md +97 -0
- package/.merlin-core/skills/general/code-typescript/SKILL.md +361 -0
- package/.merlin-core/skills/general/cold-email/SKILL.md +164 -0
- package/.merlin-core/skills/general/cold-email/references/benchmarks.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/follow-up-sequences.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/frameworks.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/personalization.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/subject-lines.md +18 -0
- package/.merlin-core/skills/general/container-security/SKILL.md +462 -0
- package/.merlin-core/skills/general/context-management/SKILL.md +79 -0
- package/.merlin-core/skills/general/copy-editing/SKILL.md +501 -0
- package/.merlin-core/skills/general/copy-editing/references/checklist.md +18 -0
- package/.merlin-core/skills/general/copy-editing/references/content-refresh.md +18 -0
- package/.merlin-core/skills/general/copy-editing/references/plain-english-alternatives.md +18 -0
- package/.merlin-core/skills/general/copywriting/SKILL.md +294 -0
- package/.merlin-core/skills/general/copywriting/references/copy-frameworks.md +392 -0
- package/.merlin-core/skills/general/copywriting/references/natural-transitions.md +276 -0
- package/.merlin-core/skills/general/database/SKILL.md +561 -0
- package/.merlin-core/skills/general/database/references/postgres-concurrency.md +182 -0
- package/.merlin-core/skills/general/database/references/postgres-connections.md +97 -0
- package/.merlin-core/skills/general/database/references/postgres-data-patterns.md +159 -0
- package/.merlin-core/skills/general/database/references/postgres-monitoring.md +136 -0
- package/.merlin-core/skills/general/database/references/postgres-rls.md +140 -0
- package/.merlin-core/skills/general/database-provision/SKILL.md +56 -0
- package/.merlin-core/skills/general/deploy/SKILL.md +65 -0
- package/.merlin-core/skills/general/design-inspiration/SKILL.md +146 -0
- package/.merlin-core/skills/general/design-palette/SKILL.md +99 -0
- package/.merlin-core/skills/general/design-palette/references/full-palettes.md +144 -0
- package/.merlin-core/skills/general/design-system/SKILL.md +94 -0
- package/.merlin-core/skills/general/design-typography/SKILL.md +115 -0
- package/.merlin-core/skills/general/design-typography/references/full-pairings.md +144 -0
- package/.merlin-core/skills/general/design-ux-patterns/SKILL.md +155 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/charts-data-guidelines.md +197 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/landing-patterns.md +199 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/professional-ui-checklist.md +56 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/style-catalog.md +89 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/ux-guidelines.md +837 -0
- package/.merlin-core/skills/general/discover-cloud/SKILL.md +108 -0
- package/.merlin-core/skills/general/doc-sync/SKILL.md +52 -0
- package/.merlin-core/skills/general/document-sharding/SKILL.md +53 -0
- package/.merlin-core/skills/general/docx/SKILL.md +418 -0
- package/.merlin-core/skills/general/docx/references/windows-setup.md +27 -0
- package/.merlin-core/skills/general/docx/scripts/__init__.py +1 -0
- package/.merlin-core/skills/general/docx/scripts/accept_changes.py +135 -0
- package/.merlin-core/skills/general/docx/scripts/comment.py +318 -0
- package/.merlin-core/skills/general/docx/scripts/office/__init__.py +0 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/__init__.py +0 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/.merlin-core/skills/general/docx/scripts/office/pack.py +159 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.merlin-core/skills/general/docx/scripts/office/soffice.py +183 -0
- package/.merlin-core/skills/general/docx/scripts/office/unpack.py +132 -0
- package/.merlin-core/skills/general/docx/scripts/office/validate.py +111 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/__init__.py +15 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/base.py +847 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/docx.py +446 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/pptx.py +275 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/redlining.py +247 -0
- package/.merlin-core/skills/general/docx/scripts/templates/comments.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsExtended.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsIds.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/people.xml +3 -0
- package/.merlin-core/skills/general/elicitation/SKILL.md +188 -0
- package/.merlin-core/skills/general/engineering-audit/SKILL.md +122 -0
- package/.merlin-core/skills/general/find-and-edit/SKILL.md +102 -0
- package/.merlin-core/skills/general/first-party-docs/SKILL.md +51 -0
- package/.merlin-core/skills/general/frontend-design/SKILL.md +204 -0
- package/.merlin-core/skills/general/guardrails/SKILL.md +144 -0
- package/.merlin-core/skills/general/image-gen/SKILL.md +49 -0
- package/.merlin-core/skills/general/learning-capture/SKILL.md +192 -0
- package/.merlin-core/skills/general/lgpd-compliance-audit/SKILL.md +448 -0
- package/.merlin-core/skills/general/load-testing/SKILL.md +114 -0
- package/.merlin-core/skills/general/load-testing/docker/Dockerfile.dashboard +21 -0
- package/.merlin-core/skills/general/load-testing/docker/docker-compose.locust.yml +39 -0
- package/.merlin-core/skills/general/load-testing/requirements.txt +1 -0
- package/.merlin-core/skills/general/load-testing/scripts/compare_baseline.py +172 -0
- package/.merlin-core/skills/general/load-testing/scripts/run_local.py +245 -0
- package/.merlin-core/skills/general/load-testing/templates/load_shape_stepped.py +35 -0
- package/.merlin-core/skills/general/load-testing/templates/locustfile_dashboard.py +47 -0
- package/.merlin-core/skills/general/load-testing/templates/threshold_hook.py +36 -0
- package/.merlin-core/skills/general/mage-beauty/SKILL.md +89 -0
- package/.merlin-core/skills/general/mage-beauty/references/anti-patterns.md +148 -0
- package/.merlin-core/skills/general/mage-beauty/references/color-and-contrast.md +87 -0
- package/.merlin-core/skills/general/mage-beauty/references/interaction-design.md +99 -0
- package/.merlin-core/skills/general/mage-beauty/references/motion-design.md +90 -0
- package/.merlin-core/skills/general/mage-beauty/references/remotion-bridge.md +187 -0
- package/.merlin-core/skills/general/mage-beauty/references/responsive-and-multi-format.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/spatial-design.md +88 -0
- package/.merlin-core/skills/general/mage-beauty/references/typography.md +60 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-adapt.md +102 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-animate.md +97 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-audit.md +99 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-bolder.md +94 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-cinematic.md +128 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-clarify.md +107 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-colorize.md +106 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-critique.md +88 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-delight.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-distill.md +97 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-harden.md +79 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-layout.md +104 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-onboard.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-optimize.md +124 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-overdrive.md +105 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-polish.md +91 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-quieter.md +95 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-rebrand.md +127 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-shape.md +160 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-typeset.md +109 -0
- package/.merlin-core/skills/general/mage-beauty/references/voice-and-microcopy.md +137 -0
- package/.merlin-core/skills/general/mcp-builder/SKILL.md +92 -0
- package/.merlin-core/skills/general/network-debug/SKILL.md +51 -0
- package/.merlin-core/skills/general/next-best-practices/SKILL.md +177 -0
- package/.merlin-core/skills/general/next-best-practices/references/async-patterns.md +87 -0
- package/.merlin-core/skills/general/next-best-practices/references/bundling.md +182 -0
- package/.merlin-core/skills/general/next-best-practices/references/data-patterns.md +306 -0
- package/.merlin-core/skills/general/next-best-practices/references/debug-tricks.md +125 -0
- package/.merlin-core/skills/general/next-best-practices/references/directives.md +74 -0
- package/.merlin-core/skills/general/next-best-practices/references/error-handling.md +232 -0
- package/.merlin-core/skills/general/next-best-practices/references/file-conventions.md +141 -0
- package/.merlin-core/skills/general/next-best-practices/references/font.md +257 -0
- package/.merlin-core/skills/general/next-best-practices/references/functions.md +108 -0
- package/.merlin-core/skills/general/next-best-practices/references/hydration-error.md +88 -0
- package/.merlin-core/skills/general/next-best-practices/references/image.md +179 -0
- package/.merlin-core/skills/general/next-best-practices/references/metadata.md +296 -0
- package/.merlin-core/skills/general/next-best-practices/references/parallel-routes.md +298 -0
- package/.merlin-core/skills/general/next-best-practices/references/route-handlers.md +146 -0
- package/.merlin-core/skills/general/next-best-practices/references/rsc-boundaries.md +164 -0
- package/.merlin-core/skills/general/next-best-practices/references/runtime-selection.md +40 -0
- package/.merlin-core/skills/general/next-best-practices/references/scripts.md +141 -0
- package/.merlin-core/skills/general/next-best-practices/references/self-hosting.md +384 -0
- package/.merlin-core/skills/general/next-best-practices/references/suspense-boundaries.md +67 -0
- package/.merlin-core/skills/general/next-steps/SKILL.md +43 -0
- package/.merlin-core/skills/general/party-mode/SKILL.md +57 -0
- package/.merlin-core/skills/general/pdf/SKILL.md +298 -0
- package/.merlin-core/skills/general/pdf/references/forms.md +312 -0
- package/.merlin-core/skills/general/pdf/references/reference.md +640 -0
- package/.merlin-core/skills/general/pdf/references/windows-setup.md +40 -0
- package/.merlin-core/skills/general/pdf/scripts/check_bounding_boxes.py +65 -0
- package/.merlin-core/skills/general/pdf/scripts/check_fillable_fields.py +11 -0
- package/.merlin-core/skills/general/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/.merlin-core/skills/general/pdf/scripts/create_validation_image.py +37 -0
- package/.merlin-core/skills/general/pdf/scripts/extract_form_field_info.py +122 -0
- package/.merlin-core/skills/general/pdf/scripts/extract_form_structure.py +115 -0
- package/.merlin-core/skills/general/pdf/scripts/fill_fillable_fields.py +98 -0
- package/.merlin-core/skills/general/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/.merlin-core/skills/general/pptx/SKILL.md +133 -0
- package/.merlin-core/skills/general/pptx/references/editing.md +213 -0
- package/.merlin-core/skills/general/pptx/references/pptxgenjs.md +581 -0
- package/.merlin-core/skills/general/pptx/references/windows-setup.md +27 -0
- package/.merlin-core/skills/general/pptx/scripts/__init__.py +0 -0
- package/.merlin-core/skills/general/pptx/scripts/add_slide.py +195 -0
- package/.merlin-core/skills/general/pptx/scripts/clean.py +286 -0
- package/.merlin-core/skills/general/pptx/scripts/thumbnail.py +289 -0
- package/.merlin-core/skills/general/property-testing/SKILL.md +214 -0
- package/.merlin-core/skills/general/purge-leaked-secret/SKILL.md +383 -0
- package/.merlin-core/skills/general/reflection/SKILL.md +100 -0
- package/.merlin-core/skills/general/secret-safe-commit/SKILL.md +246 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/.gitleaks.toml +91 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/.pre-commit-config.yaml +57 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/secret-scan.yml +48 -0
- package/.merlin-core/skills/general/semantic-search/SKILL.md +79 -0
- package/.merlin-core/skills/general/skill-creator/SKILL.md +342 -0
- package/.merlin-core/skills/general/skill-creator/agents/analyzer.md +283 -0
- package/.merlin-core/skills/general/skill-creator/agents/comparator.md +211 -0
- package/.merlin-core/skills/general/skill-creator/agents/grader.md +227 -0
- package/.merlin-core/skills/general/skill-creator/assets/eval_review.html +146 -0
- package/.merlin-core/skills/general/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.merlin-core/skills/general/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.merlin-core/skills/general/skill-creator/references/schemas.md +439 -0
- package/.merlin-core/skills/general/skill-creator/scripts/__init__.py +0 -0
- package/.merlin-core/skills/general/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.merlin-core/skills/general/skill-creator/scripts/generate_report.py +326 -0
- package/.merlin-core/skills/general/skill-creator/scripts/improve_description.py +247 -0
- package/.merlin-core/skills/general/skill-creator/scripts/package_skill.py +136 -0
- package/.merlin-core/skills/general/skill-creator/scripts/quick_validate.py +103 -0
- package/.merlin-core/skills/general/skill-creator/scripts/run_eval.py +310 -0
- package/.merlin-core/skills/general/skill-creator/scripts/run_loop.py +328 -0
- package/.merlin-core/skills/general/skill-creator/scripts/utils.py +47 -0
- package/.merlin-core/skills/general/start-here/SKILL.md +63 -0
- package/.merlin-core/skills/general/start-here/recipes.json +758 -0
- package/.merlin-core/skills/general/start-here/recipes.schema.json +57 -0
- package/.merlin-core/skills/general/static-analysis/SKILL.md +151 -0
- package/.merlin-core/skills/general/tailwind-design-system/SKILL.md +201 -0
- package/.merlin-core/skills/general/tailwind-design-system/references/advanced-v4.md +152 -0
- package/.merlin-core/skills/general/tailwind-design-system/references/component-patterns.md +353 -0
- package/.merlin-core/skills/general/teach-method/SKILL.md +86 -0
- package/.merlin-core/skills/general/team-execution/SKILL.md +67 -0
- package/.merlin-core/skills/general/testing/SKILL.md +412 -0
- package/.merlin-core/skills/general/token-economy/SKILL.md +55 -0
- package/.merlin-core/skills/general/vps-security-hardening/SKILL.md +406 -0
- package/.merlin-core/skills/general/web-quality/SKILL.md +180 -0
- package/.merlin-core/skills/general/webapp-testing/SKILL.md +153 -0
- package/.merlin-core/skills/general/webapp-testing/scripts/screenshot_compare.py +72 -0
- package/.merlin-core/skills/general/webapp-testing/scripts/with_server.py +103 -0
- package/.merlin-core/skills/general/xlsx/SKILL.md +167 -0
- package/.merlin-core/skills/general/xlsx/references/nodejs-sheetjs-styled-reports.md +141 -0
- package/.merlin-core/skills/general/xlsx/references/windows-setup.md +17 -0
- package/.merlin-core/skills/general/xlsx/scripts/recalc.py +184 -0
- package/.merlin-core/skills/general/xlsx/scripts/styled-report.js +130 -0
- package/.merlin-core/skills/general/yolo-mode/SKILL.md +60 -0
- package/.merlin-core/skills/general/youtube-transcript/SKILL.md +177 -0
- package/.merlin-core/skills/general/youtube-transcript/scripts/fetch_transcript.py +188 -0
- package/.merlin-core/skills/general/youtube-transcript/scripts/gladia_transcribe.mjs +230 -0
- package/.merlin-core/tools/commands/activate.js +72 -0
- package/.merlin-core/tools/commands/archive-thoughts.js +181 -0
- package/.merlin-core/tools/commands/backup.js +156 -0
- package/.merlin-core/tools/commands/certify-process.js +196 -0
- package/.merlin-core/tools/commands/convert.js +87 -0
- package/.merlin-core/tools/commands/cron.js +147 -0
- package/.merlin-core/tools/commands/disable.js +73 -0
- package/.merlin-core/tools/commands/doc-sync.js +127 -0
- package/.merlin-core/tools/commands/eval-skill.js +193 -0
- package/.merlin-core/tools/commands/frontmatter.js +49 -0
- package/.merlin-core/tools/commands/heartbeat.js +43 -0
- package/.merlin-core/tools/commands/index-thoughts.js +35 -0
- package/.merlin-core/tools/commands/install-remote-approve.js +184 -0
- package/.merlin-core/tools/commands/install.js +81 -0
- package/.merlin-core/tools/commands/lib/__verify__/diff-reports.js +170 -0
- package/.merlin-core/tools/commands/lib/fs-safe.js +186 -0
- package/.merlin-core/tools/commands/lib/preflight.js +607 -0
- package/.merlin-core/tools/commands/lib/preserve.js +232 -0
- package/.merlin-core/tools/commands/lib/project-config.template.yaml +69 -0
- package/.merlin-core/tools/commands/lib/report.js +231 -0
- package/.merlin-core/tools/commands/lib/settings-merge.js +134 -0
- package/.merlin-core/tools/commands/license.js +52 -0
- package/.merlin-core/tools/commands/list.js +125 -0
- package/.merlin-core/tools/commands/migrate-alkimia.js +271 -0
- package/.merlin-core/tools/commands/modules.js +68 -0
- package/.merlin-core/tools/commands/provision.js +83 -0
- package/.merlin-core/tools/commands/prune-feedback.js +114 -0
- package/.merlin-core/tools/commands/run-process.js +28 -0
- package/.merlin-core/tools/commands/state.js +79 -0
- package/.merlin-core/tools/commands/sync-bridges.js +197 -0
- package/.merlin-core/tools/commands/upgrade.js +1135 -0
- package/.merlin-core/tools/commands/validate-recipes.js +218 -0
- package/.merlin-core/tools/commands/validate.js +159 -0
- package/.merlin-core/tools/commands/yolo.js +82 -0
- package/.merlin-core/tools/compose-rules.mjs +179 -0
- package/.merlin-core/tools/disable-module.mjs +150 -0
- package/.merlin-core/tools/lib/deployer.mjs +131 -0
- package/.merlin-core/tools/lib/modules-activation.mjs +225 -0
- package/.merlin-core/tools/merlin-tools.js +153 -0
- package/.merlin-core/tools/migrate-frontmatter-v3.js +192 -0
- package/.merlin-core/tools/modules-catalog.mjs +174 -0
- package/.merlin-core/tools/provision-module.mjs +191 -0
- package/.merlin-core/tools/verify-module.mjs +99 -0
- package/.merlin-core/tools/vps-security-audit.sh +234 -0
- package/INSTALL.md +312 -0
- package/LICENSE +118 -0
- package/PRIVACY-LICENSING.md +65 -0
- package/README.md +391 -0
- package/bin/README.md +15 -0
- package/bin/convert-to-merlin.sh +109 -0
- package/bin/fleet-patch-hooks.sh +144 -0
- package/bin/fleet-patch-v3-fixes.sh +127 -0
- package/bin/merlin-init.js +232 -0
- package/bin/merlin.js +321 -0
- package/package.json +127 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webapp-testing
|
|
3
|
+
description: Browser-based testing for web applications using Playwright. Supports screenshot verification, DOM inspection, console log capture, and automated UI testing. Integrates with QA agent visual verification protocol.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility: Requires Python 3.8+ and playwright package. Install with 'pip install playwright && playwright install chromium'.
|
|
6
|
+
metadata:
|
|
7
|
+
author: merlin-framework
|
|
8
|
+
version: "3.0.0"
|
|
9
|
+
based-on: anthropics/skills/webapp-testing
|
|
10
|
+
auto_activate: [playwright, e2e-test, browser-test, visual-test, smoke-test]
|
|
11
|
+
file_triggers:
|
|
12
|
+
["*.spec.ts", "*.spec.js", "*.test.ts", "*.test.js", "*.e2e.ts", "*.e2e.js"]
|
|
13
|
+
tool_reminders:
|
|
14
|
+
[
|
|
15
|
+
Always wait for networkidle before inspecting dynamic pages,
|
|
16
|
+
Use reconnaissance-then-action pattern: screenshot → identify selectors → execute,
|
|
17
|
+
Browser tests require MEDIUM approval — confirm with user before running,
|
|
18
|
+
Always close browser when done — resource leak prevention,
|
|
19
|
+
]
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Webapp Testing with Playwright
|
|
23
|
+
|
|
24
|
+
Browser-based testing skill for verifying web application behavior through screenshots, DOM inspection, console logs, and automated UI interaction.
|
|
25
|
+
|
|
26
|
+
## Decision Tree: When to Use What
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Is the application a static HTML file?
|
|
30
|
+
YES → Open directly with Playwright, no server needed
|
|
31
|
+
NO → Is a dev server already running?
|
|
32
|
+
YES → Connect to existing server URL
|
|
33
|
+
NO → Use with_server.py to manage server lifecycle
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Server Lifecycle Management
|
|
37
|
+
|
|
38
|
+
For applications that need a dev server, use the `with_server.py` script to manage startup/shutdown:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Start server, run test, stop server
|
|
42
|
+
python .merlin-core/skills/general/webapp-testing/scripts/with_server.py \
|
|
43
|
+
--cmd "npm run dev" \
|
|
44
|
+
--port 3000 \
|
|
45
|
+
--timeout 30 \
|
|
46
|
+
-- python test_script.py
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The script:
|
|
50
|
+
|
|
51
|
+
1. Starts the dev server in the background
|
|
52
|
+
2. Waits for the port to become available
|
|
53
|
+
3. Runs your test command
|
|
54
|
+
4. Stops the server on completion (or error)
|
|
55
|
+
|
|
56
|
+
## Reconnaissance-Then-Action Pattern
|
|
57
|
+
|
|
58
|
+
NEVER interact with a page blindly. Always follow this sequence:
|
|
59
|
+
|
|
60
|
+
1. **Screenshot first** — Capture the current state before any interaction
|
|
61
|
+
2. **Identify selectors** — Use DOM inspection to find correct selectors
|
|
62
|
+
3. **Execute action** — Click, type, navigate using verified selectors
|
|
63
|
+
4. **Verify result** — Screenshot again to confirm the expected outcome
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from playwright.sync_api import sync_playwright
|
|
67
|
+
|
|
68
|
+
with sync_playwright() as p:
|
|
69
|
+
browser = p.chromium.launch()
|
|
70
|
+
page = browser.new_page()
|
|
71
|
+
page.goto("http://localhost:3000")
|
|
72
|
+
|
|
73
|
+
# 1. Reconnaissance
|
|
74
|
+
page.wait_for_load_state("networkidle")
|
|
75
|
+
page.screenshot(path="before.png")
|
|
76
|
+
|
|
77
|
+
# 2. Identify (inspect DOM if needed)
|
|
78
|
+
button = page.locator("button:has-text('Submit')")
|
|
79
|
+
|
|
80
|
+
# 3. Execute
|
|
81
|
+
button.click()
|
|
82
|
+
page.wait_for_load_state("networkidle")
|
|
83
|
+
|
|
84
|
+
# 4. Verify
|
|
85
|
+
page.screenshot(path="after.png")
|
|
86
|
+
assert page.locator(".success-message").is_visible()
|
|
87
|
+
|
|
88
|
+
browser.close()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Responsive Testing
|
|
92
|
+
|
|
93
|
+
Always test at three viewport widths:
|
|
94
|
+
|
|
95
|
+
| Viewport | Width | Use Case |
|
|
96
|
+
| -------- | ------ | ------------------- |
|
|
97
|
+
| Mobile | 640px | Phone screens |
|
|
98
|
+
| Tablet | 1024px | Tablet/small laptop |
|
|
99
|
+
| Desktop | 1440px | Standard desktop |
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
for width in [640, 1024, 1440]:
|
|
103
|
+
page.set_viewport_size({"width": width, "height": 900})
|
|
104
|
+
page.screenshot(path=f"viewport-{width}.png")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Console Log Capture
|
|
108
|
+
|
|
109
|
+
Capture and analyze console output for errors and warnings:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
console_messages = []
|
|
113
|
+
page.on("console", lambda msg: console_messages.append({
|
|
114
|
+
"type": msg.type,
|
|
115
|
+
"text": msg.text,
|
|
116
|
+
"location": msg.location
|
|
117
|
+
}))
|
|
118
|
+
|
|
119
|
+
# After interactions, check for errors
|
|
120
|
+
errors = [m for m in console_messages if m["type"] == "error"]
|
|
121
|
+
warnings = [m for m in console_messages if m["type"] == "warning"]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Screenshot Comparison
|
|
125
|
+
|
|
126
|
+
Use `screenshot_compare.py` for visual regression detection:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
python .merlin-core/skills/general/webapp-testing/scripts/screenshot_compare.py \
|
|
130
|
+
--baseline before.png \
|
|
131
|
+
--current after.png \
|
|
132
|
+
--threshold 5.0
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Returns exit code 0 if difference < threshold%, 1 otherwise.
|
|
136
|
+
|
|
137
|
+
## Integration with QA Agent
|
|
138
|
+
|
|
139
|
+
When the QA agent invokes visual verification:
|
|
140
|
+
|
|
141
|
+
1. Capture screenshots at all responsive breakpoints
|
|
142
|
+
2. Check console for errors/warnings
|
|
143
|
+
3. Compare against baseline screenshots if available
|
|
144
|
+
4. Report findings with screenshot paths for human review
|
|
145
|
+
|
|
146
|
+
## Best Practices
|
|
147
|
+
|
|
148
|
+
- **Always use `networkidle`** — Dynamic SPAs need time to settle after navigation
|
|
149
|
+
- **Use text-based selectors** — `page.locator("button:has-text('Submit')")` over CSS class selectors
|
|
150
|
+
- **Set reasonable timeouts** — 30s default, 60s for slow pages
|
|
151
|
+
- **Clean up resources** — Always close browser in finally/cleanup block
|
|
152
|
+
- **Screenshot naming** — Use descriptive names: `{page}-{viewport}-{state}.png`
|
|
153
|
+
- **Headless by default** — Use `headless=True` unless debugging
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Screenshot comparison for visual regression testing.
|
|
4
|
+
|
|
5
|
+
Compares two screenshots and reports the pixel difference percentage.
|
|
6
|
+
Returns exit code 0 if difference is below threshold, 1 otherwise.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python screenshot_compare.py --baseline before.png --current after.png --threshold 5.0
|
|
10
|
+
|
|
11
|
+
Merlin Framework v2.10.0
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from PIL import Image, ImageChops
|
|
19
|
+
HAS_PIL = True
|
|
20
|
+
except ImportError:
|
|
21
|
+
HAS_PIL = False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def compare_images(baseline_path, current_path):
|
|
25
|
+
"""Compare two images and return difference percentage."""
|
|
26
|
+
if not HAS_PIL:
|
|
27
|
+
print("Error: Pillow not installed. Run: pip install Pillow", file=sys.stderr)
|
|
28
|
+
sys.exit(2)
|
|
29
|
+
|
|
30
|
+
baseline = Image.open(baseline_path).convert("RGB")
|
|
31
|
+
current = Image.open(current_path).convert("RGB")
|
|
32
|
+
|
|
33
|
+
# Resize to match if dimensions differ
|
|
34
|
+
if baseline.size != current.size:
|
|
35
|
+
current = current.resize(baseline.size, Image.Resampling.LANCZOS)
|
|
36
|
+
|
|
37
|
+
diff = ImageChops.difference(baseline, current)
|
|
38
|
+
pixels = list(diff.getdata())
|
|
39
|
+
total_pixels = len(pixels)
|
|
40
|
+
|
|
41
|
+
if total_pixels == 0:
|
|
42
|
+
return 0.0
|
|
43
|
+
|
|
44
|
+
# Count pixels with any difference above noise threshold (5/255)
|
|
45
|
+
changed = sum(1 for p in pixels if max(p) > 5)
|
|
46
|
+
return (changed / total_pixels) * 100
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def main():
|
|
50
|
+
parser = argparse.ArgumentParser(description="Compare two screenshots for visual differences.")
|
|
51
|
+
parser.add_argument("--baseline", required=True, help="Path to baseline screenshot")
|
|
52
|
+
parser.add_argument("--current", required=True, help="Path to current screenshot")
|
|
53
|
+
parser.add_argument("--threshold", type=float, default=5.0, help="Max acceptable difference percentage (default: 5.0)")
|
|
54
|
+
parser.add_argument("--output", help="Path to save diff image (optional)")
|
|
55
|
+
|
|
56
|
+
args = parser.parse_args()
|
|
57
|
+
|
|
58
|
+
diff_pct = compare_images(args.baseline, args.current)
|
|
59
|
+
|
|
60
|
+
print(f"Difference: {diff_pct:.2f}%")
|
|
61
|
+
print(f"Threshold: {args.threshold:.2f}%")
|
|
62
|
+
|
|
63
|
+
if diff_pct <= args.threshold:
|
|
64
|
+
print("Result: PASS")
|
|
65
|
+
sys.exit(0)
|
|
66
|
+
else:
|
|
67
|
+
print("Result: FAIL — visual regression detected")
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
main()
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Server lifecycle manager for webapp testing.
|
|
4
|
+
|
|
5
|
+
Starts a development server, waits for it to be ready,
|
|
6
|
+
runs a test command, then stops the server.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python with_server.py --cmd "npm run dev" --port 3000 -- python test.py
|
|
10
|
+
python with_server.py --cmd "python -m http.server 8080" --port 8080 -- pytest tests/
|
|
11
|
+
|
|
12
|
+
Based on Anthropic's webapp-testing skill pattern.
|
|
13
|
+
Merlin Framework v2.10.0
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import subprocess
|
|
18
|
+
import sys
|
|
19
|
+
import time
|
|
20
|
+
import socket
|
|
21
|
+
import signal
|
|
22
|
+
import os
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def wait_for_port(port, host="localhost", timeout=30):
|
|
26
|
+
"""Wait for a port to become available."""
|
|
27
|
+
start = time.time()
|
|
28
|
+
while time.time() - start < timeout:
|
|
29
|
+
try:
|
|
30
|
+
with socket.create_connection((host, port), timeout=1):
|
|
31
|
+
return True
|
|
32
|
+
except (ConnectionRefusedError, OSError):
|
|
33
|
+
time.sleep(0.5)
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
parser = argparse.ArgumentParser(
|
|
39
|
+
description="Start a server, run a command, then stop the server."
|
|
40
|
+
)
|
|
41
|
+
parser.add_argument("--cmd", required=True, help="Server start command")
|
|
42
|
+
parser.add_argument("--port", type=int, required=True, help="Port to wait for")
|
|
43
|
+
parser.add_argument("--host", default="localhost", help="Host to check (default: localhost)")
|
|
44
|
+
parser.add_argument("--timeout", type=int, default=30, help="Startup timeout in seconds")
|
|
45
|
+
parser.add_argument("test_cmd", nargs=argparse.REMAINDER, help="Test command to run after server starts")
|
|
46
|
+
|
|
47
|
+
args = parser.parse_args()
|
|
48
|
+
|
|
49
|
+
# Remove leading '--' separator if present
|
|
50
|
+
test_cmd = args.test_cmd
|
|
51
|
+
if test_cmd and test_cmd[0] == "--":
|
|
52
|
+
test_cmd = test_cmd[1:]
|
|
53
|
+
|
|
54
|
+
if not test_cmd:
|
|
55
|
+
print("Error: No test command provided after '--'", file=sys.stderr)
|
|
56
|
+
sys.exit(1)
|
|
57
|
+
|
|
58
|
+
server_process = None
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
# Start server
|
|
62
|
+
print(f"Starting server: {args.cmd}")
|
|
63
|
+
server_process = subprocess.Popen(
|
|
64
|
+
args.cmd,
|
|
65
|
+
shell=True,
|
|
66
|
+
stdout=subprocess.PIPE,
|
|
67
|
+
stderr=subprocess.PIPE,
|
|
68
|
+
preexec_fn=os.setsid if hasattr(os, "setsid") else None,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Wait for port
|
|
72
|
+
print(f"Waiting for port {args.port} (timeout: {args.timeout}s)...")
|
|
73
|
+
if not wait_for_port(args.port, args.host, args.timeout):
|
|
74
|
+
print(f"Error: Server did not start on port {args.port} within {args.timeout}s", file=sys.stderr)
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
|
|
77
|
+
print(f"Server ready on port {args.port}")
|
|
78
|
+
|
|
79
|
+
# Run test command
|
|
80
|
+
print(f"Running: {' '.join(test_cmd)}")
|
|
81
|
+
result = subprocess.run(test_cmd)
|
|
82
|
+
sys.exit(result.returncode)
|
|
83
|
+
|
|
84
|
+
finally:
|
|
85
|
+
# Stop server
|
|
86
|
+
if server_process and server_process.poll() is None:
|
|
87
|
+
print("Stopping server...")
|
|
88
|
+
try:
|
|
89
|
+
if hasattr(os, "killpg"):
|
|
90
|
+
os.killpg(os.getpgid(server_process.pid), signal.SIGTERM)
|
|
91
|
+
else:
|
|
92
|
+
server_process.terminate()
|
|
93
|
+
server_process.wait(timeout=5)
|
|
94
|
+
except (ProcessLookupError, subprocess.TimeoutExpired):
|
|
95
|
+
if hasattr(os, "killpg"):
|
|
96
|
+
os.killpg(os.getpgid(server_process.pid), signal.SIGKILL)
|
|
97
|
+
else:
|
|
98
|
+
server_process.kill()
|
|
99
|
+
print("Server stopped.")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
main()
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xlsx
|
|
3
|
+
description: "Use this skill any time a spreadsheet file is the primary input or output. This includes opening, reading, editing, or fixing .xlsx/.xlsm/.csv/.tsv files; creating new spreadsheets from scratch or from other data; converting between tabular formats; cleaning messy tabular data; AND generating colored, multi-sheet operational reports from a Node/JS script (Firestore/backend exports) via SheetJS/xlsx-js-style."
|
|
4
|
+
license: MIT (Anthropic)
|
|
5
|
+
compatibility: claude-code
|
|
6
|
+
metadata:
|
|
7
|
+
source: anthropic/skills
|
|
8
|
+
imported: 2026-03-15
|
|
9
|
+
version: "3.1.0"
|
|
10
|
+
windows-setup: See references/windows-setup.md for Windows dependency installation
|
|
11
|
+
auto_activate: [xlsx, spreadsheet, excel, xlsx-js-style, sheetjs, planilha]
|
|
12
|
+
file_triggers: [*.xlsx, *.xlsm, *.csv]
|
|
13
|
+
references:
|
|
14
|
+
- references/nodejs-sheetjs-styled-reports.md (Node/SheetJS colored reports — colors, CSV BOM, sorting, reconciliation sheets, gotchas)
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Excel Spreadsheet Guide
|
|
18
|
+
|
|
19
|
+
## CRITICAL: Use Formulas, Not Hardcoded Values
|
|
20
|
+
|
|
21
|
+
Always use Excel formulas instead of calculating values in Python and hardcoding them. The spreadsheet must remain dynamic and updateable.
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# WRONG - hardcoded
|
|
25
|
+
sheet['B10'] = total
|
|
26
|
+
|
|
27
|
+
# CORRECT - Excel formula
|
|
28
|
+
sheet['B10'] = '=SUM(B2:B9)'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Assumptions placement:** All growth rates, margins, and multiples must be in separate assumption cells referenced in formulas, not hardcoded values.
|
|
32
|
+
|
|
33
|
+
**Documentation:** Hardcoded values require comments with source, date, specific reference, and URL where applicable.
|
|
34
|
+
|
|
35
|
+
## Professional Standards
|
|
36
|
+
|
|
37
|
+
### Font
|
|
38
|
+
|
|
39
|
+
Use a consistent, professional font (Arial, Times New Roman) for all deliverables.
|
|
40
|
+
|
|
41
|
+
### Template Preservation
|
|
42
|
+
|
|
43
|
+
When updating existing files, study and EXACTLY match existing format, style, and conventions rather than imposing standardized formatting.
|
|
44
|
+
|
|
45
|
+
### Zero Formula Errors
|
|
46
|
+
|
|
47
|
+
Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?).
|
|
48
|
+
|
|
49
|
+
### Financial Color Coding (Industry Standard)
|
|
50
|
+
|
|
51
|
+
- **Blue text** (0,0,255): Hardcoded inputs
|
|
52
|
+
- **Black text** (0,0,0): ALL formulas and calculations
|
|
53
|
+
- **Green text** (0,128,0): Links from other worksheets
|
|
54
|
+
- **Red text** (255,0,0): External links to other files
|
|
55
|
+
- **Yellow background** (255,255,0): Key assumptions
|
|
56
|
+
|
|
57
|
+
### Number Formatting
|
|
58
|
+
|
|
59
|
+
- **Years**: Format as text ("2024" not "2,024")
|
|
60
|
+
- **Currency**: Use $#,##0; specify units in headers ("Revenue ($mm)")
|
|
61
|
+
- **Zeros**: Format as "-"
|
|
62
|
+
- **Percentages**: 0.0% format
|
|
63
|
+
- **Negatives**: Use parentheses (123) not -123
|
|
64
|
+
|
|
65
|
+
## Workflows
|
|
66
|
+
|
|
67
|
+
### Reading and Analyzing
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import pandas as pd
|
|
71
|
+
|
|
72
|
+
df = pd.read_excel('file.xlsx')
|
|
73
|
+
all_sheets = pd.read_excel('file.xlsx', sheet_name=None)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Creating New Files
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from openpyxl import Workbook
|
|
80
|
+
from openpyxl.styles import Font, PatternFill, Alignment
|
|
81
|
+
|
|
82
|
+
wb = Workbook()
|
|
83
|
+
sheet = wb.active
|
|
84
|
+
sheet['A1'] = 'Hello'
|
|
85
|
+
sheet['B2'] = '=SUM(A1:A10)'
|
|
86
|
+
sheet['A1'].font = Font(bold=True)
|
|
87
|
+
wb.save('output.xlsx')
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Editing Existing Files
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from openpyxl import load_workbook
|
|
94
|
+
|
|
95
|
+
wb = load_workbook('existing.xlsx')
|
|
96
|
+
sheet = wb.active
|
|
97
|
+
sheet['A1'] = 'New Value'
|
|
98
|
+
wb.save('modified.xlsx')
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Formula Recalculation (MANDATORY)
|
|
102
|
+
|
|
103
|
+
After creating or modifying files with formulas, recalculate to update formula values and verify zero errors:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python scripts/recalc.py output.xlsx
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Alternative using LibreOffice CLI:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
soffice --headless --calc --convert-to xlsx output.xlsx
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Node.js / SheetJS — Styled Operational Reports
|
|
116
|
+
|
|
117
|
+
When the spreadsheet is generated by a **Node/JS** script (Firestore/backend exports, admin CLIs)
|
|
118
|
+
and you need **colored, human-scannable operational reports** (not formula models), use SheetJS.
|
|
119
|
+
Full guide + copy-paste patterns: **`references/nodejs-sheetjs-styled-reports.md`**. Reusable
|
|
120
|
+
helpers: **`scripts/styled-report.js`**. The load-bearing rules:
|
|
121
|
+
|
|
122
|
+
- **The community `xlsx` package cannot write cell colors — it silently drops `cell.s`.** Use the
|
|
123
|
+
drop-in fork **`xlsx-js-style`** (`npm i xlsx-js-style`; `require('xlsx-js-style')`). Same API.
|
|
124
|
+
- `aoa_to_sheet` takes values only; apply styles **after** via `ws[ref].s` (the "paints" pattern).
|
|
125
|
+
Create the cell if missing so the fill renders: `if(!ws[ref]) ws[ref]={t:'s',v:''}`.
|
|
126
|
+
- **Reading styles back needs `XLSX.readFile(path, { cellStyles: true })`**, and the read shape is
|
|
127
|
+
flattened (`cell.s.fgColor.rgb`, not `cell.s.fill.fgColor.rgb`) — dump `JSON.stringify(cell.s)`.
|
|
128
|
+
- **CSV for Excel:** prepend a UTF-8 BOM (`'' + csv`) and quote/escape every cell.
|
|
129
|
+
- **Readability:** IDs in the LAST column, lead with `#1,#2…`; sort completed-by-date, open-by-due-date.
|
|
130
|
+
- **Reconciliation workbook:** detail sheet + correlation MATRIX (rows=A × cols=B = count) + a
|
|
131
|
+
per-entity X-vs-Y-vs-Δ sheet — the human's tool to see "where the numbers went."
|
|
132
|
+
- **Gotchas:** `EBUSY` = the .xlsx is open in Excel/preview (close it); `new Date(y,m,d)` uses the
|
|
133
|
+
machine TZ (set `TZ` or use `Intl.DateTimeFormat(...,{timeZone})` for TZ-correct bucketing).
|
|
134
|
+
|
|
135
|
+
> Color convention: 🟢 green = done/paid · 🔵 blue = open/pending · ⚪ gray = cancelled · slate = sub-headers.
|
|
136
|
+
|
|
137
|
+
## Library Selection
|
|
138
|
+
|
|
139
|
+
- **pandas** (Python): Data analysis, bulk operations, simple export
|
|
140
|
+
- **openpyxl** (Python): Complex formatting, formulas, Excel-specific features
|
|
141
|
+
- **xlsx-js-style** (Node): Colored multi-sheet operational reports from JS/Firestore scripts
|
|
142
|
+
- **exceljs** (Node): Advanced Node needs (streaming huge files, charts, conditional formats)
|
|
143
|
+
|
|
144
|
+
## Formula Verification Checklist
|
|
145
|
+
|
|
146
|
+
- Test 2-3 sample references before building full model
|
|
147
|
+
- Verify Excel columns match (column 64 = BL, not BK)
|
|
148
|
+
- Remember Excel rows are 1-indexed (DataFrame row 5 = Excel row 6)
|
|
149
|
+
- Handle NaN values with `pd.notna()`
|
|
150
|
+
- Check denominators before division
|
|
151
|
+
- Use correct cross-sheet format (Sheet1!A1)
|
|
152
|
+
|
|
153
|
+
## Bundled Scripts
|
|
154
|
+
|
|
155
|
+
| Script | Purpose |
|
|
156
|
+
| -------------------------- | --------------------------------------------------------------------- |
|
|
157
|
+
| `scripts/recalc.py` | Recalculate formulas and verify zero errors |
|
|
158
|
+
| `scripts/styled-report.js` | (Node) Helpers for colored SheetJS reports: PALETTE, painter, CSV+BOM |
|
|
159
|
+
|
|
160
|
+
**Note:** The shared office toolkit (`unpack.py`, `pack.py`, `validate.py`, `soffice.py`) for XML-level operations lives in `../docx/scripts/office/`.
|
|
161
|
+
|
|
162
|
+
## Dependencies
|
|
163
|
+
|
|
164
|
+
- **pandas**: `pip install pandas`
|
|
165
|
+
- **openpyxl**: `pip install openpyxl`
|
|
166
|
+
- **LibreOffice**: Formula recalculation fallback
|
|
167
|
+
- **xlsx-js-style** (Node): `npm install xlsx-js-style` — required for colored cells (the community `xlsx` build silently drops styles)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Node.js / SheetJS — Styled Operational Reports (data → XLSX + CSV)
|
|
2
|
+
|
|
3
|
+
> Companion to the Python/openpyxl guidance in `SKILL.md`. Use **this** path when the
|
|
4
|
+
> spreadsheet is generated by a **Node/JS** script (e.g. exporting from Firebase/Firestore,
|
|
5
|
+
> a backend job, or an admin CLI) and you need **colored, human-readable operational reports**
|
|
6
|
+
> — not formula-driven financial models. Values are computed in code; no live formulas.
|
|
7
|
+
|
|
8
|
+
## Choosing the toolchain
|
|
9
|
+
|
|
10
|
+
| Need | Use |
|
|
11
|
+
| ----------------------------------------------------------------- | ---------------------------------- |
|
|
12
|
+
| Financial model, live formulas, recalc | Python + `openpyxl` (see SKILL.md) |
|
|
13
|
+
| Data dump / operational report from a Node script | `xlsx-js-style` (this guide) |
|
|
14
|
+
| Advanced (streaming huge files, rich charts, conditional formats) | `exceljs` |
|
|
15
|
+
|
|
16
|
+
## ⚠️ The #1 gotcha: community `xlsx` cannot write colors
|
|
17
|
+
|
|
18
|
+
The community **`xlsx`** (SheetJS) package **silently ignores `cell.s` (styles) on write** — you
|
|
19
|
+
get a file with zero formatting and no error. To produce colored headers/fills you MUST use a
|
|
20
|
+
style-capable build:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install xlsx-js-style # drop-in fork: same XLSX.utils API + style support
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
const XLSX = require("xlsx-js-style"); // instead of require('xlsx')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Everything else (`aoa_to_sheet`, `book_append_sheet`, `writeFile`, `encode_cell`) is identical.
|
|
31
|
+
|
|
32
|
+
## The "paints" pattern — coloring `aoa_to_sheet` output
|
|
33
|
+
|
|
34
|
+
`aoa_to_sheet` builds cells from **values only**; it does not accept pre-styled cell objects.
|
|
35
|
+
Apply styles **after**, by setting `ws[ref].s`. Track which cells to paint while you build the
|
|
36
|
+
array (record `data.length - 1` for each header/title row), then paint in one pass:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
const mkStyle = (rgb, sz = 11) => ({
|
|
40
|
+
fill: { patternType: "solid", fgColor: { rgb } }, // rgb = 'RRGGBB' (no '#')
|
|
41
|
+
font: { bold: true, color: { rgb: "FFFFFF" }, sz },
|
|
42
|
+
alignment: { vertical: "center" },
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const data = [];
|
|
46
|
+
const paints = []; // { r, c, style }
|
|
47
|
+
const paintRow = (r, n, style) => {
|
|
48
|
+
for (let c = 0; c < n; c++) paints.push({ r, c, style });
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
data.push(["CONCLUÍDAS (12)"]);
|
|
52
|
+
paints.push({ r: data.length - 1, c: 0, style: mkStyle("1B5E20", 12) });
|
|
53
|
+
data.push(["#", "Título", "Data"]);
|
|
54
|
+
paintRow(data.length - 1, 3, mkStyle("2E7D32"));
|
|
55
|
+
// ...push data rows...
|
|
56
|
+
|
|
57
|
+
const ws = XLSX.utils.aoa_to_sheet(data);
|
|
58
|
+
for (const p of paints) {
|
|
59
|
+
const ref = XLSX.utils.encode_cell({ r: p.r, c: p.c });
|
|
60
|
+
if (!ws[ref]) ws[ref] = { t: "s", v: "" }; // create empty cell so the fill renders
|
|
61
|
+
ws[ref].s = p.style;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Color convention that reads at a glance
|
|
66
|
+
|
|
67
|
+
- 🟢 **green** (`2E7D32` / title `1B5E20`) — done / completed / paid
|
|
68
|
+
- 🔵 **blue** (`1565C0` / title `0D47A1`) — open / in-progress / pending
|
|
69
|
+
- ⚪ **gray** (`78909C` / title `455A64`) — cancelled / neutral
|
|
70
|
+
- **slate** (`37474F`) — sub-headers, breakdowns, totals
|
|
71
|
+
|
|
72
|
+
Distinct section colors are the cheapest way to make a multi-section sheet scannable.
|
|
73
|
+
|
|
74
|
+
## ⚠️ Verifying styles on READ
|
|
75
|
+
|
|
76
|
+
`XLSX.readFile(path)` does **not** parse styles by default → `cell.s` is `undefined` even when the
|
|
77
|
+
file is fully styled. Pass `{ cellStyles: true }`. And note the **read shape differs from the write
|
|
78
|
+
shape**: a fill written as `cell.s.fill.fgColor.rgb` comes back flattened as `cell.s.fgColor.rgb`.
|
|
79
|
+
When verifying, dump the whole object instead of trusting your write-path:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
const wb = XLSX.readFile(path, { cellStyles: true });
|
|
83
|
+
console.log(JSON.stringify(wb.Sheets["Sheet1"]["A1"].s)); // don't assume .s.fill.*
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## CSV that opens cleanly in Excel
|
|
87
|
+
|
|
88
|
+
- Prepend a **UTF-8 BOM** so Excel renders accents: `fs.writeFileSync(p, '' + csv, 'utf8')`.
|
|
89
|
+
- Quote every cell and escape inner quotes: `'"' + String(c).replace(/"/g, '""') + '"'`.
|
|
90
|
+
- Join cells with `,` and rows with `\n`.
|
|
91
|
+
|
|
92
|
+
## Readability patterns for operational reports
|
|
93
|
+
|
|
94
|
+
- **IDs last, friendly index first.** Put opaque IDs (Firestore doc ids, UUIDs) in the _last_
|
|
95
|
+
column; lead with a `#1, #2…` sequence (`` `#${i+1}` ``) so humans scan rows, not hashes.
|
|
96
|
+
- **Sort each section by its meaningful date.** Completed → by completion date (chronological,
|
|
97
|
+
ascending). Open/backlog → by due date ascending (earliest/overdue first; push null dates last
|
|
98
|
+
with `?? Infinity`).
|
|
99
|
+
- **Multi-sheet reconciliation workbook** — a powerful, reusable shape when two views of the same
|
|
100
|
+
data must be cross-checked by a human:
|
|
101
|
+
1. `DETAIL` — one row per item, flat, with all attributes (and a price-/value-ready column).
|
|
102
|
+
2. `MATRIX` — correlation grid: rows = entity A, cols = entity B, cell = count (+ totals row/col).
|
|
103
|
+
This is _the_ tool to answer "where did the numbers go" (e.g. which B handled each A).
|
|
104
|
+
3. `RECONCILIATION` — per entity: metric under model X vs model Y vs Δ, with a one-line note
|
|
105
|
+
explaining what Δ means. Recompute both models in the same script over the same source rows
|
|
106
|
+
so the sheet is self-consistent.
|
|
107
|
+
- **Column widths:** `ws['!cols'] = [{ wch: N }, …]` per column index. When you stack tables with
|
|
108
|
+
_different_ column counts in one sheet, a single `!cols` can't be perfect for all — size for the
|
|
109
|
+
widest/most-used section and accept the compromise.
|
|
110
|
+
|
|
111
|
+
## Operational gotchas
|
|
112
|
+
|
|
113
|
+
- **`EBUSY: resource busy or locked`** on write — Excel (or the Explorer preview pane) holds an
|
|
114
|
+
exclusive lock on the target `.xlsx`. Close the file before re-running. If you must overwrite a
|
|
115
|
+
possibly-open file, write to a temp name then `fs.renameSync`.
|
|
116
|
+
- **Timezone** — `new Date(y, m, d)` uses the **machine's local** timezone. If your date-window
|
|
117
|
+
query must match a dashboard/TV, ensure the machine TZ matches (e.g. `America/Sao_Paulo`) or set
|
|
118
|
+
the `TZ` env var. For TZ-correct day/month bucketing regardless of the host, derive parts with
|
|
119
|
+
`Intl.DateTimeFormat('en-CA', { timeZone: 'America/Sao_Paulo' }).formatToParts(date)`.
|
|
120
|
+
- **Date formatting** — `date.toLocaleDateString('pt-BR')` for BR dates; pass
|
|
121
|
+
`{ timeZone: 'America/Sao_Paulo' }` to keep it deterministic across machines.
|
|
122
|
+
- **Firestore Timestamp → Date** — admin SDK timestamps expose `.toDate()`; serialized ones carry
|
|
123
|
+
`_seconds`. A safe coercion: `f?.toDate?.() ?? (f?._seconds != null ? new Date(f._seconds*1000) : null)`.
|
|
124
|
+
|
|
125
|
+
## Bundled helper
|
|
126
|
+
|
|
127
|
+
`scripts/styled-report.js` (in this skill) exports ready-to-use helpers: `PALETTE`, `mkStyle`,
|
|
128
|
+
`makePainter()`, `applyPaints()`, `toCsvWithBom()`, `toDate()`, `spParts()`. Import it from a Node
|
|
129
|
+
report script to avoid re-deriving the patterns above.
|
|
130
|
+
|
|
131
|
+
## Real-world example
|
|
132
|
+
|
|
133
|
+
An example SaaS monthly team-closing report (Firestore → XLSX/CSV):
|
|
134
|
+
|
|
135
|
+
- `scripts/audit-<month>.js` — dual-credit audit, per-employee sheets, **green CONCLUÍDAS /
|
|
136
|
+
blue EM ABERTO** section headers, `#n` index, Task ID last, date-sorted sections.
|
|
137
|
+
- `scripts/fechamento-<month>.js` — single-payee "folha" + `FO_BO_MATRIZ` correlation sheet +
|
|
138
|
+
`RECONCILIACAO` (dual vs single vs Δ).
|
|
139
|
+
Deps: `firebase-admin`, `xlsx-js-style`. These are concrete, working implementations of every
|
|
140
|
+
pattern in this guide.
|
|
141
|
+
</content>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Windows Setup for XLSX Tools
|
|
2
|
+
|
|
3
|
+
## Python
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install pandas openpyxl
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## System Dependencies
|
|
10
|
+
|
|
11
|
+
### LibreOffice (formula recalculation)
|
|
12
|
+
|
|
13
|
+
1. Download from: https://www.libreoffice.org/download/
|
|
14
|
+
2. Install to default location
|
|
15
|
+
3. Verify: `soffice --version`
|
|
16
|
+
|
|
17
|
+
LibreOffice is required for the `scripts/recalc.py` formula recalculation step.
|