@amsterdamdatalabs/enact-extensions 0.1.42 → 0.1.47

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 (580) hide show
  1. package/README.md +67 -108
  2. package/bundled-extensions.json +6 -0
  3. package/dist/create/enact.d.ts.map +1 -1
  4. package/dist/create/enact.js +2 -0
  5. package/dist/create/enact.js.map +1 -1
  6. package/dist/create/index.d.ts +3 -0
  7. package/dist/create/index.d.ts.map +1 -1
  8. package/dist/create/index.js +6 -0
  9. package/dist/create/index.js.map +1 -1
  10. package/dist/create/kimi.d.ts +16 -0
  11. package/dist/create/kimi.d.ts.map +1 -0
  12. package/dist/create/kimi.js +87 -0
  13. package/dist/create/kimi.js.map +1 -0
  14. package/dist/create/opencode.d.ts +129 -0
  15. package/dist/create/opencode.d.ts.map +1 -0
  16. package/dist/create/opencode.js +696 -0
  17. package/dist/create/opencode.js.map +1 -0
  18. package/dist/index.d.ts +12 -16
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +10 -10
  21. package/dist/index.js.map +1 -1
  22. package/dist/internal/agents.d.ts +11 -1
  23. package/dist/internal/agents.d.ts.map +1 -1
  24. package/dist/internal/agents.js +119 -3
  25. package/dist/internal/agents.js.map +1 -1
  26. package/dist/internal/extensions-table.d.ts +58 -0
  27. package/dist/internal/extensions-table.d.ts.map +1 -0
  28. package/dist/internal/extensions-table.js +134 -0
  29. package/dist/internal/extensions-table.js.map +1 -0
  30. package/dist/internal/file-ops.d.ts +36 -0
  31. package/dist/internal/file-ops.d.ts.map +1 -0
  32. package/dist/internal/file-ops.js +89 -0
  33. package/dist/internal/file-ops.js.map +1 -0
  34. package/dist/internal/hooks.d.ts +56 -0
  35. package/dist/internal/hooks.d.ts.map +1 -0
  36. package/dist/internal/hooks.js +128 -0
  37. package/dist/internal/hooks.js.map +1 -0
  38. package/dist/internal/json-merge.d.ts +63 -0
  39. package/dist/internal/json-merge.d.ts.map +1 -0
  40. package/dist/internal/json-merge.js +122 -0
  41. package/dist/internal/json-merge.js.map +1 -0
  42. package/dist/internal/lock-ownership.d.ts +41 -0
  43. package/dist/internal/lock-ownership.d.ts.map +1 -0
  44. package/dist/internal/lock-ownership.js +24 -0
  45. package/dist/internal/lock-ownership.js.map +1 -0
  46. package/dist/internal/platform.d.ts.map +1 -1
  47. package/dist/internal/platform.js +90 -4
  48. package/dist/internal/platform.js.map +1 -1
  49. package/dist/internal/schema.js.map +1 -1
  50. package/dist/internal/toml-block.d.ts +59 -0
  51. package/dist/internal/toml-block.d.ts.map +1 -0
  52. package/dist/internal/toml-block.js +113 -0
  53. package/dist/internal/toml-block.js.map +1 -0
  54. package/dist/internal/types.d.ts +2 -1
  55. package/dist/internal/types.d.ts.map +1 -1
  56. package/dist/projection.d.ts +47 -0
  57. package/dist/projection.d.ts.map +1 -0
  58. package/dist/projection.js +180 -0
  59. package/dist/projection.js.map +1 -0
  60. package/dist/validate/index.d.ts +9 -4
  61. package/dist/validate/index.d.ts.map +1 -1
  62. package/dist/validate/index.js +56 -7
  63. package/dist/validate/index.js.map +1 -1
  64. package/dist/validate/kimi.d.ts +3 -0
  65. package/dist/validate/kimi.d.ts.map +1 -0
  66. package/dist/validate/kimi.js +11 -0
  67. package/dist/validate/kimi.js.map +1 -0
  68. package/dist/validate/opencode.d.ts +3 -0
  69. package/dist/validate/opencode.d.ts.map +1 -0
  70. package/dist/validate/opencode.js +11 -0
  71. package/dist/validate/opencode.js.map +1 -0
  72. package/dist/validate/run.d.ts +39 -0
  73. package/dist/validate/run.d.ts.map +1 -0
  74. package/dist/validate/run.js +63 -0
  75. package/dist/validate/run.js.map +1 -0
  76. package/extensions/enact-loop/.agents/plugin.json +12 -8
  77. package/extensions/enact-loop/scripts/validate.mjs +84 -2
  78. package/extensions/enact-loop/skills/enact-loop/SKILL.md +36 -466
  79. package/extensions/enact-loop/skills/enact-loop/references/loop-contract.md +114 -0
  80. package/extensions/enact-loop/skills/loop-budget/SKILL.md +43 -26
  81. package/extensions/enact-loop/skills/loop-intake/SKILL.md +44 -32
  82. package/extensions/enact-repo/.agents/plugin.json +55 -0
  83. package/extensions/enact-repo/.mcp.json +20 -0
  84. package/extensions/enact-repo/README.md +90 -0
  85. package/extensions/enact-repo/hooks/hooks.json +98 -0
  86. package/extensions/enact-repo/lean-ctx/config.toml +35 -0
  87. package/extensions/enact-repo/lean-ctx/layout.toml +5 -0
  88. package/extensions/enact-repo/skills/aca-sandboxes/SKILL.md +53 -0
  89. package/extensions/enact-repo/skills/aca-sandboxes/references/capabilities.md +52 -0
  90. package/extensions/enact-repo/skills/aca-sandboxes/references/install.md +87 -0
  91. package/extensions/enact-repo/skills/aca-sandboxes/references/prerequisites.md +52 -0
  92. package/extensions/enact-repo/skills/aca-sandboxes/references/quickstart.md +164 -0
  93. package/extensions/enact-repo/skills/aca-sandboxes/references/reference-advanced.md +251 -0
  94. package/extensions/enact-repo/skills/aca-sandboxes/references/reference.md +287 -0
  95. package/extensions/enact-repo/skills/aca-sandboxes/references/response-cues.md +71 -0
  96. package/extensions/enact-repo/skills/aca-sandboxes/references/scenarios.md +219 -0
  97. package/extensions/enact-repo/skills/aca-sandboxes/version.json +4 -0
  98. package/extensions/enact-repo/skills/backend-remove-deadcode/SKILL.md +96 -0
  99. package/extensions/enact-repo/skills/cmux-leader/SKILL.md +61 -0
  100. package/extensions/enact-repo/skills/cmux-send/SKILL.md +61 -0
  101. package/extensions/enact-repo/skills/code-review/SKILL.md +100 -0
  102. package/extensions/enact-repo/skills/codebase-design/SKILL.md +98 -0
  103. package/extensions/enact-repo/skills/codebase-design/references/DEEPENING.md +37 -0
  104. package/extensions/enact-repo/skills/codebase-design/references/DESIGN-IT-TWICE.md +44 -0
  105. package/extensions/enact-repo/skills/codebase-design/references/TESTABILITY.md +29 -0
  106. package/extensions/enact-repo/skills/computer-use/SKILL.md +76 -0
  107. package/extensions/enact-repo/skills/debug-issue/SKILL.md +40 -0
  108. package/extensions/enact-repo/skills/diagnosing-bugs/SKILL.md +100 -0
  109. package/extensions/enact-repo/skills/diagnosing-bugs/references/FEEDBACK-LOOP-TACTICS.md +34 -0
  110. package/extensions/enact-repo/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  111. package/extensions/enact-repo/skills/domain-modeling/SKILL.md +86 -0
  112. package/extensions/enact-repo/skills/domain-modeling/references/ADR-FORMAT.md +47 -0
  113. package/extensions/enact-repo/skills/domain-modeling/references/CONTEXT-FORMAT.md +60 -0
  114. package/extensions/enact-repo/skills/explore-codebase/SKILL.md +41 -0
  115. package/extensions/enact-repo/skills/frontend-design/LICENSE.txt +177 -0
  116. package/extensions/enact-repo/skills/frontend-design/SKILL.md +56 -0
  117. package/extensions/enact-repo/skills/grill-me/SKILL.md +20 -0
  118. package/extensions/enact-repo/skills/grill-with-docs/SKILL.md +20 -0
  119. package/extensions/enact-repo/skills/handoff/SKILL.md +28 -0
  120. package/extensions/enact-repo/skills/http-contract-migration/SKILL.md +74 -0
  121. package/extensions/enact-repo/skills/http-contract-migration/references/compatibility-and-gates.md +26 -0
  122. package/extensions/enact-repo/skills/http-contract-migration/references/hexagonal-boundary.md +16 -0
  123. package/extensions/enact-repo/skills/http-contract-migration/references/publication-and-adoption.md +31 -0
  124. package/extensions/enact-repo/skills/http-contract-migration/references/wire-fidelity-and-dto.md +31 -0
  125. package/extensions/enact-repo/skills/implement/SKILL.md +28 -0
  126. package/extensions/enact-repo/skills/improve-codebase-architecture/SKILL.md +80 -0
  127. package/extensions/enact-repo/skills/improve-codebase-architecture/references/HTML-REPORT.md +123 -0
  128. package/extensions/enact-repo/skills/interaction-design/SKILL.md +30 -0
  129. package/extensions/enact-repo/skills/interaction-design/references/Workflow.md +146 -0
  130. package/extensions/enact-repo/skills/interaction-design/references/animation-libraries-gsap.md +220 -0
  131. package/extensions/enact-repo/skills/interaction-design/references/animation-libraries-native.md +110 -0
  132. package/extensions/enact-repo/skills/interaction-design/references/animation-libraries.md +178 -0
  133. package/extensions/enact-repo/skills/interaction-design/references/interaction-patterns.md +166 -0
  134. package/extensions/enact-repo/skills/interaction-design/references/microinteraction-patterns-advanced.md +285 -0
  135. package/extensions/enact-repo/skills/interaction-design/references/microinteraction-patterns.md +254 -0
  136. package/extensions/enact-repo/skills/interaction-design/references/scroll-animations-reveals.md +213 -0
  137. package/extensions/enact-repo/skills/interaction-design/references/scroll-animations.md +209 -0
  138. package/extensions/enact-repo/skills/lean-ctx/SKILL.md +81 -0
  139. package/extensions/enact-repo/skills/orca-cli/SKILL.md +88 -0
  140. package/extensions/enact-repo/skills/orchestration/SKILL.md +80 -0
  141. package/extensions/enact-repo/skills/prototype/SKILL.md +37 -0
  142. package/extensions/enact-repo/skills/prototype/references/LOGIC.md +79 -0
  143. package/extensions/enact-repo/skills/prototype/references/UI.md +112 -0
  144. package/extensions/enact-repo/skills/refactor-safely/SKILL.md +44 -0
  145. package/extensions/enact-repo/skills/remove-deadcode/SKILL.md +54 -0
  146. package/extensions/enact-repo/skills/research/SKILL.md +27 -0
  147. package/extensions/enact-repo/skills/resolving-merge-conflicts/SKILL.md +28 -0
  148. package/extensions/enact-repo/skills/review-changes/SKILL.md +45 -0
  149. package/extensions/enact-repo/skills/tailwind-4-docs/SKILL.md +88 -0
  150. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/accent-color.mdx +149 -0
  151. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/adding-custom-styles.mdx +635 -0
  152. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/align-content.mdx +300 -0
  153. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/align-items.mdx +241 -0
  154. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/align-self.mdx +294 -0
  155. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/animation.mdx +286 -0
  156. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/appearance.mdx +180 -0
  157. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/aspect-ratio.mdx +98 -0
  158. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-blur.mdx +109 -0
  159. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-brightness.mdx +82 -0
  160. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-contrast.mdx +82 -0
  161. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-grayscale.mdx +99 -0
  162. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-hue-rotate.mdx +173 -0
  163. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-invert.mdx +99 -0
  164. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-opacity.mdx +103 -0
  165. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-saturate.mdx +98 -0
  166. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter-sepia.mdx +95 -0
  167. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backdrop-filter.mdx +113 -0
  168. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/backface-visibility.mdx +110 -0
  169. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-attachment.mdx +126 -0
  170. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-blend-mode.mdx +79 -0
  171. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-clip.mdx +85 -0
  172. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-color.mdx +176 -0
  173. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-image.mdx +349 -0
  174. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-origin.mdx +64 -0
  175. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-position.mdx +171 -0
  176. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-repeat.mdx +127 -0
  177. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/background-size.mdx +100 -0
  178. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/block-size.mdx +190 -0
  179. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-collapse.mdx +181 -0
  180. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-color.mdx +316 -0
  181. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-radius.mdx +347 -0
  182. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-spacing.mdx +117 -0
  183. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-style.mdx +129 -0
  184. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/border-width.mdx +344 -0
  185. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/box-decoration-break.mdx +71 -0
  186. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/box-shadow.mdx +497 -0
  187. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/box-sizing.mdx +175 -0
  188. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/break-after.mdx +38 -0
  189. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/break-before.mdx +38 -0
  190. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/break-inside.mdx +34 -0
  191. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/caption-side.mdx +190 -0
  192. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/caret-color.mdx +66 -0
  193. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/clear.mdx +224 -0
  194. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/color-scheme.mdx +81 -0
  195. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/color.mdx +125 -0
  196. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/colors.mdx +927 -0
  197. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/columns.mdx +310 -0
  198. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/compatibility.mdx +193 -0
  199. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/content.mdx +129 -0
  200. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/cursor.mdx +104 -0
  201. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/dark-mode.mdx +191 -0
  202. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/detecting-classes-in-source-files.mdx +315 -0
  203. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/display.mdx +523 -0
  204. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/editor-setup.mdx +90 -0
  205. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/field-sizing.mdx +75 -0
  206. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/fill.mdx +100 -0
  207. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-blur.mdx +114 -0
  208. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-brightness.mdx +102 -0
  209. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-contrast.mdx +102 -0
  210. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-drop-shadow.mdx +230 -0
  211. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-grayscale.mdx +101 -0
  212. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-hue-rotate.mdx +171 -0
  213. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-invert.mdx +93 -0
  214. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-saturate.mdx +109 -0
  215. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter-sepia.mdx +92 -0
  216. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/filter.mdx +113 -0
  217. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex-basis.mdx +144 -0
  218. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex-direction.mdx +130 -0
  219. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex-grow.mdx +129 -0
  220. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex-shrink.mdx +95 -0
  221. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex-wrap.mdx +118 -0
  222. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/flex.mdx +164 -0
  223. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/float.mdx +197 -0
  224. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-family.mdx +119 -0
  225. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-feature-settings.mdx +52 -0
  226. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-size.mdx +184 -0
  227. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-smoothing.mdx +67 -0
  228. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-stretch.mdx +138 -0
  229. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-style.mdx +62 -0
  230. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-variant-numeric.mdx +228 -0
  231. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/font-weight.mdx +105 -0
  232. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/forced-color-adjust.mdx +152 -0
  233. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/functions-and-directives.mdx +322 -0
  234. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/gap.mdx +100 -0
  235. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-auto-columns.mdx +43 -0
  236. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-auto-flow.mdx +58 -0
  237. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-auto-rows.mdx +43 -0
  238. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-column.mdx +124 -0
  239. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-row.mdx +115 -0
  240. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-template-columns.mdx +101 -0
  241. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/grid-template-rows.mdx +108 -0
  242. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/height.mdx +260 -0
  243. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/hover-focus-and-other-states.mdx +4935 -0
  244. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/hyphens.mdx +112 -0
  245. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/inline-size.mdx +191 -0
  246. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/isolation.mdx +30 -0
  247. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/justify-content.mdx +348 -0
  248. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/justify-items.mdx +286 -0
  249. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/justify-self.mdx +282 -0
  250. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/letter-spacing.mdx +100 -0
  251. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/line-clamp.mdx +110 -0
  252. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/line-height.mdx +147 -0
  253. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/list-style-image.mdx +80 -0
  254. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/list-style-position.mdx +67 -0
  255. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/list-style-type.mdx +86 -0
  256. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/margin.mdx +397 -0
  257. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-clip.mdx +66 -0
  258. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-composite.mdx +70 -0
  259. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-image.mdx +933 -0
  260. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-mode.mdx +114 -0
  261. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-origin.mdx +66 -0
  262. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-position.mdx +117 -0
  263. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-repeat.mdx +169 -0
  264. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-size.mdx +104 -0
  265. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mask-type.mdx +98 -0
  266. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/max-block-size.mdx +153 -0
  267. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/max-height.mdx +164 -0
  268. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/max-inline-size.mdx +185 -0
  269. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/max-width.mdx +214 -0
  270. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/min-block-size.mdx +146 -0
  271. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/min-height.mdx +150 -0
  272. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/min-inline-size.mdx +153 -0
  273. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/min-width.mdx +153 -0
  274. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/mix-blend-mode.mdx +103 -0
  275. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/object-fit.mdx +147 -0
  276. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/object-position.mdx +182 -0
  277. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/opacity.mdx +84 -0
  278. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/order.mdx +94 -0
  279. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/outline-color.mdx +130 -0
  280. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/outline-offset.mdx +72 -0
  281. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/outline-style.mdx +134 -0
  282. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/outline-width.mdx +91 -0
  283. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/overflow-wrap.mdx +130 -0
  284. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/overflow.mdx +665 -0
  285. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/overscroll-behavior.mdx +151 -0
  286. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/padding.mdx +232 -0
  287. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/perspective-origin.mdx +127 -0
  288. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/perspective.mdx +137 -0
  289. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/place-content.mdx +257 -0
  290. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/place-items.mdx +269 -0
  291. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/place-self.mdx +257 -0
  292. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/pointer-events.mdx +101 -0
  293. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/position.mdx +399 -0
  294. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/preflight.mdx +291 -0
  295. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/resize.mdx +110 -0
  296. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/responsive-design.mdx +666 -0
  297. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/rotate.mdx +291 -0
  298. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scale.mdx +360 -0
  299. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-behavior.mdx +39 -0
  300. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-margin.mdx +268 -0
  301. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-padding.mdx +255 -0
  302. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-snap-align.mdx +281 -0
  303. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-snap-stop.mdx +198 -0
  304. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/scroll-snap-type.mdx +284 -0
  305. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/skew.mdx +352 -0
  306. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/stroke-width.mdx +74 -0
  307. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/stroke.mdx +103 -0
  308. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/styling-with-utility-classes.mdx +1020 -0
  309. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/table-layout.mdx +212 -0
  310. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-align.mdx +162 -0
  311. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-decoration-color.mdx +155 -0
  312. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-decoration-line.mdx +143 -0
  313. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-decoration-style.mdx +75 -0
  314. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-decoration-thickness.mdx +75 -0
  315. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-indent.mdx +74 -0
  316. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-overflow.mdx +103 -0
  317. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-shadow.mdx +177 -0
  318. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-transform.mdx +106 -0
  319. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-underline-offset.mdx +74 -0
  320. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/text-wrap.mdx +144 -0
  321. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/theme.mdx +1142 -0
  322. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/top-right-bottom-left.mdx +296 -0
  323. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/touch-action.mdx +95 -0
  324. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transform-origin.mdx +130 -0
  325. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transform-style.mdx +110 -0
  326. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transform.mdx +51 -0
  327. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transition-behavior.mdx +76 -0
  328. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transition-delay.mdx +76 -0
  329. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transition-duration.mdx +82 -0
  330. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transition-property.mdx +137 -0
  331. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/transition-timing-function.mdx +89 -0
  332. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/translate.mdx +487 -0
  333. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/upgrade-guide.mdx +910 -0
  334. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/user-select.mdx +114 -0
  335. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/vertical-align.mdx +194 -0
  336. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/visibility.mdx +287 -0
  337. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/white-space.mdx +211 -0
  338. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/width.mdx +264 -0
  339. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/will-change.mdx +47 -0
  340. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/word-break.mdx +94 -0
  341. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs/z-index.mdx +104 -0
  342. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs-catalog.md +251 -0
  343. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs-index.tsx +237 -0
  344. package/extensions/enact-repo/skills/tailwind-4-docs/references/docs-source.txt +6 -0
  345. package/extensions/enact-repo/skills/tailwind-4-docs/references/gotchas.md +18 -0
  346. package/extensions/enact-repo/skills/tailwind-4-docs/scripts/sync_tailwind_docs.py +183 -0
  347. package/extensions/enact-repo/skills/tdd/SKILL.md +49 -0
  348. package/extensions/enact-repo/skills/tdd/references/mocking.md +59 -0
  349. package/extensions/enact-repo/skills/tdd/references/tests.md +77 -0
  350. package/extensions/enact-repo/skills/teach/SKILL.md +88 -0
  351. package/extensions/enact-repo/skills/teach/references/GLOSSARY-FORMAT.md +35 -0
  352. package/extensions/enact-repo/skills/teach/references/LEARNING-RECORD-FORMAT.md +46 -0
  353. package/extensions/enact-repo/skills/teach/references/MISSION-FORMAT.md +31 -0
  354. package/extensions/enact-repo/skills/teach/references/PHILOSOPHY.md +65 -0
  355. package/extensions/enact-repo/skills/teach/references/RESOURCES-FORMAT.md +32 -0
  356. package/extensions/enact-repo/skills/testing/SKILL.md +54 -0
  357. package/extensions/enact-repo/skills/to-spec/SKILL.md +85 -0
  358. package/extensions/enact-repo/skills/to-tickets/SKILL.md +75 -0
  359. package/extensions/enact-repo/skills/to-tickets/references/TICKET-TEMPLATES.md +39 -0
  360. package/extensions/enact-repo/skills/triage/SKILL.md +99 -0
  361. package/extensions/enact-repo/skills/triage/references/AGENT-BRIEF.md +207 -0
  362. package/extensions/enact-repo/skills/triage/references/NEEDS-INFO-TEMPLATE.md +17 -0
  363. package/extensions/enact-repo/skills/triage/references/OUT-OF-SCOPE.md +105 -0
  364. package/extensions/enact-repo/skills/ui-ux-pro-max/SKILL.md +32 -0
  365. package/extensions/enact-repo/skills/ui-ux-pro-max/references/Workflow.md +207 -0
  366. package/extensions/enact-repo/skills/ui-ux-pro-max/references/workflow-reference.md +175 -0
  367. package/extensions/enact-repo/skills/wayfinder/SKILL.md +100 -0
  368. package/extensions/enact-repo/skills/wayfinder/references/TEMPLATES.md +35 -0
  369. package/extensions/enact-repo/skills/wayfinder/references/TICKET-TYPES.md +8 -0
  370. package/extensions/enact-repo/skills/writing-great-skills/SKILL.md +93 -0
  371. package/extensions/enact-repo/skills/writing-great-skills/references/GLOSSARY.md +201 -0
  372. package/package.json +18 -14
  373. package/scripts/enact-extensions.mjs +255 -878
  374. package/scripts/lib/allowed-plugins.mjs +52 -0
  375. package/scripts/lib/run-repo-doctor.mjs +571 -0
  376. package/scripts/lib/run-repo-install.mjs +1579 -0
  377. package/scripts/lib/run-sync.mjs +1 -1
  378. package/scripts/lib/run-validate.mjs +23 -37
  379. package/scripts/lib/skill-validator.mjs +872 -0
  380. package/spec/enact.json +21 -3
  381. package/spec/enact.md +13 -12
  382. package/spec/kimi.json +100 -0
  383. package/spec/opencode.json +64 -0
  384. package/dist/install.d.ts +0 -235
  385. package/dist/install.d.ts.map +0 -1
  386. package/dist/install.js +0 -697
  387. package/dist/install.js.map +0 -1
  388. package/dist/internal/claude.d.ts +0 -65
  389. package/dist/internal/claude.d.ts.map +0 -1
  390. package/dist/internal/claude.js +0 -200
  391. package/dist/internal/claude.js.map +0 -1
  392. package/dist/internal/codex.d.ts +0 -43
  393. package/dist/internal/codex.d.ts.map +0 -1
  394. package/dist/internal/codex.js +0 -211
  395. package/dist/internal/codex.js.map +0 -1
  396. package/dist/internal/cursor.d.ts +0 -2
  397. package/dist/internal/cursor.d.ts.map +0 -1
  398. package/dist/internal/cursor.js +0 -6
  399. package/dist/internal/cursor.js.map +0 -1
  400. package/dist/principles.d.ts +0 -28
  401. package/dist/principles.d.ts.map +0 -1
  402. package/dist/principles.js +0 -159
  403. package/dist/principles.js.map +0 -1
  404. package/dist/provision.d.ts +0 -30
  405. package/dist/provision.d.ts.map +0 -1
  406. package/dist/provision.js +0 -202
  407. package/dist/provision.js.map +0 -1
  408. package/extensions/dev-state/.agents/plugin.json +0 -36
  409. package/extensions/dev-state/skills/dev-state-plan-graduation/SKILL.md +0 -194
  410. package/extensions/dev-state/skills/dev-state-plan-graduation/agents/openai.yaml +0 -4
  411. package/extensions/dev-state/skills/dev-state-plan-graduation/references/reference.md +0 -130
  412. package/extensions/enact-context/.agents/plugin.json +0 -41
  413. package/extensions/enact-context/.mcp.json +0 -8
  414. package/extensions/enact-context/README.md +0 -25
  415. package/extensions/enact-context/assets/icon.png +0 -0
  416. package/extensions/enact-context/assets/logo.png +0 -0
  417. package/extensions/enact-context/hooks/hooks.json +0 -115
  418. package/extensions/enact-context/skills/enact-context/SKILL.md +0 -151
  419. package/extensions/enact-context/skills/enact-context/scripts/install.sh +0 -69
  420. package/extensions/enact-core/.agents/plugin.json +0 -40
  421. package/extensions/enact-core/OPERATING-PRINCIPLES.md +0 -7
  422. package/extensions/enact-core/hooks/hooks.json +0 -26
  423. package/extensions/enact-evolve/.agents/plugin.json +0 -47
  424. package/extensions/enact-evolve/agents/evolve-session-analyst.toml +0 -37
  425. package/extensions/enact-evolve/assets/icon.png +0 -0
  426. package/extensions/enact-evolve/assets/logo.png +0 -0
  427. package/extensions/enact-evolve/skills/mined-investigate-loop/SKILL.md +0 -68
  428. package/extensions/enact-evolve/skills/session-analysis/SKILL.md +0 -98
  429. package/extensions/enact-evolve/skills/session-analysis/scripts/run-evolve-analysis.sh +0 -343
  430. package/extensions/enact-factory/.agents/plugin.json +0 -49
  431. package/extensions/enact-factory/.mcp.json +0 -8
  432. package/extensions/enact-factory/agents/architect.toml +0 -34
  433. package/extensions/enact-factory/agents/code-reviewer.toml +0 -33
  434. package/extensions/enact-factory/agents/critic.toml +0 -39
  435. package/extensions/enact-factory/agents/executor.toml +0 -26
  436. package/extensions/enact-factory/agents/explore.toml +0 -25
  437. package/extensions/enact-factory/agents/planner.toml +0 -26
  438. package/extensions/enact-factory/agents/verifier.toml +0 -33
  439. package/extensions/enact-factory/assets/icon.png +0 -0
  440. package/extensions/enact-factory/assets/logo.png +0 -0
  441. package/extensions/enact-factory/skills/advisor/SKILL.md +0 -82
  442. package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +0 -57
  443. package/extensions/enact-factory/skills/autonomous-runner/SKILL.md +0 -353
  444. package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +0 -309
  445. package/extensions/enact-factory/skills/azdo-ci-strategy/references/build-failures.md +0 -60
  446. package/extensions/enact-factory/skills/azdo-ci-strategy/references/cli-reference.md +0 -87
  447. package/extensions/enact-factory/skills/azdo-ci-strategy/references/policies-and-pipelines.md +0 -132
  448. package/extensions/enact-factory/skills/azdo-ci-strategy/references/troubleshooting.md +0 -53
  449. package/extensions/enact-factory/skills/cmux-leader/SKILL.md +0 -74
  450. package/extensions/enact-factory/skills/cmux-send/SKILL.md +0 -50
  451. package/extensions/enact-factory/skills/committee/SKILL.md +0 -80
  452. package/extensions/enact-factory/skills/deep-interview/SKILL.md +0 -68
  453. package/extensions/enact-factory/skills/deslop-handover/SKILL.md +0 -97
  454. package/extensions/enact-factory/skills/deslop-handover/deslop.py +0 -181
  455. package/extensions/enact-factory/skills/drive-loop/SKILL.md +0 -394
  456. package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +0 -127
  457. package/extensions/enact-factory/skills/handoff/SKILL.md +0 -75
  458. package/extensions/enact-factory/skills/hyperplan/SKILL.md +0 -59
  459. package/extensions/enact-factory/skills/looplan/SKILL.md +0 -120
  460. package/extensions/enact-factory/skills/paseo-dispatch/SKILL.md +0 -141
  461. package/extensions/enact-factory/skills/plan/SKILL.md +0 -103
  462. package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +0 -46
  463. package/extensions/enact-factory/skills/research/SKILL.md +0 -83
  464. package/extensions/enact-factory/skills/review/SKILL.md +0 -67
  465. package/extensions/enact-factory/skills/security-research/SKILL.md +0 -57
  466. package/extensions/enact-factory/skills/tdd/SKILL.md +0 -62
  467. package/extensions/enact-factory/skills/testing-strategy/SKILL.md +0 -172
  468. package/extensions/enact-factory/skills/trace/SKILL.md +0 -42
  469. package/extensions/enact-factory/skills/ultraqa/SKILL.md +0 -85
  470. package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +0 -56
  471. package/extensions/enact-factory/skills/workitem-triage/SKILL.md +0 -42
  472. package/extensions/enact-wiki/.agents/plugin.json +0 -43
  473. package/extensions/enact-wiki/.mcp.json +0 -15
  474. package/extensions/enact-wiki/README.md +0 -44
  475. package/extensions/enact-wiki/assets/icon.png +0 -0
  476. package/extensions/enact-wiki/assets/logo.png +0 -0
  477. package/extensions/enact-wiki/skills/document-parser/SKILL.md +0 -17
  478. package/extensions/enact-wiki/skills/document-parser/scripts/parse.sh +0 -60
  479. package/extensions/enact-wiki/skills/document-parser/skill.json +0 -9
  480. package/extensions/enact-wiki/skills/enact-wiki/SKILL.md +0 -30
  481. package/extensions/enact-wiki/skills/enact-wiki/references/ingest.md +0 -62
  482. package/extensions/enact-wiki/skills/enact-wiki/references/manage.md +0 -34
  483. package/extensions/enact-wiki/skills/enact-wiki/references/query.md +0 -59
  484. package/extensions/enact-wiki/skills/search-lab/SKILL.md +0 -57
  485. package/extensions/enact-wiki/skills/search-lab/scripts/analyze.ts +0 -23
  486. package/extensions/enact-wiki/skills/wiki/SKILL.md +0 -42
  487. package/extensions/net-revenue-management/.agents/plugin.json +0 -40
  488. package/extensions/net-revenue-management/.mcp.json +0 -9
  489. package/extensions/net-revenue-management/skills/net-revenue-risks/SKILL.md +0 -30
  490. package/extensions/net-revenue-management/skills/net-revenue-scenario/SKILL.md +0 -31
  491. package/extensions/plugin-dev/.agents/plugin.json +0 -41
  492. package/extensions/plugin-dev/agents/agent-creator.md +0 -199
  493. package/extensions/plugin-dev/agents/plugin-validator.md +0 -91
  494. package/extensions/plugin-dev/agents/skill-reviewer.md +0 -212
  495. package/extensions/plugin-dev/skills/agent-development/SKILL.md +0 -641
  496. package/extensions/plugin-dev/skills/agent-development/examples/agent-creation-prompt.md +0 -250
  497. package/extensions/plugin-dev/skills/agent-development/examples/complete-agent-examples.md +0 -461
  498. package/extensions/plugin-dev/skills/agent-development/references/advanced-agent-fields.md +0 -246
  499. package/extensions/plugin-dev/skills/agent-development/references/agent-creation-system-prompt.md +0 -216
  500. package/extensions/plugin-dev/skills/agent-development/references/permission-modes-rules.md +0 -226
  501. package/extensions/plugin-dev/skills/agent-development/references/system-prompt-design.md +0 -464
  502. package/extensions/plugin-dev/skills/agent-development/references/triggering-examples.md +0 -474
  503. package/extensions/plugin-dev/skills/agent-development/scripts/create-agent-skeleton.sh +0 -176
  504. package/extensions/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh +0 -227
  505. package/extensions/plugin-dev/skills/agent-development/scripts/validate-agent.sh +0 -227
  506. package/extensions/plugin-dev/skills/create-plugin/SKILL.md +0 -505
  507. package/extensions/plugin-dev/skills/hook-development/SKILL.md +0 -861
  508. package/extensions/plugin-dev/skills/hook-development/examples/load-context.sh +0 -55
  509. package/extensions/plugin-dev/skills/hook-development/examples/validate-bash.sh +0 -57
  510. package/extensions/plugin-dev/skills/hook-development/examples/validate-write.sh +0 -48
  511. package/extensions/plugin-dev/skills/hook-development/references/advanced.md +0 -871
  512. package/extensions/plugin-dev/skills/hook-development/references/hook-input-schemas.md +0 -145
  513. package/extensions/plugin-dev/skills/hook-development/references/migration.md +0 -392
  514. package/extensions/plugin-dev/skills/hook-development/references/patterns.md +0 -430
  515. package/extensions/plugin-dev/skills/hook-development/scripts/README.md +0 -181
  516. package/extensions/plugin-dev/skills/hook-development/scripts/hook-linter.sh +0 -153
  517. package/extensions/plugin-dev/skills/hook-development/scripts/test-hook.sh +0 -276
  518. package/extensions/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh +0 -159
  519. package/extensions/plugin-dev/skills/mcp-integration/SKILL.md +0 -775
  520. package/extensions/plugin-dev/skills/mcp-integration/examples/http-server.json +0 -20
  521. package/extensions/plugin-dev/skills/mcp-integration/examples/sse-server.json +0 -19
  522. package/extensions/plugin-dev/skills/mcp-integration/examples/stdio-server.json +0 -38
  523. package/extensions/plugin-dev/skills/mcp-integration/examples/ws-server.json +0 -26
  524. package/extensions/plugin-dev/skills/mcp-integration/references/authentication.md +0 -601
  525. package/extensions/plugin-dev/skills/mcp-integration/references/server-discovery.md +0 -190
  526. package/extensions/plugin-dev/skills/mcp-integration/references/server-types.md +0 -572
  527. package/extensions/plugin-dev/skills/mcp-integration/references/tool-usage.md +0 -623
  528. package/extensions/plugin-dev/skills/plugin-dev-guide/SKILL.md +0 -221
  529. package/extensions/plugin-dev/skills/plugin-structure/SKILL.md +0 -705
  530. package/extensions/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md +0 -774
  531. package/extensions/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md +0 -83
  532. package/extensions/plugin-dev/skills/plugin-structure/examples/standard-plugin.md +0 -611
  533. package/extensions/plugin-dev/skills/plugin-structure/references/advanced-topics.md +0 -289
  534. package/extensions/plugin-dev/skills/plugin-structure/references/component-patterns.md +0 -592
  535. package/extensions/plugin-dev/skills/plugin-structure/references/github-actions.md +0 -233
  536. package/extensions/plugin-dev/skills/plugin-structure/references/headless-ci-mode.md +0 -193
  537. package/extensions/plugin-dev/skills/plugin-structure/references/manifest-reference.md +0 -625
  538. package/extensions/plugin-dev/skills/plugin-structure/references/output-styles.md +0 -116
  539. package/extensions/plugin-dev/skills/skill-development/SKILL.md +0 -562
  540. package/extensions/plugin-dev/skills/skill-development/examples/complete-skill.md +0 -465
  541. package/extensions/plugin-dev/skills/skill-development/examples/frontmatter-templates.md +0 -167
  542. package/extensions/plugin-dev/skills/skill-development/examples/minimal-skill.md +0 -111
  543. package/extensions/plugin-dev/skills/skill-development/references/advanced-frontmatter.md +0 -225
  544. package/extensions/plugin-dev/skills/skill-development/references/commands-vs-skills.md +0 -39
  545. package/extensions/plugin-dev/skills/skill-development/references/skill-creation-workflow.md +0 -379
  546. package/extensions/plugin-dev/skills/skill-development/references/skill-creator-original.md +0 -210
  547. package/extensions/plugin-dev/skills/start/SKILL.md +0 -82
  548. package/scripts/check-hooks.mjs +0 -174
  549. package/scripts/check-principles.mjs +0 -116
  550. package/scripts/hooks/session-start-drift-check.mjs +0 -49
  551. package/scripts/install.sh +0 -70
  552. package/scripts/lib/auto-update.mjs +0 -88
  553. package/scripts/lib/bundle-hash.mjs +0 -137
  554. package/scripts/lib/hooks.mjs +0 -585
  555. package/scripts/lib/ledger.mjs +0 -163
  556. package/scripts/lib/migrate-artifacts.mjs +0 -144
  557. package/scripts/lib/outdated.mjs +0 -144
  558. package/scripts/lib/postinstall-offer.mjs +0 -83
  559. package/scripts/lib/principles.mjs +0 -109
  560. package/scripts/lib/provision-mcp.mjs +0 -16
  561. package/scripts/lib/resolve-plugin-root.mjs +0 -9
  562. package/scripts/lib/run-install.mjs +0 -507
  563. package/scripts/lib/run-prune.mjs +0 -94
  564. package/scripts/lib/run-uninstall.mjs +0 -244
  565. package/scripts/lib/run-update.mjs +0 -165
  566. package/scripts/lib/serve.mjs +0 -472
  567. package/scripts/lib/ups-router.mjs +0 -392
  568. package/scripts/postinstall.mjs +0 -101
  569. package/scripts/setup-enact-context.sh +0 -28
  570. package/scripts/version-bump.sh +0 -484
  571. package/web/assets/README.md +0 -111
  572. package/web/assets/logo-full.png +0 -0
  573. package/web/assets/logo-slim.png +0 -0
  574. package/web/assets/tokens/base.css +0 -45
  575. package/web/assets/tokens/colors.css +0 -248
  576. package/web/assets/tokens/effects.css +0 -24
  577. package/web/assets/tokens/fonts.css +0 -8
  578. package/web/assets/tokens/index.css +0 -18
  579. package/web/assets/tokens/spacing.css +0 -50
  580. package/web/index.html +0 -1188
