@w3kits-com/plugin-opendesign 0.1.8 → 0.1.9

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 (1706) hide show
  1. package/dist/404/index.html +1 -1
  2. package/dist/404.html +1 -1
  3. package/dist/__next.$oc$slug.__PAGE__.txt +1 -1
  4. package/dist/__next.$oc$slug.txt +1 -1
  5. package/dist/__next._full.txt +1 -1
  6. package/dist/__next._head.txt +1 -1
  7. package/dist/__next._index.txt +1 -1
  8. package/dist/__next._tree.txt +1 -1
  9. package/dist/__w3kits/assets/design-systems/README.md +103 -0
  10. package/dist/__w3kits/assets/design-systems/_schema/AGENTS.md +179 -0
  11. package/dist/__w3kits/assets/design-systems/_schema/defaults.css +100 -0
  12. package/dist/__w3kits/assets/design-systems/_schema/tokens.schema.ts +275 -0
  13. package/dist/__w3kits/assets/design-systems/agentic/DESIGN.md +71 -0
  14. package/dist/__w3kits/assets/design-systems/airbnb/DESIGN.md +393 -0
  15. package/dist/__w3kits/assets/design-systems/airbnb/components.html +1373 -0
  16. package/dist/__w3kits/assets/design-systems/airbnb/tokens.css +261 -0
  17. package/dist/__w3kits/assets/design-systems/airtable/DESIGN.md +92 -0
  18. package/dist/__w3kits/assets/design-systems/ant/DESIGN.md +71 -0
  19. package/dist/__w3kits/assets/design-systems/apple/DESIGN.md +250 -0
  20. package/dist/__w3kits/assets/design-systems/apple/components.html +749 -0
  21. package/dist/__w3kits/assets/design-systems/apple/tokens.css +286 -0
  22. package/dist/__w3kits/assets/design-systems/application/DESIGN.md +71 -0
  23. package/dist/__w3kits/assets/design-systems/arc/DESIGN.md +152 -0
  24. package/dist/__w3kits/assets/design-systems/artistic/DESIGN.md +71 -0
  25. package/dist/__w3kits/assets/design-systems/atelier-zero/DESIGN.md +316 -0
  26. package/dist/__w3kits/assets/design-systems/bento/DESIGN.md +71 -0
  27. package/dist/__w3kits/assets/design-systems/binance/DESIGN.md +348 -0
  28. package/dist/__w3kits/assets/design-systems/bmw/DESIGN.md +183 -0
  29. package/dist/__w3kits/assets/design-systems/bmw-m/DESIGN.md +246 -0
  30. package/dist/__w3kits/assets/design-systems/bold/DESIGN.md +71 -0
  31. package/dist/__w3kits/assets/design-systems/brutalism/DESIGN.md +71 -0
  32. package/dist/__w3kits/assets/design-systems/bugatti/DESIGN.md +271 -0
  33. package/dist/__w3kits/assets/design-systems/cafe/DESIGN.md +71 -0
  34. package/dist/__w3kits/assets/design-systems/cal/DESIGN.md +262 -0
  35. package/dist/__w3kits/assets/design-systems/canva/DESIGN.md +157 -0
  36. package/dist/__w3kits/assets/design-systems/cisco/DESIGN.md +201 -0
  37. package/dist/__w3kits/assets/design-systems/claude/DESIGN.md +315 -0
  38. package/dist/__w3kits/assets/design-systems/clay/DESIGN.md +307 -0
  39. package/dist/__w3kits/assets/design-systems/claymorphism/DESIGN.md +71 -0
  40. package/dist/__w3kits/assets/design-systems/clean/DESIGN.md +71 -0
  41. package/dist/__w3kits/assets/design-systems/clickhouse/DESIGN.md +284 -0
  42. package/dist/__w3kits/assets/design-systems/cohere/DESIGN.md +269 -0
  43. package/dist/__w3kits/assets/design-systems/coinbase/DESIGN.md +132 -0
  44. package/dist/__w3kits/assets/design-systems/colorful/DESIGN.md +71 -0
  45. package/dist/__w3kits/assets/design-systems/composio/DESIGN.md +310 -0
  46. package/dist/__w3kits/assets/design-systems/contemporary/DESIGN.md +71 -0
  47. package/dist/__w3kits/assets/design-systems/corporate/DESIGN.md +71 -0
  48. package/dist/__w3kits/assets/design-systems/cosmic/DESIGN.md +71 -0
  49. package/dist/__w3kits/assets/design-systems/creative/DESIGN.md +71 -0
  50. package/dist/__w3kits/assets/design-systems/cursor/DESIGN.md +312 -0
  51. package/dist/__w3kits/assets/design-systems/cursor/components.html +654 -0
  52. package/dist/__w3kits/assets/design-systems/cursor/tokens.css +218 -0
  53. package/dist/__w3kits/assets/design-systems/dashboard/DESIGN.md +71 -0
  54. package/dist/__w3kits/assets/design-systems/default/DESIGN.md +62 -0
  55. package/dist/__w3kits/assets/design-systems/default/components.html +523 -0
  56. package/dist/__w3kits/assets/design-systems/default/tokens.css +200 -0
  57. package/dist/__w3kits/assets/design-systems/discord/DESIGN.md +162 -0
  58. package/dist/__w3kits/assets/design-systems/discord/components.html +359 -0
  59. package/dist/__w3kits/assets/design-systems/discord/tokens.css +125 -0
  60. package/dist/__w3kits/assets/design-systems/dithered/DESIGN.md +71 -0
  61. package/dist/__w3kits/assets/design-systems/doodle/DESIGN.md +71 -0
  62. package/dist/__w3kits/assets/design-systems/dramatic/DESIGN.md +71 -0
  63. package/dist/__w3kits/assets/design-systems/duolingo/DESIGN.md +154 -0
  64. package/dist/__w3kits/assets/design-systems/editorial/DESIGN.md +71 -0
  65. package/dist/__w3kits/assets/design-systems/elegant/DESIGN.md +71 -0
  66. package/dist/__w3kits/assets/design-systems/elevenlabs/DESIGN.md +268 -0
  67. package/dist/__w3kits/assets/design-systems/energetic/DESIGN.md +72 -0
  68. package/dist/__w3kits/assets/design-systems/enterprise/DESIGN.md +71 -0
  69. package/dist/__w3kits/assets/design-systems/expo/DESIGN.md +284 -0
  70. package/dist/__w3kits/assets/design-systems/expressive/DESIGN.md +71 -0
  71. package/dist/__w3kits/assets/design-systems/fantasy/DESIGN.md +71 -0
  72. package/dist/__w3kits/assets/design-systems/ferrari/DESIGN.md +317 -0
  73. package/dist/__w3kits/assets/design-systems/figma/DESIGN.md +223 -0
  74. package/dist/__w3kits/assets/design-systems/figma/components.html +344 -0
  75. package/dist/__w3kits/assets/design-systems/figma/tokens.css +126 -0
  76. package/dist/__w3kits/assets/design-systems/flat/DESIGN.md +71 -0
  77. package/dist/__w3kits/assets/design-systems/framer/DESIGN.md +249 -0
  78. package/dist/__w3kits/assets/design-systems/friendly/DESIGN.md +71 -0
  79. package/dist/__w3kits/assets/design-systems/futuristic/DESIGN.md +71 -0
  80. package/dist/__w3kits/assets/design-systems/github/DESIGN.md +155 -0
  81. package/dist/__w3kits/assets/design-systems/github/components.html +383 -0
  82. package/dist/__w3kits/assets/design-systems/github/tokens.css +125 -0
  83. package/dist/__w3kits/assets/design-systems/glassmorphism/DESIGN.md +71 -0
  84. package/dist/__w3kits/assets/design-systems/gradient/DESIGN.md +71 -0
  85. package/dist/__w3kits/assets/design-systems/hashicorp/DESIGN.md +281 -0
  86. package/dist/__w3kits/assets/design-systems/hud/DESIGN.md +173 -0
  87. package/dist/__w3kits/assets/design-systems/huggingface/DESIGN.md +149 -0
  88. package/dist/__w3kits/assets/design-systems/ibm/DESIGN.md +335 -0
  89. package/dist/__w3kits/assets/design-systems/intercom/DESIGN.md +149 -0
  90. package/dist/__w3kits/assets/design-systems/kami/DESIGN.md +410 -0
  91. package/dist/__w3kits/assets/design-systems/kami/components.html +601 -0
  92. package/dist/__w3kits/assets/design-systems/kami/tokens.css +272 -0
  93. package/dist/__w3kits/assets/design-systems/kraken/DESIGN.md +128 -0
  94. package/dist/__w3kits/assets/design-systems/lamborghini/DESIGN.md +291 -0
  95. package/dist/__w3kits/assets/design-systems/levels/DESIGN.md +71 -0
  96. package/dist/__w3kits/assets/design-systems/linear-app/DESIGN.md +370 -0
  97. package/dist/__w3kits/assets/design-systems/linear-app/components.html +370 -0
  98. package/dist/__w3kits/assets/design-systems/linear-app/tokens.css +130 -0
  99. package/dist/__w3kits/assets/design-systems/lingo/DESIGN.md +71 -0
  100. package/dist/__w3kits/assets/design-systems/loom/DESIGN.md +201 -0
  101. package/dist/__w3kits/assets/design-systems/lovable/DESIGN.md +301 -0
  102. package/dist/__w3kits/assets/design-systems/luxury/DESIGN.md +71 -0
  103. package/dist/__w3kits/assets/design-systems/mastercard/DESIGN.md +368 -0
  104. package/dist/__w3kits/assets/design-systems/material/DESIGN.md +71 -0
  105. package/dist/__w3kits/assets/design-systems/meta/DESIGN.md +369 -0
  106. package/dist/__w3kits/assets/design-systems/minimal/DESIGN.md +71 -0
  107. package/dist/__w3kits/assets/design-systems/minimax/DESIGN.md +260 -0
  108. package/dist/__w3kits/assets/design-systems/mintlify/DESIGN.md +329 -0
  109. package/dist/__w3kits/assets/design-systems/miro/DESIGN.md +111 -0
  110. package/dist/__w3kits/assets/design-systems/mission-control/DESIGN.md +474 -0
  111. package/dist/__w3kits/assets/design-systems/mistral-ai/DESIGN.md +264 -0
  112. package/dist/__w3kits/assets/design-systems/modern/DESIGN.md +71 -0
  113. package/dist/__w3kits/assets/design-systems/mongodb/DESIGN.md +269 -0
  114. package/dist/__w3kits/assets/design-systems/mono/DESIGN.md +71 -0
  115. package/dist/__w3kits/assets/design-systems/neobrutalism/DESIGN.md +71 -0
  116. package/dist/__w3kits/assets/design-systems/neon/DESIGN.md +71 -0
  117. package/dist/__w3kits/assets/design-systems/neumorphism/DESIGN.md +71 -0
  118. package/dist/__w3kits/assets/design-systems/nike/DESIGN.md +366 -0
  119. package/dist/__w3kits/assets/design-systems/notion/DESIGN.md +312 -0
  120. package/dist/__w3kits/assets/design-systems/notion/components.html +413 -0
  121. package/dist/__w3kits/assets/design-systems/notion/tokens.css +130 -0
  122. package/dist/__w3kits/assets/design-systems/nvidia/DESIGN.md +296 -0
  123. package/dist/__w3kits/assets/design-systems/ollama/DESIGN.md +270 -0
  124. package/dist/__w3kits/assets/design-systems/openai/DESIGN.md +140 -0
  125. package/dist/__w3kits/assets/design-systems/openai/components.html +382 -0
  126. package/dist/__w3kits/assets/design-systems/openai/tokens.css +133 -0
  127. package/dist/__w3kits/assets/design-systems/opencode-ai/DESIGN.md +284 -0
  128. package/dist/__w3kits/assets/design-systems/pacman/DESIGN.md +71 -0
  129. package/dist/__w3kits/assets/design-systems/paper/DESIGN.md +71 -0
  130. package/dist/__w3kits/assets/design-systems/perspective/DESIGN.md +71 -0
  131. package/dist/__w3kits/assets/design-systems/pinterest/DESIGN.md +233 -0
  132. package/dist/__w3kits/assets/design-systems/playstation/DESIGN.md +367 -0
  133. package/dist/__w3kits/assets/design-systems/posthog/DESIGN.md +259 -0
  134. package/dist/__w3kits/assets/design-systems/premium/DESIGN.md +71 -0
  135. package/dist/__w3kits/assets/design-systems/professional/DESIGN.md +71 -0
  136. package/dist/__w3kits/assets/design-systems/publication/DESIGN.md +71 -0
  137. package/dist/__w3kits/assets/design-systems/raycast/DESIGN.md +271 -0
  138. package/dist/__w3kits/assets/design-systems/refined/DESIGN.md +71 -0
  139. package/dist/__w3kits/assets/design-systems/renault/DESIGN.md +314 -0
  140. package/dist/__w3kits/assets/design-systems/replicate/DESIGN.md +264 -0
  141. package/dist/__w3kits/assets/design-systems/resend/DESIGN.md +306 -0
  142. package/dist/__w3kits/assets/design-systems/retro/DESIGN.md +71 -0
  143. package/dist/__w3kits/assets/design-systems/revolut/DESIGN.md +188 -0
  144. package/dist/__w3kits/assets/design-systems/runwayml/DESIGN.md +247 -0
  145. package/dist/__w3kits/assets/design-systems/sanity/DESIGN.md +360 -0
  146. package/dist/__w3kits/assets/design-systems/sentry/DESIGN.md +265 -0
  147. package/dist/__w3kits/assets/design-systems/shadcn/DESIGN.md +71 -0
  148. package/dist/__w3kits/assets/design-systems/shopify/DESIGN.md +353 -0
  149. package/dist/__w3kits/assets/design-systems/shopify/components.html +342 -0
  150. package/dist/__w3kits/assets/design-systems/shopify/tokens.css +141 -0
  151. package/dist/__w3kits/assets/design-systems/simple/DESIGN.md +71 -0
  152. package/dist/__w3kits/assets/design-systems/skeumorphism/DESIGN.md +71 -0
  153. package/dist/__w3kits/assets/design-systems/slack/DESIGN.md +363 -0
  154. package/dist/__w3kits/assets/design-systems/slack/components.html +387 -0
  155. package/dist/__w3kits/assets/design-systems/slack/tokens.css +127 -0
  156. package/dist/__w3kits/assets/design-systems/sleek/DESIGN.md +71 -0
  157. package/dist/__w3kits/assets/design-systems/spacex/DESIGN.md +197 -0
  158. package/dist/__w3kits/assets/design-systems/spacious/DESIGN.md +71 -0
  159. package/dist/__w3kits/assets/design-systems/spotify/DESIGN.md +249 -0
  160. package/dist/__w3kits/assets/design-systems/spotify/components.html +365 -0
  161. package/dist/__w3kits/assets/design-systems/spotify/tokens.css +127 -0
  162. package/dist/__w3kits/assets/design-systems/starbucks/DESIGN.md +583 -0
  163. package/dist/__w3kits/assets/design-systems/storytelling/DESIGN.md +71 -0
  164. package/dist/__w3kits/assets/design-systems/stripe/DESIGN.md +325 -0
  165. package/dist/__w3kits/assets/design-systems/stripe/components.html +1018 -0
  166. package/dist/__w3kits/assets/design-systems/stripe/tokens.css +295 -0
  167. package/dist/__w3kits/assets/design-systems/supabase/DESIGN.md +258 -0
  168. package/dist/__w3kits/assets/design-systems/superhuman/DESIGN.md +255 -0
  169. package/dist/__w3kits/assets/design-systems/tesla/DESIGN.md +289 -0
  170. package/dist/__w3kits/assets/design-systems/tetris/DESIGN.md +71 -0
  171. package/dist/__w3kits/assets/design-systems/theverge/DESIGN.md +342 -0
  172. package/dist/__w3kits/assets/design-systems/together-ai/DESIGN.md +266 -0
  173. package/dist/__w3kits/assets/design-systems/totality-festival/DESIGN.md +206 -0
  174. package/dist/__w3kits/assets/design-systems/trading-terminal/DESIGN.md +178 -0
  175. package/dist/__w3kits/assets/design-systems/uber/DESIGN.md +298 -0
  176. package/dist/__w3kits/assets/design-systems/uber/components.html +347 -0
  177. package/dist/__w3kits/assets/design-systems/uber/tokens.css +131 -0
  178. package/dist/__w3kits/assets/design-systems/urdu/DESIGN.md +1002 -0
  179. package/dist/__w3kits/assets/design-systems/vercel/DESIGN.md +313 -0
  180. package/dist/__w3kits/assets/design-systems/vercel/components.html +839 -0
  181. package/dist/__w3kits/assets/design-systems/vercel/tokens.css +270 -0
  182. package/dist/__w3kits/assets/design-systems/vibrant/DESIGN.md +71 -0
  183. package/dist/__w3kits/assets/design-systems/vintage/DESIGN.md +71 -0
  184. package/dist/__w3kits/assets/design-systems/vodafone/DESIGN.md +426 -0
  185. package/dist/__w3kits/assets/design-systems/voltagent/DESIGN.md +326 -0
  186. package/dist/__w3kits/assets/design-systems/warm-editorial/DESIGN.md +65 -0
  187. package/dist/__w3kits/assets/design-systems/warp/DESIGN.md +256 -0
  188. package/dist/__w3kits/assets/design-systems/webex/DESIGN.md +207 -0
  189. package/dist/__w3kits/assets/design-systems/webflow/DESIGN.md +95 -0
  190. package/dist/__w3kits/assets/design-systems/wechat/DESIGN.md +302 -0
  191. package/dist/__w3kits/assets/design-systems/wired/DESIGN.md +281 -0
  192. package/dist/__w3kits/assets/design-systems/wise/DESIGN.md +176 -0
  193. package/dist/__w3kits/assets/design-systems/x-ai/DESIGN.md +260 -0
  194. package/dist/__w3kits/assets/design-systems/xiaohongshu/DESIGN.md +402 -0
  195. package/dist/__w3kits/assets/design-systems/zapier/DESIGN.md +331 -0
  196. package/dist/__w3kits/assets/design-templates/AGENTS.md +34 -0
  197. package/dist/__w3kits/assets/design-templates/audio-jingle/SKILL.md +132 -0
  198. package/dist/__w3kits/assets/design-templates/audio-jingle/example.html +128 -0
  199. package/dist/__w3kits/assets/design-templates/blog-post/SKILL.md +81 -0
  200. package/dist/__w3kits/assets/design-templates/blog-post/example.html +80 -0
  201. package/dist/__w3kits/assets/design-templates/clinical-case-report/SKILL.md +209 -0
  202. package/dist/__w3kits/assets/design-templates/clinical-case-report/example.html +698 -0
  203. package/dist/__w3kits/assets/design-templates/clinical-case-report/examples/example-stemi.html +698 -0
  204. package/dist/__w3kits/assets/design-templates/clinical-case-report/references/case-formats.md +94 -0
  205. package/dist/__w3kits/assets/design-templates/clinical-case-report/references/checklist.md +41 -0
  206. package/dist/__w3kits/assets/design-templates/critique/SKILL.md +258 -0
  207. package/dist/__w3kits/assets/design-templates/critique/example.html +671 -0
  208. package/dist/__w3kits/assets/design-templates/dashboard/SKILL.md +76 -0
  209. package/dist/__w3kits/assets/design-templates/dashboard/example.html +118 -0
  210. package/dist/__w3kits/assets/design-templates/dating-web/SKILL.md +93 -0
  211. package/dist/__w3kits/assets/design-templates/dating-web/example.html +265 -0
  212. package/dist/__w3kits/assets/design-templates/dcf-valuation/SKILL.md +140 -0
  213. package/dist/__w3kits/assets/design-templates/dcf-valuation/references/sector-wacc.md +42 -0
  214. package/dist/__w3kits/assets/design-templates/digital-eguide/SKILL.md +95 -0
  215. package/dist/__w3kits/assets/design-templates/digital-eguide/example.html +204 -0
  216. package/dist/__w3kits/assets/design-templates/docs-page/SKILL.md +80 -0
  217. package/dist/__w3kits/assets/design-templates/docs-page/example.html +122 -0
  218. package/dist/__w3kits/assets/design-templates/email-marketing/SKILL.md +85 -0
  219. package/dist/__w3kits/assets/design-templates/email-marketing/example.html +159 -0
  220. package/dist/__w3kits/assets/design-templates/eng-runbook/SKILL.md +51 -0
  221. package/dist/__w3kits/assets/design-templates/eng-runbook/example.html +250 -0
  222. package/dist/__w3kits/assets/design-templates/finance-report/SKILL.md +62 -0
  223. package/dist/__w3kits/assets/design-templates/finance-report/example.html +242 -0
  224. package/dist/__w3kits/assets/design-templates/flowai-live-dashboard-template/SKILL.md +87 -0
  225. package/dist/__w3kits/assets/design-templates/flowai-live-dashboard-template/assets/template.html +387 -0
  226. package/dist/__w3kits/assets/design-templates/flowai-live-dashboard-template/example.html +13 -0
  227. package/dist/__w3kits/assets/design-templates/flowai-live-dashboard-template/references/checklist.md +35 -0
  228. package/dist/__w3kits/assets/design-templates/gamified-app/SKILL.md +109 -0
  229. package/dist/__w3kits/assets/design-templates/gamified-app/example.html +292 -0
  230. package/dist/__w3kits/assets/design-templates/github-dashboard/SKILL.md +130 -0
  231. package/dist/__w3kits/assets/design-templates/github-dashboard/example.html +473 -0
  232. package/dist/__w3kits/assets/design-templates/github-dashboard/references/README.md +10 -0
  233. package/dist/__w3kits/assets/design-templates/github-dashboard/references/artifact-example.json +15 -0
  234. package/dist/__w3kits/assets/design-templates/github-dashboard/references/example-data.json +138 -0
  235. package/dist/__w3kits/assets/design-templates/github-dashboard/references/provenance-example.json +92 -0
  236. package/dist/__w3kits/assets/design-templates/github-dashboard/references/template.html +473 -0
  237. package/dist/__w3kits/assets/design-templates/guizang-ppt/LICENSE +21 -0
  238. package/dist/__w3kits/assets/design-templates/guizang-ppt/README.en.md +119 -0
  239. package/dist/__w3kits/assets/design-templates/guizang-ppt/README.md +120 -0
  240. package/dist/__w3kits/assets/design-templates/guizang-ppt/README.pt-BR.md +121 -0
  241. package/dist/__w3kits/assets/design-templates/guizang-ppt/SKILL.md +314 -0
  242. package/dist/__w3kits/assets/design-templates/guizang-ppt/assets/example-slides.html +318 -0
  243. package/dist/__w3kits/assets/design-templates/guizang-ppt/assets/template.html +647 -0
  244. package/dist/__w3kits/assets/design-templates/guizang-ppt/references/checklist.md +265 -0
  245. package/dist/__w3kits/assets/design-templates/guizang-ppt/references/components.md +363 -0
  246. package/dist/__w3kits/assets/design-templates/guizang-ppt/references/layouts.md +630 -0
  247. package/dist/__w3kits/assets/design-templates/guizang-ppt/references/styles.md +195 -0
  248. package/dist/__w3kits/assets/design-templates/guizang-ppt/references/themes.md +122 -0
  249. package/dist/__w3kits/assets/design-templates/hr-onboarding/SKILL.md +52 -0
  250. package/dist/__w3kits/assets/design-templates/hr-onboarding/example.html +219 -0
  251. package/dist/__w3kits/assets/design-templates/html-ppt/.clawscan-allow +12 -0
  252. package/dist/__w3kits/assets/design-templates/html-ppt/LICENSE +21 -0
  253. package/dist/__w3kits/assets/design-templates/html-ppt/README.md +234 -0
  254. package/dist/__w3kits/assets/design-templates/html-ppt/README.pt-BR.md +239 -0
  255. package/dist/__w3kits/assets/design-templates/html-ppt/README.zh-CN.md +238 -0
  256. package/dist/__w3kits/assets/design-templates/html-ppt/SKILL.md +251 -0
  257. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/animations.css +138 -0
  258. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/_util.js +63 -0
  259. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/chain-react.js +41 -0
  260. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/confetti-cannon.js +49 -0
  261. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/constellation.js +44 -0
  262. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/counter-explosion.js +58 -0
  263. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/data-stream.js +45 -0
  264. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/firework.js +51 -0
  265. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/galaxy-swirl.js +33 -0
  266. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/gradient-blob.js +39 -0
  267. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/knowledge-graph.js +69 -0
  268. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/letter-explode.js +50 -0
  269. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/magnetic-field.js +40 -0
  270. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/matrix-rain.js +33 -0
  271. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/neural-net.js +75 -0
  272. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/orbit-ring.js +38 -0
  273. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/particle-burst.js +42 -0
  274. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/shockwave.js +39 -0
  275. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/sparkle-trail.js +62 -0
  276. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/starfield.js +30 -0
  277. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/typewriter-multi.js +51 -0
  278. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx/word-cascade.js +47 -0
  279. package/dist/__w3kits/assets/design-templates/html-ppt/assets/animations/fx-runtime.js +99 -0
  280. package/dist/__w3kits/assets/design-templates/html-ppt/assets/base.css +150 -0
  281. package/dist/__w3kits/assets/design-templates/html-ppt/assets/fonts.css +9 -0
  282. package/dist/__w3kits/assets/design-templates/html-ppt/assets/runtime.js +960 -0
  283. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/academic-paper.css +23 -0
  284. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/arctic-cool.css +14 -0
  285. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/aurora.css +20 -0
  286. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/bauhaus.css +16 -0
  287. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/blueprint.css +19 -0
  288. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/catppuccin-latte.css +14 -0
  289. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/catppuccin-mocha.css +14 -0
  290. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/corporate-clean.css +19 -0
  291. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/cyberpunk-neon.css +23 -0
  292. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/dracula.css +14 -0
  293. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/editorial-serif.css +18 -0
  294. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/engineering-whiteprint.css +26 -0
  295. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/glassmorphism.css +21 -0
  296. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/gruvbox-dark.css +14 -0
  297. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/japanese-minimal.css +21 -0
  298. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/magazine-bold.css +21 -0
  299. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/memphis-pop.css +20 -0
  300. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/midcentury.css +19 -0
  301. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/minimal-white.css +16 -0
  302. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/neo-brutalism.css +17 -0
  303. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/news-broadcast.css +20 -0
  304. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/nord.css +14 -0
  305. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/pitch-deck-vc.css +21 -0
  306. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/rainbow-gradient.css +16 -0
  307. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/retro-tv.css +22 -0
  308. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/rose-pine.css +14 -0
  309. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/sharp-mono.css +17 -0
  310. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/soft-pastel.css +14 -0
  311. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/solarized-light.css +14 -0
  312. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/sunset-warm.css +14 -0
  313. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/swiss-grid.css +17 -0
  314. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/terminal-green.css +18 -0
  315. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/tokyo-night.css +14 -0
  316. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/vaporwave.css +21 -0
  317. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/xiaohongshu-white.css +16 -0
  318. package/dist/__w3kits/assets/design-templates/html-ppt/assets/themes/y2k-chrome.css +20 -0
  319. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/_theme-cell.html +56 -0
  320. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/animations.png +0 -0
  321. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/hero.gif +0 -0
  322. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/layouts-live.gif +0 -0
  323. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/layouts.png +0 -0
  324. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/montage-animations.html +61 -0
  325. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/montage-layouts.html +72 -0
  326. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/montage-templates.html +72 -0
  327. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/montage-themes.html +38 -0
  328. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/presenter-mode.png +0 -0
  329. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/templates.png +0 -0
  330. package/dist/__w3kits/assets/design-templates/html-ppt/docs/readme/themes.png +0 -0
  331. package/dist/__w3kits/assets/design-templates/html-ppt/examples/demo-deck/index.html +161 -0
  332. package/dist/__w3kits/assets/design-templates/html-ppt/references/animations.md +147 -0
  333. package/dist/__w3kits/assets/design-templates/html-ppt/references/authoring-guide.md +141 -0
  334. package/dist/__w3kits/assets/design-templates/html-ppt/references/full-decks.md +98 -0
  335. package/dist/__w3kits/assets/design-templates/html-ppt/references/layouts.md +103 -0
  336. package/dist/__w3kits/assets/design-templates/html-ppt/references/presenter-mode.md +240 -0
  337. package/dist/__w3kits/assets/design-templates/html-ppt/references/themes.md +107 -0
  338. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/new-deck.sh +46 -0
  339. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/render.sh +71 -0
  340. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_01.png +0 -0
  341. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_02.png +0 -0
  342. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_03.png +0 -0
  343. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_04.png +0 -0
  344. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_05.png +0 -0
  345. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_06.png +0 -0
  346. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_07.png +0 -0
  347. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_08.png +0 -0
  348. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_09.png +0 -0
  349. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_10.png +0 -0
  350. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_11.png +0 -0
  351. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_12.png +0 -0
  352. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_13.png +0 -0
  353. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_14.png +0 -0
  354. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_15.png +0 -0
  355. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_16.png +0 -0
  356. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_17.png +0 -0
  357. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_18.png +0 -0
  358. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_19.png +0 -0
  359. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/animation-showcase/animation-showcase_20.png +0 -0
  360. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_01.png +0 -0
  361. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_02.png +0 -0
  362. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_03.png +0 -0
  363. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_04.png +0 -0
  364. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_05.png +0 -0
  365. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_06.png +0 -0
  366. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_07.png +0 -0
  367. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_08.png +0 -0
  368. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_09.png +0 -0
  369. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_10.png +0 -0
  370. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_11.png +0 -0
  371. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_12.png +0 -0
  372. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_13.png +0 -0
  373. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_14.png +0 -0
  374. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_15.png +0 -0
  375. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_16.png +0 -0
  376. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_17.png +0 -0
  377. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_18.png +0 -0
  378. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_19.png +0 -0
  379. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_20.png +0 -0
  380. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_21.png +0 -0
  381. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_22.png +0 -0
  382. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_23.png +0 -0
  383. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_24.png +0 -0
  384. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_25.png +0 -0
  385. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_26.png +0 -0
  386. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_27.png +0 -0
  387. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_28.png +0 -0
  388. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_29.png +0 -0
  389. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_30.png +0 -0
  390. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_31.png +0 -0
  391. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_32.png +0 -0
  392. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_33.png +0 -0
  393. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_34.png +0 -0
  394. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_35.png +0 -0
  395. package/dist/__w3kits/assets/design-templates/html-ppt/scripts/verify-output/theme-showcase/theme-showcase_36.png +0 -0
  396. package/dist/__w3kits/assets/design-templates/html-ppt/templates/animation-showcase.html +172 -0
  397. package/dist/__w3kits/assets/design-templates/html-ppt/templates/deck.html +69 -0
  398. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/course-module/README.md +8 -0
  399. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/course-module/index.html +189 -0
  400. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/course-module/style.css +46 -0
  401. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/dir-key-nav-minimal/README.md +11 -0
  402. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/dir-key-nav-minimal/index.html +138 -0
  403. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/dir-key-nav-minimal/style.css +60 -0
  404. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/graphify-dark-graph/README.md +11 -0
  405. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/graphify-dark-graph/index.html +180 -0
  406. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/graphify-dark-graph/style.css +54 -0
  407. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/hermes-cyber-terminal/README.md +11 -0
  408. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/hermes-cyber-terminal/index.html +199 -0
  409. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/hermes-cyber-terminal/style.css +55 -0
  410. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/knowledge-arch-blueprint/README.md +11 -0
  411. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/knowledge-arch-blueprint/index.html +190 -0
  412. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/knowledge-arch-blueprint/style.css +49 -0
  413. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/obsidian-claude-gradient/README.md +11 -0
  414. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/obsidian-claude-gradient/index.html +144 -0
  415. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/obsidian-claude-gradient/style.css +59 -0
  416. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/pitch-deck/README.md +9 -0
  417. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/pitch-deck/index.html +148 -0
  418. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/pitch-deck/style.css +40 -0
  419. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/presenter-mode-reveal/README.md +102 -0
  420. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/presenter-mode-reveal/index.html +187 -0
  421. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/presenter-mode-reveal/style.css +216 -0
  422. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/product-launch/README.md +8 -0
  423. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/product-launch/index.html +121 -0
  424. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/product-launch/style.css +39 -0
  425. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/tech-sharing/README.md +8 -0
  426. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/tech-sharing/index.html +156 -0
  427. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/tech-sharing/style.css +49 -0
  428. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/testing-safety-alert/README.md +11 -0
  429. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/testing-safety-alert/index.html +183 -0
  430. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/testing-safety-alert/style.css +62 -0
  431. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/weekly-report/README.md +8 -0
  432. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/weekly-report/index.html +127 -0
  433. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/weekly-report/style.css +55 -0
  434. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-pastel-card/README.md +11 -0
  435. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-pastel-card/index.html +147 -0
  436. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-pastel-card/style.css +66 -0
  437. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-post/README.md +9 -0
  438. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-post/index.html +133 -0
  439. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-post/style.css +47 -0
  440. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-white-editorial/README.md +11 -0
  441. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-white-editorial/index.html +187 -0
  442. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks/xhs-white-editorial/style.css +63 -0
  443. package/dist/__w3kits/assets/design-templates/html-ppt/templates/full-decks-index.html +82 -0
  444. package/dist/__w3kits/assets/design-templates/html-ppt/templates/layout-showcase.html +47 -0
  445. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/arch-diagram.html +46 -0
  446. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/big-quote.html +18 -0
  447. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/bullets.html +19 -0
  448. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/chart-bar.html +30 -0
  449. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/chart-line.html +35 -0
  450. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/chart-pie.html +36 -0
  451. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/chart-radar.html +31 -0
  452. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/code.html +33 -0
  453. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/comparison.html +47 -0
  454. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/cover.html +32 -0
  455. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/cta.html +27 -0
  456. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/diff.html +35 -0
  457. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/flow-diagram.html +33 -0
  458. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/gantt.html +29 -0
  459. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/image-grid.html +34 -0
  460. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/image-hero.html +33 -0
  461. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/kpi-grid.html +19 -0
  462. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/mindmap.html +38 -0
  463. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/process-steps.html +27 -0
  464. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/pros-cons.html +31 -0
  465. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/roadmap.html +46 -0
  466. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/section-divider.html +17 -0
  467. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/stat-highlight.html +17 -0
  468. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/table.html +33 -0
  469. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/terminal.html +35 -0
  470. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/thanks.html +21 -0
  471. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/three-column.html +18 -0
  472. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/timeline.html +32 -0
  473. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/toc.html +26 -0
  474. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/todo-checklist.html +33 -0
  475. package/dist/__w3kits/assets/design-templates/html-ppt/templates/single-page/two-column.html +39 -0
  476. package/dist/__w3kits/assets/design-templates/html-ppt/templates/theme-showcase.html +151 -0
  477. package/dist/__w3kits/assets/design-templates/html-ppt-course-module/SKILL.md +79 -0
  478. package/dist/__w3kits/assets/design-templates/html-ppt-course-module/example.html +542 -0
  479. package/dist/__w3kits/assets/design-templates/html-ppt-dir-key-nav-minimal/SKILL.md +78 -0
  480. package/dist/__w3kits/assets/design-templates/html-ppt-dir-key-nav-minimal/example.html +366 -0
  481. package/dist/__w3kits/assets/design-templates/html-ppt-graphify-dark-graph/SKILL.md +78 -0
  482. package/dist/__w3kits/assets/design-templates/html-ppt-graphify-dark-graph/example.html +402 -0
  483. package/dist/__w3kits/assets/design-templates/html-ppt-hermes-cyber-terminal/SKILL.md +78 -0
  484. package/dist/__w3kits/assets/design-templates/html-ppt-hermes-cyber-terminal/example.html +422 -0
  485. package/dist/__w3kits/assets/design-templates/html-ppt-knowledge-arch-blueprint/SKILL.md +78 -0
  486. package/dist/__w3kits/assets/design-templates/html-ppt-knowledge-arch-blueprint/example.html +407 -0
  487. package/dist/__w3kits/assets/design-templates/html-ppt-obsidian-claude-gradient/SKILL.md +78 -0
  488. package/dist/__w3kits/assets/design-templates/html-ppt-obsidian-claude-gradient/example.html +371 -0
  489. package/dist/__w3kits/assets/design-templates/html-ppt-pitch-deck/SKILL.md +79 -0
  490. package/dist/__w3kits/assets/design-templates/html-ppt-pitch-deck/example.html +495 -0
  491. package/dist/__w3kits/assets/design-templates/html-ppt-presenter-mode-reveal/SKILL.md +79 -0
  492. package/dist/__w3kits/assets/design-templates/html-ppt-presenter-mode-reveal/example.html +725 -0
  493. package/dist/__w3kits/assets/design-templates/html-ppt-product-launch/SKILL.md +78 -0
  494. package/dist/__w3kits/assets/design-templates/html-ppt-product-launch/example.html +467 -0
  495. package/dist/__w3kits/assets/design-templates/html-ppt-taste-brutalist/SKILL.md +70 -0
  496. package/dist/__w3kits/assets/design-templates/html-ppt-taste-brutalist/example.html +774 -0
  497. package/dist/__w3kits/assets/design-templates/html-ppt-taste-editorial/SKILL.md +60 -0
  498. package/dist/__w3kits/assets/design-templates/html-ppt-taste-editorial/example.html +490 -0
  499. package/dist/__w3kits/assets/design-templates/html-ppt-tech-sharing/SKILL.md +78 -0
  500. package/dist/__w3kits/assets/design-templates/html-ppt-tech-sharing/example.html +512 -0
  501. package/dist/__w3kits/assets/design-templates/html-ppt-testing-safety-alert/SKILL.md +79 -0
  502. package/dist/__w3kits/assets/design-templates/html-ppt-testing-safety-alert/example.html +413 -0
  503. package/dist/__w3kits/assets/design-templates/html-ppt-weekly-report/SKILL.md +78 -0
  504. package/dist/__w3kits/assets/design-templates/html-ppt-weekly-report/example.html +489 -0
  505. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-pastel-card/SKILL.md +79 -0
  506. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-pastel-card/example.html +381 -0
  507. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-post/SKILL.md +79 -0
  508. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-post/example.html +487 -0
  509. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-white-editorial/SKILL.md +78 -0
  510. package/dist/__w3kits/assets/design-templates/html-ppt-xhs-white-editorial/example.html +418 -0
  511. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-8-bit-orbit/LICENSE +21 -0
  512. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-8-bit-orbit/SKILL.md +93 -0
  513. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-8-bit-orbit/example.html +1640 -0
  514. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-8-bit-orbit/template.json +48 -0
  515. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-biennale-yellow/LICENSE +21 -0
  516. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-biennale-yellow/SKILL.md +93 -0
  517. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-biennale-yellow/example.html +833 -0
  518. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-biennale-yellow/template.json +49 -0
  519. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-block-frame/LICENSE +21 -0
  520. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-block-frame/SKILL.md +93 -0
  521. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-block-frame/example.html +1453 -0
  522. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-block-frame/template.json +47 -0
  523. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-blue-professional/LICENSE +21 -0
  524. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-blue-professional/SKILL.md +93 -0
  525. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-blue-professional/example.html +1423 -0
  526. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-blue-professional/template.json +44 -0
  527. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-bold-poster/LICENSE +21 -0
  528. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-bold-poster/SKILL.md +93 -0
  529. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-bold-poster/example.html +876 -0
  530. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-bold-poster/template.json +45 -0
  531. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-broadside/LICENSE +21 -0
  532. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-broadside/SKILL.md +92 -0
  533. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-broadside/example.html +2144 -0
  534. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-broadside/template.json +49 -0
  535. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-capsule/LICENSE +21 -0
  536. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-capsule/SKILL.md +92 -0
  537. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-capsule/example.html +1413 -0
  538. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-capsule/template.json +51 -0
  539. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cartesian/LICENSE +21 -0
  540. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cartesian/SKILL.md +92 -0
  541. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cartesian/example.html +1136 -0
  542. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cartesian/template.json +47 -0
  543. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cobalt-grid/LICENSE +21 -0
  544. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cobalt-grid/SKILL.md +93 -0
  545. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cobalt-grid/example.html +1205 -0
  546. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-cobalt-grid/template.json +49 -0
  547. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-coral/LICENSE +21 -0
  548. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-coral/SKILL.md +92 -0
  549. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-coral/example.html +1487 -0
  550. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-coral/template.json +45 -0
  551. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-creative-mode/LICENSE +21 -0
  552. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-creative-mode/SKILL.md +99 -0
  553. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-creative-mode/assets/deck-stage.js +619 -0
  554. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-creative-mode/example.html +636 -0
  555. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-creative-mode/template.json +47 -0
  556. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-daisy-days/LICENSE +21 -0
  557. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-daisy-days/SKILL.md +93 -0
  558. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-daisy-days/example.html +469 -0
  559. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-daisy-days/template.json +54 -0
  560. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-editorial-tri-tone/LICENSE +21 -0
  561. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-editorial-tri-tone/SKILL.md +98 -0
  562. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-editorial-tri-tone/assets/deck-stage.js +619 -0
  563. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-editorial-tri-tone/example.html +737 -0
  564. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-editorial-tri-tone/template.json +44 -0
  565. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-grove/LICENSE +21 -0
  566. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-grove/SKILL.md +92 -0
  567. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-grove/example.html +1676 -0
  568. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-grove/template.json +51 -0
  569. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-long-table/LICENSE +21 -0
  570. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-long-table/SKILL.md +92 -0
  571. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-long-table/example.html +1192 -0
  572. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-long-table/template.json +50 -0
  573. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-mat/LICENSE +21 -0
  574. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-mat/SKILL.md +92 -0
  575. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-mat/example.html +1372 -0
  576. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-mat/template.json +49 -0
  577. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-monochrome/LICENSE +21 -0
  578. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-monochrome/SKILL.md +91 -0
  579. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-monochrome/example.html +2596 -0
  580. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-monochrome/template.json +50 -0
  581. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-neo-grid-bold/LICENSE +21 -0
  582. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-neo-grid-bold/SKILL.md +99 -0
  583. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-neo-grid-bold/assets/deck-stage.js +619 -0
  584. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-neo-grid-bold/example.html +865 -0
  585. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-neo-grid-bold/template.json +47 -0
  586. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-peoples-platform/LICENSE +21 -0
  587. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-peoples-platform/SKILL.md +99 -0
  588. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-peoples-platform/assets/deck-stage.js +619 -0
  589. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-peoples-platform/example.html +825 -0
  590. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-peoples-platform/template.json +48 -0
  591. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/LICENSE +21 -0
  592. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/SKILL.md +100 -0
  593. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/assets/deck-stage.js +619 -0
  594. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/assets/styles.css +668 -0
  595. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/example.html +443 -0
  596. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pin-and-paper/template.json +46 -0
  597. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pink-script/LICENSE +21 -0
  598. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pink-script/SKILL.md +99 -0
  599. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pink-script/assets/deck-stage.js +619 -0
  600. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pink-script/example.html +658 -0
  601. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-pink-script/template.json +47 -0
  602. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-playful/LICENSE +21 -0
  603. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-playful/SKILL.md +92 -0
  604. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-playful/example.html +1355 -0
  605. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-playful/template.json +43 -0
  606. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-raw-grid/LICENSE +21 -0
  607. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-raw-grid/SKILL.md +93 -0
  608. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-raw-grid/example.html +1121 -0
  609. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-raw-grid/template.json +46 -0
  610. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-windows/LICENSE +21 -0
  611. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-windows/SKILL.md +92 -0
  612. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-windows/example.html +1287 -0
  613. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-windows/template.json +47 -0
  614. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-zine/LICENSE +21 -0
  615. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-zine/SKILL.md +93 -0
  616. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-zine/example.html +1058 -0
  617. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-retro-zine/template.json +47 -0
  618. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-sakura-chroma/LICENSE +21 -0
  619. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-sakura-chroma/SKILL.md +92 -0
  620. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-sakura-chroma/example.html +1405 -0
  621. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-sakura-chroma/template.json +54 -0
  622. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-scatterbrain/LICENSE +21 -0
  623. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-scatterbrain/SKILL.md +92 -0
  624. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-scatterbrain/example.html +1320 -0
  625. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-scatterbrain/template.json +50 -0
  626. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-signal/LICENSE +21 -0
  627. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-signal/SKILL.md +92 -0
  628. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-signal/example.html +2558 -0
  629. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-signal/template.json +50 -0
  630. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-soft-editorial/LICENSE +21 -0
  631. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-soft-editorial/SKILL.md +98 -0
  632. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-soft-editorial/assets/deck-stage.js +619 -0
  633. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-soft-editorial/example.html +1183 -0
  634. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-soft-editorial/template.json +47 -0
  635. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-stencil-tablet/LICENSE +21 -0
  636. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-stencil-tablet/SKILL.md +99 -0
  637. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-stencil-tablet/assets/deck-stage.js +619 -0
  638. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-stencil-tablet/example.html +954 -0
  639. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-stencil-tablet/template.json +52 -0
  640. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-studio/LICENSE +21 -0
  641. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-studio/SKILL.md +92 -0
  642. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-studio/example.html +1606 -0
  643. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-studio/template.json +49 -0
  644. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-vellum/LICENSE +21 -0
  645. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-vellum/SKILL.md +91 -0
  646. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-vellum/example.html +1091 -0
  647. package/dist/__w3kits/assets/design-templates/html-ppt-zhangzara-vellum/template.json +50 -0
  648. package/dist/__w3kits/assets/design-templates/hyperframes/SKILL.md +500 -0
  649. package/dist/__w3kits/assets/design-templates/hyperframes/data-in-motion.md +19 -0
  650. package/dist/__w3kits/assets/design-templates/hyperframes/house-style.md +71 -0
  651. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/bold-energetic.md +14 -0
  652. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/clean-corporate.md +14 -0
  653. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/dark-premium.md +14 -0
  654. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/jewel-rich.md +14 -0
  655. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/monochrome.md +14 -0
  656. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/nature-earth.md +14 -0
  657. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/neon-electric.md +14 -0
  658. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/pastel-soft.md +14 -0
  659. package/dist/__w3kits/assets/design-templates/hyperframes/palettes/warm-editorial.md +14 -0
  660. package/dist/__w3kits/assets/design-templates/hyperframes/patterns.md +118 -0
  661. package/dist/__w3kits/assets/design-templates/hyperframes/references/audio-reactive.md +76 -0
  662. package/dist/__w3kits/assets/design-templates/hyperframes/references/captions.md +132 -0
  663. package/dist/__w3kits/assets/design-templates/hyperframes/references/css-patterns.md +373 -0
  664. package/dist/__w3kits/assets/design-templates/hyperframes/references/dynamic-techniques.md +90 -0
  665. package/dist/__w3kits/assets/design-templates/hyperframes/references/html-in-canvas.md +146 -0
  666. package/dist/__w3kits/assets/design-templates/hyperframes/references/motion-principles.md +69 -0
  667. package/dist/__w3kits/assets/design-templates/hyperframes/references/transcript-guide.md +151 -0
  668. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/catalog.md +117 -0
  669. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-3d.md +12 -0
  670. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-blur.md +51 -0
  671. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-cover.md +43 -0
  672. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-destruction.md +95 -0
  673. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-dissolve.md +66 -0
  674. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-distortion.md +45 -0
  675. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-grid.md +10 -0
  676. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-light.md +49 -0
  677. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-mechanical.md +30 -0
  678. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-other.md +25 -0
  679. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-push.md +41 -0
  680. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-radial.md +37 -0
  681. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions/css-scale.md +24 -0
  682. package/dist/__w3kits/assets/design-templates/hyperframes/references/transitions.md +112 -0
  683. package/dist/__w3kits/assets/design-templates/hyperframes/references/tts.md +75 -0
  684. package/dist/__w3kits/assets/design-templates/hyperframes/references/typography.md +175 -0
  685. package/dist/__w3kits/assets/design-templates/hyperframes/scripts/animation-map.mjs +601 -0
  686. package/dist/__w3kits/assets/design-templates/hyperframes/scripts/contrast-report.mjs +338 -0
  687. package/dist/__w3kits/assets/design-templates/hyperframes/scripts/package-loader.mjs +269 -0
  688. package/dist/__w3kits/assets/design-templates/hyperframes/visual-styles.md +211 -0
  689. package/dist/__w3kits/assets/design-templates/ib-pitch-book/SKILL.md +161 -0
  690. package/dist/__w3kits/assets/design-templates/ib-pitch-book/assets/template.html +436 -0
  691. package/dist/__w3kits/assets/design-templates/ib-pitch-book/example.html +1181 -0
  692. package/dist/__w3kits/assets/design-templates/ib-pitch-book/references/attribution.md +35 -0
  693. package/dist/__w3kits/assets/design-templates/ib-pitch-book/references/checklist.md +39 -0
  694. package/dist/__w3kits/assets/design-templates/ib-pitch-book/references/compliance.md +60 -0
  695. package/dist/__w3kits/assets/design-templates/ib-pitch-book/references/conventions.md +36 -0
  696. package/dist/__w3kits/assets/design-templates/image-poster/SKILL.md +104 -0
  697. package/dist/__w3kits/assets/design-templates/image-poster/example.html +113 -0
  698. package/dist/__w3kits/assets/design-templates/invoice/SKILL.md +48 -0
  699. package/dist/__w3kits/assets/design-templates/invoice/example.html +214 -0
  700. package/dist/__w3kits/assets/design-templates/kami-deck/README.md +72 -0
  701. package/dist/__w3kits/assets/design-templates/kami-deck/SKILL.md +196 -0
  702. package/dist/__w3kits/assets/design-templates/kami-deck/example.html +1101 -0
  703. package/dist/__w3kits/assets/design-templates/kami-landing/README.md +69 -0
  704. package/dist/__w3kits/assets/design-templates/kami-landing/SKILL.md +234 -0
  705. package/dist/__w3kits/assets/design-templates/kami-landing/example.html +673 -0
  706. package/dist/__w3kits/assets/design-templates/kanban-board/SKILL.md +50 -0
  707. package/dist/__w3kits/assets/design-templates/kanban-board/example.html +270 -0
  708. package/dist/__w3kits/assets/design-templates/last30days/LICENSE +21 -0
  709. package/dist/__w3kits/assets/design-templates/last30days/SKILL.md +142 -0
  710. package/dist/__w3kits/assets/design-templates/last30days/references/save-html-brief.md +50 -0
  711. package/dist/__w3kits/assets/design-templates/last30days/scripts/briefing.py +264 -0
  712. package/dist/__w3kits/assets/design-templates/last30days/scripts/last30days.py +938 -0
  713. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/__init__.py +1 -0
  714. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/bird_x.py +443 -0
  715. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/bluesky.py +249 -0
  716. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/categories.py +283 -0
  717. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/chrome_cookies.py +265 -0
  718. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/cluster.py +271 -0
  719. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/competitors.py +199 -0
  720. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/cookie_extract.py +379 -0
  721. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/dates.py +120 -0
  722. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/dedupe.py +130 -0
  723. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/entity_extract.py +127 -0
  724. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/env.py +650 -0
  725. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/fanout.py +85 -0
  726. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/fusion.py +207 -0
  727. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/github.py +921 -0
  728. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/grounding.py +259 -0
  729. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/hackernews.py +301 -0
  730. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/html_render.py +674 -0
  731. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/http.py +204 -0
  732. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/instagram.py +500 -0
  733. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/log.py +28 -0
  734. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/normalize.py +499 -0
  735. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/perplexity.py +164 -0
  736. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/pinterest.py +182 -0
  737. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/pipeline.py +1069 -0
  738. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/planner.py +712 -0
  739. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/polymarket.py +786 -0
  740. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/preflight.py +119 -0
  741. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/providers.py +464 -0
  742. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/quality_nudge.py +190 -0
  743. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/query.py +117 -0
  744. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/reddit.py +703 -0
  745. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/reddit_enrich.py +322 -0
  746. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/reddit_public.py +377 -0
  747. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/relevance.py +168 -0
  748. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/render.py +1722 -0
  749. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/rerank.py +425 -0
  750. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/resolve.py +258 -0
  751. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/safari_cookies.py +182 -0
  752. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/schema.py +319 -0
  753. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/setup_wizard.py +535 -0
  754. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/signals.py +251 -0
  755. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/snippet.py +51 -0
  756. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/subproc.py +94 -0
  757. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/threads.py +224 -0
  758. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/tiktok.py +677 -0
  759. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/truthsocial.py +168 -0
  760. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/ui.py +610 -0
  761. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/LICENSE +21 -0
  762. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/bird-search.mjs +147 -0
  763. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/cookies.js +220 -0
  764. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/features.json +17 -0
  765. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/paginate-cursor.js +37 -0
  766. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/query-ids.json +20 -0
  767. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/runtime-features.js +151 -0
  768. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js +264 -0
  769. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-base.js +129 -0
  770. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js +50 -0
  771. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-features.js +347 -0
  772. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-search.js +157 -0
  773. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-types.js +2 -0
  774. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js +511 -0
  775. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/vendor/bird-search/package.json +13 -0
  776. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/xai_x.py +228 -0
  777. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/xiaohongshu_api.py +162 -0
  778. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/xquik.py +227 -0
  779. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/xurl_x.py +172 -0
  780. package/dist/__w3kits/assets/design-templates/last30days/scripts/lib/youtube_yt.py +967 -0
  781. package/dist/__w3kits/assets/design-templates/last30days/scripts/store.py +787 -0
  782. package/dist/__w3kits/assets/design-templates/last30days/scripts/watchlist.py +299 -0
  783. package/dist/__w3kits/assets/design-templates/live-artifact/SKILL.md +136 -0
  784. package/dist/__w3kits/assets/design-templates/live-artifact/assets/templates/clinic-console/README.md +342 -0
  785. package/dist/__w3kits/assets/design-templates/live-artifact/assets/templates/clinic-console/data.json +165 -0
  786. package/dist/__w3kits/assets/design-templates/live-artifact/assets/templates/clinic-console/template.html +548 -0
  787. package/dist/__w3kits/assets/design-templates/live-artifact/examples/baby-health-live.html +761 -0
  788. package/dist/__w3kits/assets/design-templates/live-artifact/examples/competitor-radar-live.html +1006 -0
  789. package/dist/__w3kits/assets/design-templates/live-artifact/examples/crm-table-live.html +1174 -0
  790. package/dist/__w3kits/assets/design-templates/live-artifact/examples/crypto-dashboard.html +2316 -0
  791. package/dist/__w3kits/assets/design-templates/live-artifact/examples/monday-operator-live.html +919 -0
  792. package/dist/__w3kits/assets/design-templates/live-artifact/examples/stock-dashboard.html +2246 -0
  793. package/dist/__w3kits/assets/design-templates/live-artifact/examples/stock-portfolio-live/artifact.json +16 -0
  794. package/dist/__w3kits/assets/design-templates/live-artifact/examples/stock-portfolio-live/data.json +453 -0
  795. package/dist/__w3kits/assets/design-templates/live-artifact/examples/stock-portfolio-live/provenance.json +19 -0
  796. package/dist/__w3kits/assets/design-templates/live-artifact/examples/stock-portfolio-live/template.html +1071 -0
  797. package/dist/__w3kits/assets/design-templates/live-artifact/references/artifact-schema.md +99 -0
  798. package/dist/__w3kits/assets/design-templates/live-artifact/references/connector-policy.md +119 -0
  799. package/dist/__w3kits/assets/design-templates/live-artifact/references/refresh-contract.md +78 -0
  800. package/dist/__w3kits/assets/design-templates/live-dashboard/SKILL.md +203 -0
  801. package/dist/__w3kits/assets/design-templates/live-dashboard/assets/template.html +643 -0
  802. package/dist/__w3kits/assets/design-templates/live-dashboard/example.html +946 -0
  803. package/dist/__w3kits/assets/design-templates/live-dashboard/references/checklist.md +83 -0
  804. package/dist/__w3kits/assets/design-templates/live-dashboard/references/components.md +212 -0
  805. package/dist/__w3kits/assets/design-templates/live-dashboard/references/connectors.md +171 -0
  806. package/dist/__w3kits/assets/design-templates/live-dashboard/references/layouts.md +92 -0
  807. package/dist/__w3kits/assets/design-templates/magazine-poster/SKILL.md +88 -0
  808. package/dist/__w3kits/assets/design-templates/magazine-poster/example.html +207 -0
  809. package/dist/__w3kits/assets/design-templates/meeting-notes/SKILL.md +47 -0
  810. package/dist/__w3kits/assets/design-templates/meeting-notes/example.html +234 -0
  811. package/dist/__w3kits/assets/design-templates/mobile-app/SKILL.md +102 -0
  812. package/dist/__w3kits/assets/design-templates/mobile-app/assets/template.html +442 -0
  813. package/dist/__w3kits/assets/design-templates/mobile-app/example.html +92 -0
  814. package/dist/__w3kits/assets/design-templates/mobile-app/references/checklist.md +46 -0
  815. package/dist/__w3kits/assets/design-templates/mobile-app/references/layouts.md +312 -0
  816. package/dist/__w3kits/assets/design-templates/mobile-onboarding/SKILL.md +54 -0
  817. package/dist/__w3kits/assets/design-templates/mobile-onboarding/example.html +206 -0
  818. package/dist/__w3kits/assets/design-templates/motion-frames/SKILL.md +90 -0
  819. package/dist/__w3kits/assets/design-templates/motion-frames/example.html +221 -0
  820. package/dist/__w3kits/assets/design-templates/open-design-landing/README.md +119 -0
  821. package/dist/__w3kits/assets/design-templates/open-design-landing/SKILL.md +321 -0
  822. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/about.png +0 -0
  823. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/capabilities.png +0 -0
  824. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/cta.png +0 -0
  825. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/hero.png +0 -0
  826. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/image-manifest.json +168 -0
  827. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/imagegen-prompts.md +246 -0
  828. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/lab-1.png +0 -0
  829. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/lab-2.png +0 -0
  830. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/lab-3.png +0 -0
  831. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/lab-4.png +0 -0
  832. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/lab-5.png +0 -0
  833. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/method-1.png +0 -0
  834. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/method-2.png +0 -0
  835. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/method-3.png +0 -0
  836. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/method-4.png +0 -0
  837. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/testimonial.png +0 -0
  838. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/work-1.png +0 -0
  839. package/dist/__w3kits/assets/design-templates/open-design-landing/assets/work-2.png +0 -0
  840. package/dist/__w3kits/assets/design-templates/open-design-landing/example.html +2645 -0
  841. package/dist/__w3kits/assets/design-templates/open-design-landing/inputs.example.json +365 -0
  842. package/dist/__w3kits/assets/design-templates/open-design-landing/schema.ts +447 -0
  843. package/dist/__w3kits/assets/design-templates/open-design-landing/scripts/compose.ts +821 -0
  844. package/dist/__w3kits/assets/design-templates/open-design-landing/scripts/imagegen.ts +325 -0
  845. package/dist/__w3kits/assets/design-templates/open-design-landing/scripts/placeholder.ts +174 -0
  846. package/dist/__w3kits/assets/design-templates/open-design-landing/styles.css +1858 -0
  847. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/README.md +118 -0
  848. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/SKILL.md +222 -0
  849. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/example.html +2900 -0
  850. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/inputs.example.json +210 -0
  851. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/schema.ts +128 -0
  852. package/dist/__w3kits/assets/design-templates/open-design-landing-deck/scripts/compose.ts +1056 -0
  853. package/dist/__w3kits/assets/design-templates/orbit-general/SKILL.md +203 -0
  854. package/dist/__w3kits/assets/design-templates/orbit-general/example.html +1302 -0
  855. package/dist/__w3kits/assets/design-templates/orbit-github/SKILL.md +167 -0
  856. package/dist/__w3kits/assets/design-templates/orbit-github/example.html +770 -0
  857. package/dist/__w3kits/assets/design-templates/orbit-gmail/SKILL.md +170 -0
  858. package/dist/__w3kits/assets/design-templates/orbit-gmail/example.html +643 -0
  859. package/dist/__w3kits/assets/design-templates/orbit-linear/SKILL.md +177 -0
  860. package/dist/__w3kits/assets/design-templates/orbit-linear/example.html +571 -0
  861. package/dist/__w3kits/assets/design-templates/orbit-notion/SKILL.md +186 -0
  862. package/dist/__w3kits/assets/design-templates/orbit-notion/example.html +529 -0
  863. package/dist/__w3kits/assets/design-templates/pm-spec/SKILL.md +52 -0
  864. package/dist/__w3kits/assets/design-templates/pm-spec/example.html +248 -0
  865. package/dist/__w3kits/assets/design-templates/pricing-page/SKILL.md +79 -0
  866. package/dist/__w3kits/assets/design-templates/pricing-page/example.html +127 -0
  867. package/dist/__w3kits/assets/design-templates/replit-deck/SKILL.md +233 -0
  868. package/dist/__w3kits/assets/design-templates/replit-deck/assets/template.html +488 -0
  869. package/dist/__w3kits/assets/design-templates/replit-deck/examples/README.md +18 -0
  870. package/dist/__w3kits/assets/design-templates/replit-deck/examples/example-atlas.html +499 -0
  871. package/dist/__w3kits/assets/design-templates/replit-deck/examples/example-bluehouse.html +495 -0
  872. package/dist/__w3kits/assets/design-templates/replit-deck/examples/example-helix.html +480 -0
  873. package/dist/__w3kits/assets/design-templates/replit-deck/examples/example-holm.html +513 -0
  874. package/dist/__w3kits/assets/design-templates/replit-deck/references/checklist.md +112 -0
  875. package/dist/__w3kits/assets/design-templates/replit-deck/references/components.md +143 -0
  876. package/dist/__w3kits/assets/design-templates/replit-deck/references/layouts.md +457 -0
  877. package/dist/__w3kits/assets/design-templates/replit-deck/references/themes.md +326 -0
  878. package/dist/__w3kits/assets/design-templates/saas-landing/SKILL.md +124 -0
  879. package/dist/__w3kits/assets/design-templates/saas-landing/example.html +153 -0
  880. package/dist/__w3kits/assets/design-templates/simple-deck/SKILL.md +120 -0
  881. package/dist/__w3kits/assets/design-templates/simple-deck/assets/template.html +353 -0
  882. package/dist/__w3kits/assets/design-templates/simple-deck/example.html +141 -0
  883. package/dist/__w3kits/assets/design-templates/simple-deck/references/checklist.md +55 -0
  884. package/dist/__w3kits/assets/design-templates/simple-deck/references/layouts.md +201 -0
  885. package/dist/__w3kits/assets/design-templates/social-carousel/SKILL.md +92 -0
  886. package/dist/__w3kits/assets/design-templates/social-carousel/example.html +219 -0
  887. package/dist/__w3kits/assets/design-templates/social-media-dashboard/.preview/hero.png +0 -0
  888. package/dist/__w3kits/assets/design-templates/social-media-dashboard/SKILL.md +118 -0
  889. package/dist/__w3kits/assets/design-templates/social-media-dashboard/example.html +1534 -0
  890. package/dist/__w3kits/assets/design-templates/social-media-matrix-tracker-template/SKILL.md +107 -0
  891. package/dist/__w3kits/assets/design-templates/social-media-matrix-tracker-template/assets/template.html +1258 -0
  892. package/dist/__w3kits/assets/design-templates/social-media-matrix-tracker-template/example.html +1258 -0
  893. package/dist/__w3kits/assets/design-templates/social-media-matrix-tracker-template/references/checklist.md +25 -0
  894. package/dist/__w3kits/assets/design-templates/sprite-animation/SKILL.md +95 -0
  895. package/dist/__w3kits/assets/design-templates/sprite-animation/example.html +271 -0
  896. package/dist/__w3kits/assets/design-templates/team-okrs/SKILL.md +47 -0
  897. package/dist/__w3kits/assets/design-templates/team-okrs/example.html +207 -0
  898. package/dist/__w3kits/assets/design-templates/trading-analysis-dashboard-template/SKILL.md +78 -0
  899. package/dist/__w3kits/assets/design-templates/trading-analysis-dashboard-template/assets/template.html +284 -0
  900. package/dist/__w3kits/assets/design-templates/trading-analysis-dashboard-template/example.html +22 -0
  901. package/dist/__w3kits/assets/design-templates/trading-analysis-dashboard-template/references/checklist.md +32 -0
  902. package/dist/__w3kits/assets/design-templates/tweaks/SKILL.md +240 -0
  903. package/dist/__w3kits/assets/design-templates/tweaks/assets/wrap.html +437 -0
  904. package/dist/__w3kits/assets/design-templates/tweaks/example.html +750 -0
  905. package/dist/__w3kits/assets/design-templates/video-shortform/SKILL.md +128 -0
  906. package/dist/__w3kits/assets/design-templates/video-shortform/example.html +90 -0
  907. package/dist/__w3kits/assets/design-templates/waitlist-page/SKILL.md +229 -0
  908. package/dist/__w3kits/assets/design-templates/waitlist-page/assets/template.html +457 -0
  909. package/dist/__w3kits/assets/design-templates/waitlist-page/example.html +400 -0
  910. package/dist/__w3kits/assets/design-templates/waitlist-page/references/checklist.md +42 -0
  911. package/dist/__w3kits/assets/design-templates/web-prototype/SKILL.md +97 -0
  912. package/dist/__w3kits/assets/design-templates/web-prototype/assets/template.html +338 -0
  913. package/dist/__w3kits/assets/design-templates/web-prototype/example.html +81 -0
  914. package/dist/__w3kits/assets/design-templates/web-prototype/references/checklist.md +44 -0
  915. package/dist/__w3kits/assets/design-templates/web-prototype/references/layouts.md +247 -0
  916. package/dist/__w3kits/assets/design-templates/web-prototype-taste-brutalist/SKILL.md +61 -0
  917. package/dist/__w3kits/assets/design-templates/web-prototype-taste-brutalist/example.html +449 -0
  918. package/dist/__w3kits/assets/design-templates/web-prototype-taste-editorial/SKILL.md +60 -0
  919. package/dist/__w3kits/assets/design-templates/web-prototype-taste-editorial/example.html +392 -0
  920. package/dist/__w3kits/assets/design-templates/web-prototype-taste-soft/SKILL.md +63 -0
  921. package/dist/__w3kits/assets/design-templates/web-prototype-taste-soft/example.html +542 -0
  922. package/dist/__w3kits/assets/design-templates/weekly-update/SKILL.md +50 -0
  923. package/dist/__w3kits/assets/design-templates/weekly-update/example.html +320 -0
  924. package/dist/__w3kits/assets/design-templates/wireframe-sketch/SKILL.md +97 -0
  925. package/dist/__w3kits/assets/design-templates/wireframe-sketch/example.html +256 -0
  926. package/dist/__w3kits/assets/design-templates/x-research/SKILL.md +116 -0
  927. package/dist/__w3kits/assets/skills/8-bit-orbit-video-template/SKILL.md +73 -0
  928. package/dist/__w3kits/assets/skills/8-bit-orbit-video-template/assets/default-showcase.mp4 +0 -0
  929. package/dist/__w3kits/assets/skills/8-bit-orbit-video-template/assets/template.html +506 -0
  930. package/dist/__w3kits/assets/skills/8-bit-orbit-video-template/example.html +43 -0
  931. package/dist/__w3kits/assets/skills/8-bit-orbit-video-template/references/checklist.md +21 -0
  932. package/dist/__w3kits/assets/skills/AGENTS.md +54 -0
  933. package/dist/__w3kits/assets/skills/README.md +25 -0
  934. package/dist/__w3kits/assets/skills/ad-creative/SKILL.md +43 -0
  935. package/dist/__w3kits/assets/skills/after-hours-editorial-template/SKILL.md +79 -0
  936. package/dist/__w3kits/assets/skills/after-hours-editorial-template/assets/template.html +173 -0
  937. package/dist/__w3kits/assets/skills/after-hours-editorial-template/example.html +12 -0
  938. package/dist/__w3kits/assets/skills/after-hours-editorial-template/references/checklist.md +25 -0
  939. package/dist/__w3kits/assets/skills/agent-browser/SKILL.md +193 -0
  940. package/dist/__w3kits/assets/skills/ai-music-album/SKILL.md +43 -0
  941. package/dist/__w3kits/assets/skills/algorithmic-art/SKILL.md +44 -0
  942. package/dist/__w3kits/assets/skills/apple-hig/SKILL.md +43 -0
  943. package/dist/__w3kits/assets/skills/artifacts-builder/SKILL.md +42 -0
  944. package/dist/__w3kits/assets/skills/brainstorming/SKILL.md +43 -0
  945. package/dist/__w3kits/assets/skills/brand-guidelines/SKILL.md +42 -0
  946. package/dist/__w3kits/assets/skills/canvas-design/SKILL.md +45 -0
  947. package/dist/__w3kits/assets/skills/color-expert/SKILL.md +43 -0
  948. package/dist/__w3kits/assets/skills/competitive-ads-extractor/SKILL.md +42 -0
  949. package/dist/__w3kits/assets/skills/copywriting/SKILL.md +43 -0
  950. package/dist/__w3kits/assets/skills/creative-director/SKILL.md +43 -0
  951. package/dist/__w3kits/assets/skills/d3-visualization/SKILL.md +43 -0
  952. package/dist/__w3kits/assets/skills/design-brief/SKILL.md +252 -0
  953. package/dist/__w3kits/assets/skills/design-consultation/SKILL.md +42 -0
  954. package/dist/__w3kits/assets/skills/design-md/SKILL.md +42 -0
  955. package/dist/__w3kits/assets/skills/design-review/SKILL.md +42 -0
  956. package/dist/__w3kits/assets/skills/digits-fintech-swiss-template/SKILL.md +68 -0
  957. package/dist/__w3kits/assets/skills/digits-fintech-swiss-template/assets/template.html +111 -0
  958. package/dist/__w3kits/assets/skills/digits-fintech-swiss-template/example.html +44 -0
  959. package/dist/__w3kits/assets/skills/digits-fintech-swiss-template/references/checklist.md +23 -0
  960. package/dist/__w3kits/assets/skills/doc/SKILL.md +42 -0
  961. package/dist/__w3kits/assets/skills/docx/SKILL.md +43 -0
  962. package/dist/__w3kits/assets/skills/domain-name-brainstormer/SKILL.md +43 -0
  963. package/dist/__w3kits/assets/skills/editorial-burgundy-principles-template/SKILL.md +71 -0
  964. package/dist/__w3kits/assets/skills/editorial-burgundy-principles-template/assets/template.html +94 -0
  965. package/dist/__w3kits/assets/skills/editorial-burgundy-principles-template/example.html +49 -0
  966. package/dist/__w3kits/assets/skills/editorial-burgundy-principles-template/references/checklist.md +22 -0
  967. package/dist/__w3kits/assets/skills/enhance-prompt/SKILL.md +42 -0
  968. package/dist/__w3kits/assets/skills/fal-3d/SKILL.md +43 -0
  969. package/dist/__w3kits/assets/skills/fal-generate/SKILL.md +43 -0
  970. package/dist/__w3kits/assets/skills/fal-image-edit/SKILL.md +43 -0
  971. package/dist/__w3kits/assets/skills/fal-kling-o3/SKILL.md +42 -0
  972. package/dist/__w3kits/assets/skills/fal-lip-sync/SKILL.md +43 -0
  973. package/dist/__w3kits/assets/skills/fal-realtime/SKILL.md +42 -0
  974. package/dist/__w3kits/assets/skills/fal-restore/SKILL.md +44 -0
  975. package/dist/__w3kits/assets/skills/fal-train/SKILL.md +43 -0
  976. package/dist/__w3kits/assets/skills/fal-tryon/SKILL.md +43 -0
  977. package/dist/__w3kits/assets/skills/fal-upscale/SKILL.md +43 -0
  978. package/dist/__w3kits/assets/skills/fal-video-edit/SKILL.md +43 -0
  979. package/dist/__w3kits/assets/skills/fal-vision/SKILL.md +44 -0
  980. package/dist/__w3kits/assets/skills/faq-page/SKILL.md +113 -0
  981. package/dist/__w3kits/assets/skills/faq-page/example.html +517 -0
  982. package/dist/__w3kits/assets/skills/field-notes-editorial-template/SKILL.md +78 -0
  983. package/dist/__w3kits/assets/skills/field-notes-editorial-template/assets/template.html +287 -0
  984. package/dist/__w3kits/assets/skills/field-notes-editorial-template/example.html +138 -0
  985. package/dist/__w3kits/assets/skills/field-notes-editorial-template/references/checklist.md +28 -0
  986. package/dist/__w3kits/assets/skills/figma-code-connect-components/SKILL.md +42 -0
  987. package/dist/__w3kits/assets/skills/figma-create-design-system-rules/SKILL.md +42 -0
  988. package/dist/__w3kits/assets/skills/figma-create-new-file/SKILL.md +41 -0
  989. package/dist/__w3kits/assets/skills/figma-generate-design/SKILL.md +42 -0
  990. package/dist/__w3kits/assets/skills/figma-generate-library/SKILL.md +42 -0
  991. package/dist/__w3kits/assets/skills/figma-implement-design/SKILL.md +42 -0
  992. package/dist/__w3kits/assets/skills/figma-use/SKILL.md +42 -0
  993. package/dist/__w3kits/assets/skills/flutter-animating-apps/SKILL.md +42 -0
  994. package/dist/__w3kits/assets/skills/frontend-design/SKILL.md +43 -0
  995. package/dist/__w3kits/assets/skills/frontend-dev/SKILL.md +43 -0
  996. package/dist/__w3kits/assets/skills/frontend-skill/SKILL.md +42 -0
  997. package/dist/__w3kits/assets/skills/frontend-slides/SKILL.md +43 -0
  998. package/dist/__w3kits/assets/skills/full-page-screenshot/SKILL.md +42 -0
  999. package/dist/__w3kits/assets/skills/gif-sticker-maker/SKILL.md +43 -0
  1000. package/dist/__w3kits/assets/skills/gsap-core/SKILL.md +43 -0
  1001. package/dist/__w3kits/assets/skills/gsap-react/SKILL.md +43 -0
  1002. package/dist/__w3kits/assets/skills/gsap-scrolltrigger/SKILL.md +43 -0
  1003. package/dist/__w3kits/assets/skills/gsap-timeline/SKILL.md +42 -0
  1004. package/dist/__w3kits/assets/skills/hand-drawn-diagrams/SKILL.md +42 -0
  1005. package/dist/__w3kits/assets/skills/hatch-pet/LICENSE.txt +201 -0
  1006. package/dist/__w3kits/assets/skills/hatch-pet/README.md +56 -0
  1007. package/dist/__w3kits/assets/skills/hatch-pet/SKILL.md +355 -0
  1008. package/dist/__w3kits/assets/skills/hatch-pet/agents/openai.yaml +4 -0
  1009. package/dist/__w3kits/assets/skills/hatch-pet/references/animation-rows.md +29 -0
  1010. package/dist/__w3kits/assets/skills/hatch-pet/references/codex-pet-contract.md +35 -0
  1011. package/dist/__w3kits/assets/skills/hatch-pet/references/qa-rubric.md +60 -0
  1012. package/dist/__w3kits/assets/skills/hatch-pet/scripts/compose_atlas.py +150 -0
  1013. package/dist/__w3kits/assets/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
  1014. package/dist/__w3kits/assets/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
  1015. package/dist/__w3kits/assets/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
  1016. package/dist/__w3kits/assets/skills/hatch-pet/scripts/generate_pet_images.py +295 -0
  1017. package/dist/__w3kits/assets/skills/hatch-pet/scripts/inspect_frames.py +246 -0
  1018. package/dist/__w3kits/assets/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
  1019. package/dist/__w3kits/assets/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
  1020. package/dist/__w3kits/assets/skills/hatch-pet/scripts/pet_job_status.py +117 -0
  1021. package/dist/__w3kits/assets/skills/hatch-pet/scripts/prepare_pet_run.py +674 -0
  1022. package/dist/__w3kits/assets/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
  1023. package/dist/__w3kits/assets/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
  1024. package/dist/__w3kits/assets/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
  1025. package/dist/__w3kits/assets/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
  1026. package/dist/__w3kits/assets/skills/hatch-pet/scripts/test_generate_pet_images.py +136 -0
  1027. package/dist/__w3kits/assets/skills/hatch-pet/scripts/validate_atlas.py +139 -0
  1028. package/dist/__w3kits/assets/skills/html-ppt-retro-quarterly-review/SKILL.md +79 -0
  1029. package/dist/__w3kits/assets/skills/html-ppt-retro-quarterly-review/assets/template.html +164 -0
  1030. package/dist/__w3kits/assets/skills/html-ppt-retro-quarterly-review/example.html +139 -0
  1031. package/dist/__w3kits/assets/skills/html-ppt-retro-quarterly-review/references/checklist.md +23 -0
  1032. package/dist/__w3kits/assets/skills/image-enhancer/SKILL.md +43 -0
  1033. package/dist/__w3kits/assets/skills/imagegen/SKILL.md +44 -0
  1034. package/dist/__w3kits/assets/skills/imagen/SKILL.md +43 -0
  1035. package/dist/__w3kits/assets/skills/login-flow/SKILL.md +48 -0
  1036. package/dist/__w3kits/assets/skills/login-flow/example.html +362 -0
  1037. package/dist/__w3kits/assets/skills/login-flow/references/checklist.md +19 -0
  1038. package/dist/__w3kits/assets/skills/marketing-psychology/SKILL.md +43 -0
  1039. package/dist/__w3kits/assets/skills/minimax-docx/SKILL.md +43 -0
  1040. package/dist/__w3kits/assets/skills/minimax-pdf/SKILL.md +43 -0
  1041. package/dist/__w3kits/assets/skills/nanobanana-ppt/SKILL.md +43 -0
  1042. package/dist/__w3kits/assets/skills/paywall-upgrade-cro/SKILL.md +43 -0
  1043. package/dist/__w3kits/assets/skills/pdf/SKILL.md +43 -0
  1044. package/dist/__w3kits/assets/skills/pixelbin-media/SKILL.md +43 -0
  1045. package/dist/__w3kits/assets/skills/plan-design-review/SKILL.md +42 -0
  1046. package/dist/__w3kits/assets/skills/platform-design/SKILL.md +43 -0
  1047. package/dist/__w3kits/assets/skills/pptx/SKILL.md +43 -0
  1048. package/dist/__w3kits/assets/skills/pptx-generator/SKILL.md +42 -0
  1049. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/SKILL.md +254 -0
  1050. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/references/audit-table-template.md +58 -0
  1051. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/references/font-discipline.md +363 -0
  1052. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/references/layout-discipline.md +371 -0
  1053. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/scripts/extract_pptx.py +134 -0
  1054. package/dist/__w3kits/assets/skills/pptx-html-fidelity-audit/scripts/verify_layout.py +144 -0
  1055. package/dist/__w3kits/assets/skills/release-notes-one-pager/SKILL.md +107 -0
  1056. package/dist/__w3kits/assets/skills/release-notes-one-pager/assets/template.html +342 -0
  1057. package/dist/__w3kits/assets/skills/release-notes-one-pager/example.html +156 -0
  1058. package/dist/__w3kits/assets/skills/release-notes-one-pager/references/checklist.md +41 -0
  1059. package/dist/__w3kits/assets/skills/release-notes-one-pager/references/layouts.md +299 -0
  1060. package/dist/__w3kits/assets/skills/remotion/SKILL.md +43 -0
  1061. package/dist/__w3kits/assets/skills/replicate/SKILL.md +42 -0
  1062. package/dist/__w3kits/assets/skills/screenshot/SKILL.md +42 -0
  1063. package/dist/__w3kits/assets/skills/screenshots-marketing/SKILL.md +42 -0
  1064. package/dist/__w3kits/assets/skills/shadcn-ui/SKILL.md +42 -0
  1065. package/dist/__w3kits/assets/skills/shader-dev/SKILL.md +43 -0
  1066. package/dist/__w3kits/assets/skills/slack-gif-creator/SKILL.md +42 -0
  1067. package/dist/__w3kits/assets/skills/slides/SKILL.md +42 -0
  1068. package/dist/__w3kits/assets/skills/sora/SKILL.md +43 -0
  1069. package/dist/__w3kits/assets/skills/speech/SKILL.md +42 -0
  1070. package/dist/__w3kits/assets/skills/stitch-loop/SKILL.md +42 -0
  1071. package/dist/__w3kits/assets/skills/swiftui-design/SKILL.md +43 -0
  1072. package/dist/__w3kits/assets/skills/swiss-creative-mode-template/SKILL.md +79 -0
  1073. package/dist/__w3kits/assets/skills/swiss-creative-mode-template/assets/template.html +375 -0
  1074. package/dist/__w3kits/assets/skills/swiss-creative-mode-template/example.html +70 -0
  1075. package/dist/__w3kits/assets/skills/swiss-creative-mode-template/references/checklist.md +33 -0
  1076. package/dist/__w3kits/assets/skills/swiss-user-research-video-template/SKILL.md +81 -0
  1077. package/dist/__w3kits/assets/skills/swiss-user-research-video-template/assets/template.html +265 -0
  1078. package/dist/__w3kits/assets/skills/swiss-user-research-video-template/example.html +265 -0
  1079. package/dist/__w3kits/assets/skills/swiss-user-research-video-template/references/checklist.md +24 -0
  1080. package/dist/__w3kits/assets/skills/taste-skill/SKILL.md +43 -0
  1081. package/dist/__w3kits/assets/skills/theme-factory/SKILL.md +43 -0
  1082. package/dist/__w3kits/assets/skills/threejs/SKILL.md +43 -0
  1083. package/dist/__w3kits/assets/skills/ui-skills/SKILL.md +42 -0
  1084. package/dist/__w3kits/assets/skills/ui-ux-pro-max/SKILL.md +42 -0
  1085. package/dist/__w3kits/assets/skills/venice-audio-music/SKILL.md +43 -0
  1086. package/dist/__w3kits/assets/skills/venice-audio-speech/SKILL.md +43 -0
  1087. package/dist/__w3kits/assets/skills/venice-image-edit/SKILL.md +41 -0
  1088. package/dist/__w3kits/assets/skills/venice-image-generate/SKILL.md +41 -0
  1089. package/dist/__w3kits/assets/skills/venice-video/SKILL.md +41 -0
  1090. package/dist/__w3kits/assets/skills/video-downloader/SKILL.md +42 -0
  1091. package/dist/__w3kits/assets/skills/web-artifacts-builder/SKILL.md +42 -0
  1092. package/dist/__w3kits/assets/skills/web-design-guidelines/SKILL.md +42 -0
  1093. package/dist/__w3kits/assets/skills/wpds/SKILL.md +42 -0
  1094. package/dist/__w3kits/assets/skills/youtube-clipper/SKILL.md +42 -0
  1095. package/dist/__w3kits/daemon-proxy-sw.js +45 -0
  1096. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/acp.d.ts +59 -0
  1097. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/acp.js +595 -0
  1098. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/acp.js.map +1 -0
  1099. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/active-context-routes.d.ts +5 -0
  1100. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/active-context-routes.js +64 -0
  1101. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/active-context-routes.js.map +1 -0
  1102. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/agents.d.ts +9 -0
  1103. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/agents.js +11 -0
  1104. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/agents.js.map +1 -0
  1105. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/analytics.d.ts +32 -0
  1106. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/analytics.js +140 -0
  1107. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/analytics.js.map +1 -0
  1108. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-config.d.ts +34 -0
  1109. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-config.js +305 -0
  1110. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-config.js.map +1 -0
  1111. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-version.d.ts +26 -0
  1112. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-version.js +94 -0
  1113. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/app-version.js.map +1 -0
  1114. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-manifest.d.ts +13 -0
  1115. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-manifest.js +244 -0
  1116. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-manifest.js.map +1 -0
  1117. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-stub-guard.d.ts +50 -0
  1118. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-stub-guard.js +252 -0
  1119. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/artifact-stub-guard.js.map +1 -0
  1120. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/browser-open.d.ts +16 -0
  1121. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/browser-open.js +57 -0
  1122. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/browser-open.js.map +1 -0
  1123. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/chat-routes.d.ts +5 -0
  1124. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/chat-routes.js +983 -0
  1125. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/chat-routes.js.map +1 -0
  1126. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-design-import.d.ts +4 -0
  1127. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-design-import.js +217 -0
  1128. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-design-import.js.map +1 -0
  1129. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-diagnostics.d.ts +14 -0
  1130. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-diagnostics.js +96 -0
  1131. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-diagnostics.js.map +1 -0
  1132. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-stream.d.ts +27 -0
  1133. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-stream.js +255 -0
  1134. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/claude-stream.js.map +1 -0
  1135. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cli.d.ts +2 -0
  1136. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cli.js +681 -0
  1137. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cli.js.map +1 -0
  1138. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/codex-pets.d.ts +26 -0
  1139. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/codex-pets.js +234 -0
  1140. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/codex-pets.js.map +1 -0
  1141. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/community-pets-sync.d.ts +15 -0
  1142. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/community-pets-sync.js +233 -0
  1143. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/community-pets-sync.js.map +1 -0
  1144. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectionTest.d.ts +31 -0
  1145. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectionTest.js +1252 -0
  1146. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectionTest.js.map +1 -0
  1147. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/catalog.d.ts +121 -0
  1148. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/catalog.js +102 -0
  1149. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/catalog.js.map +1 -0
  1150. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-config.d.ts +14 -0
  1151. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-config.js +101 -0
  1152. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-config.js.map +1 -0
  1153. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-curation.d.ts +2 -0
  1154. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-curation.js +120 -0
  1155. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-curation.js.map +1 -0
  1156. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-descriptions.d.ts +15 -0
  1157. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-descriptions.js +765 -0
  1158. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio-descriptions.js.map +1 -0
  1159. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio.d.ts +114 -0
  1160. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio.js +1328 -0
  1161. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/composio.js.map +1 -0
  1162. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/routes.d.ts +23 -0
  1163. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/routes.js +735 -0
  1164. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/routes.js.map +1 -0
  1165. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/service.d.ts +173 -0
  1166. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/service.js +714 -0
  1167. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/connectors/service.js.map +1 -0
  1168. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/constants.d.ts +1 -0
  1169. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/constants.js +2 -0
  1170. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/constants.js.map +1 -0
  1171. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/copilot-stream.d.ts +29 -0
  1172. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/copilot-stream.js +129 -0
  1173. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/copilot-stream.js.map +1 -0
  1174. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/craft.d.ts +11 -0
  1175. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/craft.js +47 -0
  1176. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/craft.js.map +1 -0
  1177. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-bad.d.ts +20 -0
  1178. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-bad.js +30 -0
  1179. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-bad.js.map +1 -0
  1180. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-good.d.ts +42 -0
  1181. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-good.js +52 -0
  1182. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/adapters/synthetic-good.js.map +1 -0
  1183. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/run-nightly.d.ts +24 -0
  1184. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/run-nightly.js +90 -0
  1185. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/__fixtures__/run-nightly.js.map +1 -0
  1186. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/adapter-degraded.d.ts +69 -0
  1187. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/adapter-degraded.js +110 -0
  1188. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/adapter-degraded.js.map +1 -0
  1189. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-handler.d.ts +24 -0
  1190. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-handler.js +195 -0
  1191. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-handler.js.map +1 -0
  1192. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-writer.d.ts +79 -0
  1193. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-writer.js +142 -0
  1194. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/artifact-writer.js.map +1 -0
  1195. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/config.d.ts +10 -0
  1196. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/config.js +72 -0
  1197. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/config.js.map +1 -0
  1198. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance-history.d.ts +48 -0
  1199. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance-history.js +119 -0
  1200. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance-history.js.map +1 -0
  1201. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance.d.ts +103 -0
  1202. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance.js +190 -0
  1203. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/conformance.js.map +1 -0
  1204. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/errors.d.ts +11 -0
  1205. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/errors.js +23 -0
  1206. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/errors.js.map +1 -0
  1207. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/interrupt-handler.d.ts +20 -0
  1208. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/interrupt-handler.js +110 -0
  1209. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/interrupt-handler.js.map +1 -0
  1210. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/orchestrator.d.ts +72 -0
  1211. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/orchestrator.js +806 -0
  1212. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/orchestrator.js.map +1 -0
  1213. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parser.d.ts +34 -0
  1214. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parser.js +7 -0
  1215. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parser.js.map +1 -0
  1216. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parsers/v1.d.ts +48 -0
  1217. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parsers/v1.js +526 -0
  1218. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/parsers/v1.js.map +1 -0
  1219. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/persistence.d.ts +101 -0
  1220. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/persistence.js +238 -0
  1221. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/persistence.js.map +1 -0
  1222. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/ratchet.d.ts +100 -0
  1223. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/ratchet.js +192 -0
  1224. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/ratchet.js.map +1 -0
  1225. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/rollout.d.ts +93 -0
  1226. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/rollout.js +125 -0
  1227. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/rollout.js.map +1 -0
  1228. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/run-registry.d.ts +59 -0
  1229. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/run-registry.js +58 -0
  1230. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/run-registry.js.map +1 -0
  1231. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/scoreboard.d.ts +39 -0
  1232. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/scoreboard.js +62 -0
  1233. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/scoreboard.js.map +1 -0
  1234. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/spawn-inputs.d.ts +33 -0
  1235. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/spawn-inputs.js +40 -0
  1236. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/spawn-inputs.js.map +1 -0
  1237. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/transcript.d.ts +30 -0
  1238. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/transcript.js +153 -0
  1239. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/critique/transcript.js.map +1 -0
  1240. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cwd-aliases.d.ts +22 -0
  1241. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cwd-aliases.js +131 -0
  1242. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/cwd-aliases.js.map +1 -0
  1243. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/db.d.ts +449 -0
  1244. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/db.js +1142 -0
  1245. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/db.js.map +1 -0
  1246. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy-routes.d.ts +8 -0
  1247. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy-routes.js +201 -0
  1248. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy-routes.js.map +1 -0
  1249. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy.d.ts +288 -0
  1250. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy.js +1816 -0
  1251. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/deploy.js.map +1 -0
  1252. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-preview.d.ts +12 -0
  1253. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-preview.js +603 -0
  1254. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-preview.js.map +1 -0
  1255. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-showcase.d.ts +18 -0
  1256. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-showcase.js +844 -0
  1257. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-system-showcase.js.map +1 -0
  1258. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-systems.d.ts +73 -0
  1259. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-systems.js +266 -0
  1260. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/design-systems.js.map +1 -0
  1261. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/document-preview.d.ts +26 -0
  1262. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/document-preview.js +286 -0
  1263. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/document-preview.js.map +1 -0
  1264. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/elevenlabs-voices.d.ts +10 -0
  1265. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/elevenlabs-voices.js +108 -0
  1266. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/elevenlabs-voices.js.map +1 -0
  1267. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/finalize-design.d.ts +151 -0
  1268. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/finalize-design.js +547 -0
  1269. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/finalize-design.js.map +1 -0
  1270. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/frontmatter.d.ts +10 -0
  1271. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/frontmatter.js +155 -0
  1272. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/frontmatter.js.map +1 -0
  1273. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/home-expansion.d.ts +2 -0
  1274. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/home-expansion.js +39 -0
  1275. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/home-expansion.js.map +1 -0
  1276. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/import-export-routes.d.ts +11 -0
  1277. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/import-export-routes.js +482 -0
  1278. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/import-export-routes.js.map +1 -0
  1279. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/inline-assets.d.ts +50 -0
  1280. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/inline-assets.js +332 -0
  1281. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/inline-assets.js.map +1 -0
  1282. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/json-event-stream.d.ts +8 -0
  1283. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/json-event-stream.js +405 -0
  1284. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/json-event-stream.js.map +1 -0
  1285. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-bridge.d.ts +35 -0
  1286. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-bridge.js +273 -0
  1287. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-bridge.js.map +1 -0
  1288. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-trace.d.ts +110 -0
  1289. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-trace.js +479 -0
  1290. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/langfuse-trace.js.map +1 -0
  1291. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/legacy-data-migrator.d.ts +90 -0
  1292. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/legacy-data-migrator.js +340 -0
  1293. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/legacy-data-migrator.js.map +1 -0
  1294. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/library-install.d.ts +36 -0
  1295. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/library-install.js +174 -0
  1296. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/library-install.js.map +1 -0
  1297. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/linked-dirs.d.ts +8 -0
  1298. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/linked-dirs.js +62 -0
  1299. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/linked-dirs.js.map +1 -0
  1300. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/lint-artifact.d.ts +44 -0
  1301. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/lint-artifact.js +952 -0
  1302. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/lint-artifact.js.map +1 -0
  1303. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifact-routes.d.ts +5 -0
  1304. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifact-routes.js +305 -0
  1305. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifact-routes.js.map +1 -0
  1306. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh-service.d.ts +23 -0
  1307. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh-service.js +178 -0
  1308. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh-service.js.map +1 -0
  1309. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh.d.ts +92 -0
  1310. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh.js +641 -0
  1311. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/refresh.js.map +1 -0
  1312. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/render.d.ts +15 -0
  1313. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/render.js +68 -0
  1314. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/render.js.map +1 -0
  1315. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/schema.d.ts +144 -0
  1316. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/schema.js +702 -0
  1317. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/schema.js.map +1 -0
  1318. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/store.d.ts +214 -0
  1319. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/store.js +1002 -0
  1320. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/live-artifacts/store.js.map +1 -0
  1321. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/logging/critique.d.ts +57 -0
  1322. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/logging/critique.js +30 -0
  1323. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/logging/critique.js.map +1 -0
  1324. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-config.d.ts +88 -0
  1325. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-config.js +878 -0
  1326. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-config.js.map +1 -0
  1327. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-daemon-url.d.ts +22 -0
  1328. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-daemon-url.js +44 -0
  1329. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-daemon-url.js.map +1 -0
  1330. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-install-info.d.ts +29 -0
  1331. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-install-info.js +60 -0
  1332. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-install-info.js.map +1 -0
  1333. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-live-artifacts-server.d.ts +19 -0
  1334. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-live-artifacts-server.js +238 -0
  1335. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-live-artifacts-server.js.map +1 -0
  1336. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-oauth.d.ts +155 -0
  1337. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-oauth.js +412 -0
  1338. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-oauth.js.map +1 -0
  1339. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-routes.d.ts +5 -0
  1340. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-routes.js +365 -0
  1341. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-routes.js.map +1 -0
  1342. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-tokens.d.ts +59 -0
  1343. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-tokens.js +189 -0
  1344. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp-tokens.js.map +1 -0
  1345. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp.d.ts +52 -0
  1346. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp.js +847 -0
  1347. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/mcp.js.map +1 -0
  1348. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-config.d.ts +69 -0
  1349. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-config.js +408 -0
  1350. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-config.js.map +1 -0
  1351. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-models.d.ts +31 -0
  1352. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-models.js +136 -0
  1353. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-models.js.map +1 -0
  1354. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-routes.d.ts +5 -0
  1355. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-routes.js +316 -0
  1356. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-routes.js.map +1 -0
  1357. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-tasks.d.ts +65 -0
  1358. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-tasks.js +199 -0
  1359. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media-tasks.js.map +1 -0
  1360. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media.d.ts +56 -0
  1361. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media.js +2065 -0
  1362. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/media.js.map +1 -0
  1363. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-extractions.d.ts +26 -0
  1364. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-extractions.js +233 -0
  1365. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-extractions.js.map +1 -0
  1366. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-llm.d.ts +7 -0
  1367. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-llm.js +809 -0
  1368. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory-llm.js.map +1 -0
  1369. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory.d.ts +70 -0
  1370. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory.js +654 -0
  1371. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/memory.js.map +1 -0
  1372. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/metrics/index.d.ts +51 -0
  1373. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/metrics/index.js +111 -0
  1374. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/metrics/index.js.map +1 -0
  1375. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/native-folder-dialog.d.ts +6 -0
  1376. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/native-folder-dialog.js +32 -0
  1377. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/native-folder-dialog.js.map +1 -0
  1378. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit-agent-summary.d.ts +7 -0
  1379. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit-agent-summary.js +34 -0
  1380. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit-agent-summary.js.map +1 -0
  1381. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit.d.ts +93 -0
  1382. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit.js +400 -0
  1383. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/orbit.js.map +1 -0
  1384. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/origin-validation.d.ts +21 -0
  1385. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/origin-validation.js +149 -0
  1386. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/origin-validation.js.map +1 -0
  1387. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pdf-export.d.ts +10 -0
  1388. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pdf-export.js +43 -0
  1389. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pdf-export.js.map +1 -0
  1390. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pi-rpc.d.ts +93 -0
  1391. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pi-rpc.js +475 -0
  1392. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/pi-rpc.js.map +1 -0
  1393. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-routes.d.ts +14 -0
  1394. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-routes.js +867 -0
  1395. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-routes.js.map +1 -0
  1396. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-watchers.d.ts +52 -0
  1397. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-watchers.js +162 -0
  1398. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/project-watchers.js.map +1 -0
  1399. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/projects.d.ts +90 -0
  1400. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/projects.js +1186 -0
  1401. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/projects.js.map +1 -0
  1402. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompt-templates.d.ts +24 -0
  1403. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompt-templates.js +122 -0
  1404. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompt-templates.js.map +1 -0
  1405. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/deck-framework.d.ts +38 -0
  1406. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/deck-framework.js +373 -0
  1407. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/deck-framework.js.map +1 -0
  1408. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/directions.d.ts +68 -0
  1409. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/directions.js +237 -0
  1410. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/directions.js.map +1 -0
  1411. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/discovery.d.ts +1 -0
  1412. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/discovery.js +262 -0
  1413. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/discovery.js.map +1 -0
  1414. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/media-contract.d.ts +1 -0
  1415. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/media-contract.js +359 -0
  1416. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/media-contract.js.map +1 -0
  1417. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/official-system.d.ts +11 -0
  1418. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/official-system.js +124 -0
  1419. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/official-system.js.map +1 -0
  1420. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/panel.d.ts +48 -0
  1421. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/panel.js +196 -0
  1422. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/panel.js.map +1 -0
  1423. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/research-contract.d.ts +5 -0
  1424. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/research-contract.js +52 -0
  1425. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/research-contract.js.map +1 -0
  1426. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/system.d.ts +97 -0
  1427. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/system.js +598 -0
  1428. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/prompts/system.js.map +1 -0
  1429. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/providerModels.d.ts +6 -0
  1430. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/providerModels.js +284 -0
  1431. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/providerModels.js.map +1 -0
  1432. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/qoder-stream.d.ts +13 -0
  1433. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/qoder-stream.js +162 -0
  1434. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/qoder-stream.js.map +1 -0
  1435. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/redact.d.ts +18 -0
  1436. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/redact.js +179 -0
  1437. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/redact.js.map +1 -0
  1438. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/cli-args.d.ts +5 -0
  1439. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/cli-args.js +11 -0
  1440. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/cli-args.js.map +1 -0
  1441. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/index.d.ts +14 -0
  1442. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/index.js +78 -0
  1443. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/index.js.map +1 -0
  1444. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/tavily.d.ts +19 -0
  1445. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/tavily.js +78 -0
  1446. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/research/tavily.js.map +1 -0
  1447. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/route-context-contract.d.ts +16 -0
  1448. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/route-context-contract.js +4 -0
  1449. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/route-context-contract.js.map +1 -0
  1450. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routine-routes.d.ts +37 -0
  1451. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routine-routes.js +212 -0
  1452. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routine-routes.js.map +1 -0
  1453. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routines.d.ts +100 -0
  1454. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routines.js +390 -0
  1455. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/routines.js.map +1 -0
  1456. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runs.d.ts +59 -0
  1457. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runs.js +217 -0
  1458. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runs.js.map +1 -0
  1459. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/auth.d.ts +9 -0
  1460. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/auth.js +58 -0
  1461. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/auth.js.map +1 -0
  1462. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/capabilities.d.ts +2 -0
  1463. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/capabilities.js +2 -0
  1464. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/capabilities.js.map +1 -0
  1465. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/claude.d.ts +17 -0
  1466. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/claude.js +75 -0
  1467. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/claude.js.map +1 -0
  1468. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/codex.d.ts +15 -0
  1469. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/codex.js +82 -0
  1470. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/codex.js.map +1 -0
  1471. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/copilot.d.ts +10 -0
  1472. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/copilot.js +68 -0
  1473. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/copilot.js.map +1 -0
  1474. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/cursor-agent.d.ts +16 -0
  1475. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/cursor-agent.js +46 -0
  1476. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/cursor-agent.js.map +1 -0
  1477. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/deepseek.d.ts +10 -0
  1478. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/deepseek.js +54 -0
  1479. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/deepseek.js.map +1 -0
  1480. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/devin.d.ts +10 -0
  1481. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/devin.js +43 -0
  1482. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/devin.js.map +1 -0
  1483. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/gemini.d.ts +14 -0
  1484. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/gemini.js +37 -0
  1485. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/gemini.js.map +1 -0
  1486. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/hermes.d.ts +11 -0
  1487. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/hermes.js +27 -0
  1488. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/hermes.js.map +1 -0
  1489. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kilo.d.ts +10 -0
  1490. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kilo.js +18 -0
  1491. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kilo.js.map +1 -0
  1492. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kimi.d.ts +11 -0
  1493. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kimi.js +24 -0
  1494. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kimi.js.map +1 -0
  1495. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kiro.d.ts +10 -0
  1496. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kiro.js +18 -0
  1497. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/kiro.js.map +1 -0
  1498. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/opencode.d.ts +18 -0
  1499. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/opencode.js +43 -0
  1500. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/opencode.js.map +1 -0
  1501. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/pi.d.ts +19 -0
  1502. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/pi.js +88 -0
  1503. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/pi.js.map +1 -0
  1504. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qoder.d.ts +10 -0
  1505. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qoder.js +49 -0
  1506. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qoder.js.map +1 -0
  1507. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qwen.d.ts +10 -0
  1508. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qwen.js +26 -0
  1509. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/qwen.js.map +1 -0
  1510. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/shared.d.ts +8 -0
  1511. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/shared.js +44 -0
  1512. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/shared.js.map +1 -0
  1513. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/vibe.d.ts +10 -0
  1514. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/vibe.js +18 -0
  1515. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/defs/vibe.js.map +1 -0
  1516. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/detection.d.ts +9 -0
  1517. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/detection.js +180 -0
  1518. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/detection.js.map +1 -0
  1519. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/env.d.ts +3 -0
  1520. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/env.js +38 -0
  1521. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/env.js.map +1 -0
  1522. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/executables.d.ts +8 -0
  1523. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/executables.js +155 -0
  1524. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/executables.js.map +1 -0
  1525. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/invocation.d.ts +5 -0
  1526. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/invocation.js +21 -0
  1527. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/invocation.js.map +1 -0
  1528. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/launch.d.ts +11 -0
  1529. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/launch.js +147 -0
  1530. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/launch.js.map +1 -0
  1531. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/mcp.d.ts +13 -0
  1532. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/mcp.js +13 -0
  1533. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/mcp.js.map +1 -0
  1534. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/metadata.d.ts +4 -0
  1535. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/metadata.js +90 -0
  1536. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/metadata.js.map +1 -0
  1537. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/models.d.ts +5 -0
  1538. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/models.js +43 -0
  1539. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/models.js.map +1 -0
  1540. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/paths.d.ts +2 -0
  1541. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/paths.js +22 -0
  1542. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/paths.js.map +1 -0
  1543. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/prompt-budget.d.ts +4 -0
  1544. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/prompt-budget.js +202 -0
  1545. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/prompt-budget.js.map +1 -0
  1546. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/registry.d.ts +3 -0
  1547. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/registry.js +45 -0
  1548. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/registry.js.map +1 -0
  1549. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/resolution.d.ts +1 -0
  1550. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/resolution.js +13 -0
  1551. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/resolution.js.map +1 -0
  1552. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/types.d.ts +62 -0
  1553. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/types.js +2 -0
  1554. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/runtimes/types.js.map +1 -0
  1555. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server-context.d.ts +93 -0
  1556. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server-context.js +2 -0
  1557. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server-context.js.map +1 -0
  1558. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server.d.ts +160 -0
  1559. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server.js +4384 -0
  1560. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/server.js.map +1 -0
  1561. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/index.d.ts +1 -0
  1562. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/index.js +21 -0
  1563. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/index.js.map +1 -0
  1564. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/server.d.ts +23 -0
  1565. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/server.js +175 -0
  1566. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/sidecar/server.js.map +1 -0
  1567. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/skills.d.ts +100 -0
  1568. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/skills.js +836 -0
  1569. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/skills.js.map +1 -0
  1570. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/static-resource-routes.d.ts +5 -0
  1571. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/static-resource-routes.js +593 -0
  1572. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/static-resource-routes.js.map +1 -0
  1573. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tool-tokens.d.ts +47 -0
  1574. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tool-tokens.js +131 -0
  1575. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tool-tokens.js.map +1 -0
  1576. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools/connectors.d.ts +12 -0
  1577. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools/connectors.js +124 -0
  1578. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools/connectors.js.map +1 -0
  1579. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-connectors-cli.d.ts +5 -0
  1580. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-connectors-cli.js +270 -0
  1581. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-connectors-cli.js.map +1 -0
  1582. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-live-artifacts-cli.d.ts +5 -0
  1583. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-live-artifacts-cli.js +282 -0
  1584. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/tools-live-artifacts-cli.js.map +1 -0
  1585. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/transcript-export.d.ts +16 -0
  1586. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/transcript-export.js +388 -0
  1587. package/dist/__w3kits/webcontainer-runtime/apps/daemon/dist/transcript-export.js.map +1 -0
  1588. package/dist/__w3kits/webcontainer-runtime/apps/daemon/package.json +62 -0
  1589. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/browser-vfs/dist/index.d.ts +108 -0
  1590. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/browser-vfs/dist/index.d.ts.map +1 -0
  1591. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/browser-vfs/dist/index.mjs +413 -0
  1592. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/browser-vfs/package.json +12 -0
  1593. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/artifact-id.d.ts +5 -0
  1594. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/artifact-id.d.ts.map +1 -0
  1595. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/events.d.ts +250 -0
  1596. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/events.d.ts.map +1 -0
  1597. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/index.d.ts +4 -0
  1598. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/index.d.ts.map +1 -0
  1599. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/index.mjs +186 -0
  1600. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/public-params.d.ts +26 -0
  1601. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/analytics/public-params.d.ts.map +1 -0
  1602. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/app-config.d.ts +44 -0
  1603. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/app-config.d.ts.map +1 -0
  1604. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/artifacts.d.ts +34 -0
  1605. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/artifacts.d.ts.map +1 -0
  1606. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/chat.d.ts +158 -0
  1607. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/chat.d.ts.map +1 -0
  1608. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/comments.d.ts +65 -0
  1609. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/comments.d.ts.map +1 -0
  1610. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/connectionTest.d.ts +49 -0
  1611. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/connectionTest.d.ts.map +1 -0
  1612. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/connectionTest.mjs +83 -0
  1613. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/connectors.d.ts +133 -0
  1614. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/connectors.d.ts.map +1 -0
  1615. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/files.d.ts +43 -0
  1616. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/files.d.ts.map +1 -0
  1617. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/finalize.d.ts +50 -0
  1618. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/finalize.d.ts.map +1 -0
  1619. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/finalize.mjs +5 -0
  1620. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/live-artifacts.d.ts +151 -0
  1621. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/live-artifacts.d.ts.map +1 -0
  1622. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/mcp.d.ts +117 -0
  1623. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/mcp.d.ts.map +1 -0
  1624. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/memory.d.ts +233 -0
  1625. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/memory.d.ts.map +1 -0
  1626. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/orbit.d.ts +22 -0
  1627. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/orbit.d.ts.map +1 -0
  1628. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/orbit.mjs +0 -0
  1629. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/projects.d.ts +286 -0
  1630. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/projects.d.ts.map +1 -0
  1631. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/providerModels.d.ts +19 -0
  1632. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/providerModels.d.ts.map +1 -0
  1633. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/providerModels.mjs +0 -0
  1634. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/proxy.d.ts +24 -0
  1635. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/proxy.d.ts.map +1 -0
  1636. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/registry.d.ts +156 -0
  1637. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/registry.d.ts.map +1 -0
  1638. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/research.d.ts +35 -0
  1639. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/research.d.ts.map +1 -0
  1640. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/research.mjs +9 -0
  1641. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/routines.d.ts +104 -0
  1642. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/routines.d.ts.map +1 -0
  1643. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/version.d.ts +11 -0
  1644. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/api/version.d.ts.map +1 -0
  1645. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/common.d.ts +33 -0
  1646. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/common.d.ts.map +1 -0
  1647. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/critique.d.ts +344 -0
  1648. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/critique.d.ts.map +1 -0
  1649. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/critique.mjs +182 -0
  1650. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/errors.d.ts +40 -0
  1651. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/errors.d.ts.map +1 -0
  1652. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/examples.d.ts +20 -0
  1653. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/examples.d.ts.map +1 -0
  1654. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/index.d.ts +31 -0
  1655. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/index.d.ts.map +1 -0
  1656. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/index.mjs +2072 -0
  1657. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/deck-framework.d.ts +39 -0
  1658. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/deck-framework.d.ts.map +1 -0
  1659. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/directions.d.ts +69 -0
  1660. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/directions.d.ts.map +1 -0
  1661. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/discovery.d.ts +2 -0
  1662. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/discovery.d.ts.map +1 -0
  1663. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/media-contract.d.ts +2 -0
  1664. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/media-contract.d.ts.map +1 -0
  1665. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/official-system.d.ts +12 -0
  1666. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/official-system.d.ts.map +1 -0
  1667. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/system.d.ts +58 -0
  1668. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/prompts/system.d.ts.map +1 -0
  1669. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/chat.d.ts +96 -0
  1670. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/chat.d.ts.map +1 -0
  1671. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/common.d.ts +8 -0
  1672. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/common.d.ts.map +1 -0
  1673. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/proxy.d.ts +6 -0
  1674. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/sse/proxy.d.ts.map +1 -0
  1675. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/tasks.d.ts +12 -0
  1676. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/dist/tasks.d.ts.map +1 -0
  1677. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/contracts/package.json +40 -0
  1678. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/platform/dist/index.d.ts +68 -0
  1679. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/platform/dist/index.d.ts.map +1 -0
  1680. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/platform/dist/index.mjs +397 -0
  1681. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/platform/package.json +12 -0
  1682. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar/dist/index.d.ts +144 -0
  1683. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar/dist/index.d.ts.map +1 -0
  1684. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar/dist/index.mjs +412 -0
  1685. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar/package.json +12 -0
  1686. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar-proto/dist/index.d.ts +291 -0
  1687. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar-proto/dist/index.d.ts.map +1 -0
  1688. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar-proto/dist/index.mjs +315 -0
  1689. package/dist/__w3kits/webcontainer-runtime/node_modules/@open-design/sidecar-proto/package.json +12 -0
  1690. package/dist/__w3kits/webcontainer-runtime/package.json +20 -0
  1691. package/dist/__w3kits/webcontainer-runtime.json +68 -0
  1692. package/dist/_not-found/__next._full.txt +1 -1
  1693. package/dist/_not-found/__next._head.txt +1 -1
  1694. package/dist/_not-found/__next._index.txt +1 -1
  1695. package/dist/_not-found/__next._not-found.__PAGE__.txt +1 -1
  1696. package/dist/_not-found/__next._not-found.txt +1 -1
  1697. package/dist/_not-found/__next._tree.txt +1 -1
  1698. package/dist/_not-found/index.html +1 -1
  1699. package/dist/_not-found/index.txt +1 -1
  1700. package/dist/browser-daemon.js +113 -7
  1701. package/dist/index.html +1 -1
  1702. package/dist/index.txt +1 -1
  1703. package/package.json +3 -2
  1704. /package/dist/_next/static/{ptaOAJFvinIcai1ShQRcW → Jxi73Py0I4WvBhRY47OF-}/_buildManifest.js +0 -0
  1705. /package/dist/_next/static/{ptaOAJFvinIcai1ShQRcW → Jxi73Py0I4WvBhRY47OF-}/_clientMiddlewareManifest.js +0 -0
  1706. /package/dist/_next/static/{ptaOAJFvinIcai1ShQRcW → Jxi73Py0I4WvBhRY47OF-}/_ssgManifest.js +0 -0
@@ -0,0 +1,4384 @@
1
+ import express from 'express';
2
+ import multer from 'multer';
3
+ import { execFile, spawn } from 'node:child_process';
4
+ import { createHmac, randomUUID, timingSafeEqual } from 'node:crypto';
5
+ import { createRequire } from 'node:module';
6
+ import { fileURLToPath } from 'node:url';
7
+ import path from 'node:path';
8
+ import fs from 'node:fs';
9
+ import os from 'node:os';
10
+ import net from 'node:net';
11
+ import { composeSystemPrompt, renderCodexImagegenOverride, shouldRenderCodexImagegenOverride, } from './prompts/system.js';
12
+ import { resolveProjectRelativePath } from './home-expansion.js';
13
+ import { createCommandInvocation } from '@open-design/platform';
14
+ import { buildLiveArtifactsMcpServersForAgent, checkPromptArgvBudget, checkWindowsCmdShimCommandLineBudget, checkWindowsDirectExeCommandLineBudget, detectAgents, getAgentDef, isKnownModel, applyAgentLaunchEnv, resolveAgentLaunch, sanitizeCustomModel, spawnEnvForAgent, } from './agents.js';
15
+ import { migrateLegacyDataDirSync } from './legacy-data-migrator.js';
16
+ import { findSkillById, listSkills } from './skills.js';
17
+ import { validateLinkedDirs } from './linked-dirs.js';
18
+ import { buildWindowsFolderDialogCommand, parseFolderDialogStdout } from './native-folder-dialog.js';
19
+ import { listDesignSystems, readDesignSystem, resolveDesignSystemAssets, } from './design-systems.js';
20
+ import { composeMemoryBody, deleteMemoryEntry, extractFromMessage, listMemoryEntries, maskMemoryExtractionConfig, memoryDir, memoryEvents, readMemoryConfig, readMemoryEntry, readMemoryIndex, upsertMemoryEntry, writeMemoryConfig, writeMemoryIndex, } from './memory.js';
21
+ import { clearExtractions as clearMemoryExtractions, listExtractions as listMemoryExtractions, removeExtraction as removeMemoryExtraction, } from './memory-extractions.js';
22
+ import { attachAcpSession } from './acp.js';
23
+ import { attachPiRpcSession } from './pi-rpc.js';
24
+ import { createClaudeStreamHandler } from './claude-stream.js';
25
+ import { diagnoseClaudeCliFailure } from './claude-diagnostics.js';
26
+ import { loadCritiqueConfigFromEnv } from './critique/config.js';
27
+ import { reconcileStaleRuns } from './critique/persistence.js';
28
+ import { runOrchestrator } from './critique/orchestrator.js';
29
+ import { createRunRegistry } from './critique/run-registry.js';
30
+ import { handleCritiqueInterrupt } from './critique/interrupt-handler.js';
31
+ import { handleCritiqueArtifact } from './critique/artifact-handler.js';
32
+ import { getCritiqueMetrics, register } from './metrics/index.js';
33
+ import { readConformanceHistory } from './critique/conformance-history.js';
34
+ import { evaluateRollout } from './critique/ratchet.js';
35
+ import { isCritiqueEnabled, parseEnvEnabled, parseRolloutPhase, } from './critique/rollout.js';
36
+ import { narrowProjectCritiqueOverride } from './critique/spawn-inputs.js';
37
+ import { createCopilotStreamHandler } from './copilot-stream.js';
38
+ import { createJsonEventStreamHandler } from './json-event-stream.js';
39
+ import { classifyAgentAuthFailure, cursorAuthGuidance } from './runtimes/auth.js';
40
+ import { createQoderStreamHandler } from './qoder-stream.js';
41
+ import { subscribe as subscribeFileEvents } from './project-watchers.js';
42
+ import { createChatRunService } from './runs.js';
43
+ import { reportRunCompletedFromDaemon } from './langfuse-bridge.js';
44
+ import { createAnalyticsService, readAnalyticsContext, readPublicConfigResponse, } from './analytics.js';
45
+ import { redactSecrets, testAgentConnection, testProviderConnection, validateBaseUrl, } from './connectionTest.js';
46
+ import { listProviderModels } from './providerModels.js';
47
+ import { importClaudeDesignZip } from './claude-design-import.js';
48
+ import { finalizeDesignPackage, FinalizePackageLockedError, FinalizeUpstreamError, } from './finalize-design.js';
49
+ import { buildDocumentPreview } from './document-preview.js';
50
+ import { lintArtifact, renderFindingsForAgent } from './lint-artifact.js';
51
+ import { loadCraftSections } from './craft.js';
52
+ import { stageActiveSkill } from './cwd-aliases.js';
53
+ import { buildDesktopPdfExportInput } from './pdf-export.js';
54
+ import { generateMedia } from './media.js';
55
+ import { listElevenLabsVoiceOptions } from './elevenlabs-voices.js';
56
+ import { searchResearch, ResearchError } from './research/index.js';
57
+ import { renderResearchCommandContract } from './prompts/research-contract.js';
58
+ import { AUDIO_DURATIONS_SEC, AUDIO_MODELS_BY_KIND, IMAGE_MODELS, MEDIA_ASPECTS, MEDIA_PROVIDERS, VIDEO_LENGTHS_SEC, VIDEO_MODELS, } from './media-models.js';
59
+ import { readMaskedConfig, writeConfig } from './media-config.js';
60
+ import { deleteMediaTask, getMediaTask, insertMediaTask, listMediaTasksByProject, listRecentMediaTasks, reconcileMediaTasksOnBoot, updateMediaTask, } from './media-tasks.js';
61
+ import { buildAcpMcpServers, buildClaudeMcpJson, isManagedProjectCwd, readMcpConfig, } from './mcp-config.js';
62
+ import { PendingAuthCache, refreshAccessToken, } from './mcp-oauth.js';
63
+ import { isTokenExpired, readAllTokens, setToken, } from './mcp-tokens.js';
64
+ import { agentCliEnvForAgent, readAppConfig, writeAppConfig } from './app-config.js';
65
+ import { OrbitService, formatLocalProjectTimestamp, renderOrbitTemplateSystemPrompt } from './orbit.js';
66
+ import { buildOrbitNoLiveArtifactSummary } from './orbit-agent-summary.js';
67
+ import { RoutineService, } from './routines.js';
68
+ import { buildProjectArchive, buildBatchArchive, decodeMultipartFilename, deleteProjectFile, detectEntryFile, ensureProject, isSafeId, listFiles, mimeFor, parseByteRange, projectDir, readProjectFile, renameProjectFile, removeProjectDir, sanitizeName, searchProjectFiles, resolveProjectDir, resolveProjectFilePath, writeProjectFile, } from './projects.js';
69
+ import { validateArtifactManifestInput } from './artifact-manifest.js';
70
+ import { readCurrentAppVersionInfo } from './app-version.js';
71
+ import { deleteConversation, deletePreviewComment, deleteProject as dbDeleteProject, deleteTemplate, getConversation, getDeployment, getDeploymentById, getProject, getTemplate, insertConversation, insertProject, insertRoutineRun, insertTemplate, findTemplateByNameAndProject, updateTemplate, listProjectsAwaitingInput, listConversations, listDeployments, listLatestProjectRunStatuses, listMessages, listPreviewComments, listProjects, listRoutines, listTabs, listTemplates, getLatestRoutineRun, openDatabase, setTabs, updateConversation, updatePreviewCommentStatus, updateProject, updateRoutineRun, upsertDeployment, upsertMessage, upsertPreviewComment, } from './db.js';
72
+ import { createLiveArtifact, deleteLiveArtifact, ensureLiveArtifactPreview, getLiveArtifact, LiveArtifactRefreshLockError, LiveArtifactStoreValidationError, listLiveArtifacts, listLiveArtifactRefreshLogEntries, readLiveArtifactCode, recoverStaleLiveArtifactRefreshes, updateLiveArtifact, } from './live-artifacts/store.js';
73
+ import { LiveArtifactRefreshUnavailableError, refreshLiveArtifact } from './live-artifacts/refresh-service.js';
74
+ import { LiveArtifactRefreshAbortError } from './live-artifacts/refresh.js';
75
+ import { registerConnectorRoutes } from './connectors/routes.js';
76
+ import { registerActiveContextRoutes } from './active-context-routes.js';
77
+ import { registerMcpRoutes } from './mcp-routes.js';
78
+ import { registerLiveArtifactRoutes } from './live-artifact-routes.js';
79
+ import { registerDeployRoutes, registerDeploymentCheckRoutes } from './deploy-routes.js';
80
+ import { registerMediaRoutes } from './media-routes.js';
81
+ import { registerProjectRoutes, registerProjectArtifactRoutes, registerProjectFileRoutes, registerProjectUploadRoutes } from './project-routes.js';
82
+ import { registerFinalizeRoutes, registerImportRoutes, registerProjectExportRoutes } from './import-export-routes.js';
83
+ import { registerChatRoutes } from './chat-routes.js';
84
+ import { registerStaticResourceRoutes } from './static-resource-routes.js';
85
+ import { registerRoutineRoutes, routineDbRowToContract } from './routine-routes.js';
86
+ import { assertServerContextSatisfiesRoutes } from './route-context-contract.js';
87
+ import { configureConnectorCredentialStore, ConnectorServiceError, FileConnectorCredentialStore } from './connectors/service.js';
88
+ import { composioConnectorProvider } from './connectors/composio.js';
89
+ import { configureComposioConfigStore } from './connectors/composio-config.js';
90
+ import { CHAT_TOOL_ENDPOINTS, CHAT_TOOL_OPERATIONS, toolTokenRegistry } from './tool-tokens.js';
91
+ import { aggregateCloudflarePagesStatus, buildDeployFileSet, checkDeploymentUrl, CLOUDFLARE_PAGES_PROVIDER_ID, cloudflarePagesProjectNameForProject, DeployError, deployToCloudflarePages, deployToVercel, isDeployProviderId, listCloudflarePagesZones, prepareDeployPreflight, publicDeployConfigForProvider, readDeployConfig, readCloudflarePagesDomain, VERCEL_PROVIDER_ID, writeDeployConfig, } from './deploy.js';
92
+ import { allowedBrowserPorts, configuredAllowedOrigins, isAllowedBrowserOrigin, isLocalSameOrigin, } from './origin-validation.js';
93
+ /** @typedef {import('@open-design/contracts').ApiErrorCode} ApiErrorCode */
94
+ /** @typedef {import('@open-design/contracts').ApiError} ApiError */
95
+ /** @typedef {import('@open-design/contracts').ApiErrorResponse} ApiErrorResponse */
96
+ /** @typedef {import('@open-design/contracts').ChatRequest} ChatRequest */
97
+ /** @typedef {import('@open-design/contracts').ChatSseEvent} ChatSseEvent */
98
+ /** @typedef {import('@open-design/contracts').ProxyStreamRequest} ProxyStreamRequest */
99
+ /** @typedef {import('@open-design/contracts').ProxySseEvent} ProxySseEvent */
100
+ /** @typedef {import('@open-design/contracts').ProjectConversationCreatedSsePayload} ProjectConversationCreatedSsePayload */
101
+ const __filename = fileURLToPath(import.meta.url);
102
+ const __dirname = path.dirname(__filename);
103
+ const require = createRequire(import.meta.url);
104
+ const DAEMON_CLI_PATH_ENV = 'OD_DAEMON_CLI_PATH';
105
+ export function resolveProjectRoot(moduleDir) {
106
+ const base = path.basename(moduleDir);
107
+ const daemonDir = base === 'dist' || base === 'src' ? path.dirname(moduleDir) : moduleDir;
108
+ return path.resolve(daemonDir, '../..');
109
+ }
110
+ function cleanOptionalPath(value) {
111
+ return typeof value === 'string' && value.trim().length > 0
112
+ ? path.resolve(value)
113
+ : null;
114
+ }
115
+ export function resolveDaemonCliPath(env = process.env) {
116
+ const configured = cleanOptionalPath(env[DAEMON_CLI_PATH_ENV]) ?? cleanOptionalPath(env.OD_BIN);
117
+ if (configured)
118
+ return configured;
119
+ const packageJsonPath = require.resolve('@open-design/daemon/package.json');
120
+ return path.join(path.dirname(packageJsonPath), 'dist', 'cli.js');
121
+ }
122
+ const PROJECT_ROOT = resolveProjectRoot(__dirname);
123
+ const RESOURCE_ROOT_ENV = 'OD_RESOURCE_ROOT';
124
+ let desktopAuthSecret = null;
125
+ let desktopAuthEverRegistered = process.env.OD_REQUIRE_DESKTOP_AUTH === '1';
126
+ const consumedImportNonces = new Map();
127
+ const DESKTOP_IMPORT_TOKEN_TTL_MS = 60_000;
128
+ const DESKTOP_IMPORT_TOKEN_FIELD_SEP = '~';
129
+ export function setDesktopAuthSecret(secret) {
130
+ desktopAuthSecret = secret;
131
+ if (secret != null) {
132
+ desktopAuthEverRegistered = true;
133
+ }
134
+ consumedImportNonces.clear();
135
+ }
136
+ export function isDesktopAuthRegistered() {
137
+ return desktopAuthSecret != null;
138
+ }
139
+ export function isDesktopAuthGateActive() {
140
+ return desktopAuthEverRegistered;
141
+ }
142
+ export function resetDesktopAuthForTests() {
143
+ desktopAuthSecret = null;
144
+ desktopAuthEverRegistered = process.env.OD_REQUIRE_DESKTOP_AUTH === '1';
145
+ consumedImportNonces.clear();
146
+ }
147
+ function pruneExpiredImportNonces(now) {
148
+ for (const [nonce, exp] of consumedImportNonces) {
149
+ if (exp <= now)
150
+ consumedImportNonces.delete(nonce);
151
+ }
152
+ }
153
+ function timingSafeStringEquals(a, b) {
154
+ const bufA = Buffer.from(a, 'utf8');
155
+ const bufB = Buffer.from(b, 'utf8');
156
+ if (bufA.length !== bufB.length)
157
+ return false;
158
+ return timingSafeEqual(bufA, bufB);
159
+ }
160
+ export function signDesktopImportToken(secret, baseDir, options) {
161
+ const signature = createHmac('sha256', secret)
162
+ .update(`${baseDir}\n${options.nonce}\n${options.exp}`)
163
+ .digest('base64url');
164
+ return [options.nonce, options.exp, signature].join(DESKTOP_IMPORT_TOKEN_FIELD_SEP);
165
+ }
166
+ export function verifyDesktopImportToken(secret, baseDir, token, now, consumedNonces) {
167
+ if (typeof token !== 'string' || token.length === 0) {
168
+ return { ok: false, reason: 'token missing' };
169
+ }
170
+ const parts = token.split(DESKTOP_IMPORT_TOKEN_FIELD_SEP);
171
+ if (parts.length !== 3) {
172
+ return { ok: false, reason: 'token shape invalid' };
173
+ }
174
+ const [nonce, expISO, signature] = parts;
175
+ if (nonce.length === 0 || expISO.length === 0 || signature.length === 0) {
176
+ return { ok: false, reason: 'token shape invalid' };
177
+ }
178
+ const expMs = Date.parse(expISO);
179
+ if (!Number.isFinite(expMs)) {
180
+ return { ok: false, reason: 'token expiry invalid' };
181
+ }
182
+ if (expMs <= now) {
183
+ return { ok: false, reason: 'token expired' };
184
+ }
185
+ if (expMs - now > DESKTOP_IMPORT_TOKEN_TTL_MS * 2) {
186
+ return { ok: false, reason: 'token expiry exceeds permitted window' };
187
+ }
188
+ const expected = createHmac('sha256', secret)
189
+ .update(`${baseDir}\n${nonce}\n${expISO}`)
190
+ .digest('base64url');
191
+ if (!timingSafeStringEquals(expected, signature)) {
192
+ return { ok: false, reason: 'token signature invalid' };
193
+ }
194
+ if (consumedNonces.has(nonce)) {
195
+ return { ok: false, reason: 'token nonce already used' };
196
+ }
197
+ return { ok: true, nonce, exp: expMs };
198
+ }
199
+ export function composeLiveInstructionPrompt({ daemonSystemPrompt, runtimeToolPrompt, clientSystemPrompt, finalPromptOverride, }) {
200
+ const override = typeof finalPromptOverride === 'string'
201
+ ? finalPromptOverride.trim()
202
+ : '';
203
+ const parts = [daemonSystemPrompt, runtimeToolPrompt, clientSystemPrompt]
204
+ .map((part) => (typeof part === 'string' ? part.trim() : ''))
205
+ .map((part) => override && part.includes(override)
206
+ ? part.split(override).join('').trim()
207
+ : part)
208
+ .filter(Boolean);
209
+ if (override) {
210
+ parts.push(override);
211
+ }
212
+ return parts.join('\n\n---\n\n');
213
+ }
214
+ export function resolveResearchCommandContract(research, message) {
215
+ if (!research || !research.enabled)
216
+ return '';
217
+ const researchQuery = typeof research.query === 'string' && research.query.trim()
218
+ ? research.query
219
+ : message;
220
+ return renderResearchCommandContract({
221
+ query: researchQuery,
222
+ maxSources: typeof research.maxSources === 'number' ? research.maxSources : undefined,
223
+ });
224
+ }
225
+ export function resolveCodexGeneratedImagesDir(agentId, metadata, env = process.env, homeDir = os.homedir()) {
226
+ if (!shouldRenderCodexImagegenOverride(agentId, metadata))
227
+ return null;
228
+ const rawCodexHome = typeof env?.CODEX_HOME === 'string' && env.CODEX_HOME.trim().length > 0
229
+ ? env.CODEX_HOME.trim()
230
+ : path.join(homeDir, '.codex');
231
+ const codexHome = rawCodexHome.startsWith('~/')
232
+ ? path.join(homeDir, rawCodexHome.slice(2))
233
+ : rawCodexHome;
234
+ return path.resolve(codexHome, 'generated_images');
235
+ }
236
+ function isMissingPathError(err) {
237
+ return (err &&
238
+ typeof err === 'object' &&
239
+ 'code' in err &&
240
+ err.code === 'ENOENT');
241
+ }
242
+ function collectProtectedDirRoots(protectedDirs, { realpathSync, statSync, }) {
243
+ const roots = [];
244
+ for (const raw of Array.isArray(protectedDirs) ? protectedDirs : []) {
245
+ if (typeof raw !== 'string' || raw.trim().length === 0)
246
+ continue;
247
+ const resolved = path.resolve(raw);
248
+ roots.push(resolved);
249
+ try {
250
+ const canonical = realpathSync(resolved);
251
+ try {
252
+ if (statSync(canonical).isDirectory())
253
+ roots.push(canonical);
254
+ }
255
+ catch {
256
+ roots.push(canonical);
257
+ }
258
+ }
259
+ catch {
260
+ // A missing protected root cannot be the canonical target of a symlink.
261
+ }
262
+ }
263
+ return Array.from(new Set(roots));
264
+ }
265
+ function findContainingProtectedRoot(candidate, protectedRoots) {
266
+ return protectedRoots.find((root) => isPathWithin(root, candidate)) ?? null;
267
+ }
268
+ export function validateCodexGeneratedImagesDir(codexGeneratedImagesDir, { protectedDirs = [], mkdirSync = fs.mkdirSync, lstatSync = fs.lstatSync, statSync = fs.statSync, realpathSync = fs.realpathSync.native, warn = console.warn, } = {}) {
269
+ if (typeof codexGeneratedImagesDir !== 'string' ||
270
+ codexGeneratedImagesDir.trim().length === 0) {
271
+ return null;
272
+ }
273
+ const resolved = path.resolve(codexGeneratedImagesDir);
274
+ const protectedRoots = collectProtectedDirRoots(protectedDirs, {
275
+ realpathSync,
276
+ statSync,
277
+ });
278
+ const warnSkipped = (reason) => warn(`[od] codex generated_images allowlist skipped: ${reason}`);
279
+ const protectedRoot = findContainingProtectedRoot(resolved, protectedRoots);
280
+ if (protectedRoot) {
281
+ warnSkipped(`${resolved} is inside protected root ${protectedRoot}`);
282
+ return null;
283
+ }
284
+ try {
285
+ let existingTargetStat = null;
286
+ try {
287
+ existingTargetStat = lstatSync(resolved);
288
+ }
289
+ catch (err) {
290
+ if (!isMissingPathError(err))
291
+ throw err;
292
+ }
293
+ if (existingTargetStat?.isSymbolicLink()) {
294
+ warnSkipped(`${resolved} is a symlink`);
295
+ return null;
296
+ }
297
+ if (existingTargetStat && !existingTargetStat.isDirectory()) {
298
+ warnSkipped(`${resolved} is not a directory`);
299
+ return null;
300
+ }
301
+ const parent = path.dirname(resolved);
302
+ const protectedParentRoot = findContainingProtectedRoot(parent, protectedRoots);
303
+ if (protectedParentRoot) {
304
+ warnSkipped(`${parent} is inside protected root ${protectedParentRoot}`);
305
+ return null;
306
+ }
307
+ mkdirSync(parent, { recursive: true });
308
+ const canonicalParent = realpathSync(parent);
309
+ const canonicalCandidate = path.join(canonicalParent, path.basename(resolved));
310
+ const protectedCanonicalParentRoot = findContainingProtectedRoot(canonicalCandidate, protectedRoots);
311
+ if (protectedCanonicalParentRoot) {
312
+ warnSkipped(`${canonicalCandidate} resolves inside protected root ${protectedCanonicalParentRoot}`);
313
+ return null;
314
+ }
315
+ mkdirSync(resolved, { recursive: true });
316
+ if (lstatSync(resolved).isSymbolicLink()) {
317
+ warnSkipped(`${resolved} is a symlink`);
318
+ return null;
319
+ }
320
+ if (!statSync(resolved).isDirectory()) {
321
+ warnSkipped(`${resolved} is not a directory`);
322
+ return null;
323
+ }
324
+ const canonicalDir = realpathSync(resolved);
325
+ const protectedCanonicalRoot = findContainingProtectedRoot(canonicalDir, protectedRoots);
326
+ if (protectedCanonicalRoot) {
327
+ warnSkipped(`${canonicalDir} resolves inside protected root ${protectedCanonicalRoot}`);
328
+ return null;
329
+ }
330
+ return canonicalDir;
331
+ }
332
+ catch (err) {
333
+ const message = err instanceof Error ? err.message : String(err ?? 'unknown error');
334
+ warn(`[od] codex generated_images allowlist mkdir failed: ${message}`);
335
+ return null;
336
+ }
337
+ }
338
+ export function resolveChatExtraAllowedDirs({ agentId, skillsDir, designSystemsDir, linkedDirs = [], codexGeneratedImagesDir, existsSync = fs.existsSync, }) {
339
+ const isCodex = typeof agentId === 'string' && agentId.trim().toLowerCase() === 'codex';
340
+ const candidates = isCodex
341
+ ? [codexGeneratedImagesDir]
342
+ : [
343
+ skillsDir,
344
+ designSystemsDir,
345
+ ...(Array.isArray(linkedDirs) ? linkedDirs : []),
346
+ ];
347
+ return Array.from(new Set(candidates.filter((d) => typeof d === 'string' && d.length > 0 && existsSync(d))));
348
+ }
349
+ export function resolveGrantedCodexImagegenOverride({ agentId, metadata, codexGeneratedImagesDir, extraAllowedDirs = [], }) {
350
+ if (typeof codexGeneratedImagesDir !== 'string' ||
351
+ codexGeneratedImagesDir.length === 0 ||
352
+ !Array.isArray(extraAllowedDirs) ||
353
+ !extraAllowedDirs.includes(codexGeneratedImagesDir)) {
354
+ return null;
355
+ }
356
+ return renderCodexImagegenOverride(agentId, metadata);
357
+ }
358
+ export function normalizeCommentAttachments(input) {
359
+ if (!Array.isArray(input))
360
+ return [];
361
+ return input
362
+ .map((raw, index) => {
363
+ if (!raw || typeof raw !== 'object')
364
+ return null;
365
+ const filePath = cleanString(raw.filePath);
366
+ const elementId = cleanString(raw.elementId);
367
+ const selector = cleanString(raw.selector);
368
+ const label = cleanString(raw.label);
369
+ const screenshotPath = cleanString(raw.screenshotPath);
370
+ const markKind = normalizeVisualMarkKind(raw.markKind);
371
+ const intent = compactString(raw.intent, 220);
372
+ const comment = cleanString(raw.comment) || intent;
373
+ const selectionKind = raw.selectionKind === 'visual' ? 'visual' : raw.selectionKind === 'pod' ? 'pod' : 'element';
374
+ if (!filePath || !elementId || !comment)
375
+ return null;
376
+ if (selectionKind !== 'visual' && !selector)
377
+ return null;
378
+ if (selectionKind === 'visual' && !screenshotPath)
379
+ return null;
380
+ const podMembers = selectionKind === 'pod' ? normalizeAttachmentPodMembers(raw.podMembers) : [];
381
+ const memberCount = selectionKind === 'pod'
382
+ ? (podMembers.length > 0
383
+ ? podMembers.length
384
+ : Number.isFinite(raw.memberCount)
385
+ ? Math.max(0, Math.round(raw.memberCount))
386
+ : 0)
387
+ : 0;
388
+ return {
389
+ id: cleanString(raw.id) || `comment-${index + 1}`,
390
+ order: Number.isFinite(raw.order)
391
+ ? Math.max(1, Math.round(raw.order))
392
+ : index + 1,
393
+ filePath,
394
+ elementId,
395
+ selector,
396
+ label,
397
+ comment,
398
+ currentText: compactString(raw.currentText, 160),
399
+ pagePosition: normalizeAttachmentPosition(raw.pagePosition),
400
+ htmlHint: compactString(raw.htmlHint, 180),
401
+ selectionKind,
402
+ memberCount,
403
+ podMembers,
404
+ screenshotPath: selectionKind === 'visual' ? screenshotPath : undefined,
405
+ markKind: selectionKind === 'visual' ? markKind : undefined,
406
+ intent: selectionKind === 'visual'
407
+ ? intent || visualAnnotationIntent(markKind)
408
+ : undefined,
409
+ source: raw.source === 'board-batch' ? 'board-batch' : 'saved-comment',
410
+ };
411
+ })
412
+ .filter(Boolean)
413
+ .sort((a, b) => a.order - b.order);
414
+ }
415
+ export function renderCommentAttachmentHint(commentAttachments) {
416
+ if (!commentAttachments.length)
417
+ return '';
418
+ const lines = [
419
+ '',
420
+ '',
421
+ '<attached-preview-comments>',
422
+ 'Scope: treat each attachment as the default refinement target. For visual marks, inspect the screenshot and modify the marked region first. Preserve unrelated areas.',
423
+ ];
424
+ for (const item of commentAttachments) {
425
+ const targetKind = item.selectionKind === 'visual' ? 'visual' : item.selectionKind === 'pod' ? 'pod' : 'element';
426
+ lines.push('', `${item.order}. ${item.elementId}`, `targetKind: ${targetKind}`, `file: ${item.filePath}`, `label: ${item.label || '(unlabeled)'}`, `position: ${formatAttachmentPosition(item.pagePosition)}`, `currentText: ${item.currentText || '(empty)'}`, `htmlHint: ${item.htmlHint || '(none)'}`, `comment: ${item.comment}`);
427
+ if (targetKind === 'visual') {
428
+ lines.push(`screenshot: ${item.screenshotPath}`, `markKind: ${item.markKind || 'stroke'}`, `intent: ${item.intent || visualAnnotationIntent(item.markKind || 'stroke')}`);
429
+ if (item.selector)
430
+ lines.push(`selector: ${item.selector}`);
431
+ }
432
+ else {
433
+ lines.splice(lines.length - 4, 0, `selector: ${item.selector}`);
434
+ }
435
+ if (targetKind === 'pod') {
436
+ lines.push(`memberCount: ${item.memberCount || item.podMembers.length || 0}`);
437
+ item.podMembers.slice(0, 8).forEach((member, memberIndex) => {
438
+ lines.push(`member.${memberIndex + 1}: ${member.elementId} | ${member.label || '(unlabeled)'} | ${member.selector}`);
439
+ });
440
+ }
441
+ }
442
+ lines.push('</attached-preview-comments>');
443
+ return lines.join('\n');
444
+ }
445
+ function cleanString(value) {
446
+ return typeof value === 'string' ? value.trim() : '';
447
+ }
448
+ function normalizeVisualMarkKind(value) {
449
+ return value === 'click' || value === 'click+stroke' || value === 'stroke'
450
+ ? value
451
+ : 'stroke';
452
+ }
453
+ function visualAnnotationIntent(markKind) {
454
+ if (markKind === 'click') {
455
+ return 'The screenshot has a blue focus box around the picked element; modify that picked part first.';
456
+ }
457
+ if (markKind === 'click+stroke') {
458
+ return 'The screenshot has a blue focus box and red strokes; together they identify the part the user wants changed.';
459
+ }
460
+ return 'The screenshot has red strokes that identify the visual region the user wants changed.';
461
+ }
462
+ function compactString(value, max) {
463
+ const text = cleanString(value).replace(/\s+/g, ' ');
464
+ return text.length > max ? `${text.slice(0, max - 3)}...` : text;
465
+ }
466
+ function normalizeAttachmentPosition(input) {
467
+ const value = input && typeof input === 'object' ? input : {};
468
+ return {
469
+ x: finiteAttachmentNumber(value.x),
470
+ y: finiteAttachmentNumber(value.y),
471
+ width: finiteAttachmentNumber(value.width),
472
+ height: finiteAttachmentNumber(value.height),
473
+ };
474
+ }
475
+ function normalizeAttachmentPodMembers(input) {
476
+ if (!Array.isArray(input))
477
+ return [];
478
+ return input
479
+ .map((member) => {
480
+ if (!member || typeof member !== 'object')
481
+ return null;
482
+ const elementId = cleanString(member.elementId);
483
+ const selector = cleanString(member.selector);
484
+ const label = cleanString(member.label);
485
+ if (!elementId || !selector)
486
+ return null;
487
+ return {
488
+ elementId,
489
+ selector,
490
+ label,
491
+ text: compactString(member.text, 160),
492
+ position: normalizeAttachmentPosition(member.position),
493
+ htmlHint: compactString(member.htmlHint, 180),
494
+ };
495
+ })
496
+ .filter(Boolean);
497
+ }
498
+ function finiteAttachmentNumber(value) {
499
+ return Number.isFinite(value) ? Math.round(value) : 0;
500
+ }
501
+ function formatAttachmentPosition(position) {
502
+ return `x=${position.x}, y=${position.y}, width=${position.width}, height=${position.height}`;
503
+ }
504
+ function isPathWithin(base, target) {
505
+ const relativePath = path.relative(path.resolve(base), path.resolve(target));
506
+ return (relativePath === '' ||
507
+ (relativePath.length > 0 &&
508
+ !relativePath.startsWith('..') &&
509
+ !path.isAbsolute(relativePath)));
510
+ }
511
+ function resolveProcessResourcesPath() {
512
+ if (typeof process.resourcesPath === 'string' &&
513
+ process.resourcesPath.length > 0) {
514
+ return process.resourcesPath;
515
+ }
516
+ // Packaged daemon sidecars run under the bundled Node binary rather than the
517
+ // Electron root process, so `process.resourcesPath` is unavailable there.
518
+ // Infer the macOS app Resources directory from that bundled Node path.
519
+ const resourcesMarker = `${path.sep}Contents${path.sep}Resources${path.sep}`;
520
+ const markerIndex = process.execPath.indexOf(resourcesMarker);
521
+ if (markerIndex !== -1) {
522
+ return process.execPath.slice(0, markerIndex + resourcesMarker.length - 1);
523
+ }
524
+ const normalizedExecPath = process.execPath.toLowerCase();
525
+ const windowsResourceBinMarker = `${path.sep}resources${path.sep}open-design${path.sep}bin${path.sep}`.toLowerCase();
526
+ const windowsMarkerIndex = normalizedExecPath.indexOf(windowsResourceBinMarker);
527
+ if (windowsMarkerIndex !== -1) {
528
+ return process.execPath.slice(0, windowsMarkerIndex + `${path.sep}resources`.length);
529
+ }
530
+ return null;
531
+ }
532
+ export function resolveDaemonResourceRoot({ configured = process.env[RESOURCE_ROOT_ENV], safeBases = [PROJECT_ROOT, resolveProcessResourcesPath()], } = {}) {
533
+ if (!configured || configured.length === 0)
534
+ return null;
535
+ const resolved = path.resolve(configured);
536
+ const normalizedSafeBases = safeBases
537
+ .filter((base) => typeof base === 'string' && base.length > 0)
538
+ .map((base) => path.resolve(base));
539
+ if (!normalizedSafeBases.some((base) => isPathWithin(base, resolved))) {
540
+ throw new Error(`${RESOURCE_ROOT_ENV} must be under the workspace root or app resources path`);
541
+ }
542
+ return resolved;
543
+ }
544
+ function resolveDaemonResourceDir(resourceRoot, segment, fallback) {
545
+ return resourceRoot ? path.join(resourceRoot, segment) : fallback;
546
+ }
547
+ const DAEMON_RESOURCE_ROOT = resolveDaemonResourceRoot();
548
+ // Built web app lives in `out/` — that's where Next.js writes the static
549
+ // export configured in next.config.ts. The folder name used to be `dist/`
550
+ // when this project shipped with Vite; the daemon serves whatever the
551
+ // frontend toolchain emits, no further config needed.
552
+ const STATIC_DIR = path.join(PROJECT_ROOT, 'apps', 'web', 'out');
553
+ const OD_BIN = resolveDaemonCliPath();
554
+ const OD_NODE_BIN = process.execPath;
555
+ const SKILLS_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'skills', path.join(PROJECT_ROOT, 'skills'));
556
+ const DESIGN_SYSTEMS_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'design-systems', path.join(PROJECT_ROOT, 'design-systems'));
557
+ // Renderable templates pulled out of `skills/` by the skills/design-templates
558
+ // split (PR #955) so the EntryView Templates tab gets the large rendering
559
+ // catalogue and Settings → Skills only carries functional skills the agent
560
+ // invokes mid-task. See specs/current/skills-and-design-templates.md.
561
+ const DESIGN_TEMPLATES_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'design-templates', path.join(PROJECT_ROOT, 'design-templates'));
562
+ const CRAFT_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'craft', path.join(PROJECT_ROOT, 'craft'));
563
+ // User-installed skills and design systems live under the runtime data dir
564
+ // so they respect OD_DATA_DIR overrides (test isolation, packaged runs).
565
+ // Defined after RUNTIME_DATA_DIR is resolved below.
566
+ const FRAMES_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'frames', path.join(PROJECT_ROOT, 'assets', 'frames'));
567
+ // Curated pets baked into the repo via `scripts/bake-community-pets.ts`.
568
+ // `listCodexPets` scans this in addition to `~/.codex/pets/` so the
569
+ // "Recently hatched" grid is non-empty out-of-the-box and users do not
570
+ // need to hit the "Download community pets" button to try a few pets.
571
+ const BUNDLED_PETS_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'community-pets', path.join(PROJECT_ROOT, 'assets', 'community-pets'));
572
+ const PROMPT_TEMPLATES_DIR = resolveDaemonResourceDir(DAEMON_RESOURCE_ROOT, 'prompt-templates', path.join(PROJECT_ROOT, 'prompt-templates'));
573
+ export function resolveDataDir(raw, projectRoot) {
574
+ if (!raw)
575
+ return path.join(projectRoot, '.od');
576
+ // expandHomePrefix is shared with media-config.ts so OD_DATA_DIR and
577
+ // OD_MEDIA_CONFIG_DIR can never split state under a $HOME-style value.
578
+ // Some launchers (systemd unit files, NixOS modules, certain Docker
579
+ // entrypoints, Windows scheduled tasks) pass OD_DATA_DIR with literal
580
+ // $HOME or ${HOME} because the variable is never expanded by a shell;
581
+ // expandHomePrefix turns those (and the ~ shorthand, with both / and \
582
+ // separators) into os.homedir() before path.resolve runs so launch
583
+ // surfaces stay consistent.
584
+ const resolved = resolveProjectRelativePath(raw, projectRoot);
585
+ try {
586
+ fs.mkdirSync(resolved, { recursive: true });
587
+ fs.accessSync(resolved, fs.constants.W_OK);
588
+ }
589
+ catch (err) {
590
+ const e = err;
591
+ const currentUser = (() => {
592
+ try {
593
+ return os.userInfo().username;
594
+ }
595
+ catch {
596
+ return process.env.USER ?? process.env.LOGNAME ?? 'unknown';
597
+ }
598
+ })();
599
+ const parentDir = path.dirname(resolved);
600
+ throw new Error([
601
+ `OD_DATA_DIR "${resolved}" is not writable: ${e.message}`,
602
+ `Current user: ${currentUser}`,
603
+ `Check whether the folder or one of its parents is owned by another user, is a symlink to a protected location, or was previously created with sudo.`,
604
+ `Try: ls -ld "${parentDir}" "${resolved}"`,
605
+ `If the folder should belong to you, fix ownership/permissions, for example: sudo chown -R "${currentUser}":staff "${parentDir}" && chmod -R u+rwX "${parentDir}"`,
606
+ ].join(' '));
607
+ }
608
+ return resolved;
609
+ }
610
+ const RUNTIME_DATA_DIR = resolveDataDir(process.env.OD_DATA_DIR, PROJECT_ROOT);
611
+ // Canonical (realpath-resolved) form of RUNTIME_DATA_DIR for the few callers
612
+ // that compare it against a user-supplied realpath() result. On macOS, /var
613
+ // is a symlink to /private/var, so an import realpath lands in /private/var
614
+ // and would never start-with the raw RUNTIME_DATA_DIR. Keep RUNTIME_DATA_DIR
615
+ // itself as the stable, user-shaped path so OD_DATA_DIR resolution stays
616
+ // predictable; only this canonical alias is used for symlink-aware checks.
617
+ const RUNTIME_DATA_DIR_CANONICAL = (() => {
618
+ try {
619
+ return fs.realpathSync(RUNTIME_DATA_DIR);
620
+ }
621
+ catch {
622
+ return RUNTIME_DATA_DIR;
623
+ }
624
+ })();
625
+ // One-shot legacy data migration. When OD_LEGACY_DATA_DIR is set and the
626
+ // new data root is fresh (no app.sqlite), copy the 0.3.x .od/ payload
627
+ // across before SQLite opens. Synchronous on purpose: openDatabase below
628
+ // would race an async copy. See apps/daemon/src/legacy-data-migrator.ts
629
+ // and https://github.com/nexu-io/open-design/issues/710.
630
+ migrateLegacyDataDirSync({
631
+ legacyDir: process.env.OD_LEGACY_DATA_DIR,
632
+ dataDir: RUNTIME_DATA_DIR,
633
+ });
634
+ const ARTIFACTS_DIR = path.join(RUNTIME_DATA_DIR, 'artifacts');
635
+ // Critique Theater artifacts intentionally live outside the static
636
+ // `/artifacts` tree. The per-run artifact endpoint is the sanctioned
637
+ // read path so project-membership, size, and CSP guards cannot be bypassed.
638
+ const CRITIQUE_ARTIFACTS_DIR = path.join(RUNTIME_DATA_DIR, 'critique-artifacts');
639
+ const PROJECTS_DIR = path.join(RUNTIME_DATA_DIR, 'projects');
640
+ const USER_SKILLS_DIR = path.join(RUNTIME_DATA_DIR, 'skills');
641
+ const USER_DESIGN_SYSTEMS_DIR = path.join(RUNTIME_DATA_DIR, 'design-systems');
642
+ // User-imported design templates mirror USER_SKILLS_DIR but are scanned
643
+ // against DESIGN_TEMPLATES_DIR rather than SKILLS_DIR so the EntryView
644
+ // Templates surface and the Settings → Skills surface stay decoupled.
645
+ const USER_DESIGN_TEMPLATES_DIR = path.join(RUNTIME_DATA_DIR, 'design-templates');
646
+ // Multi-root tuples used everywhere the daemon resolves a skill / template
647
+ // id without knowing which surface it came from. SKILL_ROOTS drives
648
+ // Settings → Skills; DESIGN_TEMPLATE_ROOTS drives the EntryView Templates
649
+ // gallery; ALL_SKILL_LIKE_ROOTS spans both for chat run system-prompt
650
+ // composition and the orbit template resolver, where stored project ids
651
+ // can resolve to either root after the split.
652
+ const SKILL_ROOTS = [USER_SKILLS_DIR, SKILLS_DIR];
653
+ const DESIGN_TEMPLATE_ROOTS = [USER_DESIGN_TEMPLATES_DIR, DESIGN_TEMPLATES_DIR];
654
+ const ALL_SKILL_LIKE_ROOTS = [
655
+ USER_SKILLS_DIR,
656
+ USER_DESIGN_TEMPLATES_DIR,
657
+ SKILLS_DIR,
658
+ DESIGN_TEMPLATES_DIR,
659
+ ];
660
+ fs.mkdirSync(PROJECTS_DIR, { recursive: true });
661
+ for (const dir of [USER_SKILLS_DIR, USER_DESIGN_SYSTEMS_DIR, USER_DESIGN_TEMPLATES_DIR]) {
662
+ fs.mkdirSync(dir, { recursive: true });
663
+ }
664
+ fs.mkdirSync(CRITIQUE_ARTIFACTS_DIR, { recursive: true });
665
+ const orbitService = new OrbitService(RUNTIME_DATA_DIR);
666
+ let routineService = null;
667
+ // In-memory OAuth state cache. Lives for the daemon process's lifetime.
668
+ // Maps the OAuth `state` parameter we generated in /api/mcp/oauth/start
669
+ // to the verifier + endpoint info needed to finish the exchange when the
670
+ // browser hits /api/mcp/oauth/callback.
671
+ const mcpPendingAuth = new PendingAuthCache();
672
+ /**
673
+ * Resolve the daemon's public base URL — the origin the user's browser
674
+ * (or the OAuth provider) reaches us at. Order of precedence:
675
+ *
676
+ * 1. `OD_PUBLIC_BASE_URL` env var. Cloud and packaged-electron deployments
677
+ * set this to the externally-routable URL (e.g. `https://app.example.com`).
678
+ * 2. `req.protocol://req.get('host')` from the inbound request. Works in
679
+ * local dev and most reverse-proxy setups (Express respects
680
+ * `trust proxy` so X-Forwarded-* headers are honored).
681
+ *
682
+ * The OAuth callback URI is derived from this — it MUST be reachable from
683
+ * the user's browser, otherwise the redirect after auth lands on
684
+ * ERR_CONNECTION_REFUSED. Misconfiguration is loud: the OAuth provider
685
+ * will reject `redirect_uri` mismatches.
686
+ */
687
+ function getPublicBaseUrl(req) {
688
+ const env = process.env.OD_PUBLIC_BASE_URL;
689
+ if (env && /^https?:\/\//i.test(env)) {
690
+ return env.replace(/\/+$/u, '');
691
+ }
692
+ const proto = req.protocol || 'http';
693
+ const host = req.get('host');
694
+ if (!host)
695
+ return `http://localhost:${process.env.OD_PORT ?? '7456'}`;
696
+ return `${proto}://${host}`;
697
+ }
698
+ function mcpOAuthCallbackUrl(req) {
699
+ return `${getPublicBaseUrl(req)}/api/mcp/oauth/callback`;
700
+ }
701
+ /**
702
+ * Refresh an expired token using the OAuth client context that the original
703
+ * authorization-code exchange persisted alongside the token. Refresh tokens
704
+ * are bound (RFC 6749 §6) to the client that received them, so we MUST
705
+ * refresh against the same `tokenEndpoint` / `clientId` / `clientSecret`
706
+ * pair — re-running discovery with a different redirect URI would risk
707
+ * registering a new client_id that the upstream then rejects the refresh
708
+ * for. Tokens persisted before that context was recorded can't be safely
709
+ * refreshed; the caller treats `null` as "needs reconnect".
710
+ */
711
+ async function refreshAndPersistToken(dataDir, serverId, current) {
712
+ if (!current.refreshToken)
713
+ return null;
714
+ if (!current.tokenEndpoint || !current.clientId)
715
+ return null;
716
+ const tokenResp = await refreshAccessToken({
717
+ tokenEndpoint: current.tokenEndpoint,
718
+ clientId: current.clientId,
719
+ clientSecret: current.clientSecret,
720
+ refreshToken: current.refreshToken,
721
+ scope: current.scope,
722
+ resource: current.resourceUrl,
723
+ });
724
+ const next = {
725
+ accessToken: tokenResp.access_token,
726
+ refreshToken: tokenResp.refresh_token ?? current.refreshToken,
727
+ tokenType: tokenResp.token_type ?? 'Bearer',
728
+ scope: tokenResp.scope ?? current.scope,
729
+ expiresAt: typeof tokenResp.expires_in === 'number'
730
+ ? Date.now() + tokenResp.expires_in * 1000
731
+ : undefined,
732
+ savedAt: Date.now(),
733
+ tokenEndpoint: current.tokenEndpoint,
734
+ clientId: current.clientId,
735
+ clientSecret: current.clientSecret,
736
+ authServerIssuer: current.authServerIssuer,
737
+ redirectUri: current.redirectUri,
738
+ resourceUrl: current.resourceUrl,
739
+ };
740
+ await setToken(dataDir, serverId, next);
741
+ return next;
742
+ }
743
+ const activeChatAgentEventSinks = new Map();
744
+ const activeProjectEventSinks = new Map();
745
+ function emitChatAgentEvent(runId, payload) {
746
+ const sink = activeChatAgentEventSinks.get(runId);
747
+ if (!sink)
748
+ return false;
749
+ return sink(payload);
750
+ }
751
+ function emitLiveArtifactEvent(grant, action, artifact) {
752
+ if (!artifact?.id)
753
+ return false;
754
+ const payload = {
755
+ type: 'live_artifact',
756
+ action,
757
+ projectId: artifact.projectId ?? grant.projectId,
758
+ artifactId: artifact.id,
759
+ title: artifact.title ?? artifact.id,
760
+ refreshStatus: artifact.refreshStatus,
761
+ };
762
+ let emitted = emitProjectEvent(payload.projectId, payload);
763
+ if (grant?.runId)
764
+ emitted = emitChatAgentEvent(grant.runId, payload) || emitted;
765
+ return emitted;
766
+ }
767
+ function emitLiveArtifactRefreshEvent(grant, payload) {
768
+ if (!payload?.artifactId)
769
+ return false;
770
+ const event = {
771
+ type: 'live_artifact_refresh',
772
+ projectId: grant.projectId,
773
+ ...payload,
774
+ };
775
+ let emitted = emitProjectEvent(grant.projectId, event);
776
+ if (grant?.runId)
777
+ emitted = emitChatAgentEvent(grant.runId, event) || emitted;
778
+ return emitted;
779
+ }
780
+ // Broadcast an event to every SSE subscriber currently watching the given
781
+ // project's `/api/projects/:id/events` stream. The payload's `type` field
782
+ // becomes the SSE event name (see project-routes.ts). Used for live-artifact
783
+ // events and `conversation-created` events emitted by routine runs (#1361).
784
+ function emitProjectEvent(projectId, payload) {
785
+ const sinks = activeProjectEventSinks.get(projectId);
786
+ if (!sinks || sinks.size === 0)
787
+ return false;
788
+ for (const sink of Array.from(sinks)) {
789
+ try {
790
+ sink(payload);
791
+ }
792
+ catch {
793
+ sinks.delete(sink);
794
+ }
795
+ }
796
+ if (sinks.size === 0)
797
+ activeProjectEventSinks.delete(projectId);
798
+ return true;
799
+ }
800
+ // Windows ENAMETOOLONG mitigation constants
801
+ const CMD_BAT_RE = /\.(cmd|bat)$/i;
802
+ const PROMPT_TEMP_FILE = () => '.od-prompt-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8) + '.md';
803
+ const promptFileBootstrap = (fp) => `Your full instructions are stored in the file: ${fp.replace(/\\/g, '/')}. ` +
804
+ 'Open that file first and follow every instruction in it exactly — ' +
805
+ 'it contains the system prompt, design system, skill workflow, and user request. ' +
806
+ 'Do not begin your response until you have read the entire file.';
807
+ // Load Critique Theater config once at startup so a bad OD_CRITIQUE_* value
808
+ // surfaces immediately as a boot-time RangeError instead of silently at
809
+ // run time. Default: enabled=false (M0 dark launch).
810
+ const critiqueCfg = loadCritiqueConfigFromEnv();
811
+ // Tracks adapter streamFormat values that have already received a one-time
812
+ // warning explaining why the Critique Theater orchestrator was bypassed.
813
+ // Adapter denylist for orchestrator routing is implicit: anything that is
814
+ // not the 'plain' streamFormat falls through to legacy single-pass.
815
+ const critiqueWarnedAdapters = new Set();
816
+ // In-process registry of in-flight critique runs so the interrupt endpoint
817
+ // can cascade an AbortController to the matching orchestrator invocation.
818
+ // Created once per process; not persisted across daemon restarts.
819
+ const critiqueRunRegistry = createRunRegistry();
820
+ export const SSE_KEEPALIVE_INTERVAL_MS = 25_000;
821
+ export function createAgentRuntimeEnv(baseEnv, daemonUrl, toolTokenGrant = null, nodeBin = process.execPath) {
822
+ const env = {
823
+ ...baseEnv,
824
+ OD_DAEMON_URL: daemonUrl,
825
+ OD_NODE_BIN: nodeBin,
826
+ };
827
+ if (toolTokenGrant?.token) {
828
+ env.OD_TOOL_TOKEN = toolTokenGrant.token;
829
+ }
830
+ else {
831
+ delete env.OD_TOOL_TOKEN;
832
+ }
833
+ return env;
834
+ }
835
+ export function createAgentRuntimeToolPrompt(daemonUrl, toolTokenGrant = null) {
836
+ const tokenLine = toolTokenGrant?.token
837
+ ? '- `OD_TOOL_TOKEN` is available in your environment for this run. Use it only through project wrapper commands; do not print, persist, or override it.'
838
+ : '- `OD_TOOL_TOKEN` is not available for this run, so `/api/tools/*` wrapper commands may be unavailable.';
839
+ return [
840
+ '## Runtime tool environment',
841
+ '',
842
+ `- Daemon URL: \`${daemonUrl}\` (also available as \`OD_DAEMON_URL\`).`,
843
+ '- `OD_NODE_BIN` is the absolute path to the Node-compatible runtime that started the daemon; packaged desktop installs provide this even when the user has no system `node` on PATH.',
844
+ '- `OD_BIN` is the absolute path to the Open Design CLI script. On POSIX shells run wrappers with `"$OD_NODE_BIN" "$OD_BIN" tools ...`; do not call bare `od`, which may resolve to the system octal-dump command on Unix-like systems.',
845
+ '- On PowerShell use `& $env:OD_NODE_BIN $env:OD_BIN tools ...`; on cmd.exe use `"%OD_NODE_BIN%" "%OD_BIN%" tools ...`.',
846
+ tokenLine,
847
+ '- Prefer project wrapper commands through `OD_NODE_BIN` + `OD_BIN` over raw HTTP. The wrappers read these environment values automatically.',
848
+ ].join('\n');
849
+ }
850
+ export function normalizeProjectDisplayStatus(status) {
851
+ return status === 'starting' || status === 'queued' ? 'running' : status;
852
+ }
853
+ export function composeProjectDisplayStatus(baseStatus, awaitingInputProjects, projectId) {
854
+ if (baseStatus.value === 'succeeded' &&
855
+ awaitingInputProjects.has(projectId)) {
856
+ return { ...baseStatus, value: 'awaiting_input' };
857
+ }
858
+ return {
859
+ ...baseStatus,
860
+ value: normalizeProjectDisplayStatus(baseStatus.value),
861
+ };
862
+ }
863
+ /**
864
+ * @param {ApiErrorCode} code
865
+ * @param {string} message
866
+ * @param {Omit<ApiError, 'code' | 'message'>} [init]
867
+ * @returns {ApiError}
868
+ */
869
+ export function createCompatApiError(code, message, init = {}) {
870
+ return { code, message, ...init };
871
+ }
872
+ /**
873
+ * @param {ApiErrorCode} code
874
+ * @param {string} message
875
+ * @param {Omit<ApiError, 'code' | 'message'>} [init]
876
+ * @returns {ApiErrorResponse}
877
+ */
878
+ export function createCompatApiErrorResponse(code, message, init = {}) {
879
+ return { error: createCompatApiError(code, message, init) };
880
+ }
881
+ /**
882
+ * @param {import('express').Response} res
883
+ * @param {number} status
884
+ * @param {ApiErrorCode} code
885
+ * @param {string} message
886
+ * @param {Omit<ApiError, 'code' | 'message'>} [init]
887
+ */
888
+ function sendApiError(res, status, code, message, init = {}) {
889
+ return res
890
+ .status(status)
891
+ .json(createCompatApiErrorResponse(code, message, init));
892
+ }
893
+ const TERMINAL_RUN_STATUSES = new Set(['succeeded', 'failed', 'canceled']);
894
+ export function shouldReportRunCompletedFromMessage(saved, body = {}) {
895
+ return Boolean(saved &&
896
+ saved.runId &&
897
+ typeof saved.runStatus === 'string' &&
898
+ TERMINAL_RUN_STATUSES.has(saved.runStatus) &&
899
+ body?.telemetryFinalized === true);
900
+ }
901
+ export function telemetryPromptFromRunRequest(message, currentPrompt) {
902
+ return typeof currentPrompt === 'string' ? currentPrompt : message;
903
+ }
904
+ export function createFinalizedMessageTelemetryReporter({ design, db, dataDir, reportedRuns, getAppVersion = () => null, report = reportRunCompletedFromDaemon, }) {
905
+ return (saved, body = {}) => {
906
+ if (!shouldReportRunCompletedFromMessage(saved, body))
907
+ return;
908
+ const run = design.runs.get(saved.runId);
909
+ if (!run || reportedRuns.has(run.id))
910
+ return;
911
+ reportedRuns.add(run.id);
912
+ void report({
913
+ db,
914
+ dataDir,
915
+ run,
916
+ persistedRunStatus: saved.runStatus,
917
+ persistedEndedAt: saved.endedAt,
918
+ appVersion: getAppVersion(),
919
+ });
920
+ };
921
+ }
922
+ const CLOUDFLARE_PAGES_PROJECT_METADATA_KEY = 'cloudflarePagesProjectName';
923
+ function cloudflarePagesDeploymentMetadata(projectName) {
924
+ const normalized = typeof projectName === 'string' ? projectName.trim() : '';
925
+ return normalized
926
+ ? { [CLOUDFLARE_PAGES_PROJECT_METADATA_KEY]: normalized }
927
+ : undefined;
928
+ }
929
+ function cloudflarePagesProjectNameFromDeployment(deployment) {
930
+ const value = deployment?.providerMetadata?.[CLOUDFLARE_PAGES_PROJECT_METADATA_KEY];
931
+ if (typeof value === 'string' && value.trim())
932
+ return value.trim();
933
+ return cloudflarePagesProjectNameFromUrl(deployment?.url);
934
+ }
935
+ function cloudflarePagesProjectNameFromUrl(rawUrl) {
936
+ if (typeof rawUrl !== 'string' || !rawUrl.trim())
937
+ return '';
938
+ try {
939
+ const host = new URL(rawUrl).hostname.toLowerCase();
940
+ if (!host.endsWith('.pages.dev'))
941
+ return '';
942
+ const labels = host.slice(0, -'.pages.dev'.length).split('.').filter(Boolean);
943
+ return labels.at(-1) || '';
944
+ }
945
+ catch {
946
+ return '';
947
+ }
948
+ }
949
+ function cloudflarePagesProjectNameForDeploy(db, projectId, projectName, prior) {
950
+ const priorName = cloudflarePagesProjectNameFromDeployment(prior);
951
+ if (priorName)
952
+ return priorName;
953
+ for (const deployment of listDeployments(db, projectId)) {
954
+ if (deployment.providerId !== CLOUDFLARE_PAGES_PROVIDER_ID)
955
+ continue;
956
+ const stableName = cloudflarePagesProjectNameFromDeployment(deployment);
957
+ if (stableName)
958
+ return stableName;
959
+ }
960
+ return cloudflarePagesProjectNameForProject(projectId, projectName);
961
+ }
962
+ function publicDeployment(deployment) {
963
+ if (!deployment || typeof deployment !== 'object')
964
+ return deployment;
965
+ const { providerMetadata: _providerMetadata, ...publicShape } = deployment;
966
+ return publicShape;
967
+ }
968
+ function publicDeployments(deployments) {
969
+ return (deployments || []).map(publicDeployment);
970
+ }
971
+ async function checkCloudflarePagesDeploymentLinks(existing) {
972
+ const current = existing.cloudflarePages || {};
973
+ const projectName = current.projectName || cloudflarePagesProjectNameFromDeployment(existing);
974
+ const config = await readDeployConfig(CLOUDFLARE_PAGES_PROVIDER_ID);
975
+ const pagesDevUrl = current.pagesDev?.url || existing.url;
976
+ const pagesDevResult = await checkDeploymentUrl(pagesDevUrl);
977
+ const pagesDev = {
978
+ ...(current.pagesDev || {}),
979
+ url: pagesDevUrl,
980
+ status: pagesDevResult.reachable ? 'ready' : pagesDevResult.status || 'link-delayed',
981
+ statusMessage: pagesDevResult.reachable
982
+ ? 'Public link is ready.'
983
+ : pagesDevResult.statusMessage || current.pagesDev?.statusMessage || 'Cloudflare Pages is still preparing the pages.dev link.',
984
+ reachableAt: pagesDevResult.reachable ? Date.now() : current.pagesDev?.reachableAt,
985
+ };
986
+ let customDomain = current.customDomain;
987
+ if (customDomain?.url && customDomain.status !== 'conflict') {
988
+ let pagesDomain = null;
989
+ if (config?.token && config?.accountId && projectName) {
990
+ try {
991
+ pagesDomain = await readCloudflarePagesDomain({ ...config, projectName }, customDomain.hostname);
992
+ }
993
+ catch {
994
+ pagesDomain = null;
995
+ }
996
+ }
997
+ const customResult = await checkDeploymentUrl(customDomain.url);
998
+ const pagesDomainStatus = pagesDomain?.status || customDomain.pagesDomainStatus;
999
+ const failedByApi = ['error', 'blocked', 'deactivated'].includes(String(pagesDomainStatus || '').toLowerCase());
1000
+ const activeByApi = String(pagesDomainStatus || '').toLowerCase() === 'active';
1001
+ const readyByReachability = customResult.reachable && activeByApi;
1002
+ customDomain = {
1003
+ ...customDomain,
1004
+ domainStatus: pagesDomain
1005
+ ? pagesDomain.status === 'active'
1006
+ ? 'active'
1007
+ : failedByApi
1008
+ ? 'failed'
1009
+ : 'pending'
1010
+ : customDomain.domainStatus,
1011
+ pagesDomainStatus,
1012
+ validationData: pagesDomain?.validation_data ?? customDomain.validationData,
1013
+ verificationData: pagesDomain?.verification_data ?? customDomain.verificationData,
1014
+ status: readyByReachability
1015
+ ? 'ready'
1016
+ : customDomain.status === 'failed' || failedByApi
1017
+ ? 'failed'
1018
+ : 'pending',
1019
+ statusMessage: readyByReachability
1020
+ ? 'Custom domain is ready.'
1021
+ : failedByApi
1022
+ ? 'Cloudflare Pages reported a custom-domain error.'
1023
+ : customResult.statusMessage || customDomain.statusMessage || 'Custom domain is still being prepared.',
1024
+ };
1025
+ }
1026
+ const cloudflarePages = {
1027
+ ...current,
1028
+ projectName,
1029
+ pagesDev,
1030
+ ...(customDomain ? { customDomain } : {}),
1031
+ };
1032
+ const aggregate = aggregateCloudflarePagesStatus(pagesDev, customDomain);
1033
+ return {
1034
+ url: pagesDev.url,
1035
+ status: aggregate.status,
1036
+ statusMessage: aggregate.statusMessage,
1037
+ cloudflarePages,
1038
+ providerMetadata: {
1039
+ ...(existing.providerMetadata || {}),
1040
+ cloudflarePages,
1041
+ },
1042
+ };
1043
+ }
1044
+ // Filename slug for the Content-Disposition header on archive downloads.
1045
+ // Browsers reject quotes and control bytes; we keep Unicode letters/digits
1046
+ // so a project name with non-ASCII characters (e.g. "café-design")
1047
+ // survives instead of becoming a row of underscores.
1048
+ function sanitizeArchiveFilename(raw) {
1049
+ const cleaned = String(raw ?? '')
1050
+ .replace(/[\\/:*?"<>|]/g, '_')
1051
+ .replace(/[\u0000-\u001f\u007f]/g, '')
1052
+ .replace(/\s+/g, '-')
1053
+ .replace(/^-+|-+$/g, '')
1054
+ .slice(0, 80);
1055
+ return cleaned;
1056
+ }
1057
+ function sendLiveArtifactRouteError(res, err) {
1058
+ if (err instanceof LiveArtifactStoreValidationError) {
1059
+ return sendApiError(res, 400, 'LIVE_ARTIFACT_INVALID', err.message, {
1060
+ details: { kind: 'validation', issues: err.issues },
1061
+ });
1062
+ }
1063
+ if (err instanceof LiveArtifactRefreshLockError) {
1064
+ return sendApiError(res, 409, 'REFRESH_LOCKED', err.message, {
1065
+ details: { artifactId: err.artifactId },
1066
+ });
1067
+ }
1068
+ if (err instanceof LiveArtifactRefreshUnavailableError) {
1069
+ return sendApiError(res, 400, 'LIVE_ARTIFACT_REFRESH_UNAVAILABLE', err.message);
1070
+ }
1071
+ if (err instanceof LiveArtifactRefreshAbortError) {
1072
+ return sendApiError(res, err.kind === 'cancelled' ? 499 : 504, 'LIVE_ARTIFACT_REFRESH_TIMEOUT', err.message, {
1073
+ details: { kind: err.kind, timeoutMs: err.timeoutMs ?? null, step: err.step ?? null },
1074
+ });
1075
+ }
1076
+ if (err instanceof ConnectorServiceError) {
1077
+ return sendApiError(res, err.status, err.code, err.message, err.details === undefined ? {} : { details: err.details });
1078
+ }
1079
+ if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') {
1080
+ return sendApiError(res, 404, 'LIVE_ARTIFACT_NOT_FOUND', 'live artifact not found');
1081
+ }
1082
+ return sendApiError(res, 500, 'LIVE_ARTIFACT_STORAGE_FAILED', String(err));
1083
+ }
1084
+ function normalizeLocalAuthority(value) {
1085
+ if (typeof value !== 'string')
1086
+ return null;
1087
+ const trimmed = value.trim();
1088
+ if (!trimmed || /[\s/@]/.test(trimmed) || trimmed.includes(','))
1089
+ return null;
1090
+ try {
1091
+ const parsed = new URL(`http://${trimmed}`);
1092
+ const hostname = parsed.hostname.toLowerCase().replace(/\.$/, '');
1093
+ if (!hostname || parsed.username || parsed.password || parsed.pathname !== '/')
1094
+ return null;
1095
+ return { hostname, port: parsed.port };
1096
+ }
1097
+ catch {
1098
+ return null;
1099
+ }
1100
+ }
1101
+ function isLoopbackHostname(hostname) {
1102
+ const normalized = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, '').replace(/\.$/, '');
1103
+ if (normalized === 'localhost')
1104
+ return true;
1105
+ if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1')
1106
+ return true;
1107
+ if (net.isIP(normalized) === 4)
1108
+ return normalized === '127.0.0.1' || normalized.startsWith('127.');
1109
+ return false;
1110
+ }
1111
+ function isLoopbackPeerAddress(address) {
1112
+ if (typeof address !== 'string')
1113
+ return false;
1114
+ const normalized = address.trim().toLowerCase().replace(/^\[|\]$/g, '');
1115
+ if (!normalized)
1116
+ return false;
1117
+ if (normalized.startsWith('::ffff:'))
1118
+ return isLoopbackPeerAddress(normalized.slice('::ffff:'.length));
1119
+ if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1')
1120
+ return true;
1121
+ if (net.isIP(normalized) === 4)
1122
+ return normalized === '127.0.0.1' || normalized.startsWith('127.');
1123
+ return false;
1124
+ }
1125
+ function localOriginFromHeader(value) {
1126
+ if (typeof value !== 'string')
1127
+ return null;
1128
+ const trimmed = value.trim();
1129
+ if (!trimmed || trimmed === 'null' || trimmed.includes(','))
1130
+ return null;
1131
+ try {
1132
+ const parsed = new URL(trimmed);
1133
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
1134
+ return null;
1135
+ if (parsed.pathname !== '/' || parsed.search || parsed.hash || parsed.username || parsed.password)
1136
+ return null;
1137
+ if (!isLoopbackHostname(parsed.hostname))
1138
+ return null;
1139
+ return parsed.origin;
1140
+ }
1141
+ catch {
1142
+ return null;
1143
+ }
1144
+ }
1145
+ function validateLocalDaemonRequest(req) {
1146
+ if (!isLoopbackPeerAddress(req.socket?.remoteAddress)) {
1147
+ return {
1148
+ ok: false,
1149
+ message: 'request peer must be a loopback address',
1150
+ details: { peer: 'remoteAddress' },
1151
+ };
1152
+ }
1153
+ const host = normalizeLocalAuthority(req.get('host'));
1154
+ if (!host || !isLoopbackHostname(host.hostname)) {
1155
+ return {
1156
+ ok: false,
1157
+ message: 'request host must be a loopback daemon address',
1158
+ details: { header: 'host' },
1159
+ };
1160
+ }
1161
+ const originHeader = req.get('origin');
1162
+ if (originHeader !== undefined && !localOriginFromHeader(originHeader)) {
1163
+ return {
1164
+ ok: false,
1165
+ message: 'request origin must be a loopback daemon origin',
1166
+ details: { header: 'origin' },
1167
+ };
1168
+ }
1169
+ return { ok: true, origin: localOriginFromHeader(originHeader) };
1170
+ }
1171
+ function requireLocalDaemonRequest(req, res, next) {
1172
+ const validation = validateLocalDaemonRequest(req);
1173
+ if (!validation.ok) {
1174
+ return sendApiError(res, 403, 'FORBIDDEN', validation.message, validation.details ? { details: validation.details } : {});
1175
+ }
1176
+ res.setHeader('Vary', 'Origin');
1177
+ if (validation.origin) {
1178
+ res.setHeader('Access-Control-Allow-Origin', validation.origin);
1179
+ }
1180
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
1181
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
1182
+ res.setHeader('Access-Control-Max-Age', '600');
1183
+ next();
1184
+ }
1185
+ /**
1186
+ * Render the small HTML page that the OAuth callback returns to the
1187
+ * user's browser tab. It posts a message back to the opener (the
1188
+ * Settings dialog window) and offers a manual close button. We keep
1189
+ * the markup pure HTML/CSS — no external scripts, no React — so the
1190
+ * page works even if the opener was closed and the user just sees a
1191
+ * static success/failure screen.
1192
+ */
1193
+ function renderOAuthResultPage(opts) {
1194
+ const ok = Boolean(opts.ok);
1195
+ const title = ok ? 'Connected' : 'Authorization failed';
1196
+ const heading = ok ? '✅ Connected' : '⚠️ Authorization failed';
1197
+ const body = ok
1198
+ ? `Your MCP server <code>${escapeHtml(opts.serverId ?? '')}</code> is now connected. You can close this tab and return to Open Design.`
1199
+ : escapeHtml(opts.message ?? 'Authorization could not be completed.');
1200
+ const accent = ok ? '#1a7f37' : '#cf222e';
1201
+ const payload = ok
1202
+ ? { type: 'mcp-oauth', ok: true, serverId: opts.serverId ?? null }
1203
+ : { type: 'mcp-oauth', ok: false, message: opts.message ?? null };
1204
+ return `<!doctype html>
1205
+ <html lang="en">
1206
+ <head>
1207
+ <meta charset="utf-8" />
1208
+ <title>${escapeHtml(title)} — Open Design</title>
1209
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
1210
+ <style>
1211
+ :root { color-scheme: light dark; }
1212
+ html, body { height: 100%; margin: 0; }
1213
+ body {
1214
+ display: flex; align-items: center; justify-content: center;
1215
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, sans-serif;
1216
+ background: #f6f7f9; color: #1f2328; padding: 24px;
1217
+ }
1218
+ @media (prefers-color-scheme: dark) {
1219
+ body { background: #0d1117; color: #e6edf3; }
1220
+ .card { background: #161b22; border-color: #30363d; }
1221
+ code { background: #1f242c; }
1222
+ }
1223
+ .card {
1224
+ max-width: 420px; width: 100%; padding: 28px 28px 22px; border-radius: 12px;
1225
+ background: white; border: 1px solid #d0d7de; box-shadow: 0 8px 24px rgba(0,0,0,.06);
1226
+ text-align: left;
1227
+ }
1228
+ h1 { margin: 0 0 8px; font-size: 18px; color: ${accent}; }
1229
+ p { margin: 0 0 16px; font-size: 14px; line-height: 1.55; }
1230
+ code { background: #f3f4f6; padding: 1px 6px; border-radius: 4px; font-size: 12.5px; }
1231
+ button {
1232
+ appearance: none; border: 1px solid #d0d7de; background: white;
1233
+ border-radius: 8px; padding: 8px 14px; font-size: 13px; cursor: pointer;
1234
+ }
1235
+ button:hover { background: #f6f8fa; }
1236
+ @media (prefers-color-scheme: dark) {
1237
+ button { background: #21262d; border-color: #30363d; color: #e6edf3; }
1238
+ button:hover { background: #30363d; }
1239
+ }
1240
+ </style>
1241
+ </head>
1242
+ <body>
1243
+ <div class="card">
1244
+ <h1>${escapeHtml(heading)}</h1>
1245
+ <p>${body}</p>
1246
+ <button type="button" onclick="window.close()">Close this tab</button>
1247
+ </div>
1248
+ <script>
1249
+ try {
1250
+ var payload = ${JSON.stringify(payload)};
1251
+ if (window.opener && !window.opener.closed) {
1252
+ window.opener.postMessage(payload, '*');
1253
+ }
1254
+ if (window.BroadcastChannel) {
1255
+ var bc = new BroadcastChannel('open-design-mcp-oauth');
1256
+ bc.postMessage(payload);
1257
+ bc.close();
1258
+ }
1259
+ } catch (e) { /* ignore postMessage failures */ }
1260
+ </script>
1261
+ </body>
1262
+ </html>`;
1263
+ }
1264
+ function escapeHtml(s) {
1265
+ return String(s ?? '')
1266
+ .replace(/&/g, '&amp;')
1267
+ .replace(/</g, '&lt;')
1268
+ .replace(/>/g, '&gt;')
1269
+ .replace(/"/g, '&quot;')
1270
+ .replace(/'/g, '&#39;');
1271
+ }
1272
+ function setLiveArtifactPreviewHeaders(res) {
1273
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
1274
+ res.setHeader('Cache-Control', 'no-store');
1275
+ res.setHeader('X-Content-Type-Options', 'nosniff');
1276
+ res.setHeader('Referrer-Policy', 'no-referrer');
1277
+ res.setHeader('Content-Security-Policy', [
1278
+ "default-src 'none'",
1279
+ "base-uri 'none'",
1280
+ "script-src 'none'",
1281
+ "object-src 'none'",
1282
+ "connect-src 'none'",
1283
+ "form-action 'none'",
1284
+ "frame-ancestors 'self'",
1285
+ "img-src 'self' data: blob:",
1286
+ "font-src 'self' data:",
1287
+ "style-src 'unsafe-inline'",
1288
+ 'sandbox allow-same-origin',
1289
+ ].join('; '));
1290
+ }
1291
+ function setLiveArtifactCodeHeaders(res) {
1292
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
1293
+ res.setHeader('Cache-Control', 'no-store');
1294
+ res.setHeader('X-Content-Type-Options', 'nosniff');
1295
+ res.setHeader('Referrer-Policy', 'no-referrer');
1296
+ }
1297
+ function bearerTokenFromRequest(req) {
1298
+ const header = req.get('authorization');
1299
+ if (typeof header !== 'string')
1300
+ return undefined;
1301
+ const match = /^Bearer\s+(.+)$/i.exec(header.trim());
1302
+ return match?.[1];
1303
+ }
1304
+ function authorizeToolRequest(req, res, operation) {
1305
+ const endpoint = req.path;
1306
+ const validation = toolTokenRegistry.validate(bearerTokenFromRequest(req), { endpoint, operation });
1307
+ if (!validation.ok) {
1308
+ const status = validation.code === 'TOOL_ENDPOINT_DENIED' || validation.code === 'TOOL_OPERATION_DENIED' ? 403 : 401;
1309
+ sendApiError(res, status, validation.code, validation.message, {
1310
+ details: { endpoint, operation },
1311
+ });
1312
+ return null;
1313
+ }
1314
+ return validation.grant;
1315
+ }
1316
+ function requestProjectOverride(projectId, tokenProjectId) {
1317
+ return typeof projectId === 'string' && projectId.length > 0 && projectId !== tokenProjectId;
1318
+ }
1319
+ function requestRunOverride(runId, tokenRunId) {
1320
+ return typeof runId === 'string' && runId.length > 0 && runId !== tokenRunId;
1321
+ }
1322
+ function openNativeFolderDialog() {
1323
+ return new Promise((resolve) => {
1324
+ const platform = process.platform;
1325
+ if (platform === 'darwin') {
1326
+ execFile('osascript', ['-e', 'POSIX path of (choose folder with prompt "Select a code folder to link")'], { timeout: 120_000 }, (err, stdout) => {
1327
+ if (err)
1328
+ return resolve(null);
1329
+ const p = stdout.trim().replace(/\/$/, '');
1330
+ resolve(p || null);
1331
+ });
1332
+ }
1333
+ else if (platform === 'linux') {
1334
+ execFile('zenity', ['--file-selection', '--directory', '--title=Select a code folder to link'], { timeout: 120_000 }, (err, stdout) => {
1335
+ if (err)
1336
+ return resolve(null);
1337
+ const p = stdout.trim();
1338
+ resolve(p || null);
1339
+ });
1340
+ }
1341
+ else if (platform === 'win32') {
1342
+ const command = buildWindowsFolderDialogCommand();
1343
+ execFile(command.command, command.args, { timeout: 120_000 }, (err, stdout) => {
1344
+ resolve(parseFolderDialogStdout(err, stdout));
1345
+ });
1346
+ }
1347
+ else {
1348
+ resolve(null);
1349
+ }
1350
+ });
1351
+ }
1352
+ /**
1353
+ * @param {ApiErrorCode} code
1354
+ * @param {string} message
1355
+ * @param {Omit<ApiError, 'code' | 'message'>} [init]
1356
+ */
1357
+ function createSseErrorPayload(code, message, init = {}) {
1358
+ return { message, error: createCompatApiError(code, message, init) };
1359
+ }
1360
+ const UPLOAD_DIR = path.join(os.tmpdir(), 'od-uploads');
1361
+ fs.mkdirSync(UPLOAD_DIR, { recursive: true });
1362
+ fs.mkdirSync(ARTIFACTS_DIR, { recursive: true });
1363
+ const upload = multer({
1364
+ storage: multer.diskStorage({
1365
+ destination: UPLOAD_DIR,
1366
+ filename: (_req, file, cb) => {
1367
+ file.originalname = decodeMultipartFilename(file.originalname);
1368
+ const safe = sanitizeName(file.originalname);
1369
+ cb(null, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safe}`);
1370
+ },
1371
+ }),
1372
+ limits: { fileSize: 20 * 1024 * 1024 },
1373
+ });
1374
+ const importUpload = multer({
1375
+ storage: multer.diskStorage({
1376
+ destination: UPLOAD_DIR,
1377
+ filename: (_req, file, cb) => {
1378
+ file.originalname = decodeMultipartFilename(file.originalname);
1379
+ const safe = sanitizeName(file.originalname);
1380
+ cb(null, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safe}`);
1381
+ },
1382
+ }),
1383
+ limits: { fileSize: 100 * 1024 * 1024 },
1384
+ });
1385
+ // Project-scoped multi-file upload. Lands files directly in the project
1386
+ // folder (flat — same shape FileWorkspace expects), so the composer's
1387
+ // pasted/dropped/picked images become referenceable filenames the agent
1388
+ // can Read or @-mention without any cross-folder gymnastics.
1389
+ // Bridge between the multer upload-storage destination (built at module
1390
+ // init) and the per-process project DB (instantiated inside startServer).
1391
+ // startServer() sets this so the upload destination can route attachments
1392
+ // into the right project root, including folder-imported projects whose
1393
+ // files live under metadata.baseDir.
1394
+ let projectMetadataLookup = null;
1395
+ const projectUpload = multer({
1396
+ storage: multer.diskStorage({
1397
+ destination: async (req, _file, cb) => {
1398
+ try {
1399
+ // Route uploads into the project's actual root: for folder-imported
1400
+ // projects (metadata.baseDir set) attachments need to land alongside
1401
+ // the user's files so the agent can read them via the same path
1402
+ // it sees. projectMetadataLookup is populated at startServer() boot
1403
+ // and keyed by project id; null fallback gives the standard
1404
+ // .od/projects/<id>/ behavior for non-imported projects.
1405
+ const meta = projectMetadataLookup?.(req.params.id) ?? null;
1406
+ const dir = await ensureProject(PROJECTS_DIR, req.params.id, meta);
1407
+ cb(null, dir);
1408
+ }
1409
+ catch (err) {
1410
+ cb(err, '');
1411
+ }
1412
+ },
1413
+ filename: (_req, file, cb) => {
1414
+ // multer@1 hands us latin1-decoded multipart filenames; restore the
1415
+ // original UTF-8 so the response (and the on-disk name) preserves
1416
+ // non-ASCII characters instead of mangling them. Then run the
1417
+ // shared sanitiser and prepend a base36 timestamp so multiple
1418
+ // uploads with the same original name don't clobber each other.
1419
+ file.originalname = decodeMultipartFilename(file.originalname);
1420
+ const safe = sanitizeName(file.originalname);
1421
+ cb(null, `${Date.now().toString(36)}-${safe}`);
1422
+ },
1423
+ }),
1424
+ limits: { fileSize: 200 * 1024 * 1024 }, // 200MB — covers the largest design assets we expect (PPTX/PDF/raw images)
1425
+ });
1426
+ function handleProjectUpload(req, res, next) {
1427
+ projectUpload.array('files', 12)(req, res, (err) => {
1428
+ if (err) {
1429
+ return sendMulterError(res, err);
1430
+ }
1431
+ next();
1432
+ });
1433
+ }
1434
+ function sendMulterError(res, err) {
1435
+ if (err instanceof multer.MulterError) {
1436
+ const code = err.code || 'UPLOAD_ERROR';
1437
+ const statusByCode = {
1438
+ LIMIT_FILE_SIZE: 413,
1439
+ LIMIT_FILE_COUNT: 400,
1440
+ LIMIT_UNEXPECTED_FILE: 400,
1441
+ LIMIT_PART_COUNT: 400,
1442
+ LIMIT_FIELD_KEY: 400,
1443
+ LIMIT_FIELD_VALUE: 400,
1444
+ LIMIT_FIELD_COUNT: 400,
1445
+ MISSING_FIELD_NAME: 400,
1446
+ };
1447
+ const errorByCode = {
1448
+ LIMIT_FILE_SIZE: 'file too large',
1449
+ LIMIT_FILE_COUNT: 'too many files',
1450
+ LIMIT_UNEXPECTED_FILE: 'unexpected file field',
1451
+ LIMIT_PART_COUNT: 'too many form parts',
1452
+ LIMIT_FIELD_KEY: 'field name too long',
1453
+ LIMIT_FIELD_VALUE: 'field value too long',
1454
+ LIMIT_FIELD_COUNT: 'too many form fields',
1455
+ MISSING_FIELD_NAME: 'missing field name',
1456
+ };
1457
+ const status = statusByCode[code] ?? 400;
1458
+ const message = errorByCode[code] ?? 'upload failed';
1459
+ return sendApiError(res, status, code === 'LIMIT_FILE_SIZE' ? 'PAYLOAD_TOO_LARGE' : 'BAD_REQUEST', message, { details: { legacyCode: code } });
1460
+ }
1461
+ if (err) {
1462
+ return sendApiError(res, 500, 'INTERNAL_ERROR', 'upload failed');
1463
+ }
1464
+ return sendApiError(res, 500, 'INTERNAL_ERROR', 'upload failed');
1465
+ }
1466
+ const mediaTasks = new Map();
1467
+ const TASK_TTL_AFTER_DONE_MS = 10 * 60 * 1000;
1468
+ const MEDIA_TERMINAL_STATUSES = new Set(['done', 'failed', 'interrupted']);
1469
+ function hydrateMediaTask(row) {
1470
+ const task = {
1471
+ id: row.id,
1472
+ projectId: row.projectId,
1473
+ status: row.status,
1474
+ surface: row.surface,
1475
+ model: row.model,
1476
+ progress: Array.isArray(row.progress) ? row.progress.slice() : [],
1477
+ file: row.file ?? null,
1478
+ error: row.error ?? null,
1479
+ startedAt: row.startedAt,
1480
+ endedAt: row.endedAt,
1481
+ waiters: new Set(),
1482
+ };
1483
+ mediaTasks.set(task.id, task);
1484
+ return task;
1485
+ }
1486
+ function getLiveMediaTask(db, taskId) {
1487
+ const cached = mediaTasks.get(taskId);
1488
+ if (cached)
1489
+ return cached;
1490
+ const row = getMediaTask(db, taskId);
1491
+ return row ? hydrateMediaTask(row) : null;
1492
+ }
1493
+ function createMediaTask(db, taskId, projectId, info = {}) {
1494
+ const task = {
1495
+ id: taskId,
1496
+ projectId,
1497
+ status: 'queued',
1498
+ surface: info.surface,
1499
+ model: info.model,
1500
+ progress: [],
1501
+ file: null,
1502
+ error: null,
1503
+ startedAt: Date.now(),
1504
+ endedAt: null,
1505
+ waiters: new Set(),
1506
+ };
1507
+ mediaTasks.set(taskId, task);
1508
+ insertMediaTask(db, {
1509
+ id: taskId,
1510
+ projectId,
1511
+ status: task.status,
1512
+ surface: task.surface,
1513
+ model: task.model,
1514
+ progress: task.progress,
1515
+ file: task.file,
1516
+ error: task.error,
1517
+ startedAt: task.startedAt,
1518
+ endedAt: task.endedAt,
1519
+ });
1520
+ return task;
1521
+ }
1522
+ function persistMediaTask(db, task) {
1523
+ updateMediaTask(db, task.id, {
1524
+ status: task.status,
1525
+ surface: task.surface,
1526
+ model: task.model,
1527
+ progress: task.progress,
1528
+ file: task.file,
1529
+ error: task.error,
1530
+ startedAt: task.startedAt,
1531
+ endedAt: task.endedAt,
1532
+ });
1533
+ }
1534
+ function appendTaskProgress(db, task, line) {
1535
+ task.progress.push(line);
1536
+ persistMediaTask(db, task);
1537
+ notifyTaskWaiters(db, task);
1538
+ }
1539
+ function notifyTaskWaiters(db, task) {
1540
+ const wakers = Array.from(task.waiters);
1541
+ for (const w of wakers) {
1542
+ try {
1543
+ w();
1544
+ }
1545
+ catch {
1546
+ // Never let one bad waiter block the rest.
1547
+ }
1548
+ }
1549
+ if (MEDIA_TERMINAL_STATUSES.has(task.status) &&
1550
+ !task._gcScheduled) {
1551
+ task._gcScheduled = true;
1552
+ setTimeout(() => {
1553
+ if (task.waiters.size === 0) {
1554
+ mediaTasks.delete(task.id);
1555
+ deleteMediaTask(db, task.id);
1556
+ }
1557
+ }, TASK_TTL_AFTER_DONE_MS).unref?.();
1558
+ }
1559
+ }
1560
+ function mediaTaskSnapshot(task, since = 0) {
1561
+ const snapshot = {
1562
+ taskId: task.id,
1563
+ status: task.status,
1564
+ startedAt: task.startedAt,
1565
+ endedAt: task.endedAt,
1566
+ progress: task.progress.slice(since),
1567
+ nextSince: task.progress.length,
1568
+ };
1569
+ if (task.status === 'done')
1570
+ snapshot.file = task.file;
1571
+ if (task.status === 'failed' || task.status === 'interrupted') {
1572
+ snapshot.error = task.error;
1573
+ }
1574
+ return snapshot;
1575
+ }
1576
+ export function createSseResponse(res, { keepAliveIntervalMs = SSE_KEEPALIVE_INTERVAL_MS } = {}) {
1577
+ res.setHeader('Content-Type', 'text/event-stream');
1578
+ res.setHeader('Cache-Control', 'no-cache, no-transform');
1579
+ res.setHeader('Connection', 'keep-alive');
1580
+ res.setHeader('X-Accel-Buffering', 'no');
1581
+ res.flushHeaders?.();
1582
+ const canWrite = () => !res.destroyed && !res.writableEnded;
1583
+ const writeKeepAlive = () => {
1584
+ if (canWrite()) {
1585
+ res.write(': keepalive\n\n');
1586
+ return true;
1587
+ }
1588
+ return false;
1589
+ };
1590
+ let heartbeat = null;
1591
+ if (keepAliveIntervalMs > 0) {
1592
+ heartbeat = setInterval(writeKeepAlive, keepAliveIntervalMs);
1593
+ heartbeat.unref?.();
1594
+ }
1595
+ const cleanup = () => {
1596
+ if (heartbeat) {
1597
+ clearInterval(heartbeat);
1598
+ heartbeat = null;
1599
+ }
1600
+ };
1601
+ res.on('close', cleanup);
1602
+ res.on('finish', cleanup);
1603
+ return {
1604
+ /** @param {ChatSseEvent['event'] | ProxySseEvent['event'] | string} event */
1605
+ send(event, data, id = null) {
1606
+ if (!canWrite())
1607
+ return false;
1608
+ // Assemble the full SSE event into a single write so id/event/data land
1609
+ // in one TCP chunk. Three separate writes would let `event: <type>` flush
1610
+ // ahead of the `data:` payload, which produces partial events for
1611
+ // consumers that read chunk-by-chunk (e.g. tests using a Response body
1612
+ // reader with a substring marker).
1613
+ const idLine = id !== null && id !== undefined ? `id: ${id}\n` : '';
1614
+ res.write(`${idLine}event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
1615
+ return true;
1616
+ },
1617
+ writeKeepAlive,
1618
+ cleanup,
1619
+ end() {
1620
+ cleanup();
1621
+ if (canWrite()) {
1622
+ res.end();
1623
+ }
1624
+ },
1625
+ };
1626
+ }
1627
+ const DEFAULT_CHAT_RUN_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
1628
+ const MAX_CHAT_RUN_INACTIVITY_TIMEOUT_MS = 24 * 60 * 60 * 1000;
1629
+ function resolveChatRunInactivityTimeoutMs() {
1630
+ const raw = Number(process.env.OD_CHAT_RUN_INACTIVITY_TIMEOUT_MS);
1631
+ // This watchdog observes child stdout/stderr/SSE activity, not real CPU or
1632
+ // filesystem progress. Keep the default long enough for agents that spend
1633
+ // several minutes silently writing large artifacts.
1634
+ if (!Number.isFinite(raw))
1635
+ return DEFAULT_CHAT_RUN_INACTIVITY_TIMEOUT_MS;
1636
+ // Node clamps delays larger than a signed 32-bit integer down to 1ms, which
1637
+ // makes an oversized override fail almost immediately while reporting a huge
1638
+ // timeout. Keep explicit overrides bounded to a practical, timer-safe value.
1639
+ return Math.min(MAX_CHAT_RUN_INACTIVITY_TIMEOUT_MS, Math.max(0, Math.floor(raw)));
1640
+ }
1641
+ function resolveChatRunShutdownGraceMs() {
1642
+ const raw = Number(process.env.OD_CHAT_RUN_SHUTDOWN_GRACE_MS);
1643
+ if (!Number.isFinite(raw))
1644
+ return 3_000;
1645
+ return Math.max(0, Math.floor(raw));
1646
+ }
1647
+ function resolveAcpStageTimeoutMs() {
1648
+ // Per-stage silence watchdog for ACP chat sessions. Defaults are owned by
1649
+ // `attachAcpSession` in acp.ts; this resolver only applies when an operator
1650
+ // sets `OD_ACP_STAGE_TIMEOUT_MS`. Bounded to the same 24h ceiling as the
1651
+ // outer chat inactivity watchdog so an oversized override doesn't get
1652
+ // clamped to 1ms by Node's signed-32-bit delay limit.
1653
+ const raw = Number(process.env.OD_ACP_STAGE_TIMEOUT_MS);
1654
+ if (!Number.isFinite(raw))
1655
+ return undefined;
1656
+ return Math.min(MAX_CHAT_RUN_INACTIVITY_TIMEOUT_MS, Math.max(0, Math.floor(raw)));
1657
+ }
1658
+ export async function startServer({ port = 7456, host = process.env.OD_BIND_HOST || '127.0.0.1', returnServer = false, desktopPdfExporter = null, } = {}) {
1659
+ let resolvedPort = port;
1660
+ let daemonShuttingDown = false;
1661
+ const extraAllowedOrigins = configuredAllowedOrigins();
1662
+ const app = express();
1663
+ app.use(express.json({ limit: '4mb' }));
1664
+ // Multi-directory scanning shared by every skill / template surface. The
1665
+ // helpers delegate to listSkills(roots) which walks roots in priority
1666
+ // order, tags each entry with the SkillSource ('user' for the user
1667
+ // root, 'built-in' for the bundled root) the contracts package
1668
+ // declares, and lets a user-imported entry shadow a built-in one of
1669
+ // the same id without erasing the built-in copy.
1670
+ async function listAllSkills() {
1671
+ return listSkills(SKILL_ROOTS);
1672
+ }
1673
+ async function listAllDesignTemplates() {
1674
+ return listSkills(DESIGN_TEMPLATE_ROOTS);
1675
+ }
1676
+ // Spans both roots so chat run system-prompt composition and the orbit
1677
+ // template resolver can resolve a stored project.skillId regardless of
1678
+ // which surface created the project after the skills/design-templates
1679
+ // split. Keep in sync with SKILL_ROOTS + DESIGN_TEMPLATE_ROOTS above.
1680
+ async function listAllSkillLikeEntries() {
1681
+ return listSkills(ALL_SKILL_LIKE_ROOTS);
1682
+ }
1683
+ async function listAllDesignSystems() {
1684
+ const builtIn = (await listDesignSystems(DESIGN_SYSTEMS_DIR)).map((s) => ({
1685
+ ...s,
1686
+ source: 'built-in',
1687
+ }));
1688
+ let installed = [];
1689
+ try {
1690
+ installed = (await listDesignSystems(USER_DESIGN_SYSTEMS_DIR)).map((s) => ({ ...s, source: 'installed' }));
1691
+ }
1692
+ catch {
1693
+ // User directory may not exist yet or be unreadable.
1694
+ }
1695
+ const seen = new Set(builtIn.map((s) => s.id));
1696
+ return [...builtIn, ...installed.filter((s) => !seen.has(s.id))];
1697
+ }
1698
+ // Chrome may strip the port from the Origin header on same-origin GET
1699
+ // requests. Only use this as a fallback for safe, idempotent GET requests;
1700
+ // mutating routes always require an exact origin/host match.
1701
+ function isPortlessLoopbackOrigin(origin) {
1702
+ return /^https?:\/\/(127\.0\.0\.1|localhost|\[::1\])$/.test(origin);
1703
+ }
1704
+ // Routes that serve content to sandboxed iframes (Origin: null) for
1705
+ // read-only purposes. All other /api routes reject Origin: null.
1706
+ const _NULL_ORIGIN_SAFE_GET_RE = /^\/projects\/[^/]+\/raw\/|^\/codex-pets\/[^/]+\/spritesheet$/;
1707
+ // Reject cross-origin requests to API endpoints.
1708
+ // Health/version remain open for monitoring probes.
1709
+ // Non-browser clients (no Origin header) are always allowed.
1710
+ app.use('/api', (req, res, next) => {
1711
+ // Live artifact previews have stricter local-daemon validation and
1712
+ // loopback CORS handling on the route itself. Let that middleware produce
1713
+ // the structured error shape and preflight headers for preview embeds.
1714
+ if (/^\/live-artifacts\/[^/]+\/preview$/.test(req.path))
1715
+ return next();
1716
+ const origin = req.headers.origin;
1717
+ // Non-browser client → allow.
1718
+ if (origin == null || origin === '')
1719
+ return next();
1720
+ // Origin: null (sandboxed iframes). Only allowed for safe, read-only
1721
+ // routes that set their own CORS headers for canvas drawing.
1722
+ if (origin === 'null') {
1723
+ const isSafeReadOnly = req.method === 'GET' && _NULL_ORIGIN_SAFE_GET_RE.test(req.path);
1724
+ if (!isSafeReadOnly) {
1725
+ return res.status(403).json({ error: 'Origin: null not allowed for this route' });
1726
+ }
1727
+ return next();
1728
+ }
1729
+ // Fail-closed: block all browser origins until port is resolved.
1730
+ if (!resolvedPort) {
1731
+ return res.status(403).json({ error: 'Server initializing' });
1732
+ }
1733
+ const ports = allowedBrowserPorts(resolvedPort);
1734
+ if (!isAllowedBrowserOrigin(origin, req.headers.host, ports, host, extraAllowedOrigins)) {
1735
+ if (req.method !== 'GET' || !isPortlessLoopbackOrigin(String(origin))) {
1736
+ return res.status(403).json({ error: 'Cross-origin requests are not allowed' });
1737
+ }
1738
+ }
1739
+ next();
1740
+ });
1741
+ const db = openDatabase(PROJECT_ROOT, { dataDir: RUNTIME_DATA_DIR });
1742
+ // Wire the upload-destination bridge to this db so multer can route
1743
+ // file uploads into baseDir-rooted projects' actual folders.
1744
+ projectMetadataLookup = (id) => {
1745
+ try {
1746
+ return getProject(db, id)?.metadata ?? null;
1747
+ }
1748
+ catch {
1749
+ return null;
1750
+ }
1751
+ };
1752
+ configureConnectorCredentialStore(new FileConnectorCredentialStore(RUNTIME_DATA_DIR));
1753
+ configureComposioConfigStore(RUNTIME_DATA_DIR);
1754
+ composioConnectorProvider.configureCatalogCache(RUNTIME_DATA_DIR);
1755
+ composioConnectorProvider.startCatalogRefreshLoop();
1756
+ // RoutineService persistence is a thin adapter over the SQLite helpers.
1757
+ // Routines are stored as DB rows; the service holds in-memory timers and
1758
+ // delegates "list me everything" / "record a run" back to SQLite.
1759
+ routineService = new RoutineService({
1760
+ list: () => listRoutines(db).map((row) => routineDbRowToContract(row, null)),
1761
+ insertRun: (run) => {
1762
+ insertRoutineRun(db, {
1763
+ id: run.id,
1764
+ routineId: run.routineId,
1765
+ trigger: run.trigger,
1766
+ status: run.status,
1767
+ projectId: run.projectId,
1768
+ conversationId: run.conversationId,
1769
+ agentRunId: run.agentRunId,
1770
+ startedAt: run.startedAt,
1771
+ completedAt: run.completedAt,
1772
+ summary: run.summary,
1773
+ error: run.error,
1774
+ });
1775
+ },
1776
+ updateRun: (id, patch) => {
1777
+ updateRoutineRun(db, id, patch);
1778
+ },
1779
+ getLatestRun: (routineId) => getLatestRoutineRun(db, routineId),
1780
+ });
1781
+ let daemonUrl = `http://127.0.0.1:${port}`;
1782
+ // Boot reconcile: any critique_runs row left in 'running' state by a prior
1783
+ // daemon crash gets flipped to 'interrupted' with rounds_json.recoveryReason
1784
+ // = 'daemon_restart' so the spec's daemon-restart-mid-run failure mode is
1785
+ // honored on every boot. staleAfterMs comes from CritiqueConfig, not a
1786
+ // hardcoded constant.
1787
+ const reconciledStaleRuns = reconcileStaleRuns(db, { staleAfterMs: critiqueCfg.totalTimeoutMs });
1788
+ if (reconciledStaleRuns > 0) {
1789
+ console.warn(`[critique] reconcileStaleRuns flipped ${reconciledStaleRuns} stale running row(s) to interrupted`);
1790
+ }
1791
+ const mediaReconcile = reconcileMediaTasksOnBoot(db, {
1792
+ terminalTtlMs: TASK_TTL_AFTER_DONE_MS,
1793
+ });
1794
+ if (mediaReconcile.interrupted > 0 || mediaReconcile.deleted > 0) {
1795
+ console.warn(`[media] reconcileMediaTasksOnBoot interrupted ${mediaReconcile.interrupted} task(s), ` +
1796
+ `deleted ${mediaReconcile.deleted} expired terminal task(s)`);
1797
+ }
1798
+ mediaTasks.clear();
1799
+ for (const row of listRecentMediaTasks(db, { terminalTtlMs: TASK_TTL_AFTER_DONE_MS })) {
1800
+ hydrateMediaTask(row);
1801
+ }
1802
+ if (process.env.OD_CODEX_DISABLE_PLUGINS === '1') {
1803
+ console.log('[od] Codex plugins disabled via OD_CODEX_DISABLE_PLUGINS=1');
1804
+ }
1805
+ // Warm agent-capability probes (e.g. whether the installed Claude Code
1806
+ // build advertises --include-partial-messages) so the first /api/chat
1807
+ // hits a populated cache even if /api/agents hasn't been called yet.
1808
+ void readAppConfig(RUNTIME_DATA_DIR)
1809
+ .then((config) => {
1810
+ orbitService.configure(config.orbit);
1811
+ return detectAgents(config.agentCliEnv ?? {});
1812
+ })
1813
+ .catch(() => detectAgents().catch(() => { }));
1814
+ await recoverStaleLiveArtifactRefreshes({ projectsRoot: PROJECTS_DIR }).catch((error) => {
1815
+ console.warn('[od] Failed to recover stale live artifact refreshes:', error);
1816
+ });
1817
+ if (fs.existsSync(STATIC_DIR)) {
1818
+ app.use(express.static(STATIC_DIR));
1819
+ }
1820
+ app.get('/api/health', async (_req, res) => {
1821
+ const versionInfo = await readCurrentAppVersionInfo();
1822
+ res.json({ ok: true, version: versionInfo.version });
1823
+ });
1824
+ app.get('/api/version', async (_req, res) => {
1825
+ const version = await readCurrentAppVersionInfo();
1826
+ res.json({ version });
1827
+ });
1828
+ // Prometheus scrape endpoint (Phase 12). Returns the full exposition
1829
+ // format string. Operators put this behind their existing auth proxy;
1830
+ // there is no built-in authn on the daemon HTTP server. To disable
1831
+ // the endpoint entirely (air-gapped installs, regulatory contexts),
1832
+ // set `OD_METRICS_ENDPOINT=disabled`; the route is registered only
1833
+ // when that env value is not the literal string 'disabled'.
1834
+ if (process.env.OD_METRICS_ENDPOINT !== 'disabled') {
1835
+ app.get('/api/metrics', async (_req, res) => {
1836
+ res.setHeader('Content-Type', register.contentType);
1837
+ res.send(await getCritiqueMetrics());
1838
+ });
1839
+ }
1840
+ // Phase 16 ratchet endpoint. Returns the rolling conformance window
1841
+ // and the ratchet's current recommendation. Operator-driven by
1842
+ // design: the recommendation does not flip OD_CRITIQUE_ROLLOUT_PHASE
1843
+ // automatically, it surfaces so a deploy-pipeline follow-up can
1844
+ // consume it. Tunables come from query string; defaults are the
1845
+ // spec values (14 days, 0.90 shipped, 0.95 clean-parse).
1846
+ // Codex + lefarcen P1 on PR #1499: clamp query inputs before the
1847
+ // evaluator sees them so a request like `?windowDays=0` falls back to
1848
+ // the spec default rather than producing a zero-evidence promotion.
1849
+ // The evaluator also defends at its own entry; both are intentional
1850
+ // (belt + suspenders) so a future caller that bypasses this route
1851
+ // cannot reach an unguarded code path either.
1852
+ const parsePositiveInt = (raw, fallback) => {
1853
+ if (typeof raw !== 'string' || raw.length === 0)
1854
+ return fallback;
1855
+ const n = Number(raw);
1856
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
1857
+ };
1858
+ const parseRate = (raw, fallback) => {
1859
+ if (typeof raw !== 'string' || raw.length === 0)
1860
+ return fallback;
1861
+ const n = Number(raw);
1862
+ return Number.isFinite(n) && n >= 0 && n <= 1 ? n : fallback;
1863
+ };
1864
+ app.get('/api/critique/conformance', async (req, res) => {
1865
+ try {
1866
+ const windowDays = parsePositiveInt(req.query.windowDays, 14);
1867
+ const shippedThreshold = parseRate(req.query.shippedThreshold, 0.90);
1868
+ const cleanParseThreshold = parseRate(req.query.cleanParseThreshold, 0.95);
1869
+ const history = await readConformanceHistory(RUNTIME_DATA_DIR, windowDays);
1870
+ const decision = evaluateRollout({
1871
+ current: parseRolloutPhase(process.env.OD_CRITIQUE_ROLLOUT_PHASE),
1872
+ history,
1873
+ windowDays,
1874
+ shippedThreshold,
1875
+ cleanParseThreshold,
1876
+ });
1877
+ res.json({ window: { days: windowDays, history }, decision });
1878
+ }
1879
+ catch (err) {
1880
+ sendApiError(res, 500, 'INTERNAL_ERROR', err instanceof Error ? err.message : String(err));
1881
+ }
1882
+ });
1883
+ registerConnectorRoutes(app, {
1884
+ sendApiError,
1885
+ authorizeToolRequest,
1886
+ projectsRoot: PROJECTS_DIR,
1887
+ requireLocalDaemonRequest,
1888
+ composio: composioConnectorProvider,
1889
+ });
1890
+ // ---- Projects (DB-backed) -------------------------------------------------
1891
+ // ----- Memory store -----------------------------------------------------
1892
+ // Markdown-on-disk memory under <dataDir>/memory/. The daemon folds these
1893
+ // into every system prompt (gated by `enabled`) and the chat run loop
1894
+ // calls `/api/memory/extract` after each turn to sediment new facts.
1895
+ app.get('/api/memory', async (_req, res) => {
1896
+ try {
1897
+ const [config, index, entries] = await Promise.all([
1898
+ readMemoryConfig(RUNTIME_DATA_DIR),
1899
+ readMemoryIndex(RUNTIME_DATA_DIR),
1900
+ listMemoryEntries(RUNTIME_DATA_DIR),
1901
+ ]);
1902
+ res.json({
1903
+ enabled: config.enabled,
1904
+ rootDir: memoryDir(RUNTIME_DATA_DIR),
1905
+ index,
1906
+ entries,
1907
+ extraction: maskMemoryExtractionConfig(config.extraction),
1908
+ });
1909
+ }
1910
+ catch (err) {
1911
+ res.status(500).json({ error: String(err) });
1912
+ }
1913
+ });
1914
+ // Static sub-resources (`/index`, `/config`, `/extract`) registered
1915
+ // BEFORE the `:id` catch-alls so an `index` / `config` / `extract` slug
1916
+ // can't shadow the real handlers.
1917
+ app.put('/api/memory/index', async (req, res) => {
1918
+ try {
1919
+ const body = req.body && typeof req.body === 'object' ? req.body : {};
1920
+ const index = typeof body.index === 'string' ? body.index : '';
1921
+ await writeMemoryIndex(RUNTIME_DATA_DIR, index);
1922
+ res.json({ index });
1923
+ }
1924
+ catch (err) {
1925
+ res.status(400).json({ error: String((err && err.message) || err) });
1926
+ }
1927
+ });
1928
+ app.patch('/api/memory/config', async (req, res) => {
1929
+ try {
1930
+ const body = req.body && typeof req.body === 'object' ? req.body : {};
1931
+ const patch = {};
1932
+ if (typeof body.enabled === 'boolean')
1933
+ patch.enabled = body.enabled;
1934
+ // Three-state extraction handling so the UI can: (a) leave the
1935
+ // override alone (omit `extraction`), (b) clear it back to
1936
+ // auto-pick (`extraction: null`), or (c) commit a custom override
1937
+ // (`extraction: { provider, ... }`). For the apiKey field we
1938
+ // need *four* states because the masked GET surfaces only an
1939
+ // `apiKeyTail` (the secret never round-trips):
1940
+ // - field absent → preserve the stored key (UI re-saves
1941
+ // a settings form without re-typing
1942
+ // the secret).
1943
+ // - field === '' → CLEAR the stored key (the picker's
1944
+ // drift-resync effect fires this when
1945
+ // the user clears their BYOK chat
1946
+ // API key — keeping the old daemon-
1947
+ // side credential would silently keep
1948
+ // calling the provider after the user
1949
+ // intentionally removed it from the
1950
+ // chat picker, which the reviewer
1951
+ // flagged as a credential-sync bug).
1952
+ // - field === 'sk-…' → replace with the new key.
1953
+ // - provider differs → ignore stored key entirely.
1954
+ if (Object.prototype.hasOwnProperty.call(body, 'extraction')) {
1955
+ if (body.extraction === null) {
1956
+ patch.extraction = null;
1957
+ }
1958
+ else if (body.extraction && typeof body.extraction === 'object') {
1959
+ const incoming = body.extraction;
1960
+ const current = await readMemoryConfig(RUNTIME_DATA_DIR);
1961
+ const apiKeyOmitted = !Object.prototype.hasOwnProperty.call(incoming, 'apiKey');
1962
+ const sameProvider = !!current.extraction
1963
+ && current.extraction.provider === incoming.provider;
1964
+ let nextApiKey = '';
1965
+ if (typeof incoming.apiKey === 'string' && incoming.apiKey) {
1966
+ nextApiKey = incoming.apiKey;
1967
+ }
1968
+ else if (apiKeyOmitted && sameProvider) {
1969
+ nextApiKey = current.extraction.apiKey ?? '';
1970
+ }
1971
+ patch.extraction = {
1972
+ provider: incoming.provider,
1973
+ model: typeof incoming.model === 'string' ? incoming.model : undefined,
1974
+ baseUrl: typeof incoming.baseUrl === 'string'
1975
+ ? incoming.baseUrl
1976
+ : undefined,
1977
+ apiKey: nextApiKey,
1978
+ // Azure-only; ignored by the validator for the other providers.
1979
+ // We forward whatever the UI sent (or the previously-stored
1980
+ // value when the UI omits the field) so re-saving an azure
1981
+ // override without re-typing the api-version doesn't blank it.
1982
+ apiVersion: typeof incoming.apiVersion === 'string'
1983
+ ? incoming.apiVersion
1984
+ : current.extraction?.apiVersion,
1985
+ };
1986
+ }
1987
+ }
1988
+ const next = await writeMemoryConfig(RUNTIME_DATA_DIR, patch);
1989
+ res.json({
1990
+ enabled: next.enabled,
1991
+ extraction: maskMemoryExtractionConfig(next.extraction),
1992
+ });
1993
+ }
1994
+ catch (err) {
1995
+ res.status(400).json({ error: String((err && err.message) || err) });
1996
+ }
1997
+ });
1998
+ // SSE feed of memory mutations. The web settings panel subscribes to
1999
+ // this and re-fetches on every event; toast UIs can listen for
2000
+ // `kind === 'extract'` and surface a small "Memory updated (N new)"
2001
+ // notification. Payload shape: MemoryChangeEvent (see ./memory.ts).
2002
+ //
2003
+ // The same connection also forwards `extraction` events — one per LLM
2004
+ // extraction phase transition — so the settings panel can render a
2005
+ // live "recent extractions" list. We multiplex on a single SSE stream
2006
+ // so the browser opens one connection instead of two.
2007
+ app.get('/api/memory/events', async (_req, res) => {
2008
+ const sse = createSseResponse(res);
2009
+ sse.send('connected', { at: Date.now() });
2010
+ const onChange = (event) => {
2011
+ sse.send('change', event);
2012
+ };
2013
+ const onExtraction = (event) => {
2014
+ sse.send('extraction', event);
2015
+ };
2016
+ memoryEvents.on('change', onChange);
2017
+ memoryEvents.on('extraction', onExtraction);
2018
+ res.on('close', () => {
2019
+ memoryEvents.off('change', onChange);
2020
+ memoryEvents.off('extraction', onExtraction);
2021
+ });
2022
+ });
2023
+ // Recent LLM-extraction attempts (newest first; capped server-side).
2024
+ // Surfaces skip reasons, in-flight calls, success counts, and errors
2025
+ // so the settings panel can show "why didn't memory update?" at a
2026
+ // glance instead of leaving the user to guess.
2027
+ app.get('/api/memory/extractions', async (_req, res) => {
2028
+ try {
2029
+ res.json({ extractions: listMemoryExtractions() });
2030
+ }
2031
+ catch (err) {
2032
+ res.status(500).json({ error: String(err) });
2033
+ }
2034
+ });
2035
+ // Drop the entire extraction history. Registered BEFORE the `:id`
2036
+ // catch-all so a literal "/api/memory/extractions" can still be
2037
+ // cleared with `curl -X DELETE`.
2038
+ app.delete('/api/memory/extractions', async (_req, res) => {
2039
+ try {
2040
+ const removed = clearMemoryExtractions();
2041
+ res.json({ removed });
2042
+ }
2043
+ catch (err) {
2044
+ res.status(400).json({ error: String((err && err.message) || err) });
2045
+ }
2046
+ });
2047
+ app.delete('/api/memory/extractions/:id', async (req, res) => {
2048
+ try {
2049
+ const removed = removeMemoryExtraction(req.params.id);
2050
+ res.json({ removed });
2051
+ }
2052
+ catch (err) {
2053
+ res.status(400).json({ error: String((err && err.message) || err) });
2054
+ }
2055
+ });
2056
+ // Imperative extract — used by CLI chats internally and by BYOK /
2057
+ // API-mode chats from the web app, which never reach the chat-run
2058
+ // path on the daemon. Mirrors the two-phase hook the daemon's chat
2059
+ // route applies inline:
2060
+ //
2061
+ // - Pre-turn (only `userMessage` supplied): run the synchronous
2062
+ // heuristic regex pack so explicit "remember: X" / "我是 X"
2063
+ // markers land in memory before the prompt is composed, and the
2064
+ // same turn's assistant reply already reflects them.
2065
+ // - Post-turn (`userMessage` + `assistantMessage` supplied): queue
2066
+ // the LLM extractor in the background — it speaks SSE /
2067
+ // extraction-history on its own and may take several seconds, so
2068
+ // we don't block the HTTP response on it. The heuristic is
2069
+ // skipped on this branch because the caller already ran it
2070
+ // pre-turn; running it twice would double the
2071
+ // `recordHeuristic({...})` rows in the extraction history for
2072
+ // every turn.
2073
+ //
2074
+ // External callers (curl, replay tools) that pass only
2075
+ // `userMessage` keep the legacy behaviour: heuristic-only.
2076
+ app.post('/api/memory/extract', async (req, res) => {
2077
+ try {
2078
+ const body = req.body && typeof req.body === 'object' ? req.body : {};
2079
+ const userMessage = typeof body.userMessage === 'string' ? body.userMessage : '';
2080
+ const assistantMessage = typeof body.assistantMessage === 'string' ? body.assistantMessage : '';
2081
+ const hasAssistant = assistantMessage.trim().length > 0;
2082
+ const changed = hasAssistant
2083
+ ? []
2084
+ : await extractFromMessage(RUNTIME_DATA_DIR, userMessage);
2085
+ // BYOK chat config — only forwarded by the web app for API-mode
2086
+ // chats. We strip the surface to the five fields pickProvider()
2087
+ // actually consumes and validate the provider against the four
2088
+ // shapes the extractor speaks; an unknown / missing provider
2089
+ // means "let the legacy chain decide" so a malformed payload
2090
+ // can't override the env / media-config fallbacks.
2091
+ const rawChat = body.chatProvider;
2092
+ let chatProvider = null;
2093
+ if (rawChat && typeof rawChat === 'object') {
2094
+ const provider = rawChat.provider;
2095
+ if (provider === 'anthropic'
2096
+ || provider === 'openai'
2097
+ || provider === 'azure'
2098
+ || provider === 'google'
2099
+ || provider === 'ollama') {
2100
+ chatProvider = {
2101
+ provider,
2102
+ apiKey: typeof rawChat.apiKey === 'string' ? rawChat.apiKey : '',
2103
+ baseUrl: typeof rawChat.baseUrl === 'string' ? rawChat.baseUrl : '',
2104
+ apiVersion: typeof rawChat.apiVersion === 'string' ? rawChat.apiVersion : '',
2105
+ model: typeof rawChat.model === 'string' ? rawChat.model : '',
2106
+ };
2107
+ }
2108
+ }
2109
+ let attemptedLLM = false;
2110
+ if (userMessage.trim().length > 0 && hasAssistant) {
2111
+ attemptedLLM = true;
2112
+ void import('./memory-llm.js')
2113
+ .then(({ extractWithLLM }) => extractWithLLM(RUNTIME_DATA_DIR, { userMessage, assistantMessage }, {
2114
+ projectRoot: PROJECT_ROOT,
2115
+ chatAgentId: null,
2116
+ chatProvider,
2117
+ }))
2118
+ .catch((err) => console.warn('[memory-llm] background failed (http extract)', err));
2119
+ }
2120
+ res.json({ changed, attemptedLLM });
2121
+ }
2122
+ catch (err) {
2123
+ res.status(400).json({ error: String((err && err.message) || err) });
2124
+ }
2125
+ });
2126
+ // Composed memory body for the system prompt. Daemon-side chat runs
2127
+ // call `composeMemoryBody()` directly; the web app (BYOK / API mode)
2128
+ // can't import daemon internals, so this endpoint exposes the same
2129
+ // string the daemon would have folded into the system prompt for a
2130
+ // CLI run. `ProjectView.composedSystemPrompt()` calls it before each
2131
+ // BYOK turn and passes the result into `composeSystemPrompt`'s
2132
+ // `memoryBody` field — without this, the Memory tab is a no-op for
2133
+ // BYOK users even though the UI saves model/index/entries for them.
2134
+ app.get('/api/memory/system-prompt', async (_req, res) => {
2135
+ try {
2136
+ const body = await composeMemoryBody(RUNTIME_DATA_DIR);
2137
+ res.json({ body });
2138
+ }
2139
+ catch (err) {
2140
+ res.status(500).json({ error: String((err && err.message) || err) });
2141
+ }
2142
+ });
2143
+ app.post('/api/memory', async (req, res) => {
2144
+ try {
2145
+ const body = req.body && typeof req.body === 'object' ? req.body : {};
2146
+ const entry = await upsertMemoryEntry(RUNTIME_DATA_DIR, body);
2147
+ res.json({ entry });
2148
+ }
2149
+ catch (err) {
2150
+ res.status(400).json({ error: String((err && err.message) || err) });
2151
+ }
2152
+ });
2153
+ app.get('/api/memory/:id', async (req, res) => {
2154
+ try {
2155
+ const entry = await readMemoryEntry(RUNTIME_DATA_DIR, req.params.id);
2156
+ if (!entry)
2157
+ return res.status(404).json({ error: 'memory not found' });
2158
+ res.json({ entry });
2159
+ }
2160
+ catch (err) {
2161
+ res.status(400).json({ error: String((err && err.message) || err) });
2162
+ }
2163
+ });
2164
+ app.put('/api/memory/:id', async (req, res) => {
2165
+ try {
2166
+ const body = req.body && typeof req.body === 'object' ? req.body : {};
2167
+ const entry = await upsertMemoryEntry(RUNTIME_DATA_DIR, {
2168
+ ...body,
2169
+ id: req.params.id,
2170
+ });
2171
+ res.json({ entry });
2172
+ }
2173
+ catch (err) {
2174
+ res.status(400).json({ error: String((err && err.message) || err) });
2175
+ }
2176
+ });
2177
+ app.delete('/api/memory/:id', async (req, res) => {
2178
+ try {
2179
+ await deleteMemoryEntry(RUNTIME_DATA_DIR, req.params.id);
2180
+ res.json({ ok: true });
2181
+ }
2182
+ catch (err) {
2183
+ res.status(400).json({ error: String((err && err.message) || err) });
2184
+ }
2185
+ });
2186
+ const analyticsService = createAnalyticsService({ dataDir: RUNTIME_DATA_DIR });
2187
+ const design = {
2188
+ runs: createChatRunService({ createSseResponse, createSseErrorPayload }),
2189
+ analytics: analyticsService,
2190
+ getAppVersion: () => cachedAppVersion?.version ?? '0.0.0',
2191
+ readAnalyticsContext,
2192
+ };
2193
+ // PostHog runtime config — gated on BOTH a server-side key (POSTHOG_KEY)
2194
+ // and the user's opt-in metrics consent (Privacy → "Share usage data").
2195
+ // The web bundle short-circuits when enabled=false so opt-out behaviour
2196
+ // is instant after the user toggles metrics off and reloads.
2197
+ app.get('/api/analytics/config', async (_req, res) => {
2198
+ const baseline = readPublicConfigResponse();
2199
+ if (!baseline.enabled) {
2200
+ res.json(baseline);
2201
+ return;
2202
+ }
2203
+ try {
2204
+ const appCfg = await readAppConfig(RUNTIME_DATA_DIR);
2205
+ const consentGranted = appCfg.telemetry?.metrics === true;
2206
+ if (!consentGranted) {
2207
+ res.json({ enabled: false, key: null, host: null });
2208
+ return;
2209
+ }
2210
+ // Echo the installationId so the web client uses the same anonymous
2211
+ // id PostHog already saw on prior runs (and that Langfuse uses too).
2212
+ const installationId = typeof appCfg.installationId === 'string' && appCfg.installationId
2213
+ ? appCfg.installationId
2214
+ : null;
2215
+ res.json({ ...baseline, installationId });
2216
+ }
2217
+ catch {
2218
+ // If the config file is unreadable, fail closed — no events.
2219
+ res.json({ enabled: false, key: null, host: null });
2220
+ }
2221
+ });
2222
+ // Tracks runs whose completion has already been forwarded to Langfuse so
2223
+ // repeated message updates only emit one trace per run.
2224
+ const reportedRuns = new Set();
2225
+ // App-version snapshot read once at server start for Langfuse trace metadata.
2226
+ let cachedAppVersion = null;
2227
+ void (async () => {
2228
+ try {
2229
+ cachedAppVersion = await readCurrentAppVersionInfo();
2230
+ }
2231
+ catch {
2232
+ // Telemetry is best-effort; appVersion is omitted when unavailable.
2233
+ }
2234
+ })();
2235
+ const reportFinalizedMessage = createFinalizedMessageTelemetryReporter({
2236
+ design,
2237
+ db,
2238
+ dataDir: RUNTIME_DATA_DIR,
2239
+ reportedRuns,
2240
+ getAppVersion: () => cachedAppVersion,
2241
+ });
2242
+ const validateExternalApiBaseUrl = (baseUrl) => validateBaseUrl(baseUrl);
2243
+ const resolvedPortRef = {
2244
+ get current() {
2245
+ return resolvedPort;
2246
+ },
2247
+ };
2248
+ const daemonUrlRef = {
2249
+ get current() {
2250
+ return daemonUrl;
2251
+ },
2252
+ };
2253
+ const httpDeps = {
2254
+ sendApiError,
2255
+ sendMulterError,
2256
+ sendLiveArtifactRouteError,
2257
+ createSseResponse,
2258
+ requireLocalDaemonRequest,
2259
+ isLocalSameOrigin,
2260
+ resolvedPortRef,
2261
+ };
2262
+ const pathDeps = {
2263
+ PROJECT_ROOT,
2264
+ PROJECTS_DIR,
2265
+ ARTIFACTS_DIR,
2266
+ RUNTIME_DATA_DIR,
2267
+ RUNTIME_DATA_DIR_CANONICAL,
2268
+ DESIGN_SYSTEMS_DIR,
2269
+ USER_DESIGN_SYSTEMS_DIR,
2270
+ DESIGN_TEMPLATES_DIR,
2271
+ USER_DESIGN_TEMPLATES_DIR,
2272
+ SKILLS_DIR,
2273
+ USER_SKILLS_DIR,
2274
+ PROMPT_TEMPLATES_DIR,
2275
+ BUNDLED_PETS_DIR,
2276
+ OD_BIN,
2277
+ };
2278
+ const nodeDeps = { fs, path };
2279
+ const idDeps = { randomId, randomUUID };
2280
+ const uploadDeps = { upload, importUpload, handleProjectUpload };
2281
+ const projectStoreDeps = {
2282
+ getProject,
2283
+ insertProject,
2284
+ updateProject,
2285
+ dbDeleteProject,
2286
+ removeProjectDir,
2287
+ validateLinkedDirs,
2288
+ };
2289
+ const projectFileDeps = {
2290
+ ensureProject,
2291
+ listFiles,
2292
+ searchProjectFiles,
2293
+ readProjectFile,
2294
+ resolveProjectDir,
2295
+ resolveProjectFilePath,
2296
+ parseByteRange,
2297
+ renameProjectFile,
2298
+ deleteProjectFile,
2299
+ writeProjectFile,
2300
+ sanitizeName,
2301
+ listTabs,
2302
+ setTabs,
2303
+ };
2304
+ const conversationDeps = {
2305
+ insertConversation,
2306
+ getConversation,
2307
+ listConversations,
2308
+ updateConversation,
2309
+ deleteConversation,
2310
+ listMessages,
2311
+ upsertMessage,
2312
+ listPreviewComments,
2313
+ upsertPreviewComment,
2314
+ updatePreviewCommentStatus,
2315
+ deletePreviewComment,
2316
+ };
2317
+ const templateDeps = { getTemplate, listTemplates, deleteTemplate, insertTemplate, findTemplateByNameAndProject, updateTemplate };
2318
+ const projectStatusDeps = {
2319
+ listLatestProjectRunStatuses,
2320
+ listProjectsAwaitingInput,
2321
+ normalizeProjectDisplayStatus,
2322
+ composeProjectDisplayStatus,
2323
+ listProjects,
2324
+ };
2325
+ const projectEventDeps = { subscribeFileEvents, activeProjectEventSinks };
2326
+ const importDeps = { importClaudeDesignZip, projectDir, detectEntryFile };
2327
+ const projectExportDeps = {
2328
+ buildProjectArchive,
2329
+ buildBatchArchive,
2330
+ buildDesktopPdfExportInput,
2331
+ desktopPdfExporter,
2332
+ daemonUrlRef,
2333
+ sanitizeArchiveFilename,
2334
+ };
2335
+ const artifactDeps = {
2336
+ sanitizeSlug,
2337
+ lintArtifact,
2338
+ renderFindingsForAgent,
2339
+ validateArtifactManifestInput,
2340
+ };
2341
+ const deployDeps = {
2342
+ VERCEL_PROVIDER_ID,
2343
+ CLOUDFLARE_PAGES_PROVIDER_ID,
2344
+ isDeployProviderId,
2345
+ publicDeployConfigForProvider,
2346
+ readDeployConfig,
2347
+ writeDeployConfig,
2348
+ listCloudflarePagesZones,
2349
+ DeployError,
2350
+ listDeployments,
2351
+ publicDeployments,
2352
+ getDeployment,
2353
+ getDeploymentById,
2354
+ buildDeployFileSet,
2355
+ cloudflarePagesProjectNameForDeploy,
2356
+ cloudflarePagesProjectNameFromDeployment,
2357
+ checkCloudflarePagesDeploymentLinks,
2358
+ checkDeploymentUrl,
2359
+ deployToCloudflarePages,
2360
+ deployToVercel,
2361
+ upsertDeployment,
2362
+ publicDeployment,
2363
+ cloudflarePagesDeploymentMetadata,
2364
+ prepareDeployPreflight,
2365
+ };
2366
+ const mediaDeps = {
2367
+ MEDIA_PROVIDERS,
2368
+ IMAGE_MODELS,
2369
+ VIDEO_MODELS,
2370
+ AUDIO_MODELS_BY_KIND,
2371
+ MEDIA_ASPECTS,
2372
+ VIDEO_LENGTHS_SEC,
2373
+ AUDIO_DURATIONS_SEC,
2374
+ readMaskedConfig,
2375
+ writeConfig,
2376
+ generateMedia,
2377
+ mediaTasks,
2378
+ createMediaTask: (taskId, projectId, info) => createMediaTask(db, taskId, projectId, info),
2379
+ persistMediaTask: (task) => persistMediaTask(db, task),
2380
+ appendTaskProgress: (task, line) => appendTaskProgress(db, task, line),
2381
+ notifyTaskWaiters: (task) => notifyTaskWaiters(db, task),
2382
+ getLiveMediaTask: (taskId) => getLiveMediaTask(db, taskId),
2383
+ mediaTaskSnapshot,
2384
+ listMediaTasksByProject,
2385
+ listElevenLabsVoiceOptions,
2386
+ };
2387
+ const appConfigDeps = { readAppConfig, writeAppConfig };
2388
+ const orbitDeps = { orbitService };
2389
+ const nativeDialogDeps = { openNativeFolderDialog };
2390
+ const researchDeps = { searchResearch, ResearchError };
2391
+ const liveArtifactDeps = {
2392
+ createLiveArtifact,
2393
+ listLiveArtifacts,
2394
+ updateLiveArtifact,
2395
+ refreshLiveArtifact,
2396
+ emitLiveArtifactEvent,
2397
+ emitLiveArtifactRefreshEvent,
2398
+ readLiveArtifactCode,
2399
+ setLiveArtifactCodeHeaders,
2400
+ ensureLiveArtifactPreview,
2401
+ setLiveArtifactPreviewHeaders,
2402
+ getLiveArtifact,
2403
+ listLiveArtifactRefreshLogEntries,
2404
+ deleteLiveArtifact,
2405
+ };
2406
+ const authDeps = {
2407
+ authorizeToolRequest,
2408
+ consumedImportNonces,
2409
+ desktopAuthSecret: () => desktopAuthSecret,
2410
+ isDesktopAuthGateActive,
2411
+ pruneExpiredImportNonces,
2412
+ requestProjectOverride,
2413
+ requestRunOverride,
2414
+ verifyDesktopImportToken,
2415
+ };
2416
+ const finalizeDeps = {
2417
+ finalizeDesignPackage,
2418
+ FinalizePackageLockedError,
2419
+ FinalizeUpstreamError,
2420
+ redactSecrets,
2421
+ };
2422
+ const validationDeps = { isSafeId, validateExternalApiBaseUrl, validateBaseUrl };
2423
+ const agentDeps = {
2424
+ listProviderModels,
2425
+ testProviderConnection,
2426
+ testAgentConnection,
2427
+ getAgentDef,
2428
+ isKnownModel,
2429
+ sanitizeCustomModel,
2430
+ };
2431
+ const critiqueDeps = {
2432
+ handleCritiqueArtifact,
2433
+ handleCritiqueInterrupt,
2434
+ critiqueArtifactsRoot: CRITIQUE_ARTIFACTS_DIR,
2435
+ critiqueResponseCapBytes: critiqueCfg.parserMaxBlockBytes,
2436
+ critiqueRunRegistry,
2437
+ };
2438
+ // External services
2439
+ registerMcpRoutes(app, {
2440
+ http: httpDeps,
2441
+ paths: pathDeps,
2442
+ mcp: { pendingAuth: mcpPendingAuth, daemonUrlRef },
2443
+ });
2444
+ // Project workspace
2445
+ registerActiveContextRoutes(app, {
2446
+ db,
2447
+ http: httpDeps,
2448
+ projectStore: projectStoreDeps,
2449
+ });
2450
+ registerProjectRoutes(app, {
2451
+ db,
2452
+ design,
2453
+ http: httpDeps,
2454
+ paths: pathDeps,
2455
+ projectStore: projectStoreDeps,
2456
+ projectFiles: projectFileDeps,
2457
+ conversations: conversationDeps,
2458
+ templates: templateDeps,
2459
+ status: projectStatusDeps,
2460
+ events: projectEventDeps,
2461
+ ids: idDeps,
2462
+ telemetry: { reportFinalizedMessage },
2463
+ });
2464
+ registerImportRoutes(app, {
2465
+ db,
2466
+ http: httpDeps,
2467
+ uploads: uploadDeps,
2468
+ node: nodeDeps,
2469
+ ids: idDeps,
2470
+ paths: pathDeps,
2471
+ imports: importDeps,
2472
+ auth: authDeps,
2473
+ projectStore: projectStoreDeps,
2474
+ conversations: conversationDeps,
2475
+ projectFiles: projectFileDeps,
2476
+ });
2477
+ // Resource catalog
2478
+ registerStaticResourceRoutes(app, {
2479
+ http: httpDeps,
2480
+ paths: pathDeps,
2481
+ resources: {
2482
+ listAllSkills,
2483
+ listAllDesignTemplates,
2484
+ listAllSkillLikeEntries,
2485
+ listAllDesignSystems,
2486
+ mimeFor,
2487
+ },
2488
+ });
2489
+ registerProjectArtifactRoutes(app, {
2490
+ http: httpDeps,
2491
+ uploads: uploadDeps,
2492
+ paths: pathDeps,
2493
+ node: nodeDeps,
2494
+ artifacts: artifactDeps,
2495
+ });
2496
+ registerLiveArtifactRoutes(app, {
2497
+ db,
2498
+ http: httpDeps,
2499
+ paths: pathDeps,
2500
+ auth: authDeps,
2501
+ liveArtifacts: liveArtifactDeps,
2502
+ projectStore: projectStoreDeps,
2503
+ });
2504
+ app.use('/artifacts', express.static(ARTIFACTS_DIR));
2505
+ registerDeployRoutes(app, {
2506
+ db,
2507
+ http: httpDeps,
2508
+ paths: pathDeps,
2509
+ ids: idDeps,
2510
+ deploy: deployDeps,
2511
+ projectStore: projectStoreDeps,
2512
+ });
2513
+ registerFinalizeRoutes(app, {
2514
+ db,
2515
+ http: httpDeps,
2516
+ paths: pathDeps,
2517
+ projectStore: projectStoreDeps,
2518
+ validation: validationDeps,
2519
+ finalize: finalizeDeps,
2520
+ });
2521
+ registerDeploymentCheckRoutes(app, { db, http: httpDeps, deploy: deployDeps });
2522
+ app.use('/frames', express.static(FRAMES_DIR));
2523
+ registerProjectExportRoutes(app, {
2524
+ db,
2525
+ http: httpDeps,
2526
+ paths: pathDeps,
2527
+ projectStore: projectStoreDeps,
2528
+ exports: projectExportDeps,
2529
+ projectFiles: projectFileDeps,
2530
+ validation: validationDeps,
2531
+ });
2532
+ registerProjectFileRoutes(app, {
2533
+ db,
2534
+ http: httpDeps,
2535
+ paths: pathDeps,
2536
+ uploads: uploadDeps,
2537
+ node: nodeDeps,
2538
+ projectStore: projectStoreDeps,
2539
+ projectFiles: projectFileDeps,
2540
+ documents: { buildDocumentPreview },
2541
+ artifacts: artifactDeps,
2542
+ });
2543
+ registerMediaRoutes(app, {
2544
+ db,
2545
+ http: httpDeps,
2546
+ paths: pathDeps,
2547
+ ids: idDeps,
2548
+ media: mediaDeps,
2549
+ appConfig: appConfigDeps,
2550
+ orbit: orbitDeps,
2551
+ nativeDialogs: nativeDialogDeps,
2552
+ projectStore: projectStoreDeps,
2553
+ projectFiles: projectFileDeps,
2554
+ conversations: conversationDeps,
2555
+ research: researchDeps,
2556
+ });
2557
+ registerProjectUploadRoutes(app, { http: httpDeps, uploads: uploadDeps, node: nodeDeps });
2558
+ const composeDaemonSystemPrompt = async ({ agentId, projectId, skillId, designSystemId, streamFormat, connectedExternalMcp, }) => {
2559
+ const project = typeof projectId === 'string' && projectId
2560
+ ? getProject(db, projectId)
2561
+ : null;
2562
+ const effectiveSkillId = typeof skillId === 'string' && skillId ? skillId : project?.skillId;
2563
+ const effectiveDesignSystemId = typeof designSystemId === 'string' && designSystemId
2564
+ ? designSystemId
2565
+ : project?.designSystemId;
2566
+ const metadata = project?.metadata;
2567
+ let skillBody;
2568
+ let skillName;
2569
+ let skillMode;
2570
+ let skillCraftRequires = [];
2571
+ let activeSkillDir = null;
2572
+ // Per-skill Critique Theater override sourced from
2573
+ // `od.critique.policy` in the resolved skill's SKILL.md frontmatter.
2574
+ // `null` means the skill has no opinion and the lower-priority tiers
2575
+ // (project override, env override, rollout phase default) decide.
2576
+ let skillCritiquePolicy = null;
2577
+ if (effectiveSkillId) {
2578
+ // Span both functional skills and design templates so a project
2579
+ // saved against either surface keeps its system prompt after the
2580
+ // skills/design-templates split. See specs/current/skills-and-design-templates.md.
2581
+ const skill = findSkillById(await listAllSkillLikeEntries(), effectiveSkillId);
2582
+ if (skill) {
2583
+ skillBody = skill.body;
2584
+ skillName = skill.name;
2585
+ skillMode = skill.mode;
2586
+ activeSkillDir = skill.dir;
2587
+ skillCritiquePolicy = skill.critiquePolicy;
2588
+ if (Array.isArray(skill.craftRequires))
2589
+ skillCraftRequires = skill.craftRequires;
2590
+ }
2591
+ }
2592
+ let craftBody;
2593
+ let craftSections;
2594
+ if (skillCraftRequires.length > 0) {
2595
+ const loaded = await loadCraftSections(CRAFT_DIR, skillCraftRequires);
2596
+ if (loaded.body) {
2597
+ craftBody = loaded.body;
2598
+ craftSections = loaded.sections;
2599
+ }
2600
+ }
2601
+ // Personal-memory body is always recomputed at compose time so a
2602
+ // memory the user just edited in settings shows up on the very next
2603
+ // run. composeMemoryBody returns '' when memory is disabled or
2604
+ // empty; the composer drops the block on a falsy value.
2605
+ let memoryBody = '';
2606
+ try {
2607
+ memoryBody = await composeMemoryBody(RUNTIME_DATA_DIR);
2608
+ }
2609
+ catch (err) {
2610
+ console.warn('[memory] composeMemoryBody failed', err);
2611
+ }
2612
+ // User-level custom instructions from app-config.json.
2613
+ let userInstructions = '';
2614
+ try {
2615
+ const appCfg = await readAppConfig(RUNTIME_DATA_DIR);
2616
+ if (appCfg.customInstructions)
2617
+ userInstructions = appCfg.customInstructions;
2618
+ }
2619
+ catch (err) {
2620
+ console.warn('[custom-instructions] readAppConfig failed', err);
2621
+ }
2622
+ // Project-level custom instructions from the projects table.
2623
+ const projectInstructions = project?.customInstructions ?? '';
2624
+ let designSystemBody;
2625
+ let designSystemTitle;
2626
+ // Compiled (tokens.css + components.html) form of the active brand.
2627
+ // Default-on as of PR-D — every chat that picks a brand with
2628
+ // `tokens.css` + `components.html` siblings (today: `default` and
2629
+ // `kami`; every other brand falls through silently because the
2630
+ // files are absent) gets the structured token contract appended to
2631
+ // the system prompt automatically.
2632
+ //
2633
+ // `OD_DESIGN_TOKEN_CHANNEL=0` is the kill switch: it forces the
2634
+ // daemon back to the pre-PR-C DESIGN.md-only path for every brand,
2635
+ // including the structured ones. Any other value (unset, `1`,
2636
+ // `true`, etc.) keeps the new default. Drift on prose-only brands
2637
+ // is pinned by `scripts/check-design-system-flag-parity.ts`.
2638
+ let designSystemTokensCss;
2639
+ let designSystemFixtureHtml;
2640
+ if (effectiveDesignSystemId) {
2641
+ const systems = await listAllDesignSystems();
2642
+ const summary = systems.find((s) => s.id === effectiveDesignSystemId);
2643
+ designSystemTitle = summary?.title;
2644
+ designSystemBody =
2645
+ (await readDesignSystem(DESIGN_SYSTEMS_DIR, effectiveDesignSystemId)) ??
2646
+ (await readDesignSystem(USER_DESIGN_SYSTEMS_DIR, effectiveDesignSystemId)) ??
2647
+ undefined;
2648
+ // Single seam: env gate + built-in→user-installed fallback chain
2649
+ // live together inside `resolveDesignSystemAssets` so the whole
2650
+ // server-side asset-resolution path can be tested end-to-end
2651
+ // from real disk fixtures (see `tests/design-system-assets.test.ts`).
2652
+ const assets = await resolveDesignSystemAssets(effectiveDesignSystemId, DESIGN_SYSTEMS_DIR, USER_DESIGN_SYSTEMS_DIR);
2653
+ designSystemTokensCss = assets.tokensCss;
2654
+ designSystemFixtureHtml = assets.fixtureHtml;
2655
+ }
2656
+ const template = metadata?.kind === 'template' && typeof metadata.templateId === 'string'
2657
+ ? (getTemplate(db, metadata.templateId) ?? undefined)
2658
+ : undefined;
2659
+ let audioVoiceOptions = [];
2660
+ let audioVoiceOptionsError;
2661
+ if (metadata?.kind === 'audio' &&
2662
+ metadata?.audioKind === 'speech' &&
2663
+ metadata?.audioModel === 'elevenlabs-v3' &&
2664
+ !metadata?.voice) {
2665
+ try {
2666
+ audioVoiceOptions = await listElevenLabsVoiceOptions(PROJECT_ROOT, { limit: 100 });
2667
+ }
2668
+ catch (err) {
2669
+ audioVoiceOptionsError = err && err.message ? err.message : String(err);
2670
+ console.warn('[elevenlabs] voice option lookup failed:', audioVoiceOptionsError);
2671
+ }
2672
+ }
2673
+ // Thread the critique config plus the active design-system / skill data
2674
+ // into the composer when critique is enabled. Without this the spawned
2675
+ // child receives the legacy single-pass prompt and the parser waits for
2676
+ // <CRITIQUE_RUN> tags the model was never told to emit. The composer
2677
+ // itself ignores these fields when the top-line gate is false, so the
2678
+ // legacy path stays untouched.
2679
+ //
2680
+ // Top-line gate (post-Phase-15 wireup): the daemon now routes every
2681
+ // candidate run through the rollout resolver instead of reading the
2682
+ // env-var flag directly. The resolver carries the full priority
2683
+ // matrix: skill `od.critique.policy` veto > project override > env
2684
+ // override > rollout phase default. On a fresh install with M0
2685
+ // dark-launch defaults the resolver returns `false`, so prod traffic
2686
+ // is unchanged until an operator flips the env var or a project
2687
+ // opts in. The skill-policy input is sourced from
2688
+ // `od.critique.policy` in the active skill's SKILL.md frontmatter
2689
+ // (parsed in `skills.ts:normalizeCritiquePolicy`). The project
2690
+ // override input is sourced from the `critiqueTheaterEnabled`
2691
+ // field on the project's metadata blob, which is what the M1
2692
+ // Settings toggle writes through the existing settings endpoint.
2693
+ // Both inputs collapse to `null` when the skill / project has
2694
+ // not expressed an opinion, which is the resolver's "fall through
2695
+ // to env / phase default" signal.
2696
+ // Per-project override: the M1 Settings toggle writes
2697
+ // `critiqueTheaterEnabled` onto the project's metadata blob via
2698
+ // the existing settings round-trip. A boolean wins outright; any
2699
+ // other type (missing key, malformed value) collapses to `null`
2700
+ // so the resolver falls through to the env / phase tiers exactly
2701
+ // the way it did when the toggle had never been touched.
2702
+ const projectCritiqueOverride = narrowProjectCritiqueOverride(metadata);
2703
+ const critiqueEnabledForRun = isCritiqueEnabled({
2704
+ phase: parseRolloutPhase(process.env.OD_CRITIQUE_ROLLOUT_PHASE),
2705
+ skillPolicy: skillCritiquePolicy,
2706
+ projectOverride: projectCritiqueOverride,
2707
+ envOverride: parseEnvEnabled(process.env.OD_CRITIQUE_ENABLED),
2708
+ });
2709
+ const critiqueBrand = critiqueEnabledForRun
2710
+ && typeof designSystemTitle === 'string'
2711
+ && typeof designSystemBody === 'string'
2712
+ ? { name: designSystemTitle, design_md: designSystemBody }
2713
+ : undefined;
2714
+ const critiqueSkill = critiqueEnabledForRun && typeof effectiveSkillId === 'string'
2715
+ ? { id: effectiveSkillId }
2716
+ : undefined;
2717
+ // Single-source-of-truth eligibility check. The composer downstream
2718
+ // appends <CRITIQUE_RUN> instructions only when this check passes, and
2719
+ // the spawn path routes runs through runOrchestrator(...) only when the
2720
+ // SAME flag is true, so prompt and orchestrator stay in lockstep.
2721
+ //
2722
+ // Non-plain adapters (claude-stream-json, copilot-stream-json,
2723
+ // json-event-stream, acp-json-rpc, pi-rpc) emit their own wrapper
2724
+ // protocol; the v1 critique parser only understands plain stdout. The
2725
+ // spawn path falls through to legacy generation for those, so the
2726
+ // panel addendum has to be suppressed here too: otherwise the model
2727
+ // is instructed to emit Critique Theater tags that no orchestrator
2728
+ // consumes.
2729
+ const isMediaSurface = skillMode === 'image' ||
2730
+ skillMode === 'video' ||
2731
+ skillMode === 'audio' ||
2732
+ metadata?.kind === 'image' ||
2733
+ metadata?.kind === 'video' ||
2734
+ metadata?.kind === 'audio';
2735
+ const isPlainAdapter = (streamFormat ?? 'plain') === 'plain';
2736
+ const critiqueShouldRun = critiqueEnabledForRun
2737
+ && critiqueBrand !== undefined
2738
+ && critiqueSkill !== undefined
2739
+ && !isMediaSurface
2740
+ && isPlainAdapter;
2741
+ // Only thread the critique fields when the run is actually eligible;
2742
+ // otherwise the composer's own internal eligibility check (cfg.enabled
2743
+ // && brand && skill && !isMediaSurface) might still fire on
2744
+ // non-plain adapters and we'd emit the panel for a run the orchestrator
2745
+ // skips. Gating the threading itself keeps composer + orchestrator in
2746
+ // exact lockstep regardless of which side enforces eligibility.
2747
+ const prompt = composeSystemPrompt({
2748
+ agentId,
2749
+ includeCodexImagegenOverride: false,
2750
+ skillBody,
2751
+ skillName,
2752
+ skillMode,
2753
+ designSystemBody,
2754
+ designSystemTitle,
2755
+ designSystemTokensCss,
2756
+ designSystemFixtureHtml,
2757
+ craftBody,
2758
+ craftSections,
2759
+ memoryBody,
2760
+ metadata,
2761
+ template,
2762
+ audioVoiceOptions,
2763
+ audioVoiceOptionsError,
2764
+ // critiqueCfg.enabled is loaded from OD_CRITIQUE_ENABLED only, so a
2765
+ // run that the resolver enabled via phase / project / skill (env
2766
+ // unset) would have critiqueShouldRun = true while critiqueCfg.enabled
2767
+ // remains false. Without this override the composer's own gate
2768
+ // (cfg.enabled) drops the panel addendum, the orchestrator still
2769
+ // launches, and the parser waits for <CRITIQUE_RUN> tags the model
2770
+ // was never told to emit (codex P2 on PR #1338). Build a derived
2771
+ // config that pins enabled to the resolver decision so the composer
2772
+ // and the orchestrator agree on every eligibility input.
2773
+ critique: critiqueShouldRun ? { ...critiqueCfg, enabled: true } : undefined,
2774
+ critiqueBrand: critiqueShouldRun ? critiqueBrand : undefined,
2775
+ critiqueSkill: critiqueShouldRun ? critiqueSkill : undefined,
2776
+ streamFormat,
2777
+ connectedExternalMcp: Array.isArray(connectedExternalMcp)
2778
+ ? connectedExternalMcp
2779
+ : undefined,
2780
+ userInstructions,
2781
+ projectInstructions,
2782
+ });
2783
+ // The chat handler also needs to know where the active skill lives
2784
+ // on disk so it can stage a per-project copy of its side files
2785
+ // before spawning the agent. Returning that here avoids a second
2786
+ // `listSkills()` scan in `startChatRun`. critiqueShouldRun threads
2787
+ // the same panel-eligibility decision down to the spawn-path
2788
+ // orchestrator gate so prompt and orchestrator stay in lockstep.
2789
+ return { prompt, activeSkillDir, critiqueShouldRun };
2790
+ };
2791
+ const startChatRun = async (chatBody, run) => {
2792
+ /** @type {Partial<ChatRequest> & { imagePaths?: string[] }} */
2793
+ chatBody = chatBody || {};
2794
+ const { agentId, message, currentPrompt, systemPrompt, imagePaths = [], projectId, conversationId, assistantMessageId, clientRequestId, skillId, designSystemId, attachments = [], commentAttachments = [], model, reasoning, research, } = chatBody;
2795
+ if (typeof projectId === 'string' && projectId)
2796
+ run.projectId = projectId;
2797
+ if (typeof conversationId === 'string' && conversationId)
2798
+ run.conversationId = conversationId;
2799
+ if (typeof assistantMessageId === 'string' && assistantMessageId)
2800
+ run.assistantMessageId = assistantMessageId;
2801
+ if (typeof clientRequestId === 'string' && clientRequestId)
2802
+ run.clientRequestId = clientRequestId;
2803
+ if (typeof agentId === 'string' && agentId)
2804
+ run.agentId = agentId;
2805
+ // Stash the original user prompt + per-turn config so the
2806
+ // langfuse-bridge report path can include them without reaching back
2807
+ // into chatBody across the createChatRunService boundary. Each field
2808
+ // is optional and only set when the chat body actually carried it.
2809
+ const telemetryPrompt = telemetryPromptFromRunRequest(message, currentPrompt);
2810
+ if (typeof telemetryPrompt === 'string')
2811
+ run.userPrompt = telemetryPrompt;
2812
+ if (typeof model === 'string' && model)
2813
+ run.model = model;
2814
+ if (typeof reasoning === 'string' && reasoning)
2815
+ run.reasoning = reasoning;
2816
+ if (typeof skillId === 'string' && skillId)
2817
+ run.skillId = skillId;
2818
+ if (typeof designSystemId === 'string' && designSystemId)
2819
+ run.designSystemId = designSystemId;
2820
+ const def = getAgentDef(agentId);
2821
+ if (!def)
2822
+ return design.runs.fail(run, 'AGENT_UNAVAILABLE', `unknown agent: ${agentId}`);
2823
+ if (!def.bin)
2824
+ return design.runs.fail(run, 'AGENT_UNAVAILABLE', 'agent has no binary');
2825
+ const safeCommentAttachments = normalizeCommentAttachments(commentAttachments);
2826
+ if ((typeof message !== 'string' || !message.trim()) &&
2827
+ safeCommentAttachments.length === 0) {
2828
+ return design.runs.fail(run, 'BAD_REQUEST', 'message required');
2829
+ }
2830
+ if (run.cancelRequested || design.runs.isTerminal(run.status))
2831
+ return;
2832
+ const runId = run.id;
2833
+ // Auto-memory hook. Pulls explicit "remember:" / "我是 X" / "I prefer Y"
2834
+ // markers out of the just-arrived user message and writes them as MD
2835
+ // files under <dataDir>/memory/. We await so the very next
2836
+ // composeSystemPrompt() call (a few lines below) re-reads memory from
2837
+ // disk and a marker inside this turn's message is reflected in this
2838
+ // turn's prompt. Failures are swallowed — memory is best-effort and
2839
+ // must never block the agent run.
2840
+ if (typeof message === 'string' && message.trim().length > 0) {
2841
+ try {
2842
+ await extractFromMessage(RUNTIME_DATA_DIR, message);
2843
+ }
2844
+ catch (err) {
2845
+ console.warn('[memory] extractFromMessage failed', err);
2846
+ }
2847
+ }
2848
+ // Resolve the project working directory (creating the folder if it
2849
+ // doesn't exist yet). Without one we don't pass cwd to spawn — the
2850
+ // agent then runs in whatever inherited dir, which still lets API
2851
+ // mode work but loses file-tool addressability.
2852
+ // For git-linked projects (metadata.baseDir), use that folder directly
2853
+ // so the agent writes back to the user's original source tree.
2854
+ let cwd = null;
2855
+ let existingProjectFiles = [];
2856
+ if (typeof projectId === 'string' && projectId) {
2857
+ try {
2858
+ const chatProject = getProject(db, projectId);
2859
+ const chatMeta = chatProject?.metadata;
2860
+ if (chatMeta?.baseDir) {
2861
+ cwd = path.normalize(chatMeta.baseDir);
2862
+ existingProjectFiles = await listFiles(PROJECTS_DIR, projectId, { metadata: chatMeta });
2863
+ }
2864
+ else {
2865
+ cwd = await ensureProject(PROJECTS_DIR, projectId);
2866
+ existingProjectFiles = await listFiles(PROJECTS_DIR, projectId);
2867
+ }
2868
+ }
2869
+ catch {
2870
+ cwd = null;
2871
+ }
2872
+ }
2873
+ if (run.cancelRequested || design.runs.isTerminal(run.status))
2874
+ return;
2875
+ // Sanitise supplied image paths: must live under UPLOAD_DIR.
2876
+ const safeImages = imagePaths.filter((p) => {
2877
+ const resolved = path.resolve(p);
2878
+ return (resolved.startsWith(UPLOAD_DIR + path.sep) && fs.existsSync(resolved));
2879
+ });
2880
+ // Project-scoped attachments: project-relative paths inside cwd. Each
2881
+ // is run through the same path-traversal guard the file CRUD endpoints
2882
+ // use, then existence-checked. Whatever survives shows up as an
2883
+ // explicit list at the bottom of the user message so the agent knows
2884
+ // to Read it.
2885
+ const safeAttachments = cwd
2886
+ ? (Array.isArray(attachments) ? attachments : [])
2887
+ .filter((p) => typeof p === 'string' && p.length > 0)
2888
+ .filter((p) => {
2889
+ try {
2890
+ const abs = path.resolve(cwd, p);
2891
+ return ((abs === cwd || abs.startsWith(cwd + path.sep)) &&
2892
+ fs.existsSync(abs));
2893
+ }
2894
+ catch {
2895
+ return false;
2896
+ }
2897
+ })
2898
+ : [];
2899
+ // Local code agents don't accept a separate "system" channel the way the
2900
+ // Messages API does — we fold the skill + design-system prompt into the
2901
+ // user message. The <artifact> wrapping instruction comes from
2902
+ // systemPrompt. We also stitch in the cwd hint so the agent knows
2903
+ // where its file tools should write, and the attachment list so it
2904
+ // doesn't have to guess what the user just dropped in.
2905
+ // Also ship the current file listing so the agent can pick a unique
2906
+ // filename instead of clobbering a previous artifact.
2907
+ const filesListBlock = existingProjectFiles.length
2908
+ ? `\nFiles already in this folder (do NOT overwrite unless the user asks; pick a fresh, descriptive name for new artifacts):\n${existingProjectFiles
2909
+ .map((f) => `- ${f.name}`)
2910
+ .join('\n')}`
2911
+ : '\nThis folder is empty. Choose a clear, descriptive filename for whatever you create.';
2912
+ const projectRecord = typeof projectId === 'string' && projectId
2913
+ ? getProject(db, projectId)
2914
+ : null;
2915
+ const linkedDirs = (() => {
2916
+ if (!Array.isArray(projectRecord?.metadata?.linkedDirs))
2917
+ return [];
2918
+ const v = validateLinkedDirs(projectRecord.metadata.linkedDirs);
2919
+ return v.dirs ?? [];
2920
+ })();
2921
+ const cwdHint = cwd
2922
+ ? `\n\nYour working directory: ${cwd}\nWrite project files relative to it (e.g. \`index.html\`, \`assets/x.png\`). The user can browse those files in real time.${filesListBlock}`
2923
+ : '';
2924
+ const linkedDirsHint = linkedDirs.length > 0
2925
+ ? `\n\nLinked code folders (read-only reference code the user wants you to see):\n${linkedDirs.map((d) => `- \`${d}\``).join('\n')}`
2926
+ : '';
2927
+ const attachmentHint = safeAttachments.length
2928
+ ? `\n\nAttached project files: ${safeAttachments.map((p) => `\`${p}\``).join(', ')}`
2929
+ : '';
2930
+ const toolTokenGrant = cwd && typeof projectId === 'string' && projectId
2931
+ ? toolTokenRegistry.mint({
2932
+ runId,
2933
+ projectId,
2934
+ allowedEndpoints: CHAT_TOOL_ENDPOINTS,
2935
+ allowedOperations: CHAT_TOOL_OPERATIONS,
2936
+ })
2937
+ : null;
2938
+ let toolTokenRevoked = false;
2939
+ const revokeToolToken = (reason) => {
2940
+ if (toolTokenRevoked || !toolTokenGrant)
2941
+ return;
2942
+ toolTokenRevoked = true;
2943
+ toolTokenRegistry.revokeToken(toolTokenGrant.token, reason);
2944
+ };
2945
+ const runtimeToolPrompt = createAgentRuntimeToolPrompt(daemonUrl, toolTokenGrant);
2946
+ const commentHint = renderCommentAttachmentHint(safeCommentAttachments);
2947
+ // Resolve external MCP config + stored OAuth tokens up-front so the
2948
+ // system prompt can warn the model away from Claude Code's synthetic
2949
+ // `*_authenticate` / `*_complete_authentication` tools for any
2950
+ // server the daemon already holds a valid Bearer for. We re-use both
2951
+ // values further down at .mcp.json write time — see the spawn block
2952
+ // below — instead of re-reading.
2953
+ let externalMcpConfig = { servers: [] };
2954
+ try {
2955
+ externalMcpConfig = await readMcpConfig(RUNTIME_DATA_DIR);
2956
+ }
2957
+ catch (err) {
2958
+ console.warn('[mcp-config] read failed:', err && err.message ? err.message : err);
2959
+ }
2960
+ const enabledExternalMcp = externalMcpConfig.servers.filter((s) => s.enabled);
2961
+ const oauthTokensForSpawn = {};
2962
+ try {
2963
+ const stored = await readAllTokens(RUNTIME_DATA_DIR);
2964
+ for (const [serverId, tok] of Object.entries(stored)) {
2965
+ if (!enabledExternalMcp.find((s) => s.id === serverId))
2966
+ continue;
2967
+ // Default to the persisted access token; null it out if expired so
2968
+ // we never inject a stale `Authorization: Bearer …` header. The
2969
+ // model treats a server with a Bearer pinned as connected and
2970
+ // discourages re-auth, which is the worst possible UX when the
2971
+ // token is going to 401 every call.
2972
+ let access = isTokenExpired(tok) ? null : tok.accessToken;
2973
+ if (isTokenExpired(tok) && tok.refreshToken) {
2974
+ try {
2975
+ const refreshed = await refreshAndPersistToken(RUNTIME_DATA_DIR, serverId, tok);
2976
+ if (refreshed)
2977
+ access = refreshed.accessToken;
2978
+ }
2979
+ catch (err) {
2980
+ console.warn('[mcp-oauth] refresh failed for', serverId, err && err.message ? err.message : err);
2981
+ }
2982
+ }
2983
+ if (access) {
2984
+ oauthTokensForSpawn[serverId] = access;
2985
+ }
2986
+ else {
2987
+ console.warn('[mcp-oauth] skipping expired token for', serverId, '— reconnect required');
2988
+ }
2989
+ }
2990
+ }
2991
+ catch (err) {
2992
+ console.warn('[mcp-tokens] read failed:', err && err.message ? err.message : err);
2993
+ }
2994
+ const connectedExternalMcp = enabledExternalMcp
2995
+ .filter((s) => typeof oauthTokensForSpawn[s.id] === 'string')
2996
+ .map((s) => ({ id: s.id, label: s.label }));
2997
+ const { prompt: daemonSystemPrompt, activeSkillDir, critiqueShouldRun } = await composeDaemonSystemPrompt({
2998
+ agentId,
2999
+ projectId,
3000
+ skillId,
3001
+ designSystemId,
3002
+ streamFormat: def?.streamFormat ?? 'plain',
3003
+ connectedExternalMcp,
3004
+ });
3005
+ // Make skill side files reachable through three layers, in order of
3006
+ // preference. The skill preamble emitted by `withSkillRootPreamble()`
3007
+ // advertises both the cwd-relative path (1) and the absolute path
3008
+ // (2/3) so the agent can pick whichever works.
3009
+ //
3010
+ // 1. CWD-relative copy. Stage the *active* skill into
3011
+ // `<cwd>/.od-skills/<folder>/` so any agent CLI — not just the
3012
+ // ones that honour `--add-dir` — can reach those files via a
3013
+ // path inside its working directory. We copy (not symlink) so
3014
+ // the staged directory is a true write barrier — agents cannot
3015
+ // mutate the shipped repo resource through their cwd.
3016
+ // 2. `--add-dir` allowlist. For non-Codex agents, pass `SKILLS_DIR`
3017
+ // and `DESIGN_SYSTEMS_DIR` so the absolute fallback path in the
3018
+ // preamble is reachable when staging fails (e.g. the project has
3019
+ // no on-disk cwd, or fs.cp errored). Codex treats `--add-dir`
3020
+ // entries as writable, so Codex receives only the narrow
3021
+ // `${CODEX_HOME:-$HOME/.codex}/generated_images` output folder
3022
+ // for allowlisted gpt-image image projects.
3023
+ // 3. PROJECT_ROOT cwd. When `cwd` is null, the agent runs with
3024
+ // `cwd: PROJECT_ROOT` — there the absolute path is already an
3025
+ // in-cwd path, so neither (1) nor (2) is required for it to
3026
+ // resolve.
3027
+ //
3028
+ // Design systems are *not* staged here. Their bodies are read by the
3029
+ // daemon and folded into the system prompt directly (see
3030
+ // `readDesignSystem`), so an agent never has to open them via the
3031
+ // filesystem.
3032
+ if (cwd && activeSkillDir) {
3033
+ const result = await stageActiveSkill(cwd, path.basename(activeSkillDir), activeSkillDir, (msg) => console.warn(msg));
3034
+ if (!result.staged) {
3035
+ console.warn(`[od] skill-stage skipped: ${result.reason ?? 'unknown reason'}; falling back to absolute paths`);
3036
+ }
3037
+ }
3038
+ // Resolve the agent's effective working directory once and use it
3039
+ // everywhere the agent could read it (buildArgs runtimeContext, spawn
3040
+ // cwd, ACP session new). Falling back to PROJECT_ROOT — rather than
3041
+ // letting `spawn` inherit the daemon process cwd — is what makes the
3042
+ // absolute-path fallback in the skill preamble actually in-cwd for
3043
+ // no-project runs (packaged daemons / service launches do not start
3044
+ // their working directory from the workspace root).
3045
+ const effectiveCwd = cwd ?? PROJECT_ROOT;
3046
+ let codexGeneratedImagesDir = resolveCodexGeneratedImagesDir(agentId, projectRecord?.metadata);
3047
+ if (codexGeneratedImagesDir) {
3048
+ codexGeneratedImagesDir = validateCodexGeneratedImagesDir(codexGeneratedImagesDir, {
3049
+ protectedDirs: [SKILLS_DIR, DESIGN_SYSTEMS_DIR, ...linkedDirs],
3050
+ });
3051
+ }
3052
+ const extraAllowedDirs = resolveChatExtraAllowedDirs({
3053
+ agentId,
3054
+ skillsDir: SKILLS_DIR,
3055
+ designSystemsDir: DESIGN_SYSTEMS_DIR,
3056
+ linkedDirs,
3057
+ codexGeneratedImagesDir,
3058
+ });
3059
+ const codexImagegenOverride = resolveGrantedCodexImagegenOverride({
3060
+ agentId,
3061
+ metadata: projectRecord?.metadata,
3062
+ codexGeneratedImagesDir,
3063
+ extraAllowedDirs,
3064
+ });
3065
+ const researchCommandContract = resolveResearchCommandContract(research, message);
3066
+ const clientInstructionPrompt = [researchCommandContract, systemPrompt]
3067
+ .map((part) => (typeof part === 'string' ? part.trim() : ''))
3068
+ .filter(Boolean)
3069
+ .join('\n\n---\n\n');
3070
+ const instructionPrompt = composeLiveInstructionPrompt({
3071
+ daemonSystemPrompt,
3072
+ runtimeToolPrompt,
3073
+ clientSystemPrompt: clientInstructionPrompt,
3074
+ finalPromptOverride: codexImagegenOverride,
3075
+ });
3076
+ const composed = [
3077
+ instructionPrompt
3078
+ ? `# Instructions (read first)\n\n${instructionPrompt}${cwdHint}${linkedDirsHint}\n\n---\n`
3079
+ : cwdHint
3080
+ ? `# Instructions${cwdHint}${linkedDirsHint}\n\n---\n`
3081
+ : linkedDirsHint
3082
+ ? `# Instructions${linkedDirsHint}\n\n---\n`
3083
+ : '',
3084
+ `# User request\n\n${message || '(No extra typed instruction.)'}${attachmentHint}${commentHint}`,
3085
+ safeImages.length
3086
+ ? `\n\n${safeImages.map((p) => `@${p}`).join(' ')}`
3087
+ : '',
3088
+ ].join('');
3089
+ // Per-agent model + reasoning the user picked in the model menu.
3090
+ // Trust the value when it matches the most recent /api/agents listing
3091
+ // (live or fallback). Otherwise allow it through if it passes a
3092
+ // permissive sanitizer — that's the path for user-typed custom model
3093
+ // ids the CLI's listing didn't surface yet.
3094
+ const safeModel = typeof model === 'string'
3095
+ ? isKnownModel(def, model)
3096
+ ? model
3097
+ : sanitizeCustomModel(model)
3098
+ : null;
3099
+ const safeReasoning = typeof reasoning === 'string' && Array.isArray(def.reasoningOptions)
3100
+ ? (def.reasoningOptions.find((r) => r.id === reasoning)?.id ?? null)
3101
+ : null;
3102
+ const agentOptions = { model: safeModel, reasoning: safeReasoning };
3103
+ const mcpServers = buildLiveArtifactsMcpServersForAgent(def, {
3104
+ enabled: Boolean(toolTokenGrant?.token),
3105
+ command: process.execPath,
3106
+ argsPrefix: [OD_BIN],
3107
+ });
3108
+ // External MCP servers configured by the user in Settings → External MCP.
3109
+ // Open Design relays them to the agent so the model can call those tools.
3110
+ // Two delivery shapes today:
3111
+ // - Claude Code: write a `.mcp.json` into the project cwd. Claude Code
3112
+ // auto-loads that file at spawn (same format the CLI accepts via
3113
+ // `claude mcp add` + Claude Desktop's config). Fire-and-forget; we
3114
+ // deliberately do NOT block spawn on a write failure since the agent
3115
+ // can still run without external tools — log a warning and continue.
3116
+ // - ACP agents (Hermes/Kimi): merge stdio entries into the existing
3117
+ // `mcpServers` array; SSE/HTTP entries are skipped because ACP's
3118
+ // stdio-only descriptor can't represent them yet.
3119
+ // Other agents (Codex, Gemini, OpenCode, Cursor, Qwen, Qoder, Copilot,
3120
+ // Pi, DeepSeek) inherit the user's per-CLI MCP config from their own
3121
+ // home dir for now — a future change can grow this list.
3122
+ //
3123
+ // The MCP config + OAuth tokens were resolved earlier (above
3124
+ // composeDaemonSystemPrompt) so the system prompt could mention any
3125
+ // already-authenticated servers; we reuse `enabledExternalMcp` and
3126
+ // `oauthTokensForSpawn` here for the Claude `.mcp.json` write +
3127
+ // ACP merge so we don't pay for a second filesystem read.
3128
+ //
3129
+ // Claude Code: write `.mcp.json` to the daemon-managed project cwd before
3130
+ // spawn so Claude Code auto-loads the user's external MCP servers. Strict
3131
+ // gating is essential here:
3132
+ // - cwd must be set (no project → no `.mcp.json` write).
3133
+ // - cwd must live UNDER PROJECTS_DIR. We never write to a git-linked
3134
+ // baseDir (= the user's own repo), since that would silently overwrite
3135
+ // a hand-crafted .mcp.json the user already keeps in their source tree.
3136
+ // We also unlink a stale `.mcp.json` we previously wrote when the user has
3137
+ // since disabled all servers, so removing a server actually takes effect
3138
+ // on the next run.
3139
+ if (def.id === 'claude' && isManagedProjectCwd(cwd, PROJECTS_DIR)) {
3140
+ {
3141
+ const target = path.join(cwd, '.mcp.json');
3142
+ if (enabledExternalMcp.length > 0) {
3143
+ try {
3144
+ const claudeMcp = buildClaudeMcpJson(enabledExternalMcp, oauthTokensForSpawn);
3145
+ if (claudeMcp) {
3146
+ await fs.promises.mkdir(path.dirname(target), { recursive: true });
3147
+ await fs.promises.writeFile(target, JSON.stringify(claudeMcp, null, 2), 'utf8');
3148
+ }
3149
+ }
3150
+ catch (err) {
3151
+ console.warn('[mcp-config] failed to write project .mcp.json:', err && err.message ? err.message : err);
3152
+ }
3153
+ }
3154
+ else {
3155
+ try {
3156
+ await fs.promises.unlink(target);
3157
+ }
3158
+ catch (err) {
3159
+ if ((err && err.code) !== 'ENOENT') {
3160
+ console.warn('[mcp-config] failed to remove stale .mcp.json:', err && err.message ? err.message : err);
3161
+ }
3162
+ }
3163
+ }
3164
+ }
3165
+ }
3166
+ if (enabledExternalMcp.length > 0 && def.streamFormat === 'acp-json-rpc') {
3167
+ const acpExternal = buildAcpMcpServers(enabledExternalMcp);
3168
+ mcpServers.push(...acpExternal);
3169
+ }
3170
+ // Pre-flight the composed prompt against any argv-byte budget the
3171
+ // adapter declared (only DeepSeek TUI today — its CLI doesn't accept
3172
+ // a `-` stdin sentinel, so the prompt has to ride argv). Doing this
3173
+ // before bin resolution means the test harness pins the guard
3174
+ // independently of whether the adapter binary happens to be on PATH
3175
+ // in the CI environment, and the user gets the actionable
3176
+ // adapter-named error even if /api/agents hadn't refreshed yet.
3177
+ const promptBudgetError = checkPromptArgvBudget(def, composed);
3178
+ if (promptBudgetError) {
3179
+ design.runs.emit(run, 'error', createSseErrorPayload(promptBudgetError.code, promptBudgetError.message, { retryable: false }));
3180
+ return design.runs.finish(run, 'failed', 1, null);
3181
+ }
3182
+ let configuredAgentEnv = {};
3183
+ try {
3184
+ const appConfig = await readAppConfig(RUNTIME_DATA_DIR);
3185
+ configuredAgentEnv = agentCliEnvForAgent(appConfig.agentCliEnv, def.id);
3186
+ }
3187
+ catch {
3188
+ configuredAgentEnv = {};
3189
+ }
3190
+ const agentLaunch = resolveAgentLaunch(def, configuredAgentEnv);
3191
+ const resolvedBin = agentLaunch.selectedPath;
3192
+ const args = def.buildArgs(composed, safeImages, extraAllowedDirs, agentOptions, { cwd: effectiveCwd });
3193
+ // Second-pass budget check that knows about the Windows `.cmd` shim
3194
+ // wrap. The pre-buildArgs `checkPromptArgvBudget` only looks at the
3195
+ // raw composed prompt; on Windows an npm-installed adapter resolves
3196
+ // to e.g. `deepseek.cmd`, the spawn path goes through `cmd.exe /d /s
3197
+ // /c "<inner>"`, and `quoteForWindowsCmdShim` doubles every embedded
3198
+ // `"` plus wraps any whitespace/special-char arg in outer quotes —
3199
+ // so a quote-heavy prompt that fit under `maxPromptArgBytes` can
3200
+ // still expand past CreateProcess's 32_767-char cap. Fail fast with
3201
+ // the same `AGENT_PROMPT_TOO_LARGE` shape so the SSE error path
3202
+ // doesn't have to special-case it.
3203
+ const cmdShimBudgetError = checkWindowsCmdShimCommandLineBudget(def, agentLaunch.launchPath ?? resolvedBin, args);
3204
+ if (cmdShimBudgetError) {
3205
+ design.runs.emit(run, 'error', createSseErrorPayload(cmdShimBudgetError.code, cmdShimBudgetError.message, { retryable: false }));
3206
+ return design.runs.finish(run, 'failed', 1, null);
3207
+ }
3208
+ // Companion guard for non-shim Windows installs (e.g. a cargo-built
3209
+ // `deepseek.exe` rather than the npm `.cmd` shim). Direct `.exe`
3210
+ // spawns skip the cmd.exe wrap above, but Node/libuv still composes
3211
+ // a CreateProcess `lpCommandLine` by walking each argv element
3212
+ // through `quote_cmd_arg`, which escapes every embedded `"` as `\"`
3213
+ // and doubles backslashes adjacent to quotes. A quote-heavy prompt
3214
+ // under `maxPromptArgBytes` can expand past the 32_767-char kernel
3215
+ // cap there too, so the cmd-shim early-return alone would let those
3216
+ // users hit a generic `spawn ENAMETOOLONG`.
3217
+ const directExeBudgetError = checkWindowsDirectExeCommandLineBudget(def, agentLaunch.launchPath ?? resolvedBin, args);
3218
+ if (directExeBudgetError) {
3219
+ design.runs.emit(run, 'error', createSseErrorPayload(directExeBudgetError.code, directExeBudgetError.message, { retryable: false }));
3220
+ return design.runs.finish(run, 'failed', 1, null);
3221
+ }
3222
+ const send = (event, data) => design.runs.emit(run, event, data);
3223
+ const inactivityTimeoutMs = resolveChatRunInactivityTimeoutMs();
3224
+ const inactivityKillGraceMs = 3_000;
3225
+ let inactivityTimer = null;
3226
+ let childStdoutSeen = false;
3227
+ let lastAgentEventPhase = 'spawn pending';
3228
+ let lastToolResultChars = 0;
3229
+ const summarizeAgentEventForInactivity = (payload) => {
3230
+ const type = payload?.type ? String(payload.type) : 'unknown';
3231
+ if (type === 'tool_result') {
3232
+ const content = typeof payload.content === 'string' ? payload.content : '';
3233
+ lastToolResultChars = Math.max(lastToolResultChars, content.length);
3234
+ return `tool_result:${content.length} chars`;
3235
+ }
3236
+ if (type === 'tool_use') {
3237
+ const name = payload?.name ? String(payload.name) : 'unknown';
3238
+ return `tool_use:${name}`;
3239
+ }
3240
+ if (type === 'text_delta' || type === 'thinking_delta') {
3241
+ const text = typeof payload.text === 'string' ? payload.text : '';
3242
+ return `${type}:${text.length} chars`;
3243
+ }
3244
+ return type;
3245
+ };
3246
+ const clearInactivityWatchdog = () => {
3247
+ if (inactivityTimer) {
3248
+ clearTimeout(inactivityTimer);
3249
+ inactivityTimer = null;
3250
+ }
3251
+ };
3252
+ const scheduleForcedChildShutdown = () => {
3253
+ if (!child)
3254
+ return;
3255
+ setTimeout(() => {
3256
+ if (child && !child.killed)
3257
+ child.kill('SIGTERM');
3258
+ }, inactivityKillGraceMs).unref?.();
3259
+ setTimeout(() => {
3260
+ if (child && !child.killed)
3261
+ child.kill('SIGKILL');
3262
+ }, inactivityKillGraceMs * 2).unref?.();
3263
+ };
3264
+ const failForInactivity = () => {
3265
+ if (run.cancelRequested || design.runs.isTerminal(run.status))
3266
+ return;
3267
+ const message = `Agent stalled without emitting any new output for ${Math.round(inactivityTimeoutMs / 1000)}s. ` +
3268
+ 'The model or CLI likely hung while generating. ' +
3269
+ `Phase details: spawned agent binary ${resolvedBin}; stdout arrived: ${childStdoutSeen ? 'yes' : 'no'}; ` +
3270
+ `last agent event: ${lastAgentEventPhase}; largest tool result observed: ${lastToolResultChars} chars. ` +
3271
+ 'Retry the turn, pick a different model, or start a new conversation if the prior context is very large.';
3272
+ clearInactivityWatchdog();
3273
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', message, { retryable: true }));
3274
+ design.runs.finish(run, 'failed', 1, null);
3275
+ if (acpSession?.abort) {
3276
+ acpSession.abort();
3277
+ }
3278
+ if (child && !child.killed)
3279
+ child.kill('SIGTERM');
3280
+ scheduleForcedChildShutdown();
3281
+ };
3282
+ const noteAgentActivity = () => {
3283
+ if (inactivityTimeoutMs <= 0)
3284
+ return;
3285
+ clearInactivityWatchdog();
3286
+ inactivityTimer = setTimeout(failForInactivity, inactivityTimeoutMs);
3287
+ inactivityTimer.unref?.();
3288
+ };
3289
+ const unregisterChatAgentEventSink = () => {
3290
+ activeChatAgentEventSinks.delete(toolTokenGrant?.runId ?? runId);
3291
+ };
3292
+ if (toolTokenGrant?.runId) {
3293
+ activeChatAgentEventSinks.set(toolTokenGrant.runId, (payload) => {
3294
+ lastAgentEventPhase = summarizeAgentEventForInactivity(payload);
3295
+ noteAgentActivity();
3296
+ send('agent', payload);
3297
+ });
3298
+ }
3299
+ // If detection can't find the binary, surface a friendly SSE error
3300
+ // pointing at /api/agents instead of silently falling back to
3301
+ // spawn(def.bin) — that fallback re-introduces the exact ENOENT symptom
3302
+ // from issue #10.
3303
+ if (!resolvedBin || !agentLaunch.launchPath) {
3304
+ revokeToolToken('child_exit');
3305
+ unregisterChatAgentEventSink();
3306
+ send('error', createSseErrorPayload('AGENT_UNAVAILABLE', `Agent "${def.name}" (\`${def.bin}\`) is not installed or not on PATH. ` +
3307
+ 'Install it and refresh the agent list (GET /api/agents) before retrying.', { retryable: true }));
3308
+ return design.runs.finish(run, 'failed', 1, null);
3309
+ }
3310
+ const odMediaEnv = {
3311
+ OD_BIN,
3312
+ OD_NODE_BIN,
3313
+ OD_DAEMON_URL: daemonUrl,
3314
+ ...(typeof projectId === 'string' && projectId && cwd
3315
+ ? {
3316
+ OD_PROJECT_ID: projectId,
3317
+ OD_PROJECT_DIR: cwd,
3318
+ }
3319
+ : {}),
3320
+ };
3321
+ if (run.cancelRequested || design.runs.isTerminal(run.status)) {
3322
+ revokeToolToken('child_exit');
3323
+ unregisterChatAgentEventSink();
3324
+ return;
3325
+ }
3326
+ run.status = 'running';
3327
+ run.updatedAt = Date.now();
3328
+ send('start', {
3329
+ runId,
3330
+ agentId,
3331
+ bin: resolvedBin,
3332
+ streamFormat: def.streamFormat ?? 'plain',
3333
+ projectId: typeof projectId === 'string' ? projectId : null,
3334
+ cwd,
3335
+ model: safeModel,
3336
+ reasoning: safeReasoning,
3337
+ toolTokenExpiresAt: toolTokenGrant?.expiresAt ?? null,
3338
+ });
3339
+ noteAgentActivity();
3340
+ let child;
3341
+ let acpSession = null;
3342
+ let writePromptToChildStdin = false;
3343
+ let spawnedAgentEnv = null;
3344
+ let agentStdoutTail = '';
3345
+ let agentStderrTail = '';
3346
+ try {
3347
+ // Prompt delivery via stdin is now the universal default. This bypasses
3348
+ // both the cmd.exe 8KB limit and the CreateProcess 32KB limit.
3349
+ const stdinMode = def.promptViaStdin || def.streamFormat === 'acp-json-rpc'
3350
+ ? 'pipe'
3351
+ : 'ignore';
3352
+ const env = applyAgentLaunchEnv({
3353
+ ...spawnEnvForAgent(def.id, {
3354
+ ...createAgentRuntimeEnv(process.env, daemonUrl, toolTokenGrant),
3355
+ ...(def.env || {}),
3356
+ }, configuredAgentEnv),
3357
+ ...odMediaEnv,
3358
+ }, agentLaunch);
3359
+ spawnedAgentEnv = env;
3360
+ const invocation = createCommandInvocation({
3361
+ command: agentLaunch.launchPath,
3362
+ args,
3363
+ env,
3364
+ });
3365
+ child = spawn(invocation.command, invocation.args, {
3366
+ env,
3367
+ stdio: [stdinMode, 'pipe', 'pipe'],
3368
+ cwd: effectiveCwd,
3369
+ shell: false,
3370
+ // Required when invocation wraps a Windows .cmd/.bat shim through
3371
+ // cmd.exe; without this, Node re-escapes the inner command line and
3372
+ // breaks paths containing spaces (issue #315).
3373
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments,
3374
+ });
3375
+ run.child = child;
3376
+ if (def.promptViaStdin && child.stdin && def.streamFormat !== 'pi-rpc') {
3377
+ // EPIPE from a fast-exiting CLI (bad auth, missing model, exit on
3378
+ // launch) would otherwise surface as an unhandled stream error and
3379
+ // crash the daemon. Swallow it — the regular exit/close handlers
3380
+ // below already route the underlying failure to SSE via stderr.
3381
+ child.stdin.on('error', (err) => {
3382
+ if (err.code !== 'EPIPE') {
3383
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', `stdin: ${err.message}`));
3384
+ }
3385
+ });
3386
+ writePromptToChildStdin = true;
3387
+ }
3388
+ }
3389
+ catch (err) {
3390
+ revokeToolToken('child_exit');
3391
+ unregisterChatAgentEventSink();
3392
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', `spawn failed: ${err.message}`));
3393
+ design.runs.finish(run, 'failed', 1, null);
3394
+ return;
3395
+ }
3396
+ child.stdout.setEncoding('utf8');
3397
+ child.stderr.setEncoding('utf8');
3398
+ // Reset the inactivity watchdog on every raw stdout byte so that
3399
+ // structured adapters that buffer partial lines (Codex item.completed,
3400
+ // pi-rpc session/prompt, ACP agent messages) and models that spend a
3401
+ // long time in non-streamed reasoning still keep the run alive.
3402
+ child.stdout.on('data', (chunk) => {
3403
+ childStdoutSeen = true;
3404
+ noteAgentActivity();
3405
+ agentStdoutTail = `${agentStdoutTail}${chunk}`.slice(-2000);
3406
+ });
3407
+ // ---- Memory: assistant-reply buffer for LLM extraction --------------
3408
+ // Capture up to 32 KiB of raw stdout. The LLM extractor (fired in the
3409
+ // close handler) trims further; we only need enough to ground the
3410
+ // model. Multiple `on('data')` listeners coexist — the wrapper-stream
3411
+ // handlers below also subscribe and that's fine.
3412
+ const MEMORY_BUFFER_CAP = 32 * 1024;
3413
+ let memoryAssistantBuffer = '';
3414
+ child.stdout.on('data', (chunk) => {
3415
+ if (memoryAssistantBuffer.length >= MEMORY_BUFFER_CAP)
3416
+ return;
3417
+ memoryAssistantBuffer += String(chunk);
3418
+ if (memoryAssistantBuffer.length > MEMORY_BUFFER_CAP) {
3419
+ memoryAssistantBuffer = memoryAssistantBuffer.slice(0, MEMORY_BUFFER_CAP);
3420
+ }
3421
+ });
3422
+ child.on('close', () => {
3423
+ const captured = memoryAssistantBuffer;
3424
+ const userMsg = typeof message === 'string' ? message : '';
3425
+ // Forward the chat agent id so memory-llm.pickProvider can
3426
+ // constrain its auto-pick to the chat protocol's family — keeps
3427
+ // a Claude Code (anthropic) chat from triggering OpenAI/gpt-4o-
3428
+ // mini extraction in the background just because the user has
3429
+ // an OpenAI key parked in media-config.
3430
+ void import('./memory-llm.js')
3431
+ .then(({ extractWithLLM }) => extractWithLLM(RUNTIME_DATA_DIR, {
3432
+ userMessage: userMsg,
3433
+ assistantMessage: captured,
3434
+ }, {
3435
+ projectRoot: PROJECT_ROOT,
3436
+ chatAgentId: typeof agentId === 'string' ? agentId : null,
3437
+ }))
3438
+ .catch((err) => console.warn('[memory-llm] background failed', err));
3439
+ });
3440
+ // Critique Theater branch (M0 dark launch, default disabled).
3441
+ // Only plain-stream adapters are routed through runOrchestrator in v1.
3442
+ // Adapters that emit structured wrappers (claude-stream-json,
3443
+ // qoder-stream-json, copilot-stream-json, json-event-stream,
3444
+ // acp-json-rpc, pi-rpc) fall
3445
+ // through to the legacy single-pass code path below with a one-time
3446
+ // stderr warning so the parser never sees wrapper bytes. Per-format
3447
+ // decoding into the orchestrator is a v2 concern.
3448
+ //
3449
+ // Use critiqueShouldRun (computed in the prompt builder) instead of
3450
+ // just the env var or the rollout resolver so the orchestrator gate
3451
+ // is in lockstep with the panel addendum. Media surfaces and runs
3452
+ // missing brand/skill context never get the panel prompt, so they
3453
+ // must also skip the orchestrator and fall through to legacy
3454
+ // generation; otherwise the parser waits for <CRITIQUE_RUN> tags
3455
+ // the model was never told to emit.
3456
+ if (critiqueShouldRun) {
3457
+ const adapterStreamFormat = def.streamFormat ?? 'plain';
3458
+ if (adapterStreamFormat !== 'plain') {
3459
+ if (!critiqueWarnedAdapters.has(adapterStreamFormat)) {
3460
+ critiqueWarnedAdapters.add(adapterStreamFormat);
3461
+ console.warn(`[critique] adapter format=${adapterStreamFormat} is not plain-stream; skipping orchestrator and falling through to legacy generation`);
3462
+ }
3463
+ }
3464
+ else {
3465
+ const critiqueRunId = run.id;
3466
+ // Per-run artifact directory keeps concurrent or sequential runs in the
3467
+ // same project from overwriting each other's transcript or final HTML.
3468
+ // Spec: artifacts/<projectId>/<runId>/transcript.ndjson(.gz).
3469
+ const critiqueProjectKey = typeof projectId === 'string' && projectId ? projectId : critiqueRunId;
3470
+ const critiqueArtifactDir = path.join(ARTIFACTS_DIR, critiqueProjectKey, critiqueRunId);
3471
+ const stdoutIterable = (async function* () {
3472
+ for await (const chunk of child.stdout)
3473
+ yield String(chunk);
3474
+ })();
3475
+ // Forward each CritiqueSseEvent on its own contract-defined channel
3476
+ // (critique.run_started, critique.ship, critique.failed, ...) rather
3477
+ // than wrapping the frame inside the legacy 'agent' channel. Clients
3478
+ // that subscribe to the new event names see them directly with the
3479
+ // contract payload as event.data.
3480
+ //
3481
+ // Critique events go to TWO sinks (codex P1 on PR #1338):
3482
+ //
3483
+ // 1. `design.runs.emit(...)` via `send(...)`, which fans out on
3484
+ // `/api/runs/:runId/events`. Existing transport, unchanged.
3485
+ // 2. The per-project event-sinks map, which fans out on
3486
+ // `/api/projects/:projectId/events`. This is the transport the
3487
+ // web `CritiqueTheaterMount` actually subscribes to (the mount
3488
+ // is project-scoped, not run-scoped, because it lives at the
3489
+ // project workspace level and follows the user across runs).
3490
+ // Without this second sink the mount sees no frames in
3491
+ // production and only the e2e tests' stubbed routes deliver
3492
+ // anything to the reducer.
3493
+ //
3494
+ // The project-events route emits via `sse.send(payload.type,
3495
+ // payload)`, so we pack the SSE channel name onto `payload.type`
3496
+ // and let the sink push the right channel name. The web's
3497
+ // `sseToPanelEvent` overwrites `type` from the channel name on the
3498
+ // way back into a PanelEvent, so this round-trip stays correct.
3499
+ const critiqueProjectIdForBus = typeof projectId === 'string' && projectId ? projectId : null;
3500
+ const critiqueBus = {
3501
+ emit: (e) => {
3502
+ // Two transports for every critique event: the run-scoped
3503
+ // SSE send back to the originating chat run, plus the
3504
+ // project-scoped fan-out so the Theater mount (subscribed
3505
+ // to /api/projects/:id/events) sees it too. Route the
3506
+ // project fan-out through emitProjectEvent so empty-sink
3507
+ // cleanup and any future broadcast policy (rate limiting,
3508
+ // schema validation, telemetry) apply uniformly across
3509
+ // every project emitter (PerishCode P3 on PR #1338).
3510
+ send(e.event, e.data);
3511
+ if (critiqueProjectIdForBus) {
3512
+ emitProjectEvent(critiqueProjectIdForBus, { ...e.data, type: e.event });
3513
+ }
3514
+ },
3515
+ };
3516
+ // Register this run with the in-process registry so the interrupt
3517
+ // endpoint can cascade an AbortController to the orchestrator. The
3518
+ // register call must run BEFORE runOrchestrator is invoked, so a
3519
+ // request that arrives between spawn and orchestrator-start cannot
3520
+ // miss a runId that already has a live child process.
3521
+ const critiqueAbort = new AbortController();
3522
+ critiqueRunRegistry.register({
3523
+ runId: critiqueRunId,
3524
+ projectId: critiqueProjectKey,
3525
+ abort: critiqueAbort,
3526
+ startedAt: Date.now(),
3527
+ });
3528
+ // Stderr forwarding and child.on('error') must be wired BEFORE the
3529
+ // orchestrator awaits stdout. Otherwise a CLI that floods stderr can
3530
+ // fill the OS pipe and deadlock the run until the total timeout, and
3531
+ // an early child error fired before the orchestrator returns has no
3532
+ // listener. Both registrations are idempotent and the run lifecycle
3533
+ // is owned solely by the orchestrator's awaited result below.
3534
+ child.stderr.on('data', (chunk) => {
3535
+ noteAgentActivity();
3536
+ send('stderr', { chunk });
3537
+ });
3538
+ child.on('error', (err) => {
3539
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', err.message));
3540
+ });
3541
+ // Wrap the child's close event so the orchestrator can race child
3542
+ // exit against parser completion, abort, and timeouts in one awaited
3543
+ // flow. Without this the orchestrator can't tell a non-zero exit
3544
+ // apart from a clean ship and may misclassify failures.
3545
+ const childExitPromise = new Promise((resolve) => {
3546
+ child.once('close', (code, signal) => resolve({ code, signal }));
3547
+ });
3548
+ try {
3549
+ const orchestratorResult = await runOrchestrator({
3550
+ runId: critiqueRunId,
3551
+ projectId: typeof projectId === 'string' ? projectId : '',
3552
+ conversationId: typeof conversationId === 'string' ? conversationId : null,
3553
+ artifactId: critiqueRunId,
3554
+ artifactDir: critiqueArtifactDir,
3555
+ adapter: typeof agentId === 'string' ? agentId : 'unknown',
3556
+ // Codex P2 on PR #1485: thread the resolved skill id into the
3557
+ // orchestrator so the Phase 12 metrics carry the real label
3558
+ // instead of falling through to 'unknown' for every live run.
3559
+ // `effectiveSkillId` was already computed above (line ~2951) as
3560
+ // the request skillId with a project-row fallback; pass it
3561
+ // through verbatim, and leave the orchestrator's own default
3562
+ // of 'unknown' for runs that genuinely have no skill assigned.
3563
+ skill: typeof effectiveSkillId === 'string' && effectiveSkillId
3564
+ ? effectiveSkillId
3565
+ : undefined,
3566
+ cfg: critiqueCfg,
3567
+ db,
3568
+ bus: critiqueBus,
3569
+ stdout: stdoutIterable,
3570
+ child,
3571
+ childExitPromise,
3572
+ signal: critiqueAbort.signal,
3573
+ });
3574
+ // Map the critique terminal status to the chat run lifecycle.
3575
+ // 'shipped' and 'below_threshold' both ran to a ship decision and
3576
+ // finalize as 'succeeded'; every other status (timed_out,
3577
+ // interrupted, degraded, failed, legacy) is a failure path so the
3578
+ // run reflects the real outcome instead of a misleading success.
3579
+ const succeeded = orchestratorResult.status === 'shipped'
3580
+ || orchestratorResult.status === 'below_threshold';
3581
+ if (run.cancelRequested) {
3582
+ design.runs.finish(run, 'canceled', 1, null);
3583
+ }
3584
+ else if (succeeded) {
3585
+ design.runs.finish(run, 'succeeded', 0, null);
3586
+ }
3587
+ else {
3588
+ design.runs.finish(run, 'failed', 1, null);
3589
+ }
3590
+ }
3591
+ catch (err) {
3592
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', err instanceof Error ? err.message : String(err)));
3593
+ design.runs.finish(run, 'failed', 1, null);
3594
+ }
3595
+ finally {
3596
+ critiqueRunRegistry.unregister(critiqueProjectKey, critiqueRunId);
3597
+ }
3598
+ return;
3599
+ }
3600
+ }
3601
+ // Structured streams (Claude Code) go through a line-delimited JSON
3602
+ // parser that turns stream_event objects into UI-friendly events. For
3603
+ // plain streams (most other CLIs) we forward raw chunks unchanged so
3604
+ // the browser can append them to the assistant's text buffer.
3605
+ let agentStreamError = null;
3606
+ // Tracks whether any stream the run is using actually emitted user-
3607
+ // visible content. Only the streams routed through `sendAgentEvent`
3608
+ // contribute to this flag; ACP sessions and plain stdout streams are
3609
+ // covered by their own success/failure paths and the empty-output
3610
+ // guard below skips them via `trackingSubstantiveOutput`.
3611
+ let agentProducedOutput = false;
3612
+ let trackingSubstantiveOutput = false;
3613
+ // Event types that count as "the agent actually produced something the
3614
+ // user can see." Lifecycle markers (`status`) and meter readings
3615
+ // (`usage`) deliberately do NOT count — a model can emit token-usage
3616
+ // numbers for an empty completion (issue #691), and a `status:running`
3617
+ // banner without any follow-up is exactly the silent-failure shape we
3618
+ // want to surface as failed instead of succeeded.
3619
+ const SUBSTANTIVE_AGENT_EVENT_TYPES = new Set([
3620
+ 'text_delta',
3621
+ 'thinking_delta',
3622
+ 'tool_use',
3623
+ 'tool_result',
3624
+ 'artifact',
3625
+ ]);
3626
+ const sendAgentEvent = (ev) => {
3627
+ if (ev?.type === 'error') {
3628
+ if (agentStreamError)
3629
+ return;
3630
+ agentStreamError = String(ev.message || 'Agent stream error');
3631
+ clearInactivityWatchdog();
3632
+ const authFailure = classifyAgentAuthFailure(agentId, [
3633
+ agentStreamError,
3634
+ typeof ev.raw === 'string' ? ev.raw : '',
3635
+ agentStdoutTail,
3636
+ agentStderrTail,
3637
+ ].join('\n'));
3638
+ if (authFailure?.status === 'missing') {
3639
+ send('error', createSseErrorPayload('AGENT_AUTH_REQUIRED', cursorAuthGuidance(), { retryable: true }));
3640
+ return;
3641
+ }
3642
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', agentStreamError, {
3643
+ details: ev.raw ? { raw: ev.raw } : undefined,
3644
+ retryable: false,
3645
+ }));
3646
+ return;
3647
+ }
3648
+ lastAgentEventPhase = summarizeAgentEventForInactivity(ev);
3649
+ noteAgentActivity();
3650
+ if (ev?.type && SUBSTANTIVE_AGENT_EVENT_TYPES.has(ev.type)) {
3651
+ agentProducedOutput = true;
3652
+ }
3653
+ send('agent', ev);
3654
+ };
3655
+ if (def.streamFormat === 'claude-stream-json') {
3656
+ const claude = createClaudeStreamHandler((ev) => {
3657
+ lastAgentEventPhase = summarizeAgentEventForInactivity(ev);
3658
+ noteAgentActivity();
3659
+ send('agent', ev);
3660
+ // Stream-json input mode keeps the child's stdin open across the
3661
+ // turn so we can answer interactive tools like `AskUserQuestion`
3662
+ // with a real `tool_result`. The child has no other way to know
3663
+ // the conversation is over, though — without an EOF it sits idle
3664
+ // until the inactivity watchdog kills it. Bookkeeping here:
3665
+ // - tool_use(AskUserQuestion): record the id so we know we owe
3666
+ // the model a tool_result before the turn can end.
3667
+ // - turn_end (per-turn synthesized from `stop_reason`): fire on
3668
+ // `end_turn` etc. but NOT on `tool_use` — that stop reason
3669
+ // means the model paused mid-tool, not "turn complete".
3670
+ // - usage (session result at EOF in single-shot mode).
3671
+ try {
3672
+ if (run.stdinOpen) {
3673
+ if (ev &&
3674
+ typeof ev === 'object' &&
3675
+ ev.type === 'tool_use' &&
3676
+ (ev.name === 'AskUserQuestion' || ev.name === 'ask_user_question') &&
3677
+ typeof ev.id === 'string') {
3678
+ if (!run.pendingHostAnswers)
3679
+ run.pendingHostAnswers = new Set();
3680
+ run.pendingHostAnswers.add(ev.id);
3681
+ }
3682
+ else if (ev &&
3683
+ typeof ev === 'object' &&
3684
+ ((ev.type === 'turn_end' &&
3685
+ // `stop_reason: tool_use` means the model paused to wait
3686
+ // for tool execution (claude-code is about to run an
3687
+ // internal tool, or we owe a host tool_result). Either
3688
+ // way the conversation is still in flight — do not close.
3689
+ ev.stopReason !== 'tool_use') ||
3690
+ ev.type === 'usage') &&
3691
+ (!run.pendingHostAnswers || run.pendingHostAnswers.size === 0)) {
3692
+ // Per-turn `turn_end` (synthesized from
3693
+ // `assistant.message.stop_reason` in `claude-stream`) is the
3694
+ // primary close signal; `usage` is the session-level result
3695
+ // that fires at EOF in single-shot mode. Either is a valid
3696
+ // "this turn is done" cue, but only when there's no host
3697
+ // answer outstanding AND the model isn't paused mid-tool.
3698
+ if (run.child && run.child.stdin && !run.child.stdin.destroyed) {
3699
+ try {
3700
+ run.child.stdin.end();
3701
+ }
3702
+ catch { }
3703
+ }
3704
+ run.stdinOpen = false;
3705
+ }
3706
+ }
3707
+ }
3708
+ catch { }
3709
+ });
3710
+ child.stdout.on('data', (chunk) => claude.feed(chunk));
3711
+ child.on('close', () => claude.flush());
3712
+ }
3713
+ else if (def.streamFormat === 'qoder-stream-json') {
3714
+ trackingSubstantiveOutput = true;
3715
+ const qoder = createQoderStreamHandler(sendAgentEvent);
3716
+ child.stdout.on('data', (chunk) => qoder.feed(chunk));
3717
+ child.on('close', () => qoder.flush());
3718
+ }
3719
+ else if (def.streamFormat === 'copilot-stream-json') {
3720
+ const copilot = createCopilotStreamHandler((ev) => {
3721
+ lastAgentEventPhase = summarizeAgentEventForInactivity(ev);
3722
+ noteAgentActivity();
3723
+ send('agent', ev);
3724
+ });
3725
+ child.stdout.on('data', (chunk) => copilot.feed(chunk));
3726
+ child.on('close', () => copilot.flush());
3727
+ }
3728
+ else if (def.streamFormat === 'pi-rpc') {
3729
+ // Route through sendAgentEvent so that pi-rpc's error events
3730
+ // (extension_error, auto_retry_end with success=false, and the
3731
+ // message_update error delta) set agentStreamError and flip the
3732
+ // run to `failed` on close — same path as qoder-stream-json and
3733
+ // json-event-stream after issue #691. Also enables the
3734
+ // substantive-output guard (agentProducedOutput) so a pi run
3735
+ // that exits 0 without producing visible content is caught.
3736
+ //
3737
+ // attachPiRpcSession invokes its send callback with the two-arg
3738
+ // channel/payload shape: send('agent', payload) for normal events
3739
+ // and send('error', {message}) from fail(). sendAgentEvent
3740
+ // expects a single event object, so we adapt at the call site:
3741
+ // - 'agent' channel → relay payload through sendAgentEvent
3742
+ // - 'error' channel → route through the daemon's error path
3743
+ // (createSseErrorPayload + send SSE + set agentStreamError)
3744
+ trackingSubstantiveOutput = true;
3745
+ acpSession = attachPiRpcSession({
3746
+ child,
3747
+ prompt: composed,
3748
+ cwd: effectiveCwd,
3749
+ model: safeModel,
3750
+ send: (channel, payload) => {
3751
+ if (channel === 'agent') {
3752
+ sendAgentEvent(payload);
3753
+ }
3754
+ else if (channel === 'error') {
3755
+ if (agentStreamError)
3756
+ return;
3757
+ agentStreamError = String(payload?.message || 'Pi session error');
3758
+ clearInactivityWatchdog();
3759
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', agentStreamError, { retryable: false }));
3760
+ }
3761
+ else {
3762
+ noteAgentActivity();
3763
+ send(channel, payload);
3764
+ }
3765
+ },
3766
+ imagePaths: def.supportsImagePaths ? safeImages : [],
3767
+ uploadRoot: UPLOAD_DIR,
3768
+ });
3769
+ }
3770
+ else if (def.streamFormat === 'acp-json-rpc') {
3771
+ const acpStageTimeoutMs = resolveAcpStageTimeoutMs();
3772
+ acpSession = attachAcpSession({
3773
+ child,
3774
+ prompt: composed,
3775
+ cwd: effectiveCwd,
3776
+ model: safeModel,
3777
+ mcpServers,
3778
+ send: (event, data) => {
3779
+ noteAgentActivity();
3780
+ send(event, data);
3781
+ },
3782
+ ...(acpStageTimeoutMs !== undefined ? { stageTimeoutMs: acpStageTimeoutMs } : {}),
3783
+ });
3784
+ }
3785
+ else if (def.streamFormat === 'json-event-stream') {
3786
+ // Pipe through sendAgentEvent so the OpenCode `type:'error'` frame
3787
+ // (now emitted as a real error event by json-event-stream.ts after
3788
+ // #691) actually triggers `agentStreamError` instead of being
3789
+ // forwarded as a no-op `agent` SSE event. This also wires the
3790
+ // substantive-output tracking the close handler reads below.
3791
+ trackingSubstantiveOutput = true;
3792
+ const handler = createJsonEventStreamHandler(def.eventParser || def.id, sendAgentEvent);
3793
+ child.stdout.on('data', (chunk) => handler.feed(chunk));
3794
+ child.on('close', () => handler.flush());
3795
+ }
3796
+ else {
3797
+ child.stdout.on('data', (chunk) => {
3798
+ noteAgentActivity();
3799
+ send('stdout', { chunk });
3800
+ });
3801
+ }
3802
+ // Wire the acpSession onto the run so cancel() can call abort()
3803
+ // instead of raw SIGTERM (applies to pi-rpc and acp-json-rpc).
3804
+ run.acpSession = acpSession;
3805
+ child.stderr.on('data', (chunk) => {
3806
+ noteAgentActivity();
3807
+ agentStderrTail = `${agentStderrTail}${chunk}`.slice(-2000);
3808
+ send('stderr', { chunk });
3809
+ });
3810
+ child.on('error', (err) => {
3811
+ clearInactivityWatchdog();
3812
+ revokeToolToken('child_exit');
3813
+ unregisterChatAgentEventSink();
3814
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', err.message));
3815
+ design.runs.finish(run, 'failed', 1, null);
3816
+ });
3817
+ child.on('close', (code, signal) => {
3818
+ clearInactivityWatchdog();
3819
+ revokeToolToken('child_exit');
3820
+ unregisterChatAgentEventSink();
3821
+ if (acpSession?.hasFatalError()) {
3822
+ return design.runs.finish(run, 'failed', code ?? 1, signal ?? null);
3823
+ }
3824
+ if (agentStreamError) {
3825
+ return design.runs.finish(run, 'failed', code ?? 1, signal ?? null);
3826
+ }
3827
+ if (code !== 0 &&
3828
+ !run.cancelRequested &&
3829
+ classifyAgentAuthFailure(agentId, `${agentStderrTail}\n${agentStdoutTail}`)?.status === 'missing') {
3830
+ send('error', createSseErrorPayload('AGENT_AUTH_REQUIRED', cursorAuthGuidance(), { retryable: true }));
3831
+ return design.runs.finish(run, 'failed', code ?? 1, signal ?? null);
3832
+ }
3833
+ // Empty-output guard: a clean `code === 0` exit on a stream we are
3834
+ // tracking, with no error frame and no substantive event, means the
3835
+ // run silently finished without producing anything visible. That used
3836
+ // to be marked `succeeded` and rendered as an empty assistant turn —
3837
+ // see issue #691, where OpenCode runs were ending in ~3s with no
3838
+ // chat content and no error banner. Surface an explicit failure
3839
+ // instead so the chat shows a clear reason. ACP sessions and plain
3840
+ // stdout streams are gated out via `trackingSubstantiveOutput`;
3841
+ // their success/failure determination lives elsewhere.
3842
+ if (code === 0 &&
3843
+ !run.cancelRequested &&
3844
+ trackingSubstantiveOutput &&
3845
+ !agentProducedOutput) {
3846
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', 'Agent completed without producing any output. The model or provider may have returned an empty response — check the agent logs for upstream errors.', { retryable: true }));
3847
+ return design.runs.finish(run, 'failed', code, signal);
3848
+ }
3849
+ // ACP agents that don't shut down on stdin.end() (e.g. Devin for
3850
+ // Terminal) are forced to exit via SIGTERM from attachAcpSession after
3851
+ // a clean prompt completion. Without an override, the chat run would
3852
+ // be marked `failed` because `code === 0` fails (code is null on a
3853
+ // signal exit). `completedSuccessfully()` reports whether the ACP
3854
+ // session resolved without a fatal error or abort.
3855
+ //
3856
+ // Scope the override narrowly to the exact forced-shutdown shape this
3857
+ // PR introduces: code is null AND signal is SIGTERM AND the ACP
3858
+ // session reported clean completion. Any other post-response failure
3859
+ // (non-zero exit code, SIGKILL, SIGSEGV, etc.) still propagates as
3860
+ // `failed`, preserving the existing close-status behavior for genuine
3861
+ // post-response process problems.
3862
+ const acpCleanCompletion = typeof acpSession?.completedSuccessfully === 'function' &&
3863
+ acpSession.completedSuccessfully();
3864
+ const acpForcedShutdown = code === null && signal === 'SIGTERM' && acpCleanCompletion;
3865
+ const status = run.cancelRequested
3866
+ ? 'canceled'
3867
+ : code === 0 || acpForcedShutdown
3868
+ ? 'succeeded'
3869
+ : 'failed';
3870
+ if (status === 'failed') {
3871
+ const diagnostic = diagnoseClaudeCliFailure({
3872
+ agentId: def.id,
3873
+ exitCode: code,
3874
+ signal,
3875
+ stderrTail: agentStderrTail,
3876
+ stdoutTail: agentStdoutTail,
3877
+ env: spawnedAgentEnv,
3878
+ });
3879
+ if (diagnostic) {
3880
+ send('error', createSseErrorPayload('AGENT_EXECUTION_FAILED', diagnostic.message, { retryable: diagnostic.retryable, details: { detail: diagnostic.detail } }));
3881
+ }
3882
+ }
3883
+ design.runs.finish(run, status, code, signal);
3884
+ });
3885
+ if (writePromptToChildStdin && child.stdin) {
3886
+ const promptInputFormat = def.promptInputFormat ?? 'text';
3887
+ if (promptInputFormat === 'stream-json') {
3888
+ // Wrap the prompt as an Anthropic user message and write it as one
3889
+ // JSONL line. Do NOT close stdin: claude-code keeps reading further
3890
+ // messages until EOF, which is what lets us inject a `tool_result`
3891
+ // block later when the user answers an `AskUserQuestion` card. The
3892
+ // stdin is closed implicitly when the child exits (run terminates,
3893
+ // user cancels, or the model finishes without an outstanding tool
3894
+ // call).
3895
+ const userMessage = JSON.stringify({
3896
+ type: 'user',
3897
+ message: {
3898
+ role: 'user',
3899
+ content: [{ type: 'text', text: composed }],
3900
+ },
3901
+ });
3902
+ try {
3903
+ child.stdin.write(`${userMessage}\n`, 'utf8');
3904
+ }
3905
+ catch (err) {
3906
+ // Swallow EPIPE here for the same reason as the listener above —
3907
+ // a fast-exiting child has already routed its failure through
3908
+ // stderr / exit handlers.
3909
+ if (err && err.code !== 'EPIPE')
3910
+ throw err;
3911
+ }
3912
+ run.stdinOpen = true;
3913
+ }
3914
+ else {
3915
+ child.stdin.end(composed, 'utf8');
3916
+ }
3917
+ }
3918
+ };
3919
+ // Send a `tool_result` content block into a still-running stream-json
3920
+ // child. Used for interactive tools that the host answers (currently:
3921
+ // Claude's `AskUserQuestion`). The run must still be active and its
3922
+ // stdin must still be open — we never re-spawn a closed child.
3923
+ const submitToolResultToRun = (runId, toolUseId, content, isError = false) => {
3924
+ const run = design.runs.get(runId);
3925
+ if (!run)
3926
+ return { ok: false, reason: 'not_found' };
3927
+ if (design.runs.isTerminal(run.status)) {
3928
+ return { ok: false, reason: 'run_terminal' };
3929
+ }
3930
+ if (!run.child || !run.child.stdin || run.child.stdin.destroyed) {
3931
+ return { ok: false, reason: 'stdin_closed' };
3932
+ }
3933
+ if (!run.stdinOpen) {
3934
+ return { ok: false, reason: 'stdin_text_mode' };
3935
+ }
3936
+ if (typeof toolUseId !== 'string' || !toolUseId) {
3937
+ return { ok: false, reason: 'bad_tool_use_id' };
3938
+ }
3939
+ const safeContent = typeof content === 'string' ? content : String(content ?? '');
3940
+ const userMessage = JSON.stringify({
3941
+ type: 'user',
3942
+ message: {
3943
+ role: 'user',
3944
+ content: [
3945
+ {
3946
+ type: 'tool_result',
3947
+ tool_use_id: toolUseId,
3948
+ content: safeContent,
3949
+ is_error: !!isError,
3950
+ },
3951
+ ],
3952
+ },
3953
+ });
3954
+ try {
3955
+ run.child.stdin.write(`${userMessage}\n`, 'utf8');
3956
+ }
3957
+ catch (err) {
3958
+ return { ok: false, reason: 'write_failed', error: err && err.message };
3959
+ }
3960
+ if (run.pendingHostAnswers) {
3961
+ run.pendingHostAnswers.delete(toolUseId);
3962
+ if (run.pendingHostAnswers.size === 0 && run.stdinOpen) {
3963
+ if (run.child && run.child.stdin && !run.child.stdin.destroyed) {
3964
+ try {
3965
+ run.child.stdin.end();
3966
+ }
3967
+ catch { }
3968
+ }
3969
+ run.stdinOpen = false;
3970
+ }
3971
+ }
3972
+ return { ok: true };
3973
+ };
3974
+ orbitService.setRunHandler(async ({ trigger, startedAt, prompt, systemPrompt, template, }) => {
3975
+ // Each Orbit run gets its own project so the conversation, messages, and
3976
+ // live artifact are isolated. The handler does the synchronous prep here
3977
+ // (insert project/conversation/run rows, kick off the chat run) and
3978
+ // returns immediately with the new project id; the daemon endpoint
3979
+ // resolves the HTTP request with that id so the client can navigate to
3980
+ // the new project before the agent has finished. Anything that depends
3981
+ // on the agent's final status (live artifact discovery, lastRun summary
3982
+ // metadata) lives inside the `completion` promise.
3983
+ const appConfig = await readAppConfig(RUNTIME_DATA_DIR);
3984
+ let agentId = typeof appConfig.agentId === 'string' && appConfig.agentId
3985
+ ? appConfig.agentId
3986
+ : null;
3987
+ if (!agentId) {
3988
+ const agents = await detectAgents(appConfig.agentCliEnv ?? {}).catch(() => []);
3989
+ agentId = agents.find((agent) => agent.available)?.id ?? null;
3990
+ }
3991
+ if (!agentId)
3992
+ throw new Error('No available agent is configured for Orbit. Choose an agent in Settings first.');
3993
+ const now = Date.now();
3994
+ const projectId = `orbit-${randomUUID()}`;
3995
+ const conversationId = `orbit-conv-${randomUUID()}`;
3996
+ const assistantMessageId = `orbit-assistant-${randomUUID()}`;
3997
+ const projectName = `Orbit · ${formatLocalProjectTimestamp(startedAt)}`;
3998
+ const orbitDesignSystemId = template?.designSystemRequired === false
3999
+ ? null
4000
+ : appConfig.designSystemId ?? null;
4001
+ insertProject(db, {
4002
+ id: projectId,
4003
+ name: projectName,
4004
+ skillId: 'live-artifact',
4005
+ designSystemId: orbitDesignSystemId,
4006
+ pendingPrompt: null,
4007
+ metadata: { kind: 'orbit', trigger },
4008
+ createdAt: now,
4009
+ updatedAt: now,
4010
+ });
4011
+ insertConversation(db, {
4012
+ id: conversationId,
4013
+ projectId,
4014
+ title: projectName,
4015
+ createdAt: now,
4016
+ updatedAt: now,
4017
+ });
4018
+ const run = design.runs.create({
4019
+ projectId,
4020
+ conversationId,
4021
+ assistantMessageId,
4022
+ clientRequestId: `orbit-${trigger}-${randomUUID()}`,
4023
+ agentId,
4024
+ });
4025
+ upsertMessage(db, conversationId, {
4026
+ id: `orbit-user-${run.id}`,
4027
+ role: 'user',
4028
+ content: prompt,
4029
+ });
4030
+ upsertMessage(db, conversationId, {
4031
+ id: assistantMessageId,
4032
+ role: 'assistant',
4033
+ content: '',
4034
+ agentId,
4035
+ agentName: getAgentDef(agentId)?.name ?? agentId,
4036
+ runId: run.id,
4037
+ runStatus: 'queued',
4038
+ startedAt: now,
4039
+ });
4040
+ if (template?.dir) {
4041
+ const cwd = await ensureProject(PROJECTS_DIR, projectId);
4042
+ const result = await stageActiveSkill(cwd, path.basename(template.dir), template.dir, (msg) => console.warn(msg));
4043
+ if (!result.staged) {
4044
+ console.warn(`[od] orbit template skill-stage skipped: ${result.reason ?? 'unknown reason'}; falling back to prompt-embedded instructions`);
4045
+ }
4046
+ }
4047
+ const modelPrefs = appConfig.agentModels?.[agentId] ?? {};
4048
+ design.runs.start(run, () => startChatRun({
4049
+ agentId,
4050
+ projectId,
4051
+ conversationId: run.conversationId,
4052
+ assistantMessageId: run.assistantMessageId,
4053
+ clientRequestId: run.clientRequestId,
4054
+ skillId: 'live-artifact',
4055
+ designSystemId: orbitDesignSystemId,
4056
+ model: modelPrefs.model ?? null,
4057
+ reasoning: modelPrefs.reasoning ?? null,
4058
+ message: prompt,
4059
+ systemPrompt: [
4060
+ renderOrbitTemplateSystemPrompt(template),
4061
+ systemPrompt,
4062
+ 'You are Orbit, an autonomous activity-summary agent inside Open Design.',
4063
+ 'You must discover connectors and connector tools yourself through the OD CLI; the daemon has not chosen tools for you.',
4064
+ 'You must create and register a Live Artifact as the final deliverable. Do not merely describe what you would do.',
4065
+ 'Do not ask follow-up questions, do not emit <question-form>, and do not wait for user input. This run is unattended; pick reasonable defaults and complete the artifact.',
4066
+ 'Keep connector credentials and OD_TOOL_TOKEN private; never print or persist secrets.',
4067
+ ].join('\n'),
4068
+ }, run));
4069
+ const completion = (async () => {
4070
+ const finalStatus = await design.runs.wait(run);
4071
+ db.prepare(`UPDATE messages SET run_status = ?, ended_at = ? WHERE id = ?`).run(finalStatus.status, Date.now(), assistantMessageId);
4072
+ const artifacts = await listLiveArtifacts({ projectsRoot: PROJECTS_DIR, projectId });
4073
+ const artifact = artifacts.find((candidate) => candidate.createdByRunId === run.id);
4074
+ const status = finalStatus.status === 'succeeded' && !artifact ? 'failed' : finalStatus.status;
4075
+ return {
4076
+ agentRunId: run.id,
4077
+ status,
4078
+ ...(artifact?.id ? { artifactId: artifact.id, artifactProjectId: projectId } : {}),
4079
+ summary: artifact?.id
4080
+ ? `Agent ${finalStatus.status} and registered live artifact ${artifact.title}.`
4081
+ : finalStatus.status === 'succeeded'
4082
+ ? buildOrbitNoLiveArtifactSummary(run.events)
4083
+ : `Agent ${finalStatus.status} but did not register a live artifact for this Orbit run.`,
4084
+ };
4085
+ })();
4086
+ return { projectId, agentRunId: run.id, completion };
4087
+ });
4088
+ orbitService.setTemplateResolver(async (skillId) => {
4089
+ // Orbit templates (live-artifact, etc.) live under design-templates after
4090
+ // the split, but earlier projects may still point at functional-skill
4091
+ // ids for the same purpose — search both roots so a stored project id
4092
+ // keeps resolving through one or the other.
4093
+ const skills = await listAllSkillLikeEntries();
4094
+ const skill = findSkillById(skills, skillId);
4095
+ if (!skill || skill.scenario !== 'orbit')
4096
+ return null;
4097
+ return {
4098
+ id: skill.id,
4099
+ name: skill.name,
4100
+ examplePrompt: skill.examplePrompt,
4101
+ dir: skill.dir,
4102
+ body: skill.body,
4103
+ designSystemRequired: skill.designSystemRequired !== false,
4104
+ };
4105
+ });
4106
+ // Each routine fire resolves an agent, prepares project/conversation state,
4107
+ // and dispatches into the same chat runner used by manual runs.
4108
+ routineService.setRunHandler(async ({ routine, trigger, startedAt }) => {
4109
+ const appConfig = await readAppConfig(RUNTIME_DATA_DIR);
4110
+ let agentId = routine.agentId
4111
+ || (typeof appConfig.agentId === 'string' && appConfig.agentId ? appConfig.agentId : null);
4112
+ if (!agentId) {
4113
+ const agents = await detectAgents(appConfig.agentCliEnv ?? {}).catch(() => []);
4114
+ agentId = agents.find((agent) => agent.available)?.id ?? null;
4115
+ }
4116
+ if (!agentId) {
4117
+ throw new Error('No available agent is configured. Choose an agent in Settings first.');
4118
+ }
4119
+ const now = startedAt;
4120
+ const stamp = formatLocalProjectTimestamp(new Date(now).toISOString());
4121
+ let projectId;
4122
+ let projectName;
4123
+ if (routine.target.mode === 'reuse') {
4124
+ const project = getProject(db, routine.target.projectId);
4125
+ if (!project)
4126
+ throw new Error(`Routine target project ${routine.target.projectId} not found`);
4127
+ projectId = project.id;
4128
+ projectName = project.name;
4129
+ }
4130
+ else {
4131
+ projectId = `routine-${randomUUID()}`;
4132
+ projectName = `${routine.name} · ${stamp}`;
4133
+ insertProject(db, {
4134
+ id: projectId,
4135
+ name: projectName,
4136
+ skillId: routine.skillId ?? null,
4137
+ designSystemId: appConfig.designSystemId ?? null,
4138
+ pendingPrompt: null,
4139
+ metadata: { kind: 'other', intent: 'routine', routineId: routine.id, trigger },
4140
+ createdAt: now,
4141
+ updatedAt: now,
4142
+ });
4143
+ }
4144
+ const conversationId = `routine-conv-${randomUUID()}`;
4145
+ const conversationTitle = routine.target.mode === 'reuse'
4146
+ ? `${routine.name} · ${stamp}`
4147
+ : projectName;
4148
+ insertConversation(db, {
4149
+ id: conversationId,
4150
+ projectId,
4151
+ title: conversationTitle,
4152
+ createdAt: now,
4153
+ updatedAt: now,
4154
+ });
4155
+ // Notify any open `ProjectView` watching this project so its
4156
+ // conversation list picks up the new routine conversation without
4157
+ // requiring the user to leave and re-enter the project (#1361).
4158
+ // For reuse-an-existing-project mode this is the only path the
4159
+ // open view has to learn the conversation exists; for new-project
4160
+ // mode this is harmless (no subscribers for a project that was
4161
+ // just created milliseconds ago). The payload shape is the shared
4162
+ // `ProjectConversationCreatedSsePayload` from `@open-design/contracts`
4163
+ // so the daemon producer and the web consumer cannot drift.
4164
+ /** @type {ProjectConversationCreatedSsePayload} */
4165
+ const conversationCreatedEvent = {
4166
+ type: 'conversation-created',
4167
+ projectId,
4168
+ conversationId,
4169
+ title: conversationTitle,
4170
+ createdAt: now,
4171
+ };
4172
+ emitProjectEvent(projectId, conversationCreatedEvent);
4173
+ const assistantMessageId = `routine-assistant-${randomUUID()}`;
4174
+ const run = design.runs.create({
4175
+ projectId,
4176
+ conversationId,
4177
+ assistantMessageId,
4178
+ clientRequestId: `routine-${trigger}-${randomUUID()}`,
4179
+ agentId,
4180
+ });
4181
+ upsertMessage(db, conversationId, {
4182
+ id: `routine-user-${run.id}`,
4183
+ role: 'user',
4184
+ content: routine.prompt,
4185
+ });
4186
+ upsertMessage(db, conversationId, {
4187
+ id: assistantMessageId,
4188
+ role: 'assistant',
4189
+ content: '',
4190
+ agentId,
4191
+ agentName: getAgentDef(agentId)?.name ?? agentId,
4192
+ runId: run.id,
4193
+ runStatus: 'queued',
4194
+ startedAt: now,
4195
+ });
4196
+ const modelPrefs = appConfig.agentModels?.[agentId] ?? {};
4197
+ design.runs.start(run, () => startChatRun({
4198
+ agentId,
4199
+ projectId,
4200
+ conversationId: run.conversationId,
4201
+ assistantMessageId: run.assistantMessageId,
4202
+ clientRequestId: run.clientRequestId,
4203
+ skillId: routine.skillId ?? null,
4204
+ designSystemId: appConfig.designSystemId ?? null,
4205
+ model: modelPrefs.model ?? null,
4206
+ reasoning: modelPrefs.reasoning ?? null,
4207
+ message: routine.prompt,
4208
+ systemPrompt: [
4209
+ `You are running an unattended scheduled routine named "${routine.name}".`,
4210
+ 'Do not ask follow-up questions, do not emit <question-form>, and do not wait for user input. Pick reasonable defaults and finish the task.',
4211
+ ].join('\n'),
4212
+ }, run));
4213
+ const completion = (async () => {
4214
+ const finalStatus = await design.runs.wait(run);
4215
+ db.prepare(`UPDATE messages SET run_status = ?, ended_at = ? WHERE id = ?`)
4216
+ .run(finalStatus.status, Date.now(), assistantMessageId);
4217
+ return {
4218
+ status: finalStatus.status,
4219
+ summary: `Routine "${routine.name}" ${finalStatus.status}.`,
4220
+ };
4221
+ })();
4222
+ return { projectId, conversationId, agentRunId: run.id, completion };
4223
+ });
4224
+ routineService.start();
4225
+ assertServerContextSatisfiesRoutes({
4226
+ db,
4227
+ design,
4228
+ http: httpDeps,
4229
+ paths: pathDeps,
4230
+ ids: idDeps,
4231
+ uploads: uploadDeps,
4232
+ node: nodeDeps,
4233
+ projectStore: projectStoreDeps,
4234
+ projectFiles: projectFileDeps,
4235
+ conversations: conversationDeps,
4236
+ templates: templateDeps,
4237
+ status: projectStatusDeps,
4238
+ events: projectEventDeps,
4239
+ imports: importDeps,
4240
+ exports: projectExportDeps,
4241
+ artifacts: artifactDeps,
4242
+ documents: { buildDocumentPreview },
4243
+ auth: authDeps,
4244
+ liveArtifacts: liveArtifactDeps,
4245
+ deploy: deployDeps,
4246
+ media: mediaDeps,
4247
+ appConfig: appConfigDeps,
4248
+ orbit: orbitDeps,
4249
+ nativeDialogs: nativeDialogDeps,
4250
+ research: researchDeps,
4251
+ mcp: { pendingAuth: mcpPendingAuth, daemonUrlRef },
4252
+ resources: {
4253
+ listAllSkills,
4254
+ listAllDesignTemplates,
4255
+ listAllSkillLikeEntries,
4256
+ listAllDesignSystems,
4257
+ mimeFor,
4258
+ },
4259
+ routines: { routineService },
4260
+ validation: validationDeps,
4261
+ finalize: finalizeDeps,
4262
+ chat: { startChatRun, submitToolResultToRun },
4263
+ agents: agentDeps,
4264
+ critique: critiqueDeps,
4265
+ lifecycle: { isDaemonShuttingDown: () => daemonShuttingDown },
4266
+ });
4267
+ registerRoutineRoutes(app, {
4268
+ db,
4269
+ routines: { routineService },
4270
+ });
4271
+ registerChatRoutes(app, {
4272
+ db,
4273
+ design,
4274
+ http: httpDeps,
4275
+ chat: { startChatRun, submitToolResultToRun },
4276
+ agents: agentDeps,
4277
+ critique: critiqueDeps,
4278
+ validation: validationDeps,
4279
+ lifecycle: { isDaemonShuttingDown: () => daemonShuttingDown },
4280
+ });
4281
+ // Wait for `listen` to bind so callers always see the resolved URL —
4282
+ // critical when port=0 (ephemeral port) and when the embedding sidecar
4283
+ // needs to advertise the port to a parent process before any request
4284
+ // can flow. Three callers depend on this contract:
4285
+ // - `apps/daemon/src/cli.ts` → expects `{ url, server, shutdown }`
4286
+ // - `apps/daemon/sidecar/server.ts` → expects `{ url, server }`
4287
+ // - `apps/daemon/tests/version-route.test.ts` → expects `{ url, server }`
4288
+ return await new Promise((resolve, reject) => {
4289
+ let daemonShutdownStarted = false;
4290
+ const cleanupDaemonBackgroundWork = () => {
4291
+ composioConnectorProvider.stopCatalogRefreshLoop();
4292
+ orbitService.stop();
4293
+ routineService?.stop();
4294
+ };
4295
+ const shutdownDaemonRuns = async () => {
4296
+ if (daemonShutdownStarted)
4297
+ return;
4298
+ daemonShutdownStarted = true;
4299
+ daemonShuttingDown = true;
4300
+ await design.runs.shutdownActive({ graceMs: resolveChatRunShutdownGraceMs() });
4301
+ await design.analytics.shutdown();
4302
+ };
4303
+ let server;
4304
+ try {
4305
+ server = app.listen(port, host, () => {
4306
+ const address = server.address();
4307
+ // `address()` can in theory return `string | AddressInfo | null`. For
4308
+ // a TCP listener it's always `AddressInfo` with a `.port` — the guard
4309
+ // is belt-and-braces so an unexpected null never silently produces a
4310
+ // `http://127.0.0.1:0` URL that callers would then try to fetch.
4311
+ const boundPort = address && typeof address === 'object' ? address.port : null;
4312
+ if (!boundPort) {
4313
+ reject(new Error(`[od] daemon failed to resolve listening port (address=${JSON.stringify(address)})`));
4314
+ return;
4315
+ }
4316
+ resolvedPort = boundPort;
4317
+ // When binding to all interfaces report localhost for local callers;
4318
+ // when binding to a specific address (e.g. a Tailscale IP) report that
4319
+ // address so remote callers and the sidecar use the correct URL.
4320
+ const reportHost = host === '0.0.0.0' || host === '::' ? '127.0.0.1' : host;
4321
+ const url = `http://${reportHost}:${resolvedPort}`;
4322
+ if (!returnServer) {
4323
+ console.log(`[od] daemon listening on ${url}`);
4324
+ }
4325
+ daemonUrl = url;
4326
+ resolve(returnServer ? { url, server, shutdown: shutdownDaemonRuns } : url);
4327
+ });
4328
+ }
4329
+ catch (error) {
4330
+ cleanupDaemonBackgroundWork();
4331
+ reject(error);
4332
+ return;
4333
+ }
4334
+ server.once('close', () => {
4335
+ void shutdownDaemonRuns().finally(cleanupDaemonBackgroundWork);
4336
+ });
4337
+ // `app.listen` throws synchronously when the port is already in use on
4338
+ // some Node versions, but emits an `error` event on others (and for
4339
+ // EACCES / EADDRNOTAVAIL even on the same Node). Wire the event so the
4340
+ // returned Promise always settles instead of hanging forever.
4341
+ server.on('error', (error) => {
4342
+ cleanupDaemonBackgroundWork();
4343
+ reject(error);
4344
+ });
4345
+ });
4346
+ }
4347
+ function randomId() {
4348
+ return randomUUID();
4349
+ }
4350
+ function sanitizeSlug(text) {
4351
+ return String(text)
4352
+ .toLowerCase()
4353
+ .replace(/[^\w\s-]/g, '')
4354
+ .replace(/[\s_]+/g, '-')
4355
+ .replace(/^-+|-+$/g, '')
4356
+ .slice(0, 64);
4357
+ }
4358
+ function assembleExample(templateHtml, slidesHtml, title) {
4359
+ return templateHtml
4360
+ .replace('<!-- SLIDES_HERE -->', slidesHtml)
4361
+ .replace(/<title>.*?<\/title>/, `<title>${title} | Open Design Example</title>`);
4362
+ }
4363
+ // Skill example HTML often references shipped images via relative paths
4364
+ // like `./assets/hero.png`. Those resolve correctly when the file is
4365
+ // opened from disk, but the web app loads the example into a sandboxed
4366
+ // iframe via `srcdoc`, where the document URL is `about:srcdoc` and
4367
+ // relative URLs cannot find the assets. Rewriting them to an absolute
4368
+ // `/api/skills/<id>/assets/...` URL lets the same HTML render in both
4369
+ // places — the disk preview keeps working, and the in-app preview now
4370
+ // fetches assets through the matching route below.
4371
+ export function rewriteSkillAssetUrls(html, skillId) {
4372
+ if (typeof html !== 'string' || html.length === 0)
4373
+ return html;
4374
+ // Match src/href attributes whose values point at the current skill's
4375
+ // assets (`./assets/...` or `assets/...`) or a sibling skill's assets
4376
+ // (`../other-skill/assets/...`). Quote style is preserved so we do not
4377
+ // disturb the surrounding markup.
4378
+ return html.replace(/(\s(?:src|href)\s*=\s*)(['"])((?:\.\.\/([^/'"#?]+)\/)?(?:\.\/)?assets\/([^'"#?]+))(\2)/gi, (_match, attr, openQuote, _fullPath, siblingSkillId, relPath, closeQuote) => {
4379
+ const resolvedSkillId = siblingSkillId || skillId;
4380
+ const prefix = `/api/skills/${encodeURIComponent(resolvedSkillId)}/assets/`;
4381
+ return `${attr}${openQuote}${prefix}${relPath}${closeQuote}`;
4382
+ });
4383
+ }
4384
+ //# sourceMappingURL=server.js.map