quiver-cli 1.3.1 → 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.
Files changed (407) hide show
  1. package/README.md +197 -239
  2. package/dist/cli.js +3163 -2040
  3. package/package.json +10 -11
  4. package/template/.agents/AGENTS.md +0 -26
  5. package/template/.agents/commands/cp.md +0 -108
  6. package/template/.agents/commands/next-setup.md +0 -1064
  7. package/template/.agents/commands/review.md +0 -68
  8. package/template/.agents/commands/terraform-readme.md +0 -38
  9. package/template/.agents/config.json +0 -80
  10. package/template/.agents/plugins/opencode/rtk.ts +0 -34
  11. package/template/.agents/skills/agent-browser/SKILL.md +0 -52
  12. package/template/.agents/skills/apps/skybridge/SKILL.md +0 -52
  13. package/template/.agents/skills/code/cleanup/SKILL.md +0 -26
  14. package/template/.agents/skills/code/improve/SKILL.md +0 -122
  15. package/template/.agents/skills/code/improve/references/audit-playbook.md +0 -130
  16. package/template/.agents/skills/code/improve/references/closing-the-loop.md +0 -96
  17. package/template/.agents/skills/code/improve/references/plan-template.md +0 -197
  18. package/template/.agents/skills/code/vercel-react-best-practices/AGENTS.md +0 -3810
  19. package/template/.agents/skills/code/vercel-react-best-practices/README.md +0 -123
  20. package/template/.agents/skills/code/vercel-react-best-practices/SKILL.md +0 -149
  21. package/template/.agents/skills/code/vercel-react-best-practices/metadata.json +0 -15
  22. package/template/.agents/skills/code/vercel-react-best-practices/rules/_sections.md +0 -46
  23. package/template/.agents/skills/code/vercel-react-best-practices/rules/_template.md +0 -28
  24. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-effect-event-deps.md +0 -56
  25. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  26. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  27. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  28. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  29. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +0 -37
  30. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-defer-await.md +0 -82
  31. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  32. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-parallel.md +0 -28
  33. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  34. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-analyzable-paths.md +0 -63
  35. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -60
  36. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  37. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  38. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  39. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  40. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  41. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  42. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  43. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  44. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  45. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  46. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  47. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  48. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  49. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  50. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  51. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  52. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  53. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  54. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  55. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-request-idle-callback.md +0 -105
  56. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  57. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  58. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  59. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  60. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  61. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  62. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  63. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  64. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  65. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  66. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  67. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  68. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  69. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  70. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  71. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  72. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  73. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  74. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  75. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  76. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  77. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  78. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  79. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  80. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  81. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  82. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  83. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  84. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  85. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  86. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  87. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  88. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  89. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -149
  90. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-no-shared-module-state.md +0 -50
  91. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  92. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +0 -34
  93. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-serialization.md +0 -38
  94. package/template/.agents/skills/data/prisma-cli/SKILL.md +0 -265
  95. package/template/.agents/skills/data/prisma-cli/references/agent-safety.md +0 -27
  96. package/template/.agents/skills/data/prisma-cli/references/complete.md +0 -22
  97. package/template/.agents/skills/data/prisma-cli/references/db-execute.md +0 -78
  98. package/template/.agents/skills/data/prisma-cli/references/db-pull.md +0 -185
  99. package/template/.agents/skills/data/prisma-cli/references/db-push.md +0 -150
  100. package/template/.agents/skills/data/prisma-cli/references/db-seed.md +0 -188
  101. package/template/.agents/skills/data/prisma-cli/references/debug.md +0 -46
  102. package/template/.agents/skills/data/prisma-cli/references/dev.md +0 -157
  103. package/template/.agents/skills/data/prisma-cli/references/format.md +0 -48
  104. package/template/.agents/skills/data/prisma-cli/references/generate.md +0 -173
  105. package/template/.agents/skills/data/prisma-cli/references/init.md +0 -139
  106. package/template/.agents/skills/data/prisma-cli/references/mcp.md +0 -39
  107. package/template/.agents/skills/data/prisma-cli/references/migrate-deploy.md +0 -127
  108. package/template/.agents/skills/data/prisma-cli/references/migrate-dev.md +0 -145
  109. package/template/.agents/skills/data/prisma-cli/references/migrate-diff.md +0 -89
  110. package/template/.agents/skills/data/prisma-cli/references/migrate-reset.md +0 -80
  111. package/template/.agents/skills/data/prisma-cli/references/migrate-resolve.md +0 -57
  112. package/template/.agents/skills/data/prisma-cli/references/migrate-status.md +0 -65
  113. package/template/.agents/skills/data/prisma-cli/references/studio.md +0 -137
  114. package/template/.agents/skills/data/prisma-cli/references/validate.md +0 -53
  115. package/template/.agents/skills/data/prisma-client-api/SKILL.md +0 -216
  116. package/template/.agents/skills/data/prisma-client-api/references/client-methods.md +0 -223
  117. package/template/.agents/skills/data/prisma-client-api/references/constructor.md +0 -221
  118. package/template/.agents/skills/data/prisma-client-api/references/filters.md +0 -256
  119. package/template/.agents/skills/data/prisma-client-api/references/model-queries.md +0 -281
  120. package/template/.agents/skills/data/prisma-client-api/references/query-options.md +0 -276
  121. package/template/.agents/skills/data/prisma-client-api/references/raw-queries.md +0 -198
  122. package/template/.agents/skills/data/prisma-client-api/references/relations.md +0 -308
  123. package/template/.agents/skills/data/prisma-client-api/references/transactions.md +0 -184
  124. package/template/.agents/skills/design/impeccable/SKILL.md +0 -84
  125. package/template/.agents/skills/design/impeccable/reference/adapt.md +0 -312
  126. package/template/.agents/skills/design/impeccable/reference/adapt.native.md +0 -58
  127. package/template/.agents/skills/design/impeccable/reference/android.md +0 -46
  128. package/template/.agents/skills/design/impeccable/reference/animate.md +0 -89
  129. package/template/.agents/skills/design/impeccable/reference/audit.md +0 -136
  130. package/template/.agents/skills/design/impeccable/reference/audit.native.md +0 -139
  131. package/template/.agents/skills/design/impeccable/reference/bolder.md +0 -33
  132. package/template/.agents/skills/design/impeccable/reference/clarify.md +0 -94
  133. package/template/.agents/skills/design/impeccable/reference/colorize.md +0 -86
  134. package/template/.agents/skills/design/impeccable/reference/craft-floor.md +0 -44
  135. package/template/.agents/skills/design/impeccable/reference/craft.md +0 -5
  136. package/template/.agents/skills/design/impeccable/reference/critique.md +0 -806
  137. package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +0 -37
  138. package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +0 -24
  139. package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +0 -38
  140. package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +0 -92
  141. package/template/.agents/skills/design/impeccable/reference/delight.md +0 -70
  142. package/template/.agents/skills/design/impeccable/reference/distill.md +0 -111
  143. package/template/.agents/skills/design/impeccable/reference/doctor.md +0 -54
  144. package/template/.agents/skills/design/impeccable/reference/document.md +0 -416
  145. package/template/.agents/skills/design/impeccable/reference/extract.md +0 -69
  146. package/template/.agents/skills/design/impeccable/reference/harden.md +0 -336
  147. package/template/.agents/skills/design/impeccable/reference/hooks.md +0 -111
  148. package/template/.agents/skills/design/impeccable/reference/init.md +0 -131
  149. package/template/.agents/skills/design/impeccable/reference/ios.md +0 -51
  150. package/template/.agents/skills/design/impeccable/reference/layout.md +0 -84
  151. package/template/.agents/skills/design/impeccable/reference/live-setup.md +0 -102
  152. package/template/.agents/skills/design/impeccable/reference/live.md +0 -323
  153. package/template/.agents/skills/design/impeccable/reference/new-work.md +0 -145
  154. package/template/.agents/skills/design/impeccable/reference/onboard.md +0 -234
  155. package/template/.agents/skills/design/impeccable/reference/operate.md +0 -61
  156. package/template/.agents/skills/design/impeccable/reference/optimize.md +0 -258
  157. package/template/.agents/skills/design/impeccable/reference/overdrive.md +0 -127
  158. package/template/.agents/skills/design/impeccable/reference/polish.md +0 -105
  159. package/template/.agents/skills/design/impeccable/reference/quieter.md +0 -99
  160. package/template/.agents/skills/design/impeccable/reference/routing.md +0 -18
  161. package/template/.agents/skills/design/impeccable/reference/shape.md +0 -59
  162. package/template/.agents/skills/design/impeccable/reference/typeset.md +0 -80
  163. package/template/.agents/skills/design/impeccable/reference/visualize.md +0 -46
  164. package/template/.agents/skills/design/impeccable/scripts/build-phase.mjs +0 -1022
  165. package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +0 -94
  166. package/template/.agents/skills/design/impeccable/scripts/comp-diff.mjs +0 -391
  167. package/template/.agents/skills/design/impeccable/scripts/comp-spec.mjs +0 -513
  168. package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +0 -814
  169. package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +0 -325
  170. package/template/.agents/skills/design/impeccable/scripts/context.mjs +0 -1565
  171. package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +0 -473
  172. package/template/.agents/skills/design/impeccable/scripts/data/font-index-failures.json +0 -121
  173. package/template/.agents/skills/design/impeccable/scripts/data/font-index.json +0 -1
  174. package/template/.agents/skills/design/impeccable/scripts/detect-csp.mjs +0 -198
  175. package/template/.agents/skills/design/impeccable/scripts/detect.mjs +0 -30
  176. package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +0 -2204
  177. package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +0 -432
  178. package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +0 -1311
  179. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +0 -9043
  180. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +0 -51
  181. package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +0 -434
  182. package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +0 -1319
  183. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +0 -1241
  184. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +0 -288
  185. package/template/.agents/skills/design/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +0 -189
  186. package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +0 -18
  187. package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +0 -213
  188. package/template/.agents/skills/design/impeccable/scripts/detector/profile/profiler.mjs +0 -166
  189. package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +0 -635
  190. package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +0 -5681
  191. package/template/.agents/skills/design/impeccable/scripts/detector/shared/color.mjs +0 -596
  192. package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +0 -127
  193. package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +0 -30
  194. package/template/.agents/skills/design/impeccable/scripts/detector/shared/inline-ignores.mjs +0 -148
  195. package/template/.agents/skills/design/impeccable/scripts/detector/shared/page.mjs +0 -7
  196. package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +0 -329
  197. package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +0 -166
  198. package/template/.agents/skills/design/impeccable/scripts/font-match.mjs +0 -457
  199. package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +0 -447
  200. package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +0 -819
  201. package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +0 -538
  202. package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +0 -2490
  203. package/template/.agents/skills/design/impeccable/scripts/hook.mjs +0 -79
  204. package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +0 -93
  205. package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +0 -200
  206. package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +0 -396
  207. package/template/.agents/skills/design/impeccable/scripts/lib/design-parser.mjs +0 -880
  208. package/template/.agents/skills/design/impeccable/scripts/lib/font-fingerprint.mjs +0 -564
  209. package/template/.agents/skills/design/impeccable/scripts/lib/font-index.mjs +0 -130
  210. package/template/.agents/skills/design/impeccable/scripts/lib/hero-checks.mjs +0 -246
  211. package/template/.agents/skills/design/impeccable/scripts/lib/image-metrics.mjs +0 -306
  212. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +0 -640
  213. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +0 -137
  214. package/template/.agents/skills/design/impeccable/scripts/lib/is-generated.mjs +0 -72
  215. package/template/.agents/skills/design/impeccable/scripts/lib/live-path-globs.mjs +0 -37
  216. package/template/.agents/skills/design/impeccable/scripts/lib/open-system-browser.mjs +0 -26
  217. package/template/.agents/skills/design/impeccable/scripts/lib/png.mjs +0 -281
  218. package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +0 -5
  219. package/template/.agents/skills/design/impeccable/scripts/lib/raster.mjs +0 -194
  220. package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +0 -369
  221. package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +0 -485
  222. package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +0 -169
  223. package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +0 -533
  224. package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +0 -149
  225. package/template/.agents/skills/design/impeccable/scripts/lib/target-args.mjs +0 -42
  226. package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +0 -33
  227. package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +0 -146
  228. package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +0 -617
  229. package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +0 -60
  230. package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +0 -84
  231. package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +0 -28
  232. package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +0 -199
  233. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +0 -47
  234. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +0 -73
  235. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +0 -143
  236. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +0 -197
  237. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +0 -49
  238. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +0 -161
  239. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +0 -17
  240. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +0 -26
  241. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +0 -71
  242. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +0 -247
  243. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +0 -70
  244. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +0 -42
  245. package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +0 -149
  246. package/template/.agents/skills/design/impeccable/scripts/live/insert-ui.mjs +0 -458
  247. package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +0 -142
  248. package/template/.agents/skills/design/impeccable/scripts/live/manual-apply.mjs +0 -939
  249. package/template/.agents/skills/design/impeccable/scripts/live/manual-edit-routes.mjs +0 -357
  250. package/template/.agents/skills/design/impeccable/scripts/live/manual-edits-buffer.mjs +0 -152
  251. package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +0 -14
  252. package/template/.agents/skills/design/impeccable/scripts/live/project-ignores.mjs +0 -139
  253. package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +0 -508
  254. package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +0 -563
  255. package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +0 -105
  256. package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +0 -105
  257. package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +0 -969
  258. package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +0 -1366
  259. package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +0 -304
  260. package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +0 -259
  261. package/template/.agents/skills/design/impeccable/scripts/live/ui-surfaces.mjs +0 -75
  262. package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +0 -171
  263. package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +0 -938
  264. package/template/.agents/skills/design/impeccable/scripts/live-browser-dom.js +0 -146
  265. package/template/.agents/skills/design/impeccable/scripts/live-browser-ignores.js +0 -242
  266. package/template/.agents/skills/design/impeccable/scripts/live-browser-session.js +0 -123
  267. package/template/.agents/skills/design/impeccable/scripts/live-browser.js +0 -12551
  268. package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +0 -1200
  269. package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +0 -107
  270. package/template/.agents/skills/design/impeccable/scripts/live-copy-edit-agent.mjs +0 -800
  271. package/template/.agents/skills/design/impeccable/scripts/live-discard-manual-edits.mjs +0 -51
  272. package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +0 -463
  273. package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +0 -292
  274. package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +0 -368
  275. package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +0 -430
  276. package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +0 -123
  277. package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +0 -1698
  278. package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +0 -71
  279. package/template/.agents/skills/design/impeccable/scripts/live-target.mjs +0 -30
  280. package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +0 -927
  281. package/template/.agents/skills/design/impeccable/scripts/live.mjs +0 -334
  282. package/template/.agents/skills/design/impeccable/scripts/modern-screenshot.umd.js +0 -14
  283. package/template/.agents/skills/design/impeccable/scripts/palette.mjs +0 -628
  284. package/template/.agents/skills/design/impeccable/scripts/pin.mjs +0 -224
  285. package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +0 -1783
  286. package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +0 -74
  287. package/template/.agents/skills/design/shadcn/SKILL.md +0 -277
  288. package/template/.agents/skills/design/shadcn/agents/openai.yml +0 -5
  289. package/template/.agents/skills/design/shadcn/assets/shadcn-small.png +0 -0
  290. package/template/.agents/skills/design/shadcn/assets/shadcn.png +0 -0
  291. package/template/.agents/skills/design/shadcn/cli.md +0 -290
  292. package/template/.agents/skills/design/shadcn/customization.md +0 -209
  293. package/template/.agents/skills/design/shadcn/evals/evals.json +0 -77
  294. package/template/.agents/skills/design/shadcn/mcp.md +0 -105
  295. package/template/.agents/skills/design/shadcn/registry.md +0 -277
  296. package/template/.agents/skills/design/shadcn/rules/base-vs-radix.md +0 -306
  297. package/template/.agents/skills/design/shadcn/rules/chat.md +0 -250
  298. package/template/.agents/skills/design/shadcn/rules/composition.md +0 -213
  299. package/template/.agents/skills/design/shadcn/rules/forms.md +0 -192
  300. package/template/.agents/skills/design/shadcn/rules/icons.md +0 -101
  301. package/template/.agents/skills/design/shadcn/rules/styling.md +0 -185
  302. package/template/.agents/skills/find-skills/SKILL.md +0 -141
  303. package/template/.agents/skills/hono/SKILL.md +0 -593
  304. package/template/.agents/skills/integrations/langfuse/SKILL.md +0 -150
  305. package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +0 -41
  306. package/template/.agents/skills/integrations/langfuse/references/cli.md +0 -60
  307. package/template/.agents/skills/integrations/langfuse/references/create-dataset.md +0 -35
  308. package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +0 -87
  309. package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +0 -121
  310. package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +0 -293
  311. package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +0 -35
  312. package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +0 -79
  313. package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +0 -34
  314. package/template/.agents/skills/integrations/langfuse/references/setting-up-evals.md +0 -65
  315. package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +0 -35
  316. package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +0 -76
  317. package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +0 -66
  318. package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +0 -75
  319. package/template/.agents/skills/integrations/posthog/SKILL.md +0 -102
  320. package/template/.agents/skills/integrations/posthog/references/error-tracking-alerts.md +0 -63
  321. package/template/.agents/skills/integrations/posthog/references/error-tracking-assigning-issues.md +0 -77
  322. package/template/.agents/skills/integrations/posthog/references/error-tracking-fingerprints.md +0 -57
  323. package/template/.agents/skills/integrations/posthog/references/error-tracking-monitoring.md +0 -140
  324. package/template/.agents/skills/integrations/posthog/references/error-tracking-nextjs.md +0 -490
  325. package/template/.agents/skills/integrations/posthog/references/error-tracking-source-maps.md +0 -45
  326. package/template/.agents/skills/integrations/posthog/references/feature-flags-best-practices.md +0 -139
  327. package/template/.agents/skills/integrations/posthog/references/feature-flags-react.md +0 -302
  328. package/template/.agents/skills/integrations/posthog/references/identify-users.md +0 -202
  329. package/template/.agents/skills/integrations/posthog/references/integration-example.md +0 -706
  330. package/template/.agents/skills/integrations/posthog/references/integration-nextjs.md +0 -385
  331. package/template/.agents/skills/integrations/posthog/references/integration-step-1-begin.md +0 -43
  332. package/template/.agents/skills/integrations/posthog/references/integration-step-2-edit.md +0 -37
  333. package/template/.agents/skills/integrations/posthog/references/integration-step-3-revise.md +0 -22
  334. package/template/.agents/skills/integrations/posthog/references/integration-step-4-conclude.md +0 -38
  335. package/template/.agents/skills/integrations/posthog/references/llm-analytics-anthropic.md +0 -200
  336. package/template/.agents/skills/integrations/posthog/references/llm-analytics-basics.md +0 -62
  337. package/template/.agents/skills/integrations/posthog/references/llm-analytics-costs.md +0 -197
  338. package/template/.agents/skills/integrations/posthog/references/llm-analytics-manual-capture.md +0 -397
  339. package/template/.agents/skills/integrations/posthog/references/llm-analytics-traces.md +0 -98
  340. package/template/.agents/skills/integrations/posthog/references/llm-analytics-vercel-ai.md +0 -120
  341. package/template/.agents/skills/repo/repo-ci/SKILL.md +0 -265
  342. package/template/.agents/skills/repo/repo-init-next-js/SKILL.md +0 -129
  343. package/template/.agents/skills/repo/repo-init-next-js/references/file-contents.md +0 -800
  344. package/template/.agents/skills/repo/repo-init-next-js/scripts/setup.sh +0 -47
  345. package/template/.agents/skills/repo/repo-init-node/SKILL.md +0 -196
  346. package/template/.agents/skills/skill-creator/LICENSE.txt +0 -202
  347. package/template/.agents/skills/skill-creator/SKILL.md +0 -485
  348. package/template/.agents/skills/skill-creator/agents/analyzer.md +0 -274
  349. package/template/.agents/skills/skill-creator/agents/comparator.md +0 -202
  350. package/template/.agents/skills/skill-creator/agents/grader.md +0 -223
  351. package/template/.agents/skills/skill-creator/assets/eval_review.html +0 -146
  352. package/template/.agents/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  353. package/template/.agents/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  354. package/template/.agents/skills/skill-creator/references/schemas.md +0 -430
  355. package/template/.agents/skills/skill-creator/scripts/__init__.py +0 -0
  356. package/template/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  357. package/template/.agents/skills/skill-creator/scripts/generate_report.py +0 -326
  358. package/template/.agents/skills/skill-creator/scripts/improve_description.py +0 -247
  359. package/template/.agents/skills/skill-creator/scripts/package_skill.py +0 -136
  360. package/template/.agents/skills/skill-creator/scripts/quick_validate.py +0 -103
  361. package/template/.agents/skills/skill-creator/scripts/run_eval.py +0 -310
  362. package/template/.agents/skills/skill-creator/scripts/run_loop.py +0 -328
  363. package/template/.agents/skills/skill-creator/scripts/utils.py +0 -47
  364. package/template/.agents/skills/supabase/CHANGELOG.md +0 -78
  365. package/template/.agents/skills/supabase/SKILL.md +0 -149
  366. package/template/.agents/skills/supabase/assets/feedback-issue-template.md +0 -17
  367. package/template/.agents/skills/supabase/references/skill-feedback.md +0 -17
  368. package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +0 -73
  369. package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +0 -64
  370. package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +0 -170
  371. package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +0 -39
  372. package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +0 -34
  373. package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +0 -55
  374. package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +0 -49
  375. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +0 -46
  376. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +0 -44
  377. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +0 -41
  378. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +0 -46
  379. package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +0 -54
  380. package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +0 -53
  381. package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +0 -50
  382. package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +0 -50
  383. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +0 -56
  384. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +0 -68
  385. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +0 -50
  386. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +0 -54
  387. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +0 -45
  388. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +0 -55
  389. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +0 -55
  390. package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +0 -44
  391. package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +0 -40
  392. package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +0 -48
  393. package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +0 -43
  394. package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +0 -45
  395. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +0 -80
  396. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +0 -46
  397. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +0 -59
  398. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +0 -55
  399. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +0 -55
  400. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +0 -61
  401. package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +0 -54
  402. package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +0 -50
  403. package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +0 -63
  404. package/template/.agents/skills/writing/humanizer/LICENSE +0 -21
  405. package/template/.agents/skills/writing/humanizer/README.md +0 -209
  406. package/template/.agents/skills/writing/humanizer/SKILL.md +0 -456
  407. package/template/.agents/upstreams.json +0 -115
