quiver-cli 1.3.0 → 2.0.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 +197 -239
- package/dist/cli.js +3163 -2040
- package/package.json +10 -11
- package/template/.agents/AGENTS.md +0 -26
- package/template/.agents/commands/cp.md +0 -108
- package/template/.agents/commands/next-setup.md +0 -1064
- package/template/.agents/commands/review.md +0 -68
- package/template/.agents/commands/terraform-readme.md +0 -38
- package/template/.agents/config.json +0 -80
- package/template/.agents/plugins/opencode/rtk.ts +0 -34
- package/template/.agents/skills/agent-browser/SKILL.md +0 -51
- package/template/.agents/skills/apps/skybridge/SKILL.md +0 -50
- package/template/.agents/skills/code/cleanup/SKILL.md +0 -26
- package/template/.agents/skills/code/improve/SKILL.md +0 -122
- package/template/.agents/skills/code/improve/references/audit-playbook.md +0 -130
- package/template/.agents/skills/code/improve/references/closing-the-loop.md +0 -96
- package/template/.agents/skills/code/improve/references/plan-template.md +0 -197
- package/template/.agents/skills/code/vercel-react-best-practices/AGENTS.md +0 -3810
- package/template/.agents/skills/code/vercel-react-best-practices/README.md +0 -123
- package/template/.agents/skills/code/vercel-react-best-practices/SKILL.md +0 -149
- package/template/.agents/skills/code/vercel-react-best-practices/metadata.json +0 -15
- package/template/.agents/skills/code/vercel-react-best-practices/rules/_sections.md +0 -46
- package/template/.agents/skills/code/vercel-react-best-practices/rules/_template.md +0 -28
- package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-effect-event-deps.md +0 -56
- package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
- package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +0 -37
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-defer-await.md +0 -82
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-dependencies.md +0 -51
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/template/.agents/skills/code/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-analyzable-paths.md +0 -63
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -60
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/template/.agents/skills/code/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/template/.agents/skills/code/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/template/.agents/skills/code/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/template/.agents/skills/code/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-request-idle-callback.md +0 -105
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/template/.agents/skills/code/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
- package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -149
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-no-shared-module-state.md +0 -50
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +0 -34
- package/template/.agents/skills/code/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/template/.agents/skills/data/prisma-cli/SKILL.md +0 -247
- package/template/.agents/skills/data/prisma-cli/references/db-execute.md +0 -78
- package/template/.agents/skills/data/prisma-cli/references/db-pull.md +0 -185
- package/template/.agents/skills/data/prisma-cli/references/db-push.md +0 -148
- package/template/.agents/skills/data/prisma-cli/references/db-seed.md +0 -188
- package/template/.agents/skills/data/prisma-cli/references/debug.md +0 -46
- package/template/.agents/skills/data/prisma-cli/references/dev.md +0 -157
- package/template/.agents/skills/data/prisma-cli/references/format.md +0 -48
- package/template/.agents/skills/data/prisma-cli/references/generate.md +0 -173
- package/template/.agents/skills/data/prisma-cli/references/init.md +0 -136
- package/template/.agents/skills/data/prisma-cli/references/mcp.md +0 -38
- package/template/.agents/skills/data/prisma-cli/references/migrate-deploy.md +0 -127
- package/template/.agents/skills/data/prisma-cli/references/migrate-dev.md +0 -145
- package/template/.agents/skills/data/prisma-cli/references/migrate-diff.md +0 -89
- package/template/.agents/skills/data/prisma-cli/references/migrate-reset.md +0 -78
- package/template/.agents/skills/data/prisma-cli/references/migrate-resolve.md +0 -57
- package/template/.agents/skills/data/prisma-cli/references/migrate-status.md +0 -65
- package/template/.agents/skills/data/prisma-cli/references/studio.md +0 -137
- package/template/.agents/skills/data/prisma-cli/references/validate.md +0 -53
- package/template/.agents/skills/data/prisma-client-api/SKILL.md +0 -216
- package/template/.agents/skills/data/prisma-client-api/references/client-methods.md +0 -223
- package/template/.agents/skills/data/prisma-client-api/references/constructor.md +0 -208
- package/template/.agents/skills/data/prisma-client-api/references/filters.md +0 -256
- package/template/.agents/skills/data/prisma-client-api/references/model-queries.md +0 -281
- package/template/.agents/skills/data/prisma-client-api/references/query-options.md +0 -276
- package/template/.agents/skills/data/prisma-client-api/references/raw-queries.md +0 -194
- package/template/.agents/skills/data/prisma-client-api/references/relations.md +0 -308
- package/template/.agents/skills/data/prisma-client-api/references/transactions.md +0 -184
- package/template/.agents/skills/design/impeccable/SKILL.md +0 -84
- package/template/.agents/skills/design/impeccable/reference/adapt.md +0 -312
- package/template/.agents/skills/design/impeccable/reference/adapt.native.md +0 -58
- package/template/.agents/skills/design/impeccable/reference/android.md +0 -40
- package/template/.agents/skills/design/impeccable/reference/animate.md +0 -86
- package/template/.agents/skills/design/impeccable/reference/audit.md +0 -136
- package/template/.agents/skills/design/impeccable/reference/audit.native.md +0 -139
- package/template/.agents/skills/design/impeccable/reference/bolder.md +0 -31
- package/template/.agents/skills/design/impeccable/reference/clarify.md +0 -94
- package/template/.agents/skills/design/impeccable/reference/colorize.md +0 -86
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +0 -42
- package/template/.agents/skills/design/impeccable/reference/craft.md +0 -5
- package/template/.agents/skills/design/impeccable/reference/critique.md +0 -788
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +0 -90
- package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +0 -24
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +0 -37
- package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +0 -92
- package/template/.agents/skills/design/impeccable/reference/delight.md +0 -70
- package/template/.agents/skills/design/impeccable/reference/distill.md +0 -111
- package/template/.agents/skills/design/impeccable/reference/doctor.md +0 -53
- package/template/.agents/skills/design/impeccable/reference/document.md +0 -416
- package/template/.agents/skills/design/impeccable/reference/extract.md +0 -69
- package/template/.agents/skills/design/impeccable/reference/harden.md +0 -336
- package/template/.agents/skills/design/impeccable/reference/hooks.md +0 -105
- package/template/.agents/skills/design/impeccable/reference/init.md +0 -125
- package/template/.agents/skills/design/impeccable/reference/ios.md +0 -45
- package/template/.agents/skills/design/impeccable/reference/layout.md +0 -84
- package/template/.agents/skills/design/impeccable/reference/live-setup.md +0 -102
- package/template/.agents/skills/design/impeccable/reference/live.md +0 -323
- package/template/.agents/skills/design/impeccable/reference/new-work.md +0 -105
- package/template/.agents/skills/design/impeccable/reference/onboard.md +0 -234
- package/template/.agents/skills/design/impeccable/reference/operate.md +0 -61
- package/template/.agents/skills/design/impeccable/reference/optimize.md +0 -258
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +0 -127
- package/template/.agents/skills/design/impeccable/reference/polish.md +0 -97
- package/template/.agents/skills/design/impeccable/reference/quieter.md +0 -99
- package/template/.agents/skills/design/impeccable/reference/routing.md +0 -18
- package/template/.agents/skills/design/impeccable/reference/shape.md +0 -59
- package/template/.agents/skills/design/impeccable/reference/typeset.md +0 -80
- package/template/.agents/skills/design/impeccable/reference/visualize.md +0 -47
- package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +0 -94
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +0 -558
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +0 -334
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +0 -1450
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +0 -213
- package/template/.agents/skills/design/impeccable/scripts/detect-csp.mjs +0 -198
- package/template/.agents/skills/design/impeccable/scripts/detect.mjs +0 -21
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +0 -2023
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +0 -438
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +0 -983
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +0 -8283
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +0 -50
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +0 -372
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +0 -768
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +0 -1186
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +0 -264
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +0 -189
- package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +0 -18
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +0 -212
- package/template/.agents/skills/design/impeccable/scripts/detector/profile/profiler.mjs +0 -166
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +0 -617
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +0 -5580
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/color.mjs +0 -124
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +0 -112
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +0 -30
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/inline-ignores.mjs +0 -148
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/page.mjs +0 -7
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +0 -336
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +0 -133
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +0 -240
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +0 -741
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +0 -516
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +0 -2100
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +0 -78
- package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +0 -93
- package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +0 -200
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +0 -357
- package/template/.agents/skills/design/impeccable/scripts/lib/design-parser.mjs +0 -842
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +0 -658
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +0 -137
- package/template/.agents/skills/design/impeccable/scripts/lib/is-generated.mjs +0 -69
- package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +0 -5
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +0 -362
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +0 -457
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +0 -169
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +0 -457
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +0 -151
- package/template/.agents/skills/design/impeccable/scripts/lib/target-args.mjs +0 -42
- package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +0 -33
- package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +0 -146
- package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +0 -617
- package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +0 -60
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +0 -55
- package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +0 -28
- package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +0 -199
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +0 -47
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +0 -73
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +0 -143
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +0 -197
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +0 -49
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +0 -161
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +0 -17
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +0 -26
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +0 -71
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +0 -247
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +0 -70
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +0 -42
- package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +0 -149
- package/template/.agents/skills/design/impeccable/scripts/live/insert-ui.mjs +0 -458
- package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +0 -142
- package/template/.agents/skills/design/impeccable/scripts/live/manual-apply.mjs +0 -939
- package/template/.agents/skills/design/impeccable/scripts/live/manual-edit-routes.mjs +0 -357
- package/template/.agents/skills/design/impeccable/scripts/live/manual-edits-buffer.mjs +0 -152
- package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +0 -14
- package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +0 -508
- package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +0 -563
- package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +0 -105
- package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +0 -105
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +0 -961
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +0 -1342
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +0 -316
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +0 -280
- package/template/.agents/skills/design/impeccable/scripts/live/ui-core.mjs +0 -180
- package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +0 -171
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +0 -954
- package/template/.agents/skills/design/impeccable/scripts/live-browser-dom.js +0 -146
- package/template/.agents/skills/design/impeccable/scripts/live-browser-session.js +0 -123
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +0 -12512
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +0 -1244
- package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +0 -107
- package/template/.agents/skills/design/impeccable/scripts/live-copy-edit-agent.mjs +0 -683
- package/template/.agents/skills/design/impeccable/scripts/live-discard-manual-edits.mjs +0 -51
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +0 -503
- package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +0 -292
- package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +0 -368
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +0 -429
- package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +0 -123
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +0 -1661
- package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +0 -71
- package/template/.agents/skills/design/impeccable/scripts/live-target.mjs +0 -30
- package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +0 -927
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +0 -359
- package/template/.agents/skills/design/impeccable/scripts/modern-screenshot.umd.js +0 -14
- package/template/.agents/skills/design/impeccable/scripts/palette.mjs +0 -628
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +0 -221
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +0 -932
- package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +0 -74
- package/template/.agents/skills/design/shadcn/SKILL.md +0 -277
- package/template/.agents/skills/design/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/design/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/design/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/design/shadcn/cli.md +0 -290
- package/template/.agents/skills/design/shadcn/customization.md +0 -209
- package/template/.agents/skills/design/shadcn/evals/evals.json +0 -77
- package/template/.agents/skills/design/shadcn/mcp.md +0 -105
- package/template/.agents/skills/design/shadcn/registry.md +0 -277
- package/template/.agents/skills/design/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/design/shadcn/rules/chat.md +0 -224
- package/template/.agents/skills/design/shadcn/rules/composition.md +0 -213
- package/template/.agents/skills/design/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/design/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/design/shadcn/rules/styling.md +0 -185
- package/template/.agents/skills/find-skills/SKILL.md +0 -141
- package/template/.agents/skills/hono/SKILL.md +0 -579
- package/template/.agents/skills/integrations/langfuse/SKILL.md +0 -146
- package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +0 -41
- package/template/.agents/skills/integrations/langfuse/references/cli.md +0 -60
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +0 -88
- package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +0 -121
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +0 -291
- package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +0 -35
- package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +0 -79
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +0 -55
- package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +0 -76
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +0 -92
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +0 -73
- package/template/.agents/skills/integrations/posthog/SKILL.md +0 -102
- package/template/.agents/skills/integrations/posthog/references/error-tracking-alerts.md +0 -63
- package/template/.agents/skills/integrations/posthog/references/error-tracking-assigning-issues.md +0 -77
- package/template/.agents/skills/integrations/posthog/references/error-tracking-fingerprints.md +0 -57
- package/template/.agents/skills/integrations/posthog/references/error-tracking-monitoring.md +0 -140
- package/template/.agents/skills/integrations/posthog/references/error-tracking-nextjs.md +0 -490
- package/template/.agents/skills/integrations/posthog/references/error-tracking-source-maps.md +0 -45
- package/template/.agents/skills/integrations/posthog/references/feature-flags-best-practices.md +0 -139
- package/template/.agents/skills/integrations/posthog/references/feature-flags-react.md +0 -302
- package/template/.agents/skills/integrations/posthog/references/identify-users.md +0 -202
- package/template/.agents/skills/integrations/posthog/references/integration-example.md +0 -706
- package/template/.agents/skills/integrations/posthog/references/integration-nextjs.md +0 -385
- package/template/.agents/skills/integrations/posthog/references/integration-step-1-begin.md +0 -43
- package/template/.agents/skills/integrations/posthog/references/integration-step-2-edit.md +0 -37
- package/template/.agents/skills/integrations/posthog/references/integration-step-3-revise.md +0 -22
- package/template/.agents/skills/integrations/posthog/references/integration-step-4-conclude.md +0 -38
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-anthropic.md +0 -200
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-basics.md +0 -62
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-costs.md +0 -197
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-manual-capture.md +0 -397
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-traces.md +0 -98
- package/template/.agents/skills/integrations/posthog/references/llm-analytics-vercel-ai.md +0 -120
- package/template/.agents/skills/repo/repo-ci/SKILL.md +0 -265
- package/template/.agents/skills/repo/repo-init-next-js/SKILL.md +0 -129
- package/template/.agents/skills/repo/repo-init-next-js/references/file-contents.md +0 -800
- package/template/.agents/skills/repo/repo-init-next-js/scripts/setup.sh +0 -47
- package/template/.agents/skills/repo/repo-init-node/SKILL.md +0 -196
- package/template/.agents/skills/skill-creator/LICENSE.txt +0 -202
- package/template/.agents/skills/skill-creator/SKILL.md +0 -485
- package/template/.agents/skills/skill-creator/agents/analyzer.md +0 -274
- package/template/.agents/skills/skill-creator/agents/comparator.md +0 -202
- package/template/.agents/skills/skill-creator/agents/grader.md +0 -223
- package/template/.agents/skills/skill-creator/assets/eval_review.html +0 -146
- package/template/.agents/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/template/.agents/skills/skill-creator/eval-viewer/viewer.html +0 -1325
- package/template/.agents/skills/skill-creator/references/schemas.md +0 -430
- package/template/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/template/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/template/.agents/skills/skill-creator/scripts/generate_report.py +0 -326
- package/template/.agents/skills/skill-creator/scripts/improve_description.py +0 -247
- package/template/.agents/skills/skill-creator/scripts/package_skill.py +0 -136
- package/template/.agents/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/template/.agents/skills/skill-creator/scripts/run_eval.py +0 -310
- package/template/.agents/skills/skill-creator/scripts/run_loop.py +0 -328
- package/template/.agents/skills/skill-creator/scripts/utils.py +0 -47
- package/template/.agents/skills/supabase/CHANGELOG.md +0 -71
- package/template/.agents/skills/supabase/SKILL.md +0 -145
- package/template/.agents/skills/supabase/assets/feedback-issue-template.md +0 -17
- package/template/.agents/skills/supabase/references/skill-feedback.md +0 -17
- package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +0 -73
- package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +0 -64
- package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +0 -170
- package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +0 -39
- package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +0 -34
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +0 -55
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +0 -49
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +0 -46
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +0 -44
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +0 -41
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +0 -46
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +0 -54
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +0 -53
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +0 -50
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +0 -50
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +0 -56
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +0 -68
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +0 -50
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +0 -54
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +0 -45
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +0 -55
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +0 -55
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +0 -44
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +0 -40
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +0 -48
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +0 -43
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +0 -45
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +0 -80
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +0 -46
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +0 -59
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +0 -55
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +0 -55
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +0 -61
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +0 -54
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +0 -50
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +0 -63
- package/template/.agents/skills/writing/humanizer/SKILL.md +0 -621
- package/template/.agents/upstreams.json +0 -116
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
import { loadDesignSystemForTarget } from '../design-system.mjs';
|
|
6
|
-
import { RULE_SCOPES, filterByScopes } from '../registry/antipatterns.mjs';
|
|
7
|
-
import { createBrowserDetector, detectUrl } from '../engines/browser/detect-url.mjs';
|
|
8
|
-
import { detectHtml } from '../engines/static-html/detect-html.mjs';
|
|
9
|
-
import { detectText } from '../engines/regex/detect-text.mjs';
|
|
10
|
-
import {
|
|
11
|
-
filterDetectionFindings,
|
|
12
|
-
readDetectionConfig,
|
|
13
|
-
shouldIgnoreDetectionFile,
|
|
14
|
-
} from '../../lib/impeccable-config.mjs';
|
|
15
|
-
import {
|
|
16
|
-
HTML_EXTENSIONS,
|
|
17
|
-
buildImportGraph,
|
|
18
|
-
detectFrameworkConfig,
|
|
19
|
-
isPortListening,
|
|
20
|
-
walkDir,
|
|
21
|
-
} from '../node/file-system.mjs';
|
|
22
|
-
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
// Output formatting
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
|
|
27
|
-
function formatFindingSummary(count) {
|
|
28
|
-
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Local filesystem path behind a file:// URL, or null when it can't be mapped.
|
|
32
|
-
function fileUrlToLocalPath(url) {
|
|
33
|
-
try {
|
|
34
|
-
return fileURLToPath(url);
|
|
35
|
-
} catch {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Advisory findings are detected but never treated as failures: they list in a
|
|
41
|
-
// separate, visually dimmed section, are excluded from the failure count that
|
|
42
|
-
// drives the exit code, and carry `"advisory": true` in JSON so consumers can
|
|
43
|
-
// filter. Every advisory finding carries the flag (stamped by the registry via
|
|
44
|
-
// findings.mjs).
|
|
45
|
-
function isAdvisory(finding) {
|
|
46
|
-
return finding && finding.advisory === true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function partitionAdvisory(findings) {
|
|
50
|
-
const primary = [];
|
|
51
|
-
const advisory = [];
|
|
52
|
-
for (const f of findings) (isAdvisory(f) ? advisory : primary).push(f);
|
|
53
|
-
return { primary, advisory };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// ANSI dim, when stderr is a TTY. Advisory output is chrome, so keep it quiet.
|
|
57
|
-
function dim(text) {
|
|
58
|
-
return process.stderr.isTTY ? `\x1b[2m${text}\x1b[0m` : text;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function formatFindingsBody(findings) {
|
|
62
|
-
const grouped = {};
|
|
63
|
-
for (const f of findings) {
|
|
64
|
-
if (!grouped[f.file]) grouped[f.file] = [];
|
|
65
|
-
grouped[f.file].push(f);
|
|
66
|
-
}
|
|
67
|
-
const out = [];
|
|
68
|
-
for (const [file, items] of Object.entries(grouped)) {
|
|
69
|
-
const importNote = items[0]?.importedBy?.length ? ` (imported by ${items[0].importedBy.join(', ')})` : '';
|
|
70
|
-
out.push(`\n${file}${importNote}`);
|
|
71
|
-
for (const item of items) {
|
|
72
|
-
out.push(` ${item.line ? `line ${item.line}: ` : ''}[${item.antipattern}] ${item.snippet}`);
|
|
73
|
-
out.push(` → ${item.description}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return out;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function formatAdvisorySection(advisory) {
|
|
80
|
-
if (!advisory || advisory.length === 0) return '';
|
|
81
|
-
const lines = [`\n${dim('── Advisory (not counted as failures) ──')}`];
|
|
82
|
-
for (const line of formatFindingsBody(advisory)) lines.push(dim(line));
|
|
83
|
-
lines.push(dim(`\n${advisory.length} advisory note${advisory.length === 1 ? '' : 's'}. Suppress with --no-advisory.`));
|
|
84
|
-
return lines.join('\n');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Text/JSON formatter. `findings` is the full set; advisory items are separated
|
|
88
|
-
// out into their own section and excluded from the failure summary count. JSON
|
|
89
|
-
// output keeps every finding (each advisory one flagged) in a single array.
|
|
90
|
-
function formatFindings(findings, jsonMode) {
|
|
91
|
-
if (jsonMode) return JSON.stringify(findings, null, 2);
|
|
92
|
-
|
|
93
|
-
const { primary, advisory } = partitionAdvisory(findings);
|
|
94
|
-
const out = [...formatFindingsBody(primary)];
|
|
95
|
-
out.push(`\n${formatFindingSummary(primary.length)}`);
|
|
96
|
-
const advisorySection = formatAdvisorySection(advisory);
|
|
97
|
-
if (advisorySection) out.push(advisorySection);
|
|
98
|
-
return out.join('\n');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
// Stdin handling
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
|
-
|
|
105
|
-
// `optionsFor` maps a local path to scan options carrying that path's own
|
|
106
|
-
// project design system (or base options when null). Falls back to a plain
|
|
107
|
-
// object so direct/legacy callers still work.
|
|
108
|
-
async function handleStdin(optionsFor = () => ({})) {
|
|
109
|
-
const resolve = typeof optionsFor === 'function' ? optionsFor : () => optionsFor;
|
|
110
|
-
const chunks = [];
|
|
111
|
-
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
112
|
-
const input = Buffer.concat(chunks).toString('utf-8');
|
|
113
|
-
try {
|
|
114
|
-
const parsed = JSON.parse(input);
|
|
115
|
-
const fp = parsed?.tool_input?.file_path;
|
|
116
|
-
if (fp && fs.existsSync(fp)) {
|
|
117
|
-
const options = resolve(fp);
|
|
118
|
-
return HTML_EXTENSIONS.has(path.extname(fp).toLowerCase())
|
|
119
|
-
? detectHtml(fp, options) : detectText(fs.readFileSync(fp, 'utf-8'), fp, options);
|
|
120
|
-
}
|
|
121
|
-
} catch { /* not JSON */ }
|
|
122
|
-
return detectText(input, '<stdin>', resolve(null));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// ---------------------------------------------------------------------------
|
|
127
|
-
// CLI
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
|
|
130
|
-
async function confirm(question) {
|
|
131
|
-
const rl = (await import('node:readline')).default.createInterface({
|
|
132
|
-
input: process.stdin, output: process.stderr,
|
|
133
|
-
});
|
|
134
|
-
return new Promise((resolve) => {
|
|
135
|
-
rl.question(`${question} [Y/n] `, (answer) => {
|
|
136
|
-
rl.close();
|
|
137
|
-
resolve(!answer || /^y(es)?$/i.test(answer.trim()));
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function printUsage() {
|
|
143
|
-
console.log(`Usage: impeccable detect [options] [file-or-dir-or-url...]
|
|
144
|
-
|
|
145
|
-
Scan files or URLs for UI anti-patterns and design quality issues.
|
|
146
|
-
|
|
147
|
-
Options:
|
|
148
|
-
--json Output results as JSON
|
|
149
|
-
--quiet In text mode, only print the final findings count
|
|
150
|
-
--scope <name> Only report rules in the given design domain
|
|
151
|
-
(type, layout). Comma-separated.
|
|
152
|
-
--viewport <WxH> Browser viewport for URL scans (default 1280x800),
|
|
153
|
-
e.g. --viewport 390x844 for a mobile-width pass
|
|
154
|
-
--no-config Do not apply project config, detector ignores, inline
|
|
155
|
-
ignore comments, or DESIGN.md
|
|
156
|
-
--no-inline-ignores Do not honor in-file impeccable-disable* ignore comments
|
|
157
|
-
--no-design-system Do not load local DESIGN.md / .impeccable/design.json context
|
|
158
|
-
--no-advisory Suppress advisory findings entirely (e.g. em-dash overuse)
|
|
159
|
-
--help Show this help message
|
|
160
|
-
|
|
161
|
-
Advisory findings:
|
|
162
|
-
Some rules are advisory: detected and listed in a separate section, but never
|
|
163
|
-
counted as failures and never changing the exit code. They stay out of the
|
|
164
|
-
failure count so they never block automation. --no-advisory hides them.
|
|
165
|
-
|
|
166
|
-
Project config:
|
|
167
|
-
Respects .impeccable/config.json and .impeccable/config.local.json detector
|
|
168
|
-
settings: detector.ignoreRules, detector.ignoreFiles, detector.ignoreValues,
|
|
169
|
-
and detector.designSystem.enabled.
|
|
170
|
-
|
|
171
|
-
Inline ignores:
|
|
172
|
-
In-file comments waive a finding where it lives and travel with the file:
|
|
173
|
-
<!-- impeccable-disable overused-font -- exported brand doc -->
|
|
174
|
-
.brand { font-family: Inter } /* impeccable-disable-line overused-font */
|
|
175
|
-
// impeccable-disable-next-line bounce-easing: intentional bounce
|
|
176
|
-
impeccable-disable applies to the whole file; -line / -next-line are scoped.
|
|
177
|
-
List one or more rule ids (comma-separated), or omit them / use * for all.
|
|
178
|
-
|
|
179
|
-
Detection modes:
|
|
180
|
-
HTML files Static HTML/CSS analysis (default, catches linked CSS)
|
|
181
|
-
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
|
|
182
|
-
URLs Puppeteer full browser rendering (auto-detected;
|
|
183
|
-
http(s):// and file:// URLs)
|
|
184
|
-
|
|
185
|
-
Examples:
|
|
186
|
-
impeccable detect src/
|
|
187
|
-
impeccable detect index.html
|
|
188
|
-
impeccable detect https://example.com
|
|
189
|
-
impeccable detect --json .
|
|
190
|
-
impeccable detect --no-config src/`);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async function detectCli() {
|
|
194
|
-
let args = process.argv.slice(2).map(arg => {
|
|
195
|
-
if (arg === '-json') return '--json';
|
|
196
|
-
if (arg === '-fast') return '--fast';
|
|
197
|
-
return arg;
|
|
198
|
-
});
|
|
199
|
-
if (args[0] === 'detect') args = args.slice(1);
|
|
200
|
-
const jsonMode = args.includes('--json');
|
|
201
|
-
const quietMode = args.includes('--quiet');
|
|
202
|
-
const helpMode = args.includes('--help');
|
|
203
|
-
const noAdvisory = args.includes('--no-advisory');
|
|
204
|
-
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
|
205
|
-
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
|
206
|
-
// only loses coverage for no real speed win. Accept the flag for back-compat
|
|
207
|
-
// but ignore it and run the full scan.
|
|
208
|
-
if (args.includes('--fast')) {
|
|
209
|
-
process.stderr.write(
|
|
210
|
-
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
if (args.includes('--gpt') || args.includes('--gemini')) {
|
|
214
|
-
process.stderr.write(
|
|
215
|
-
'Note: --gpt and --gemini are deprecated and ignored. Generated-UI tells now run by default.\n',
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
const configEnabled = !args.includes('--no-config');
|
|
219
|
-
const detectionConfig = configEnabled
|
|
220
|
-
? readDetectionConfig(process.cwd())
|
|
221
|
-
: { ignoreRules: [], ignoreFiles: [], ignoreValues: [] };
|
|
222
|
-
const scopes = [];
|
|
223
|
-
for (let i = 0; i < args.length; i++) {
|
|
224
|
-
if (args[i] !== '--scope' && !args[i].startsWith('--scope=')) continue;
|
|
225
|
-
const inline = args[i].startsWith('--scope=');
|
|
226
|
-
const value = inline ? args[i].slice('--scope='.length) : args[i + 1];
|
|
227
|
-
const parsed = (value && !value.startsWith('--'))
|
|
228
|
-
? value.split(',').map(s => s.trim()).filter(Boolean)
|
|
229
|
-
: [];
|
|
230
|
-
// A bare `--scope` would otherwise fall out of `targets` and scan unscoped;
|
|
231
|
-
// fail loudly so a mistyped pre-scan never runs the wrong rule set.
|
|
232
|
-
if (parsed.length === 0) {
|
|
233
|
-
process.stderr.write(
|
|
234
|
-
`Error: --scope requires a value. Valid scopes: ${[...RULE_SCOPES].join(', ')}\n`,
|
|
235
|
-
);
|
|
236
|
-
process.exit(1);
|
|
237
|
-
}
|
|
238
|
-
scopes.push(...parsed);
|
|
239
|
-
args.splice(i, inline ? 1 : 2);
|
|
240
|
-
i -= 1;
|
|
241
|
-
}
|
|
242
|
-
let viewport = null;
|
|
243
|
-
for (let i = 0; i < args.length; i++) {
|
|
244
|
-
if (args[i] !== '--viewport' && !args[i].startsWith('--viewport=')) continue;
|
|
245
|
-
const inline = args[i].startsWith('--viewport=');
|
|
246
|
-
const value = inline ? args[i].slice('--viewport='.length) : args[i + 1];
|
|
247
|
-
const match = /^(\d{2,5})x(\d{2,5})$/i.exec(value || '');
|
|
248
|
-
if (!match) {
|
|
249
|
-
process.stderr.write('Error: --viewport requires a WxH value, e.g. --viewport 390x844\n');
|
|
250
|
-
process.exit(1);
|
|
251
|
-
}
|
|
252
|
-
viewport = { width: Number(match[1]), height: Number(match[2]) };
|
|
253
|
-
args.splice(i, inline ? 1 : 2);
|
|
254
|
-
i -= 1;
|
|
255
|
-
}
|
|
256
|
-
const unknownScopes = scopes.filter(s => !RULE_SCOPES.has(s));
|
|
257
|
-
if (unknownScopes.length > 0) {
|
|
258
|
-
process.stderr.write(
|
|
259
|
-
`Error: unknown --scope value(s): ${unknownScopes.join(', ')}. Valid scopes: ${[...RULE_SCOPES].join(', ')}\n`,
|
|
260
|
-
);
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
const designSystemEnabled = configEnabled && !args.includes('--no-design-system') && detectionConfig.designSystem?.enabled !== false;
|
|
264
|
-
// Inline `impeccable-disable*` waivers are part of the scanned file, so they
|
|
265
|
-
// apply by default. `--no-config` (raw scan) and the dedicated
|
|
266
|
-
// `--no-inline-ignores` both turn them off.
|
|
267
|
-
const inlineIgnoresEnabled = configEnabled && !args.includes('--no-inline-ignores');
|
|
268
|
-
const baseScanOptions = { inlineIgnores: inlineIgnoresEnabled };
|
|
269
|
-
if (viewport) baseScanOptions.viewport = viewport;
|
|
270
|
-
// DESIGN.md must resolve from EACH scan target's own project root, not from
|
|
271
|
-
// process.cwd(): scanning project B's files from inside project A applied A's
|
|
272
|
-
// design rules (cross-project contamination). Resolve per target, memoized by
|
|
273
|
-
// resolved project root so a multi-file scan pays the read once per project.
|
|
274
|
-
// A target with no project marker above it gets no design system (never cwd's).
|
|
275
|
-
const designSystemCache = new Map();
|
|
276
|
-
const scanOptionsFor = (localPath) => {
|
|
277
|
-
if (!designSystemEnabled || !localPath) return baseScanOptions;
|
|
278
|
-
const designSystem = loadDesignSystemForTarget(localPath, { cache: designSystemCache });
|
|
279
|
-
return designSystem ? { ...baseScanOptions, designSystem } : baseScanOptions;
|
|
280
|
-
};
|
|
281
|
-
const targets = args.filter(a => !a.startsWith('--'));
|
|
282
|
-
|
|
283
|
-
if (helpMode) { printUsage(); process.exit(0); }
|
|
284
|
-
|
|
285
|
-
let allFindings = [];
|
|
286
|
-
|
|
287
|
-
if (!process.stdin.isTTY && targets.length === 0) {
|
|
288
|
-
allFindings = await handleStdin(scanOptionsFor);
|
|
289
|
-
} else {
|
|
290
|
-
const paths = targets.length > 0 ? targets : [process.cwd()];
|
|
291
|
-
// file:// URLs get the same Puppeteer-rendered pass as http(s) — the
|
|
292
|
-
// real cascade, real computed styles, real layout. Callers that want a
|
|
293
|
-
// browser-grade scan of a local artifact can pass file:///abs/path.html
|
|
294
|
-
// instead of the bare path (which stays on the static engine).
|
|
295
|
-
const urlRe = /^(?:https?|file):\/\//i;
|
|
296
|
-
const urlTargetCount = paths.filter(target => urlRe.test(target)).length;
|
|
297
|
-
const browserDetector = urlTargetCount > 1 ? await createBrowserDetector() : null;
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
for (const target of paths) {
|
|
301
|
-
if (urlRe.test(target)) {
|
|
302
|
-
// A file:// URL points at a local artifact, so its design system
|
|
303
|
-
// resolves from that file's project. A remote http(s) URL has no
|
|
304
|
-
// local project — it gets base options (no design system), never
|
|
305
|
-
// process.cwd()'s.
|
|
306
|
-
const urlOptions = /^file:/i.test(target)
|
|
307
|
-
? scanOptionsFor(fileUrlToLocalPath(target))
|
|
308
|
-
: baseScanOptions;
|
|
309
|
-
try {
|
|
310
|
-
const scanner = browserDetector
|
|
311
|
-
? (url) => browserDetector.detectUrl(url, urlOptions)
|
|
312
|
-
: (url) => detectUrl(url, urlOptions);
|
|
313
|
-
allFindings.push(...await scanner(target));
|
|
314
|
-
} catch (e) { process.stderr.write(`Error: ${e.message}\n`); }
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const resolved = path.resolve(target);
|
|
319
|
-
let stat;
|
|
320
|
-
try { stat = fs.statSync(resolved); }
|
|
321
|
-
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
|
322
|
-
|
|
323
|
-
if (stat.isDirectory()) {
|
|
324
|
-
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
|
325
|
-
if (!jsonMode && !quietMode) {
|
|
326
|
-
const fwConfig = detectFrameworkConfig(resolved);
|
|
327
|
-
if (fwConfig) {
|
|
328
|
-
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
|
329
|
-
if (probe.listening && probe.matched) {
|
|
330
|
-
process.stderr.write(
|
|
331
|
-
`\n${fwConfig.name} dev server detected on localhost:${fwConfig.port}.\n` +
|
|
332
|
-
`For more accurate results, scan the running site:\n` +
|
|
333
|
-
` npx impeccable detect http://localhost:${fwConfig.port}\n\n`
|
|
334
|
-
);
|
|
335
|
-
} else if (probe.listening && !probe.matched) {
|
|
336
|
-
process.stderr.write(
|
|
337
|
-
`\n${fwConfig.name} project detected (${path.basename(fwConfig.configPath)}).\n` +
|
|
338
|
-
`Port ${fwConfig.port} is in use by another service. Start the ${fwConfig.name} dev server and scan via URL for best results.\n\n`
|
|
339
|
-
);
|
|
340
|
-
} else {
|
|
341
|
-
process.stderr.write(
|
|
342
|
-
`\n${fwConfig.name} project detected (${path.basename(fwConfig.configPath)}).\n` +
|
|
343
|
-
`Start the dev server and scan via URL for best results:\n` +
|
|
344
|
-
` npx impeccable detect http://localhost:${fwConfig.port}\n\n`
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const files = walkDir(resolved)
|
|
351
|
-
.filter(file => !shouldIgnoreDetectionFile(file, process.cwd(), detectionConfig));
|
|
352
|
-
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
|
353
|
-
|
|
354
|
-
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
|
355
|
-
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
|
356
|
-
process.stderr.write(
|
|
357
|
-
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
|
358
|
-
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
|
359
|
-
`Target a specific subdirectory to narrow scope.\n`
|
|
360
|
-
);
|
|
361
|
-
const ok = await confirm('Continue?');
|
|
362
|
-
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Build import graph for multi-file awareness
|
|
366
|
-
const graph = buildImportGraph(files);
|
|
367
|
-
// Build reverse map: file -> set of files that import it
|
|
368
|
-
const importedByMap = new Map();
|
|
369
|
-
for (const [importer, imports] of graph) {
|
|
370
|
-
for (const imported of imports) {
|
|
371
|
-
if (!importedByMap.has(imported)) importedByMap.set(imported, new Set());
|
|
372
|
-
importedByMap.get(imported).add(importer);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
for (const file of files) {
|
|
377
|
-
const ext = path.extname(file).toLowerCase();
|
|
378
|
-
// Each file resolves its own project design system (cached by root),
|
|
379
|
-
// so a scan spanning sibling projects applies the right rules per file.
|
|
380
|
-
const fileOptions = scanOptionsFor(file);
|
|
381
|
-
let fileFindings;
|
|
382
|
-
if (HTML_EXTENSIONS.has(ext)) {
|
|
383
|
-
fileFindings = await detectHtml(file, fileOptions);
|
|
384
|
-
} else {
|
|
385
|
-
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, fileOptions);
|
|
386
|
-
}
|
|
387
|
-
// Annotate findings with import context
|
|
388
|
-
const importers = importedByMap.get(file);
|
|
389
|
-
if (importers && importers.size > 0) {
|
|
390
|
-
const importerNames = [...importers].map(f => path.basename(f));
|
|
391
|
-
for (const f of fileFindings) {
|
|
392
|
-
f.importedBy = importerNames;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
allFindings.push(...fileFindings);
|
|
396
|
-
}
|
|
397
|
-
} else if (stat.isFile()) {
|
|
398
|
-
if (shouldIgnoreDetectionFile(resolved, process.cwd(), detectionConfig)) continue;
|
|
399
|
-
const ext = path.extname(resolved).toLowerCase();
|
|
400
|
-
const fileOptions = scanOptionsFor(resolved);
|
|
401
|
-
if (HTML_EXTENSIONS.has(ext)) {
|
|
402
|
-
allFindings.push(...await detectHtml(resolved, fileOptions));
|
|
403
|
-
} else {
|
|
404
|
-
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, fileOptions));
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
} finally {
|
|
409
|
-
if (browserDetector) await browserDetector.close();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
allFindings = filterDetectionFindings(allFindings, detectionConfig);
|
|
414
|
-
allFindings = filterByScopes(allFindings, scopes);
|
|
415
|
-
// --no-advisory drops advisory findings before any output or exit-code math.
|
|
416
|
-
if (noAdvisory) allFindings = allFindings.filter((f) => !isAdvisory(f));
|
|
417
|
-
|
|
418
|
-
// The exit code and failure count reflect non-advisory findings only. An
|
|
419
|
-
// advisory-only scan still prints its notes but exits 0 (a clean pass), so
|
|
420
|
-
// advisory rules never break CI or block automation.
|
|
421
|
-
const { primary, advisory } = partitionAdvisory(allFindings);
|
|
422
|
-
|
|
423
|
-
if (allFindings.length > 0) {
|
|
424
|
-
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
|
425
|
-
else if (quietMode) {
|
|
426
|
-
process.stderr.write(formatFindingSummary(primary.length) + '\n');
|
|
427
|
-
if (advisory.length > 0) {
|
|
428
|
-
process.stderr.write(dim(`${advisory.length} advisory note${advisory.length === 1 ? '' : 's'} (not counted).`) + '\n');
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
|
432
|
-
process.exit(primary.length > 0 ? 2 : 0);
|
|
433
|
-
}
|
|
434
|
-
if (jsonMode) process.stdout.write('[]\n');
|
|
435
|
-
process.exit(0);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
export { formatFindings, handleStdin, confirm, printUsage, detectCli };
|