@dsalazardev/ai-hub-cli 0.0.0-stage → 0.1.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 (1288) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +34 -0
  3. package/README.md +64 -2
  4. package/agents/cpp-build-resolver.md +25 -0
  5. package/agents/cpp-reviewer.md +28 -0
  6. package/agents/csharp-reviewer.md +28 -0
  7. package/agents/django-build-resolver.md +25 -0
  8. package/agents/django-reviewer.md +28 -0
  9. package/agents/explorer-domain.md +28 -0
  10. package/agents/fastapi-reviewer.md +28 -0
  11. package/agents/flutter-build-resolver.md +25 -0
  12. package/agents/flutter-reviewer.md +28 -0
  13. package/agents/go-build-resolver.md +25 -0
  14. package/agents/go-reviewer.md +28 -0
  15. package/agents/implementer-backend.md +30 -0
  16. package/agents/implementer-frontend.md +30 -0
  17. package/agents/java-build-resolver.md +26 -0
  18. package/agents/java-reviewer.md +29 -0
  19. package/agents/kotlin-build-resolver.md +25 -0
  20. package/agents/kotlin-reviewer.md +28 -0
  21. package/agents/mle-reviewer.md +28 -0
  22. package/agents/php-reviewer.md +29 -0
  23. package/agents/postgres-reviewer.md +28 -0
  24. package/agents/python-reviewer.md +28 -0
  25. package/agents/pytorch-build-resolver.md +25 -0
  26. package/agents/rag-reviewer.md +28 -0
  27. package/agents/react-build-resolver.md +26 -0
  28. package/agents/react-reviewer.md +29 -0
  29. package/agents/reviewer-architecture.md +32 -0
  30. package/agents/reviewer-tests.md +31 -0
  31. package/agents/rust-build-resolver.md +25 -0
  32. package/agents/rust-reviewer.md +28 -0
  33. package/agents/spec-author.md +36 -0
  34. package/agents/spec-miner.md +14 -0
  35. package/agents/swift-build-resolver.md +25 -0
  36. package/agents/swift-reviewer.md +28 -0
  37. package/agents/typescript-reviewer.md +28 -0
  38. package/agents/vue-reviewer.md +28 -0
  39. package/dist/backup/snapshots.d.ts +24 -0
  40. package/dist/backup/snapshots.js +171 -0
  41. package/dist/bin/ai-hub.d.ts +2 -0
  42. package/dist/bin/ai-hub.js +11 -0
  43. package/dist/cli/args.d.ts +4 -0
  44. package/dist/cli/args.js +63 -0
  45. package/dist/cli/context.d.ts +7 -0
  46. package/dist/cli/context.js +74 -0
  47. package/dist/cli/doctor.d.ts +14 -0
  48. package/dist/cli/doctor.js +200 -0
  49. package/dist/cli/drift.d.ts +2 -0
  50. package/dist/cli/drift.js +34 -0
  51. package/dist/cli/items.d.ts +5 -0
  52. package/dist/cli/items.js +10 -0
  53. package/dist/cli/legacy.d.ts +3 -0
  54. package/dist/cli/legacy.js +18 -0
  55. package/dist/cli/maintenance.d.ts +8 -0
  56. package/dist/cli/maintenance.js +262 -0
  57. package/dist/cli/memory.d.ts +2 -0
  58. package/dist/cli/memory.js +84 -0
  59. package/dist/cli/onboarding.d.ts +17 -0
  60. package/dist/cli/onboarding.js +234 -0
  61. package/dist/cli/run.d.ts +15 -0
  62. package/dist/cli/run.js +183 -0
  63. package/dist/cli/source.d.ts +5 -0
  64. package/dist/cli/source.js +22 -0
  65. package/dist/cli/trunk.d.ts +8 -0
  66. package/dist/cli/trunk.js +54 -0
  67. package/dist/cli/types.d.ts +17 -0
  68. package/dist/cli/types.js +4 -0
  69. package/dist/cli/worktrees.d.ts +11 -0
  70. package/dist/cli/worktrees.js +141 -0
  71. package/dist/engine/engine.d.ts +48 -0
  72. package/dist/engine/engine.js +114 -0
  73. package/dist/engine/gates.d.ts +2 -0
  74. package/dist/engine/gates.js +93 -0
  75. package/dist/frontmatter.d.ts +11 -0
  76. package/dist/frontmatter.js +30 -0
  77. package/dist/harness/guards/adapters/context.d.ts +19 -0
  78. package/dist/harness/guards/adapters/context.js +153 -0
  79. package/dist/harness/guards/adapters/hermes.d.ts +13 -0
  80. package/dist/harness/guards/adapters/hermes.js +18 -0
  81. package/dist/harness/guards/adapters/hooks.d.ts +25 -0
  82. package/dist/harness/guards/adapters/hooks.js +52 -0
  83. package/dist/harness/guards/branch.d.ts +5 -0
  84. package/dist/harness/guards/branch.js +43 -0
  85. package/dist/harness/guards/danger.d.ts +13 -0
  86. package/dist/harness/guards/danger.js +157 -0
  87. package/dist/harness/guards/index.d.ts +6 -0
  88. package/dist/harness/guards/index.js +6 -0
  89. package/dist/harness/guards/preflight.d.ts +14 -0
  90. package/dist/harness/guards/preflight.js +37 -0
  91. package/dist/harness/guards/ship.d.ts +2 -0
  92. package/dist/harness/guards/ship.js +35 -0
  93. package/dist/harness/guards/trunk.d.ts +5 -0
  94. package/dist/harness/guards/trunk.js +41 -0
  95. package/dist/harness/guards/types.d.ts +50 -0
  96. package/dist/harness/guards/types.js +1 -0
  97. package/dist/harness/memory/ledger.d.ts +53 -0
  98. package/dist/harness/memory/ledger.js +136 -0
  99. package/dist/harness/memory/state.d.ts +35 -0
  100. package/dist/harness/memory/state.js +121 -0
  101. package/dist/harness/worktree/reaper.d.ts +32 -0
  102. package/dist/harness/worktree/reaper.js +54 -0
  103. package/dist/manifest/build.d.ts +1 -0
  104. package/dist/manifest/build.js +1 -0
  105. package/dist/manifest/cli.d.ts +2 -0
  106. package/dist/manifest/cli.js +44 -0
  107. package/dist/manifest/dispatch.d.ts +13 -0
  108. package/dist/manifest/dispatch.js +36 -0
  109. package/dist/manifest/labels.d.ts +15 -0
  110. package/dist/manifest/labels.js +70 -0
  111. package/dist/manifest/manifest.d.ts +113 -0
  112. package/dist/manifest/manifest.js +202 -0
  113. package/dist/package-info.d.ts +4 -0
  114. package/dist/package-info.js +7 -0
  115. package/dist/paths.d.ts +33 -0
  116. package/dist/paths.js +123 -0
  117. package/dist/presets/detect.d.ts +24 -0
  118. package/dist/presets/detect.js +116 -0
  119. package/dist/presets/materialize.d.ts +18 -0
  120. package/dist/presets/materialize.js +101 -0
  121. package/dist/presets/resolve.d.ts +37 -0
  122. package/dist/presets/resolve.js +83 -0
  123. package/dist/presets/schema.d.ts +57 -0
  124. package/dist/presets/schema.js +68 -0
  125. package/dist/source-checkout.d.ts +8 -0
  126. package/dist/source-checkout.js +19 -0
  127. package/dist/sync/config.d.ts +47 -0
  128. package/dist/sync/config.js +85 -0
  129. package/dist/sync/lock.d.ts +16 -0
  130. package/dist/sync/lock.js +43 -0
  131. package/dist/sync/render.d.ts +18 -0
  132. package/dist/sync/render.js +255 -0
  133. package/dist/sync/sync.d.ts +38 -0
  134. package/dist/sync/sync.js +288 -0
  135. package/dist/sync/targets.d.ts +24 -0
  136. package/dist/sync/targets.js +78 -0
  137. package/engine/coupling.json +4 -0
  138. package/engine/engine.yaml +250 -0
  139. package/engine/legacy-paths.json +4 -0
  140. package/engine/preflight.md +11 -0
  141. package/manifest.json +393 -0
  142. package/package.json +61 -4
  143. package/presets/angular-express/harness/rules/01-zero-any.sh +25 -0
  144. package/presets/angular-express/harness/rules/02-no-ng-module.sh +21 -0
  145. package/presets/angular-express/harness/rules/03-no-constructor-injection.sh +21 -0
  146. package/presets/angular-express/harness/rules/04-no-legacy-directives.sh +21 -0
  147. package/presets/angular-express/harness/rules/05-no-dolibarrdal-inheritance.sh +25 -0
  148. package/presets/angular-express/harness/rules/06-no-todos.sh +22 -0
  149. package/presets/angular-express/harness/run-all.sh +13 -0
  150. package/presets/angular-express/preset.yaml +55 -0
  151. package/presets/angular-express/references/common-imports-catalog.md +146 -0
  152. package/presets/angular-express/references/fichajes-migration-notes.md +57 -0
  153. package/presets/angular-express/references/module-implementation-flow.md +260 -0
  154. package/presets/angular-express/references/products-coding-standard.md +143 -0
  155. package/presets/angular-express/references/products-module-blueprint.md +860 -0
  156. package/presets/angular-express/references/replicate-module-checklist.md +72 -0
  157. package/presets/angular-express/references/users-migration-notes.md +172 -0
  158. package/presets/angular-express/rules/architecture.md +8 -0
  159. package/presets/angular-express/rules/backend.md +4 -0
  160. package/presets/angular-express/rules/frontend.md +53 -0
  161. package/presets/angular-express/skills/angular-developer/SKILL.md +130 -0
  162. package/presets/angular-express/skills/angular-developer/references/angular-animations.md +160 -0
  163. package/presets/angular-express/skills/angular-developer/references/angular-aria.md +410 -0
  164. package/presets/angular-express/skills/angular-developer/references/cli.md +86 -0
  165. package/presets/angular-express/skills/angular-developer/references/component-harnesses.md +59 -0
  166. package/presets/angular-express/skills/angular-developer/references/component-styling.md +91 -0
  167. package/presets/angular-express/skills/angular-developer/references/components.md +117 -0
  168. package/presets/angular-express/skills/angular-developer/references/creating-services.md +97 -0
  169. package/presets/angular-express/skills/angular-developer/references/data-resolvers.md +69 -0
  170. package/presets/angular-express/skills/angular-developer/references/define-routes.md +67 -0
  171. package/presets/angular-express/skills/angular-developer/references/defining-providers.md +72 -0
  172. package/presets/angular-express/skills/angular-developer/references/di-fundamentals.md +120 -0
  173. package/presets/angular-express/skills/angular-developer/references/e2e-testing.md +66 -0
  174. package/presets/angular-express/skills/angular-developer/references/effects.md +83 -0
  175. package/presets/angular-express/skills/angular-developer/references/hierarchical-injectors.md +43 -0
  176. package/presets/angular-express/skills/angular-developer/references/host-elements.md +80 -0
  177. package/presets/angular-express/skills/angular-developer/references/injection-context.md +63 -0
  178. package/presets/angular-express/skills/angular-developer/references/inputs.md +101 -0
  179. package/presets/angular-express/skills/angular-developer/references/linked-signal.md +59 -0
  180. package/presets/angular-express/skills/angular-developer/references/loading-strategies.md +61 -0
  181. package/presets/angular-express/skills/angular-developer/references/mcp.md +106 -0
  182. package/presets/angular-express/skills/angular-developer/references/migrations.md +30 -0
  183. package/presets/angular-express/skills/angular-developer/references/navigate-to-routes.md +69 -0
  184. package/presets/angular-express/skills/angular-developer/references/outputs.md +86 -0
  185. package/presets/angular-express/skills/angular-developer/references/reactive-forms.md +122 -0
  186. package/presets/angular-express/skills/angular-developer/references/rendering-strategies.md +44 -0
  187. package/presets/angular-express/skills/angular-developer/references/resource.md +74 -0
  188. package/presets/angular-express/skills/angular-developer/references/route-animations.md +56 -0
  189. package/presets/angular-express/skills/angular-developer/references/route-guards.md +52 -0
  190. package/presets/angular-express/skills/angular-developer/references/router-lifecycle.md +45 -0
  191. package/presets/angular-express/skills/angular-developer/references/router-testing.md +87 -0
  192. package/presets/angular-express/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
  193. package/presets/angular-express/skills/angular-developer/references/signal-forms.md +897 -0
  194. package/presets/angular-express/skills/angular-developer/references/signals-overview.md +94 -0
  195. package/presets/angular-express/skills/angular-developer/references/tailwind-css.md +69 -0
  196. package/presets/angular-express/skills/angular-developer/references/template-driven-forms.md +114 -0
  197. package/presets/angular-express/skills/angular-developer/references/testing-fundamentals.md +66 -0
  198. package/presets/angular-express/skills/angular-new-app/SKILL.md +62 -0
  199. package/presets/angular-express/skills/frontend-design/LICENSE.txt +177 -0
  200. package/presets/angular-express/skills/frontend-design/SKILL.md +55 -0
  201. package/presets/angular-express/skills/onna-architecture-angular/SKILL.md +229 -0
  202. package/presets/angular-express/skills/onna-architecture-bff/SKILL.md +446 -0
  203. package/presets/angular-express/skills/onna-architecture-common/SKILL.md +313 -0
  204. package/presets/angular-express/skills/onna-design-system/SKILL.md +615 -0
  205. package/presets/base/preset.yaml +27 -0
  206. package/presets/base/rules/core.md +35 -0
  207. package/presets/generic-ts/preset.yaml +46 -0
  208. package/presets/python/preset.yaml +47 -0
  209. package/presets/python/rules/python.md +10 -0
  210. package/schema/engine.schema.json +73 -0
  211. package/schema/manifest.schema.json +140 -0
  212. package/schema/preset.schema.json +98 -0
  213. package/schema/state.schema.json +27 -0
  214. package/skills/shared/ab-testing/SKILL.md +159 -0
  215. package/skills/shared/ab-testing/evals/README.md +8 -0
  216. package/skills/shared/ab-testing/evals/cases.yaml +49 -0
  217. package/skills/shared/ab-testing/references/pitfalls.md +74 -0
  218. package/skills/shared/ab-testing/references/sample-size-and-cuped.md +128 -0
  219. package/skills/shared/ab-testing/scripts/verify.sh +89 -0
  220. package/skills/shared/accessibility/SKILL.md +216 -0
  221. package/skills/shared/accessibility/evals/README.md +3 -0
  222. package/skills/shared/accessibility/evals/cases.yaml +47 -0
  223. package/skills/shared/accessibility/references/aria-patterns.md +113 -0
  224. package/skills/shared/accessibility/references/wcag22-checklist.md +83 -0
  225. package/skills/shared/accessibility/scripts/verify.sh +103 -0
  226. package/skills/shared/agent-eval/SKILL.md +187 -0
  227. package/skills/shared/agent-eval/evals/README.md +12 -0
  228. package/skills/shared/agent-eval/evals/cases.yaml +45 -0
  229. package/skills/shared/agent-eval/references/judge-design.md +118 -0
  230. package/skills/shared/agent-eval/references/runner-and-gate.md +183 -0
  231. package/skills/shared/agent-eval/scripts/verify.sh +161 -0
  232. package/skills/shared/agent-safety/SKILL.md +169 -0
  233. package/skills/shared/agent-safety/evals/README.md +12 -0
  234. package/skills/shared/agent-safety/evals/cases.yaml +46 -0
  235. package/skills/shared/agent-safety/references/threat-model.md +51 -0
  236. package/skills/shared/analyze/SKILL.md +123 -0
  237. package/skills/shared/analyze/evals/README.md +72 -0
  238. package/skills/shared/analyze/evals/cases.yaml +74 -0
  239. package/skills/shared/angular/SKILL.md +275 -0
  240. package/skills/shared/angular/evals/README.md +3 -0
  241. package/skills/shared/angular/evals/cases.yaml +38 -0
  242. package/skills/shared/angular/references/migration.md +81 -0
  243. package/skills/shared/angular/references/signals-rxjs.md +92 -0
  244. package/skills/shared/angular/scripts/verify.sh +122 -0
  245. package/skills/shared/api-connector-builder/SKILL.md +268 -0
  246. package/skills/shared/api-connector-builder/evals/README.md +11 -0
  247. package/skills/shared/api-connector-builder/evals/cases.yaml +47 -0
  248. package/skills/shared/api-connector-builder/references/auth-flows.md +132 -0
  249. package/skills/shared/api-connector-builder/references/pagination.md +144 -0
  250. package/skills/shared/api-connector-builder/scripts/verify.sh +172 -0
  251. package/skills/shared/api-design/SKILL.md +182 -0
  252. package/skills/shared/api-design/evals/README.md +3 -0
  253. package/skills/shared/api-design/evals/cases.yaml +45 -0
  254. package/skills/shared/api-design/references/graphql-design.md +70 -0
  255. package/skills/shared/api-design/references/openapi-contract.md +86 -0
  256. package/skills/shared/api-design/references/rest-conventions.md +63 -0
  257. package/skills/shared/api-design/references/versioning-and-evolution.md +49 -0
  258. package/skills/shared/api-design/scripts/verify.sh +138 -0
  259. package/skills/shared/astro/SKILL.md +257 -0
  260. package/skills/shared/astro/evals/README.md +3 -0
  261. package/skills/shared/astro/evals/cases.yaml +41 -0
  262. package/skills/shared/astro/references/content-layer.md +118 -0
  263. package/skills/shared/astro/references/deploy-and-integrations.md +163 -0
  264. package/skills/shared/astro/scripts/verify.sh +137 -0
  265. package/skills/shared/author-skill/SKILL.md +194 -0
  266. package/skills/shared/author-skill/evals/README.md +66 -0
  267. package/skills/shared/author-skill/evals/cases.yaml +75 -0
  268. package/skills/shared/author-skill/references/description-recipe.md +85 -0
  269. package/skills/shared/author-skill/references/eval-authoring.md +108 -0
  270. package/skills/shared/author-skill/references/skill-conventions.md +95 -0
  271. package/skills/shared/automation-flows/SKILL.md +122 -0
  272. package/skills/shared/automation-flows/evals/README.md +5 -0
  273. package/skills/shared/automation-flows/evals/cases.yaml +44 -0
  274. package/skills/shared/automation-flows/references/error-handling.md +58 -0
  275. package/skills/shared/automation-flows/references/n8n-workflow-json.md +63 -0
  276. package/skills/shared/automation-flows/scripts/verify.sh +78 -0
  277. package/skills/shared/aws-essentials/SKILL.md +206 -0
  278. package/skills/shared/aws-essentials/evals/README.md +10 -0
  279. package/skills/shared/aws-essentials/evals/cases.yaml +44 -0
  280. package/skills/shared/aws-essentials/references/iam-least-privilege.md +134 -0
  281. package/skills/shared/aws-essentials/references/rds-cloudfront-recipes.md +127 -0
  282. package/skills/shared/aws-essentials/scripts/verify.sh +99 -0
  283. package/skills/shared/backups/SKILL.md +131 -0
  284. package/skills/shared/backups/evals/README.md +3 -0
  285. package/skills/shared/backups/evals/cases.yaml +42 -0
  286. package/skills/shared/backups/references/engine-recipes.md +121 -0
  287. package/skills/shared/backups/references/restore-runbook.md +65 -0
  288. package/skills/shared/backups/scripts/verify.sh +80 -0
  289. package/skills/shared/bash-scripting/SKILL.md +227 -0
  290. package/skills/shared/bash-scripting/evals/README.md +3 -0
  291. package/skills/shared/bash-scripting/evals/cases.yaml +45 -0
  292. package/skills/shared/bash-scripting/references/portability.md +97 -0
  293. package/skills/shared/bash-scripting/scripts/verify.sh +140 -0
  294. package/skills/shared/building-agents/SKILL.md +386 -0
  295. package/skills/shared/building-agents/evals/README.md +68 -0
  296. package/skills/shared/building-agents/evals/cases.yaml +60 -0
  297. package/skills/shared/building-agents/references/agent-loops-and-harness.md +371 -0
  298. package/skills/shared/building-agents/references/evals-and-observability.md +420 -0
  299. package/skills/shared/building-agents/references/mcp-servers.md +294 -0
  300. package/skills/shared/building-agents/references/provider-abstraction.md +489 -0
  301. package/skills/shared/building-agents/references/tools-and-rag.md +417 -0
  302. package/skills/shared/building-agents/scripts/verify.sh +121 -0
  303. package/skills/shared/chatbot/SKILL.md +151 -0
  304. package/skills/shared/chatbot/evals/README.md +13 -0
  305. package/skills/shared/chatbot/evals/cases.yaml +43 -0
  306. package/skills/shared/chatbot/references/handoff-and-sales.md +71 -0
  307. package/skills/shared/chatbot/references/system-prompt-and-guardrails.md +78 -0
  308. package/skills/shared/chatbot/scripts/verify.sh +162 -0
  309. package/skills/shared/chrome-extension/SKILL.md +169 -0
  310. package/skills/shared/chrome-extension/evals/README.md +12 -0
  311. package/skills/shared/chrome-extension/evals/cases.yaml +40 -0
  312. package/skills/shared/chrome-extension/references/store-and-migration.md +84 -0
  313. package/skills/shared/chrome-extension/scripts/verify.sh +62 -0
  314. package/skills/shared/clarify/SKILL.md +161 -0
  315. package/skills/shared/clarify/evals/README.md +70 -0
  316. package/skills/shared/clarify/evals/cases.yaml +71 -0
  317. package/skills/shared/clickhouse-analytics/SKILL.md +159 -0
  318. package/skills/shared/clickhouse-analytics/evals/README.md +3 -0
  319. package/skills/shared/clickhouse-analytics/evals/cases.yaml +45 -0
  320. package/skills/shared/clickhouse-analytics/references/ingestion-and-mvs.md +109 -0
  321. package/skills/shared/clickhouse-analytics/references/query-optimization.md +76 -0
  322. package/skills/shared/clickhouse-analytics/references/schema-and-engines.md +63 -0
  323. package/skills/shared/clickhouse-analytics/scripts/verify.sh +109 -0
  324. package/skills/shared/cloudflare/SKILL.md +186 -0
  325. package/skills/shared/cloudflare/evals/README.md +15 -0
  326. package/skills/shared/cloudflare/evals/cases.yaml +46 -0
  327. package/skills/shared/cloudflare/references/storage-primitives.md +104 -0
  328. package/skills/shared/cloudflare/references/wrangler-config.md +91 -0
  329. package/skills/shared/cloudflare/scripts/verify.sh +133 -0
  330. package/skills/shared/code-review/SKILL.md +132 -0
  331. package/skills/shared/code-review/evals/README.md +3 -0
  332. package/skills/shared/code-review/evals/cases.yaml +55 -0
  333. package/skills/shared/code-review/references/pr-workflow.md +67 -0
  334. package/skills/shared/codebase-onboarding/SKILL.md +128 -0
  335. package/skills/shared/codebase-onboarding/evals/README.md +3 -0
  336. package/skills/shared/codebase-onboarding/evals/cases.yaml +69 -0
  337. package/skills/shared/codebase-onboarding/references/recon-playbook.md +57 -0
  338. package/skills/shared/codebase-onboarding/scripts/verify.sh +54 -0
  339. package/skills/shared/compose-multiplatform/SKILL.md +198 -0
  340. package/skills/shared/compose-multiplatform/evals/README.md +3 -0
  341. package/skills/shared/compose-multiplatform/evals/cases.yaml +40 -0
  342. package/skills/shared/compose-multiplatform/references/ios-interop.md +91 -0
  343. package/skills/shared/compose-multiplatform/references/project-setup.md +96 -0
  344. package/skills/shared/compose-multiplatform/scripts/verify.sh +123 -0
  345. package/skills/shared/connect-tool/SKILL.md +163 -0
  346. package/skills/shared/connect-tool/evals/cases.yaml +58 -0
  347. package/skills/shared/constitution/SKILL.md +158 -0
  348. package/skills/shared/constitution/evals/README.md +68 -0
  349. package/skills/shared/constitution/evals/cases.yaml +72 -0
  350. package/skills/shared/constitution/references/constitution-template.md +100 -0
  351. package/skills/shared/context-budget/SKILL.md +114 -0
  352. package/skills/shared/context-budget/evals/README.md +11 -0
  353. package/skills/shared/context-budget/evals/cases.yaml +40 -0
  354. package/skills/shared/context-budget/references/handoff-and-compaction.md +96 -0
  355. package/skills/shared/continuous-learning/SKILL.md +106 -0
  356. package/skills/shared/continuous-learning/evals/README.md +16 -0
  357. package/skills/shared/continuous-learning/evals/cases.yaml +39 -0
  358. package/skills/shared/continuous-learning/references/lesson-routing.md +106 -0
  359. package/skills/shared/coolify/SKILL.md +194 -0
  360. package/skills/shared/coolify/evals/README.md +21 -0
  361. package/skills/shared/coolify/evals/cases.yaml +46 -0
  362. package/skills/shared/coolify/references/databases-and-backups.md +99 -0
  363. package/skills/shared/coolify/references/deploy-recipes.md +105 -0
  364. package/skills/shared/coolify/references/install-and-proxy.md +80 -0
  365. package/skills/shared/coolify/scripts/verify.sh +123 -0
  366. package/skills/shared/cost-tracking/SKILL.md +176 -0
  367. package/skills/shared/cost-tracking/evals/README.md +3 -0
  368. package/skills/shared/cost-tracking/evals/cases.yaml +45 -0
  369. package/skills/shared/cost-tracking/references/cloud-caps.md +52 -0
  370. package/skills/shared/cost-tracking/references/pricing-tables.md +51 -0
  371. package/skills/shared/cost-tracking/scripts/verify.sh +135 -0
  372. package/skills/shared/cpp/SKILL.md +302 -0
  373. package/skills/shared/cpp/evals/README.md +14 -0
  374. package/skills/shared/cpp/evals/cases.yaml +44 -0
  375. package/skills/shared/cpp/references/cmake.md +167 -0
  376. package/skills/shared/cpp/references/move-and-templates.md +130 -0
  377. package/skills/shared/cpp/references/undefined-behavior.md +86 -0
  378. package/skills/shared/cpp/scripts/verify.sh +165 -0
  379. package/skills/shared/csharp-dotnet/SKILL.md +272 -0
  380. package/skills/shared/csharp-dotnet/evals/README.md +3 -0
  381. package/skills/shared/csharp-dotnet/evals/cases.yaml +48 -0
  382. package/skills/shared/csharp-dotnet/references/aspnetcore.md +99 -0
  383. package/skills/shared/csharp-dotnet/references/async.md +82 -0
  384. package/skills/shared/csharp-dotnet/references/efcore.md +96 -0
  385. package/skills/shared/csharp-dotnet/scripts/verify.sh +90 -0
  386. package/skills/shared/data-cleaning/SKILL.md +259 -0
  387. package/skills/shared/data-cleaning/evals/README.md +16 -0
  388. package/skills/shared/data-cleaning/evals/cases.yaml +57 -0
  389. package/skills/shared/data-cleaning/references/normalization-recipes.md +136 -0
  390. package/skills/shared/data-cleaning/references/validation-patterns.md +134 -0
  391. package/skills/shared/data-cleaning/scripts/verify.sh +115 -0
  392. package/skills/shared/data-scraper/SKILL.md +130 -0
  393. package/skills/shared/data-scraper/evals/README.md +3 -0
  394. package/skills/shared/data-scraper/evals/cases.yaml +46 -0
  395. package/skills/shared/data-scraper/references/anti-bot.md +85 -0
  396. package/skills/shared/data-scraper/references/frameworks.md +116 -0
  397. package/skills/shared/data-scraper/references/legal-compliance.md +64 -0
  398. package/skills/shared/data-scraper/scripts/verify.sh +166 -0
  399. package/skills/shared/db-migrations/SKILL.md +237 -0
  400. package/skills/shared/db-migrations/evals/README.md +10 -0
  401. package/skills/shared/db-migrations/evals/cases.yaml +46 -0
  402. package/skills/shared/db-migrations/references/backfill-and-batching.md +105 -0
  403. package/skills/shared/db-migrations/references/expand-contract-playbook.md +152 -0
  404. package/skills/shared/db-migrations/references/tools-and-runners.md +88 -0
  405. package/skills/shared/db-migrations/scripts/verify.sh +112 -0
  406. package/skills/shared/debug/SKILL.md +188 -0
  407. package/skills/shared/debug/evals/README.md +88 -0
  408. package/skills/shared/debug/evals/cases.yaml +74 -0
  409. package/skills/shared/decision-challenge/SKILL.md +113 -0
  410. package/skills/shared/decision-challenge/evals/README.md +3 -0
  411. package/skills/shared/decision-challenge/evals/cases.yaml +42 -0
  412. package/skills/shared/decision-records/SKILL.md +202 -0
  413. package/skills/shared/decision-records/evals/README.md +3 -0
  414. package/skills/shared/decision-records/evals/cases.yaml +43 -0
  415. package/skills/shared/decision-records/references/templates.md +252 -0
  416. package/skills/shared/decision-records/scripts/verify.sh +105 -0
  417. package/skills/shared/deep-learning/SKILL.md +226 -0
  418. package/skills/shared/deep-learning/evals/README.md +11 -0
  419. package/skills/shared/deep-learning/evals/cases.yaml +48 -0
  420. package/skills/shared/deep-learning/references/distributed.md +105 -0
  421. package/skills/shared/deep-learning/references/training-recipes.md +135 -0
  422. package/skills/shared/deployment/SKILL.md +374 -0
  423. package/skills/shared/deployment/evals/README.md +50 -0
  424. package/skills/shared/deployment/evals/cases.yaml +53 -0
  425. package/skills/shared/deployment/references/coolify.md +216 -0
  426. package/skills/shared/deployment/references/dockerfiles-by-stack.md +319 -0
  427. package/skills/shared/deployment/references/github-actions.md +295 -0
  428. package/skills/shared/deployment/references/hosting-targets.md +272 -0
  429. package/skills/shared/deployment/scripts/verify.sh +134 -0
  430. package/skills/shared/deprecation/SKILL.md +123 -0
  431. package/skills/shared/deprecation/evals/README.md +3 -0
  432. package/skills/shared/deprecation/evals/cases.yaml +42 -0
  433. package/skills/shared/design/IMPECCABLE-LICENSE.txt +191 -0
  434. package/skills/shared/design/SKILL.md +111 -0
  435. package/skills/shared/design/THIRD_PARTY.md +26 -0
  436. package/skills/shared/design/engine/LICENSE +21 -0
  437. package/skills/shared/design/engine/RUN.md +515 -0
  438. package/skills/shared/design/engine/UPSTREAM.json +4 -0
  439. package/skills/shared/design/engine/assets/app.css +216 -0
  440. package/skills/shared/design/engine/assets/base.css +105 -0
  441. package/skills/shared/design/engine/assets/base.js +37 -0
  442. package/skills/shared/design/engine/assets/charts.js +617 -0
  443. package/skills/shared/design/engine/assets/scenes/stage.css +28 -0
  444. package/skills/shared/design/engine/assets/scenes/stage.js +133 -0
  445. package/skills/shared/design/engine/library/app.json +1327 -0
  446. package/skills/shared/design/engine/library/directions.json +1078 -0
  447. package/skills/shared/design/engine/library/heroes.json +1086 -0
  448. package/skills/shared/design/engine/library/motions.json +92 -0
  449. package/skills/shared/design/engine/library/palettes.json +1485 -0
  450. package/skills/shared/design/engine/library/photos.json +7240 -0
  451. package/skills/shared/design/engine/library/sections.json +4429 -0
  452. package/skills/shared/design/engine/library/sites.json +8350 -0
  453. package/skills/shared/design/engine/library/type.json +2024 -0
  454. package/skills/shared/design/engine/references/app-screens.md +1199 -0
  455. package/skills/shared/design/engine/references/colour.md +141 -0
  456. package/skills/shared/design/engine/references/copy.md +177 -0
  457. package/skills/shared/design/engine/references/critique.md +182 -0
  458. package/skills/shared/design/engine/references/imagery.md +791 -0
  459. package/skills/shared/design/engine/references/layout.md +292 -0
  460. package/skills/shared/design/engine/references/motion.md +980 -0
  461. package/skills/shared/design/engine/references/research.md +356 -0
  462. package/skills/shared/design/engine/references/scenes.md +174 -0
  463. package/skills/shared/design/engine/references/tells.md +115 -0
  464. package/skills/shared/design/engine/references/type.md +170 -0
  465. package/skills/shared/design/engine/scripts/assets.mjs +865 -0
  466. package/skills/shared/design/engine/scripts/draw.mjs +584 -0
  467. package/skills/shared/design/engine/scripts/inspect.mjs +303 -0
  468. package/skills/shared/design/engine/scripts/lib/app-draw.mjs +203 -0
  469. package/skills/shared/design/engine/scripts/lib/cdp.mjs +248 -0
  470. package/skills/shared/design/engine/scripts/lib/probe.mjs +909 -0
  471. package/skills/shared/design/engine/scripts/lib/rules.mjs +243 -0
  472. package/skills/shared/design/engine/scripts/lint.mjs +119 -0
  473. package/skills/shared/design/engine/scripts/scenes.mjs +124 -0
  474. package/skills/shared/design/evals/cases.yaml +45 -0
  475. package/skills/shared/design/references/design-md.md +49 -0
  476. package/skills/shared/design/references/finish-review.md +46 -0
  477. package/skills/shared/design/references/modes.md +51 -0
  478. package/skills/shared/digitalocean/SKILL.md +227 -0
  479. package/skills/shared/digitalocean/evals/README.md +10 -0
  480. package/skills/shared/digitalocean/evals/cases.yaml +37 -0
  481. package/skills/shared/digitalocean/references/app-spec.md +126 -0
  482. package/skills/shared/digitalocean/references/droplet-ops.md +95 -0
  483. package/skills/shared/digitalocean/scripts/verify.sh +102 -0
  484. package/skills/shared/django/SKILL.md +263 -0
  485. package/skills/shared/django/evals/README.md +11 -0
  486. package/skills/shared/django/evals/cases.yaml +47 -0
  487. package/skills/shared/django/references/drf.md +109 -0
  488. package/skills/shared/django/references/orm-performance.md +91 -0
  489. package/skills/shared/django/references/security.md +81 -0
  490. package/skills/shared/django/references/testing.md +86 -0
  491. package/skills/shared/django/scripts/verify.sh +115 -0
  492. package/skills/shared/docker/SKILL.md +251 -0
  493. package/skills/shared/docker/evals/README.md +10 -0
  494. package/skills/shared/docker/evals/cases.yaml +44 -0
  495. package/skills/shared/docker/references/base-images-and-stages.md +104 -0
  496. package/skills/shared/docker/references/compose-recipes.md +109 -0
  497. package/skills/shared/docker/scripts/verify.sh +149 -0
  498. package/skills/shared/domains-dns/SKILL.md +131 -0
  499. package/skills/shared/domains-dns/evals/README.md +16 -0
  500. package/skills/shared/domains-dns/evals/cases.yaml +47 -0
  501. package/skills/shared/domains-dns/references/record-cookbook.md +94 -0
  502. package/skills/shared/domains-dns/references/tls-and-acme.md +90 -0
  503. package/skills/shared/domains-dns/references/verify-and-debug.md +64 -0
  504. package/skills/shared/domains-dns/scripts/verify.sh +163 -0
  505. package/skills/shared/drizzle-orm/SKILL.md +231 -0
  506. package/skills/shared/drizzle-orm/evals/README.md +12 -0
  507. package/skills/shared/drizzle-orm/evals/cases.yaml +47 -0
  508. package/skills/shared/drizzle-orm/references/relations-and-drivers.md +118 -0
  509. package/skills/shared/drizzle-orm/scripts/verify.sh +155 -0
  510. package/skills/shared/duckdb/SKILL.md +202 -0
  511. package/skills/shared/duckdb/evals/README.md +31 -0
  512. package/skills/shared/duckdb/evals/cases.yaml +41 -0
  513. package/skills/shared/duckdb/references/python-and-interop.md +105 -0
  514. package/skills/shared/duckdb/references/remote-and-lakehouse.md +101 -0
  515. package/skills/shared/duckdb/scripts/verify.sh +71 -0
  516. package/skills/shared/dynamodb/SKILL.md +204 -0
  517. package/skills/shared/dynamodb/evals/README.md +8 -0
  518. package/skills/shared/dynamodb/evals/cases.yaml +46 -0
  519. package/skills/shared/dynamodb/references/access-patterns.md +127 -0
  520. package/skills/shared/dynamodb/references/capacity-and-limits.md +78 -0
  521. package/skills/shared/dynamodb/scripts/verify.sh +108 -0
  522. package/skills/shared/e2e-testing/SKILL.md +233 -0
  523. package/skills/shared/e2e-testing/evals/README.md +10 -0
  524. package/skills/shared/e2e-testing/evals/cases.yaml +64 -0
  525. package/skills/shared/e2e-testing/references/config-and-ci.md +156 -0
  526. package/skills/shared/e2e-testing/references/flakiness-playbook.md +124 -0
  527. package/skills/shared/e2e-testing/scripts/verify.sh +117 -0
  528. package/skills/shared/electron/SKILL.md +209 -0
  529. package/skills/shared/electron/evals/README.md +13 -0
  530. package/skills/shared/electron/evals/cases.yaml +38 -0
  531. package/skills/shared/electron/references/packaging-and-updates.md +122 -0
  532. package/skills/shared/electron/references/security-and-ipc.md +158 -0
  533. package/skills/shared/electron/scripts/verify.sh +143 -0
  534. package/skills/shared/elixir/SKILL.md +209 -0
  535. package/skills/shared/elixir/evals/README.md +3 -0
  536. package/skills/shared/elixir/evals/cases.yaml +41 -0
  537. package/skills/shared/elixir/references/mix-and-releases.md +91 -0
  538. package/skills/shared/elixir/references/otp-patterns.md +96 -0
  539. package/skills/shared/elixir/scripts/verify.sh +76 -0
  540. package/skills/shared/email-deliverability/SKILL.md +148 -0
  541. package/skills/shared/email-deliverability/evals/README.md +21 -0
  542. package/skills/shared/email-deliverability/evals/cases.yaml +45 -0
  543. package/skills/shared/email-deliverability/scripts/verify.sh +98 -0
  544. package/skills/shared/embeddings-search/SKILL.md +184 -0
  545. package/skills/shared/embeddings-search/evals/README.md +10 -0
  546. package/skills/shared/embeddings-search/evals/cases.yaml +44 -0
  547. package/skills/shared/embeddings-search/references/evaluation.md +86 -0
  548. package/skills/shared/embeddings-search/references/models.md +73 -0
  549. package/skills/shared/embeddings-search/scripts/verify.sh +103 -0
  550. package/skills/shared/error-handling/SKILL.md +273 -0
  551. package/skills/shared/error-handling/evals/README.md +12 -0
  552. package/skills/shared/error-handling/evals/cases.yaml +46 -0
  553. package/skills/shared/error-handling/references/boundaries-and-messaging.md +120 -0
  554. package/skills/shared/error-handling/references/retry-and-resilience.md +154 -0
  555. package/skills/shared/error-handling/scripts/verify.sh +110 -0
  556. package/skills/shared/expo/SKILL.md +243 -0
  557. package/skills/shared/expo/evals/README.md +13 -0
  558. package/skills/shared/expo/evals/cases.yaml +44 -0
  559. package/skills/shared/expo/references/config-plugins.md +117 -0
  560. package/skills/shared/expo/references/eas-update.md +118 -0
  561. package/skills/shared/expo/scripts/verify.sh +132 -0
  562. package/skills/shared/fal/SKILL.md +196 -0
  563. package/skills/shared/fal/evals/README.md +3 -0
  564. package/skills/shared/fal/evals/cases.yaml +42 -0
  565. package/skills/shared/fal/references/models-and-cost.md +53 -0
  566. package/skills/shared/fal/references/queue-and-webhooks.md +153 -0
  567. package/skills/shared/fal/scripts/verify.sh +72 -0
  568. package/skills/shared/fastapi/SKILL.md +469 -0
  569. package/skills/shared/fastapi/evals/README.md +50 -0
  570. package/skills/shared/fastapi/evals/cases.yaml +55 -0
  571. package/skills/shared/fastapi/references/database.md +347 -0
  572. package/skills/shared/fastapi/references/production.md +338 -0
  573. package/skills/shared/fastapi/references/security.md +330 -0
  574. package/skills/shared/fastapi/references/testing.md +349 -0
  575. package/skills/shared/fastapi/scripts/verify.sh +157 -0
  576. package/skills/shared/finetuning/SKILL.md +232 -0
  577. package/skills/shared/finetuning/evals/README.md +13 -0
  578. package/skills/shared/finetuning/evals/cases.yaml +50 -0
  579. package/skills/shared/finetuning/references/hyperparameters-and-eval.md +74 -0
  580. package/skills/shared/finetuning/references/methods.md +189 -0
  581. package/skills/shared/firebase/SKILL.md +237 -0
  582. package/skills/shared/firebase/evals/README.md +12 -0
  583. package/skills/shared/firebase/evals/cases.yaml +45 -0
  584. package/skills/shared/firebase/references/cloud-functions.md +102 -0
  585. package/skills/shared/firebase/references/data-modeling.md +108 -0
  586. package/skills/shared/firebase/references/security-rules.md +137 -0
  587. package/skills/shared/firebase/scripts/verify.sh +98 -0
  588. package/skills/shared/flutter/SKILL.md +400 -0
  589. package/skills/shared/flutter/evals/README.md +54 -0
  590. package/skills/shared/flutter/evals/cases.yaml +69 -0
  591. package/skills/shared/flutter/references/architecture-and-state.md +499 -0
  592. package/skills/shared/flutter/references/i18n-and-dependencies.md +197 -0
  593. package/skills/shared/flutter/references/performance.md +299 -0
  594. package/skills/shared/flutter/references/testing.md +385 -0
  595. package/skills/shared/flutter/references/ui-and-navigation.md +378 -0
  596. package/skills/shared/flutter/scripts/verify.sh +104 -0
  597. package/skills/shared/fly-io/SKILL.md +197 -0
  598. package/skills/shared/fly-io/evals/README.md +3 -0
  599. package/skills/shared/fly-io/evals/cases.yaml +42 -0
  600. package/skills/shared/fly-io/references/fly-toml.md +155 -0
  601. package/skills/shared/fly-io/references/multi-region.md +66 -0
  602. package/skills/shared/fly-io/scripts/verify.sh +90 -0
  603. package/skills/shared/ftd/SKILL.md +111 -0
  604. package/skills/shared/ftd/evals/cases.yaml +66 -0
  605. package/skills/shared/ftd/evals/routing.json +24 -0
  606. package/skills/shared/game-design/SKILL.md +146 -0
  607. package/skills/shared/game-design/evals/README.md +13 -0
  608. package/skills/shared/game-design/evals/cases.yaml +47 -0
  609. package/skills/shared/game-design/references/mechanics-and-loops.md +78 -0
  610. package/skills/shared/game-design/references/playtesting-and-scope.md +58 -0
  611. package/skills/shared/game-design/references/progression-and-economy.md +70 -0
  612. package/skills/shared/game-storytelling/SKILL.md +134 -0
  613. package/skills/shared/game-storytelling/evals/README.md +28 -0
  614. package/skills/shared/game-storytelling/evals/cases.yaml +51 -0
  615. package/skills/shared/game-storytelling/references/branching-and-state.md +134 -0
  616. package/skills/shared/game-storytelling/references/dialogue-tools.md +117 -0
  617. package/skills/shared/game-storytelling/references/environmental-storytelling.md +71 -0
  618. package/skills/shared/gamedev-multiplayer/SKILL.md +237 -0
  619. package/skills/shared/gamedev-multiplayer/evals/README.md +12 -0
  620. package/skills/shared/gamedev-multiplayer/evals/cases.yaml +44 -0
  621. package/skills/shared/gamedev-multiplayer/references/godot-high-level-multiplayer.md +133 -0
  622. package/skills/shared/gamedev-multiplayer/references/prediction-and-latency.md +104 -0
  623. package/skills/shared/gamedev-multiplayer/references/unity-and-unreal-netcode.md +166 -0
  624. package/skills/shared/gamedev-pathing/SKILL.md +233 -0
  625. package/skills/shared/gamedev-pathing/evals/README.md +14 -0
  626. package/skills/shared/gamedev-pathing/evals/cases.yaml +49 -0
  627. package/skills/shared/gamedev-pathing/references/navmesh-workflow.md +110 -0
  628. package/skills/shared/gamedev-pathing/references/search-algorithms.md +135 -0
  629. package/skills/shared/gamedev-pathing/references/steering-and-avoidance.md +120 -0
  630. package/skills/shared/gamedev-physics/SKILL.md +225 -0
  631. package/skills/shared/gamedev-physics/evals/README.md +12 -0
  632. package/skills/shared/gamedev-physics/evals/cases.yaml +54 -0
  633. package/skills/shared/gamedev-physics/references/character-controllers.md +120 -0
  634. package/skills/shared/gamedev-physics/references/determinism-and-queries.md +124 -0
  635. package/skills/shared/gamedev-physics/references/layers-and-masks.md +115 -0
  636. package/skills/shared/gamedev-shaders/SKILL.md +232 -0
  637. package/skills/shared/gamedev-shaders/evals/README.md +14 -0
  638. package/skills/shared/gamedev-shaders/evals/cases.yaml +45 -0
  639. package/skills/shared/gamedev-shaders/references/effect-recipes.md +205 -0
  640. package/skills/shared/gamedev-shaders/references/godot-shading-language.md +133 -0
  641. package/skills/shared/gamedev-shaders/references/unity-and-unreal-shaders.md +169 -0
  642. package/skills/shared/gamedev-shipping/SKILL.md +220 -0
  643. package/skills/shared/gamedev-shipping/evals/README.md +9 -0
  644. package/skills/shared/gamedev-shipping/evals/cases.yaml +55 -0
  645. package/skills/shared/gamedev-shipping/references/mobile-and-desktop.md +127 -0
  646. package/skills/shared/gamedev-shipping/references/stores-and-ci.md +162 -0
  647. package/skills/shared/gamedev-shipping/references/web-export-headers.md +140 -0
  648. package/skills/shared/gcp-essentials/SKILL.md +324 -0
  649. package/skills/shared/gcp-essentials/evals/README.md +12 -0
  650. package/skills/shared/gcp-essentials/evals/cases.yaml +38 -0
  651. package/skills/shared/gcp-essentials/references/deploy-recipes.md +81 -0
  652. package/skills/shared/gcp-essentials/references/iam-and-auth.md +94 -0
  653. package/skills/shared/gcp-essentials/references/networking-and-sql.md +74 -0
  654. package/skills/shared/gcp-essentials/scripts/verify.sh +158 -0
  655. package/skills/shared/git-workflow/SKILL.md +214 -0
  656. package/skills/shared/git-workflow/evals/README.md +10 -0
  657. package/skills/shared/git-workflow/evals/cases.yaml +52 -0
  658. package/skills/shared/git-workflow/references/gitmoji.md +157 -0
  659. package/skills/shared/git-workflow/references/interactive-rebase.md +89 -0
  660. package/skills/shared/github-actions/SKILL.md +244 -0
  661. package/skills/shared/github-actions/evals/README.md +3 -0
  662. package/skills/shared/github-actions/evals/cases.yaml +45 -0
  663. package/skills/shared/github-actions/references/caching-and-matrix.md +92 -0
  664. package/skills/shared/github-actions/references/oidc-deploys.md +130 -0
  665. package/skills/shared/github-actions/scripts/verify.sh +105 -0
  666. package/skills/shared/gitlab-auth/SKILL.md +99 -0
  667. package/skills/shared/gitlab-workflow/SKILL.md +138 -0
  668. package/skills/shared/go/SKILL.md +390 -0
  669. package/skills/shared/go/evals/README.md +56 -0
  670. package/skills/shared/go/evals/cases.yaml +55 -0
  671. package/skills/shared/go/references/concurrency.md +557 -0
  672. package/skills/shared/go/references/http-services.md +529 -0
  673. package/skills/shared/go/references/testing.md +338 -0
  674. package/skills/shared/go/scripts/verify.sh +134 -0
  675. package/skills/shared/godot/SKILL.md +300 -0
  676. package/skills/shared/godot/evals/README.md +13 -0
  677. package/skills/shared/godot/evals/cases.yaml +50 -0
  678. package/skills/shared/godot/references/export-and-testing.md +102 -0
  679. package/skills/shared/godot/references/gdscript-style.md +84 -0
  680. package/skills/shared/godot/references/godot3-to-4-traps.md +89 -0
  681. package/skills/shared/godot/references/nodes-scenes-resources.md +109 -0
  682. package/skills/shared/harness/SKILL.md +316 -0
  683. package/skills/shared/harness/assets/_TEMPLATE/.env.example +8 -0
  684. package/skills/shared/harness/assets/_TEMPLATE/CREDENTIALS.md +25 -0
  685. package/skills/shared/harness/assets/_TEMPLATE/README.md +25 -0
  686. package/skills/shared/harness/assets/_TEMPLATE/gitignore +10 -0
  687. package/skills/shared/harness/assets/_TEMPLATE/test_connection.sh +30 -0
  688. package/skills/shared/harness/evals/README.md +54 -0
  689. package/skills/shared/harness/evals/cases.yaml +72 -0
  690. package/skills/shared/harness/examples/audit-example.md +120 -0
  691. package/skills/shared/harness/references/agents-md-template.md +41 -0
  692. package/skills/shared/harness/references/audit-report-template.html +140 -0
  693. package/skills/shared/harness/references/audit-report-template.md +116 -0
  694. package/skills/shared/harness/references/claude-md-template.md +85 -0
  695. package/skills/shared/harness/references/daily-curation-automation.md +68 -0
  696. package/skills/shared/harness/references/inbox-readme-template.md +51 -0
  697. package/skills/shared/harness/references/ingest-formats.md +185 -0
  698. package/skills/shared/harness/references/ingest-ignore-defaults.md +48 -0
  699. package/skills/shared/harness/references/obsidian-scaffolding.md +103 -0
  700. package/skills/shared/harness/references/providers.yaml +3546 -0
  701. package/skills/shared/harness/references/tools-readme-template.md +88 -0
  702. package/skills/shared/harness/references/wiki-archive-template.html +81 -0
  703. package/skills/shared/harness/references/wiki-article-template.md +60 -0
  704. package/skills/shared/harness/references/wiki-dashboard-template.html +136 -0
  705. package/skills/shared/harness/references/wiki-deep-improve-report-template.html +126 -0
  706. package/skills/shared/harness/references/wiki-gaps-template.md +22 -0
  707. package/skills/shared/harness/references/wiki-index-template.md +32 -0
  708. package/skills/shared/harness/references/wiki-protocol.md +926 -0
  709. package/skills/shared/harness/references/wiki-raw-template.md +7 -0
  710. package/skills/shared/harness/references/wiki-worklog-template.md +60 -0
  711. package/skills/shared/hetzner/SKILL.md +203 -0
  712. package/skills/shared/hetzner/evals/README.md +35 -0
  713. package/skills/shared/hetzner/evals/cases.yaml +46 -0
  714. package/skills/shared/hetzner/references/cloud-init.md +120 -0
  715. package/skills/shared/hetzner/references/plans-and-locations.md +56 -0
  716. package/skills/shared/hetzner/scripts/verify.sh +122 -0
  717. package/skills/shared/htmx/SKILL.md +261 -0
  718. package/skills/shared/htmx/evals/README.md +3 -0
  719. package/skills/shared/htmx/evals/cases.yaml +38 -0
  720. package/skills/shared/htmx/references/patterns.md +113 -0
  721. package/skills/shared/htmx/references/server-contract.md +91 -0
  722. package/skills/shared/htmx/scripts/verify.sh +93 -0
  723. package/skills/shared/huggingface/SKILL.md +191 -0
  724. package/skills/shared/huggingface/evals/README.md +11 -0
  725. package/skills/shared/huggingface/evals/cases.yaml +41 -0
  726. package/skills/shared/huggingface/references/endpoints-and-spaces.md +99 -0
  727. package/skills/shared/huggingface/references/hub-and-cli.md +85 -0
  728. package/skills/shared/huggingface/references/inference-providers.md +115 -0
  729. package/skills/shared/huggingface/scripts/verify.sh +123 -0
  730. package/skills/shared/idea-refinement/SKILL.md +121 -0
  731. package/skills/shared/idea-refinement/evals/README.md +3 -0
  732. package/skills/shared/idea-refinement/evals/cases.yaml +42 -0
  733. package/skills/shared/implement/SKILL.md +383 -0
  734. package/skills/shared/implement/evals/README.md +56 -0
  735. package/skills/shared/implement/evals/cases.yaml +43 -0
  736. package/skills/shared/implement/references/per-task-review.md +46 -0
  737. package/skills/shared/implement/scripts/review-package +59 -0
  738. package/skills/shared/implement/scripts/sdd-workspace +47 -0
  739. package/skills/shared/implement/scripts/task-brief +77 -0
  740. package/skills/shared/init/SKILL.md +209 -0
  741. package/skills/shared/init/evals/README.md +49 -0
  742. package/skills/shared/init/evals/cases.yaml +74 -0
  743. package/skills/shared/init/references/accompaniment-and-profile.md +122 -0
  744. package/skills/shared/init/references/discovery.md +90 -0
  745. package/skills/shared/init/references/recommend-skills.md +115 -0
  746. package/skills/shared/init/scripts/verify.sh +118 -0
  747. package/skills/shared/java/SKILL.md +341 -0
  748. package/skills/shared/java/evals/README.md +23 -0
  749. package/skills/shared/java/evals/cases.yaml +43 -0
  750. package/skills/shared/java/references/builds.md +133 -0
  751. package/skills/shared/java/references/concurrency.md +108 -0
  752. package/skills/shared/java/references/streams.md +102 -0
  753. package/skills/shared/java/scripts/verify.sh +107 -0
  754. package/skills/shared/knowledge-ops/SKILL.md +122 -0
  755. package/skills/shared/knowledge-ops/evals/README.md +16 -0
  756. package/skills/shared/knowledge-ops/evals/cases.yaml +50 -0
  757. package/skills/shared/knowledge-ops/references/gardening-playbook.md +126 -0
  758. package/skills/shared/kotlin-android/SKILL.md +245 -0
  759. package/skills/shared/kotlin-android/evals/README.md +13 -0
  760. package/skills/shared/kotlin-android/evals/cases.yaml +56 -0
  761. package/skills/shared/kotlin-android/references/architecture.md +200 -0
  762. package/skills/shared/kotlin-android/references/gradle-setup.md +125 -0
  763. package/skills/shared/kotlin-android/scripts/verify.sh +109 -0
  764. package/skills/shared/laravel/SKILL.md +301 -0
  765. package/skills/shared/laravel/evals/README.md +10 -0
  766. package/skills/shared/laravel/evals/cases.yaml +45 -0
  767. package/skills/shared/laravel/references/eloquent-patterns.md +126 -0
  768. package/skills/shared/laravel/references/queues-and-scheduling.md +153 -0
  769. package/skills/shared/laravel/scripts/verify.sh +128 -0
  770. package/skills/shared/level-design/SKILL.md +143 -0
  771. package/skills/shared/level-design/evals/README.md +35 -0
  772. package/skills/shared/level-design/evals/cases.yaml +58 -0
  773. package/skills/shared/level-design/references/blockout-to-art.md +118 -0
  774. package/skills/shared/level-design/references/guidance-and-readability.md +152 -0
  775. package/skills/shared/level-design/references/pacing-and-encounters.md +142 -0
  776. package/skills/shared/llm-pipeline/SKILL.md +150 -0
  777. package/skills/shared/llm-pipeline/evals/README.md +3 -0
  778. package/skills/shared/llm-pipeline/evals/cases.yaml +44 -0
  779. package/skills/shared/llm-pipeline/references/caching-layers.md +60 -0
  780. package/skills/shared/llm-pipeline/references/litellm-router.md +101 -0
  781. package/skills/shared/llm-pipeline/scripts/verify.sh +169 -0
  782. package/skills/shared/machine-learning/SKILL.md +228 -0
  783. package/skills/shared/machine-learning/evals/README.md +15 -0
  784. package/skills/shared/machine-learning/evals/cases.yaml +54 -0
  785. package/skills/shared/machine-learning/references/gbdt-and-tuning.md +83 -0
  786. package/skills/shared/machine-learning/references/metrics-and-imbalance.md +82 -0
  787. package/skills/shared/machine-learning/references/pipelines-and-cv.md +135 -0
  788. package/skills/shared/modal/SKILL.md +290 -0
  789. package/skills/shared/modal/evals/README.md +29 -0
  790. package/skills/shared/modal/evals/cases.yaml +50 -0
  791. package/skills/shared/modal/references/images-gpu-cookbook.md +160 -0
  792. package/skills/shared/modal/references/web-and-scaling.md +138 -0
  793. package/skills/shared/modal/scripts/verify.sh +127 -0
  794. package/skills/shared/mongodb/SKILL.md +342 -0
  795. package/skills/shared/mongodb/evals/README.md +29 -0
  796. package/skills/shared/mongodb/evals/cases.yaml +41 -0
  797. package/skills/shared/mongodb/references/aggregation.md +115 -0
  798. package/skills/shared/mongodb/references/data-modeling.md +135 -0
  799. package/skills/shared/mongodb/references/transactions-and-ops.md +128 -0
  800. package/skills/shared/mongodb/scripts/verify.sh +151 -0
  801. package/skills/shared/monitoring/SKILL.md +155 -0
  802. package/skills/shared/monitoring/evals/README.md +3 -0
  803. package/skills/shared/monitoring/evals/cases.yaml +47 -0
  804. package/skills/shared/monitoring/references/burn-rate-and-oncall.md +128 -0
  805. package/skills/shared/monitoring/references/tool-setup.md +154 -0
  806. package/skills/shared/monitoring/scripts/verify.sh +145 -0
  807. package/skills/shared/mysql/SKILL.md +249 -0
  808. package/skills/shared/mysql/evals/README.md +12 -0
  809. package/skills/shared/mysql/evals/cases.yaml +49 -0
  810. package/skills/shared/mysql/references/indexing-and-explain.md +161 -0
  811. package/skills/shared/mysql/references/mysql-vs-mariadb.md +78 -0
  812. package/skills/shared/mysql/references/online-ddl-and-migrations.md +120 -0
  813. package/skills/shared/mysql/references/replication-and-ha.md +115 -0
  814. package/skills/shared/mysql/scripts/verify.sh +141 -0
  815. package/skills/shared/neon/SKILL.md +218 -0
  816. package/skills/shared/neon/evals/README.md +11 -0
  817. package/skills/shared/neon/evals/cases.yaml +45 -0
  818. package/skills/shared/neon/references/branching-ci.md +86 -0
  819. package/skills/shared/neon/scripts/verify.sh +78 -0
  820. package/skills/shared/nestjs/SKILL.md +217 -0
  821. package/skills/shared/nestjs/evals/README.md +3 -0
  822. package/skills/shared/nestjs/evals/cases.yaml +38 -0
  823. package/skills/shared/nestjs/references/cross-cutting.md +135 -0
  824. package/skills/shared/nestjs/references/testing-recipes.md +105 -0
  825. package/skills/shared/nestjs/scripts/verify.sh +98 -0
  826. package/skills/shared/netlify/SKILL.md +208 -0
  827. package/skills/shared/netlify/evals/README.md +13 -0
  828. package/skills/shared/netlify/evals/cases.yaml +43 -0
  829. package/skills/shared/netlify/references/functions.md +97 -0
  830. package/skills/shared/netlify/references/netlify-toml.md +115 -0
  831. package/skills/shared/netlify/scripts/verify.sh +95 -0
  832. package/skills/shared/nextjs/SKILL.md +400 -0
  833. package/skills/shared/nextjs/evals/README.md +59 -0
  834. package/skills/shared/nextjs/evals/cases.yaml +56 -0
  835. package/skills/shared/nextjs/references/data-and-caching.md +309 -0
  836. package/skills/shared/nextjs/references/metadata.md +208 -0
  837. package/skills/shared/nextjs/references/performance.md +325 -0
  838. package/skills/shared/nextjs/references/react.md +383 -0
  839. package/skills/shared/nextjs/references/security.md +239 -0
  840. package/skills/shared/nextjs/references/testing.md +290 -0
  841. package/skills/shared/nextjs/scripts/verify.sh +141 -0
  842. package/skills/shared/nlp/SKILL.md +225 -0
  843. package/skills/shared/nlp/evals/README.md +10 -0
  844. package/skills/shared/nlp/evals/cases.yaml +45 -0
  845. package/skills/shared/nlp/references/evaluation.md +107 -0
  846. package/skills/shared/nlp/references/tokenization.md +95 -0
  847. package/skills/shared/no-code-app/SKILL.md +145 -0
  848. package/skills/shared/no-code-app/evals/README.md +3 -0
  849. package/skills/shared/no-code-app/evals/cases.yaml +43 -0
  850. package/skills/shared/no-code-app/references/platform-limits.md +100 -0
  851. package/skills/shared/nodejs/SKILL.md +229 -0
  852. package/skills/shared/nodejs/evals/README.md +3 -0
  853. package/skills/shared/nodejs/evals/cases.yaml +39 -0
  854. package/skills/shared/nodejs/references/express5-migration.md +53 -0
  855. package/skills/shared/nodejs/references/graceful-shutdown.md +73 -0
  856. package/skills/shared/nodejs/scripts/verify.sh +122 -0
  857. package/skills/shared/observability/SKILL.md +235 -0
  858. package/skills/shared/observability/evals/README.md +3 -0
  859. package/skills/shared/observability/evals/cases.yaml +51 -0
  860. package/skills/shared/observability/references/collector-config.md +98 -0
  861. package/skills/shared/observability/references/instrumentation-recipes.md +115 -0
  862. package/skills/shared/observability/scripts/verify.sh +156 -0
  863. package/skills/shared/ollama/SKILL.md +213 -0
  864. package/skills/shared/ollama/evals/README.md +9 -0
  865. package/skills/shared/ollama/evals/cases.yaml +43 -0
  866. package/skills/shared/ollama/references/api.md +148 -0
  867. package/skills/shared/ollama/references/hardware-sizing.md +87 -0
  868. package/skills/shared/ollama/scripts/verify.sh +116 -0
  869. package/skills/shared/open-weights/SKILL.md +239 -0
  870. package/skills/shared/open-weights/evals/README.md +14 -0
  871. package/skills/shared/open-weights/evals/cases.yaml +42 -0
  872. package/skills/shared/open-weights/references/licenses.md +123 -0
  873. package/skills/shared/open-weights/references/model-families.md +83 -0
  874. package/skills/shared/open-weights/references/sizing-and-quant.md +89 -0
  875. package/skills/shared/orient/SKILL.md +92 -0
  876. package/skills/shared/orient/evals/README.md +18 -0
  877. package/skills/shared/orient/evals/cases.yaml +67 -0
  878. package/skills/shared/orient/references/explain-ladder.md +93 -0
  879. package/skills/shared/orient/references/orientation-contract.md +86 -0
  880. package/skills/shared/parallel/SKILL.md +168 -0
  881. package/skills/shared/parallel/evals/README.md +62 -0
  882. package/skills/shared/parallel/evals/cases.yaml +44 -0
  883. package/skills/shared/performance/SKILL.md +229 -0
  884. package/skills/shared/performance/evals/README.md +3 -0
  885. package/skills/shared/performance/evals/cases.yaml +49 -0
  886. package/skills/shared/performance/references/profiling-playbook.md +54 -0
  887. package/skills/shared/performance/scripts/verify.sh +94 -0
  888. package/skills/shared/phoenix/SKILL.md +169 -0
  889. package/skills/shared/phoenix/evals/README.md +3 -0
  890. package/skills/shared/phoenix/evals/cases.yaml +40 -0
  891. package/skills/shared/phoenix/references/auth-and-scopes.md +82 -0
  892. package/skills/shared/phoenix/references/ecto-patterns.md +93 -0
  893. package/skills/shared/phoenix/references/liveview.md +134 -0
  894. package/skills/shared/phoenix/scripts/verify.sh +73 -0
  895. package/skills/shared/php/SKILL.md +397 -0
  896. package/skills/shared/php/evals/README.md +12 -0
  897. package/skills/shared/php/evals/cases.yaml +45 -0
  898. package/skills/shared/php/references/tooling.md +170 -0
  899. package/skills/shared/php/references/type-system.md +220 -0
  900. package/skills/shared/php/scripts/verify.sh +155 -0
  901. package/skills/shared/plan/SKILL.md +166 -0
  902. package/skills/shared/plan/evals/README.md +62 -0
  903. package/skills/shared/plan/evals/cases.yaml +49 -0
  904. package/skills/shared/plan/references/plan-template.md +153 -0
  905. package/skills/shared/planetscale/SKILL.md +198 -0
  906. package/skills/shared/planetscale/evals/README.md +11 -0
  907. package/skills/shared/planetscale/evals/cases.yaml +46 -0
  908. package/skills/shared/planetscale/references/deploy-requests.md +75 -0
  909. package/skills/shared/planetscale/references/no-foreign-keys.md +88 -0
  910. package/skills/shared/planetscale/scripts/verify.sh +115 -0
  911. package/skills/shared/planning-with-files/SKILL.md +278 -0
  912. package/skills/shared/planning-with-files/examples.md +202 -0
  913. package/skills/shared/planning-with-files/reference.md +218 -0
  914. package/skills/shared/planning-with-files/scripts/attest-plan.ps1 +118 -0
  915. package/skills/shared/planning-with-files/scripts/attest-plan.sh +110 -0
  916. package/skills/shared/planning-with-files/scripts/check-complete.ps1 +44 -0
  917. package/skills/shared/planning-with-files/scripts/check-complete.sh +46 -0
  918. package/skills/shared/planning-with-files/scripts/init-session.ps1 +166 -0
  919. package/skills/shared/planning-with-files/scripts/init-session.sh +284 -0
  920. package/skills/shared/planning-with-files/scripts/resolve-plan-dir.ps1 +44 -0
  921. package/skills/shared/planning-with-files/scripts/resolve-plan-dir.sh +76 -0
  922. package/skills/shared/planning-with-files/scripts/session-catchup.py +438 -0
  923. package/skills/shared/planning-with-files/scripts/set-active-plan.ps1 +50 -0
  924. package/skills/shared/planning-with-files/scripts/set-active-plan.sh +50 -0
  925. package/skills/shared/planning-with-files/templates/findings.md +95 -0
  926. package/skills/shared/planning-with-files/templates/progress.md +114 -0
  927. package/skills/shared/planning-with-files/templates/task_plan.md +132 -0
  928. package/skills/shared/postgresdb/SKILL.md +354 -0
  929. package/skills/shared/postgresdb/evals/README.md +55 -0
  930. package/skills/shared/postgresdb/evals/cases.yaml +57 -0
  931. package/skills/shared/postgresdb/references/migrations.md +279 -0
  932. package/skills/shared/postgresdb/references/operations-and-security.md +267 -0
  933. package/skills/shared/postgresdb/references/query-optimization.md +374 -0
  934. package/skills/shared/postgresdb/references/schema-and-indexing.md +379 -0
  935. package/skills/shared/postgresdb/scripts/verify.sh +191 -0
  936. package/skills/shared/prisma-orm/SKILL.md +313 -0
  937. package/skills/shared/prisma-orm/evals/README.md +12 -0
  938. package/skills/shared/prisma-orm/evals/cases.yaml +56 -0
  939. package/skills/shared/prisma-orm/references/migrations-and-v7-upgrade.md +197 -0
  940. package/skills/shared/prisma-orm/references/queries-and-performance.md +169 -0
  941. package/skills/shared/prisma-orm/scripts/verify.sh +137 -0
  942. package/skills/shared/prompt-engineering/SKILL.md +127 -0
  943. package/skills/shared/prompt-engineering/evals/README.md +11 -0
  944. package/skills/shared/prompt-engineering/evals/cases.yaml +46 -0
  945. package/skills/shared/prompt-engineering/references/eval-templates.md +94 -0
  946. package/skills/shared/prompt-engineering/references/output-contracts.md +120 -0
  947. package/skills/shared/prompt-engineering/scripts/verify.sh +84 -0
  948. package/skills/shared/python/SKILL.md +320 -0
  949. package/skills/shared/python/evals/README.md +19 -0
  950. package/skills/shared/python/evals/cases.yaml +46 -0
  951. package/skills/shared/python/references/async.md +136 -0
  952. package/skills/shared/python/references/stdlib.md +162 -0
  953. package/skills/shared/python/references/typing.md +160 -0
  954. package/skills/shared/python/scripts/verify.sh +125 -0
  955. package/skills/shared/rag/SKILL.md +209 -0
  956. package/skills/shared/rag/evals/README.md +13 -0
  957. package/skills/shared/rag/evals/cases.yaml +45 -0
  958. package/skills/shared/rag/references/evaluation.md +99 -0
  959. package/skills/shared/rag/references/pipeline.md +151 -0
  960. package/skills/shared/rag/scripts/verify.sh +99 -0
  961. package/skills/shared/rails/SKILL.md +264 -0
  962. package/skills/shared/rails/evals/README.md +12 -0
  963. package/skills/shared/rails/evals/cases.yaml +47 -0
  964. package/skills/shared/rails/references/activerecord.md +148 -0
  965. package/skills/shared/rails/references/hotwire.md +139 -0
  966. package/skills/shared/rails/references/testing.md +110 -0
  967. package/skills/shared/rails/scripts/verify.sh +128 -0
  968. package/skills/shared/railway/SKILL.md +245 -0
  969. package/skills/shared/railway/evals/README.md +14 -0
  970. package/skills/shared/railway/evals/cases.yaml +44 -0
  971. package/skills/shared/railway/references/cli-cookbook.md +137 -0
  972. package/skills/shared/railway/references/config-as-code.md +120 -0
  973. package/skills/shared/railway/scripts/verify.sh +162 -0
  974. package/skills/shared/react/SKILL.md +182 -0
  975. package/skills/shared/react/evals/README.md +3 -0
  976. package/skills/shared/react/evals/cases.yaml +43 -0
  977. package/skills/shared/react/references/data-and-state.md +152 -0
  978. package/skills/shared/react/references/performance.md +75 -0
  979. package/skills/shared/react/references/routing.md +99 -0
  980. package/skills/shared/react/scripts/verify.sh +123 -0
  981. package/skills/shared/react-native/SKILL.md +215 -0
  982. package/skills/shared/react-native/evals/README.md +3 -0
  983. package/skills/shared/react-native/evals/cases.yaml +42 -0
  984. package/skills/shared/react-native/references/native-modules.md +123 -0
  985. package/skills/shared/react-native/references/performance-debugging.md +46 -0
  986. package/skills/shared/react-native/scripts/verify.sh +120 -0
  987. package/skills/shared/redis/SKILL.md +298 -0
  988. package/skills/shared/redis/evals/README.md +10 -0
  989. package/skills/shared/redis/evals/cases.yaml +43 -0
  990. package/skills/shared/redis/references/caching.md +116 -0
  991. package/skills/shared/redis/references/locks-and-rate-limiting.md +140 -0
  992. package/skills/shared/redis/references/queues.md +102 -0
  993. package/skills/shared/redis/scripts/verify.sh +164 -0
  994. package/skills/shared/render/SKILL.md +256 -0
  995. package/skills/shared/render/evals/README.md +12 -0
  996. package/skills/shared/render/evals/cases.yaml +45 -0
  997. package/skills/shared/render/references/blueprint-reference.md +203 -0
  998. package/skills/shared/render/scripts/verify.sh +167 -0
  999. package/skills/shared/replicate/SKILL.md +210 -0
  1000. package/skills/shared/replicate/evals/README.md +9 -0
  1001. package/skills/shared/replicate/evals/cases.yaml +45 -0
  1002. package/skills/shared/replicate/references/cog-packaging.md +89 -0
  1003. package/skills/shared/replicate/references/deployments-api.md +87 -0
  1004. package/skills/shared/replicate/references/webhooks-and-async.md +110 -0
  1005. package/skills/shared/replicate/scripts/verify.sh +162 -0
  1006. package/skills/shared/research-ops/SKILL.md +200 -0
  1007. package/skills/shared/research-ops/evals/README.md +13 -0
  1008. package/skills/shared/research-ops/evals/cases.yaml +38 -0
  1009. package/skills/shared/research-ops/references/credibility-rubric.md +78 -0
  1010. package/skills/shared/research-ops/references/memo-template.md +63 -0
  1011. package/skills/shared/research-ops/scripts/verify.sh +181 -0
  1012. package/skills/shared/review/SKILL.md +314 -0
  1013. package/skills/shared/review/evals/README.md +84 -0
  1014. package/skills/shared/review/evals/cases.yaml +55 -0
  1015. package/skills/shared/ruby/SKILL.md +295 -0
  1016. package/skills/shared/ruby/evals/README.md +12 -0
  1017. package/skills/shared/ruby/evals/cases.yaml +41 -0
  1018. package/skills/shared/ruby/references/gems-and-testing.md +208 -0
  1019. package/skills/shared/ruby/references/metaprogramming.md +161 -0
  1020. package/skills/shared/ruby/scripts/verify.sh +83 -0
  1021. package/skills/shared/runpod/SKILL.md +238 -0
  1022. package/skills/shared/runpod/evals/README.md +11 -0
  1023. package/skills/shared/runpod/evals/cases.yaml +47 -0
  1024. package/skills/shared/runpod/references/cost-and-scaling.md +85 -0
  1025. package/skills/shared/runpod/references/serverless-workers.md +101 -0
  1026. package/skills/shared/runpod/scripts/verify.sh +126 -0
  1027. package/skills/shared/rust/SKILL.md +320 -0
  1028. package/skills/shared/rust/evals/README.md +12 -0
  1029. package/skills/shared/rust/evals/cases.yaml +42 -0
  1030. package/skills/shared/rust/references/async-tokio.md +141 -0
  1031. package/skills/shared/rust/references/axum-service.md +132 -0
  1032. package/skills/shared/rust/references/ownership.md +86 -0
  1033. package/skills/shared/rust/references/testing.md +108 -0
  1034. package/skills/shared/rust/scripts/verify.sh +91 -0
  1035. package/skills/shared/scaling/SKILL.md +137 -0
  1036. package/skills/shared/scaling/evals/README.md +3 -0
  1037. package/skills/shared/scaling/evals/cases.yaml +42 -0
  1038. package/skills/shared/scaling/references/load-testing-k6.md +127 -0
  1039. package/skills/shared/scaling/scripts/example.load.js +24 -0
  1040. package/skills/shared/scaling/scripts/verify.sh +70 -0
  1041. package/skills/shared/sdd/SKILL.md +250 -0
  1042. package/skills/shared/sdd/evals/README.md +60 -0
  1043. package/skills/shared/sdd/evals/cases.yaml +90 -0
  1044. package/skills/shared/sdd/references/model-routing.md +194 -0
  1045. package/skills/shared/sdd-init/SKILL.md +189 -0
  1046. package/skills/shared/sdd-init/evals/README.md +3 -0
  1047. package/skills/shared/sdd-init/evals/cases.yaml +43 -0
  1048. package/skills/shared/secure-coding/SKILL.md +336 -0
  1049. package/skills/shared/secure-coding/evals/README.md +68 -0
  1050. package/skills/shared/secure-coding/evals/cases.yaml +55 -0
  1051. package/skills/shared/secure-coding/references/authn-authz.md +249 -0
  1052. package/skills/shared/secure-coding/references/owasp-by-stack.md +574 -0
  1053. package/skills/shared/secure-coding/references/secrets-and-supply-chain.md +205 -0
  1054. package/skills/shared/secure-coding/references/threat-modeling.md +213 -0
  1055. package/skills/shared/secure-coding/scripts/verify.sh +208 -0
  1056. package/skills/shared/security-scan/SKILL.md +219 -0
  1057. package/skills/shared/security-scan/evals/README.md +14 -0
  1058. package/skills/shared/security-scan/evals/cases.yaml +50 -0
  1059. package/skills/shared/security-scan/references/tools.md +97 -0
  1060. package/skills/shared/security-scan/references/triage.md +92 -0
  1061. package/skills/shared/security-scan/scripts/verify.sh +108 -0
  1062. package/skills/shared/ship/SKILL.md +272 -0
  1063. package/skills/shared/ship/evals/README.md +89 -0
  1064. package/skills/shared/ship/evals/cases.yaml +44 -0
  1065. package/skills/shared/shopify/SKILL.md +229 -0
  1066. package/skills/shared/shopify/evals/README.md +14 -0
  1067. package/skills/shared/shopify/evals/cases.yaml +41 -0
  1068. package/skills/shared/shopify/references/apps-graphql.md +103 -0
  1069. package/skills/shared/shopify/references/checkout-extensibility.md +71 -0
  1070. package/skills/shared/shopify/references/liquid-themes.md +89 -0
  1071. package/skills/shared/shopify/scripts/verify.sh +120 -0
  1072. package/skills/shared/simplify-code/SKILL.md +101 -0
  1073. package/skills/shared/simplify-code/evals/README.md +3 -0
  1074. package/skills/shared/simplify-code/evals/cases.yaml +42 -0
  1075. package/skills/shared/skill-scout/SKILL.md +169 -0
  1076. package/skills/shared/skill-scout/evals/README.md +12 -0
  1077. package/skills/shared/skill-scout/evals/cases.yaml +56 -0
  1078. package/skills/shared/skill-scout/references/install-commands.md +76 -0
  1079. package/skills/shared/skill-scout/scripts/verify.sh +154 -0
  1080. package/skills/shared/solid-js/SKILL.md +260 -0
  1081. package/skills/shared/solid-js/evals/README.md +3 -0
  1082. package/skills/shared/solid-js/evals/cases.yaml +38 -0
  1083. package/skills/shared/solid-js/references/reactivity-deep-dive.md +89 -0
  1084. package/skills/shared/solid-js/references/router-and-start.md +93 -0
  1085. package/skills/shared/solid-js/scripts/verify.sh +130 -0
  1086. package/skills/shared/source-grounded-development/SKILL.md +108 -0
  1087. package/skills/shared/source-grounded-development/evals/README.md +3 -0
  1088. package/skills/shared/source-grounded-development/evals/cases.yaml +42 -0
  1089. package/skills/shared/specify/SKILL.md +391 -0
  1090. package/skills/shared/specify/evals/README.md +73 -0
  1091. package/skills/shared/specify/evals/cases.yaml +93 -0
  1092. package/skills/shared/specify/references/eliciting-requirements.md +117 -0
  1093. package/skills/shared/specify/references/spec-template.md +101 -0
  1094. package/skills/shared/speckit-analyze/SKILL.md +35 -0
  1095. package/skills/shared/speckit-assess-decide/SKILL.md +36 -0
  1096. package/skills/shared/speckit-assess-define/SKILL.md +36 -0
  1097. package/skills/shared/speckit-assess-intake/SKILL.md +38 -0
  1098. package/skills/shared/speckit-assess-research/SKILL.md +36 -0
  1099. package/skills/shared/speckit-assess-shape/SKILL.md +36 -0
  1100. package/skills/shared/speckit-bug-assess/SKILL.md +38 -0
  1101. package/skills/shared/speckit-bug-fix/SKILL.md +37 -0
  1102. package/skills/shared/speckit-bug-test/SKILL.md +37 -0
  1103. package/skills/shared/speckit-checklist/SKILL.md +35 -0
  1104. package/skills/shared/speckit-clarify/SKILL.md +32 -0
  1105. package/skills/shared/speckit-constitution/SKILL.md +35 -0
  1106. package/skills/shared/speckit-converge/SKILL.md +36 -0
  1107. package/skills/shared/speckit-implement/SKILL.md +32 -0
  1108. package/skills/shared/speckit-plan/SKILL.md +37 -0
  1109. package/skills/shared/speckit-specify/SKILL.md +36 -0
  1110. package/skills/shared/speckit-tasks/SKILL.md +34 -0
  1111. package/skills/shared/spreadsheet-ops/SKILL.md +180 -0
  1112. package/skills/shared/spreadsheet-ops/evals/README.md +33 -0
  1113. package/skills/shared/spreadsheet-ops/evals/cases.yaml +42 -0
  1114. package/skills/shared/spreadsheet-ops/references/formula-cookbook.md +70 -0
  1115. package/skills/shared/spreadsheet-ops/references/python-excel.md +87 -0
  1116. package/skills/shared/spreadsheet-ops/references/sheets-api-appsscript.md +118 -0
  1117. package/skills/shared/spreadsheet-ops/scripts/verify.sh +152 -0
  1118. package/skills/shared/spring-boot/SKILL.md +350 -0
  1119. package/skills/shared/spring-boot/evals/README.md +11 -0
  1120. package/skills/shared/spring-boot/evals/cases.yaml +49 -0
  1121. package/skills/shared/spring-boot/references/jpa.md +94 -0
  1122. package/skills/shared/spring-boot/references/security.md +92 -0
  1123. package/skills/shared/spring-boot/references/testing.md +95 -0
  1124. package/skills/shared/spring-boot/scripts/verify.sh +115 -0
  1125. package/skills/shared/sql/SKILL.md +286 -0
  1126. package/skills/shared/sql/evals/README.md +9 -0
  1127. package/skills/shared/sql/evals/cases.yaml +49 -0
  1128. package/skills/shared/sql/references/ctes-and-recursion.md +63 -0
  1129. package/skills/shared/sql/references/joins-and-sets.md +71 -0
  1130. package/skills/shared/sql/references/portability.md +38 -0
  1131. package/skills/shared/sql/references/window-functions.md +72 -0
  1132. package/skills/shared/sql/scripts/verify.sh +139 -0
  1133. package/skills/shared/sqlite-turso/SKILL.md +214 -0
  1134. package/skills/shared/sqlite-turso/evals/README.md +24 -0
  1135. package/skills/shared/sqlite-turso/evals/cases.yaml +45 -0
  1136. package/skills/shared/sqlite-turso/references/embedded-replicas.md +96 -0
  1137. package/skills/shared/sqlite-turso/scripts/verify.sh +95 -0
  1138. package/skills/shared/structured-extraction/SKILL.md +230 -0
  1139. package/skills/shared/structured-extraction/evals/README.md +13 -0
  1140. package/skills/shared/structured-extraction/evals/cases.yaml +70 -0
  1141. package/skills/shared/structured-extraction/references/providers.md +152 -0
  1142. package/skills/shared/structured-extraction/scripts/verify.sh +160 -0
  1143. package/skills/shared/suggest/SKILL.md +123 -0
  1144. package/skills/shared/suggest/evals/README.md +17 -0
  1145. package/skills/shared/suggest/evals/cases.yaml +78 -0
  1146. package/skills/shared/supabase/SKILL.md +268 -0
  1147. package/skills/shared/supabase/evals/README.md +12 -0
  1148. package/skills/shared/supabase/evals/cases.yaml +42 -0
  1149. package/skills/shared/supabase/references/auth-ssr.md +173 -0
  1150. package/skills/shared/supabase/references/rls-cookbook.md +122 -0
  1151. package/skills/shared/supabase/scripts/verify.sh +149 -0
  1152. package/skills/shared/svelte/SKILL.md +238 -0
  1153. package/skills/shared/svelte/evals/README.md +3 -0
  1154. package/skills/shared/svelte/evals/cases.yaml +41 -0
  1155. package/skills/shared/svelte/references/runes.md +97 -0
  1156. package/skills/shared/svelte/references/sveltekit-data.md +156 -0
  1157. package/skills/shared/svelte/scripts/verify.sh +128 -0
  1158. package/skills/shared/swift-ios/SKILL.md +224 -0
  1159. package/skills/shared/swift-ios/evals/README.md +3 -0
  1160. package/skills/shared/swift-ios/evals/cases.yaml +46 -0
  1161. package/skills/shared/swift-ios/references/concurrency.md +132 -0
  1162. package/skills/shared/swift-ios/references/testing.md +112 -0
  1163. package/skills/shared/swift-ios/scripts/verify.sh +98 -0
  1164. package/skills/shared/tasks/SKILL.md +265 -0
  1165. package/skills/shared/tasks/evals/README.md +70 -0
  1166. package/skills/shared/tasks/evals/cases.yaml +75 -0
  1167. package/skills/shared/tauri/SKILL.md +219 -0
  1168. package/skills/shared/tauri/evals/README.md +12 -0
  1169. package/skills/shared/tauri/evals/cases.yaml +46 -0
  1170. package/skills/shared/tauri/references/bundling-distribution.md +129 -0
  1171. package/skills/shared/tauri/references/security.md +143 -0
  1172. package/skills/shared/tauri/scripts/verify.sh +178 -0
  1173. package/skills/shared/technical-writing/SKILL.md +230 -0
  1174. package/skills/shared/technical-writing/evals/README.md +12 -0
  1175. package/skills/shared/technical-writing/evals/cases.yaml +53 -0
  1176. package/skills/shared/technical-writing/references/diataxis-modes.md +131 -0
  1177. package/skills/shared/technical-writing/references/vale-starter.md +90 -0
  1178. package/skills/shared/technical-writing/scripts/verify.sh +83 -0
  1179. package/skills/shared/testing-go/SKILL.md +263 -0
  1180. package/skills/shared/testing-go/evals/README.md +3 -0
  1181. package/skills/shared/testing-go/evals/cases.yaml +46 -0
  1182. package/skills/shared/testing-go/references/coverage-and-benchmarks.md +85 -0
  1183. package/skills/shared/testing-go/references/mocks-and-fakes.md +140 -0
  1184. package/skills/shared/testing-go/references/synctest-and-concurrency.md +82 -0
  1185. package/skills/shared/testing-go/scripts/verify.sh +72 -0
  1186. package/skills/shared/testing-py/SKILL.md +197 -0
  1187. package/skills/shared/testing-py/evals/README.md +5 -0
  1188. package/skills/shared/testing-py/evals/cases.yaml +44 -0
  1189. package/skills/shared/testing-py/references/mocking.md +141 -0
  1190. package/skills/shared/testing-py/references/property-testing.md +99 -0
  1191. package/skills/shared/testing-py/scripts/verify.sh +117 -0
  1192. package/skills/shared/testing-web/SKILL.md +244 -0
  1193. package/skills/shared/testing-web/evals/README.md +11 -0
  1194. package/skills/shared/testing-web/evals/cases.yaml +52 -0
  1195. package/skills/shared/testing-web/references/jest-setup.md +88 -0
  1196. package/skills/shared/testing-web/references/recipes.md +116 -0
  1197. package/skills/shared/testing-web/scripts/verify.sh +111 -0
  1198. package/skills/shared/together-fireworks/SKILL.md +176 -0
  1199. package/skills/shared/together-fireworks/evals/README.md +3 -0
  1200. package/skills/shared/together-fireworks/evals/cases.yaml +50 -0
  1201. package/skills/shared/together-fireworks/references/batch-and-tuning.md +59 -0
  1202. package/skills/shared/together-fireworks/references/models-and-pricing.md +79 -0
  1203. package/skills/shared/together-fireworks/scripts/verify.sh +165 -0
  1204. package/skills/shared/training-data/SKILL.md +226 -0
  1205. package/skills/shared/training-data/evals/README.md +13 -0
  1206. package/skills/shared/training-data/evals/cases.yaml +41 -0
  1207. package/skills/shared/training-data/references/formats.md +118 -0
  1208. package/skills/shared/training-data/references/synthesis-dedup-quality.md +134 -0
  1209. package/skills/shared/translation-l10n/SKILL.md +229 -0
  1210. package/skills/shared/translation-l10n/evals/README.md +3 -0
  1211. package/skills/shared/translation-l10n/evals/cases.yaml +39 -0
  1212. package/skills/shared/translation-l10n/references/icu-cookbook.md +82 -0
  1213. package/skills/shared/translation-l10n/references/rtl-and-bidi.md +60 -0
  1214. package/skills/shared/typescript/SKILL.md +225 -0
  1215. package/skills/shared/typescript/evals/README.md +15 -0
  1216. package/skills/shared/typescript/evals/cases.yaml +46 -0
  1217. package/skills/shared/typescript/references/build-and-monorepo.md +141 -0
  1218. package/skills/shared/typescript/references/type-system.md +162 -0
  1219. package/skills/shared/typescript/scripts/verify.sh +52 -0
  1220. package/skills/shared/ui-engineering/SKILL.md +113 -0
  1221. package/skills/shared/ui-engineering/evals/cases.yaml +38 -0
  1222. package/skills/shared/unity/SKILL.md +282 -0
  1223. package/skills/shared/unity/evals/README.md +8 -0
  1224. package/skills/shared/unity/evals/cases.yaml +43 -0
  1225. package/skills/shared/unity/references/build-and-platforms.md +65 -0
  1226. package/skills/shared/unity/references/input-system.md +102 -0
  1227. package/skills/shared/unity/references/lifecycle-deep-dive.md +75 -0
  1228. package/skills/shared/unreal/SKILL.md +270 -0
  1229. package/skills/shared/unreal/evals/README.md +12 -0
  1230. package/skills/shared/unreal/evals/cases.yaml +45 -0
  1231. package/skills/shared/unreal/references/blueprint-cpp-parity.md +109 -0
  1232. package/skills/shared/unreal/references/gameplay-framework.md +95 -0
  1233. package/skills/shared/unreal/references/packaging.md +83 -0
  1234. package/skills/shared/unslop/SKILL.md +143 -0
  1235. package/skills/shared/unslop/evals/README.md +25 -0
  1236. package/skills/shared/unslop/evals/cases.yaml +61 -0
  1237. package/skills/shared/unsloth/SKILL.md +254 -0
  1238. package/skills/shared/unsloth/evals/README.md +10 -0
  1239. package/skills/shared/unsloth/evals/cases.yaml +42 -0
  1240. package/skills/shared/unsloth/references/export.md +75 -0
  1241. package/skills/shared/unsloth/references/grpo.md +91 -0
  1242. package/skills/shared/unsloth/references/masking-and-templates.md +91 -0
  1243. package/skills/shared/variant-explorer/SKILL.md +93 -0
  1244. package/skills/shared/variant-explorer/evals/cases.yaml +38 -0
  1245. package/skills/shared/vector-db/SKILL.md +189 -0
  1246. package/skills/shared/vector-db/evals/README.md +10 -0
  1247. package/skills/shared/vector-db/evals/cases.yaml +45 -0
  1248. package/skills/shared/vector-db/references/engines.md +175 -0
  1249. package/skills/shared/vector-db/references/tuning.md +62 -0
  1250. package/skills/shared/vector-db/scripts/verify.sh +110 -0
  1251. package/skills/shared/vercel/SKILL.md +242 -0
  1252. package/skills/shared/vercel/evals/README.md +23 -0
  1253. package/skills/shared/vercel/evals/cases.yaml +45 -0
  1254. package/skills/shared/vercel/references/cli-cookbook.md +98 -0
  1255. package/skills/shared/vercel/references/vercel-json.md +120 -0
  1256. package/skills/shared/vercel/scripts/verify.sh +168 -0
  1257. package/skills/shared/verify/SKILL.md +230 -0
  1258. package/skills/shared/verify/evals/README.md +78 -0
  1259. package/skills/shared/verify/evals/cases.yaml +104 -0
  1260. package/skills/shared/vllm/SKILL.md +235 -0
  1261. package/skills/shared/vllm/evals/README.md +9 -0
  1262. package/skills/shared/vllm/evals/cases.yaml +47 -0
  1263. package/skills/shared/vllm/references/flags-and-endpoints.md +105 -0
  1264. package/skills/shared/vllm/references/memory-and-throughput.md +78 -0
  1265. package/skills/shared/vue-nuxt/SKILL.md +323 -0
  1266. package/skills/shared/vue-nuxt/evals/README.md +11 -0
  1267. package/skills/shared/vue-nuxt/evals/cases.yaml +49 -0
  1268. package/skills/shared/vue-nuxt/references/data-and-state.md +127 -0
  1269. package/skills/shared/vue-nuxt/references/migration-nuxt4.md +79 -0
  1270. package/skills/shared/vue-nuxt/references/nitro-and-rendering.md +117 -0
  1271. package/skills/shared/vue-nuxt/references/reactivity.md +135 -0
  1272. package/skills/shared/vue-nuxt/scripts/verify.sh +148 -0
  1273. package/skills/shared/webhooks/SKILL.md +229 -0
  1274. package/skills/shared/webhooks/evals/README.md +15 -0
  1275. package/skills/shared/webhooks/evals/cases.yaml +46 -0
  1276. package/skills/shared/webhooks/references/framework-raw-body.md +97 -0
  1277. package/skills/shared/webhooks/references/signature-schemes.md +66 -0
  1278. package/skills/shared/webhooks/scripts/verify.sh +142 -0
  1279. package/skills/shared/wordpress/SKILL.md +224 -0
  1280. package/skills/shared/wordpress/evals/README.md +3 -0
  1281. package/skills/shared/wordpress/evals/cases.yaml +50 -0
  1282. package/skills/shared/wordpress/references/hardening.md +108 -0
  1283. package/skills/shared/wordpress/references/performance.md +80 -0
  1284. package/skills/shared/wordpress/references/woocommerce.md +65 -0
  1285. package/skills/shared/wordpress/scripts/verify.sh +96 -0
  1286. package/skills/shared/worktrees/SKILL.md +204 -0
  1287. package/skills/shared/worktrees/evals/README.md +78 -0
  1288. package/skills/shared/worktrees/evals/cases.yaml +47 -0
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env node
2
+ // tasteskill / inspect — render the page in a real browser, measure it, and photograph it.
3
+ //
4
+ // node inspect.mjs <url | path/to/file.html> [--out DIR] [--widths 1440,768,390] [--allow rule,rule] [--app] [--film] [--json]
5
+ //
6
+ // --film also photographs the scroll as a visitor sees it (a frame every third of a screen, real wheel
7
+ // input) into desktop-film-NN.jpg, so a scroll scene is judged by its in-between states. A direction
8
+ // that dealt scroll scenes switches it on by itself.
9
+ //
10
+ // --app judges an app screen (dashboard, admin, settings) by the rules in references/app-screens.md; a
11
+ // direction dealt with draw.mjs --app switches it on by itself.
12
+ //
13
+ // Exit code 0 = no FAIL findings. Exit code 1 = at least one FAIL (the page is not done).
14
+ // Zero dependencies: drives an installed Chrome/Edge/Chromium. Node 22+.
15
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync, createReadStream, readdirSync, unlinkSync } from 'node:fs';
16
+ import { resolve, join, relative, dirname, extname, sep } from 'node:path';
17
+ import { createServer } from 'node:http';
18
+ import { Browser, sleep } from './lib/cdp.mjs';
19
+ import { probe, frame, layout, app, colourShare } from './lib/probe.mjs';
20
+ import { judge, judgeLayout, judgeApp, APP_SKIP } from './lib/rules.mjs';
21
+
22
+ const args = process.argv.slice(2);
23
+ const flag = (name, def) => { const i = args.indexOf('--' + name); if (i === -1) return def; const v = args[i + 1]; args.splice(i, 2); return v; };
24
+ const has = (name) => { const i = args.indexOf('--' + name); if (i === -1) return false; args.splice(i, 1); return true; };
25
+ const outDir = resolve(flag('out', '.taste-skill/inspect'));
26
+ const widths = flag('widths', '1440,768,390').split(',').map(Number).filter(Boolean);
27
+ let allow = flag('allow', '').split(',').filter(Boolean);
28
+ const asJson = has('json');
29
+ let appMode = has('app');
30
+ let film = has('film');
31
+ let dealtFonts = []; // the faces the saved sheet dealt, to catch a build that quietly fell back to a default
32
+ const target = args[0];
33
+ if (!target || target === '-h' || target.startsWith('--')) {
34
+ console.error('usage: node inspect.mjs <url | file.html> [--out DIR] [--widths 1440,768,390] [--allow rule,rule] [--app] [--film] [--json]');
35
+ process.exit(2);
36
+ }
37
+ // Allowances granted by the drawn direction (written by draw.mjs) apply automatically.
38
+ for (const p of ['.taste-skill/direction.json', join(outDir, '..', 'direction.json')]) {
39
+ if (existsSync(p)) { try { const d = JSON.parse(readFileSync(p, 'utf8')); allow = [...new Set([...allow, ...(d.allow || [])])]; if (d.kind === 'app') appMode = true; if (Array.isArray(d.scenes) && d.scenes.length) film = true; dealtFonts = (d.input?.keep || []).includes('type') ? [] : d.kind === 'app' ? [d.style?.tokens?.font?.family].filter(Boolean) : [d.type?.display?.family, d.type?.text?.family].filter(Boolean); } catch {} break; }
40
+ }
41
+ // A local file is served over http from a throwaway server on 127.0.0.1, so the browser never has to
42
+ // open a file path (some sandboxes show Node and the browser different views of the disk) and relative
43
+ // assets, fetch() and module scripts behave as they will when the page is hosted.
44
+ let url = target; let server = null;
45
+ if (!/^https?:\/\//.test(target)) {
46
+ const file = resolve(target);
47
+ if (!existsSync(file)) { console.error('No such file: ' + file); process.exit(2); }
48
+ const cwd = resolve('.');
49
+ const root = file.startsWith(cwd + sep) ? cwd : dirname(file);
50
+ const MIME = { '.html': 'text/html; charset=utf-8', '.htm': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.mjs': 'text/javascript; charset=utf-8', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.avif': 'image/avif', '.gif': 'image/gif', '.ico': 'image/x-icon', '.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/ttf', '.otf': 'font/otf', '.mp4': 'video/mp4', '.webm': 'video/webm', '.txt': 'text/plain; charset=utf-8', '.xml': 'application/xml', '.webmanifest': 'application/manifest+json' };
51
+ server = createServer((req, res) => {
52
+ try {
53
+ let f = resolve(join(root, decodeURIComponent(new URL(req.url, 'http://x').pathname)));
54
+ if (f !== root && !f.startsWith(root + sep)) { res.writeHead(403); return res.end(); }
55
+ if (statSync(f).isDirectory()) f = join(f, 'index.html');
56
+ res.writeHead(200, { 'content-type': MIME[extname(f).toLowerCase()] || 'application/octet-stream', 'content-length': statSync(f).size, 'cache-control': 'no-store' });
57
+ createReadStream(f).pipe(res);
58
+ } catch { res.writeHead(404); res.end('not found'); }
59
+ });
60
+ await new Promise((r) => server.listen(0, '127.0.0.1', r));
61
+ url = `http://127.0.0.1:${server.address().port}/${relative(root, file).split(sep).map(encodeURIComponent).join('/')}`;
62
+ }
63
+ const HEIGHT = { 1440: 900, 1280: 800, 1024: 768, 768: 1024, 390: 844, 375: 812 };
64
+ const name = (w) => (w >= 1100 ? 'desktop' : w >= 600 ? 'tablet' : 'mobile');
65
+
66
+ mkdirSync(outDir, { recursive: true });
67
+ // Screenshots from an earlier run would sit beside the new ones when the page got shorter.
68
+ for (const f of readdirSync(outDir)) if (/^(desktop|tablet|mobile)-(fold|page-\d+|film-\d+)\.jpg$/.test(f)) unlinkSync(join(outDir, f));
69
+ const browser = await Browser.launch();
70
+ const helper = await browser.newPage({ width: 1600, height: 1000 });
71
+ const report = { url: server ? target : url, at: new Date().toISOString(), allow, viewports: [], findings: [], images: [] };
72
+
73
+ const MOTION_MIN = 8, MOTION_GOOD = 16; // distinct moving elements over load + one scroll through the page
74
+ // Runs in the page before any of its own scripts: counts the distinct elements that actually move while
75
+ // the page loads and is scrolled (CSS animations, CSS transitions, Web Animations, and script-driven
76
+ // transform/opacity changes such as GSAP), so a page that never moves can be told from one that does.
77
+ const MOTION_RECORDER = `(() => {
78
+ const seen = new WeakSet(); const c = { elements: 0, css: 0, transitions: 0, scripted: 0 };
79
+ const note = (t, k) => { if (!(t instanceof Element) || seen.has(t)) return; seen.add(t); c.elements++; c[k]++; };
80
+ addEventListener('animationstart', (e) => note(e.target, 'css'), true);
81
+ addEventListener('transitionrun', (e) => note(e.target, 'transitions'), true);
82
+ const watch = () => new MutationObserver((list) => { for (const m of list) { const s = m.target.getAttribute && m.target.getAttribute('style') || ''; if (/transform|translate|opacity|scale|rotate|clip-path/.test(s)) note(m.target, 'scripted'); } })
83
+ .observe(document.documentElement, { attributes: true, attributeFilter: ['style'], subtree: true });
84
+ if (document.documentElement) watch(); else addEventListener('DOMContentLoaded', watch);
85
+ window.__motionSample = () => { for (const a of document.getAnimations ? document.getAnimations() : []) { const t = a.effect && a.effect.target; if (t) note(t, a.constructor && a.constructor.name === 'CSSTransition' ? 'transitions' : 'css'); } };
86
+ window.__motion = () => { window.__motionSample(); const v = [...document.querySelectorAll('video')]; return { ...c, videos: v.length, playingVideos: v.filter((x) => x.autoplay || !x.paused).length }; };
87
+ })();`;
88
+
89
+ // Is the page's title on screen and readable: in the viewport, not faded, not masked away?
90
+ const TITLE_SEEN = `(() => {
91
+ const h = document.querySelector('h1'); if (!h) return { found: false };
92
+ const r = h.getBoundingClientRect();
93
+ if (r.width < 2 || r.height < 2) return { found: true, visible: false, why: 'it has no size yet' };
94
+ if (r.bottom < 0 || r.top > innerHeight) return { found: false }; // a title below the first screen is the no-title check's business
95
+ let o = 1; for (let p = h; p && p !== document.documentElement; p = p.parentElement) { const cs = getComputedStyle(p); if (cs.visibility === 'hidden' || cs.display === 'none') return { found: true, visible: false, why: 'it is hidden' }; o *= +cs.opacity; }
96
+ if (o < 0.5) return { found: true, visible: false, why: 'it is at ' + Math.round(o * 100) + '% opacity' };
97
+ // text moved out of its own masked line, or a cover lying over it, shows up as nothing at its centre
98
+ const range = document.createRange(); range.selectNodeContents(h); const rr = range.getBoundingClientRect();
99
+ const x = Math.min(innerWidth - 1, Math.max(0, rr.left + rr.width / 2)), y = Math.min(innerHeight - 1, Math.max(0, rr.top + Math.min(rr.height, 80) / 2));
100
+ const hit = document.elementFromPoint(x, y);
101
+ if (hit && !h.contains(hit) && !hit.contains(h)) { const cs = getComputedStyle(hit); if (cs.backgroundColor !== 'rgba(0, 0, 0, 0)' || /^(IMG|VIDEO|CANVAS)$/.test(hit.tagName)) return { found: true, visible: false, why: 'something lies over it' }; }
102
+ return { found: true, visible: true };
103
+ })()`;
104
+
105
+ async function sheet(frames, cols, cellW, cellH, path) {
106
+ const rows = Math.ceil(frames.length / cols);
107
+ await helper.setViewport({ width: cols * cellW, height: rows * cellH, dsf: 1 });
108
+ await helper.eval((a) => {
109
+ document.body.style.cssText = `margin:0;background:#888;display:grid;grid-template-columns:repeat(${a.cols},${a.cellW}px)`;
110
+ document.body.innerHTML = a.frames.map((s) => `<img src="data:image/jpeg;base64,${s}" style="width:${a.cellW}px;height:${a.cellH}px;display:block;outline:1px solid #888">`).join('');
111
+ return Promise.all([...document.images].map((i) => i.decode().catch(() => {})));
112
+ }, { frames, cols, cellW, cellH });
113
+ await helper.screenshot({ path, quality: 76 });
114
+ }
115
+
116
+ try {
117
+ for (const w of widths) {
118
+ const h = HEIGHT[w] || Math.round(w * 0.625);
119
+ const label = name(w);
120
+ const page = await browser.newPage({ width: w, height: h, dsf: 1, mobile: w < 600 });
121
+ await page.send('Page.addScriptToEvaluateOnNewDocument', { source: MOTION_RECORDER }).catch(() => {});
122
+ const how = await page.goto(url, { timeoutMs: 30000, settleMs: 600 });
123
+ await sleep(600); // about 1.2s after the load event: is the title there to read yet?
124
+ const early = await page.eval(TITLE_SEEN).catch(() => null);
125
+ await page.eval('document.fonts.ready.then(() => true)').catch(() => {});
126
+ await sleep(800); // let the load choreography finish before judging the first screen
127
+ const fold = join(outDir, `${label}-fold.jpg`);
128
+ await page.screenshot({ path: fold, quality: 82 });
129
+ const metrics = await page.eval(probe);
130
+
131
+ // walk the page one screen at a time so scroll reveals fire, photographing each screen
132
+ const frames = [readFileSync(fold).toString('base64')];
133
+ const frameChecks = [await page.eval(frame).catch(() => null)];
134
+ const screens = Math.min(11, Math.max(0, Math.ceil(metrics.page.height / h) - 1));
135
+ for (let i = 1; i <= screens; i++) {
136
+ await page.eval(`window.scrollTo({ top: ${i * h}, behavior: 'instant' })`).catch(() => {});
137
+ await page.wheel(2);
138
+ await sleep(650);
139
+ frames.push(await page.screenshot({ quality: 78 }));
140
+ frameChecks.push(await page.eval(frame).catch(() => null));
141
+ await page.eval('window.__motionSample && window.__motionSample()').catch(() => {});
142
+ }
143
+ const motion = await page.eval('window.__motion ? window.__motion() : null').catch(() => null);
144
+ // re-measure after everything has revealed (catches content that only exists post-reveal)
145
+ await page.eval(`window.scrollTo({ top: 0, behavior: 'instant' })`).catch(() => {});
146
+ await sleep(350);
147
+ const after = await page.eval(probe).catch(() => metrics);
148
+ const m = after.headings.length >= metrics.headings.length ? after : metrics;
149
+ const lay = await page.eval(layout).catch(() => null);
150
+ const appM = appMode ? await page.eval(app).catch(() => null) : null;
151
+ if (appM) appM.colourShare = await helper.eval(colourShare, 'data:image/jpeg;base64,' + frames[0]).catch(() => null);
152
+
153
+ // scroll scenes (assets/scenes): each must have started, run live on desktop, and leave the page room
154
+ const sceneState = w >= 1100 && !appMode ? await page.eval(`[...document.querySelectorAll('section.scene, .scene[data-scene]')].map((s) => ({ id: s.dataset.scene || s.id || 'scene', live: s.classList.contains('is-live'), rest: s.classList.contains('is-rest'), h: Math.round(s.getBoundingClientRect().height) }))`).catch(() => []) : [];
155
+ const sceneFindings = [];
156
+ if (sceneState.length) {
157
+ const idle = sceneState.filter((s) => !s.live && !s.rest);
158
+ if (idle.length && !allow.includes('scene-not-started')) sceneFindings.push({ level: 'FAIL', id: 'scene-not-started', width: w, message: `${idle.length} scene(s) never started: ${idle.map((s) => s.id).join(', ')}.`, fix: 'Load assets/scenes/stage.js and the scene file for each data-scene, then call Stage.smooth(); Stage.init(); at the end of <body> (references/scenes.md, "Putting a scene on a page").' });
159
+ const atRest = sceneState.filter((s) => s.rest);
160
+ if (atRest.length && !allow.includes('scene-not-live')) sceneFindings.push({ level: 'FAIL', id: 'scene-not-live', width: w, message: `${atRest.length} scene(s) show their finished composition on desktop instead of running: ${atRest.map((s) => s.id).join(', ')}.`, fix: 'GSAP or ScrollTrigger did not load (check the pinned CDN lines and the console), or the scene threw while building. The scene must run where motion is allowed.' });
161
+ if (sceneState.length > 4 && !allow.includes('many-scenes')) sceneFindings.push({ level: 'WARN', id: 'many-scenes', width: w, message: `${sceneState.length} scroll scenes on one page.`, fix: 'Two or three scenes, with quiet sections between them, so each one lands. Cut the weakest.' });
162
+ const held = sceneState.reduce((a, s) => a + Math.max(0, s.h - h), 0);
163
+ if (held > (metrics.page.height || 1) * 0.6 && !allow.includes('scene-heavy')) sceneFindings.push({ level: 'WARN', id: 'scene-heavy', width: w, message: `Scenes hold ${Math.round(held / h)} of the page's ${Math.round((metrics.page.height || 0) / h)} screens.`, fix: 'Shorten the holds (one screen per beat) or cut a scene; the reading sections need room between them.' });
164
+ }
165
+
166
+ // --film: the scroll as a visitor sees it. Real wheel input and a frame every third of a screen, so a
167
+ // scroll scene shows its in-between states, not only where each screen lands.
168
+ const filmSheets = [];
169
+ if (film && w >= 1100) {
170
+ await page.eval(`window.scrollTo({ top: 0, behavior: 'instant' })`).catch(() => {});
171
+ await sleep(700);
172
+ const shots = []; let lastY = -1, still = 0;
173
+ for (let i = 0; i < 96; i++) {
174
+ shots.push(await page.screenshot({ quality: 70 }));
175
+ await page.wheel(Math.round(h / 3), { step: 100, pauseMs: 16 });
176
+ await sleep(420);
177
+ const y = await page.eval('Math.round(scrollY || document.scrollingElement.scrollTop || 0)').catch(() => -1);
178
+ if (y === lastY) { if (++still >= 2) break; } else still = 0;
179
+ lastY = y;
180
+ }
181
+ for (let i = 0; i < shots.length; i += 24) {
182
+ const p = join(outDir, `${label}-film-${String(i / 24 + 1).padStart(2, '0')}.jpg`);
183
+ await sheet(shots.slice(i, i + 24), 6, 320, 200, p);
184
+ filmSheets.push(p);
185
+ }
186
+ }
187
+
188
+ const cols = w >= 1100 ? 2 : w >= 600 ? 3 : 4;
189
+ const cellW = w >= 1100 ? 800 : w >= 600 ? 512 : 390;
190
+ const cellH = Math.round((cellW * h) / w);
191
+ const perSheet = w >= 1100 ? 4 : w >= 600 ? 6 : 8;
192
+ const sheets = [];
193
+ for (let i = 0; i < frames.length; i += perSheet) {
194
+ const p = join(outDir, `${label}-page-${String(i / perSheet + 1).padStart(2, '0')}.jpg`);
195
+ await sheet(frames.slice(i, i + perSheet), cols, cellW, cellH, p);
196
+ sheets.push(p);
197
+ }
198
+ let findings = [...judge(m, { width: w, allow }), ...sceneFindings];
199
+ if (dealtFonts.length && w >= 1100 && !allow.includes('font-not-dealt')) {
200
+ const norm = (f) => String(f).toLowerCase().replace(/["']/g, '').replace(/\s+variable$/, '').trim();
201
+ const used = m.type.families.filter((f) => f.share >= 0.1).map((f) => norm(f.family));
202
+ const missing = dealtFonts.filter((f) => !used.some((u) => u === norm(f) || u.startsWith(norm(f))));
203
+ if (missing.length === dealtFonts.length) findings.push({ level: appMode ? 'FAIL' : 'WARN', id: 'font-not-dealt', width: w, message: `The sheet dealt ${dealtFonts.join(' and ')}, but the page renders ${m.type.families.slice(0, 2).map((f) => f.family).join(', ')}.`, fix: 'Load the dealt face (the link on the sheet) and put it first in font-family. A build that falls back to a default face lands on the default look.' });
204
+ }
205
+ // a third of the studied award pages were still unreadable 4.5s after load; the house sequence is over by 1.2s
206
+ if (!appMode && early && early.found && !early.visible && !allow.includes('late-title')) findings.push({ level: 'FAIL', id: 'late-title', width: w, message: `The title is not readable 1.2s after the page loaded (${early.why}).`, fix: 'Put the headline in the HTML, painted on the first frame; the load sequence only adds arrival and is settled by 1.2s (references/motion.md, "Load sequence in 1.2 seconds"). No preloader, no gate, no waiting for the load event.' });
207
+ if (lay) findings.push(...judgeLayout(lay, { width: w, allow }));
208
+ if (appMode) {
209
+ findings = findings.filter((f) => !APP_SKIP.has(f.id) && f.id !== 'no-title' && f.id !== 'small-title');
210
+ if (appM) findings.push(...judgeApp(appM, m, { width: w, allow }));
211
+ }
212
+ // what only shows up while scrolling: text hidden under something, and screens with almost nothing on them
213
+ const coveredText = [...new Map(frameChecks.filter(Boolean).flatMap((f, i) => f.covered.map((c) => [c.text, { ...c, screen: i + 1 }]))).values()];
214
+ if (coveredText.length && !allow.includes('covered-text')) findings.push({ level: 'FAIL', id: 'covered-text', width: w, message: `Large text lies under another element at some scroll position: ` + coveredText.slice(0, 4).map((c) => `"${c.text}" (screen ${c.screen}, ${Math.round(c.share * 100)}% hidden)`).join('; '), fix: 'Nothing may sit on top of a headline or statement. Move the picture, shorten the pinned run, or raise the text above it (z-index) and give it a ground.' });
215
+ const clippedText = [...new Map(frameChecks.filter(Boolean).flatMap((f, i) => (f.clipped || []).map((c) => [c.text, { ...c, screen: i + 1 }]))).values()];
216
+ if (clippedText.length && !allow.includes('clipped-text')) findings.push({ level: 'FAIL', id: 'clipped-text', width: w, message: 'Large text is cut off along its top by the box that holds it: ' + clippedText.slice(0, 3).map((c) => `"${c.text}" (screen ${c.screen})`).join('; '), fix: 'Jurors read a wordmark sliced at the top as broken. Give the box room for the ascenders (line-height and padding), or crop at the bottom or a side edge on purpose.' });
217
+ const overPictures = [...new Map(frameChecks.filter(Boolean).flatMap((f, i) => (f.pinnedOver || []).map((c) => [c.text, { ...c, screen: i + 1 }]))).values()];
218
+ if (overPictures.length && !allow.includes('pinned-over-picture')) findings.push({ level: 'WARN', id: 'pinned-over-picture', width: w, message: 'Pinned large text slides across pictures while the page scrolls: ' + overPictures.slice(0, 3).map((c) => `"${c.text}" (screen ${c.screen}, ${Math.round(c.share * 100)}% over a picture)`).join('; '), fix: 'Jurors read a pinned title crossing drawings or photographs as a collision. Keep the pictures in the column the title does not occupy, or unpin it.' });
219
+ const empty = frameChecks.map((f, i) => ({ f, i })).filter(({ f }) => f && f.filled < 0.2);
220
+ // the same large statement on screen for three screens or more in a row
221
+ const runs = new Map();
222
+ frameChecks.forEach((f, i) => { for (const t of f?.big || []) { const r = runs.get(t) || { start: i, last: i - 1, best: 0 }; if (r.last === i - 1) r.last = i; else { r.start = i; r.last = i; } r.best = Math.max(r.best, r.last - r.start + 1); runs.set(t, r); } });
223
+ const longPins = [...runs.entries()].filter(([, r]) => r.best >= 3);
224
+ if (w >= 1100 && longPins.length && !allow.includes('long-pin')) findings.push({ level: 'WARN', id: 'long-pin', width: w, message: `The same large text stays on screen for ${Math.max(...longPins.map(([, r]) => r.best))} screens in a row: ` + longPins.slice(0, 2).map(([t]) => `"${t}"`).join('; '), fix: 'A pinned element earns two screens, and something must change at each. Shorten the run or give every screen its own content.' });
225
+ // a page that barely moves: counted from what really animated while it loaded and was scrolled
226
+ if (w >= 1100 && motion && !allow.includes('still-page')) {
227
+ const moving = motion.elements + motion.playingVideos * 4;
228
+ if (moving < MOTION_MIN) findings.push({ level: 'FAIL', id: 'still-page', width: w, message: `Only ${motion.elements} element(s) moved while the page loaded and scrolled${motion.playingVideos ? ` (plus ${motion.playingVideos} playing video)` : ''}.`, fix: 'Build the motion layer (SKILL.md step 9, references/motion.md): the signature move, an entrance for the parts of every section, feedback on every control, and one moving picture. Transform and opacity only, with a reduced-motion fallback.' });
229
+ else if (moving < MOTION_GOOD) findings.push({ level: 'WARN', id: 'still-page', width: w, message: `Little motion: ${motion.elements} element(s) moved while the page loaded and scrolled.`, fix: 'Give every section an entrance for its parts (not one fade of the whole block) and add one moving picture: a looping clip or a slow move on a photograph.' });
230
+ }
231
+ if (w >= 1100 && empty.length >= 2 && !allow.includes('empty-screens')) findings.push({ level: 'FAIL', id: 'empty-screens', width: w, message: `${empty.length} of ${frameChecks.length} desktop screens are almost empty ground (under 20% of the screen holds text, a picture or a colour field): screens ${empty.map(({ i }) => i + 1).join(', ')}.`, fix: 'An empty screen is a rest only once per page. Elsewhere it means the section is underbuilt: set its content larger, give it the full information, put it on a colour field, or cut it.' });
232
+ report.viewports.push({ width: w, height: h, load: how, screens: frames.length, filled: frameChecks.map((f) => f?.filled ?? null), motion, metrics: m, layout: lay, app: appM, consoleErrors: page.consoleErrors.slice(0, 5) });
233
+ report.findings.push(...(appMode ? findings.filter((f) => !APP_SKIP.has(f.id)) : findings));
234
+ report.images.push({ viewport: label, width: w, fold, pages: sheets, film: filmSheets });
235
+ await page.close();
236
+ }
237
+ // Under prefers-reduced-motion the page is the finished page: nothing may stay hidden waiting for an
238
+ // animation that will not run. Two in three studied award pages had no reduced-motion rules at all.
239
+ if (!appMode && widths.some((x) => x >= 1100) && !allow.includes('reduced-hidden')) {
240
+ const rp = await browser.newPage({ width: 1440, height: 900, dsf: 1, reducedMotion: true });
241
+ try {
242
+ await rp.goto(url, { timeoutMs: 30000, settleMs: 1500 });
243
+ const hidden = await rp.eval(`(() => {
244
+ const out = []; const w = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT); const rg = document.createRange();
245
+ for (let n = w.nextNode(); n; n = w.nextNode()) {
246
+ const t = n.nodeValue.trim(); const el = n.parentElement; if (t.length < 3 || !el || el.closest('script, style, noscript, [aria-hidden="true"]')) continue;
247
+ rg.selectNodeContents(n); const r = rg.getBoundingClientRect(); if (r.width < 2 || r.top > innerHeight || r.bottom < 0) continue;
248
+ let o = 1, gone = false; for (let p = el; p && p !== document.documentElement; p = p.parentElement) { const cs = getComputedStyle(p); if (cs.visibility === 'hidden') { gone = true; break; } o *= +cs.opacity; }
249
+ if (gone || o < 0.1) out.push(t.slice(0, 40));
250
+ }
251
+ return out;
252
+ })()`).catch(() => []);
253
+ if (hidden.length >= 2) report.findings.push({ level: 'FAIL', id: 'reduced-hidden', width: 1440, message: `With reduced motion requested, ${hidden.length} text block(s) on the first screen stay invisible: ` + hidden.slice(0, 4).map((t) => `"${t}"`).join(', '), fix: 'Put every hidden starting state inside @media (prefers-reduced-motion: no-preference); the reduced page is the finished page (references/motion.md §8).' });
254
+ } finally { await rp.close(); }
255
+ }
256
+ } finally {
257
+ await browser.close();
258
+ if (server) server.close();
259
+ }
260
+
261
+ // de-duplicate findings that repeat across viewports (keep the widest occurrence, note the others)
262
+ const merged = [];
263
+ for (const f of report.findings) {
264
+ const same = merged.find((x) => x.id === f.id && x.level === f.level);
265
+ if (same && f.id !== 'headline-lines' && f.id !== 'overflow') { same.alsoAt = [...(same.alsoAt || []), f.width]; continue; }
266
+ merged.push(f);
267
+ }
268
+ report.findings = merged;
269
+ writeFileSync(join(outDir, 'report.json'), JSON.stringify(report, null, 1));
270
+
271
+ if (asJson) { console.log(JSON.stringify(report, null, 1)); process.exit(merged.some((f) => f.level === 'FAIL') ? 1 : 0); }
272
+
273
+ const d = report.viewports[0].metrics;
274
+ const line = (s = '') => console.log(s);
275
+ line(`TASTESKILL · INSPECT ${report.url}`);
276
+ line('');
277
+ line('MEASURED (first viewport listed)');
278
+ if (d.hero) line(` hero headline "${d.hero.text.slice(0, 70)}" ${d.hero.words} words · ${d.hero.lines} line(s) · ${d.hero.size}px (${d.hero.vw}vw) · ${d.hero.font} ${d.hero.weight} · tracking ${d.hero.tracking}em · leading ${d.hero.leading}`);
279
+ for (const v of report.viewports.slice(1)) if (v.metrics.hero) line(` @${v.width}px ${v.metrics.hero.lines} line(s) · ${v.metrics.hero.size}px`);
280
+ line(` typefaces ${d.type.families.filter((f) => f.share >= 0.02).map((f) => `${f.family} ${Math.round(f.share * 100)}%`).join(', ')}`);
281
+ line(` sizes in use ${d.type.sizes.join(' / ')} px${d.type.body ? ` body ${d.type.body.size}px / ${d.type.body.leading}` : ''}`);
282
+ line(` colour page ${d.color.bodyBg}${d.color.sectionBgs.length ? ' · sections ' + d.color.sectionBgs.map((s) => s.color).slice(0, 6).join(' ') : ''}${d.color.button ? ' · button ' + d.color.button.bg : ''}`);
283
+ line(` page ${d.page.screens} screens · ${d.page.words} words · ${d.page.img} images · hero media ${d.heroMedia[0] ? Math.round(d.heroMedia[0].ratio * 100) + '% ' + d.heroMedia[0].type : 'none'}`);
284
+ line(` headings ${d.headingSummary.count} · longest ${d.headingSummary.maxLines} line(s) · median ${d.headingSummary.medianWords ?? '-'} words`);
285
+ line('');
286
+ const fails = merged.filter((f) => f.level === 'FAIL'), warns = merged.filter((f) => f.level === 'WARN');
287
+ if (!fails.length && !warns.length) line('FINDINGS none. Measurements are clean — now judge the pictures.');
288
+ for (const [title, list] of [['FAIL — fix every one of these', fails], ['WARN — fix, or be able to defend', warns]]) {
289
+ if (!list.length) continue;
290
+ line(title);
291
+ for (const f of list) {
292
+ line(` [${f.id}] @${f.width}px${f.alsoAt ? ' (+' + f.alsoAt.join(', ') + ')' : ''} ${f.message}`);
293
+ line(` → ${f.fix}`);
294
+ }
295
+ line('');
296
+ }
297
+ line('LOOK AT THE RENDER — open these with your image viewer / Read tool before saying anything about quality:');
298
+ const rel = (p) => relative(process.cwd(), p).split('\\').join('/');
299
+ for (const im of report.images) { line(` ${(im.viewport + ' ' + im.width + 'px').padEnd(15)} ${rel(im.fold)}`); for (const p of im.pages) line(` ${''.padEnd(15)} ${rel(p)}`); for (const p of im.film || []) line(` ${'scroll film'.padEnd(15)} ${rel(p)} (6 frames a row, a third of a screen apart)`); }
300
+ line('');
301
+ line(`report: ${rel(join(outDir, 'report.json'))}`);
302
+ line(fails.length ? `RESULT: ${fails.length} FAIL, ${warns.length} WARN — not done.` : `RESULT: 0 FAIL, ${warns.length} WARN — measurements pass. Passing the meter is the floor, not the grade: score the screenshots with references/critique.md.`);
303
+ process.exit(fails.length ? 1 : 0);
@@ -0,0 +1,203 @@
1
+ // tasteskill / draw --app — deal a style for an app screen (dashboard, admin, settings, inbox).
2
+ //
3
+ // node draw.mjs --app --kind <kind> --brief "one line" [--screens overview,list,detail,settings]
4
+ // [--theme light|dark] [--keep palette,type] [--options 3] [--style <id>] [--seed N]
5
+ // node draw.mjs --show reprint the saved sheet
6
+ // node draw.mjs --redraw style|shell|screen:<name>
7
+ // node draw.mjs --app --list kinds|styles|screens
8
+ //
9
+ // Same idea as the page draw: the script deals, you choose among what it dealt, so two products do not
10
+ // end up in the same default look. The library (library/app.json) was distilled from a study of real
11
+ // product screens; it holds styles (tokens and the one move that makes each recognisable), shells and
12
+ // screen patterns.
13
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
14
+ import { dirname, join, resolve } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { randomInt } from 'node:crypto';
17
+ import { homedir } from 'node:os';
18
+
19
+ const HERE = dirname(fileURLToPath(import.meta.url));
20
+ const LIB = JSON.parse(readFileSync(join(HERE, '..', '..', 'library', 'app.json'), 'utf8'));
21
+ const argv = process.argv.slice(2);
22
+ const opt = (name, def) => { const i = argv.indexOf('--' + name); if (i === -1) return def; const v = argv[i + 1]; return v === undefined || v.startsWith('--') ? true : v; };
23
+ const list = (v) => (typeof v === 'string' ? v.split(',').map((s) => s.trim()).filter(Boolean) : []);
24
+ const outDir = resolve(String(opt('out', '.taste-skill')));
25
+ const sheetPath = join(outDir, 'direction.json');
26
+
27
+ const KINDS = Object.keys(LIB.kinds);
28
+ // signature patterns are elements of one kind of product (a power flow, a sell-out strip), not whole screens
29
+ const SCREENS = [...new Set(LIB.patterns.filter((p) => p.screen).map((p) => p.screen))];
30
+ const SIGNATURES = LIB.patterns.filter((p) => p.signature);
31
+ const signaturesFor = (brief = '') => { const b = brief.toLowerCase(); return SIGNATURES.filter((p) => (p.cues || []).some((c) => new RegExp('(^|[^a-z])' + c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i').test(b))); };
32
+
33
+ if (opt('list')) {
34
+ const what = opt('list');
35
+ if (what === 'kinds') for (const [k, v] of Object.entries(LIB.kinds)) console.log(`${k.padEnd(14)} ${v.note}`);
36
+ else if (what === 'screens') for (const s of SCREENS) console.log(`${s.padEnd(12)} ${LIB.patterns.filter((p) => p.screen === s).map((p) => p.id).join(', ')}`);
37
+ else if (what === 'signatures') for (const p of SIGNATURES) console.log(`${p.id.padEnd(16)} ${p.name} — ${(p.cues || []).slice(0, 5).join(', ')}`);
38
+ else for (const s of LIB.styles) console.log(`${s.id.padEnd(22)} ${s.name} — ${s.theme}, ${s.suits.join(', ')}`);
39
+ process.exit(0);
40
+ }
41
+
42
+ let seed = opt('seed') !== undefined && opt('seed') !== true ? Number(opt('seed')) : randomInt(1, 2 ** 31 - 1);
43
+ const startSeed = seed;
44
+ const rnd = () => { seed |= 0; seed = (seed + 0x6d2b79f5) | 0; let t = Math.imul(seed ^ (seed >>> 15), 1 | seed); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; };
45
+ const pick = (arr) => arr[Math.floor(rnd() * arr.length)];
46
+ const userHist = process.env.TASTE_SKILL_HISTORY || join(homedir(), '.taste-skill', 'history.json');
47
+ const readHist = () => { try { return JSON.parse(readFileSync(userHist, 'utf8')); } catch { return []; } };
48
+ const writeHist = (e) => { try { mkdirSync(dirname(userHist), { recursive: true }); const h = readHist(); h.unshift(e); writeFileSync(userHist, JSON.stringify(h.slice(0, 24), null, 1)); } catch {} };
49
+ const recentStyles = readHist().filter((h) => h.kind === 'app').slice(0, 3).map((h) => h.style);
50
+
51
+ const saved = existsSync(sheetPath) ? JSON.parse(readFileSync(sheetPath, 'utf8')) : null;
52
+ if (opt('show')) { if (!saved || saved.kind !== 'app') { console.error('No saved app sheet. Run draw.mjs --app first.'); process.exit(2); } console.log(render(saved)); process.exit(0); }
53
+
54
+ function stylePool(input) {
55
+ const pref = LIB.kinds[input.kind]?.styles || [];
56
+ let pool = LIB.styles.filter((s) => !(input.avoid || []).includes(s.id));
57
+ if (input.theme) { const t = pool.filter((s) => s.theme === input.theme); if (t.length) pool = t; }
58
+ const fit = pool.filter((s) => pref.includes(s.id) || s.suits.includes(input.kind));
59
+ if (fit.length >= 2) pool = fit;
60
+ return pool;
61
+ }
62
+ function dealStyle(input, exclude = []) {
63
+ let pool = stylePool(input).filter((s) => !exclude.includes(s.id));
64
+ if (!pool.length) pool = LIB.styles.filter((s) => !exclude.includes(s.id));
65
+ const fresh = pool.filter((s) => !recentStyles.includes(s.id));
66
+ return pick(fresh.length ? fresh : pool.length ? pool : LIB.styles);
67
+ }
68
+ // The style's own shell usually carries part of its move, so it is dealt about two times in three.
69
+ function dealShell(style, input, exclude = []) {
70
+ const own = LIB.shells.find((s) => s.id === style.shell && !exclude.includes(s.id));
71
+ const alts = LIB.shells.filter((s) => (style.shellAlternatives || []).includes(s.id) && !exclude.includes(s.id));
72
+ if (own && (!alts.length || rnd() < 0.66)) return own;
73
+ if (alts.length) return pick(alts);
74
+ const rest = LIB.shells.filter((s) => !exclude.includes(s.id));
75
+ return pick(rest.length ? rest : LIB.shells);
76
+ }
77
+ function dealScreen(name, style, input, exclude = []) {
78
+ let pool = LIB.patterns.filter((p) => p.screen === name && !exclude.includes(p.id));
79
+ // a pattern written for another kind of product brings that product's furniture with it (a getting-started strip on a
80
+ // leave planner): when none fits this kind, the sheet says to compose the screen from the chapter instead
81
+ pool = pool.filter((p) => !p.kinds || p.kinds.includes(input.kind));
82
+ return pool.length ? pick(pool) : null;
83
+ }
84
+ function deal(input) {
85
+ const style = input.style ? LIB.styles.find((s) => s.id === input.style) : dealStyle(input);
86
+ if (!style) { console.error(`No app style ${input.style}. List them with --app --list styles.`); process.exit(2); }
87
+ const s = { version: 1, kind: 'app', at: new Date().toISOString(), seed: startSeed, input, style, shell: dealShell(style, input), screens: [] };
88
+ for (const name of input.screens) s.screens.push({ name, pattern: dealScreen(name, style, input) });
89
+ return s;
90
+ }
91
+
92
+ let sheet;
93
+ if (opt('redraw') && saved?.kind === 'app') {
94
+ sheet = saved; sheet.redraws = (sheet.redraws || 0) + 1;
95
+ const what = String(opt('redraw'));
96
+ if (what === 'style') { sheet.style = dealStyle(sheet.input, [sheet.style.id]); }
97
+ else if (what === 'shell') sheet.shell = dealShell(sheet.style, sheet.input, [sheet.shell.id]);
98
+ else if (what.startsWith('screen:')) { const n = what.slice(7); const i = sheet.screens.findIndex((x) => x.name === n); if (i === -1) { console.error('No screen ' + n + ' on this sheet.'); process.exit(2); } sheet.screens[i].pattern = dealScreen(n, sheet.style, sheet.input, [sheet.screens[i].pattern?.id]) || sheet.screens[i].pattern; }
99
+ else { console.error('Redraw style, shell or screen:<name>.'); process.exit(2); }
100
+ } else {
101
+ const kind = String(opt('kind', ''));
102
+ if (!KINDS.includes(kind)) { console.error(`--kind is required with --app. One of:\n ${KINDS.join(', ')}`); process.exit(2); }
103
+ const screens = list(opt('screens')).length ? list(opt('screens')) : (LIB.kinds[kind].screens || ['overview']);
104
+ const bad = screens.filter((x) => !SCREENS.includes(x));
105
+ if (bad.length) { console.error(`Unknown screen(s): ${bad.join(', ')}. One of: ${SCREENS.join(', ')}`); process.exit(2); }
106
+ const input = { kind, brief: typeof opt('brief') === 'string' ? opt('brief') : '', theme: ['light', 'dark'].includes(opt('theme')) ? opt('theme') : null, screens, keep: list(opt('keep')), style: typeof opt('style') === 'string' ? opt('style') : null };
107
+ if (opt('options')) {
108
+ const n = Math.max(2, Math.min(5, Number(opt('options')) || 3)); const pool = stylePool(input); const out = [];
109
+ let rest = pool.filter((s) => !recentStyles.includes(s.id)); if (rest.length < n) rest = pool;
110
+ while (out.length < n && rest.length) { const s = pick(rest); out.push(s); rest = rest.filter((x) => x !== s); }
111
+ console.log(`# ${out.length} app styles dealt for this brief\n`);
112
+ console.log('Choose the one that suits how this product is used (long sessions or a quick look, money or media, a team or one person), not the most familiar. Then deal it with the same command plus `--style <id>` (and without --options).\n');
113
+ for (const s of out) console.log(`## \`${s.id}\` — ${s.name} (${s.theme})\n${s.idea}\nThe move: ${s.signature}\n`);
114
+ process.exit(0);
115
+ }
116
+ sheet = deal(input);
117
+ }
118
+ mkdirSync(outDir, { recursive: true });
119
+ writeFileSync(sheetPath, JSON.stringify(sheet, null, 1));
120
+ if (!opt('redraw')) writeHist({ at: sheet.at, kind: 'app', style: sheet.style.id, shell: sheet.shell.id });
121
+ console.log(render(sheet));
122
+ process.exit(0);
123
+
124
+ function kebab(k) { return k.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase()); }
125
+ // A Google Fonts link for the style's faces (all of them are free there).
126
+ function fontLink(f) {
127
+ const fam = (name, w) => 'family=' + name.trim().replace(/ /g, '+') + ':wght@' + w.join(';');
128
+ const fams = [fam(f.family, f.weights || [400, 500, 600])];
129
+ const second = f.second && f.second.split(',')[0].trim();
130
+ if (second && !/^(system|inter\b)/i.test(second)) fams.push(fam(second, [400, 500]));
131
+ return `<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n<link href="https://fonts.googleapis.com/css2?${fams.join('&')}&display=swap" rel="stylesheet">`;
132
+ }
133
+ function render(s) {
134
+ const st = s.style, t = st.tokens, o = []; const p = (x = '') => o.push(x);
135
+ p(`# APP SHEET — ${st.name}`);
136
+ p(`seed ${s.seed} · drawn ${s.at.slice(0, 10)}${s.redraws ? ` · redraws: ${s.redraws}` : ''} · kind ${s.input.kind} · ${st.theme}`);
137
+ if (s.input.brief) p(`Brief: ${s.input.brief}`);
138
+ p();
139
+ p('This is the style for this product. Adopt it whole and keep its move intact; everything the sheet does not fix comes from the');
140
+ p('shared defaults in references/app-screens.md. Redraw only for a reason you can state (it contradicts the brand, or the product is');
141
+ p('used in a way the style does not suit) and say why in your report. The values were measured on real product screens: use them');
142
+ p('as given rather than rounding them towards your habits.');
143
+ p();
144
+ p('## 1. The style'); p(st.idea); p(); p(`**The move:** ${st.signature}`); p();
145
+ if (st.colourBudget) p(`**Colour budget:** ${st.colourBudget}.`);
146
+ if (st.avoid?.length) p('**Off-style here:** ' + st.avoid.join('; ') + '.');
147
+ if (st.basis) p(`Distilled from ${st.basis}.${st.notes ? ' ' + st.notes : ''}`);
148
+ p();
149
+ // the style makes a screen correct; its face makes it this product's (references/app-screens.md, §2.3)
150
+ if (st.identity?.length) {
151
+ p('**Its face.** Choose one of these (or one of your own of the same weight) before you build, write it in your notes next to');
152
+ p('the screen\'s question, and check that it shows on the first screen. Without one the screen reads as a well-applied kit.');
153
+ for (const x of st.identity) p('- ' + x);
154
+ p();
155
+ }
156
+ const sigs = signaturesFor(s.input.brief);
157
+ if (sigs.length) {
158
+ p('**Signature elements this brief names** (an element only this kind of product has; build one of them as part of a screen):');
159
+ for (const g of sigs) p(`- **${g.name}** (\`${g.id}\`). ${g.blueprint}${g.phone ? ' On a phone: ' + g.phone : ''}`);
160
+ p();
161
+ }
162
+ const f = t.font || {};
163
+ if (!s.input.keep.includes('palette')) {
164
+ p('## 2. Tokens'); p('```css'); p(':root {');
165
+ for (const [k, v] of Object.entries(t)) {
166
+ if (k === 'font' || k === 'density') continue;
167
+ if (typeof v === 'string') p(` --${kebab(k)}: ${v};`);
168
+ else if (typeof v === 'number') p(` --${kebab(k)}: ${v}px;`);
169
+ else if (k === 'chart') v.forEach((c, i) => p(` --chart-${i + 1}: ${c};`));
170
+ else if (k === 'pills') for (const [n, [bg, ink]] of Object.entries(v)) p(` --pill-${n}-bg: ${bg}; --pill-${n}-ink: ${ink};`);
171
+ else if (k === 'radius') for (const [n, r] of Object.entries(v)) p(` --radius-${n}: ${r}px;`);
172
+ }
173
+ if (f.sizes) for (const [n, v] of Object.entries(f.sizes)) p(` --fs-${n}: ${v}px;`);
174
+ p('}'); p('```');
175
+ p(`Density: ${t.density}. One gap value, horizontally and vertically. ${t.shadow ? 'The shadow belongs to this dark style\'s cards only; nothing else casts one.' : 'No shadow on anything at rest.'}`);
176
+ p();
177
+ } else { p('## 2. Tokens'); p('Kept from the brand: map its colours onto this style\'s roles (ground, surface, raised, border, rule, control, text, muted, accent, status pills, chart) and keep its proportions: ' + (st.colourBudget || 'colour on data and status only') + '. Take the sizes, radii, row and control heights from the style as they are.'); p(); }
178
+ if (!s.input.keep.includes('type') && f.family) {
179
+ p(`## 3. Type — ${f.family}`);
180
+ p('```html'); p(fontLink(f)); p('```');
181
+ p(`\`font-family: "${f.family}", ${f.fallback || 'system-ui, sans-serif'}\`. Weights ${(f.weights || []).join(', ')}. Sizes: ${Object.entries(f.sizes || {}).map(([k, v]) => `${k} ${v}px`).join(' · ')}.${f.note ? ' ' + f.note : ''}${f.second ? ' Second face: ' + f.second + '.' : ''}`);
182
+ p('Numbers: `font-variant-numeric: tabular-nums` on every table, KPI and anything that updates. Sentence case; no tracked capitals.'); p();
183
+ }
184
+ p(`## 4. Shell — ${s.shell.name}`); p(s.shell.blueprint);
185
+ if (s.shell.numbers) p('Numbers: ' + Object.entries(s.shell.numbers).map(([k, v]) => `${k} ${v}`).join('; ') + '.');
186
+ if (s.shell.phone) p(`On a phone: ${s.shell.phone}`); p();
187
+ p('## 5. Screens');
188
+ for (const sc of s.screens) {
189
+ p();
190
+ if (!sc.pattern) { p(`### ${sc.name}`); p('No pattern in the library for this screen. Compose it from the rules in references/app-screens.md.'); continue; }
191
+ p(`### ${sc.name} — ${sc.pattern.name}`); p(sc.pattern.blueprint); if (sc.pattern.phone) p(`On a phone: ${sc.pattern.phone}`);
192
+ }
193
+ p();
194
+ p('## 6. Always');
195
+ p('Real data for this product, written before the markup: names, amounts that add up, dates in order, units on every figure,');
196
+ p('honest zeros and dashes. One chart answers one question. No gradients, glows, glass, icons in tinted squares, sparklines on KPIs,');
197
+ p('rainbow charts, emoji, lorem or Acme. `<skill>/assets/app.css` and `<skill>/assets/charts.js` are a neutral start set to these');
198
+ p('rules. Check with `node <skill>/scripts/lint.mjs <files>` and `node <skill>/scripts/inspect.mjs <page>`: this sheet switches both');
199
+ p('to app rules.');
200
+ p();
201
+ p(`Saved to ${sheetPath.split('\\').join('/')} · reprint with \`node draw.mjs --show\``);
202
+ return o.join('\n');
203
+ }