@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,406 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vps-security-hardening
|
|
3
|
+
description: Canonical 7-step VPS security hardening protocol — SSH key auth, ufw firewall, fail2ban, password rotation, recovery doc. Apply to EVERY new VPS before exposing services to the internet.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: merlin-framework
|
|
7
|
+
version: "3.0.0"
|
|
8
|
+
auto_activate:
|
|
9
|
+
[vps-hardening, vps-setup, ssh-hardening, ufw, fail2ban, ssh-brute-force]
|
|
10
|
+
tool_reminders:
|
|
11
|
+
[
|
|
12
|
+
Disabling password auth requires HIGH approval — verify key auth works FIRST,
|
|
13
|
+
Enabling ufw requires whitelist port 22 BEFORE enabling — order matters,
|
|
14
|
+
sshd config changes require `sshd -t` validation BEFORE reload,
|
|
15
|
+
Use `systemctl reload ssh` (not restart) to preserve current session,
|
|
16
|
+
Recovery doc with private key MUST be encrypted before leaving disk,
|
|
17
|
+
Old credentials in committed scripts are dead after rotation but should be purged anyway,
|
|
18
|
+
]
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# VPS Security Hardening Skill
|
|
22
|
+
|
|
23
|
+
**Mission:** Every VPS that touches the public internet on behalf of a Merlin
|
|
24
|
+
project goes through this 7-step protocol BEFORE production traffic. No
|
|
25
|
+
exceptions. This skill exists because the cost of forgetting once is total
|
|
26
|
+
compromise; the cost of running through the checklist is 30 minutes.
|
|
27
|
+
|
|
28
|
+
The protocol was forged on 2026-04-27 during a real VPS security audit, where a
|
|
29
|
+
production server was found with `PermitRootLogin yes` + `PasswordAuthentication
|
|
30
|
+
yes` + no firewall + no fail2ban while receiving 626 SSH brute-force attempts
|
|
31
|
+
per day. None succeeded, but the exposure was unacceptable. This skill
|
|
32
|
+
codifies the fix so future-us never has to rediscover it.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## When to invoke this skill
|
|
37
|
+
|
|
38
|
+
**Always run on:**
|
|
39
|
+
|
|
40
|
+
- A freshly provisioned VPS, before any service is exposed
|
|
41
|
+
- An inherited VPS where security posture is unknown
|
|
42
|
+
- After the user mentions "I just got a new VPS / droplet / server"
|
|
43
|
+
- When auditing an existing server (run as a comparison checklist)
|
|
44
|
+
|
|
45
|
+
**Pre-flight signals you need this skill NOW:**
|
|
46
|
+
|
|
47
|
+
- `ufw status` returns "inactive"
|
|
48
|
+
- `crontab -l` shows no entries (no fail2ban triggers, no automation)
|
|
49
|
+
- `grep PasswordAuthentication /etc/ssh/sshd_config*/*.conf` shows `yes`
|
|
50
|
+
- `cat /root/.ssh/authorized_keys` is empty
|
|
51
|
+
- `which fail2ban-client` returns nothing
|
|
52
|
+
- `journalctl _SYSTEMD_UNIT=ssh.service --since '1 day ago' | grep -c 'Failed password'` returns >50
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## The 7-Step Canonical Protocol
|
|
57
|
+
|
|
58
|
+
Execute IN ORDER. Each step must succeed before the next. Each step is
|
|
59
|
+
independently verifiable and reversible if you stop early.
|
|
60
|
+
|
|
61
|
+
### Step 1 — Install local SSH public key on VPS (no destructive change)
|
|
62
|
+
|
|
63
|
+
Use the existing dev machine SSH key (or generate one with `ssh-keygen -t ed25519`).
|
|
64
|
+
Append public key to `/root/.ssh/authorized_keys` via password auth (still enabled
|
|
65
|
+
at this stage).
|
|
66
|
+
|
|
67
|
+
**Idempotency:** Always grep the fingerprint first; only append if absent.
|
|
68
|
+
**Verification:** Connect with key-only auth (`allow_agent=False, look_for_keys=False`)
|
|
69
|
+
in a separate session before proceeding.
|
|
70
|
+
|
|
71
|
+
### Step 2 — Verify key auth works END-TO-END
|
|
72
|
+
|
|
73
|
+
Open a NEW SSH connection using ONLY the key (refuse password fallback). If it
|
|
74
|
+
fails, stop and debug. Common causes:
|
|
75
|
+
|
|
76
|
+
- `~/.ssh/authorized_keys` permissions wrong (must be 600, owned by root)
|
|
77
|
+
- `~/.ssh/` directory permissions wrong (must be 700)
|
|
78
|
+
- SELinux contexts (rare on Ubuntu, common on RHEL)
|
|
79
|
+
|
|
80
|
+
**DO NOT proceed to step 3 until this is green.**
|
|
81
|
+
|
|
82
|
+
### Step 3 — Install + configure `fail2ban`
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
|
86
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq fail2ban
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Write `/etc/fail2ban/jail.local`:
|
|
90
|
+
|
|
91
|
+
```ini
|
|
92
|
+
[DEFAULT]
|
|
93
|
+
bantime = 1h
|
|
94
|
+
findtime = 10m
|
|
95
|
+
maxretry = 5
|
|
96
|
+
ignoreip = 127.0.0.1/8 ::1 <DEV_HOME_IP>
|
|
97
|
+
backend = systemd
|
|
98
|
+
|
|
99
|
+
[sshd]
|
|
100
|
+
enabled = true
|
|
101
|
+
port = ssh
|
|
102
|
+
filter = sshd
|
|
103
|
+
maxretry = 5
|
|
104
|
+
findtime = 10m
|
|
105
|
+
bantime = 1h
|
|
106
|
+
# Ubuntu 24.04 uses ssh.service, NOT sshd.service — see Gotcha #1
|
|
107
|
+
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Then `systemctl enable fail2ban && systemctl restart fail2ban`.
|
|
111
|
+
|
|
112
|
+
**Verification:** `fail2ban-client status sshd` shows the journal match line
|
|
113
|
+
ending in `_SYSTEMD_UNIT=ssh.service`.
|
|
114
|
+
|
|
115
|
+
### Step 4 — Enable `ufw` with strict whitelist
|
|
116
|
+
|
|
117
|
+
**ORDER IS LIFE-OR-DEATH:** add allow rules BEFORE enabling. If you enable
|
|
118
|
+
first, you lose access immediately.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ufw default deny incoming
|
|
122
|
+
ufw default allow outgoing
|
|
123
|
+
ufw allow 22/tcp comment 'SSH'
|
|
124
|
+
ufw allow 80/tcp comment 'HTTP'
|
|
125
|
+
ufw allow 443/tcp comment 'HTTPS'
|
|
126
|
+
# Add only the ports your services actually need:
|
|
127
|
+
# ufw allow 5432/tcp comment 'PostgreSQL'
|
|
128
|
+
# ufw allow 8000/tcp comment 'App'
|
|
129
|
+
# ufw allow 9000/tcp comment 'Portainer'
|
|
130
|
+
ufw --force enable
|
|
131
|
+
ufw status verbose
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Verification:** Open a NEW SSH session through the firewall. The existing
|
|
135
|
+
session is unaffected (ufw only governs new connections).
|
|
136
|
+
|
|
137
|
+
### Step 5 — Disable password auth + restrict root to key-only
|
|
138
|
+
|
|
139
|
+
Write `/etc/ssh/sshd_config.d/99-<project>-hardening.conf`:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
PasswordAuthentication no
|
|
143
|
+
PubkeyAuthentication yes
|
|
144
|
+
PermitRootLogin prohibit-password
|
|
145
|
+
PermitEmptyPasswords no
|
|
146
|
+
ChallengeResponseAuthentication no
|
|
147
|
+
KbdInteractiveAuthentication no
|
|
148
|
+
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
|
|
149
|
+
MaxAuthTries 3
|
|
150
|
+
MaxSessions 5
|
|
151
|
+
LoginGraceTime 30s
|
|
152
|
+
ClientAliveInterval 300
|
|
153
|
+
ClientAliveCountMax 2
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Critical sub-step:** Cloud images often ship `/etc/ssh/sshd_config.d/50-cloud-init.conf`
|
|
157
|
+
with `PasswordAuthentication yes`. Higher number drop-in (`99-*`) overrides
|
|
158
|
+
lexically, BUT some sshd versions read in alphabetical order and stop at first
|
|
159
|
+
match. **Neutralize the cloud-init line:**
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
sed -i 's/^PasswordAuthentication yes/#PasswordAuthentication yes # neutralized by hardening/' \
|
|
163
|
+
/etc/ssh/sshd_config.d/50-cloud-init.conf
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Validate config syntax BEFORE reload (NEVER skip this):**
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
sshd -t || { echo "CONFIG ERROR — DO NOT RELOAD"; exit 1; }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Reload (NOT restart) — keeps current session alive:**
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
systemctl reload ssh
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Verify config is live:**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
sshd -T | grep -iE '^(passwordauth|permitroot|kbdinter)'
|
|
182
|
+
# Expected:
|
|
183
|
+
# passwordauthentication no
|
|
184
|
+
# permitrootlogin without-password (this is the canonical form of prohibit-password)
|
|
185
|
+
# kbdinteractiveauthentication no
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**TWO-PART VERIFICATION:**
|
|
189
|
+
|
|
190
|
+
1. NEW session via key — must succeed
|
|
191
|
+
2. Connection attempt with password — must FAIL with `paramiko.AuthenticationException`
|
|
192
|
+
|
|
193
|
+
If part 2 succeeds (password still works), the hardening did not take effect —
|
|
194
|
+
roll back via the existing session and debug.
|
|
195
|
+
|
|
196
|
+
### Step 6 — Rotate root password (defense in depth)
|
|
197
|
+
|
|
198
|
+
Even with password auth disabled, rotate the password because:
|
|
199
|
+
|
|
200
|
+
- Console access via cloud provider panel still uses it
|
|
201
|
+
- Old password may exist in committed scripts / shell history / leaked logs
|
|
202
|
+
- Defense-in-depth — if password auth gets re-enabled by accident, the old
|
|
203
|
+
one is dead
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
import secrets, string
|
|
207
|
+
alphabet = string.ascii_letters + string.digits + '!@#%^*-_=+'
|
|
208
|
+
new_password = ''.join(secrets.choice(alphabet) for _ in range(32))
|
|
209
|
+
# Apply via: echo "root:NEW_PW" | chpasswd
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Save the new password in:**
|
|
213
|
+
|
|
214
|
+
1. Project password manager (1Password, Bitwarden, KeePass) — primary
|
|
215
|
+
2. Encrypted recovery USB (see Step 7) — secondary
|
|
216
|
+
|
|
217
|
+
### Step 7 — Generate offline recovery kit
|
|
218
|
+
|
|
219
|
+
Create a self-contained markdown file with:
|
|
220
|
+
|
|
221
|
+
- New root password (post-rotation)
|
|
222
|
+
- SSH private key (full text, copy-pasteable)
|
|
223
|
+
- SSH public key
|
|
224
|
+
- Recovery scenarios (lost laptop, lost USB, panel inaccessible)
|
|
225
|
+
- Date stamp + project name + VPS IP
|
|
226
|
+
|
|
227
|
+
**Storage requirements:**
|
|
228
|
+
|
|
229
|
+
- BitLocker-encrypted USB (Windows native) OR VeraCrypt container OR hardware-encrypted USB
|
|
230
|
+
- Physical safe / vault for the encrypted USB
|
|
231
|
+
- **A SECOND copy in a geographically different location** (more important than encryption — protects against fire, theft, USB hardware failure)
|
|
232
|
+
|
|
233
|
+
**Acceptable shortcut:** plaintext file on USB inside a real safe (NOT a R$200
|
|
234
|
+
fire safe) is defensible for small-business threat models, but encryption
|
|
235
|
+
costs 5 minutes and survives safe compromise.
|
|
236
|
+
|
|
237
|
+
**Unacceptable:** Google Drive, Dropbox, email, WhatsApp, repo (even private),
|
|
238
|
+
unencrypted USB outside a safe, password manager note (those are designed for
|
|
239
|
+
short secrets, not multi-line keys).
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Critical Gotchas (the hard-won knowledge)
|
|
244
|
+
|
|
245
|
+
### Gotcha #1 — Ubuntu 24.04 systemd unit is `ssh.service`, NOT `sshd.service`
|
|
246
|
+
|
|
247
|
+
Default fail2ban filter expects `_SYSTEMD_UNIT=sshd.service`. On Ubuntu 24.04
|
|
248
|
+
the unit is `ssh.service` (the binary is `sshd`, but systemd registers `ssh`).
|
|
249
|
+
Without explicit `journalmatch` override, fail2ban will sit at "Total failed:
|
|
250
|
+
0" forever while attacks continue.
|
|
251
|
+
|
|
252
|
+
**Detection:** `systemctl status sshd` returns "Unit sshd.service could not be found"
|
|
253
|
+
but `systemctl status ssh` works.
|
|
254
|
+
|
|
255
|
+
**Fix:** explicit `journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd` in
|
|
256
|
+
jail.local (see Step 3 template).
|
|
257
|
+
|
|
258
|
+
### Gotcha #2 — `cloud-init` ships `PasswordAuthentication yes` in a drop-in
|
|
259
|
+
|
|
260
|
+
Cloud provider images (Hostinger, DigitalOcean, AWS, Azure, GCP) install
|
|
261
|
+
`/etc/ssh/sshd_config.d/50-cloud-init.conf` with password auth ENABLED. Even
|
|
262
|
+
if your hardening drop-in says `no`, sshd may read 50- before 99- depending
|
|
263
|
+
on version. Always neutralize the cloud-init directive directly.
|
|
264
|
+
|
|
265
|
+
### Gotcha #3 — `systemctl restart ssh` kills your session; `reload` doesn't
|
|
266
|
+
|
|
267
|
+
`restart` terminates all current SSH sessions including yours. If the new
|
|
268
|
+
config has a syntax error you didn't catch, you're locked out. **Always use
|
|
269
|
+
`reload`** — current sessions live until they disconnect, new connections use
|
|
270
|
+
new config. Combined with `sshd -t` validation before reload, this gives you
|
|
271
|
+
a safe atomic upgrade.
|
|
272
|
+
|
|
273
|
+
### Gotcha #4 — `ufw enable` BEFORE `ufw allow 22` = locked out instantly
|
|
274
|
+
|
|
275
|
+
Default policy is `deny incoming`. If you enable before adding the SSH allow
|
|
276
|
+
rule, your current session continues (existing connections unaffected) but
|
|
277
|
+
you cannot reconnect. Always `ufw allow 22/tcp` first, then `ufw enable`.
|
|
278
|
+
|
|
279
|
+
### Gotcha #5 — `paramiko.connect()` fingerprint cache (`known_hosts`)
|
|
280
|
+
|
|
281
|
+
After enabling key auth, paramiko on Windows may cache the host key in
|
|
282
|
+
`~/.ssh/known_hosts`. If the VPS host key changes (rebuild, OS reinstall),
|
|
283
|
+
paramiko refuses to connect with `MissingHostKeyPolicy=RejectPolicy`. Use
|
|
284
|
+
`AutoAddPolicy()` for dev tooling, but be aware it disables MITM detection.
|
|
285
|
+
|
|
286
|
+
### Gotcha #6 — `Postgres on 0.0.0.0:5432` is required if Cloud Functions need it
|
|
287
|
+
|
|
288
|
+
If the project uses Firebase Functions / AWS Lambda / Vercel that connect to
|
|
289
|
+
the VPS Postgres directly, you cannot bind Postgres to 127.0.0.1. The
|
|
290
|
+
mitigation is strong Postgres auth + IP allowlist in `pg_hba.conf` for the
|
|
291
|
+
provider's egress IP range. Don't try to "fix" this exposure without
|
|
292
|
+
understanding the dependency.
|
|
293
|
+
|
|
294
|
+
### Gotcha #7 — Hardcoded passwords in committed scripts survive git history
|
|
295
|
+
|
|
296
|
+
Even after rotating the root password, the OLD password remains in
|
|
297
|
+
`git log -p` forever (unless you `git-filter-repo`, which is overkill for
|
|
298
|
+
already-rotated credentials). The damage is done — anyone who cloned the repo
|
|
299
|
+
when the password was live has it. Rotation invalidates that exposure but does
|
|
300
|
+
not "undo" the leak. **Conclusion: never put passwords in scripts in the first
|
|
301
|
+
place. Use env vars, password managers, or SSH keys.**
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Tooling — Reusable Scripts
|
|
306
|
+
|
|
307
|
+
A reference project (`/path/to/project/scripts/`) has battle-tested
|
|
308
|
+
implementations of all 7 steps using paramiko. When applying this skill to a
|
|
309
|
+
new VPS, copy and adapt:
|
|
310
|
+
|
|
311
|
+
| Script | Purpose |
|
|
312
|
+
| ------------------------- | ---------------------------------------------------------------------- |
|
|
313
|
+
| `_vps_ssh.py` | Helper: `connect()` returns paramiko SSHClient via key auth |
|
|
314
|
+
| `vps_install_ssh_key.py` | Step 1-2 (one-shot bootstrap; reads VPS_PASSWORD from env) |
|
|
315
|
+
| `vps_install_fail2ban.py` | Step 3 (idempotent install + config + verify) |
|
|
316
|
+
| `vps_enable_ufw.py` | Step 4 (whitelist-first ordering) |
|
|
317
|
+
| `vps_harden_sshd.py` | Step 5 (backup + drop-in + sshd -t + reload + verify) |
|
|
318
|
+
| `vps_full_audit.py` | Health check: containers, DB, certs, backups, ports |
|
|
319
|
+
| `vps_security_check.py` | Compromise indicator scan: successful logins, UID 0 users, hidden cron |
|
|
320
|
+
|
|
321
|
+
When provisioning a new VPS for any Merlin project: clone these into the new
|
|
322
|
+
project's `scripts/` dir, edit `_vps_ssh.py` with the new IP/host, and run the
|
|
323
|
+
sequence.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Recovery Doc Template
|
|
328
|
+
|
|
329
|
+
For Step 7, generate a markdown file with this skeleton:
|
|
330
|
+
|
|
331
|
+
```markdown
|
|
332
|
+
# 🔐 <PROJECT> VPS — KIT DE RECUPERAÇÃO DE EMERGÊNCIA
|
|
333
|
+
|
|
334
|
+
**Gerado:** YYYY-MM-DD
|
|
335
|
+
**Servidor:** <IP> (<provider>)
|
|
336
|
+
**Domínio:** <domain>
|
|
337
|
+
|
|
338
|
+
## 1. Senha root (apenas console emergencial — SSH password disabled)
|
|
339
|
+
|
|
340
|
+
<rotated_password>
|
|
341
|
+
|
|
342
|
+
## 2. Chave privada SSH (Ed25519)
|
|
343
|
+
|
|
344
|
+
**Fingerprint:** SHA256:...
|
|
345
|
+
-----BEGIN OPENSSH PRIVATE KEY-----
|
|
346
|
+
<content>
|
|
347
|
+
-----END OPENSSH PRIVATE KEY-----
|
|
348
|
+
|
|
349
|
+
## 3. Chave pública (instalada em /root/.ssh/authorized_keys)
|
|
350
|
+
|
|
351
|
+
ssh-ed25519 AAAA... user@host
|
|
352
|
+
|
|
353
|
+
## 4. Cenários de recuperação
|
|
354
|
+
|
|
355
|
+
A. Perdi o PC mas tenho USB → copiar conteúdo das seções 2-3 para ~/.ssh/
|
|
356
|
+
B. Perdi PC + USB → console do provedor + senha da seção 1 + nova chave
|
|
357
|
+
C. Provedor inacessível → suporte do provedor para reset out-of-band
|
|
358
|
+
D. Adicionar 2ª chave de backup → SSH normal + echo >> authorized_keys
|
|
359
|
+
|
|
360
|
+
## 5. Configuração aplicada (referência)
|
|
361
|
+
|
|
362
|
+
- PasswordAuthentication: no
|
|
363
|
+
- PermitRootLogin: prohibit-password
|
|
364
|
+
- ufw: active (allow <ports>)
|
|
365
|
+
- fail2ban: active (5 fails / 10min = 1h ban)
|
|
366
|
+
- Backup do sshd config em: /etc/ssh/sshd_config.bak.YYYYMMDD
|
|
367
|
+
|
|
368
|
+
## 6. Compromisso de manutenção
|
|
369
|
+
|
|
370
|
+
- Atualizar este doc ao rotacionar credenciais
|
|
371
|
+
- Rotação anual recomendada
|
|
372
|
+
- Manter cópia em ≥2 locais físicos diferentes
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Threat Model — what this skill defends against
|
|
378
|
+
|
|
379
|
+
| Threat | Defense | Residual risk |
|
|
380
|
+
| --------------------------------------- | ----------------------------------- | --------------------------------------------- |
|
|
381
|
+
| SSH brute-force (automated bots) | fail2ban + key-only auth | Effectively zero |
|
|
382
|
+
| Stolen password from leaked script | Password auth disabled + rotated | Zero (password is non-functional for SSH) |
|
|
383
|
+
| Targeted attack with stolen private key | Hardware-encrypted USB + safe | Low — requires physical access to safe |
|
|
384
|
+
| Cloud provider panel compromise | None at this layer | High — accept or use 2FA on provider account |
|
|
385
|
+
| Postgres direct attack on 5432 | Provider firewall + Postgres auth | Medium — depends on app passwords |
|
|
386
|
+
| Insider with prior root password | Rotation invalidates | Zero post-rotation |
|
|
387
|
+
| Lost laptop with private key | USB recovery doc + provider console | Low — accept brief downtime to rebuild access |
|
|
388
|
+
| Catastrophic cofre/USB loss | Geographic redundancy (2nd USB) | Accept if not implemented |
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Maintenance cadence
|
|
393
|
+
|
|
394
|
+
- **Quarterly:** verify `ufw status`, `fail2ban-client status sshd`, recent successful SSH logins (`journalctl _SYSTEMD_UNIT=ssh.service --since '90 days ago' | grep Accepted`)
|
|
395
|
+
- **Annually:** rotate SSH key + root password + regenerate recovery doc
|
|
396
|
+
- **On staff change:** rotate immediately + remove old key from authorized_keys + update recovery doc
|
|
397
|
+
- **On VPS rebuild:** re-run Steps 1-7 from scratch on the new instance
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## References
|
|
402
|
+
|
|
403
|
+
- [VPS hardening session research](.merlin-core/thoughts/shared/research/) — 2026-04-27 audit + live hardening
|
|
404
|
+
- [SSH best practices — Mozilla](https://infosec.mozilla.org/guidelines/openssh)
|
|
405
|
+
- [fail2ban systemd backend docs](https://fail2ban.readthedocs.io/)
|
|
406
|
+
- [Ubuntu 24.04 ssh.service vs sshd.service](https://wiki.ubuntu.com/SSH) — gotcha #1 reference
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-quality
|
|
3
|
+
description: Web quality optimization covering Core Web Vitals (LCP, CLS, INP), accessibility (WCAG 2.2), SEO best practices, and performance budgets. Framework-aware for React, Next.js, Vue, and Svelte.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: merlin-framework
|
|
7
|
+
version: "3.0.0"
|
|
8
|
+
inspired-by: AO/web-quality-skills
|
|
9
|
+
auto_activate:
|
|
10
|
+
[lighthouse, core-web-vitals, accessibility, wcag, a11y, page-speed]
|
|
11
|
+
file_triggers: ["*.html", "*.tsx", "*.jsx", "*.vue", "*.svelte"]
|
|
12
|
+
tool_reminders:
|
|
13
|
+
[
|
|
14
|
+
Always check accessibility before visual polish — WCAG 2.2 Level AA minimum,
|
|
15
|
+
Performance budgets: LCP < 2.5s,
|
|
16
|
+
CLS < 0.1,
|
|
17
|
+
INP < 200ms,
|
|
18
|
+
Use Lighthouse CI for automated performance regression detection,
|
|
19
|
+
]
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Web Quality Skills
|
|
23
|
+
|
|
24
|
+
Comprehensive web quality optimization covering performance, accessibility, and SEO.
|
|
25
|
+
|
|
26
|
+
## Core Web Vitals
|
|
27
|
+
|
|
28
|
+
| Metric | Good | Needs Improvement | Poor |
|
|
29
|
+
| ------------------------------- | ------- | ----------------- | ------- |
|
|
30
|
+
| LCP (Largest Contentful Paint) | ≤ 2.5s | ≤ 4.0s | > 4.0s |
|
|
31
|
+
| CLS (Cumulative Layout Shift) | ≤ 0.1 | ≤ 0.25 | > 0.25 |
|
|
32
|
+
| INP (Interaction to Next Paint) | ≤ 200ms | ≤ 500ms | > 500ms |
|
|
33
|
+
|
|
34
|
+
### LCP Optimization
|
|
35
|
+
|
|
36
|
+
- Preload critical resources: `<link rel="preload" as="image" href="hero.webp">`
|
|
37
|
+
- Use responsive images with `srcset` and `sizes`
|
|
38
|
+
- Inline critical CSS, defer non-critical
|
|
39
|
+
- Use `fetchpriority="high"` on LCP element
|
|
40
|
+
- **React**: Use `next/image` or lazy loading for below-fold images
|
|
41
|
+
- **Next.js**: Use `priority` prop on hero images, ISR for dynamic content
|
|
42
|
+
|
|
43
|
+
### CLS Prevention
|
|
44
|
+
|
|
45
|
+
- Always set `width` and `height` on images and videos
|
|
46
|
+
- Use `aspect-ratio` CSS property for responsive containers
|
|
47
|
+
- Reserve space for dynamic content (ads, embeds, lazy-loaded content)
|
|
48
|
+
- Use `font-display: swap` with proper fallback metrics
|
|
49
|
+
- Avoid inserting content above existing content
|
|
50
|
+
|
|
51
|
+
### INP Optimization
|
|
52
|
+
|
|
53
|
+
- Break long tasks with `requestIdleCallback` or `scheduler.yield()`
|
|
54
|
+
- Use `content-visibility: auto` for off-screen content
|
|
55
|
+
- Debounce expensive event handlers (resize, scroll, input)
|
|
56
|
+
- Use `will-change` sparingly for known animations
|
|
57
|
+
- **React**: Use `useDeferredValue` and `useTransition` for non-urgent updates
|
|
58
|
+
|
|
59
|
+
## Accessibility (WCAG 2.2 Level AA)
|
|
60
|
+
|
|
61
|
+
### Semantic HTML Checklist
|
|
62
|
+
|
|
63
|
+
- [ ] Use `<nav>`, `<main>`, `<header>`, `<footer>`, `<aside>` landmarks
|
|
64
|
+
- [ ] Headings follow proper hierarchy (h1 → h2 → h3, no skipping)
|
|
65
|
+
- [ ] Links have descriptive text (no "click here")
|
|
66
|
+
- [ ] Forms have associated `<label>` elements
|
|
67
|
+
- [ ] Tables have `<th>` with `scope` attribute
|
|
68
|
+
- [ ] Lists use `<ul>`, `<ol>`, `<dl>` appropriately
|
|
69
|
+
|
|
70
|
+
### ARIA Guidelines
|
|
71
|
+
|
|
72
|
+
- Use ARIA only when native HTML semantics are insufficient
|
|
73
|
+
- `aria-label` for icon-only buttons
|
|
74
|
+
- `aria-live` regions for dynamic content updates
|
|
75
|
+
- `role="alert"` for error messages
|
|
76
|
+
- `aria-expanded` for collapsible sections
|
|
77
|
+
- Never use `role="presentation"` on focusable elements
|
|
78
|
+
|
|
79
|
+
### Keyboard Navigation
|
|
80
|
+
|
|
81
|
+
- [ ] All interactive elements are focusable
|
|
82
|
+
- [ ] Focus order follows visual order
|
|
83
|
+
- [ ] Focus indicator is visible (min 2px outline, 3:1 contrast)
|
|
84
|
+
- [ ] Escape closes modals and returns focus to trigger
|
|
85
|
+
- [ ] Skip navigation link present
|
|
86
|
+
- [ ] No keyboard traps
|
|
87
|
+
|
|
88
|
+
### Color Contrast
|
|
89
|
+
|
|
90
|
+
- Normal text: minimum 4.5:1 ratio
|
|
91
|
+
- Large text (18pt or 14pt bold): minimum 3:1 ratio
|
|
92
|
+
- UI components and graphical objects: minimum 3:1 ratio
|
|
93
|
+
- Tool: `npx @contrast-checker/cli check "#333" "#fff"`
|
|
94
|
+
|
|
95
|
+
## SEO Checklist
|
|
96
|
+
|
|
97
|
+
### Technical SEO
|
|
98
|
+
|
|
99
|
+
- [ ] Unique `<title>` per page (50-60 characters)
|
|
100
|
+
- [ ] Meta description per page (150-160 characters)
|
|
101
|
+
- [ ] Canonical URL: `<link rel="canonical" href="...">`
|
|
102
|
+
- [ ] Open Graph tags: `og:title`, `og:description`, `og:image`
|
|
103
|
+
- [ ] Structured data (JSON-LD) for content type
|
|
104
|
+
- [ ] `robots.txt` configured correctly
|
|
105
|
+
- [ ] XML sitemap generated and submitted
|
|
106
|
+
- [ ] Proper 301 redirects for moved content
|
|
107
|
+
|
|
108
|
+
### Content SEO
|
|
109
|
+
|
|
110
|
+
- [ ] One `<h1>` per page matching topic
|
|
111
|
+
- [ ] Descriptive alt text on all images
|
|
112
|
+
- [ ] Internal linking between related content
|
|
113
|
+
- [ ] Clean, readable URLs (no query params for content pages)
|
|
114
|
+
|
|
115
|
+
## Lighthouse CI
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Install
|
|
119
|
+
npm install -g @lhci/cli
|
|
120
|
+
|
|
121
|
+
# Run against local server
|
|
122
|
+
lhci autorun --collect.url=http://localhost:3000
|
|
123
|
+
|
|
124
|
+
# CI configuration (.lighthouserc.json)
|
|
125
|
+
{
|
|
126
|
+
"ci": {
|
|
127
|
+
"collect": {
|
|
128
|
+
"numberOfRuns": 3,
|
|
129
|
+
"url": ["http://localhost:3000/", "http://localhost:3000/about"]
|
|
130
|
+
},
|
|
131
|
+
"assert": {
|
|
132
|
+
"assertions": {
|
|
133
|
+
"categories:performance": ["error", {"minScore": 0.9}],
|
|
134
|
+
"categories:accessibility": ["error", {"minScore": 0.95}],
|
|
135
|
+
"categories:seo": ["error", {"minScore": 0.9}],
|
|
136
|
+
"categories:best-practices": ["error", {"minScore": 0.9}]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Framework-Specific Patterns
|
|
144
|
+
|
|
145
|
+
### React
|
|
146
|
+
|
|
147
|
+
- Use `React.memo()` for expensive renders, but measure first
|
|
148
|
+
- `useMemo`/`useCallback` for referential stability, not premature optimization
|
|
149
|
+
- Code-split routes with `React.lazy()` + `Suspense`
|
|
150
|
+
- Use `react-helmet-async` for SEO meta tags
|
|
151
|
+
|
|
152
|
+
### Next.js
|
|
153
|
+
|
|
154
|
+
- Use `next/image` for automatic optimization
|
|
155
|
+
- ISR (`revalidate`) for semi-static pages
|
|
156
|
+
- `generateMetadata()` for dynamic SEO
|
|
157
|
+
- `loading.tsx` for route-level loading states
|
|
158
|
+
|
|
159
|
+
### Vue
|
|
160
|
+
|
|
161
|
+
- Use `defineAsyncComponent` for code splitting
|
|
162
|
+
- `v-once` for static content that never updates
|
|
163
|
+
- `useHead()` from `@unhead/vue` for SEO
|
|
164
|
+
|
|
165
|
+
### Svelte
|
|
166
|
+
|
|
167
|
+
- Leverage compiler optimizations (no virtual DOM overhead)
|
|
168
|
+
- Use `{#await}` blocks for async data
|
|
169
|
+
- `svelte:head` for SEO meta tags
|
|
170
|
+
|
|
171
|
+
## Performance Budgets
|
|
172
|
+
|
|
173
|
+
| Resource Type | Budget |
|
|
174
|
+
| ---------------------- | -------- |
|
|
175
|
+
| Total JS (compressed) | < 200 KB |
|
|
176
|
+
| Total CSS (compressed) | < 50 KB |
|
|
177
|
+
| Hero image | < 100 KB |
|
|
178
|
+
| Web fonts | < 100 KB |
|
|
179
|
+
| Third-party scripts | < 50 KB |
|
|
180
|
+
| Total page weight | < 500 KB |
|