exonous 0.0.0-stage → 2.10.4

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 (385) hide show
  1. package/README.md +100 -2
  2. package/assets/THIRD-PARTY-NOTICES.md +29 -0
  3. package/assets/adapters/opencode/exonous.js +54 -0
  4. package/assets/agents/exo-backend.md +22 -0
  5. package/assets/agents/exo-cto.md +22 -0
  6. package/assets/agents/exo-data-ai.md +22 -0
  7. package/assets/agents/exo-designer.md +22 -0
  8. package/assets/agents/exo-devops.md +22 -0
  9. package/assets/agents/exo-frontend.md +22 -0
  10. package/assets/agents/exo-infra.md +22 -0
  11. package/assets/agents/exo-mobile.md +22 -0
  12. package/assets/agents/exo-pm.md +22 -0
  13. package/assets/agents/exo-qa.md +22 -0
  14. package/assets/agents/exo-researcher.md +22 -0
  15. package/assets/agents/exo-security.md +22 -0
  16. package/assets/agents/roster.json +209 -0
  17. package/assets/agents/taxis.js +189 -0
  18. package/assets/editors/cursor/frontend-skills.mdc +27 -0
  19. package/assets/editors/hooks/cursor/hooks.json +11 -0
  20. package/assets/machine/PR-TEMPLATE.md +21 -0
  21. package/assets/machine/hooks/anamnesis.cjs +61 -0
  22. package/assets/machine/hooks/ethos.cjs +48 -0
  23. package/assets/machine/hooks/kairos.cjs +46 -0
  24. package/assets/machine/hooks/lib/cli-options.cjs +133 -0
  25. package/assets/machine/hooks/lib/memory.cjs +488 -0
  26. package/assets/machine/hooks/lib/metron.cjs +52 -0
  27. package/assets/machine/hooks/lib/paths.cjs +99 -0
  28. package/assets/machine/hooks/lib/payload.cjs +81 -0
  29. package/assets/machine/hooks/lib/pr-template-validate.cjs +103 -0
  30. package/assets/machine/hooks/lib/release.cjs +58 -0
  31. package/assets/machine/hooks/lib/repo.cjs +138 -0
  32. package/assets/machine/hooks/lib/sanitize.cjs +37 -0
  33. package/assets/machine/hooks/lib/selfupdate.cjs +354 -0
  34. package/assets/machine/hooks/lib/shell.cjs +722 -0
  35. package/assets/machine/hooks/lib/template.cjs +70 -0
  36. package/assets/machine/hooks/lib/token.cjs +110 -0
  37. package/assets/machine/hooks/lib/validate-pr-body.cjs +21 -0
  38. package/assets/machine/hooks/pyle.cjs +302 -0
  39. package/assets/rules/nomos.md +59 -0
  40. package/assets/rules/praxis.md +38 -0
  41. package/assets/skills/code-review/SKILL.md +124 -0
  42. package/assets/skills/commit-changes/SKILL.md +49 -0
  43. package/assets/skills/deliver/SKILL.md +114 -0
  44. package/assets/skills/deliver/references/parallel.md +37 -0
  45. package/assets/skills/doc/SKILL.md +140 -0
  46. package/assets/skills/doc/doc.mjs +277 -0
  47. package/assets/skills/issue-board/SKILL.md +84 -0
  48. package/assets/skills/issue-board/board.mjs +389 -0
  49. package/assets/skills/issue-board/config.example.json +9 -0
  50. package/assets/skills/issue-board/render.py +189 -0
  51. package/assets/skills/make-pr/SKILL.md +24 -0
  52. package/assets/skills/native-ui/SKILL.md +67 -0
  53. package/assets/skills/native-ui/reference/apple.md +180 -0
  54. package/assets/skills/native-ui/reference/mobile-feel.md +221 -0
  55. package/assets/skills/native-ui/reference/swift.md +289 -0
  56. package/assets/skills/project-memory/SKILL.md +59 -0
  57. package/assets/skills/project-memory/config.example.json +4 -0
  58. package/assets/skills/project-memory/project-memory.mjs +478 -0
  59. package/assets/skills/security-review/SKILL.md +102 -0
  60. package/assets/skills/session-handoff/SKILL.md +23 -0
  61. package/assets/skills/session-handoff/config.example.json +3 -0
  62. package/assets/skills/ui-design/SKILL.md +75 -0
  63. package/assets/skills/ui-design/reference/adapt.md +151 -0
  64. package/assets/skills/ui-design/reference/adapt.native.md +35 -0
  65. package/assets/skills/ui-design/reference/android.md +50 -0
  66. package/assets/skills/ui-design/reference/animate.md +87 -0
  67. package/assets/skills/ui-design/reference/audit.md +76 -0
  68. package/assets/skills/ui-design/reference/audit.native.md +126 -0
  69. package/assets/skills/ui-design/reference/bolder.md +33 -0
  70. package/assets/skills/ui-design/reference/clarify.md +84 -0
  71. package/assets/skills/ui-design/reference/colorize.md +86 -0
  72. package/assets/skills/ui-design/reference/craft-floor.md +25 -0
  73. package/assets/skills/ui-design/reference/critique.md +345 -0
  74. package/assets/skills/ui-design/reference/degraded/asset-producer.md +35 -0
  75. package/assets/skills/ui-design/reference/degraded/documenter.md +23 -0
  76. package/assets/skills/ui-design/reference/degraded/finish-reviewer.md +43 -0
  77. package/assets/skills/ui-design/reference/degraded/manual-edit-applier.md +56 -0
  78. package/assets/skills/ui-design/reference/delight.md +63 -0
  79. package/assets/skills/ui-design/reference/distill.md +98 -0
  80. package/assets/skills/ui-design/reference/doctor.md +49 -0
  81. package/assets/skills/ui-design/reference/document.md +273 -0
  82. package/assets/skills/ui-design/reference/extract.md +52 -0
  83. package/assets/skills/ui-design/reference/harden.md +122 -0
  84. package/assets/skills/ui-design/reference/hooks.md +114 -0
  85. package/assets/skills/ui-design/reference/init.md +47 -0
  86. package/assets/skills/ui-design/reference/ios.md +55 -0
  87. package/assets/skills/ui-design/reference/layout.md +81 -0
  88. package/assets/skills/ui-design/reference/live-setup.md +75 -0
  89. package/assets/skills/ui-design/reference/live.md +326 -0
  90. package/assets/skills/ui-design/reference/new-work.md +350 -0
  91. package/assets/skills/ui-design/reference/onboard.md +85 -0
  92. package/assets/skills/ui-design/reference/operate.md +29 -0
  93. package/assets/skills/ui-design/reference/optimize.md +101 -0
  94. package/assets/skills/ui-design/reference/overdrive.md +83 -0
  95. package/assets/skills/ui-design/reference/polish.md +77 -0
  96. package/assets/skills/ui-design/reference/quieter.md +95 -0
  97. package/assets/skills/ui-design/reference/routing.md +37 -0
  98. package/assets/skills/ui-design/reference/shape.md +43 -0
  99. package/assets/skills/ui-design/reference/styles/brutalist.md +45 -0
  100. package/assets/skills/ui-design/reference/styles/design-md.md +70 -0
  101. package/assets/skills/ui-design/reference/styles/direction.md +95 -0
  102. package/assets/skills/ui-design/reference/styles/full-output.md +42 -0
  103. package/assets/skills/ui-design/reference/styles/minimalist.md +64 -0
  104. package/assets/skills/ui-design/reference/styles/premium.md +65 -0
  105. package/assets/skills/ui-design/reference/styles/redesign.md +59 -0
  106. package/assets/skills/ui-design/reference/typeset.md +73 -0
  107. package/assets/skills/ui-design/reference/visualize.md +156 -0
  108. package/assets/skills/ui-design/scripts/ENGINE-LICENSE +191 -0
  109. package/assets/skills/ui-design/scripts/VERSION +1 -0
  110. package/assets/skills/ui-design/scripts/bin/darwin-arm64/impeccable +0 -0
  111. package/assets/skills/ui-design/scripts/command-metadata.json +94 -0
  112. package/assets/skills/ui-design/scripts/data/font-index-failures.json +121 -0
  113. package/assets/skills/ui-design/scripts/data/font-index.json +1 -0
  114. package/assets/skills/ui-design/scripts/impeccable +206 -0
  115. package/assets/skills/ui-design/scripts/impeccable.cmd +214 -0
  116. package/assets/skills/ui-design/scripts/live-browser-dom.js +167 -0
  117. package/assets/skills/ui-design/scripts/live-browser-ignores.js +242 -0
  118. package/assets/skills/ui-design/scripts/live-browser-session.js +144 -0
  119. package/assets/skills/ui-design/scripts/live-browser.js +12990 -0
  120. package/assets/skills/ui-design/scripts/modern-screenshot.umd.js +14 -0
  121. package/assets/skills/ui-design/scripts/ui-design +6 -0
  122. package/assets/skills/ui-design/scripts/ui-design.cmd +3 -0
  123. package/assets/skills/ui-design/scripts/ui-design.mjs +124 -0
  124. package/assets/skills/ui-mockup/SKILL.md +68 -0
  125. package/assets/skills/ui-mockup/reference/brandkit.md +101 -0
  126. package/assets/skills/ui-mockup/reference/image-to-code.md +83 -0
  127. package/assets/skills/ui-mockup/reference/mobile-comps.md +94 -0
  128. package/assets/skills/ui-mockup/reference/web-comps.md +83 -0
  129. package/assets/skills/ui-motion/SKILL.md +112 -0
  130. package/assets/skills/ui-motion/reference/expo.md +224 -0
  131. package/assets/skills/ui-motion/reference/opportunities.md +81 -0
  132. package/assets/skills/ui-motion/reference/prototype.md +238 -0
  133. package/assets/skills/ui-motion/reference/review.md +163 -0
  134. package/assets/skills/ui-motion/reference/toasts.md +144 -0
  135. package/assets/skills/ui-motion/reference/ui-libraries.md +71 -0
  136. package/assets/skills/ui-motion/reference/vocabulary.md +130 -0
  137. package/assets/skills/ui-motion/reference/web.md +294 -0
  138. package/assets/skills/ui-patterns/SKILL.md +105 -0
  139. package/assets/skills/ui-patterns/references/stacks/html-tailwind.md +40 -0
  140. package/assets/skills/ui-patterns/references/stacks/nextjs.md +52 -0
  141. package/assets/skills/ui-patterns/references/stacks/nuxt.md +100 -0
  142. package/assets/skills/ui-patterns/references/stacks/react-native.md +48 -0
  143. package/assets/skills/ui-patterns/references/stacks/react.md +49 -0
  144. package/assets/skills/ui-patterns/references/stacks/shadcn.md +57 -0
  145. package/assets/skills/ui-patterns/references/stacks/vue.md +37 -0
  146. package/assets/techne/.claude-plugin/marketplace.json +31 -0
  147. package/assets/techne/.claude-plugin/plugin.json +24 -0
  148. package/assets/techne/.mcp.json +8 -0
  149. package/assets/techne/commands/build-fix.md +48 -0
  150. package/assets/techne/commands/refactor-clean.md +46 -0
  151. package/assets/techne/commands/test-coverage.md +42 -0
  152. package/assets/techne/hooks/hooks.json +49 -0
  153. package/assets/techne/rules/angular/coding-style.md +49 -0
  154. package/assets/techne/rules/angular/hooks.md +23 -0
  155. package/assets/techne/rules/angular/patterns.md +48 -0
  156. package/assets/techne/rules/angular/security.md +26 -0
  157. package/assets/techne/rules/angular/testing.md +46 -0
  158. package/assets/techne/rules/arkts/coding-style.md +63 -0
  159. package/assets/techne/rules/arkts/hooks.md +38 -0
  160. package/assets/techne/rules/arkts/patterns.md +42 -0
  161. package/assets/techne/rules/arkts/security.md +35 -0
  162. package/assets/techne/rules/arkts/testing.md +39 -0
  163. package/assets/techne/rules/common/agents.md +6 -0
  164. package/assets/techne/rules/common/code-review.md +15 -0
  165. package/assets/techne/rules/common/coding-style.md +13 -0
  166. package/assets/techne/rules/common/development-workflow.md +5 -0
  167. package/assets/techne/rules/common/git-workflow.md +30 -0
  168. package/assets/techne/rules/common/hooks.md +7 -0
  169. package/assets/techne/rules/common/patterns.md +3 -0
  170. package/assets/techne/rules/common/performance.md +3 -0
  171. package/assets/techne/rules/common/security.md +5 -0
  172. package/assets/techne/rules/common/testing.md +3 -0
  173. package/assets/techne/rules/cpp/coding-style.md +31 -0
  174. package/assets/techne/rules/cpp/hooks.md +26 -0
  175. package/assets/techne/rules/cpp/patterns.md +31 -0
  176. package/assets/techne/rules/cpp/security.md +37 -0
  177. package/assets/techne/rules/cpp/testing.md +31 -0
  178. package/assets/techne/rules/csharp/coding-style.md +30 -0
  179. package/assets/techne/rules/csharp/hooks.md +24 -0
  180. package/assets/techne/rules/csharp/patterns.md +28 -0
  181. package/assets/techne/rules/csharp/security.md +32 -0
  182. package/assets/techne/rules/csharp/testing.md +27 -0
  183. package/assets/techne/rules/dart/coding-style.md +47 -0
  184. package/assets/techne/rules/dart/hooks.md +26 -0
  185. package/assets/techne/rules/dart/patterns.md +38 -0
  186. package/assets/techne/rules/dart/security.md +44 -0
  187. package/assets/techne/rules/dart/testing.md +39 -0
  188. package/assets/techne/rules/fsharp/coding-style.md +34 -0
  189. package/assets/techne/rules/fsharp/hooks.md +25 -0
  190. package/assets/techne/rules/fsharp/patterns.md +43 -0
  191. package/assets/techne/rules/fsharp/security.md +32 -0
  192. package/assets/techne/rules/fsharp/testing.md +27 -0
  193. package/assets/techne/rules/golang/coding-style.md +30 -0
  194. package/assets/techne/rules/golang/hooks.md +17 -0
  195. package/assets/techne/rules/golang/patterns.md +43 -0
  196. package/assets/techne/rules/golang/security.md +33 -0
  197. package/assets/techne/rules/golang/testing.md +20 -0
  198. package/assets/techne/rules/java/coding-style.md +51 -0
  199. package/assets/techne/rules/java/hooks.md +18 -0
  200. package/assets/techne/rules/java/patterns.md +55 -0
  201. package/assets/techne/rules/java/security.md +33 -0
  202. package/assets/techne/rules/java/testing.md +33 -0
  203. package/assets/techne/rules/kotlin/coding-style.md +50 -0
  204. package/assets/techne/rules/kotlin/hooks.md +17 -0
  205. package/assets/techne/rules/kotlin/patterns.md +44 -0
  206. package/assets/techne/rules/kotlin/security.md +34 -0
  207. package/assets/techne/rules/kotlin/testing.md +38 -0
  208. package/assets/techne/rules/nuxt/coding-style.md +20 -0
  209. package/assets/techne/rules/nuxt/hooks.md +16 -0
  210. package/assets/techne/rules/nuxt/patterns.md +46 -0
  211. package/assets/techne/rules/nuxt/security.md +19 -0
  212. package/assets/techne/rules/nuxt/testing.md +15 -0
  213. package/assets/techne/rules/perl/coding-style.md +33 -0
  214. package/assets/techne/rules/perl/hooks.md +22 -0
  215. package/assets/techne/rules/perl/patterns.md +43 -0
  216. package/assets/techne/rules/perl/security.md +39 -0
  217. package/assets/techne/rules/perl/testing.md +42 -0
  218. package/assets/techne/rules/php/coding-style.md +30 -0
  219. package/assets/techne/rules/php/hooks.md +24 -0
  220. package/assets/techne/rules/php/patterns.md +26 -0
  221. package/assets/techne/rules/php/security.md +27 -0
  222. package/assets/techne/rules/php/testing.md +28 -0
  223. package/assets/techne/rules/python/coding-style.md +38 -0
  224. package/assets/techne/rules/python/fastapi.md +57 -0
  225. package/assets/techne/rules/python/hooks.md +19 -0
  226. package/assets/techne/rules/python/patterns.md +37 -0
  227. package/assets/techne/rules/python/security.md +26 -0
  228. package/assets/techne/rules/python/testing.md +32 -0
  229. package/assets/techne/rules/react/coding-style.md +24 -0
  230. package/assets/techne/rules/react/hooks.md +62 -0
  231. package/assets/techne/rules/react/patterns.md +48 -0
  232. package/assets/techne/rules/react/security.md +45 -0
  233. package/assets/techne/rules/react/testing.md +42 -0
  234. package/assets/techne/rules/react-native/accessibility.md +14 -0
  235. package/assets/techne/rules/react-native/coding-style.md +16 -0
  236. package/assets/techne/rules/react-native/hooks.md +16 -0
  237. package/assets/techne/rules/react-native/patterns.md +18 -0
  238. package/assets/techne/rules/react-native/performance.md +14 -0
  239. package/assets/techne/rules/react-native/production-readiness.md +16 -0
  240. package/assets/techne/rules/react-native/security.md +16 -0
  241. package/assets/techne/rules/react-native/testing.md +14 -0
  242. package/assets/techne/rules/ruby/coding-style.md +40 -0
  243. package/assets/techne/rules/ruby/hooks.md +33 -0
  244. package/assets/techne/rules/ruby/patterns.md +33 -0
  245. package/assets/techne/rules/ruby/security.md +39 -0
  246. package/assets/techne/rules/ruby/testing.md +35 -0
  247. package/assets/techne/rules/rust/coding-style.md +41 -0
  248. package/assets/techne/rules/rust/hooks.md +16 -0
  249. package/assets/techne/rules/rust/patterns.md +42 -0
  250. package/assets/techne/rules/rust/security.md +33 -0
  251. package/assets/techne/rules/rust/testing.md +30 -0
  252. package/assets/techne/rules/swift/coding-style.md +30 -0
  253. package/assets/techne/rules/swift/hooks.md +20 -0
  254. package/assets/techne/rules/swift/patterns.md +30 -0
  255. package/assets/techne/rules/swift/security.md +22 -0
  256. package/assets/techne/rules/swift/testing.md +28 -0
  257. package/assets/techne/rules/typescript/coding-style.md +38 -0
  258. package/assets/techne/rules/typescript/hooks.md +14 -0
  259. package/assets/techne/rules/typescript/patterns.md +12 -0
  260. package/assets/techne/rules/typescript/security.md +14 -0
  261. package/assets/techne/rules/typescript/testing.md +12 -0
  262. package/assets/techne/rules/vue/coding-style.md +19 -0
  263. package/assets/techne/rules/vue/hooks.md +13 -0
  264. package/assets/techne/rules/vue/patterns.md +29 -0
  265. package/assets/techne/rules/vue/security.md +11 -0
  266. package/assets/techne/rules/vue/testing.md +11 -0
  267. package/assets/techne/rules/web/coding-style.md +25 -0
  268. package/assets/techne/rules/web/design-quality.md +21 -0
  269. package/assets/techne/rules/web/hooks.md +39 -0
  270. package/assets/techne/rules/web/patterns.md +23 -0
  271. package/assets/techne/rules/web/performance.md +25 -0
  272. package/assets/techne/rules/web/security.md +23 -0
  273. package/assets/techne/rules/web/testing.md +21 -0
  274. package/assets/techne/scripts/hooks/config-guard.js +50 -0
  275. package/assets/techne/scripts/hooks/edit-tracker.js +26 -0
  276. package/assets/techne/scripts/hooks/lib/shell.js +204 -0
  277. package/assets/techne/scripts/hooks/no-verify-guard.js +205 -0
  278. package/assets/techne/scripts/hooks/run.js +92 -0
  279. package/assets/techne/scripts/hooks/stop-checks.js +136 -0
  280. package/assets/techne/skills/angular/SKILL.md +34 -0
  281. package/assets/techne/skills/angular/reference/components-and-templates.md +63 -0
  282. package/assets/techne/skills/angular/reference/dependency-injection.md +44 -0
  283. package/assets/techne/skills/angular/reference/forms.md +97 -0
  284. package/assets/techne/skills/angular/reference/routing.md +50 -0
  285. package/assets/techne/skills/angular/reference/signals-and-state.md +59 -0
  286. package/assets/techne/skills/angular/reference/styling-motion-a11y.md +54 -0
  287. package/assets/techne/skills/angular/reference/testing.md +52 -0
  288. package/assets/techne/skills/angular/reference/tooling.md +31 -0
  289. package/assets/techne/skills/cpp/SKILL.md +27 -0
  290. package/assets/techne/skills/cpp/reference/coding-standards.md +160 -0
  291. package/assets/techne/skills/databases/SKILL.md +35 -0
  292. package/assets/techne/skills/databases/reference/clickhouse.md +102 -0
  293. package/assets/techne/skills/databases/reference/migrations.md +94 -0
  294. package/assets/techne/skills/databases/reference/mysql.md +101 -0
  295. package/assets/techne/skills/databases/reference/postgres.md +72 -0
  296. package/assets/techne/skills/databases/reference/prisma.md +105 -0
  297. package/assets/techne/skills/databases/reference/redis.md +108 -0
  298. package/assets/techne/skills/delivery/SKILL.md +35 -0
  299. package/assets/techne/skills/delivery/reference/deployment-patterns.md +58 -0
  300. package/assets/techne/skills/delivery/reference/docker-patterns.md +77 -0
  301. package/assets/techne/skills/delivery/reference/git-workflow.md +64 -0
  302. package/assets/techne/skills/delivery/reference/github-ops.md +67 -0
  303. package/assets/techne/skills/delivery/reference/jira-integration.md +53 -0
  304. package/assets/techne/skills/delivery/reference/kubernetes-patterns.md +67 -0
  305. package/assets/techne/skills/dotnet/SKILL.md +27 -0
  306. package/assets/techne/skills/dotnet/reference/dotnet-core.md +131 -0
  307. package/assets/techne/skills/flutter/SKILL.md +29 -0
  308. package/assets/techne/skills/flutter/reference/code-review.md +76 -0
  309. package/assets/techne/skills/flutter/reference/patterns.md +201 -0
  310. package/assets/techne/skills/go/SKILL.md +28 -0
  311. package/assets/techne/skills/go/reference/patterns.md +87 -0
  312. package/assets/techne/skills/go/reference/testing.md +142 -0
  313. package/assets/techne/skills/java/SKILL.md +29 -0
  314. package/assets/techne/skills/java/reference/java-standards.md +117 -0
  315. package/assets/techne/skills/java/reference/springboot.md +108 -0
  316. package/assets/techne/skills/kotlin/SKILL.md +35 -0
  317. package/assets/techne/skills/kotlin/reference/android-clean-architecture.md +115 -0
  318. package/assets/techne/skills/kotlin/reference/compose-multiplatform-patterns.md +113 -0
  319. package/assets/techne/skills/kotlin/reference/kotlin-coroutines-flows.md +93 -0
  320. package/assets/techne/skills/kotlin/reference/kotlin-patterns.md +74 -0
  321. package/assets/techne/skills/kotlin/reference/kotlin-testing.md +115 -0
  322. package/assets/techne/skills/ml/SKILL.md +34 -0
  323. package/assets/techne/skills/ml/reference/ai-regression-testing.md +99 -0
  324. package/assets/techne/skills/ml/reference/cost-aware-llm-pipeline.md +133 -0
  325. package/assets/techne/skills/ml/reference/eval-harness.md +94 -0
  326. package/assets/techne/skills/ml/reference/mle-workflow.md +177 -0
  327. package/assets/techne/skills/ml/reference/prompt-optimizer.md +107 -0
  328. package/assets/techne/skills/ml/reference/pytorch-patterns.md +164 -0
  329. package/assets/techne/skills/php/SKILL.md +27 -0
  330. package/assets/techne/skills/php/reference/laravel.md +142 -0
  331. package/assets/techne/skills/python/SKILL.md +33 -0
  332. package/assets/techne/skills/python/reference/django.md +104 -0
  333. package/assets/techne/skills/python/reference/fastapi.md +118 -0
  334. package/assets/techne/skills/python/reference/python-core.md +88 -0
  335. package/assets/techne/skills/python/reference/python-testing.md +105 -0
  336. package/assets/techne/skills/quality/SKILL.md +34 -0
  337. package/assets/techne/skills/quality/reference/benchmark.md +55 -0
  338. package/assets/techne/skills/quality/reference/browser-qa.md +60 -0
  339. package/assets/techne/skills/quality/reference/coding-standards.md +88 -0
  340. package/assets/techne/skills/quality/reference/e2e-testing.md +99 -0
  341. package/assets/techne/skills/quality/reference/tdd-workflow.md +89 -0
  342. package/assets/techne/skills/quality/reference/verification-loop.md +80 -0
  343. package/assets/techne/skills/react/SKILL.md +30 -0
  344. package/assets/techne/skills/react/reference/nextjs-turbopack.md +42 -0
  345. package/assets/techne/skills/react/reference/react-patterns.md +139 -0
  346. package/assets/techne/skills/react/reference/react-performance.md +101 -0
  347. package/assets/techne/skills/react/reference/react-testing.md +139 -0
  348. package/assets/techne/skills/react-native/SKILL.md +28 -0
  349. package/assets/techne/skills/react-native/reference/expo-patterns.md +196 -0
  350. package/assets/techne/skills/research/SKILL.md +35 -0
  351. package/assets/techne/skills/research/reference/architecture-decision-records.md +65 -0
  352. package/assets/techne/skills/research/reference/codebase-onboarding.md +44 -0
  353. package/assets/techne/skills/research/reference/deep-research.md +50 -0
  354. package/assets/techne/skills/research/reference/iterative-retrieval.md +62 -0
  355. package/assets/techne/skills/research/reference/product-lens.md +38 -0
  356. package/assets/techne/skills/research/reference/search-first.md +50 -0
  357. package/assets/techne/skills/rust/SKILL.md +28 -0
  358. package/assets/techne/skills/rust/reference/patterns.md +108 -0
  359. package/assets/techne/skills/rust/reference/testing.md +142 -0
  360. package/assets/techne/skills/services/SKILL.md +32 -0
  361. package/assets/techne/skills/services/reference/api-contracts.md +139 -0
  362. package/assets/techne/skills/services/reference/backend-layers.md +95 -0
  363. package/assets/techne/skills/services/reference/errors-and-resilience.md +146 -0
  364. package/assets/techne/skills/services/reference/hexagonal-boundaries.md +93 -0
  365. package/assets/techne/skills/services/reference/mcp-servers.md +50 -0
  366. package/assets/techne/skills/services/reference/nestjs.md +96 -0
  367. package/assets/techne/skills/swift/SKILL.md +29 -0
  368. package/assets/techne/skills/swift/reference/concurrency.md +83 -0
  369. package/assets/techne/skills/swift/reference/swiftui.md +139 -0
  370. package/assets/techne/skills/vue/SKILL.md +29 -0
  371. package/assets/techne/skills/vue/reference/nuxt4-patterns.md +90 -0
  372. package/assets/techne/skills/vue/reference/ui-to-vue.md +90 -0
  373. package/assets/techne/skills/vue/reference/vue-patterns.md +151 -0
  374. package/assets/techne/skills/web/SKILL.md +30 -0
  375. package/assets/techne/skills/web/reference/bun-runtime.md +55 -0
  376. package/assets/techne/skills/web/reference/frontend-patterns.md +54 -0
  377. package/assets/techne/skills/web/reference/seo.md +77 -0
  378. package/assets/techne/skills/web/reference/vite-patterns.md +96 -0
  379. package/bin/native.cjs +30 -0
  380. package/native/aarch64-apple-darwin/exonous +0 -0
  381. package/native/aarch64-unknown-linux-gnu/exonous +0 -0
  382. package/native/x86_64-apple-darwin/exonous +0 -0
  383. package/native/x86_64-pc-windows-msvc/exonous.exe +0 -0
  384. package/native/x86_64-unknown-linux-gnu/exonous +0 -0
  385. package/package.json +1 -6