@@ -1,485 +0,0 @@
1
- /**
2
- * Tier 2 staleness checks: the ones that cost too much to run on every session
3
- * boot. Shelling out to git, walking workspaces, resolving hook script paths,
4
- * and validating ignore lists against the live rule registry all belong here.
5
- *
6
- * The boot tier answers "did an older Impeccable write this". This tier also
7
- * asks "does it still describe the code", which no file comparison can settle
8
- * on its own. Where the answer needs judgment, the finding reports a measured
9
- * proxy and says it is a proxy. It never claims a document is wrong because a
10
- * number is large.
11
- *
12
- * Same finding shape and severities as lib/staleness.mjs.
13
- */
14
-
15
- import fs from 'node:fs';
16
- import path from 'node:path';
17
- import { execFileSync } from 'node:child_process';
18
- import { fileURLToPath, pathToFileURL } from 'node:url';
19
-
20
- const VISUAL_SOURCE_DIRS = ['src', 'app', 'pages', 'components', 'site', 'styles', 'public'];
21
-
22
- const HOOK_MANIFESTS_BY_PROVIDER = Object.freeze({
23
- 'claude-code': ['.claude/settings.local.json', '.claude/settings.json'],
24
- codex: ['.codex/hooks.json'],
25
- agents: ['.codex/hooks.json'],
26
- cursor: ['.cursor/hooks.json'],
27
- github: ['.github/hooks/impeccable.json'],
28
- grok: ['.grok/hooks/impeccable.json'],
29
- });
30
-
31
- const HOOK_SCRIPT_MARKERS = [
32
- 'skills/impeccable/scripts/hook.mjs',
33
- 'skills/impeccable/scripts/hook-before-edit.mjs',
34
- ];
35
-
36
- // Retired live-mode state locations. impeccable-paths still reads these as
37
- // fallbacks; reporting them is what eventually lets the fallbacks go.
38
- const LEGACY_LIVE_PATHS = ['.impeccable-live.json', '.impeccable-live'];
39
-
40
- function finding({ id, artifact, filePath = null, severity, summary, fix }) {
41
- return { id, artifact, path: filePath, severity, summary, fix };
42
- }
43
-
44
- function readJson(filePath) {
45
- try {
46
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
47
- } catch {
48
- return null;
49
- }
50
- }
51
-
52
- function toRelative(filePath, root) {
53
- if (!filePath) return null;
54
- const rel = path.relative(root, filePath);
55
- return rel && !rel.startsWith('..') && !path.isAbsolute(rel)
56
- ? rel.split(path.sep).join('/')
57
- : filePath;
58
- }
59
-
60
- function git(args, cwd) {
61
- try {
62
- return execFileSync('git', args, {
63
- cwd,
64
- encoding: 'utf-8',
65
- stdio: ['ignore', 'pipe', 'ignore'],
66
- timeout: 5000,
67
- }).trim();
68
- } catch {
69
- return null;
70
- }
71
- }
72
-
73
- // ─── DESIGN.md truth drift ─────────────────────────────────────────────────
74
-
75
- /**
76
- * How much UI work has landed since DESIGN.md was last touched, measured in
77
- * commits to the visual source directories. A proxy, and reported as one: a
78
- * large number means the document is worth re-reading, not that it is wrong.
79
- * Silent outside a git repo, on an untracked DESIGN.md, and when the count is
80
- * small enough to be ordinary maintenance.
81
- */
82
- export function checkDesignDrift({ designPath, projectRoot, threshold = 25 }) {
83
- if (!designPath || !projectRoot) return [];
84
- if (!git(['rev-parse', '--is-inside-work-tree'], projectRoot)) return [];
85
-
86
- const relDesign = toRelative(designPath, projectRoot);
87
- const lastDesignCommit = git(['log', '-1', '--format=%H', '--', relDesign], projectRoot);
88
- if (!lastDesignCommit) return [];
89
-
90
- const dirs = VISUAL_SOURCE_DIRS.filter((dir) => fs.existsSync(path.join(projectRoot, dir)));
91
- if (!dirs.length) return [];
92
-
93
- const log = git(
94
- ['log', '--oneline', `${lastDesignCommit}..HEAD`, '--', ...dirs],
95
- projectRoot,
96
- );
97
- if (log === null) return [];
98
- const commits = log ? log.split('\n').filter(Boolean).length : 0;
99
- if (commits < threshold) return [];
100
-
101
- const when = git(['log', '-1', '--format=%ad', '--date=short', '--', relDesign], projectRoot);
102
- return [finding({
103
- id: 'design-md-drift',
104
- artifact: 'DESIGN.md',
105
- filePath: relDesign,
106
- severity: 'route',
107
- summary: `${commits} commits have touched ${dirs.join(', ')} since ${relDesign} was last edited`
108
- + `${when ? ` (${when})` : ''}. This counts commits, not contradictions: it says the document is worth `
109
- + 're-reading, not that it is wrong.',
110
- fix: 'Read DESIGN.md against the current tokens and components before trusting it as authority. '
111
- + 'If it has genuinely drifted, `document` regenerates it from the code.',
112
- })];
113
- }
114
-
115
- /**
116
- * Canonical DESIGN.md sections that carry nothing. Distinct from truth drift:
117
- * a section can be absent because it never applied, so this is reported as a
118
- * documentation gap for a human to judge, never as an error.
119
- */
120
- function hasCoverageValue(value) {
121
- if (Array.isArray(value)) return value.some(hasCoverageValue);
122
- if (value && typeof value === 'object') {
123
- return Object.values(value).some(hasCoverageValue);
124
- }
125
- if (typeof value === 'string') {
126
- const trimmed = value.trim();
127
- return trimmed.length > 0 && !/^(?:\[\s*\]|\{\s*\})$/.test(trimmed);
128
- }
129
- return false;
130
- }
131
-
132
- const SEED_DESIGN_MARKERS = ['/', '$'].map((prefix) =>
133
- '<!-- SEED: established with the user before implementation; '
134
- + `re-run ${prefix}impeccable document once there's code to capture the actual tokens and components. -->`
135
- );
136
-
137
- export function checkDesignCoverage({ design, designPath, parseDesignMd }) {
138
- if (!design || typeof parseDesignMd !== 'function') return [];
139
- let model;
140
- try {
141
- model = parseDesignMd(design);
142
- } catch {
143
- return [];
144
- }
145
- const isSeed = SEED_DESIGN_MARKERS.some((marker) => design.includes(marker));
146
- const requiredSections = isSeed
147
- ? ['colors', 'typography']
148
- : ['colors', 'typography', 'components'];
149
- const missing = requiredSections
150
- .filter((section) => !model[section] && !hasCoverageValue(model.frontmatter?.[section]));
151
- if (!missing.length) return [];
152
- return [finding({
153
- id: 'design-md-coverage',
154
- artifact: 'DESIGN.md',
155
- filePath: designPath,
156
- severity: 'mention',
157
- summary: `${designPath || 'DESIGN.md'} has no ${missing.join(', ')} section. `
158
- + 'Agents generating new screens get no normative guidance for those, and the live design panel renders '
159
- + 'generic approximations in their place.',
160
- fix: 'Ask whether the section never applied or was never written. `document` fills it from the code if the '
161
- + 'project has the answer in its CSS.',
162
- })];
163
- }
164
-
165
- // ─── detector ignore lists ─────────────────────────────────────────────────
166
-
167
- /**
168
- * Ignore entries that no longer match anything: rule ids the engine dropped or
169
- * renamed, and file paths that are gone. Both read as working suppressions
170
- * until someone checks, and a dead rule ignore also hides that the rule left.
171
- */
172
- export function checkDetectorIgnores({ projectRoot, knownRuleIds = null }) {
173
- const findings = [];
174
- if (!projectRoot) return findings;
175
-
176
- for (const name of ['config.json', 'config.local.json']) {
177
- const filePath = path.join(projectRoot, '.impeccable', name);
178
- const raw = readJson(filePath);
179
- const detector = raw?.detector;
180
- if (!detector || typeof detector !== 'object') continue;
181
- const rel = toRelative(filePath, projectRoot);
182
-
183
- if (knownRuleIds && Array.isArray(detector.ignoreRules)) {
184
- const unknown = detector.ignoreRules
185
- .map((rule) => String(rule || '').trim().toLowerCase())
186
- .filter((rule) => rule && rule !== '*' && !knownRuleIds.has(rule));
187
- if (unknown.length) {
188
- findings.push(finding({
189
- id: 'detector-ignore-rules-unknown',
190
- artifact: 'config.json',
191
- filePath: rel,
192
- severity: 'mention',
193
- summary: `${rel} ignores rule id(s) the detector does not have: `
194
- + `${unknown.map((rule) => `\`${rule}\``).join(', ')}. Either the rule was renamed or removed, or the `
195
- + 'id was mistyped and has never suppressed anything.',
196
- fix: 'Report the exact ids. Removing them is safe; keeping a dead ignore hides that the rule is gone.',
197
- }));
198
- }
199
- }
200
-
201
- if (Array.isArray(detector.ignoreFiles)) {
202
- const missing = detector.ignoreFiles
203
- .map((entry) => String(entry || '').trim())
204
- .filter((entry) => entry && !entry.includes('*') && !fs.existsSync(path.join(projectRoot, entry)));
205
- if (missing.length) {
206
- findings.push(finding({
207
- id: 'detector-ignore-files-missing',
208
- artifact: 'config.json',
209
- filePath: rel,
210
- severity: 'mention',
211
- summary: `${rel} ignores file path(s) that no longer exist: `
212
- + `${missing.map((entry) => `\`${entry}\``).join(', ')}.`,
213
- fix: 'Ask whether the file moved (repoint the entry) or was deleted (drop it). '
214
- + 'A stale entry silently stops covering the file that replaced it.',
215
- }));
216
- }
217
- }
218
- }
219
- return findings;
220
- }
221
-
222
- // ─── hook installation ─────────────────────────────────────────────────────
223
-
224
- function collectHookCommands(value, out = []) {
225
- if (typeof value === 'string') {
226
- if (HOOK_SCRIPT_MARKERS.some((marker) => value.includes(marker))) out.push(value);
227
- return out;
228
- }
229
- if (Array.isArray(value)) {
230
- for (const entry of value) collectHookCommands(entry, out);
231
- return out;
232
- }
233
- if (value && typeof value === 'object') {
234
- for (const entry of Object.values(value)) collectHookCommands(entry, out);
235
- }
236
- return out;
237
- }
238
-
239
- const HOOK_MARKER = /skills\/impeccable\/scripts\/hook(?:-before-edit)?\.mjs/;
240
-
241
- // Pull the script-path token out of a hook command line, placeholders intact.
242
- // The forms our manifests ship:
243
- // * bare: node "${CLAUDE_PROJECT_DIR}/.../hook.mjs"
244
- // * bundle-relative: node ".agents/.../hook.mjs"
245
- // * legacy unquoted: node .claude/.../hook.mjs
246
- // * guarded (#399): [ ! -f "PATH" ] || node "PATH" (PATH twice, identical)
247
- // * absolute (#476): [ ! -f 'PATH' ] || node 'PATH' (single-quoted since
248
- // the shell-injection fix; older installs double-quote)
249
- // * github portable: node "$(git rev-parse --show-toplevel)/.../hook.mjs"
250
- // A quoted path wins; the guard's two occurrences are identical, so the first
251
- // quoted match is the path. Otherwise fall back to the whitespace/metachar-
252
- // delimited token that ends at the marker, so we don't absorb `node`, `[`, `!`
253
- // or `||`. Returns the token verbatim; resolution happens separately.
254
- function hookScriptTokenFrom(command) {
255
- const str = String(command);
256
- if (!HOOK_MARKER.test(str)) return null;
257
- const quoted = str.match(/"([^"]*skills\/impeccable\/scripts\/hook(?:-before-edit)?\.mjs)"/);
258
- if (quoted) return quoted[1];
259
- // A path containing an apostrophe serializes as '\'' inside single quotes;
260
- // no regex reassembles that, and the bare fallback would misread a fragment
261
- // of it, so return null: the caller never asserts on a path it can't parse.
262
- if (str.includes("'\\''")) return null;
263
- const singleQuoted = str.match(/'([^']*skills\/impeccable\/scripts\/hook(?:-before-edit)?\.mjs)'/);
264
- if (singleQuoted) return singleQuoted[1];
265
- const bare = str.match(/([^\s"'|&;()]*skills\/impeccable\/scripts\/hook(?:-before-edit)?\.mjs)/);
266
- return bare ? bare[1] : null;
267
- }
268
-
269
- // Resolve a script token to an absolute path the doctor can existsSync, or null
270
- // when the doctor cannot know where it points — in which case the caller must
271
- // NOT report it missing (a doctor never asserts a negative it cannot verify).
272
- //
273
- // Per-placeholder policy, mirroring what each runtime actually expands:
274
- // ${CLAUDE_PROJECT_DIR} → the project root being scanned. This is exactly the
275
- // runtime mapping (Claude Code sets it to the project
276
- // dir at hook time), so we EXPAND it against `root`.
277
- // Not doing so was the #402 bug: the literal
278
- // `${CLAUDE_PROJECT_DIR}/...` string never exists.
279
- // ${CLAUDE_PLUGIN_ROOT} → plugin-package install dir, set by the harness to
280
- // ${PLUGIN_ROOT} wherever the plugin/codex/grok bundle was unpacked
281
- // ${GROK_PLUGIN_ROOT} (grok aliases CLAUDE_PLUGIN_ROOT). The doctor has no
282
- // way to know that location → SKIP (return null).
283
- // $(...) / backticks → command substitution, e.g. GitHub's
284
- // `$(git rev-parse --show-toplevel)`. Not statically
285
- // resolvable → SKIP.
286
- // any other ${VAR}/$VAR → unknown to the doctor → SKIP.
287
- // A token with no placeholder is a literal path: absolute as-is, else relative
288
- // to `root`.
289
- function resolveHookScriptPath(token, root) {
290
- if (!token) return null;
291
- // Command substitution or backtick expansion we can't evaluate.
292
- if (token.includes('$(') || token.includes('`')) return null;
293
- const expanded = token.replace(/\$\{CLAUDE_PROJECT_DIR\}/g, root);
294
- // Any placeholder or shell variable still present is one we can't map.
295
- if (/\$\{[^}]*\}|\$[A-Za-z_]/.test(expanded)) return null;
296
- return path.isAbsolute(expanded) ? expanded : path.join(root, expanded);
297
- }
298
-
299
- /**
300
- * A hook whose script path does not resolve is a silent no-op, and the user
301
- * believes the project is covered. Also catches the contradiction of an
302
- * installed manifest against `hook.enabled: false`.
303
- */
304
- export function checkHookInstallation({ projectRoot, repoRoot, providerId }) {
305
- const findings = [];
306
- const manifests = HOOK_MANIFESTS_BY_PROVIDER[providerId] || [];
307
- if (!manifests.length) return findings;
308
-
309
- const roots = [...new Set([projectRoot, repoRoot].filter(Boolean).map((root) => path.resolve(root)))];
310
- let installedAt = null;
311
-
312
- for (const root of roots) {
313
- for (const rel of manifests) {
314
- const manifestPath = path.join(root, rel);
315
- const raw = readJson(manifestPath);
316
- if (!raw?.hooks) continue;
317
- const commands = collectHookCommands(raw.hooks);
318
- if (!commands.length) continue;
319
- installedAt = toRelative(manifestPath, projectRoot || root);
320
-
321
- const broken = commands.filter((command) => {
322
- const token = hookScriptTokenFrom(command);
323
- if (!token) return false;
324
- const abs = resolveHookScriptPath(token, root);
325
- // Unresolvable placeholder or command substitution: never assert missing.
326
- if (!abs) return false;
327
- return !fs.existsSync(abs);
328
- });
329
- if (broken.length) {
330
- findings.push(finding({
331
- id: 'hook-script-missing',
332
- artifact: 'hook manifest',
333
- filePath: installedAt,
334
- severity: 'mention',
335
- summary: `${installedAt} installs the design hook, but its script path does not exist: `
336
- + `${broken.map((command) => `\`${command}\``).join(', ')}. The hook runs as a no-op, so UI edits `
337
- + 'have been going unscanned while the project looks covered.',
338
- fix: `Reinstall with \`impeccable hooks on\`, which rewrites the manifest against the skill's current location.`,
339
- }));
340
- }
341
- }
342
- }
343
-
344
- if (installedAt) {
345
- for (const root of roots) {
346
- for (const name of ['config.json', 'config.local.json']) {
347
- const raw = readJson(path.join(root, '.impeccable', name));
348
- if (raw?.hook && raw.hook.enabled === false) {
349
- findings.push(finding({
350
- id: 'hook-enabled-conflict',
351
- artifact: 'config.json',
352
- filePath: toRelative(path.join(root, '.impeccable', name), projectRoot || root),
353
- severity: 'mention',
354
- summary: `${installedAt} installs the design hook while this config sets \`hook.enabled: false\`, `
355
- + 'so the hook fires and then declines to scan.',
356
- fix: 'Ask which was intended: `impeccable hooks on` to enable, or `impeccable hooks off` to uninstall '
357
- + 'the manifest entry as well.',
358
- }));
359
- return findings;
360
- }
361
- }
362
- }
363
- }
364
-
365
- return findings;
366
- }
367
-
368
- // ─── retired locations ─────────────────────────────────────────────────────
369
-
370
- export function checkLegacyLiveState({ projectRoot }) {
371
- if (!projectRoot) return [];
372
- const present = LEGACY_LIVE_PATHS.filter((rel) => fs.existsSync(path.join(projectRoot, rel)));
373
- if (!present.length) return [];
374
- return [finding({
375
- id: 'legacy-live-state',
376
- artifact: 'live state',
377
- filePath: present.join(', '),
378
- severity: 'auto',
379
- summary: `Live-mode state sits in retired location(s): ${present.map((rel) => `\`${rel}\``).join(', ')}. `
380
- + 'Current live mode writes under `.impeccable/live/`.',
381
- fix: 'These are read only through backward-compatible fallbacks and are safe to delete once no live session '
382
- + 'is running. No user decision is needed.',
383
- })];
384
- }
385
-
386
- // ─── monorepo sweep ────────────────────────────────────────────────────────
387
-
388
- /**
389
- * Per-workspace context, plus the case worth acting on: a workspace with
390
- * native build files inheriting a repo-root PRODUCT.md that says web. Each
391
- * such app gets web guidance and never loads the native references, and
392
- * nothing at boot reports it because the root record parses cleanly.
393
- *
394
- * `candidates` comes from context.mjs's discovery so the walk is not repeated.
395
- */
396
- export function checkWorkspaces({ repoRoot, candidates = [], checkNativePlatformEvidence, extractPlatform, readFile }) {
397
- if (!repoRoot || !candidates.length) return { findings: [], workspaces: [] };
398
- const findings = [];
399
- const workspaces = [];
400
-
401
- for (const candidate of candidates) {
402
- const workspaceRoot = path.join(repoRoot, candidate.path);
403
- const productPath = candidate.productPath ? path.join(repoRoot, candidate.productPath) : null;
404
- const product = productPath && readFile ? readFile(productPath) : null;
405
- const platform = extractPlatform ? extractPlatform(product) : null;
406
-
407
- workspaces.push({
408
- name: candidate.name,
409
- path: candidate.path,
410
- productStatus: candidate.productStatus,
411
- productPath: candidate.productPath,
412
- designStatus: candidate.designStatus,
413
- designPath: candidate.designPath,
414
- platform: platform || (product ? 'web (default)' : null),
415
- });
416
-
417
- if (!checkNativePlatformEvidence) continue;
418
- const native = checkNativePlatformEvidence({
419
- projectRoot: workspaceRoot,
420
- platform,
421
- product,
422
- productPath: candidate.productPath,
423
- });
424
- for (const entry of native) {
425
- findings.push(finding({
426
- id: 'workspace-platform-native-evidence',
427
- artifact: 'PRODUCT.md',
428
- filePath: candidate.productPath || `${candidate.path}/PRODUCT.md`,
429
- severity: 'mention',
430
- summary: `Workspace \`${candidate.path}\` ${
431
- candidate.productStatus === 'inherited'
432
- ? 'inherits the repo-root PRODUCT.md'
433
- : 'has a PRODUCT.md'
434
- } that resolves to web, but the workspace itself carries native build files. ${entry.summary}`,
435
- fix: candidate.productStatus === 'inherited'
436
- ? `Give \`${candidate.path}\` its own PRODUCT.md with the right \`## Platform\`. `
437
- + 'An inherited record cannot describe two platforms at once.'
438
- : entry.fix,
439
- }));
440
- }
441
- }
442
-
443
- const inherited = workspaces.filter((entry) => entry.productStatus === 'inherited');
444
- if (inherited.length) {
445
- findings.push(finding({
446
- id: 'workspace-context-inherited',
447
- artifact: 'PRODUCT.md',
448
- filePath: null,
449
- severity: 'mention',
450
- summary: `${inherited.length} of ${workspaces.length} workspace(s) inherit the repo-root PRODUCT.md: `
451
- + `${inherited.map((entry) => `\`${entry.path}\``).join(', ')}. Inheritance is intended; whether one `
452
- + 'record truthfully describes these apps is not something this check can tell.',
453
- fix: 'Ask the user whether the inherited record describes each app. Where it does not, `init` in that '
454
- + 'workspace writes a child PRODUCT.md that overrides it.',
455
- }));
456
- }
457
-
458
- return { findings, workspaces };
459
- }
460
-
461
- // ─── rule registry ─────────────────────────────────────────────────────────
462
-
463
- /**
464
- * Rule ids from the bundled detector, or null when it cannot be resolved (a
465
- * partial install, or a harness that ships the skill without the engine).
466
- * Null means "cannot check", which the ignore-rule check treats as skip rather
467
- * than as every id being unknown.
468
- */
469
- export async function loadKnownRuleIds(scriptsDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')) {
470
- // Same two locations detect.mjs resolves: the bundled copy in an installed
471
- // skill, then the source-repo engine when running from a checkout.
472
- const candidates = [
473
- path.join(scriptsDir, 'detector', 'detect-antipatterns.mjs'),
474
- path.join(scriptsDir, '..', '..', 'cli', 'engine', 'detect-antipatterns.mjs'),
475
- ];
476
- const detectorPath = candidates.find((candidate) => fs.existsSync(candidate));
477
- if (!detectorPath) return null;
478
- try {
479
- const { ANTIPATTERNS } = await import(pathToFileURL(detectorPath).href);
480
- if (!Array.isArray(ANTIPATTERNS)) return null;
481
- return new Set(ANTIPATTERNS.map((rule) => String(rule.id).toLowerCase()));
482
- } catch {
483
- return null;
484
- }
485
- }
@@ -1,169 +0,0 @@
1
- /**
2
- * Notice throttling and directive rendering for staleness findings.
3
- *
4
- * The boot path already carries PRODUCT.md, DESIGN.md, a surface brief,
5
- * RESOLVED_CONTEXT, the detector fallback, native platform references, and the
6
- * update directive. An unthrottled staleness block would push real context out
7
- * of attention and train the agent to open every session with housekeeping, so
8
- * the rules here are deliberately strict:
9
- *
10
- * - One directive for the whole set, never one per finding.
11
- * - A 'mention' or 'route' finding surfaces at most once a week per project,
12
- * mirroring the update check's anti-nag window. A finding the user has
13
- * already declined to act on must not reappear tomorrow.
14
- * - 'auto' findings are not throttled and are not shown to the user. They are
15
- * migrations the next write performs anyway, so the agent needs the note
16
- * every session until the write happens, and the user needs it never.
17
- *
18
- * State lives in the user's home dir alongside the update cache rather than in
19
- * the project, so no gitignore entry is owed and a clone does not inherit
20
- * someone else's dismissals.
21
- */
22
-
23
- import fs from 'node:fs';
24
- import os from 'node:os';
25
- import path from 'node:path';
26
-
27
- const RENOTIFY_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000;
28
-
29
- // Resolved per call rather than at import so a test (or a sandboxed run) can
30
- // redirect the cache without reloading the module.
31
- function cachePath() {
32
- return process.env.IMPECCABLE_STALENESS_CACHE
33
- || path.join(os.homedir(), '.impeccable', 'staleness-check.json');
34
- }
35
-
36
- function readCache() {
37
- try {
38
- const raw = JSON.parse(fs.readFileSync(cachePath(), 'utf-8'));
39
- return raw && typeof raw === 'object' && raw.projects ? raw : { projects: {} };
40
- } catch {
41
- return { projects: {} };
42
- }
43
- }
44
-
45
- /**
46
- * Drop project entries whose newest stamp has aged past the renotify window.
47
- * They would be re-notified on the next boot anyway, so keeping them only lets
48
- * the file accumulate one entry per directory Impeccable has ever booted in
49
- * (scratch dirs and test fixtures included).
50
- */
51
- function pruneCache(cache, now) {
52
- const projects = {};
53
- for (const [key, entries] of Object.entries(cache.projects || {})) {
54
- if (!entries || typeof entries !== 'object') continue;
55
- const stamps = Object.values(entries).filter((value) => typeof value === 'number');
56
- if (stamps.length && now - Math.max(...stamps) < RENOTIFY_INTERVAL_MS) projects[key] = entries;
57
- }
58
- return { projects };
59
- }
60
-
61
- function writeCache(cache) {
62
- try {
63
- const filePath = cachePath();
64
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
65
- fs.writeFileSync(filePath, JSON.stringify(cache));
66
- } catch {
67
- // Best-effort. A read-only home dir means the notice repeats next session,
68
- // which is strictly better than failing the boot.
69
- }
70
- }
71
-
72
- function readJson(filePath) {
73
- try {
74
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
75
- } catch {
76
- return null;
77
- }
78
- }
79
-
80
- /**
81
- * Opt out with IMPECCABLE_NO_STALENESS_CHECK=1 or `"stalenessCheck": false` in
82
- * .impeccable/config.json. Local config overrides shared, matching how
83
- * updateCheck resolves.
84
- */
85
- export function stalenessCheckDisabled(roots = [process.cwd()]) {
86
- if (process.env.IMPECCABLE_NO_STALENESS_CHECK) return true;
87
- let value;
88
- for (const root of roots) {
89
- if (!root) continue;
90
- for (const name of ['config.json', 'config.local.json']) {
91
- const raw = readJson(path.join(root, '.impeccable', name));
92
- if (raw && typeof raw === 'object' && typeof raw.stalenessCheck === 'boolean') {
93
- value = raw.stalenessCheck;
94
- }
95
- }
96
- }
97
- return value === false;
98
- }
99
-
100
- /**
101
- * Drop findings already surfaced for this project inside the renotify window,
102
- * and stamp the ones that survive. 'auto' findings pass through untouched and
103
- * unstamped: they are for the agent, not the user, and repeat until fixed.
104
- */
105
- export function filterFreshFindings(findings, { projectRoot, now = Date.now() } = {}) {
106
- if (!findings.length) return [];
107
- const auto = findings.filter((entry) => entry.severity === 'auto');
108
- const notifiable = findings.filter((entry) => entry.severity !== 'auto');
109
- if (!notifiable.length) return auto;
110
-
111
- const key = path.resolve(projectRoot || process.cwd());
112
- const cache = readCache();
113
- const seen = cache.projects[key] && typeof cache.projects[key] === 'object' ? cache.projects[key] : {};
114
-
115
- const fresh = notifiable.filter((entry) => {
116
- const last = seen[entry.id];
117
- return !(typeof last === 'number' && now - last < RENOTIFY_INTERVAL_MS);
118
- });
119
-
120
- // Forget stamps for findings that no longer fire, so a recurrence after a
121
- // real fix is reported again instead of being suppressed by an old stamp.
122
- // This has to run even when nothing is fresh: the common shape is one
123
- // finding fixed while another is still inside its window.
124
- const live = new Set(notifiable.map((entry) => entry.id));
125
- const next = Object.fromEntries(
126
- Object.entries(seen).filter(([id]) => live.has(id)),
127
- );
128
- for (const entry of fresh) next[entry.id] = now;
129
-
130
- const changed = JSON.stringify(next) !== JSON.stringify(seen);
131
- if (changed) {
132
- const pruned = pruneCache(cache, now);
133
- pruned.projects[key] = next;
134
- writeCache(pruned);
135
- }
136
- return [...auto, ...fresh];
137
- }
138
-
139
- /**
140
- * Render the single boot directive, or null when nothing survived throttling.
141
- */
142
- export function buildStalenessDirective(findings) {
143
- if (!findings.length) return null;
144
- const payload = findings.map((entry) => ({
145
- id: entry.id,
146
- artifact: entry.artifact,
147
- path: entry.path,
148
- severity: entry.severity,
149
- summary: entry.summary,
150
- fix: entry.fix,
151
- }));
152
-
153
- const hasReportable = findings.some((entry) => entry.severity !== 'auto');
154
- const lines = [
155
- `CONTEXT_STALE:\n${JSON.stringify(payload, null, 2)}`,
156
- "Impeccable's own project files have drifted from what this version reads. "
157
- + 'Do not stop, reorder, or expand the requested task for any of this.',
158
- 'By severity: `auto` is a migration the next write to that file performs anyway, so apply it then and do not '
159
- + 'raise it with the user. `mention` gets one short line in your reply with the offered fix. `route` names the '
160
- + 'command that owns the repair; offer it, and run it only if the user asks.',
161
- 'A finding that reports a deprecated field is binding: treat that field as absent for every decision in this '
162
- + 'session, whatever value it holds.',
163
- ];
164
- if (hasReportable) {
165
- lines.push('Surface the reportable findings once, after the task response, in at most two sentences. '
166
- + 'They are already throttled, so say them plainly rather than hedging about whether they matter.');
167
- }
168
- return lines.join(' ');
169
- }