@minhduydev/mdpi 0.3.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/README.md +31 -0
- package/dist/index.js +1187 -0
- package/dist/template/.pi/.env.example +28 -0
- package/dist/template/.pi/AGENTS.md +226 -0
- package/dist/template/.pi/QUALITY.md +13 -0
- package/dist/template/.pi/README.md +452 -0
- package/dist/template/.pi/VERSION +1 -0
- package/dist/template/.pi/agents/INDEX.md +54 -0
- package/dist/template/.pi/agents/build.md +194 -0
- package/dist/template/.pi/agents/explore.md +85 -0
- package/dist/template/.pi/agents/general.md +189 -0
- package/dist/template/.pi/agents/plan.md +407 -0
- package/dist/template/.pi/agents/review.md +198 -0
- package/dist/template/.pi/agents/scout.md +142 -0
- package/dist/template/.pi/agents/vision.md +157 -0
- package/dist/template/.pi/artifacts/example/plan.md +12 -0
- package/dist/template/.pi/artifacts/example/progress.md +4 -0
- package/dist/template/.pi/artifacts/example/research.md +4 -0
- package/dist/template/.pi/artifacts/example/spec.md +16 -0
- package/dist/template/.pi/context/architecture.md +141 -0
- package/dist/template/.pi/context/fallow.md +137 -0
- package/dist/template/.pi/extensions/templates-injector.ts +76 -0
- package/dist/template/.pi/extensions/workflows-runner.ts +301 -0
- package/dist/template/.pi/guard.example.json +75 -0
- package/dist/template/.pi/prompts/INDEX.md +78 -0
- package/dist/template/.pi/prompts/audit.md +109 -0
- package/dist/template/.pi/prompts/close.md +88 -0
- package/dist/template/.pi/prompts/create.md +197 -0
- package/dist/template/.pi/prompts/fix.md +117 -0
- package/dist/template/.pi/prompts/gc.md +112 -0
- package/dist/template/.pi/prompts/init.md +206 -0
- package/dist/template/.pi/prompts/loop-check.md +87 -0
- package/dist/template/.pi/prompts/loop-init.md +157 -0
- package/dist/template/.pi/prompts/loop-review.md +90 -0
- package/dist/template/.pi/prompts/plan.md +254 -0
- package/dist/template/.pi/prompts/research.md +136 -0
- package/dist/template/.pi/prompts/ship.md +219 -0
- package/dist/template/.pi/prompts/status.md +92 -0
- package/dist/template/.pi/prompts/verify.md +154 -0
- package/dist/template/.pi/scripts/gc-check.sh +86 -0
- package/dist/template/.pi/settings.json +15 -0
- package/dist/template/.pi/skills/INDEX.md +331 -0
- package/dist/template/.pi/skills/accessibility-audit/SKILL.md +205 -0
- package/dist/template/.pi/skills/accessibility-audit/references/accessibility-checklist.md +109 -0
- package/dist/template/.pi/skills/agent-code-quality-gate/SKILL.md +131 -0
- package/dist/template/.pi/skills/api-and-interface-design/SKILL.md +159 -0
- package/dist/template/.pi/skills/behavioral-kernel/SKILL.md +92 -0
- package/dist/template/.pi/skills/brainstorming/SKILL.md +138 -0
- package/dist/template/.pi/skills/browser-testing-with-devtools/SKILL.md +90 -0
- package/dist/template/.pi/skills/chrome-devtools/SKILL.md +129 -0
- package/dist/template/.pi/skills/ci-cd-and-automation/SKILL.md +199 -0
- package/dist/template/.pi/skills/cloudflare/SKILL.md +271 -0
- package/dist/template/.pi/skills/cloudflare/references/agents-sdk/README.md +35 -0
- package/dist/template/.pi/skills/cloudflare/references/agents-sdk/api.md +100 -0
- package/dist/template/.pi/skills/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/dist/template/.pi/skills/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/dist/template/.pi/skills/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-gateway/README.md +695 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-search/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-search/api.md +38 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-search/configuration.md +52 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-search/gotchas.md +41 -0
- package/dist/template/.pi/skills/cloudflare/references/ai-search/patterns.md +45 -0
- package/dist/template/.pi/skills/cloudflare/references/analytics-engine/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/analytics-engine/api.md +27 -0
- package/dist/template/.pi/skills/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/dist/template/.pi/skills/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/dist/template/.pi/skills/cloudflare/references/api/README.md +21 -0
- package/dist/template/.pi/skills/cloudflare/references/api/api.md +31 -0
- package/dist/template/.pi/skills/cloudflare/references/api/configuration.md +20 -0
- package/dist/template/.pi/skills/cloudflare/references/api/gotchas.md +28 -0
- package/dist/template/.pi/skills/cloudflare/references/api/patterns.md +47 -0
- package/dist/template/.pi/skills/cloudflare/references/api-shield/README.md +20 -0
- package/dist/template/.pi/skills/cloudflare/references/api-shield/api.md +78 -0
- package/dist/template/.pi/skills/cloudflare/references/api-shield/configuration.md +128 -0
- package/dist/template/.pi/skills/cloudflare/references/api-shield/gotchas.md +51 -0
- package/dist/template/.pi/skills/cloudflare/references/api-shield/patterns.md +145 -0
- package/dist/template/.pi/skills/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/dist/template/.pi/skills/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/dist/template/.pi/skills/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/dist/template/.pi/skills/cloudflare/references/bindings/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/bindings/api.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/bindings/configuration.md +58 -0
- package/dist/template/.pi/skills/cloudflare/references/bindings/gotchas.md +35 -0
- package/dist/template/.pi/skills/cloudflare/references/bindings/patterns.md +37 -0
- package/dist/template/.pi/skills/cloudflare/references/bot-management/README.md +71 -0
- package/dist/template/.pi/skills/cloudflare/references/bot-management/api.md +168 -0
- package/dist/template/.pi/skills/cloudflare/references/bot-management/configuration.md +114 -0
- package/dist/template/.pi/skills/cloudflare/references/bot-management/gotchas.md +99 -0
- package/dist/template/.pi/skills/cloudflare/references/bot-management/patterns.md +125 -0
- package/dist/template/.pi/skills/cloudflare/references/browser-rendering/README.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/browser-rendering/api.md +54 -0
- package/dist/template/.pi/skills/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/dist/template/.pi/skills/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/dist/template/.pi/skills/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/dist/template/.pi/skills/cloudflare/references/c3/README.md +264 -0
- package/dist/template/.pi/skills/cloudflare/references/cache-reserve/README.md +93 -0
- package/dist/template/.pi/skills/cloudflare/references/cache-reserve/api.md +176 -0
- package/dist/template/.pi/skills/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/dist/template/.pi/skills/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/dist/template/.pi/skills/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/dist/template/.pi/skills/cloudflare/references/containers/README.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/containers/api.md +43 -0
- package/dist/template/.pi/skills/cloudflare/references/containers/configuration.md +56 -0
- package/dist/template/.pi/skills/cloudflare/references/containers/gotchas.md +21 -0
- package/dist/template/.pi/skills/cloudflare/references/containers/patterns.md +40 -0
- package/dist/template/.pi/skills/cloudflare/references/cron-triggers/README.md +85 -0
- package/dist/template/.pi/skills/cloudflare/references/cron-triggers/api.md +198 -0
- package/dist/template/.pi/skills/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/dist/template/.pi/skills/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/dist/template/.pi/skills/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/dist/template/.pi/skills/cloudflare/references/d1/README.md +92 -0
- package/dist/template/.pi/skills/cloudflare/references/d1/api.md +141 -0
- package/dist/template/.pi/skills/cloudflare/references/d1/configuration.md +127 -0
- package/dist/template/.pi/skills/cloudflare/references/d1/gotchas.md +70 -0
- package/dist/template/.pi/skills/cloudflare/references/d1/patterns.md +144 -0
- package/dist/template/.pi/skills/cloudflare/references/ddos/README.md +34 -0
- package/dist/template/.pi/skills/cloudflare/references/ddos/api.md +136 -0
- package/dist/template/.pi/skills/cloudflare/references/ddos/configuration.md +67 -0
- package/dist/template/.pi/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/dist/template/.pi/skills/cloudflare/references/ddos/patterns.md +158 -0
- package/dist/template/.pi/skills/cloudflare/references/do-storage/README.md +62 -0
- package/dist/template/.pi/skills/cloudflare/references/do-storage/api.md +89 -0
- package/dist/template/.pi/skills/cloudflare/references/do-storage/configuration.md +116 -0
- package/dist/template/.pi/skills/cloudflare/references/do-storage/gotchas.md +93 -0
- package/dist/template/.pi/skills/cloudflare/references/do-storage/patterns.md +112 -0
- package/dist/template/.pi/skills/cloudflare/references/durable-objects/README.md +125 -0
- package/dist/template/.pi/skills/cloudflare/references/durable-objects/api.md +152 -0
- package/dist/template/.pi/skills/cloudflare/references/durable-objects/configuration.md +148 -0
- package/dist/template/.pi/skills/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/dist/template/.pi/skills/cloudflare/references/durable-objects/patterns.md +255 -0
- package/dist/template/.pi/skills/cloudflare/references/email-routing/README.md +18 -0
- package/dist/template/.pi/skills/cloudflare/references/email-routing/api.md +46 -0
- package/dist/template/.pi/skills/cloudflare/references/email-routing/configuration.md +63 -0
- package/dist/template/.pi/skills/cloudflare/references/email-routing/gotchas.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/email-routing/patterns.md +46 -0
- package/dist/template/.pi/skills/cloudflare/references/email-workers/README.md +598 -0
- package/dist/template/.pi/skills/cloudflare/references/hyperdrive/README.md +62 -0
- package/dist/template/.pi/skills/cloudflare/references/hyperdrive/api.md +137 -0
- package/dist/template/.pi/skills/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/dist/template/.pi/skills/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/dist/template/.pi/skills/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/dist/template/.pi/skills/cloudflare/references/images/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/images/api.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/images/configuration.md +45 -0
- package/dist/template/.pi/skills/cloudflare/references/images/gotchas.md +23 -0
- package/dist/template/.pi/skills/cloudflare/references/images/patterns.md +31 -0
- package/dist/template/.pi/skills/cloudflare/references/kv/README.md +60 -0
- package/dist/template/.pi/skills/cloudflare/references/kv/api.md +114 -0
- package/dist/template/.pi/skills/cloudflare/references/kv/configuration.md +92 -0
- package/dist/template/.pi/skills/cloudflare/references/kv/gotchas.md +117 -0
- package/dist/template/.pi/skills/cloudflare/references/kv/patterns.md +139 -0
- package/dist/template/.pi/skills/cloudflare/references/miniflare/README.md +64 -0
- package/dist/template/.pi/skills/cloudflare/references/miniflare/api.md +144 -0
- package/dist/template/.pi/skills/cloudflare/references/miniflare/configuration.md +203 -0
- package/dist/template/.pi/skills/cloudflare/references/miniflare/gotchas.md +187 -0
- package/dist/template/.pi/skills/cloudflare/references/miniflare/patterns.md +211 -0
- package/dist/template/.pi/skills/cloudflare/references/network-interconnect/README.md +60 -0
- package/dist/template/.pi/skills/cloudflare/references/network-interconnect/api.md +240 -0
- package/dist/template/.pi/skills/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/dist/template/.pi/skills/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/dist/template/.pi/skills/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/dist/template/.pi/skills/cloudflare/references/observability/README.md +18 -0
- package/dist/template/.pi/skills/cloudflare/references/observability/api.md +51 -0
- package/dist/template/.pi/skills/cloudflare/references/observability/configuration.md +60 -0
- package/dist/template/.pi/skills/cloudflare/references/observability/gotchas.md +36 -0
- package/dist/template/.pi/skills/cloudflare/references/observability/patterns.md +42 -0
- package/dist/template/.pi/skills/cloudflare/references/pages/README.md +76 -0
- package/dist/template/.pi/skills/cloudflare/references/pages/api.md +200 -0
- package/dist/template/.pi/skills/cloudflare/references/pages/configuration.md +228 -0
- package/dist/template/.pi/skills/cloudflare/references/pages/gotchas.md +161 -0
- package/dist/template/.pi/skills/cloudflare/references/pages/patterns.md +145 -0
- package/dist/template/.pi/skills/cloudflare/references/pages-functions/README.md +57 -0
- package/dist/template/.pi/skills/cloudflare/references/pages-functions/api.md +201 -0
- package/dist/template/.pi/skills/cloudflare/references/pages-functions/configuration.md +159 -0
- package/dist/template/.pi/skills/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/dist/template/.pi/skills/cloudflare/references/pages-functions/patterns.md +190 -0
- package/dist/template/.pi/skills/cloudflare/references/pipelines/README.md +664 -0
- package/dist/template/.pi/skills/cloudflare/references/pulumi/README.md +107 -0
- package/dist/template/.pi/skills/cloudflare/references/pulumi/api.md +194 -0
- package/dist/template/.pi/skills/cloudflare/references/pulumi/configuration.md +216 -0
- package/dist/template/.pi/skills/cloudflare/references/pulumi/gotchas.md +223 -0
- package/dist/template/.pi/skills/cloudflare/references/pulumi/patterns.md +139 -0
- package/dist/template/.pi/skills/cloudflare/references/queues/README.md +69 -0
- package/dist/template/.pi/skills/cloudflare/references/queues/api.md +138 -0
- package/dist/template/.pi/skills/cloudflare/references/queues/configuration.md +125 -0
- package/dist/template/.pi/skills/cloudflare/references/queues/gotchas.md +112 -0
- package/dist/template/.pi/skills/cloudflare/references/queues/patterns.md +155 -0
- package/dist/template/.pi/skills/cloudflare/references/r2/README.md +61 -0
- package/dist/template/.pi/skills/cloudflare/references/r2/api.md +127 -0
- package/dist/template/.pi/skills/cloudflare/references/r2/configuration.md +76 -0
- package/dist/template/.pi/skills/cloudflare/references/r2/gotchas.md +94 -0
- package/dist/template/.pi/skills/cloudflare/references/r2/patterns.md +127 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/dist/template/.pi/skills/cloudflare/references/r2-sql/README.md +512 -0
- package/dist/template/.pi/skills/cloudflare/references/realtime-sfu/README.md +21 -0
- package/dist/template/.pi/skills/cloudflare/references/realtime-sfu/api.md +135 -0
- package/dist/template/.pi/skills/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/dist/template/.pi/skills/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/dist/template/.pi/skills/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/dist/template/.pi/skills/cloudflare/references/realtimekit/README.md +81 -0
- package/dist/template/.pi/skills/cloudflare/references/realtimekit/api.md +164 -0
- package/dist/template/.pi/skills/cloudflare/references/realtimekit/configuration.md +147 -0
- package/dist/template/.pi/skills/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/dist/template/.pi/skills/cloudflare/references/realtimekit/patterns.md +155 -0
- package/dist/template/.pi/skills/cloudflare/references/sandbox/README.md +90 -0
- package/dist/template/.pi/skills/cloudflare/references/sandbox/api.md +178 -0
- package/dist/template/.pi/skills/cloudflare/references/sandbox/configuration.md +131 -0
- package/dist/template/.pi/skills/cloudflare/references/sandbox/gotchas.md +156 -0
- package/dist/template/.pi/skills/cloudflare/references/sandbox/patterns.md +203 -0
- package/dist/template/.pi/skills/cloudflare/references/secrets-store/README.md +58 -0
- package/dist/template/.pi/skills/cloudflare/references/secrets-store/api.md +182 -0
- package/dist/template/.pi/skills/cloudflare/references/secrets-store/configuration.md +140 -0
- package/dist/template/.pi/skills/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/dist/template/.pi/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/dist/template/.pi/skills/cloudflare/references/smart-placement/README.md +91 -0
- package/dist/template/.pi/skills/cloudflare/references/smart-placement/api.md +139 -0
- package/dist/template/.pi/skills/cloudflare/references/smart-placement/configuration.md +129 -0
- package/dist/template/.pi/skills/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/dist/template/.pi/skills/cloudflare/references/smart-placement/patterns.md +135 -0
- package/dist/template/.pi/skills/cloudflare/references/snippets/README.md +15 -0
- package/dist/template/.pi/skills/cloudflare/references/snippets/api.md +47 -0
- package/dist/template/.pi/skills/cloudflare/references/snippets/configuration.md +33 -0
- package/dist/template/.pi/skills/cloudflare/references/snippets/gotchas.md +21 -0
- package/dist/template/.pi/skills/cloudflare/references/snippets/patterns.md +34 -0
- package/dist/template/.pi/skills/cloudflare/references/spectrum/README.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/spectrum/api.md +24 -0
- package/dist/template/.pi/skills/cloudflare/references/spectrum/configuration.md +43 -0
- package/dist/template/.pi/skills/cloudflare/references/spectrum/gotchas.md +42 -0
- package/dist/template/.pi/skills/cloudflare/references/spectrum/patterns.md +40 -0
- package/dist/template/.pi/skills/cloudflare/references/static-assets/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/static-assets/api.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/static-assets/configuration.md +47 -0
- package/dist/template/.pi/skills/cloudflare/references/static-assets/gotchas.md +44 -0
- package/dist/template/.pi/skills/cloudflare/references/static-assets/patterns.md +42 -0
- package/dist/template/.pi/skills/cloudflare/references/stream/README.md +103 -0
- package/dist/template/.pi/skills/cloudflare/references/stream/api.md +204 -0
- package/dist/template/.pi/skills/cloudflare/references/stream/configuration.md +127 -0
- package/dist/template/.pi/skills/cloudflare/references/stream/gotchas.md +131 -0
- package/dist/template/.pi/skills/cloudflare/references/stream/patterns.md +152 -0
- package/dist/template/.pi/skills/cloudflare/references/tail-workers/README.md +640 -0
- package/dist/template/.pi/skills/cloudflare/references/terraform/README.md +76 -0
- package/dist/template/.pi/skills/cloudflare/references/terraform/api.md +159 -0
- package/dist/template/.pi/skills/cloudflare/references/terraform/configuration.md +156 -0
- package/dist/template/.pi/skills/cloudflare/references/terraform/gotchas.md +207 -0
- package/dist/template/.pi/skills/cloudflare/references/terraform/patterns.md +135 -0
- package/dist/template/.pi/skills/cloudflare/references/tunnel/README.md +82 -0
- package/dist/template/.pi/skills/cloudflare/references/tunnel/api.md +105 -0
- package/dist/template/.pi/skills/cloudflare/references/tunnel/configuration.md +113 -0
- package/dist/template/.pi/skills/cloudflare/references/tunnel/gotchas.md +115 -0
- package/dist/template/.pi/skills/cloudflare/references/tunnel/patterns.md +157 -0
- package/dist/template/.pi/skills/cloudflare/references/turn/README.md +699 -0
- package/dist/template/.pi/skills/cloudflare/references/turnstile/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/turnstile/api.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/turnstile/configuration.md +19 -0
- package/dist/template/.pi/skills/cloudflare/references/turnstile/gotchas.md +27 -0
- package/dist/template/.pi/skills/cloudflare/references/turnstile/patterns.md +41 -0
- package/dist/template/.pi/skills/cloudflare/references/vectorize/README.md +682 -0
- package/dist/template/.pi/skills/cloudflare/references/waf/README.md +14 -0
- package/dist/template/.pi/skills/cloudflare/references/waf/api.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/waf/configuration.md +44 -0
- package/dist/template/.pi/skills/cloudflare/references/waf/gotchas.md +24 -0
- package/dist/template/.pi/skills/cloudflare/references/waf/patterns.md +29 -0
- package/dist/template/.pi/skills/cloudflare/references/web-analytics/README.md +19 -0
- package/dist/template/.pi/skills/cloudflare/references/web-analytics/api.md +52 -0
- package/dist/template/.pi/skills/cloudflare/references/web-analytics/configuration.md +31 -0
- package/dist/template/.pi/skills/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/dist/template/.pi/skills/cloudflare/references/web-analytics/patterns.md +52 -0
- package/dist/template/.pi/skills/cloudflare/references/workerd/README.md +47 -0
- package/dist/template/.pi/skills/cloudflare/references/workerd/api.md +199 -0
- package/dist/template/.pi/skills/cloudflare/references/workerd/configuration.md +185 -0
- package/dist/template/.pi/skills/cloudflare/references/workerd/gotchas.md +203 -0
- package/dist/template/.pi/skills/cloudflare/references/workerd/patterns.md +216 -0
- package/dist/template/.pi/skills/cloudflare/references/workers/README.md +96 -0
- package/dist/template/.pi/skills/cloudflare/references/workers/api.md +137 -0
- package/dist/template/.pi/skills/cloudflare/references/workers/configuration.md +147 -0
- package/dist/template/.pi/skills/cloudflare/references/workers/gotchas.md +99 -0
- package/dist/template/.pi/skills/cloudflare/references/workers/patterns.md +149 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-ai/README.md +116 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-playground/README.md +16 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-playground/api.md +20 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-playground/configuration.md +3 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-playground/patterns.md +42 -0
- package/dist/template/.pi/skills/cloudflare/references/workers-vpc/README.md +579 -0
- package/dist/template/.pi/skills/cloudflare/references/workflows/README.md +62 -0
- package/dist/template/.pi/skills/cloudflare/references/workflows/api.md +125 -0
- package/dist/template/.pi/skills/cloudflare/references/workflows/configuration.md +177 -0
- package/dist/template/.pi/skills/cloudflare/references/workflows/gotchas.md +136 -0
- package/dist/template/.pi/skills/cloudflare/references/workflows/patterns.md +132 -0
- package/dist/template/.pi/skills/cloudflare/references/wrangler/README.md +90 -0
- package/dist/template/.pi/skills/cloudflare/references/wrangler/api.md +140 -0
- package/dist/template/.pi/skills/cloudflare/references/wrangler/configuration.md +128 -0
- package/dist/template/.pi/skills/cloudflare/references/wrangler/gotchas.md +93 -0
- package/dist/template/.pi/skills/cloudflare/references/wrangler/patterns.md +150 -0
- package/dist/template/.pi/skills/cloudflare/references/zaraz/README.md +360 -0
- package/dist/template/.pi/skills/code-cleanup/SKILL.md +232 -0
- package/dist/template/.pi/skills/code-review-and-quality/SKILL.md +344 -0
- package/dist/template/.pi/skills/code-simplification/SKILL.md +348 -0
- package/dist/template/.pi/skills/context-engineering/SKILL.md +296 -0
- package/dist/template/.pi/skills/core-data-expert/SKILL.md +117 -0
- package/dist/template/.pi/skills/core-data-expert/references/batch-operations.md +543 -0
- package/dist/template/.pi/skills/core-data-expert/references/cloudkit-integration.md +259 -0
- package/dist/template/.pi/skills/core-data-expert/references/concurrency.md +522 -0
- package/dist/template/.pi/skills/core-data-expert/references/fetch-requests.md +643 -0
- package/dist/template/.pi/skills/core-data-expert/references/glossary.md +233 -0
- package/dist/template/.pi/skills/core-data-expert/references/migration.md +393 -0
- package/dist/template/.pi/skills/core-data-expert/references/model-configuration.md +597 -0
- package/dist/template/.pi/skills/core-data-expert/references/performance.md +300 -0
- package/dist/template/.pi/skills/core-data-expert/references/persistent-history.md +553 -0
- package/dist/template/.pi/skills/core-data-expert/references/project-audit.md +60 -0
- package/dist/template/.pi/skills/core-data-expert/references/saving.md +574 -0
- package/dist/template/.pi/skills/core-data-expert/references/stack-setup.md +625 -0
- package/dist/template/.pi/skills/core-data-expert/references/testing.md +300 -0
- package/dist/template/.pi/skills/core-data-expert/references/threading.md +589 -0
- package/dist/template/.pi/skills/debugging-and-error-recovery/SKILL.md +274 -0
- package/dist/template/.pi/skills/deep-module-design/SKILL.md +218 -0
- package/dist/template/.pi/skills/defense-in-depth/SKILL.md +161 -0
- package/dist/template/.pi/skills/deprecation-and-migration/SKILL.md +186 -0
- package/dist/template/.pi/skills/design-system-audit/SKILL.md +176 -0
- package/dist/template/.pi/skills/design-taste-frontend/SKILL.md +255 -0
- package/dist/template/.pi/skills/development-lifecycle/SKILL.md +285 -0
- package/dist/template/.pi/skills/documentation-and-adrs/SKILL.md +217 -0
- package/dist/template/.pi/skills/doubt-driven-development/SKILL.md +207 -0
- package/dist/template/.pi/skills/fallow/SKILL.md +457 -0
- package/dist/template/.pi/skills/fallow/references/cli-reference.md +1905 -0
- package/dist/template/.pi/skills/fallow/references/gotchas.md +644 -0
- package/dist/template/.pi/skills/fallow/references/patterns.md +791 -0
- package/dist/template/.pi/skills/figma/SKILL.md +241 -0
- package/dist/template/.pi/skills/frontend-design/SKILL.md +262 -0
- package/dist/template/.pi/skills/frontend-design/references/animation/motion-advanced.md +224 -0
- package/dist/template/.pi/skills/frontend-design/references/animation/motion-core.md +181 -0
- package/dist/template/.pi/skills/frontend-design/references/canvas/execution.md +90 -0
- package/dist/template/.pi/skills/frontend-design/references/canvas/philosophy.md +94 -0
- package/dist/template/.pi/skills/frontend-design/references/design/color-system.md +111 -0
- package/dist/template/.pi/skills/frontend-design/references/design/interaction.md +149 -0
- package/dist/template/.pi/skills/frontend-design/references/design/typography-rules.md +106 -0
- package/dist/template/.pi/skills/frontend-design/references/design/ux-writing.md +99 -0
- package/dist/template/.pi/skills/frontend-design/references/shadcn/accessibility.md +132 -0
- package/dist/template/.pi/skills/frontend-design/references/shadcn/core-components.md +153 -0
- package/dist/template/.pi/skills/frontend-design/references/shadcn/form-components.md +158 -0
- package/dist/template/.pi/skills/frontend-design/references/shadcn/setup.md +69 -0
- package/dist/template/.pi/skills/frontend-design/references/shadcn/theming.md +152 -0
- package/dist/template/.pi/skills/frontend-design/references/tailwind/responsive.md +112 -0
- package/dist/template/.pi/skills/frontend-design/references/tailwind/utilities-layout.md +134 -0
- package/dist/template/.pi/skills/frontend-design/references/tailwind/utilities-styling.md +165 -0
- package/dist/template/.pi/skills/frontend-design/references/tailwind/v4-config.md +147 -0
- package/dist/template/.pi/skills/frontend-design/references/tailwind/v4-features.md +128 -0
- package/dist/template/.pi/skills/frontend-ui-engineering/SKILL.md +217 -0
- package/dist/template/.pi/skills/gemini-large-context/SKILL.md +238 -0
- package/dist/template/.pi/skills/git-workflow-and-versioning/SKILL.md +217 -0
- package/dist/template/.pi/skills/grill-me/SKILL.md +162 -0
- package/dist/template/.pi/skills/high-end-visual-design/SKILL.md +128 -0
- package/dist/template/.pi/skills/idea-refine/SKILL.md +195 -0
- package/dist/template/.pi/skills/idea-refine/examples.md +62 -0
- package/dist/template/.pi/skills/idea-refine/frameworks.md +63 -0
- package/dist/template/.pi/skills/idea-refine/refinement-criteria.md +56 -0
- package/dist/template/.pi/skills/incremental-implementation/SKILL.md +190 -0
- package/dist/template/.pi/skills/industrial-brutalist-ui/SKILL.md +131 -0
- package/dist/template/.pi/skills/interview-me/SKILL.md +227 -0
- package/dist/template/.pi/skills/jira/SKILL.md +306 -0
- package/dist/template/.pi/skills/loop-audit/SKILL.md +141 -0
- package/dist/template/.pi/skills/loop-cost/SKILL.md +130 -0
- package/dist/template/.pi/skills/loop-engineering/SKILL.md +175 -0
- package/dist/template/.pi/skills/minimalist-ui/SKILL.md +124 -0
- package/dist/template/.pi/skills/mockup-to-code/SKILL.md +197 -0
- package/dist/template/.pi/skills/observability-and-instrumentation/SKILL.md +202 -0
- package/dist/template/.pi/skills/opensrc/SKILL.md +297 -0
- package/dist/template/.pi/skills/opensrc/references/architecture.md +176 -0
- package/dist/template/.pi/skills/opensrc/references/cli-usage.md +176 -0
- package/dist/template/.pi/skills/opensrc/references/registry-support.md +137 -0
- package/dist/template/.pi/skills/pdf-extract/SKILL.md +461 -0
- package/dist/template/.pi/skills/performance-optimization/SKILL.md +233 -0
- package/dist/template/.pi/skills/performance-optimization/references/performance-checklist.md +85 -0
- package/dist/template/.pi/skills/planning-and-task-breakdown/SKILL.md +204 -0
- package/dist/template/.pi/skills/playwright/SKILL.md +404 -0
- package/dist/template/.pi/skills/playwright/references/agent-browser-cli.md +405 -0
- package/dist/template/.pi/skills/polar/SKILL.md +125 -0
- package/dist/template/.pi/skills/react-best-practices/SKILL.md +156 -0
- package/dist/template/.pi/skills/react-best-practices/rules/_sections.md +46 -0
- package/dist/template/.pi/skills/react-best-practices/rules/_template.md +28 -0
- package/dist/template/.pi/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/template/.pi/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/dist/template/.pi/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/template/.pi/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/dist/template/.pi/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/dist/template/.pi/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/dist/template/.pi/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/template/.pi/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/dist/template/.pi/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/template/.pi/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/template/.pi/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/template/.pi/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/template/.pi/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/template/.pi/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/template/.pi/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/template/.pi/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/template/.pi/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/template/.pi/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/template/.pi/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/template/.pi/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/template/.pi/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/template/.pi/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/template/.pi/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/dist/template/.pi/skills/redesign-existing-projects/SKILL.md +217 -0
- package/dist/template/.pi/skills/resend/SKILL.md +196 -0
- package/dist/template/.pi/skills/resend/references/react-email.md +287 -0
- package/dist/template/.pi/skills/resend/references/receive-email.md +248 -0
- package/dist/template/.pi/skills/resend/references/send-email.md +318 -0
- package/dist/template/.pi/skills/root-cause-tracing/SKILL.md +216 -0
- package/dist/template/.pi/skills/security-and-hardening/SKILL.md +293 -0
- package/dist/template/.pi/skills/security-and-hardening/references/security-checklist.md +105 -0
- package/dist/template/.pi/skills/shipping-and-launch/SKILL.md +101 -0
- package/dist/template/.pi/skills/source-driven-development/SKILL.md +108 -0
- package/dist/template/.pi/skills/spec-driven-development/SKILL.md +177 -0
- package/dist/template/.pi/skills/srcwalk/SKILL.md +182 -0
- package/dist/template/.pi/skills/subagent-driven-development/SKILL.md +253 -0
- package/dist/template/.pi/skills/supabase/SKILL.md +153 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/SKILL.md +88 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
- package/dist/template/.pi/skills/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
- package/dist/template/.pi/skills/swift-concurrency/SKILL.md +290 -0
- package/dist/template/.pi/skills/swift-concurrency/references/actors.md +640 -0
- package/dist/template/.pi/skills/swift-concurrency/references/async-algorithms.md +822 -0
- package/dist/template/.pi/skills/swift-concurrency/references/async-await-basics.md +249 -0
- package/dist/template/.pi/skills/swift-concurrency/references/async-sequences.md +670 -0
- package/dist/template/.pi/skills/swift-concurrency/references/core-data.md +533 -0
- package/dist/template/.pi/skills/swift-concurrency/references/glossary.md +128 -0
- package/dist/template/.pi/skills/swift-concurrency/references/linting.md +142 -0
- package/dist/template/.pi/skills/swift-concurrency/references/memory-management.md +542 -0
- package/dist/template/.pi/skills/swift-concurrency/references/migration.md +1076 -0
- package/dist/template/.pi/skills/swift-concurrency/references/performance.md +574 -0
- package/dist/template/.pi/skills/swift-concurrency/references/sendable.md +578 -0
- package/dist/template/.pi/skills/swift-concurrency/references/tasks.md +604 -0
- package/dist/template/.pi/skills/swift-concurrency/references/testing.md +565 -0
- package/dist/template/.pi/skills/swift-concurrency/references/threading.md +452 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/SKILL.md +343 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/state-management.md +447 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/dist/template/.pi/skills/swiftui-expert-skill/references/view-structure.md +276 -0
- package/dist/template/.pi/skills/test-driven-development/SKILL.md +400 -0
- package/dist/template/.pi/skills/test-driven-development/references/testing-patterns.md +155 -0
- package/dist/template/.pi/skills/testing-anti-patterns/SKILL.md +339 -0
- package/dist/template/.pi/skills/using-agent-skills/SKILL.md +371 -0
- package/dist/template/.pi/skills/using-git-worktrees/SKILL.md +275 -0
- package/dist/template/.pi/skills/vercel-deploy-claimable/SKILL.md +144 -0
- package/dist/template/.pi/skills/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/dist/template/.pi/skills/verification-before-completion/SKILL.md +348 -0
- package/dist/template/.pi/skills/webclaw/SKILL.md +188 -0
- package/dist/template/.pi/skills/writing-skills/SKILL.md +329 -0
- package/dist/template/.pi/skills/writing-skills/references/anti-patterns.md +25 -0
- package/dist/template/.pi/skills/writing-skills/references/claude-search-optimization.md +140 -0
- package/dist/template/.pi/skills/writing-skills/references/discovery-workflow.md +11 -0
- package/dist/template/.pi/skills/writing-skills/references/file-organization.md +32 -0
- package/dist/template/.pi/skills/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/dist/template/.pi/skills/writing-skills/references/rationalization-hardening.md +75 -0
- package/dist/template/.pi/skills/writing-skills/references/testing-methodology.md +397 -0
- package/dist/template/.pi/skills/writing-skills/references/testing-skill-types.md +52 -0
- package/dist/template/.pi/subagents.json +10 -0
- package/dist/template/.pi/templates/adr.md +47 -0
- package/dist/template/.pi/templates/design.md +61 -0
- package/dist/template/.pi/templates/loop-github-action.yml +162 -0
- package/dist/template/.pi/templates/loop-orchestrator.sh +514 -0
- package/dist/template/.pi/templates/loop-orchestrator.test.ts +332 -0
- package/dist/template/.pi/templates/loop-orchestrator.ts +936 -0
- package/dist/template/.pi/templates/loop-state.json +24 -0
- package/dist/template/.pi/templates/loop-state.md +98 -0
- package/dist/template/.pi/templates/loop-vision.md +110 -0
- package/dist/template/.pi/templates/prd.md +204 -0
- package/dist/template/.pi/templates/progress.md +55 -0
- package/dist/template/.pi/templates/project.md +58 -0
- package/dist/template/.pi/templates/proposal.md +40 -0
- package/dist/template/.pi/templates/review-state.json +20 -0
- package/dist/template/.pi/templates/roadmap.md +93 -0
- package/dist/template/.pi/templates/state.md +97 -0
- package/dist/template/.pi/templates/tasks.md +202 -0
- package/dist/template/.pi/templates/tech-stack.md +85 -0
- package/dist/template/.pi/templates/user.md +26 -0
- package/dist/template/.pi/workflows/INDEX.md +63 -0
- package/dist/template/.pi/workflows/audit-pattern.md +84 -0
- package/dist/template/.pi/workflows/batch-implement.md +121 -0
- package/dist/template/.pi/workflows/deep-research.md +89 -0
- package/dist/template/.pi/workflows/development-lifecycle-workflow.md +175 -0
- package/dist/template/.pi/workflows/garbage-collection.md +144 -0
- package/dist/template/.pi/workflows/quality-loop.md +211 -0
- package/package.json +57 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pdf-extract
|
|
3
|
+
description: Use when extracting text, images, tables, or metadata from PDF files. MUST load to choose the correct extraction library based on PDF complexity — simple text vs structured data vs complex layouts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PDF Content Extraction
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- When you need to extract text, images, tables, or metadata from PDF files.
|
|
11
|
+
|
|
12
|
+
## When NOT to Use
|
|
13
|
+
|
|
14
|
+
- When the source data is already available in a non-PDF, structured format.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Quick Decision Guide
|
|
18
|
+
|
|
19
|
+
| Use Case | Recommended Library | Why |
|
|
20
|
+
| --------------------------- | ------------------- | ---------------------------------- |
|
|
21
|
+
| Simple text extraction | `pdf-parse` (v2+) | Fast, lightweight, pure TypeScript |
|
|
22
|
+
| Complex layouts/coordinates | `pdfjs-dist` | Full control, precise positioning |
|
|
23
|
+
| Tables/tabular data | `pdf-data-parser` | Built for grid-based content |
|
|
24
|
+
| Forms (XFA) | `pdf-lib` + custom | Form field extraction |
|
|
25
|
+
| Browser + Node.js | `pdf-parse` v2 | Cross-platform, works everywhere |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Library 1: pdf-parse (Recommended for Text)
|
|
30
|
+
|
|
31
|
+
**Best for:** Simple text extraction, metadata, fast processing
|
|
32
|
+
|
|
33
|
+
### Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install pdf-parse
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Basic Text Extraction
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { PDFParse } from "pdf-parse";
|
|
43
|
+
import { readFile } from "fs/promises";
|
|
44
|
+
|
|
45
|
+
async function extractText(filePath: string): Promise<string> {
|
|
46
|
+
const parser = new PDFParse();
|
|
47
|
+
const buffer = await readFile(filePath);
|
|
48
|
+
|
|
49
|
+
const result = await parser.parse(buffer);
|
|
50
|
+
return result.text;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Usage
|
|
54
|
+
const text = await extractText("./document.pdf");
|
|
55
|
+
console.log(text);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Extract with Metadata
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { PDFParse } from "pdf-parse";
|
|
62
|
+
|
|
63
|
+
async function extractWithMetadata(filePath: string) {
|
|
64
|
+
const parser = new PDFParse();
|
|
65
|
+
const buffer = await readFile(filePath);
|
|
66
|
+
|
|
67
|
+
const result = await parser.parse(buffer);
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
text: result.text,
|
|
71
|
+
info: result.info, // Document metadata
|
|
72
|
+
numpages: result.numpages,
|
|
73
|
+
version: result.version,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Extract Specific Pages
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { PDFParse } from "pdf-parse";
|
|
82
|
+
|
|
83
|
+
async function extractPage(filePath: string, pageNum: number) {
|
|
84
|
+
const parser = new PDFParse();
|
|
85
|
+
const buffer = await readFile(filePath);
|
|
86
|
+
|
|
87
|
+
const result = await parser.parse(buffer, {
|
|
88
|
+
max: pageNum,
|
|
89
|
+
min: pageNum,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return result.text;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### URL-based Extraction (without downloading full file)
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { getHeader } from "pdf-parse/node";
|
|
100
|
+
|
|
101
|
+
async function checkPDFHeaders(url: string) {
|
|
102
|
+
// Check file size and headers before downloading
|
|
103
|
+
const headers = await getHeader(url, true);
|
|
104
|
+
console.log(`File size: ${headers.size} bytes`);
|
|
105
|
+
|
|
106
|
+
if (headers.size > 10 * 1024 * 1024) {
|
|
107
|
+
console.warn("Large PDF - consider streaming");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Library 2: pdfjs-dist (Mozilla PDF.js)
|
|
115
|
+
|
|
116
|
+
**Best for:** Complex layouts, coordinates, images, page-by-page control
|
|
117
|
+
|
|
118
|
+
### Installation
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm install pdfjs-dist
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Basic Text Extraction with Coordinates
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import * as pdfjsLib from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
128
|
+
import { readFile } from "fs/promises";
|
|
129
|
+
import path from "path";
|
|
130
|
+
|
|
131
|
+
async function extractWithCoordinates(pdfPath: string) {
|
|
132
|
+
const data = await readFile(pdfPath);
|
|
133
|
+
const dataArray = new Uint8Array(data);
|
|
134
|
+
|
|
135
|
+
const pdfDocument = await pdfjsLib.getDocument({
|
|
136
|
+
data: dataArray,
|
|
137
|
+
standardFontDataUrl: path.join(process.cwd(), "node_modules/pdfjs-dist/standard_fonts/"),
|
|
138
|
+
}).promise;
|
|
139
|
+
|
|
140
|
+
const numPages = pdfDocument.numPages;
|
|
141
|
+
const results = [];
|
|
142
|
+
|
|
143
|
+
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
|
|
144
|
+
const page = await pdfDocument.getPage(pageNum);
|
|
145
|
+
const textContent = await page.getTextContent();
|
|
146
|
+
|
|
147
|
+
const pageText = textContent.items.map((item: any) => ({
|
|
148
|
+
text: item.str,
|
|
149
|
+
x: item.transform[4],
|
|
150
|
+
y: item.transform[5],
|
|
151
|
+
font: item.fontName,
|
|
152
|
+
width: item.width,
|
|
153
|
+
height: item.height,
|
|
154
|
+
}));
|
|
155
|
+
|
|
156
|
+
results.push({
|
|
157
|
+
page: pageNum,
|
|
158
|
+
items: pageText,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return results;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Extract Images from PDF
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import * as pdfjsLib from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
170
|
+
|
|
171
|
+
async function extractImages(pdfPath: string) {
|
|
172
|
+
const data = await readFile(pdfPath);
|
|
173
|
+
const pdfDocument = await pdfjsLib.getDocument({ data: new Uint8Array(data) }).promise;
|
|
174
|
+
|
|
175
|
+
const images = [];
|
|
176
|
+
|
|
177
|
+
for (let pageNum = 1; pageNum <= pdfDocument.numPages; pageNum++) {
|
|
178
|
+
const page = await pdfDocument.getPage(pageNum);
|
|
179
|
+
const ops = await page.getOperatorList();
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < ops.fnArray.length; i++) {
|
|
182
|
+
if (ops.fnArray[i] === pdfjsLib.OPS.paintImageXObject) {
|
|
183
|
+
const imageName = ops.argsArray[i][0];
|
|
184
|
+
const image = await page.objs.get(imageName);
|
|
185
|
+
|
|
186
|
+
images.push({
|
|
187
|
+
page: pageNum,
|
|
188
|
+
name: imageName,
|
|
189
|
+
width: image.width,
|
|
190
|
+
height: image.height,
|
|
191
|
+
data: image.data, // Raw image data
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return images;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Render Page to Image
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import * as pdfjsLib from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
205
|
+
import { createCanvas } from "canvas";
|
|
206
|
+
import { writeFile } from "fs/promises";
|
|
207
|
+
|
|
208
|
+
async function renderPageToImage(pdfPath: string, pageNum: number, outputPath: string) {
|
|
209
|
+
const data = await readFile(pdfPath);
|
|
210
|
+
const pdfDocument = await pdfjsLib.getDocument({ data: new Uint8Array(data) }).promise;
|
|
211
|
+
|
|
212
|
+
const page = await pdfDocument.getPage(pageNum);
|
|
213
|
+
const viewport = page.getViewport({ scale: 2.0 }); // Higher scale = better quality
|
|
214
|
+
|
|
215
|
+
const canvas = createCanvas(viewport.width, viewport.height);
|
|
216
|
+
const context = canvas.getContext("2d");
|
|
217
|
+
|
|
218
|
+
await page.render({
|
|
219
|
+
canvasContext: context,
|
|
220
|
+
viewport: viewport,
|
|
221
|
+
}).promise;
|
|
222
|
+
|
|
223
|
+
const buffer = canvas.toBuffer("image/png");
|
|
224
|
+
await writeFile(outputPath, buffer);
|
|
225
|
+
|
|
226
|
+
console.log(`Page ${pageNum} saved to ${outputPath}`);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Library 3: pdf-data-parser (Tables)
|
|
233
|
+
|
|
234
|
+
**Best for:** Tabular data, structured grid content
|
|
235
|
+
|
|
236
|
+
### Installation
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
npm install pdf-data-parser
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Extract Tables
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { PdfDataParser } from "pdf-data-parser";
|
|
246
|
+
|
|
247
|
+
async function extractTables(pdfPath: string) {
|
|
248
|
+
const parser = new PdfDataParser({
|
|
249
|
+
url: pdfPath,
|
|
250
|
+
// Options
|
|
251
|
+
heading: "Table Title", // Filter to specific table
|
|
252
|
+
cells: 3, // Minimum cells per row
|
|
253
|
+
headers: ["Name", "Amount"], // Expected headers
|
|
254
|
+
repeating: false, // Handle repeating headers
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const rows = await parser.parse();
|
|
258
|
+
return rows; // Array of arrays
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Stream Large PDFs
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import { PdfDataReader } from "pdf-data-parser";
|
|
266
|
+
import { createWriteStream } from "fs";
|
|
267
|
+
|
|
268
|
+
async function streamToCSV(pdfPath: string, outputPath: string) {
|
|
269
|
+
const reader = new PdfDataReader({
|
|
270
|
+
url: pdfPath,
|
|
271
|
+
cells: 2,
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const output = createWriteStream(outputPath);
|
|
275
|
+
|
|
276
|
+
reader.on("data", (row: string[]) => {
|
|
277
|
+
output.write(row.join(",") + "\n");
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
reader.on("end", () => {
|
|
281
|
+
output.end();
|
|
282
|
+
console.log("CSV created");
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Best Practices
|
|
290
|
+
|
|
291
|
+
### 1. Error Handling
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
async function safeExtract(filePath: string) {
|
|
295
|
+
try {
|
|
296
|
+
const buffer = await readFile(filePath);
|
|
297
|
+
|
|
298
|
+
// Validate PDF header
|
|
299
|
+
const header = buffer.slice(0, 5).toString();
|
|
300
|
+
if (header !== "%PDF-") {
|
|
301
|
+
throw new Error("Invalid PDF file");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const result = await parser.parse(buffer);
|
|
305
|
+
return result;
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (error.message.includes("password")) {
|
|
308
|
+
throw new Error("PDF is password protected");
|
|
309
|
+
}
|
|
310
|
+
if (error.message.includes("damaged")) {
|
|
311
|
+
throw new Error("PDF is corrupted");
|
|
312
|
+
}
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 2. Memory Management (Large Files)
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// For large PDFs, process page by page
|
|
322
|
+
async function extractLargePDF(pdfPath: string) {
|
|
323
|
+
const data = await readFile(pdfPath);
|
|
324
|
+
const pdfDocument = await pdfjsLib.getDocument({ data: new Uint8Array(data) }).promise;
|
|
325
|
+
|
|
326
|
+
// Don't load all pages at once
|
|
327
|
+
for (let i = 1; i <= pdfDocument.numPages; i++) {
|
|
328
|
+
const page = await pdfDocument.getPage(i);
|
|
329
|
+
const text = await page.getTextContent();
|
|
330
|
+
|
|
331
|
+
// Process immediately, don't accumulate
|
|
332
|
+
await processPageText(text);
|
|
333
|
+
|
|
334
|
+
// Clean up
|
|
335
|
+
page.cleanup();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### 3. Text Cleaning
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
function cleanExtractedText(text: string): string {
|
|
344
|
+
return text
|
|
345
|
+
.replace(/\s+/g, " ") // Normalize whitespace
|
|
346
|
+
.replace(/[^\x20-\x7E\n]/g, "") // Remove non-printable chars
|
|
347
|
+
.trim();
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 4. Performance Tips
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// Parallel extraction for multiple files
|
|
355
|
+
async function extractMultiple(files: string[]) {
|
|
356
|
+
const results = await Promise.all(
|
|
357
|
+
files.map((file) => extractText(file).catch((err) => ({ file, error: err }))),
|
|
358
|
+
);
|
|
359
|
+
return results;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Use streams for very large files
|
|
363
|
+
import { createReadStream } from "fs";
|
|
364
|
+
import { PdfDataReader } from "pdf-data-parser";
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Common Issues & Solutions
|
|
370
|
+
|
|
371
|
+
| Issue | Cause | Solution |
|
|
372
|
+
| -------------------- | --------------------- | ------------------------------------- |
|
|
373
|
+
| Text appears garbled | Encoding issue | Use pdfjs-dist with explicit encoding |
|
|
374
|
+
| Missing text | Scanned image PDF | Use OCR (Tesseract) before extraction |
|
|
375
|
+
| Out of memory | Large PDF | Stream processing, page-by-page |
|
|
376
|
+
| Password error | Encrypted PDF | Use `pdf-lib` to decrypt first |
|
|
377
|
+
| Missing coordinates | Wrong library | Use pdfjs-dist for positioning |
|
|
378
|
+
| Table structure lost | Plain text extraction | Use pdf-data-parser |
|
|
379
|
+
| Font warnings | Missing fonts | Set `standardFontDataUrl` option |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Complete Example: Document Processor
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { PDFParse } from "pdf-parse";
|
|
387
|
+
import { readFile } from "fs/promises";
|
|
388
|
+
|
|
389
|
+
interface DocumentResult {
|
|
390
|
+
text: string;
|
|
391
|
+
metadata: {
|
|
392
|
+
title?: string;
|
|
393
|
+
author?: string;
|
|
394
|
+
pages: number;
|
|
395
|
+
creationDate?: Date;
|
|
396
|
+
};
|
|
397
|
+
summary: string;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
async function processDocument(filePath: string): Promise<DocumentResult> {
|
|
401
|
+
const parser = new PDFParse();
|
|
402
|
+
const buffer = await readFile(filePath);
|
|
403
|
+
|
|
404
|
+
const result = await parser.parse(buffer);
|
|
405
|
+
|
|
406
|
+
// Generate summary (first 500 chars)
|
|
407
|
+
const summary = result.text.replace(/\s+/g, " ").slice(0, 500).trim() + "...";
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
text: result.text,
|
|
411
|
+
metadata: {
|
|
412
|
+
title: result.info?.Title,
|
|
413
|
+
author: result.info?.Author,
|
|
414
|
+
pages: result.numpages,
|
|
415
|
+
creationDate: result.info?.CreationDate ? new Date(result.info.CreationDate) : undefined,
|
|
416
|
+
},
|
|
417
|
+
summary,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Usage
|
|
422
|
+
const doc = await processDocument("./report.pdf");
|
|
423
|
+
console.log(`Document: ${doc.metadata.title}`);
|
|
424
|
+
console.log(`Pages: ${doc.metadata.pages}`);
|
|
425
|
+
console.log(`Summary: ${doc.summary}`);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## References
|
|
431
|
+
|
|
432
|
+
- [pdf-parse npm](https://www.npmjs.com/package/pdf-parse)
|
|
433
|
+
- [pdfjs-dist docs](https://mozilla.github.io/pdf.js/)
|
|
434
|
+
- [pdf-data-parser GitHub](https://github.com/drewletcher/pdf-data-parser)
|
|
435
|
+
- [pdf-lib GitHub](https://github.com/Hopding/pdf-lib)
|
|
436
|
+
|
|
437
|
+
## Common Rationalizations
|
|
438
|
+
|
|
439
|
+
| Rationalization | Reality |
|
|
440
|
+
|---|---|
|
|
441
|
+
| "One extraction tool works for all PDFs" | PDFs vary wildly in structure. Simple text PDFs ≠ scanned documents ≠ complex layouts. |
|
|
442
|
+
| "The extracted text looks correct" | Visual inspection misses encoding issues, missing characters, and ordering problems. Validate programmatically. |
|
|
443
|
+
| "I don't need to handle edge cases" | PDFs are edge-case generators. Corrupt files, encrypted documents, and embedded fonts will appear. |
|
|
444
|
+
|
|
445
|
+
## Red Flags
|
|
446
|
+
|
|
447
|
+
- Single extraction method applied to all PDFs regardless of structure
|
|
448
|
+
- Extracted text not validated against original document
|
|
449
|
+
- Tables extracted as unstructured text
|
|
450
|
+
- Embedded images and fonts ignored
|
|
451
|
+
- Encrypted PDFs cause unhandled errors
|
|
452
|
+
|
|
453
|
+
## Verification
|
|
454
|
+
|
|
455
|
+
After PDF extraction:
|
|
456
|
+
|
|
457
|
+
- [ ] Extracted text is spot-checked against original document
|
|
458
|
+
- [ ] Tables are extracted with structure preserved (not as flat text)
|
|
459
|
+
- [ ] Character encoding issues are detected and handled
|
|
460
|
+
- [ ] Edge cases tested: encrypted PDFs, scanned documents, complex layouts
|
|
461
|
+
- [ ] Extraction method is appropriate for the PDF type (not one-size-fits-all)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-optimization
|
|
3
|
+
description: Use when profiling, optimizing, or adding performance budgets to applications — covers measure-first workflow, Core Web Vitals, common anti-patterns, and performance regression prevention
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Performance Optimization
|
|
7
|
+
|
|
8
|
+
> **Replaces** premature optimization and gut-feeling tuning with measurement-driven improvements that target actual bottlenecks
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Application is measurably slow (user reports, metrics, profiler data)
|
|
13
|
+
- Setting up performance budgets for a new project
|
|
14
|
+
- Reviewing code for common performance anti-patterns
|
|
15
|
+
- Performance regression detected in CI or monitoring
|
|
16
|
+
|
|
17
|
+
## When NOT to Use
|
|
18
|
+
|
|
19
|
+
- No evidence of a performance problem — premature optimization wastes time
|
|
20
|
+
- Micro-optimizations that save nanoseconds in non-hot paths
|
|
21
|
+
- Choosing "fast" over "correct" — correctness first, always
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
Performance optimization is an empirical process. Measure, identify, fix, verify. Never optimize without profiling first.
|
|
26
|
+
|
|
27
|
+
**Core principle:** Measure before optimizing. Optimize the bottleneck, not the code you happen to be reading. Verify the improvement with numbers.
|
|
28
|
+
|
|
29
|
+
## Measure-First Workflow
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
1. MEASURE — Profile to identify actual bottlenecks (not guessed ones)
|
|
33
|
+
2. IDENTIFY — Find the specific hot path or resource constraint
|
|
34
|
+
3. FIX — Apply targeted optimization to the bottleneck
|
|
35
|
+
4. VERIFY — Measure again to confirm improvement
|
|
36
|
+
5. GUARD — Add budget/benchmark to prevent regression
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Rule:** Skip to step 3 only if you have measurement data that justifies the optimization.
|
|
40
|
+
|
|
41
|
+
## Performance Targets
|
|
42
|
+
|
|
43
|
+
### Core Web Vitals (Web)
|
|
44
|
+
|
|
45
|
+
| Metric | Good | Needs Improvement | Poor |
|
|
46
|
+
| ------------------------------- | ------- | ----------------- | ------- |
|
|
47
|
+
| LCP (Largest Contentful Paint) | ≤ 2.5s | ≤ 4.0s | > 4.0s |
|
|
48
|
+
| INP (Interaction to Next Paint) | ≤ 200ms | ≤ 500ms | > 500ms |
|
|
49
|
+
| CLS (Cumulative Layout Shift) | ≤ 0.1 | ≤ 0.25 | > 0.25 |
|
|
50
|
+
|
|
51
|
+
### General Targets
|
|
52
|
+
|
|
53
|
+
| Context | Target | Measure |
|
|
54
|
+
| ------------------- | ------------ | ---------------------- |
|
|
55
|
+
| API response (p95) | < 200ms | Server-side timing |
|
|
56
|
+
| CLI command startup | < 500ms | `time` or `perf_hooks` |
|
|
57
|
+
| Build time | < 60s | CI pipeline metrics |
|
|
58
|
+
| Bundle size (JS) | < 200KB gzip | Bundler output |
|
|
59
|
+
| Database query | < 50ms | Query EXPLAIN + timing |
|
|
60
|
+
|
|
61
|
+
## Common Anti-Patterns & Fixes
|
|
62
|
+
|
|
63
|
+
### N+1 Queries
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// [ ] N+1: One query per user
|
|
67
|
+
const users = await db.query("SELECT * FROM users");
|
|
68
|
+
for (const user of users) {
|
|
69
|
+
user.posts = await db.query("SELECT * FROM posts WHERE user_id = ?", [user.id]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// [x] Batch: Two queries total
|
|
73
|
+
const users = await db.query("SELECT * FROM users");
|
|
74
|
+
const userIds = users.map((u) => u.id);
|
|
75
|
+
const posts = await db.query("SELECT * FROM posts WHERE user_id IN (?)", [userIds]);
|
|
76
|
+
// Group posts by user_id in application code
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Unbounded Fetching
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// [ ] Fetch everything
|
|
83
|
+
const allItems = await db.query("SELECT * FROM items");
|
|
84
|
+
|
|
85
|
+
// [x] Paginate
|
|
86
|
+
const items = await db.query("SELECT * FROM items LIMIT ? OFFSET ?", [pageSize, offset]);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Missing Memoization
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// [ ] Recompute on every render
|
|
93
|
+
function ExpensiveList({ items }) {
|
|
94
|
+
const sorted = items.sort((a, b) => complexSort(a, b)); // sorts on every render
|
|
95
|
+
return <List items={sorted} />;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// [x] Memoize expensive computation
|
|
99
|
+
function ExpensiveList({ items }) {
|
|
100
|
+
const sorted = useMemo(
|
|
101
|
+
() => [...items].sort((a, b) => complexSort(a, b)),
|
|
102
|
+
[items]
|
|
103
|
+
);
|
|
104
|
+
return <List items={sorted} />;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Large Bundle Size
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// [ ] Import entire library
|
|
112
|
+
import _ from "lodash";
|
|
113
|
+
const result = _.debounce(fn, 300);
|
|
114
|
+
|
|
115
|
+
// [x] Import only what you need
|
|
116
|
+
import debounce from "lodash/debounce";
|
|
117
|
+
const result = debounce(fn, 300);
|
|
118
|
+
|
|
119
|
+
// [x][x] Use native (no dependency)
|
|
120
|
+
function debounce(fn, ms) {
|
|
121
|
+
/* ... */
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Missing Image Optimization
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<!-- [ ] Unoptimized -->
|
|
129
|
+
<img src="hero.png" />
|
|
130
|
+
|
|
131
|
+
<!-- [x] Optimized -->
|
|
132
|
+
<img
|
|
133
|
+
src="hero.webp"
|
|
134
|
+
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
|
|
135
|
+
sizes="(max-width: 600px) 400px, (max-width: 1024px) 800px, 1200px"
|
|
136
|
+
loading="lazy"
|
|
137
|
+
decoding="async"
|
|
138
|
+
width="1200"
|
|
139
|
+
height="630"
|
|
140
|
+
alt="Hero image"
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Unnecessary Re-renders (React)
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// [ ] New object every render causes child re-render
|
|
148
|
+
function Parent() {
|
|
149
|
+
return <Child style={{ color: 'red' }} onClick={() => doThing()} />;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// [x] Stable references
|
|
153
|
+
const style = { color: 'red' };
|
|
154
|
+
function Parent() {
|
|
155
|
+
const handleClick = useCallback(() => doThing(), []);
|
|
156
|
+
return <Child style={style} onClick={handleClick} />;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Profiling Tools
|
|
161
|
+
|
|
162
|
+
| Context | Tool | What It Shows |
|
|
163
|
+
| ---------------- | -------------------------------- | --------------------------------- |
|
|
164
|
+
| Web (browser) | Chrome DevTools Performance | Paint, scripting, layout, network |
|
|
165
|
+
| Web (field data) | CrUX, PageSpeed Insights | Real-user Core Web Vitals |
|
|
166
|
+
| Node.js | `node --prof` + `--prof-process` | V8 profiling ticks per function |
|
|
167
|
+
| Node.js | `clinic.js` | Flamegraphs, event loop delays |
|
|
168
|
+
| React | React DevTools Profiler | Component render times |
|
|
169
|
+
| SQL | `EXPLAIN ANALYZE` | Query execution plan |
|
|
170
|
+
| Bundle | `source-map-explorer` | Module size breakdown |
|
|
171
|
+
| Network | `lighthouse` | Loading performance audit |
|
|
172
|
+
|
|
173
|
+
## Performance Budget
|
|
174
|
+
|
|
175
|
+
### Setting Budgets
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"budgets": [
|
|
180
|
+
{ "metric": "js-bundle", "max": "200KB", "warn": "150KB" },
|
|
181
|
+
{ "metric": "css-bundle", "max": "50KB", "warn": "40KB" },
|
|
182
|
+
{ "metric": "lcp", "max": "2500ms", "warn": "2000ms" },
|
|
183
|
+
{ "metric": "api-p95", "max": "200ms", "warn": "150ms" }
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Enforcing Budgets in CI
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
- name: Check bundle size
|
|
192
|
+
run: |
|
|
193
|
+
npx bundlesize --config .bundlesizerc.json
|
|
194
|
+
|
|
195
|
+
- name: Lighthouse audit
|
|
196
|
+
run: |
|
|
197
|
+
npx lighthouse $URL --output json --chrome-flags="--headless"
|
|
198
|
+
# Parse and assert against budgets
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Common Rationalizations
|
|
202
|
+
|
|
203
|
+
| Excuse | Rebuttal |
|
|
204
|
+
| --------------------------------- | ---------------------------------------------------------------------------------- |
|
|
205
|
+
| "It's fast enough on my machine" | Test on low-end devices and slow networks. Your machine isn't representative. |
|
|
206
|
+
| "We'll optimize later" | Performance debt compounds. Set budgets now, optimize when they're breached. |
|
|
207
|
+
| "This micro-optimization matters" | Profile first. If it's not in the hot path, it doesn't matter. |
|
|
208
|
+
| "Users won't notice 200ms" | Studies show 100ms delays reduce conversions. Users notice more than you think. |
|
|
209
|
+
| "Adding metrics is overhead" | The overhead of measurement is trivial compared to the cost of blind optimization. |
|
|
210
|
+
| "Caching will fix it" | Caching masks problems. Fix the root cause, then add caching as defense. |
|
|
211
|
+
|
|
212
|
+
## Red Flags — STOP
|
|
213
|
+
|
|
214
|
+
- Optimizing without profiling data
|
|
215
|
+
- Adding caching to mask a fundamentally slow operation
|
|
216
|
+
- Micro-optimizing code that runs once per request
|
|
217
|
+
- Bundle size growing without review
|
|
218
|
+
- No performance budget or monitoring in place
|
|
219
|
+
- Using `SELECT *` in production queries
|
|
220
|
+
|
|
221
|
+
## Verification
|
|
222
|
+
|
|
223
|
+
- [ ] Bottleneck identified with profiling data (not intuition)
|
|
224
|
+
- [ ] Optimization shows measurable improvement in profiler
|
|
225
|
+
- [ ] Performance budget is set and enforced in CI
|
|
226
|
+
- [ ] No regressions in existing benchmarks
|
|
227
|
+
- [ ] Optimization doesn't sacrifice correctness or readability
|
|
228
|
+
|
|
229
|
+
## See Also
|
|
230
|
+
|
|
231
|
+
- **react-best-practices** — React-specific performance patterns (server components, bundle optimization)
|
|
232
|
+
- **ci-cd-and-automation** — Enforcing performance budgets in CI
|
|
233
|
+
- **code-simplification** — Simplifying code often improves performance as a side effect
|