@@ -0,0 +1,354 @@
1
+ 'use strict';
2
+
3
+ // Self-contained: copied to ~/.claude/exonous/hooks/lib/, node builtins only. One state dir serves every tool.
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { execFileSync } = require('child_process');
8
+ const { exoDir, stateDir, redirectedHome, testMode, foreignOwner } = require('./paths.cjs');
9
+ const { RELEASE_REF, compareVersions, listReleases } = require('./release.cjs');
10
+ const repo = require('./repo.cjs');
11
+
12
+ const DAY_MS = 24 * 60 * 60 * 1000;
13
+ const LOCK_STALE_MS = 30 * 60 * 1000;
14
+ const LOG_MAX = 64 * 1024;
15
+ const NOTE_MAX = 200;
16
+ // Fixed on purpose: install.json `source` is informational and never executed.
17
+ const SOURCE = 'https://github.com/zaqueu-1/exonous.git';
18
+ const SLUG = 'zaqueu-1/exonous';
19
+ const PMS = ['npm', 'pnpm', 'bun'];
20
+ const SHA = /^[0-9a-f]{40}$/;
21
+ const VERSION = /^\d+\.\d+\.\d+$/;
22
+
23
+ const NOTES = {
24
+ updated: (from, to) => `exonous updated v${from} → v${to} (restart to load new hooks)`,
25
+ failed: (to) => `exonous update to v${to} failed — run \`exonous update\` to see why`,
26
+ major: (version) => `exonous v${version} is a new major — run \`exonous update --major\``,
27
+ tagMoved: (version) => `exonous: release tag v${version} moved since install — run \`exonous doctor\``,
28
+ };
29
+
30
+ const statePath = (name) => path.join(stateDir(), name);
31
+ // Another uid (root in a user's session) owns the exonous dir: read nothing, write nothing.
32
+ const notOwner = () => foreignOwner(exoDir()) !== null || foreignOwner(stateDir()) !== null;
33
+ const parts = (version) => String(version).split('.').map(Number);
34
+
35
+ function readJson(file) {
36
+ try {
37
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+
43
+ function writeState(name, content) {
44
+ fs.mkdirSync(stateDir(), { recursive: true, mode: 0o700 });
45
+ fs.writeFileSync(statePath(name), content, { mode: 0o600 });
46
+ }
47
+
48
+ /** Detailed errors stay in state/update.log (64 KB, one rotation), never in the note. */
49
+ function logLine(text) {
50
+ try {
51
+ fs.mkdirSync(stateDir(), { recursive: true, mode: 0o700 });
52
+ const file = statePath('update.log');
53
+ const line = `${new Date().toISOString()} ${flatten(text).slice(0, 4096)}\n`;
54
+ let size = 0;
55
+ try {
56
+ size = fs.statSync(file).size;
57
+ } catch {
58
+ // first line
59
+ }
60
+ if (size + Buffer.byteLength(line) > LOG_MAX) fs.renameSync(file, `${file}.1`);
61
+ fs.appendFileSync(file, line, { mode: 0o600 });
62
+ } catch {
63
+ // logging must never break an update
64
+ }
65
+ }
66
+
67
+ const installFile = () => path.join(exoDir(), 'install.json');
68
+ const readInstall = () => readJson(installFile());
69
+
70
+ function patchInstall(fields) {
71
+ const file = installFile();
72
+ const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
73
+ fs.writeFileSync(tmp, `${JSON.stringify({ ...readInstall(), ...fields }, null, 2)}\n`, { mode: 0o600, flag: 'wx' });
74
+ fs.renameSync(tmp, file);
75
+ }
76
+
77
+ /** @returns {string | null} why automatic updates are off */
78
+ function optedOut(env = process.env) {
79
+ if (env.EXONOUS_NO_UPDATE && env.EXONOUS_NO_UPDATE !== '0') return 'EXONOUS_NO_UPDATE';
80
+ if (env.CI || env.CONTINUOUS_INTEGRATION) return 'CI';
81
+ if (readJson(path.join(exoDir(), 'config.json'))?.autoUpdate === false) return 'config.json autoUpdate:false';
82
+ return null;
83
+ }
84
+
85
+ /** @returns {number | null} ms timestamp of the last update check */
86
+ function lastCheck() {
87
+ try {
88
+ return fs.statSync(statePath('last-check')).mtimeMs;
89
+ } catch {
90
+ return null;
91
+ }
92
+ }
93
+
94
+ // A last-check in the future (clock moved back) counts as due.
95
+ function due({ now = Date.now() } = {}) {
96
+ const last = lastCheck();
97
+ return last === null || now - last >= DAY_MS || now < last;
98
+ }
99
+
100
+ function markChecked({ now = Date.now() } = {}) {
101
+ if (notOwner()) return false;
102
+ writeState('last-check', `${now}\n`);
103
+ const t = now / 1000;
104
+ fs.utimesSync(statePath('last-check'), t, t);
105
+ return true;
106
+ }
107
+
108
+ /** One printable line: whitespace collapsed, control and bidi characters dropped. */
109
+ const flatten = (text) => String(text)
110
+ .replace(/[\u0000-\u001f\u007f-\u009f]+/g, ' ')
111
+ .replace(/[\u200b-\u200f\u202a-\u202e\u2066-\u2069\ufeff]/g, '')
112
+ .replace(/\s+/g, ' ')
113
+ .trim();
114
+
115
+ function cleanNote(text) {
116
+ const flat = flatten(text);
117
+ return flat.length > NOTE_MAX ? `${flat.slice(0, NOTE_MAX - 1)}…` : flat;
118
+ }
119
+
120
+ function writeNote(text) {
121
+ writeState('note', `${cleanNote(text)}\n`);
122
+ }
123
+
124
+ /** Note left for the next session start, removed once read. */
125
+ function takeNote() {
126
+ if (notOwner()) return '';
127
+ try {
128
+ const note = cleanNote(fs.readFileSync(statePath('note'), 'utf8'));
129
+ fs.rmSync(statePath('note'), { force: true });
130
+ return note;
131
+ } catch {
132
+ return '';
133
+ }
134
+ }
135
+
136
+ /** @returns {{ version: string, expected: string, actual: string } | null} set when an installed release tag moved */
137
+ function tagWarning() {
138
+ return readJson(statePath('tag-moved.json'));
139
+ }
140
+
141
+ /**
142
+ * Compares install.json with the release tags; changes nothing.
143
+ * @param {{ major?: boolean }} [options] major: also consider a newer major.
144
+ */
145
+ function check({ major = false } = {}) {
146
+ const info = readInstall();
147
+ if (!info?.version) return { status: 'not-installed' };
148
+ if (info.ref && !RELEASE_REF.test(info.ref)) return { status: 'pinned', from: info.version, ref: info.ref };
149
+ const from = info.version;
150
+ // Repo mode follows the repo's own dependency spec (source and ref), never install.json.
151
+ const source = repo.repoSource(info);
152
+ if (source && (repo.pinned(source.ref) || !source.url)) return { status: 'pinned', from, ref: `${source.dep.name}@${source.dep.spec} in ${source.root}`, repo: source.root };
153
+ const releases = listReleases(source ? source.url : SOURCE).filter((r) => SHA.test(r.sha));
154
+ const sameMajor = releases.filter((r) => r.parts[0] === parts(from)[0]).pop();
155
+ const top = releases[releases.length - 1];
156
+ const result = { status: 'current', from };
157
+ const newer = (r) => r && compareVersions(r.parts, parts(from)) > 0;
158
+ if (newer(top) && top.parts[0] !== parts(from)[0]) result.newMajor = top.version;
159
+ const installedTag = releases.find((r) => r.version === from);
160
+ if (installedTag && info.tagSha && installedTag.sha !== info.tagSha) {
161
+ result.tagMoved = { version: from, expected: info.tagSha, actual: installedTag.sha };
162
+ }
163
+ if (installedTag && !info.tagSha) result.tagSha = installedTag.sha;
164
+ const target = major && result.newMajor ? top : sameMajor;
165
+ if (!releases.length) return { ...result, status: 'no-release' };
166
+ if (newer(target)) return { ...result, status: 'available', to: target.version, sha: target.sha };
167
+ return { ...result, to: from };
168
+ }
169
+
170
+ const lockFile = () => statePath('update.lock');
171
+
172
+ function lockAcquire() {
173
+ fs.mkdirSync(stateDir(), { recursive: true, mode: 0o700 });
174
+ for (let attempt = 0; attempt < 2; attempt++) {
175
+ try {
176
+ fs.closeSync(fs.openSync(lockFile(), 'wx', 0o600));
177
+ fs.writeFileSync(lockFile(), `${process.pid}\n`);
178
+ return true;
179
+ } catch (err) {
180
+ if (err.code !== 'EEXIST') throw err;
181
+ try {
182
+ if (Date.now() - fs.statSync(lockFile()).mtimeMs < LOCK_STALE_MS) return false;
183
+ fs.rmSync(lockFile(), { force: true });
184
+ } catch {
185
+ // gone between the open and the stat: retry
186
+ }
187
+ }
188
+ }
189
+ return false;
190
+ }
191
+
192
+ // Keeps a long update from looking stale to a concurrent session.
193
+ function lockTouch() {
194
+ try {
195
+ const t = Date.now() / 1000;
196
+ fs.utimesSync(lockFile(), t, t);
197
+ } catch {
198
+ // lock removed underneath: the update still finishes
199
+ }
200
+ }
201
+
202
+ /** The only spec ever installed: the fixed repo at the tag's commit. */
203
+ function spec(sha) {
204
+ if (!SHA.test(sha)) throw new Error(`refusing to install: "${sha}" is not a commit sha`);
205
+ return `github:${SLUG}#${sha}`;
206
+ }
207
+
208
+ /** pm binary recorded at install when it still looks like that pm; else the name on PATH. */
209
+ function pmCommand(info) {
210
+ const pm = PMS.includes(info.pm) ? info.pm : 'npm';
211
+ const recorded = info.pmPath;
212
+ const ok = typeof recorded === 'string' && path.isAbsolute(recorded) && !/["%]/.test(recorded)
213
+ && path.basename(recorded).replace(/\.(cmd|exe)$/i, '') === pm && fs.existsSync(recorded);
214
+ return { pm, bin: ok ? recorded : pm };
215
+ }
216
+
217
+ // win32 needs a shell for .cmd shims: command quoted, args are fixed literals or a validated sha spec.
218
+ function pmRun({ bin }, args) {
219
+ const win = process.platform === 'win32';
220
+ return execFileSync(win ? `"${bin}"` : bin, args, {
221
+ encoding: 'utf8', timeout: 10 * 60 * 1000, stdio: ['ignore', 'pipe', 'pipe'], shell: win, windowsHide: true,
222
+ });
223
+ }
224
+
225
+ function globalRoot(cmd) {
226
+ if (cmd.pm === 'bun') return path.join(process.env.BUN_INSTALL || path.join(os.homedir(), '.bun'), 'install', 'global', 'node_modules', 'exonous');
227
+ const out = pmRun(cmd, ['root', '-g']).trim().split(/\r?\n/).pop();
228
+ if (!path.isAbsolute(out)) throw new Error(`${cmd.pm} root -g gave no absolute path`);
229
+ return path.join(out, 'exonous');
230
+ }
231
+
232
+ /**
233
+ * Checks the installed package is the release: name, version, and the commit wherever the pm records it.
234
+ * npm: <global>/node_modules/.package-lock.json; pnpm: <global>/pnpm-lock.yaml; bun: <global>/bun.lock. None → name + version only.
235
+ */
236
+ function verifyPackage(root, { to, sha }) {
237
+ const pkg = readJson(path.join(root, 'package.json'));
238
+ if (pkg?.name !== 'exonous') throw new Error(`${root} is not the exonous package`);
239
+ if (pkg.version !== to) throw new Error(`${root} holds v${pkg.version || '?'}, expected v${to}`);
240
+ if (pkg.gitHead && pkg.gitHead !== sha) throw new Error(`${root} was built from ${pkg.gitHead}, expected ${sha}`);
241
+ const nm = path.dirname(root);
242
+ const locks = [path.join(nm, '.package-lock.json'), path.join(path.dirname(nm), 'pnpm-lock.yaml'), path.join(path.dirname(nm), 'bun.lock')]
243
+ .map((file) => {
244
+ try {
245
+ return fs.readFileSync(file, 'utf8');
246
+ } catch {
247
+ return '';
248
+ }
249
+ })
250
+ .filter((text) => text.includes(SLUG));
251
+ if (locks.length && !locks.some((text) => text.includes(sha))) throw new Error(`the ${path.basename(nm)} lockfile does not pin exonous to ${sha}`);
252
+ return { commitVerified: locks.length > 0 };
253
+ }
254
+
255
+ // A redirected home must not reach the real global pm prefix; only test mode may use its PATH shims.
256
+ const globalAllowed = () => !redirectedHome() || (testMode() && process.env.EXONOUS_UPDATE_TEST_PM === '1');
257
+
258
+ const devCheckout = (info) => typeof info.packageRoot === 'string' && fs.existsSync(path.join(info.packageRoot, '.git'));
259
+
260
+ const detail = (err) => flatten(`${err.message || err}${err.stderr ? ` | ${err.stderr}` : ''}`).slice(0, 4000);
261
+
262
+ /** Global mode: the fixed source at the tag's commit, through the recorded pm. Returns the new package root. */
263
+ function installGlobal(info, decision) {
264
+ const cmd = pmCommand(info);
265
+ const target = spec(decision.sha);
266
+ pmRun(cmd, cmd.pm === 'npm' ? ['i', '-g', '--no-audit', '--no-fund', target] : ['add', '-g', target]);
267
+ return globalRoot(cmd);
268
+ }
269
+
270
+ /** @returns {{ warnings: string[], commitVerified: boolean }} */
271
+ function apply(info, decision) {
272
+ if (!VERSION.test(decision.to)) throw new Error(`invalid release version ${decision.to}`);
273
+ const source = repo.repoSource(info);
274
+ const root = source ? repo.bumpRepo(source, decision.to) : installGlobal(info, decision);
275
+ lockTouch();
276
+ const { commitVerified } = verifyPackage(root, decision);
277
+ lockTouch();
278
+ // The hooks under ~/.claude/exonous only change if this install succeeds; `setup` from a repo copy keeps repo mode.
279
+ const out = execFileSync(process.execPath, [path.join(root, 'bin', 'exonous.js'), source ? 'setup' : 'install', '--quiet'], {
280
+ cwd: source ? source.root : undefined,
281
+ env: source ? { ...process.env, INIT_CWD: source.root } : process.env,
282
+ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10 * 60 * 1000, windowsHide: true,
283
+ });
284
+ const warnings = String(out).split('\n').filter((l) => l.includes('WARN'));
285
+ if (!warnings.length) patchInstall({ ref: `v${decision.to}`, tagSha: decision.sha });
286
+ return { warnings, commitVerified };
287
+ }
288
+
289
+ function recordTag(decision) {
290
+ if (decision.tagMoved) {
291
+ writeState('tag-moved.json', `${JSON.stringify(decision.tagMoved)}\n`);
292
+ logLine(`release tag v${decision.tagMoved.version} moved: installed ${decision.tagMoved.expected}, now ${decision.tagMoved.actual}`);
293
+ writeNote(NOTES.tagMoved(decision.tagMoved.version));
294
+ } else if (decision.status !== 'pinned') {
295
+ fs.rmSync(statePath('tag-moved.json'), { force: true });
296
+ }
297
+ if (decision.tagSha) patchInstall({ tagSha: decision.tagSha });
298
+ }
299
+
300
+ function announceMajor(version) {
301
+ if (readJson(statePath('major-seen.json'))?.version === version) return;
302
+ writeState('major-seen.json', `${JSON.stringify({ version })}\n`);
303
+ writeNote(NOTES.major(version));
304
+ }
305
+
306
+ /**
307
+ * Checks and, when a newer release exists, reinstalls through the recorded pm. Never throws in background mode.
308
+ * @param {{ background?: boolean, major?: boolean }} [options] background: honor opt-outs and report through state/note.
309
+ */
310
+ function run({ background = false, major = false } = {}) {
311
+ if (notOwner()) return { status: 'not-owner' };
312
+ if (background) {
313
+ const reason = optedOut();
314
+ if (reason) return { status: 'disabled', reason };
315
+ }
316
+ let decision;
317
+ try {
318
+ decision = check({ major });
319
+ recordTag(decision);
320
+ } catch (err) {
321
+ markChecked();
322
+ logLine(`check failed: ${detail(err)}`);
323
+ if (!background) throw err;
324
+ return { status: 'error', error: detail(err) };
325
+ }
326
+ if (decision.status !== 'available') {
327
+ if (background && decision.newMajor) announceMajor(decision.newMajor);
328
+ return decision;
329
+ }
330
+ const info = readInstall();
331
+ if (devCheckout(info)) return { ...decision, status: 'pinned', ref: `dev checkout ${info.packageRoot}` };
332
+ if (!globalAllowed()) return { ...decision, status: 'isolated' };
333
+ if (!lockAcquire()) return { ...decision, status: 'busy' };
334
+ try {
335
+ const { warnings, commitVerified } = apply(info, decision);
336
+ for (const w of warnings) logLine(`install v${decision.to}: ${cleanNote(w)}`);
337
+ if (!commitVerified) logLine(`v${decision.to}: no pm lockfile records the commit; verified by name and version only`);
338
+ if (background) writeNote(NOTES.updated(decision.from, decision.to));
339
+ return { ...decision, status: 'updated', warnings: warnings.length };
340
+ } catch (err) {
341
+ markChecked();
342
+ const error = detail(err);
343
+ logLine(`update to v${decision.to} failed: ${error}`);
344
+ if (background) writeNote(NOTES.failed(decision.to));
345
+ return { ...decision, status: 'failed', error };
346
+ } finally {
347
+ fs.rmSync(lockFile(), { force: true });
348
+ }
349
+ }
350
+
351
+ module.exports = {
352
+ DAY_MS, LOCK_STALE_MS, SOURCE, notOwner, optedOut, due, lastCheck, markChecked, cleanNote, takeNote, tagWarning, check, run, spec,
353
+ pmCommand, pmRun, globalRoot, globalAllowed, verifyPackage,
354
+ };