@@ -0,0 +1,696 @@
1
+ import { MANIFEST_FIELDS } from "../internal/platform.js";
2
+ import { pickManifestFields, withPlatformKeyword } from "../internal/pick.js";
3
+ import { withHostFlag } from "../internal/hooks.js";
4
+ // ---------------------------------------------------------------------------
5
+ // OpenCode manifest descriptor (DERIVERS entry)
6
+ // ---------------------------------------------------------------------------
7
+ /**
8
+ * Derive the OpenCode descriptor (`.opencode-plugin/plugin.json`) from the
9
+ * canonical Enact manifest. OpenCode has no documented plugin manifest file of
10
+ * its own — this descriptor is Enact-internal bookkeeping (validated by
11
+ * spec/opencode.json) that records project metadata plus the canonical
12
+ * `hooks`/`mcpServers` SOURCE PATHS (not their resolved content). A future
13
+ * installer reads those paths, loads the referenced JSON, and calls
14
+ * {@link deriveOpenCodeMcp} / {@link deriveOpenCodePlugin} to generate the
15
+ * real OpenCode artifacts: a root `opencode.json` MCP fragment and a
16
+ * `.opencode/plugins/<name>.ts` file.
17
+ */
18
+ export function deriveOpenCodeManifest(enact) {
19
+ const picked = pickManifestFields(enact, MANIFEST_FIELDS.opencode);
20
+ return {
21
+ ...picked,
22
+ description: (typeof picked.description === "string" ? picked.description : undefined) ??
23
+ `${enact.name} plugin for OpenCode.`,
24
+ keywords: withPlatformKeyword(Array.isArray(picked.keywords) ? picked.keywords : undefined, "opencode"),
25
+ };
26
+ }
27
+ /**
28
+ * Project a canonical `.mcp.json` document
29
+ * (`{mcpServers:{name:{command,args,env,cwd?}}}`) into OpenCode's root
30
+ * `opencode.json` MCP fragment.
31
+ *
32
+ * Source (verified 2026-09-14, this session): https://opencode.ai/docs —
33
+ * OpenCode MCP servers are declared directly under `"mcp"` in `opencode.json`
34
+ * as `{"<name>": {"type":"local", "command":["cmd", ...args],
35
+ * "environment": {...}, "cwd": "...", "enabled": true}}`. There is no
36
+ * `servers` wrapper (unlike the canonical `mcpServers` key) and no `disabled`
37
+ * key — OpenCode uses `enabled` and we always emit `enabled: true` for a
38
+ * server the canonical manifest declares (a disabled server simply would not
39
+ * be declared).
40
+ *
41
+ * Servers without a `command` (e.g. a remote/HTTP-only definition) have no
42
+ * documented OpenCode "local" equivalent here and are skipped rather than
43
+ * guessed at.
44
+ */
45
+ export function deriveOpenCodeMcp(canonicalMcp) {
46
+ const doc = canonicalMcp && typeof canonicalMcp === "object" && !Array.isArray(canonicalMcp)
47
+ ? canonicalMcp
48
+ : {};
49
+ const servers = doc.mcpServers && typeof doc.mcpServers === "object" && !Array.isArray(doc.mcpServers)
50
+ ? doc.mcpServers
51
+ : {};
52
+ const mcp = {};
53
+ for (const [name, def] of Object.entries(servers)) {
54
+ if (!def || typeof def !== "object" || Array.isArray(def))
55
+ continue;
56
+ const command = typeof def.command === "string" ? def.command : undefined;
57
+ if (!command)
58
+ continue;
59
+ const args = Array.isArray(def.args) ? def.args.map((a) => String(a)) : [];
60
+ const entry = {
61
+ type: "local",
62
+ command: [command, ...args],
63
+ enabled: true,
64
+ };
65
+ if (def.env && typeof def.env === "object" && !Array.isArray(def.env)) {
66
+ const environment = {};
67
+ for (const [k, v] of Object.entries(def.env)) {
68
+ environment[k] = String(v);
69
+ }
70
+ entry.environment = environment;
71
+ }
72
+ if (typeof def.cwd === "string" && def.cwd.trim()) {
73
+ entry.cwd = def.cwd;
74
+ }
75
+ mcp[name] = entry;
76
+ }
77
+ return { mcp };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // OpenCode hooks + MCP + skills -> ONE project plugin
81
+ // ---------------------------------------------------------------------------
82
+ //
83
+ // Owner decision (Tarun, 2026-09-14): OpenCode output is a SINGLE real plugin
84
+ // (`.opencode/plugins/<name>.ts`) that carries hooks, MCP servers AND skills
85
+ // together — not three separate artifacts. This reflects live evidence
86
+ // gathered against a real OpenCode 1.18.29 install (see
87
+ // .scratch/opencode-plugin-example/ and .scratch/opencode-probe/ in this
88
+ // repo) plus the official @opencode-ai/plugin `Hooks` interface:
89
+ //
90
+ // - `config(input)` mutation adds `mcp` servers and `skills.paths` —
91
+ // confirmed via `opencode debug config` / `opencode mcp list` /
92
+ // `opencode debug skill` against a live install. A same-named MCP server
93
+ // already present in the user's config is left untouched (skip + log to
94
+ // stderr) — user config survives.
95
+ // - `session.created` / `session.idle` are NOT top-level Hooks keys (an
96
+ // earlier version of this generator emitted them as top-level object
97
+ // keys, which never fired — a real bug the current tests catch). They
98
+ // only arrive via the generic `event({event})` hook, dispatched on
99
+ // `event.type`.
100
+ // - Pushing a synthetic text part onto `chat.message`'s `output.parts` was
101
+ // tried and PASSED without throwing, but broke every subsequent real
102
+ // `opencode run` call with `UnknownError: Unexpected server error` (live
103
+ // A/B evidence, .scratch/opencode-probe/log.jsonl). Context injection
104
+ // instead: `chat.message` runs the UserPromptSubmit command and stores
105
+ // its context keyed by `input.sessionID`; `experimental.chat.system.transform`
106
+ // (confirmed firing on every request, carrying `sessionID`) appends that
107
+ // stored context to `output.system` for the MATCHING session only.
108
+ // - `tool.execute.before` (throw to block) / `tool.execute.after` are real
109
+ // top-level keys, live-confirmed to block a bash call.
110
+ // - Plugin root is resolved from the `directory` the OpenCode runtime
111
+ // passes into the plugin factory (the project root) — never from
112
+ // `${CLAUDE_PLUGIN_ROOT}`, which OpenCode does not set.
113
+ //
114
+ // Event mapping (table-driven, same pattern as CURSOR_HOOK_EVENT_MAP in
115
+ // src/internal/agents.ts). The map value is either a literal OpenCode Hooks
116
+ // key ("tool.execute.before", "chat.message", ...) or, for the two events
117
+ // that only exist as `event.type` values, a synthetic "event:<type>" key
118
+ // meaning "dispatched inside the shared `event` hook when event.type equals
119
+ // <type>":
120
+ //
121
+ // PreToolUse -> tool.execute.before (throw to block; deny contract below)
122
+ // PostToolUse -> tool.execute.after (cannot block: the call already ran)
123
+ // UserPromptSubmit -> chat.message (+ experimental.chat.system.transform
124
+ // pairing — see context-injection
125
+ // note above; this used to fall
126
+ // back onto SessionStart because no
127
+ // direct equivalent was known. It
128
+ // is now a NATIVE mapping.)
129
+ // SessionStart -> event:session.created
130
+ // SessionIdle -> event:session.idle
131
+ // PreCompact -> experimental.session.compacting
132
+ //
133
+ // Left UNMAPPED on purpose (never invented — surfaced as `warnings` instead):
134
+ // - Stop: no documented "main agent turn finished" event distinct from
135
+ // session.idle (which already covers SessionIdle).
136
+ // - SubagentStart / SubagentStop: no documented subagent lifecycle hook.
137
+ //
138
+ // Fallback (owner rule, Tarun): when a host has no equivalent of a canonical
139
+ // event, its hooks run on a documented substitute event instead:
140
+ // - SessionEnd -> SessionIdle: OpenCode has no session-end event, so
141
+ // canonical SessionEnd hooks run on `event:session.idle` (folded into the
142
+ // same bucket as native SessionIdle hooks, running after them, each
143
+ // command still carrying its own `fallback_for: "SessionEnd"` tag).
144
+ // Accepted consequence: they fire after every response, not only at true
145
+ // session end.
146
+ const OPENCODE_HOOK_EVENT_MAP = {
147
+ PreToolUse: "tool.execute.before",
148
+ PostToolUse: "tool.execute.after",
149
+ UserPromptSubmit: "chat.message",
150
+ SessionStart: "event:session.created",
151
+ SessionIdle: "event:session.idle",
152
+ PreCompact: "experimental.session.compacting",
153
+ };
154
+ /**
155
+ * Table-driven fallback for canonical events with no documented OpenCode
156
+ * equivalent of their own.
157
+ *
158
+ * - SessionEnd -> SessionIdle (owner rule, Tarun): OpenCode has no
159
+ * session-end event, so canonical SessionEnd hooks run on SessionIdle
160
+ * instead — attaching to the `event:session.idle` bucket. Accepted
161
+ * consequence: they fire after every response, not only at true session
162
+ * end.
163
+ *
164
+ * Fallback commands run AFTER any native commands already targeting that
165
+ * same bucket, each still honoring its own `timeout`. The stdin payload for a
166
+ * fallback command stays truthful about which event actually fired
167
+ * (`hook_event_name` is the FALLBACK TARGET's canonical name) plus
168
+ * `fallback_for` naming the originating canonical event — and never
169
+ * fabricates fields that don't exist for the target event.
170
+ */
171
+ const OPENCODE_HOOK_EVENT_FALLBACK = {
172
+ SessionEnd: "SessionIdle",
173
+ };
174
+ /** OpenCode Hooks keys whose handler receives the tool call as `(input, output)`. */
175
+ const OPENCODE_TOOL_EVENTS = new Set(["tool.execute.before", "tool.execute.after"]);
176
+ /**
177
+ * Canonical (Claude-style, cross-host) tool-name token -> real OpenCode tool
178
+ * id. Canonical `hooks.json` matchers (see
179
+ * `extensions/enact-repo/hooks/hooks.json`) are written in Claude's
180
+ * PascalCase vocabulary plus a handful of other hosts' own names
181
+ * (`str_replace_editor` is Codex's editor tool, `edit_file` is Cursor's,
182
+ * `create_file`/`write_file` appear in some agent SDKs) -- none of which
183
+ * match OpenCode's OWN tool ids.
184
+ *
185
+ * Source of truth: live `GET /experimental/tool/ids` against a real
186
+ * `opencode serve` 1.18.18 instance (verified 2026-09-14, this session,
187
+ * `.scratch/toolid-probe/`), which returned exactly:
188
+ * ["invalid","question","bash","read","glob","grep","edit","write","task",
189
+ * "webfetch","todowrite","websearch","skill","apply_patch"]
190
+ * Notably: OpenCode tool ids are lowercase and single-word; there is no
191
+ * "list" tool, and the apply-a-raw-patch tool is "apply_patch", not "patch".
192
+ */
193
+ const CANONICAL_TO_OPENCODE_TOOL = {
194
+ bash: "bash",
195
+ shell: "bash",
196
+ read: "read",
197
+ write: "write",
198
+ writefile: "write",
199
+ write_file: "write",
200
+ createfile: "write",
201
+ create_file: "write",
202
+ edit: "edit",
203
+ multiedit: "edit",
204
+ strreplace: "edit",
205
+ str_replace: "edit",
206
+ str_replace_editor: "edit",
207
+ edit_file: "edit",
208
+ replace_in_file: "edit",
209
+ grep: "grep",
210
+ glob: "glob",
211
+ webfetch: "webfetch",
212
+ websearch: "websearch",
213
+ todowrite: "todowrite",
214
+ task: "task",
215
+ skill: "skill",
216
+ apply_patch: "apply_patch",
217
+ patch: "apply_patch",
218
+ question: "question",
219
+ };
220
+ /**
221
+ * Project a canonical matcher (e.g. `"Bash"`, or
222
+ * `"Write|Edit|MultiEdit|StrReplace|str_replace_editor|..."`) into an
223
+ * OpenCode-tool-id alternation (e.g. `"bash"`, `"write|edit"`), deduping
224
+ * repeated targets. A token with no known canonical mapping is kept
225
+ * (lowercased) as a passthrough rather than dropped -- combined with the
226
+ * case-insensitive ANCHORED matching {@link emitToolMethod} generates, this
227
+ * is a safety net that still matches an already-OpenCode-shaped or unknown
228
+ * matcher instead of silently never firing.
229
+ */
230
+ export function projectMatcherToOpenCode(matcher) {
231
+ const tokens = matcher
232
+ .split("|")
233
+ .map((t) => t.trim())
234
+ .filter(Boolean);
235
+ const projected = [];
236
+ for (const token of tokens) {
237
+ const key = token.toLowerCase().replace(/[^a-z0-9_]/g, "");
238
+ const mapped = CANONICAL_TO_OPENCODE_TOOL[key] ?? token.toLowerCase();
239
+ if (!projected.includes(mapped))
240
+ projected.push(mapped);
241
+ }
242
+ return projected.join("|");
243
+ }
244
+ function asCanonicalHooksDoc(canonicalHooks) {
245
+ if (!canonicalHooks || typeof canonicalHooks !== "object")
246
+ return {};
247
+ const doc = canonicalHooks;
248
+ return doc.hooks && typeof doc.hooks === "object" && !Array.isArray(doc.hooks) ? doc.hooks : {};
249
+ }
250
+ function flattenCanonicalEvent(entries, fallbackFor) {
251
+ if (!Array.isArray(entries))
252
+ return [];
253
+ const flat = [];
254
+ for (const entry of entries) {
255
+ const matcher = typeof entry.matcher === "string" && entry.matcher.trim() ? entry.matcher : undefined;
256
+ for (const inner of entry.hooks ?? []) {
257
+ const command = typeof inner.command === "string" ? inner.command : undefined;
258
+ if (!command)
259
+ continue;
260
+ const flatCommand = { command: withHostFlag(command, "opencode") };
261
+ if (matcher)
262
+ flatCommand.matcher = projectMatcherToOpenCode(matcher);
263
+ if (typeof inner.timeout === "number" && Number.isFinite(inner.timeout)) {
264
+ flatCommand.timeoutMs = Math.round(inner.timeout * 1000);
265
+ }
266
+ if (fallbackFor)
267
+ flatCommand.fallbackFor = fallbackFor;
268
+ flat.push(flatCommand);
269
+ }
270
+ }
271
+ return flat;
272
+ }
273
+ /**
274
+ * Return canonical hook events that declare active commands but have no
275
+ * documented OpenCode equivalent in {@link OPENCODE_HOOK_EVENT_MAP} AND no
276
+ * entry in {@link OPENCODE_HOOK_EVENT_FALLBACK} (a fallback-projected event
277
+ * is not "unmapped" — see {@link fallbackOpenCodeHookEvents}).
278
+ */
279
+ export function unmappedOpenCodeHookEvents(canonicalHooks) {
280
+ const sourceHooks = asCanonicalHooksDoc(canonicalHooks);
281
+ const unmapped = [];
282
+ for (const [event, entries] of Object.entries(sourceHooks)) {
283
+ if (OPENCODE_HOOK_EVENT_MAP[event])
284
+ continue;
285
+ if (OPENCODE_HOOK_EVENT_FALLBACK[event])
286
+ continue;
287
+ if (flattenCanonicalEvent(entries).length > 0)
288
+ unmapped.push(event);
289
+ }
290
+ return unmapped;
291
+ }
292
+ /**
293
+ * Return the canonical hook events projected via
294
+ * {@link OPENCODE_HOOK_EVENT_FALLBACK} that declare active commands — e.g.
295
+ * `[{from:"SessionEnd", to:"SessionIdle"}]`. These are NOT reported by
296
+ * {@link unmappedOpenCodeHookEvents}: they run, just on a substitute event.
297
+ */
298
+ export function fallbackOpenCodeHookEvents(canonicalHooks) {
299
+ const sourceHooks = asCanonicalHooksDoc(canonicalHooks);
300
+ const fallbacks = [];
301
+ for (const [from, to] of Object.entries(OPENCODE_HOOK_EVENT_FALLBACK)) {
302
+ if (flattenCanonicalEvent(sourceHooks[from]).length > 0)
303
+ fallbacks.push({ from, to });
304
+ }
305
+ return fallbacks;
306
+ }
307
+ function toIdentifier(pluginName) {
308
+ const parts = pluginName.split(/[^a-zA-Z0-9]+/).filter(Boolean);
309
+ if (parts.length === 0)
310
+ return "plugin";
311
+ const [first, ...rest] = parts;
312
+ return (first.toLowerCase() +
313
+ rest.map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join(""));
314
+ }
315
+ function emitCommandArray(name, commands) {
316
+ const lines = commands.map((c) => {
317
+ const fields = [`command: ${JSON.stringify(c.command)}`];
318
+ if (c.matcher)
319
+ fields.push(`matcher: ${JSON.stringify(c.matcher)}`);
320
+ if (c.timeoutMs !== undefined)
321
+ fields.push(`timeoutMs: ${c.timeoutMs}`);
322
+ if (c.fallbackFor)
323
+ fields.push(`fallbackFor: ${JSON.stringify(c.fallbackFor)}`);
324
+ return ` { ${fields.join(", ")} },`;
325
+ });
326
+ return `const ${name}: HookCommandSpec[] = [\n${lines.join("\n")}\n];`;
327
+ }
328
+ function emitConfigMethod(hasMcp, hasSkills) {
329
+ const mcpBlock = hasMcp
330
+ ? ` input.mcp = input.mcp || {};
331
+ for (const [name, def] of Object.entries(CONFIG_MCP_SERVERS)) {
332
+ if (Object.prototype.hasOwnProperty.call(input.mcp, name)) {
333
+ // OpenCode re-invokes config() on every config reload. If WE added
334
+ // this server on a previous call, seeing it again here is not a
335
+ // real conflict -- do not warn about our own injection. Only a
336
+ // same-named entry this plugin never added is a genuine
337
+ // user-defined conflict worth logging.
338
+ if (!enactInjectedMcpServers.has(name)) {
339
+ console.error("[" + PLUGIN_NAME + "] config: mcp server " + name + " already defined in user config -- skipping");
340
+ }
341
+ continue;
342
+ }
343
+ input.mcp[name] = def;
344
+ enactInjectedMcpServers.add(name);
345
+ }`
346
+ : "";
347
+ const skillsBlock = hasSkills
348
+ ? ` input.skills = input.skills || {};
349
+ input.skills.paths = Array.isArray(input.skills.paths) ? input.skills.paths : [];
350
+ const skillsDirAbs = join(directory, CONFIG_SKILLS_DIR);
351
+ if (!input.skills.paths.includes(skillsDirAbs)) {
352
+ input.skills.paths.push(skillsDirAbs);
353
+ }`
354
+ : "";
355
+ const body = [mcpBlock, skillsBlock].filter(Boolean).join("\n");
356
+ return ` async config(input: any) {
357
+ ${body}
358
+ },`;
359
+ }
360
+ function emitChatMessageMethod(constName) {
361
+ return ` "chat.message": async (input: any, output: any) => {
362
+ const parts = output && Array.isArray(output.parts) ? output.parts : [];
363
+ const promptText = parts.filter((p: any) => p && p.type === "text").map((p: any) => p.text).join(" ");
364
+ let context: string | undefined;
365
+ for (const spec of ${constName}) {
366
+ const payload = {
367
+ hook_event_name: "UserPromptSubmit",
368
+ prompt: promptText,
369
+ cwd: directory,
370
+ session_id: input && input.sessionID,
371
+ };
372
+ const result = await runHookCommand(spec, payload, directory);
373
+ const extracted = extractHookContext(result);
374
+ if (extracted) context = context ? context + " " + extracted : extracted;
375
+ }
376
+ const sessionID = input && input.sessionID;
377
+ if (sessionID) {
378
+ if (context) enactPromptContext.set(sessionID, context);
379
+ else enactPromptContext.delete(sessionID);
380
+ }
381
+ },`;
382
+ }
383
+ function emitChatSystemTransformMethod() {
384
+ return ` "experimental.chat.system.transform": async (input: any, output: any) => {
385
+ const sessionID = input && input.sessionID;
386
+ if (!sessionID) return;
387
+ const context = enactPromptContext.get(sessionID);
388
+ if (context && output && Array.isArray(output.system)) {
389
+ output.system.push(context);
390
+ }
391
+ },`;
392
+ }
393
+ function emitToolMethod(opencodeEvent, constName, canonicalEvent, canBlock) {
394
+ return ` ${JSON.stringify(opencodeEvent)}: async (input: ToolHookInput, output: ToolHookOutput) => {
395
+ for (const spec of ${constName}) {
396
+ if (spec.matcher && !new RegExp("^(?:" + spec.matcher + ")$", "i").test(input.tool)) continue;
397
+ const payload = {
398
+ hook_event_name: ${JSON.stringify(canonicalEvent)},
399
+ tool_name: input.tool,
400
+ tool_input: output.args,
401
+ cwd: directory,
402
+ session_id: input.sessionID,
403
+ };
404
+ const result = await runHookCommand(spec, payload, directory);
405
+ ${canBlock ? "const reason = denyReason(result);\n if (reason) throw new Error(reason);" : "// PostToolUse cannot block: the tool call already completed."}
406
+ }
407
+ },`;
408
+ }
409
+ function emitEventMethod(hasCreated, hasIdle, createdConstName, idleConstName) {
410
+ const createdBlock = hasCreated
411
+ ? ` if (event && event.type === "session.created") {
412
+ for (const spec of ${createdConstName}) {
413
+ const payload = {
414
+ hook_event_name: "SessionStart",
415
+ cwd: directory,
416
+ session_id: event.properties && (event.properties.sessionID || (event.properties.info && event.properties.info.id)),
417
+ };
418
+ await runHookCommand(spec, payload, directory);
419
+ }
420
+ }`
421
+ : "";
422
+ const idleBlock = hasIdle
423
+ ? ` if (event && event.type === "session.idle") {
424
+ for (const spec of ${idleConstName}) {
425
+ const payload = {
426
+ hook_event_name: "SessionIdle",
427
+ cwd: directory,
428
+ session_id: event.properties && (event.properties.sessionID || (event.properties.info && event.properties.info.id)),
429
+ ...(spec.fallbackFor ? { fallback_for: spec.fallbackFor } : {}),
430
+ };
431
+ await runHookCommand(spec, payload, directory);
432
+ }
433
+ }`
434
+ : "";
435
+ const body = [createdBlock, idleBlock].filter(Boolean).join("\n");
436
+ return ` event: async ({ event }: { event: any }) => {
437
+ ${body}
438
+ },`;
439
+ }
440
+ function emitCompactingMethod(constName) {
441
+ return ` "experimental.session.compacting": async (input: any) => {
442
+ for (const spec of ${constName}) {
443
+ const payload = {
444
+ hook_event_name: "PreCompact",
445
+ cwd: directory,
446
+ session_id: input && input.sessionID,
447
+ };
448
+ await runHookCommand(spec, payload, directory);
449
+ }
450
+ },`;
451
+ }
452
+ /**
453
+ * Generate the TypeScript source for a SINGLE OpenCode project plugin
454
+ * (`.opencode/plugins/<pluginName>.ts`) that carries a bundle's hooks, MCP
455
+ * servers AND skills together — see the module-level owner-decision comment
456
+ * above for the live-evidence basis of every mapping choice below.
457
+ *
458
+ * Runtime choice: OpenCode plugins run on Bun. This generated file uses
459
+ * `Bun.spawn` rather than the Bun Shell `$` helper because `Bun.spawn` has a
460
+ * documented `timeout` + `killSignal` option
461
+ * (https://bun.com/docs/api/spawn, verified 2026-09-14) needed to honor each
462
+ * canonical hook command's `timeout` (seconds), and gives direct access to
463
+ * `stdin`, `exitCode`, `stdout`/`stderr` text.
464
+ *
465
+ * Truthful failures: a hook command that crashes (e.g. `Bun.spawn` itself
466
+ * throws) or exits non-zero for a reason other than a PreToolUse deny is
467
+ * logged to stderr with the plugin's name — never silently swallowed, and
468
+ * never treated as a block (fail open). The PreToolUse deny throw itself
469
+ * happens OUTSIDE any try/catch in the generated code, so it can never be
470
+ * caught and swallowed by error handling elsewhere in the same method.
471
+ *
472
+ * PreToolUse (`tool.execute.before`) deny contract: the configured command
473
+ * receives `{hook_event_name, tool_name, tool_input, cwd, session_id}` as
474
+ * JSON on stdin. The call is blocked (the generated hook throws) when the
475
+ * command exits with code 2, or its stdout parses as JSON with
476
+ * `hookSpecificOutput.permissionDecision === "deny"`.
477
+ *
478
+ * UserPromptSubmit (`chat.message` + `experimental.chat.system.transform`):
479
+ * the configured command receives `{hook_event_name:"UserPromptSubmit",
480
+ * prompt, cwd, session_id}` as JSON on stdin. Its `hookSpecificOutput.additionalContext`
481
+ * (or, failing that, its raw stdout) is stored keyed by session id and
482
+ * injected into `output.system` the next time `experimental.chat.system.transform`
483
+ * fires for that same session — see the module comment for why this replaced
484
+ * a direct `output.parts` push.
485
+ *
486
+ * Canonical events with no documented OpenCode equivalent and no fallback are
487
+ * NOT wired into any hook; call {@link unmappedOpenCodeHookEvents} to get
488
+ * that list. Events projected via {@link OPENCODE_HOOK_EVENT_FALLBACK} (e.g.
489
+ * SessionEnd -> SessionIdle) ARE wired in, under their fallback target's
490
+ * bucket; call {@link fallbackOpenCodeHookEvents} to get that list.
491
+ */
492
+ export function deriveOpenCodePlugin(source, pluginName) {
493
+ const sourceHooks = asCanonicalHooksDoc(source?.hooks);
494
+ // Keyed by the OpenCode Hooks method this bucket attaches to (or, for
495
+ // SessionStart/SessionIdle, the synthetic "event:<event.type>" dispatch
496
+ // key), but each entry keeps the ORIGINATING canonical event name too: the
497
+ // JSON payload's `hook_event_name` must stay the canonical PascalCase name
498
+ // (PreToolUse, SessionStart, ...) so a command written against the
499
+ // canonical hook contract (Claude/Codex/Cursor-style) sees the name it
500
+ // expects, not OpenCode's own event naming.
501
+ const byOpenCodeEvent = new Map();
502
+ for (const [canonicalEvent, opencodeEvent] of Object.entries(OPENCODE_HOOK_EVENT_MAP)) {
503
+ const flat = flattenCanonicalEvent(sourceHooks[canonicalEvent]);
504
+ if (flat.length > 0)
505
+ byOpenCodeEvent.set(opencodeEvent, { canonicalEvent, commands: flat });
506
+ }
507
+ // Fold fallback-projected events (OPENCODE_HOOK_EVENT_FALLBACK) into their
508
+ // target's bucket, AFTER any native commands already collected above, so
509
+ // e.g. SessionEnd commands run after native SessionIdle commands under the
510
+ // same "event:session.idle" bucket.
511
+ for (const [fallbackEvent, targetCanonicalEvent] of Object.entries(OPENCODE_HOOK_EVENT_FALLBACK)) {
512
+ const opencodeEvent = OPENCODE_HOOK_EVENT_MAP[targetCanonicalEvent];
513
+ if (!opencodeEvent)
514
+ continue; // defensive: fallback target must itself be a mapped event
515
+ const flat = flattenCanonicalEvent(sourceHooks[fallbackEvent], fallbackEvent);
516
+ if (flat.length === 0)
517
+ continue;
518
+ const existing = byOpenCodeEvent.get(opencodeEvent);
519
+ if (existing) {
520
+ existing.commands = [...existing.commands, ...flat];
521
+ }
522
+ else {
523
+ byOpenCodeEvent.set(opencodeEvent, { canonicalEvent: targetCanonicalEvent, commands: flat });
524
+ }
525
+ }
526
+ const warnings = unmappedOpenCodeHookEvents(source?.hooks);
527
+ const fallbacks = fallbackOpenCodeHookEvents(source?.hooks);
528
+ const identifier = toIdentifier(pluginName);
529
+ const mcpAdditions = deriveOpenCodeMcp(source?.mcpServers).mcp;
530
+ const hasMcp = Object.keys(mcpAdditions).length > 0;
531
+ const skillsDir = typeof source?.skillsDir === "string" && source.skillsDir.trim() ? source.skillsDir : undefined;
532
+ const hasConfig = hasMcp || Boolean(skillsDir);
533
+ const hasChatMessage = byOpenCodeEvent.has("chat.message");
534
+ const hasToolBefore = byOpenCodeEvent.has("tool.execute.before");
535
+ const hasToolAfter = byOpenCodeEvent.has("tool.execute.after");
536
+ const hasSessionCreated = byOpenCodeEvent.has("event:session.created");
537
+ const hasSessionIdle = byOpenCodeEvent.has("event:session.idle");
538
+ const hasEvent = hasSessionCreated || hasSessionIdle;
539
+ const hasCompacting = byOpenCodeEvent.has("experimental.session.compacting");
540
+ const hasAnyHookExec = hasChatMessage || hasToolBefore || hasToolAfter || hasEvent || hasCompacting;
541
+ const isEmpty = !hasConfig && !hasAnyHookExec;
542
+ const constNameFor = (key) => `HOOKS_${key.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}`;
543
+ const constDecls = [];
544
+ for (const [key, { commands }] of byOpenCodeEvent.entries()) {
545
+ constDecls.push(emitCommandArray(constNameFor(key), commands));
546
+ }
547
+ if (hasMcp) {
548
+ constDecls.push(`const CONFIG_MCP_SERVERS: Record<string, any> = ${JSON.stringify(mcpAdditions, null, 2)};`);
549
+ // Tracks MCP server names THIS plugin instance has injected into
550
+ // input.mcp, across repeated config() calls (OpenCode re-invokes
551
+ // config() on every config reload) -- see emitConfigMethod.
552
+ constDecls.push(`const enactInjectedMcpServers = new Set<string>();`);
553
+ }
554
+ if (skillsDir) {
555
+ constDecls.push(`const CONFIG_SKILLS_DIR = ${JSON.stringify(skillsDir)};`);
556
+ }
557
+ const methods = [];
558
+ if (hasConfig)
559
+ methods.push(emitConfigMethod(hasMcp, Boolean(skillsDir)));
560
+ if (hasChatMessage) {
561
+ methods.push(emitChatMessageMethod(constNameFor("chat.message")));
562
+ methods.push(emitChatSystemTransformMethod());
563
+ }
564
+ if (hasToolBefore) {
565
+ methods.push(emitToolMethod("tool.execute.before", constNameFor("tool.execute.before"), byOpenCodeEvent.get("tool.execute.before").canonicalEvent, true));
566
+ }
567
+ if (hasToolAfter) {
568
+ methods.push(emitToolMethod("tool.execute.after", constNameFor("tool.execute.after"), byOpenCodeEvent.get("tool.execute.after").canonicalEvent, false));
569
+ }
570
+ if (hasEvent) {
571
+ methods.push(emitEventMethod(hasSessionCreated, hasSessionIdle, constNameFor("event:session.created"), constNameFor("event:session.idle")));
572
+ }
573
+ if (hasCompacting)
574
+ methods.push(emitCompactingMethod(constNameFor("experimental.session.compacting")));
575
+ const warningsComment = warnings.length > 0
576
+ ? `//\n// Unmapped canonical events with active commands (no documented OpenCode\n// equivalent — see OPENCODE_HOOK_EVENT_MAP in src/create/opencode.ts):\n${warnings.map((w) => `// - ${w}`).join("\n")}\n`
577
+ : "";
578
+ const fallbackComment = fallbacks.length > 0
579
+ ? `//\n// Projected via fallback (owner rule: an event with no documented OpenCode\n// equivalent runs on a substitute event instead — see\n// OPENCODE_HOOK_EVENT_FALLBACK in src/create/opencode.ts):\n${fallbacks.map((f) => `// - ${f.from} -> ${f.to}`).join("\n")}\n`
580
+ : "";
581
+ // `join` is only actually referenced by the skills.paths block, not by the
582
+ // MCP block, so import it only when a skills dir was provided.
583
+ const importsBlock = skillsDir ? `import { join } from "node:path";\n\n` : "";
584
+ // PLUGIN_NAME is referenced both by config()'s same-named-server skip log
585
+ // and by runHookCommand's truthful-failure logging -- emit it whenever
586
+ // EITHER needs it, not only when hooks execute (a config-only plugin, with
587
+ // MCP servers but no hooks, still needs it for the skip log).
588
+ const needsPluginName = hasMcp || hasAnyHookExec;
589
+ const pluginNameConst = needsPluginName ? `const PLUGIN_NAME = ${JSON.stringify(pluginName)};\n\n` : "";
590
+ const sharedHelpers = hasAnyHookExec
591
+ ? `async function runHookCommand(
592
+ spec: HookCommandSpec,
593
+ payload: Record<string, unknown>,
594
+ cwd: string,
595
+ ): Promise<{ exitCode: number | null; stdout: string; stderr: string }> {
596
+ try {
597
+ const proc = Bun.spawn(["/bin/sh", "-c", spec.command], {
598
+ cwd,
599
+ stdin: "pipe",
600
+ stdout: "pipe",
601
+ stderr: "pipe",
602
+ ...(spec.timeoutMs ? { timeout: spec.timeoutMs, killSignal: "SIGTERM" } : {}),
603
+ });
604
+ proc.stdin.write(JSON.stringify(payload));
605
+ proc.stdin.end();
606
+ const [stdout, stderr] = await Promise.all([
607
+ new Response(proc.stdout).text(),
608
+ new Response(proc.stderr).text(),
609
+ ]);
610
+ await proc.exited;
611
+ if (proc.exitCode !== 0 && proc.exitCode !== 2) {
612
+ console.error("[" + PLUGIN_NAME + "] hook command exited " + proc.exitCode + ": " + spec.command);
613
+ }
614
+ return { exitCode: proc.exitCode, stdout, stderr };
615
+ } catch (err) {
616
+ const message = err instanceof Error ? err.message : String(err);
617
+ console.error("[" + PLUGIN_NAME + "] hook command crashed: " + spec.command + " -- " + message);
618
+ return { exitCode: null, stdout: "", stderr: message };
619
+ }
620
+ }
621
+ `
622
+ : "";
623
+ const denyHelper = hasToolBefore
624
+ ? `
625
+ function denyReason(result: { exitCode: number | null; stdout: string; stderr: string }): string | undefined {
626
+ if (result.exitCode === 2) {
627
+ return result.stderr.trim() || "PreToolUse hook denied the call (exit code 2)";
628
+ }
629
+ try {
630
+ const parsed = JSON.parse(result.stdout) as {
631
+ hookSpecificOutput?: { permissionDecision?: string; permissionDecisionReason?: string };
632
+ };
633
+ if (parsed?.hookSpecificOutput?.permissionDecision === "deny") {
634
+ return parsed.hookSpecificOutput.permissionDecisionReason || "PreToolUse hook denied the call";
635
+ }
636
+ } catch {
637
+ // stdout was not JSON -- not a deny signal.
638
+ }
639
+ return undefined;
640
+ }
641
+ `
642
+ : "";
643
+ const chatContextHelper = hasChatMessage
644
+ ? `
645
+ const enactPromptContext = new Map<string, string>();
646
+
647
+ function extractHookContext(result: { exitCode: number | null; stdout: string; stderr: string }): string | undefined {
648
+ const trimmed = result.stdout.trim();
649
+ if (!trimmed) return undefined;
650
+ try {
651
+ const parsed = JSON.parse(trimmed) as { hookSpecificOutput?: { additionalContext?: string } };
652
+ const additional = parsed?.hookSpecificOutput?.additionalContext;
653
+ if (typeof additional === "string" && additional.trim()) {
654
+ return additional.trim();
655
+ }
656
+ } catch {
657
+ // stdout was not JSON -- treat it as plain-text context.
658
+ }
659
+ return trimmed;
660
+ }
661
+ `
662
+ : "";
663
+ return `// AUTO-GENERATED by enact-extensions (deriveOpenCodePlugin). Do not edit by hand.
664
+ // Source: canonical hooks.json + .mcp.json + skills dir -> ONE OpenCode project plugin.
665
+ ${warningsComment}${fallbackComment}
666
+ ${importsBlock}interface HookCommandSpec {
667
+ command: string;
668
+ matcher?: string;
669
+ timeoutMs?: number;
670
+ fallbackFor?: string;
671
+ }
672
+
673
+ interface ToolHookInput {
674
+ tool: string;
675
+ sessionID?: string;
676
+ callID?: string;
677
+ }
678
+
679
+ interface ToolHookOutput {
680
+ args: Record<string, unknown>;
681
+ }
682
+
683
+ ${constDecls.join("\n\n") || "// No canonical hook event maps to a documented OpenCode hook for this plugin, and no MCP servers or skills dir were provided."}
684
+
685
+ ${pluginNameConst}
686
+ ${sharedHelpers}${denyHelper}${chatContextHelper}
687
+ export const ${identifier}Plugin = async ({ directory }: { directory: string }) => {
688
+ return {
689
+ ${methods.join("\n") || " // No mapped hooks."}
690
+ };
691
+ };
692
+
693
+ export default ${identifier}Plugin;
694
+ `;
695
+ }
696
+ //# sourceMappingURL=opencode.js.map