@guuey/create-agentic-app 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/README.md +22 -2
  2. package/dist/{chunk-JD4RAKEG.js → chunk-5V2IFXD4.js} +96 -21
  3. package/dist/cli.cjs +145 -17
  4. package/dist/cli.js +60 -5
  5. package/dist/index.cjs +97 -21
  6. package/dist/index.d.cts +33 -2
  7. package/dist/index.d.ts +33 -2
  8. package/dist/index.js +3 -1
  9. package/dist/templates/{openai-agents-sdk → agentic-app/claude-agent-sdk}/AGENTS.md +2 -2
  10. package/dist/templates/{openai-agents-sdk → agentic-app/claude-agent-sdk}/README.md +17 -3
  11. package/dist/templates/agentic-app/claude-agent-sdk/gitignore +5 -0
  12. package/dist/templates/agentic-app/claude-agent-sdk/guuey.app.json +28 -0
  13. package/dist/templates/agentic-app/claude-agent-sdk/guuey.app.schema.json +119 -0
  14. package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/package.json +6 -3
  15. package/dist/templates/agentic-app/claude-agent-sdk/scripts/bootstrap.mjs +376 -0
  16. package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/web/index.html +0 -1
  17. package/dist/templates/agentic-app/claude-agent-sdk/web/package.json +28 -0
  18. package/dist/templates/agentic-app/claude-agent-sdk/web/src/components/AgentChat.tsx +53 -0
  19. package/dist/templates/agentic-app/claude-agent-sdk/web/src/components/AppShell.tsx +65 -0
  20. package/dist/templates/agentic-app/claude-agent-sdk/web/src/components/BootstrapGate.tsx +30 -0
  21. package/dist/templates/agentic-app/claude-agent-sdk/web/src/components/Shell.tsx +50 -0
  22. package/dist/templates/agentic-app/claude-agent-sdk/web/src/config.ts +148 -0
  23. package/dist/templates/agentic-app/claude-agent-sdk/web/src/lib/identity.ts +67 -0
  24. package/dist/templates/agentic-app/claude-agent-sdk/web/src/lib/oidc.ts +79 -0
  25. package/dist/templates/agentic-app/claude-agent-sdk/web/src/lib/status.ts +45 -0
  26. package/dist/templates/agentic-app/claude-agent-sdk/web/src/lib/widget.ts +96 -0
  27. package/dist/templates/agentic-app/claude-agent-sdk/web/src/main.tsx +52 -0
  28. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/AgentCanvas.tsx +14 -0
  29. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/Dashboard.tsx +36 -0
  30. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/Home.tsx +133 -0
  31. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/Landing.tsx +50 -0
  32. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/Login.tsx +81 -0
  33. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/Reports.tsx +9 -0
  34. package/dist/templates/agentic-app/claude-agent-sdk/web/src/pages/TalkOnMobile.tsx +50 -0
  35. package/dist/templates/agentic-app/claude-agent-sdk/web/src/routes.ts +7 -0
  36. package/dist/templates/agentic-app/claude-agent-sdk/web/src/styles-app.css +132 -0
  37. package/dist/templates/agentic-app/claude-agent-sdk/web/src/styles.css +248 -0
  38. package/dist/templates/agentic-app/claude-agent-sdk/web/src/vite-env.d.ts +1 -0
  39. package/dist/templates/agentic-app/claude-agent-sdk/web/tsconfig.json +18 -0
  40. package/dist/templates/agentic-app/claude-agent-sdk/web/vite.config.ts +46 -0
  41. package/dist/templates/{google-adk → agentic-app/google-adk}/AGENTS.md +2 -2
  42. package/dist/templates/agentic-app/google-adk/gitignore +5 -0
  43. package/dist/templates/agentic-app/google-adk/guuey.app.json +28 -0
  44. package/dist/templates/agentic-app/google-adk/guuey.app.schema.json +119 -0
  45. package/dist/templates/{google-adk → agentic-app/google-adk}/package.json +6 -3
  46. package/dist/templates/agentic-app/google-adk/scripts/bootstrap.mjs +376 -0
  47. package/dist/templates/{google-adk → agentic-app/google-adk}/web/index.html +0 -1
  48. package/dist/templates/agentic-app/google-adk/web/package.json +28 -0
  49. package/dist/templates/agentic-app/google-adk/web/src/components/AgentChat.tsx +53 -0
  50. package/dist/templates/agentic-app/google-adk/web/src/components/AppShell.tsx +65 -0
  51. package/dist/templates/agentic-app/google-adk/web/src/components/BootstrapGate.tsx +30 -0
  52. package/dist/templates/agentic-app/google-adk/web/src/components/Shell.tsx +50 -0
  53. package/dist/templates/agentic-app/google-adk/web/src/config.ts +148 -0
  54. package/dist/templates/agentic-app/google-adk/web/src/lib/identity.ts +67 -0
  55. package/dist/templates/agentic-app/google-adk/web/src/lib/oidc.ts +79 -0
  56. package/dist/templates/agentic-app/google-adk/web/src/lib/status.ts +45 -0
  57. package/dist/templates/agentic-app/google-adk/web/src/lib/widget.ts +96 -0
  58. package/dist/templates/agentic-app/google-adk/web/src/main.tsx +52 -0
  59. package/dist/templates/agentic-app/google-adk/web/src/pages/AgentCanvas.tsx +14 -0
  60. package/dist/templates/agentic-app/google-adk/web/src/pages/Dashboard.tsx +36 -0
  61. package/dist/templates/agentic-app/google-adk/web/src/pages/Home.tsx +133 -0
  62. package/dist/templates/agentic-app/google-adk/web/src/pages/Landing.tsx +50 -0
  63. package/dist/templates/agentic-app/google-adk/web/src/pages/Login.tsx +81 -0
  64. package/dist/templates/agentic-app/google-adk/web/src/pages/Reports.tsx +9 -0
  65. package/dist/templates/agentic-app/google-adk/web/src/pages/TalkOnMobile.tsx +50 -0
  66. package/dist/templates/agentic-app/google-adk/web/src/routes.ts +7 -0
  67. package/dist/templates/agentic-app/google-adk/web/src/styles-app.css +132 -0
  68. package/dist/templates/agentic-app/google-adk/web/src/styles.css +248 -0
  69. package/dist/templates/agentic-app/google-adk/web/src/vite-env.d.ts +1 -0
  70. package/dist/templates/agentic-app/google-adk/web/tsconfig.json +18 -0
  71. package/dist/templates/agentic-app/google-adk/web/vite.config.ts +46 -0
  72. package/dist/templates/{claude-agent-sdk → agentic-app/openai-agents-sdk}/AGENTS.md +2 -2
  73. package/dist/templates/{claude-agent-sdk → agentic-app/openai-agents-sdk}/README.md +17 -3
  74. package/dist/templates/agentic-app/openai-agents-sdk/gitignore +5 -0
  75. package/dist/templates/agentic-app/openai-agents-sdk/guuey.app.json +28 -0
  76. package/dist/templates/agentic-app/openai-agents-sdk/guuey.app.schema.json +119 -0
  77. package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/package.json +6 -3
  78. package/dist/templates/agentic-app/openai-agents-sdk/scripts/bootstrap.mjs +376 -0
  79. package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/web/index.html +0 -1
  80. package/dist/templates/agentic-app/openai-agents-sdk/web/package.json +28 -0
  81. package/dist/templates/agentic-app/openai-agents-sdk/web/src/components/AgentChat.tsx +53 -0
  82. package/dist/templates/agentic-app/openai-agents-sdk/web/src/components/AppShell.tsx +65 -0
  83. package/dist/templates/agentic-app/openai-agents-sdk/web/src/components/BootstrapGate.tsx +30 -0
  84. package/dist/templates/agentic-app/openai-agents-sdk/web/src/components/Shell.tsx +50 -0
  85. package/dist/templates/agentic-app/openai-agents-sdk/web/src/config.ts +148 -0
  86. package/dist/templates/agentic-app/openai-agents-sdk/web/src/lib/identity.ts +67 -0
  87. package/dist/templates/agentic-app/openai-agents-sdk/web/src/lib/oidc.ts +79 -0
  88. package/dist/templates/agentic-app/openai-agents-sdk/web/src/lib/status.ts +45 -0
  89. package/dist/templates/agentic-app/openai-agents-sdk/web/src/lib/widget.ts +96 -0
  90. package/dist/templates/agentic-app/openai-agents-sdk/web/src/main.tsx +52 -0
  91. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/AgentCanvas.tsx +14 -0
  92. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/Dashboard.tsx +36 -0
  93. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/Home.tsx +133 -0
  94. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/Landing.tsx +50 -0
  95. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/Login.tsx +81 -0
  96. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/Reports.tsx +9 -0
  97. package/dist/templates/agentic-app/openai-agents-sdk/web/src/pages/TalkOnMobile.tsx +50 -0
  98. package/dist/templates/agentic-app/openai-agents-sdk/web/src/routes.ts +7 -0
  99. package/dist/templates/agentic-app/openai-agents-sdk/web/src/styles-app.css +132 -0
  100. package/dist/templates/agentic-app/openai-agents-sdk/web/src/styles.css +248 -0
  101. package/dist/templates/agentic-app/openai-agents-sdk/web/src/vite-env.d.ts +1 -0
  102. package/dist/templates/agentic-app/openai-agents-sdk/web/tsconfig.json +18 -0
  103. package/dist/templates/agentic-app/openai-agents-sdk/web/vite.config.ts +46 -0
  104. package/dist/templates/base/claude-agent-sdk/.env.example +4 -0
  105. package/dist/templates/base/claude-agent-sdk/.mcp.json +1 -0
  106. package/dist/templates/base/claude-agent-sdk/AGENTS.md +135 -0
  107. package/dist/templates/base/claude-agent-sdk/README.md +171 -0
  108. package/dist/templates/base/claude-agent-sdk/ggui/blueprints/.gitkeep +0 -0
  109. package/dist/templates/base/claude-agent-sdk/ggui/ggui.json +15 -0
  110. package/dist/templates/base/claude-agent-sdk/ggui/themes/.gitkeep +0 -0
  111. package/dist/templates/base/claude-agent-sdk/gitignore +5 -0
  112. package/dist/templates/base/claude-agent-sdk/guuey.app.json +28 -0
  113. package/dist/templates/base/claude-agent-sdk/guuey.app.schema.json +119 -0
  114. package/dist/templates/base/claude-agent-sdk/guuey.json +14 -0
  115. package/dist/templates/base/claude-agent-sdk/mcps/todo/Dockerfile +46 -0
  116. package/dist/templates/base/claude-agent-sdk/mcps/todo/package.json +22 -0
  117. package/dist/templates/base/claude-agent-sdk/mcps/todo/src/server.ts +173 -0
  118. package/dist/templates/base/claude-agent-sdk/mcps/todo/tsconfig.json +15 -0
  119. package/dist/templates/base/claude-agent-sdk/mcps/todo/tsup.config.ts +14 -0
  120. package/dist/templates/base/claude-agent-sdk/package.json +30 -0
  121. package/dist/templates/base/claude-agent-sdk/pnpm-workspace.yaml +24 -0
  122. package/dist/templates/base/claude-agent-sdk/prompts/system.md +4 -0
  123. package/dist/templates/base/claude-agent-sdk/scripts/bootstrap.mjs +376 -0
  124. package/dist/templates/base/claude-agent-sdk/scripts/dev.mjs +45 -0
  125. package/dist/templates/base/claude-agent-sdk/src/agent-config.ts +77 -0
  126. package/dist/templates/base/claude-agent-sdk/src/worker.ts +89 -0
  127. package/dist/templates/base/claude-agent-sdk/tsconfig.json +15 -0
  128. package/dist/templates/base/claude-agent-sdk/tsup.config.ts +9 -0
  129. package/dist/templates/base/claude-agent-sdk/web/index.html +12 -0
  130. package/dist/templates/{claude-agent-sdk → base/claude-agent-sdk}/web/package.json +9 -8
  131. package/dist/templates/base/claude-agent-sdk/web/src/components/AgentChat.tsx +53 -0
  132. package/dist/templates/base/claude-agent-sdk/web/src/components/BootstrapGate.tsx +30 -0
  133. package/dist/templates/base/claude-agent-sdk/web/src/components/Shell.tsx +50 -0
  134. package/dist/templates/base/claude-agent-sdk/web/src/config.ts +148 -0
  135. package/dist/templates/base/claude-agent-sdk/web/src/lib/identity.ts +67 -0
  136. package/dist/templates/base/claude-agent-sdk/web/src/lib/oidc.ts +79 -0
  137. package/dist/templates/base/claude-agent-sdk/web/src/lib/status.ts +45 -0
  138. package/dist/templates/base/claude-agent-sdk/web/src/lib/widget.ts +96 -0
  139. package/dist/templates/base/claude-agent-sdk/web/src/main.tsx +38 -0
  140. package/dist/templates/base/claude-agent-sdk/web/src/pages/Chat.tsx +15 -0
  141. package/dist/templates/base/claude-agent-sdk/web/src/pages/Home.tsx +133 -0
  142. package/dist/templates/base/claude-agent-sdk/web/src/pages/Landing.tsx +50 -0
  143. package/dist/templates/base/claude-agent-sdk/web/src/pages/Login.tsx +81 -0
  144. package/dist/templates/base/claude-agent-sdk/web/src/routes.ts +7 -0
  145. package/dist/templates/base/claude-agent-sdk/web/src/styles.css +248 -0
  146. package/dist/templates/base/claude-agent-sdk/web/src/vite-env.d.ts +1 -0
  147. package/dist/templates/base/claude-agent-sdk/web/tsconfig.json +18 -0
  148. package/dist/templates/base/claude-agent-sdk/web/vite.config.ts +46 -0
  149. package/dist/templates/base/google-adk/.env.example +4 -0
  150. package/dist/templates/base/google-adk/.mcp.json +1 -0
  151. package/dist/templates/base/google-adk/AGENTS.md +135 -0
  152. package/dist/templates/base/google-adk/README.md +90 -0
  153. package/dist/templates/base/google-adk/ggui/blueprints/.gitkeep +0 -0
  154. package/dist/templates/base/google-adk/ggui/ggui.json +15 -0
  155. package/dist/templates/base/google-adk/ggui/themes/.gitkeep +0 -0
  156. package/dist/templates/base/google-adk/gitignore +5 -0
  157. package/dist/templates/base/google-adk/guuey.app.json +28 -0
  158. package/dist/templates/base/google-adk/guuey.app.schema.json +119 -0
  159. package/dist/templates/base/google-adk/guuey.json +15 -0
  160. package/dist/templates/base/google-adk/mcps/todo/Dockerfile +46 -0
  161. package/dist/templates/base/google-adk/mcps/todo/package.json +22 -0
  162. package/dist/templates/base/google-adk/mcps/todo/src/server.ts +173 -0
  163. package/dist/templates/base/google-adk/mcps/todo/tsconfig.json +15 -0
  164. package/dist/templates/base/google-adk/mcps/todo/tsup.config.ts +14 -0
  165. package/dist/templates/base/google-adk/package.json +30 -0
  166. package/dist/templates/base/google-adk/pnpm-workspace.yaml +34 -0
  167. package/dist/templates/base/google-adk/prompts/system.md +4 -0
  168. package/dist/templates/base/google-adk/scripts/bootstrap.mjs +376 -0
  169. package/dist/templates/base/google-adk/scripts/dev.mjs +45 -0
  170. package/dist/templates/base/google-adk/src/agent.ts +43 -0
  171. package/dist/templates/base/google-adk/tsconfig.json +15 -0
  172. package/dist/templates/base/google-adk/tsup.config.ts +13 -0
  173. package/dist/templates/base/google-adk/web/index.html +12 -0
  174. package/dist/templates/{google-adk → base/google-adk}/web/package.json +9 -8
  175. package/dist/templates/base/google-adk/web/src/components/AgentChat.tsx +53 -0
  176. package/dist/templates/base/google-adk/web/src/components/BootstrapGate.tsx +30 -0
  177. package/dist/templates/base/google-adk/web/src/components/Shell.tsx +50 -0
  178. package/dist/templates/base/google-adk/web/src/config.ts +148 -0
  179. package/dist/templates/base/google-adk/web/src/lib/identity.ts +67 -0
  180. package/dist/templates/base/google-adk/web/src/lib/oidc.ts +79 -0
  181. package/dist/templates/base/google-adk/web/src/lib/status.ts +45 -0
  182. package/dist/templates/base/google-adk/web/src/lib/widget.ts +96 -0
  183. package/dist/templates/base/google-adk/web/src/main.tsx +38 -0
  184. package/dist/templates/base/google-adk/web/src/pages/Chat.tsx +15 -0
  185. package/dist/templates/base/google-adk/web/src/pages/Home.tsx +133 -0
  186. package/dist/templates/base/google-adk/web/src/pages/Landing.tsx +50 -0
  187. package/dist/templates/base/google-adk/web/src/pages/Login.tsx +81 -0
  188. package/dist/templates/base/google-adk/web/src/routes.ts +7 -0
  189. package/dist/templates/base/google-adk/web/src/styles.css +248 -0
  190. package/dist/templates/base/google-adk/web/src/vite-env.d.ts +1 -0
  191. package/dist/templates/base/google-adk/web/tsconfig.json +18 -0
  192. package/dist/templates/base/google-adk/web/vite.config.ts +46 -0
  193. package/dist/templates/base/openai-agents-sdk/.env.example +4 -0
  194. package/dist/templates/base/openai-agents-sdk/.mcp.json +1 -0
  195. package/dist/templates/base/openai-agents-sdk/AGENTS.md +135 -0
  196. package/dist/templates/base/openai-agents-sdk/README.md +171 -0
  197. package/dist/templates/base/openai-agents-sdk/ggui/blueprints/.gitkeep +0 -0
  198. package/dist/templates/base/openai-agents-sdk/ggui/ggui.json +15 -0
  199. package/dist/templates/base/openai-agents-sdk/ggui/themes/.gitkeep +0 -0
  200. package/dist/templates/base/openai-agents-sdk/gitignore +5 -0
  201. package/dist/templates/base/openai-agents-sdk/guuey.app.json +28 -0
  202. package/dist/templates/base/openai-agents-sdk/guuey.app.schema.json +119 -0
  203. package/dist/templates/base/openai-agents-sdk/guuey.json +27 -0
  204. package/dist/templates/base/openai-agents-sdk/mcps/todo/Dockerfile +46 -0
  205. package/dist/templates/base/openai-agents-sdk/mcps/todo/package.json +22 -0
  206. package/dist/templates/base/openai-agents-sdk/mcps/todo/src/server.ts +173 -0
  207. package/dist/templates/base/openai-agents-sdk/mcps/todo/tsconfig.json +15 -0
  208. package/dist/templates/base/openai-agents-sdk/mcps/todo/tsup.config.ts +14 -0
  209. package/dist/templates/base/openai-agents-sdk/package.json +30 -0
  210. package/dist/templates/base/openai-agents-sdk/pnpm-workspace.yaml +24 -0
  211. package/dist/templates/base/openai-agents-sdk/prompts/system.md +4 -0
  212. package/dist/templates/base/openai-agents-sdk/scripts/bootstrap.mjs +376 -0
  213. package/dist/templates/base/openai-agents-sdk/scripts/dev.mjs +45 -0
  214. package/dist/templates/base/openai-agents-sdk/src/agent-config.ts +77 -0
  215. package/dist/templates/base/openai-agents-sdk/src/worker.ts +75 -0
  216. package/dist/templates/base/openai-agents-sdk/tsconfig.json +15 -0
  217. package/dist/templates/base/openai-agents-sdk/tsup.config.ts +16 -0
  218. package/dist/templates/base/openai-agents-sdk/web/index.html +12 -0
  219. package/dist/templates/{openai-agents-sdk → base/openai-agents-sdk}/web/package.json +9 -8
  220. package/dist/templates/base/openai-agents-sdk/web/src/components/AgentChat.tsx +53 -0
  221. package/dist/templates/base/openai-agents-sdk/web/src/components/BootstrapGate.tsx +30 -0
  222. package/dist/templates/base/openai-agents-sdk/web/src/components/Shell.tsx +50 -0
  223. package/dist/templates/base/openai-agents-sdk/web/src/config.ts +148 -0
  224. package/dist/templates/base/openai-agents-sdk/web/src/lib/identity.ts +67 -0
  225. package/dist/templates/base/openai-agents-sdk/web/src/lib/oidc.ts +79 -0
  226. package/dist/templates/base/openai-agents-sdk/web/src/lib/status.ts +45 -0
  227. package/dist/templates/base/openai-agents-sdk/web/src/lib/widget.ts +96 -0
  228. package/dist/templates/base/openai-agents-sdk/web/src/main.tsx +38 -0
  229. package/dist/templates/base/openai-agents-sdk/web/src/pages/Chat.tsx +15 -0
  230. package/dist/templates/base/openai-agents-sdk/web/src/pages/Home.tsx +133 -0
  231. package/dist/templates/base/openai-agents-sdk/web/src/pages/Landing.tsx +50 -0
  232. package/dist/templates/base/openai-agents-sdk/web/src/pages/Login.tsx +81 -0
  233. package/dist/templates/base/openai-agents-sdk/web/src/routes.ts +7 -0
  234. package/dist/templates/base/openai-agents-sdk/web/src/styles.css +248 -0
  235. package/dist/templates/base/openai-agents-sdk/web/src/vite-env.d.ts +1 -0
  236. package/dist/templates/base/openai-agents-sdk/web/tsconfig.json +18 -0
  237. package/dist/templates/base/openai-agents-sdk/web/vite.config.ts +46 -0
  238. package/package.json +6 -3
  239. package/dist/templates/claude-agent-sdk/web/.env.example +0 -17
  240. package/dist/templates/claude-agent-sdk/web/sandbox-proxy.ts +0 -239
  241. package/dist/templates/claude-agent-sdk/web/src/App.tsx +0 -272
  242. package/dist/templates/claude-agent-sdk/web/src/main.tsx +0 -12
  243. package/dist/templates/claude-agent-sdk/web/src/useAgentChat.ts +0 -122
  244. package/dist/templates/claude-agent-sdk/web/src/vite-env.d.ts +0 -27
  245. package/dist/templates/claude-agent-sdk/web/tsconfig.json +0 -20
  246. package/dist/templates/claude-agent-sdk/web/vite.config.ts +0 -12
  247. package/dist/templates/google-adk/web/.env.example +0 -17
  248. package/dist/templates/google-adk/web/sandbox-proxy.ts +0 -239
  249. package/dist/templates/google-adk/web/src/App.tsx +0 -272
  250. package/dist/templates/google-adk/web/src/main.tsx +0 -12
  251. package/dist/templates/google-adk/web/src/useAgentChat.ts +0 -122
  252. package/dist/templates/google-adk/web/src/vite-env.d.ts +0 -27
  253. package/dist/templates/google-adk/web/tsconfig.json +0 -20
  254. package/dist/templates/google-adk/web/vite.config.ts +0 -12
  255. package/dist/templates/openai-agents-sdk/web/.env.example +0 -17
  256. package/dist/templates/openai-agents-sdk/web/sandbox-proxy.ts +0 -239
  257. package/dist/templates/openai-agents-sdk/web/src/App.tsx +0 -272
  258. package/dist/templates/openai-agents-sdk/web/src/main.tsx +0 -12
  259. package/dist/templates/openai-agents-sdk/web/src/useAgentChat.ts +0 -122
  260. package/dist/templates/openai-agents-sdk/web/src/vite-env.d.ts +0 -27
  261. package/dist/templates/openai-agents-sdk/web/tsconfig.json +0 -20
  262. package/dist/templates/openai-agents-sdk/web/vite.config.ts +0 -12
  263. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/.env.example +0 -0
  264. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/.mcp.json +0 -0
  265. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/ggui/blueprints/.gitkeep +0 -0
  266. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/ggui/ggui.json +0 -0
  267. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/ggui/themes/.gitkeep +0 -0
  268. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/guuey.json +0 -0
  269. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/mcps/todo/Dockerfile +0 -0
  270. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/mcps/todo/package.json +0 -0
  271. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/mcps/todo/src/server.ts +0 -0
  272. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/mcps/todo/tsconfig.json +0 -0
  273. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/mcps/todo/tsup.config.ts +0 -0
  274. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/pnpm-workspace.yaml +0 -0
  275. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/prompts/system.md +0 -0
  276. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/scripts/dev.mjs +0 -0
  277. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/src/agent-config.ts +0 -0
  278. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/src/worker.ts +0 -0
  279. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/tsconfig.json +0 -0
  280. /package/dist/templates/{claude-agent-sdk → agentic-app/claude-agent-sdk}/tsup.config.ts +0 -0
  281. /package/dist/templates/{google-adk → agentic-app/google-adk}/.env.example +0 -0
  282. /package/dist/templates/{google-adk → agentic-app/google-adk}/.mcp.json +0 -0
  283. /package/dist/templates/{google-adk → agentic-app/google-adk}/README.md +0 -0
  284. /package/dist/templates/{google-adk → agentic-app/google-adk}/ggui/blueprints/.gitkeep +0 -0
  285. /package/dist/templates/{google-adk → agentic-app/google-adk}/ggui/ggui.json +0 -0
  286. /package/dist/templates/{google-adk → agentic-app/google-adk}/ggui/themes/.gitkeep +0 -0
  287. /package/dist/templates/{google-adk → agentic-app/google-adk}/guuey.json +0 -0
  288. /package/dist/templates/{google-adk → agentic-app/google-adk}/mcps/todo/Dockerfile +0 -0
  289. /package/dist/templates/{google-adk → agentic-app/google-adk}/mcps/todo/package.json +0 -0
  290. /package/dist/templates/{google-adk → agentic-app/google-adk}/mcps/todo/src/server.ts +0 -0
  291. /package/dist/templates/{google-adk → agentic-app/google-adk}/mcps/todo/tsconfig.json +0 -0
  292. /package/dist/templates/{google-adk → agentic-app/google-adk}/mcps/todo/tsup.config.ts +0 -0
  293. /package/dist/templates/{google-adk → agentic-app/google-adk}/pnpm-workspace.yaml +0 -0
  294. /package/dist/templates/{google-adk → agentic-app/google-adk}/prompts/system.md +0 -0
  295. /package/dist/templates/{google-adk → agentic-app/google-adk}/scripts/dev.mjs +0 -0
  296. /package/dist/templates/{google-adk → agentic-app/google-adk}/src/agent.ts +0 -0
  297. /package/dist/templates/{google-adk → agentic-app/google-adk}/tsconfig.json +0 -0
  298. /package/dist/templates/{google-adk → agentic-app/google-adk}/tsup.config.ts +0 -0
  299. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/.env.example +0 -0
  300. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/.mcp.json +0 -0
  301. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/ggui/blueprints/.gitkeep +0 -0
  302. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/ggui/ggui.json +0 -0
  303. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/ggui/themes/.gitkeep +0 -0
  304. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/guuey.json +0 -0
  305. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/mcps/todo/Dockerfile +0 -0
  306. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/mcps/todo/package.json +0 -0
  307. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/mcps/todo/src/server.ts +0 -0
  308. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/mcps/todo/tsconfig.json +0 -0
  309. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/mcps/todo/tsup.config.ts +0 -0
  310. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/pnpm-workspace.yaml +0 -0
  311. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/prompts/system.md +0 -0
  312. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/scripts/dev.mjs +0 -0
  313. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/src/agent-config.ts +0 -0
  314. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/src/worker.ts +0 -0
  315. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/tsconfig.json +0 -0
  316. /package/dist/templates/{openai-agents-sdk → agentic-app/openai-agents-sdk}/tsup.config.ts +0 -0
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ // pnpm dev — boots the whole local stack. Ctrl-C tears everything down.
3
+ import { spawn } from "node:child_process";
4
+ import { existsSync } from "node:fs";
5
+
6
+ const procs = [];
7
+ function boot(name, command, args, opts = {}) {
8
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], ...opts });
9
+ const prefix = `[${name}]`.padEnd(9);
10
+ child.stdout.on("data", (d) => process.stdout.write(String(d).replace(/^/gm, prefix)));
11
+ child.stderr.on("data", (d) => process.stderr.write(String(d).replace(/^/gm, prefix)));
12
+ child.on("exit", (code) => {
13
+ if (code !== 0 && !shuttingDown) shutdown(`${name} exited (${code})`, 1);
14
+ });
15
+ procs.push(child);
16
+ }
17
+ let shuttingDown = false;
18
+ function shutdown(reason, code = 0) {
19
+ if (shuttingDown) return;
20
+ shuttingDown = true;
21
+ console.log(`\n${reason} — shutting down`);
22
+ for (const p of procs) p.kill("SIGTERM");
23
+ setTimeout(() => process.exit(code), 500);
24
+ }
25
+ process.on("SIGINT", () => shutdown("interrupted"));
26
+ process.on("SIGTERM", () => shutdown("terminated"));
27
+
28
+ if (!existsSync(".env.local"))
29
+ console.warn("hint: cp .env.example .env.local and set your LLM key");
30
+
31
+ boot("worker", "pnpm", ["exec", "tsup", "--watch"]); // rebuilds guuey.worker.js on change
32
+ // `guuey dev` auto-spawns every `kind: 'colocated'` mcpServers entry itself
33
+ // (name→localhost devPort resolution) — the todo MCP is colocated, so it no
34
+ // longer needs its own boot() here; a manual second spawn would double-bind
35
+ // :6782 and crash with EADDRINUSE.
36
+ boot("agent", "pnpm", ["exec", "guuey", "dev", "--serve", "--port", "6790"]);
37
+ boot("ggui", "pnpm", ["exec", "ggui", "serve", "--mcp-only", "--dev-allow-all", "--port", "6781"], {
38
+ cwd: "ggui",
39
+ });
40
+ boot("web", "pnpm", ["--filter", "@agentic-app-template/web", "dev"], {
41
+ env: { ...process.env, PORT: "6890" },
42
+ });
43
+
44
+ console.log("\n agent http://localhost:6790 todo-mcp http://localhost:6782");
45
+ console.log(" ggui http://localhost:6781 web http://localhost:6890\n");
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Snapshot + system-prompt + MCP-endpoint resolution shared by both framework
3
+ * overlays. Duplicated verbatim in `templates-src/frameworks/openai-agents-sdk`
4
+ * by design — template code must be self-contained (no cross-overlay imports),
5
+ * so keep the two copies byte-identical when editing either one.
6
+ */
7
+ import { readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { parseGuueyJson, type GuueyAgent } from "@guuey/config";
10
+ import { listCredentials, type Invoke } from "@guuey/worker";
11
+
12
+ /** GUUEY_AGENT_SNAPSHOT (set by the platform pod and by `guuey dev`) wins; guuey.json is the fallback. */
13
+ export function loadAgent(invoke: Invoke): GuueyAgent {
14
+ const env = process.env.GUUEY_AGENT_SNAPSHOT;
15
+ if (env) return JSON.parse(env) as GuueyAgent;
16
+ const raw = JSON.parse(readFileSync(join(invoke.fs.app, "guuey.json"), "utf8"));
17
+ return parseGuueyJson(raw).agent;
18
+ }
19
+
20
+ export function systemPrompt(invoke: Invoke, agent: GuueyAgent): string | undefined {
21
+ const sp = agent.systemPrompt;
22
+ if (typeof sp === "string") return sp;
23
+ if (sp?.file) return readFileSync(join(invoke.fs.app, sp.file), "utf8");
24
+ return undefined;
25
+ }
26
+
27
+ /**
28
+ * One resolved MCP endpoint this worker may connect to. `transport` rides
29
+ * alongside `url`/`headers` (not hardcoded to `"http"`) because a credential
30
+ * file — `<session>/.guuey/credentials/<name>.json`, shape
31
+ * `{url, transport, headers}` per `@guuey/worker`'s `CredentialFile` — may
32
+ * resolve a server onto the `sse` transport arm.
33
+ */
34
+ export interface McpEndpoint {
35
+ url: string;
36
+ transport: "http" | "sse";
37
+ headers: Record<string, string>;
38
+ }
39
+
40
+ /**
41
+ * Endpoint set = broker-written credential DIRECTORY (source of truth for
42
+ * federated + platform-injected servers — incl. guuey-memory/guuey-profile,
43
+ * invisible to the declared map by design) ∪ declared external entries that
44
+ * have no credential file (plain endpoints, static headers). Credential wins
45
+ * per name. One honest log line names both sets — no silent fallback.
46
+ */
47
+ export function mcpEndpoints(invoke: Invoke, agent: GuueyAgent): Record<string, McpEndpoint> {
48
+ const out: Record<string, McpEndpoint> = {};
49
+ for (const [name, entry] of Object.entries(agent.mcpServers ?? {})) {
50
+ if (entry === false) continue; // `ggui: false` is the generative-UI opt-out, not a server entry
51
+ if (entry.kind !== "external") continue; // hosted/colocated are lowered to external before a worker ever runs
52
+ out[name] = {
53
+ url: entry.url,
54
+ transport: entry.transport ?? "http",
55
+ headers: { ...(entry.headers ?? {}) },
56
+ };
57
+ }
58
+ const creds = listCredentials(invoke.fs)();
59
+ for (const { name, cred } of creds) {
60
+ out[name] = { url: cred.url, transport: cred.transport, headers: cred.headers };
61
+ }
62
+ const credentialed = creds.map((c) => c.name);
63
+ const declaredOnly = Object.keys(out).filter((n) => !credentialed.includes(n));
64
+ console.log(
65
+ `[guuey] mcp endpoints: credentialed=[${credentialed.join(",")}] declared-only=[${declaredOnly.join(",")}]`
66
+ );
67
+ return out;
68
+ }
69
+
70
+ /** Fold prior turns into a prompt preamble (v1 keep-it-simple history handling). */
71
+ export function withHistory(invoke: Invoke): string {
72
+ if (invoke.history.length === 0) return invoke.input;
73
+ const lines = invoke.history.map(
74
+ (h) => `${h.role === "agent" ? "Assistant" : "User"}: ${h.text}`
75
+ );
76
+ return `<conversation_history>\n${lines.join("\n")}\n</conversation_history>\n\n${invoke.input}`;
77
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * agentic-app-template's code-mode worker entry (Claude Agent SDK). Reads the
3
+ * resolved agent snapshot + MCP endpoints via `./agent-config.js`, drives one
4
+ * `query()` per invoke, and streams every native SDK message to the Router
5
+ * via `emit.native` (the field spellings below — `mcpServers`/`systemPrompt`/
6
+ * `allowedTools`/`maxTurns`, and the `type === "result" && subtype ===
7
+ * "success"` result-detection — mirror `@guuey/host`'s `buildOptions` /
8
+ * `runInvoke`, the platform's own consumer of this exact snapshot shape).
9
+ */
10
+ import { createRequire } from "node:module";
11
+ import { query } from "@anthropic-ai/claude-agent-sdk";
12
+ import { serveNative } from "@guuey/worker";
13
+ import { loadAgent, systemPrompt, mcpEndpoints, withHistory } from "./agent-config.js";
14
+
15
+ /**
16
+ * This worker is tsup-bundled (`noExternal`), which breaks the SDK's own
17
+ * native-CLI lookup: the SDK resolves `claude-agent-sdk-<platform>-<arch>`
18
+ * relative to its OWN module location, and once inlined into
19
+ * `guuey.worker.js` that location is the bundle's — where no node_modules
20
+ * has the binary. Resolution order here:
21
+ * 1. `GUUEY_CLAUDE_CODE_EXECUTABLE` — set by the guuey pod Router, pointing
22
+ * at the platform image's binary (a deployed `/worker` has no
23
+ * node_modules at all).
24
+ * 2. Anchored resolve — find the *installed* SDK from the bundle's location
25
+ * (it is this app's direct dependency), then resolve the platform binary
26
+ * package from the SDK's real location, exactly as the unbundled SDK
27
+ * would. Covers local `guuey dev --serve`, where the bundle runs next to
28
+ * the app's node_modules.
29
+ * 3. undefined — let the SDK try (and fail with its actionable error).
30
+ */
31
+ function claudeExecutable(): string | undefined {
32
+ if (process.env.GUUEY_CLAUDE_CODE_EXECUTABLE) return process.env.GUUEY_CLAUDE_CODE_EXECUTABLE;
33
+ try {
34
+ const sdkEntry = createRequire(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");
35
+ return createRequire(sdkEntry).resolve(
36
+ `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}/claude`
37
+ );
38
+ } catch {
39
+ return undefined;
40
+ }
41
+ }
42
+ const pathToClaudeCodeExecutable = claudeExecutable();
43
+
44
+ await serveNative(
45
+ async (invoke, emit) => {
46
+ const agent = loadAgent(invoke);
47
+ const mcpServers = Object.fromEntries(
48
+ Object.entries(mcpEndpoints(invoke, agent)).map(([name, ep]) => [
49
+ name,
50
+ // `alwaysLoad` — this agent's declared MCP servers ARE its tool
51
+ // surface; without it the CLI defers MCP tools behind its ToolSearch
52
+ // built-in (absent here — see `tools: []` below), leaving the model
53
+ // tool-less.
54
+ { type: ep.transport, url: ep.url, headers: ep.headers, alwaysLoad: true },
55
+ ])
56
+ );
57
+ let result = "";
58
+ for await (const message of query({
59
+ prompt: withHistory(invoke),
60
+ options: {
61
+ ...(agent.model ? { model: agent.model } : {}),
62
+ ...(systemPrompt(invoke, agent) ? { systemPrompt: systemPrompt(invoke, agent) } : {}),
63
+ mcpServers,
64
+ // Same posture as `@guuey/host`'s `buildOptions` (options.ts):
65
+ // - allowedTools: the snapshot allowlist verbatim, else every tool
66
+ // from every declared server (`mcp__<server>` prefix match) — MCP
67
+ // calls would otherwise hit the SDK's interactive ask stage, which
68
+ // nothing answers headless, so they'd be silently denied.
69
+ // - tools: [] — purely MCP-driven; no Bash/file/search built-ins.
70
+ // - settingSources: [] — never load the machine's ~/.claude or
71
+ // project settings into this worker (a dev box's logged-in Claude
72
+ // Code MCPs/plugins would leak into the tool catalog).
73
+ // - strictMcpConfig: true — the snapshot's servers only; ignore
74
+ // .mcp.json / user settings / plugins.
75
+ allowedTools: agent.tools?.allowlist ?? Object.keys(mcpServers).map((s) => `mcp__${s}`),
76
+ tools: [],
77
+ settingSources: [],
78
+ strictMcpConfig: true,
79
+ ...(agent.runtime?.maxTurns ? { maxTurns: agent.runtime.maxTurns } : {}),
80
+ ...(pathToClaudeCodeExecutable ? { pathToClaudeCodeExecutable } : {}),
81
+ },
82
+ })) {
83
+ emit.native(JSON.parse(JSON.stringify(message)));
84
+ if (message.type === "result" && message.subtype === "success") result = message.result;
85
+ }
86
+ return result;
87
+ },
88
+ { framework: "claude-agent-sdk", sdkName: "@anthropic-ai/claude-agent-sdk" }
89
+ );
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2023",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "noEmit": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true
12
+ },
13
+ "include": ["src"],
14
+ "exclude": ["node_modules", "dist"]
15
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: { "guuey.worker": "src/worker.ts" },
5
+ format: ["esm"],
6
+ outDir: ".",
7
+ clean: false,
8
+ noExternal: [/./], // bundle everything — the deploy tarball must be runnable via `node guuey.worker.js`
9
+ });
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>agentic-app-template</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentic-app-template/web",
3
- "version": "0.0.0",
4
3
  "private": true,
4
+ "version": "0.0.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite --port 6890",
@@ -9,17 +9,18 @@
9
9
  "typecheck": "tsc --noEmit"
10
10
  },
11
11
  "dependencies": {
12
- "@mcp-ui/client": "^7.1.1",
13
- "@silverprotocol/core": "0.5.0",
12
+ "@guuey/chat": "0.10.0",
13
+ "oidc-client-ts": "^3.1.0",
14
14
  "react": "^19.0.0",
15
- "react-dom": "^19.0.0"
15
+ "react-dom": "^19.0.0",
16
+ "react-router-dom": "^7.1.0"
16
17
  },
17
18
  "devDependencies": {
18
- "@types/node": "^22.0.0",
19
+ "@types/node": "^24.0.0",
19
20
  "@types/react": "^19.0.0",
20
21
  "@types/react-dom": "^19.0.0",
21
- "@vitejs/plugin-react": "^4.3.0",
22
- "typescript": "^5.8.0",
23
- "vite": "^6.0.0"
22
+ "@vitejs/plugin-react": "^4.3.4",
23
+ "typescript": "^5.7.2",
24
+ "vite": "^7.0.0"
24
25
  }
25
26
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The configured `<GuueyChat>` for this app — distribution way #2, the
3
+ * embedded chat SDK. One place wires endpoint, history, identity and theme;
4
+ * every chat surface (the /chat page here, the fullscreen agent canvas in
5
+ * the agentic-app template) renders this.
6
+ *
7
+ * Identity rule: ONE mode per surface. When OIDC is configured AND a
8
+ * session exists, the bearer wins; otherwise the client-minted guest
9
+ * secret. Never both.
10
+ */
11
+ import { useEffect, useState, type CSSProperties } from "react";
12
+ import { GuueyChat } from "@guuey/chat/react";
13
+ import { agentEndpointUrl, appConfig, historyBaseUrl } from "../config";
14
+ import { currentIdentityMode, ensureGuestSecret } from "../lib/identity";
15
+ import { getBearerToken, currentUser, oidcConfigured } from "../lib/oidc";
16
+
17
+ export function AgentChat({ className, style }: { className?: string; style?: CSSProperties }) {
18
+ // The user's CHOSEN mode wins: an explicit "Continue as guest" must never
19
+ // be shadowed by a cached OIDC session. Only when no choice is recorded
20
+ // does a live session imply oidc.
21
+ const chosen = currentIdentityMode();
22
+ const [identity, setIdentity] = useState<"resolving" | "guest" | "oidc">(
23
+ chosen === "guest" || !oidcConfigured() ? "guest" : chosen === "oidc" ? "oidc" : "resolving",
24
+ );
25
+
26
+ useEffect(() => {
27
+ if (identity !== "resolving") return;
28
+ let cancelled = false;
29
+ void currentUser().then((user) => {
30
+ if (!cancelled) setIdentity(user ? "oidc" : "guest");
31
+ });
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [identity]);
36
+
37
+ if (identity === "resolving") return null;
38
+
39
+ const shared = {
40
+ endpointUrl: agentEndpointUrl(),
41
+ appId: appConfig.link?.appId ?? "local",
42
+ apiBaseUrl: historyBaseUrl(),
43
+ mode: appConfig.theme.mode,
44
+ className,
45
+ style,
46
+ };
47
+
48
+ return identity === "oidc" ? (
49
+ <GuueyChat {...shared} getAccessToken={() => getBearerToken()} />
50
+ ) : (
51
+ <GuueyChat {...shared} getGuestSecret={() => ensureGuestSecret()} />
52
+ );
53
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Dev-time gate: until `pnpm bootstrap` has run, every page renders this
3
+ * setup screen instead of a half-configured app. Production builds are
4
+ * gated harder — vite.config.ts fails the build outright.
5
+ */
6
+ import type { ReactNode } from "react";
7
+ import { appConfig } from "../config";
8
+
9
+ export function BootstrapGate({ children }: { children: ReactNode }) {
10
+ if (appConfig.bootstrapped) return <>{children}</>;
11
+ return (
12
+ <main className="gate">
13
+ <div className="gate-card">
14
+ <h1>Run bootstrap first</h1>
15
+ <p>
16
+ This project has not been configured yet. From the project root:
17
+ </p>
18
+ <pre>
19
+ <code>pnpm bootstrap</code>
20
+ </pre>
21
+ <p>
22
+ That writes <code>guuey.app.json</code> (brand, theme, copy) and
23
+ regenerates <code>AGENTS.md</code>. Then start the local stack with{" "}
24
+ <code>pnpm dev</code>. When you are ready to bind a deployed guuey
25
+ app: <code>pnpm bootstrap -- --link</code>.
26
+ </p>
27
+ </div>
28
+ </main>
29
+ );
30
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Base-template chrome: brand header + nav + auth affordance. Pages render
3
+ * inside via the router outlet.
4
+ */
5
+ import { Link, NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
6
+ import { appConfig } from "../config";
7
+ import { CHAT_PATH, HOME_PATH } from "../routes";
8
+ import { currentIdentityMode, logOut } from "../lib/identity";
9
+ import { oidcConfigured, signOutOidc } from "../lib/oidc";
10
+
11
+ export function Shell() {
12
+ const navigate = useNavigate();
13
+ // Subscribing to the location re-renders this chrome on every navigation,
14
+ // so the render-time read below stays fresh after login/logout. (A
15
+ // `storage` listener would NOT work — that event only fires in OTHER
16
+ // tabs, never the one that wrote the change.)
17
+ useLocation();
18
+ const mode = currentIdentityMode();
19
+
20
+ async function handleLogOut() {
21
+ if (mode === "oidc" && oidcConfigured()) await signOutOidc();
22
+ logOut();
23
+ navigate("/");
24
+ }
25
+
26
+ return (
27
+ <div className="shell">
28
+ <header className="topbar">
29
+ <Link to="/" className="brand">
30
+ <span className="brand-mark">{appConfig.brand.logoText}</span>
31
+ <span>{appConfig.brand.name}</span>
32
+ </Link>
33
+ <nav>
34
+ <NavLink to={CHAT_PATH}>Chat</NavLink>
35
+ <NavLink to={HOME_PATH}>Home</NavLink>
36
+ {mode === null ? (
37
+ <NavLink to="/login" className="btn btn-accent">
38
+ Sign in
39
+ </NavLink>
40
+ ) : (
41
+ <button type="button" className="btn" onClick={() => void handleLogOut()}>
42
+ Log out{mode === "guest" ? " (guest)" : ""}
43
+ </button>
44
+ )}
45
+ </nav>
46
+ </header>
47
+ <Outlet />
48
+ </div>
49
+ );
50
+ }
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Typed access to `guuey.app.json` — the ONE file `pnpm bootstrap` writes.
3
+ *
4
+ * The JSON is validated structurally here (not just cast) so a hand-edited
5
+ * config fails with a named path instead of an undefined-deep-in-React
6
+ * crash. The schema is documented in `../guuey.app.schema.json`.
7
+ */
8
+ import rawConfig from "../../guuey.app.json";
9
+
10
+ export interface OidcConfig {
11
+ /** OIDC issuer URL (https). Discovery via /.well-known/openid-configuration. */
12
+ issuer: string;
13
+ clientId: string;
14
+ }
15
+
16
+ export interface AppLink {
17
+ appId: string;
18
+ env: "dev" | "staging" | "release";
19
+ /** Public API base ending in /v1 — history + persisted-card reads. */
20
+ apiBaseUrl: string;
21
+ /** The agent pod's public origin — live chat + health probe. */
22
+ endpointUrl: string;
23
+ /** Widget host origin serving /v1.js for this environment. */
24
+ widgetOrigin: string;
25
+ /** Portal web origin (the "talk on mobile" target). */
26
+ portalUrl: string;
27
+ slug: string | null;
28
+ /** The agent's own hosted page (https://<slug>.agents...), when slugged. */
29
+ pageUrl: string | null;
30
+ }
31
+
32
+ export interface AppConfig {
33
+ schema: number;
34
+ bootstrapped: boolean;
35
+ brand: { name: string; tagline: string; logoText: string };
36
+ theme: { accent: string; mode: "light" | "dark" };
37
+ copy: {
38
+ landing: { headline: string; sub: string };
39
+ login: { guestHint: string };
40
+ };
41
+ auth: { oidc: OidcConfig | null };
42
+ link: AppLink | null;
43
+ demoMode: boolean;
44
+ }
45
+
46
+ class ConfigError extends Error {
47
+ constructor(path: string, expected: string) {
48
+ super(`guuey.app.json: ${path} — expected ${expected}. Re-run \`pnpm bootstrap\` or fix the file by hand (schema: guuey.app.schema.json).`);
49
+ }
50
+ }
51
+
52
+ function str(v: unknown, path: string): string {
53
+ if (typeof v !== "string" || v.length === 0) throw new ConfigError(path, "a non-empty string");
54
+ return v;
55
+ }
56
+
57
+ function bool(v: unknown, path: string): boolean {
58
+ if (typeof v !== "boolean") throw new ConfigError(path, "a boolean");
59
+ return v;
60
+ }
61
+
62
+ function obj(v: unknown, path: string): Record<string, unknown> {
63
+ if (typeof v !== "object" || v === null || Array.isArray(v)) throw new ConfigError(path, "an object");
64
+ return v as Record<string, unknown>;
65
+ }
66
+
67
+ function validate(raw: unknown): AppConfig {
68
+ const root = obj(raw, "$");
69
+ if (root.schema !== 1) throw new ConfigError("schema", "the literal 1");
70
+
71
+ const brand = obj(root.brand, "brand");
72
+ const theme = obj(root.theme, "theme");
73
+ const mode = theme.mode;
74
+ if (mode !== "light" && mode !== "dark") throw new ConfigError("theme.mode", '"light" | "dark"');
75
+ const copy = obj(root.copy, "copy");
76
+ const landing = obj(copy.landing, "copy.landing");
77
+ const login = obj(copy.login, "copy.login");
78
+ const auth = obj(root.auth, "auth");
79
+
80
+ let oidc: OidcConfig | null = null;
81
+ if (auth.oidc !== null && auth.oidc !== undefined) {
82
+ const o = obj(auth.oidc, "auth.oidc");
83
+ oidc = { issuer: str(o.issuer, "auth.oidc.issuer"), clientId: str(o.clientId, "auth.oidc.clientId") };
84
+ }
85
+
86
+ let link: AppLink | null = null;
87
+ if (root.link !== null && root.link !== undefined) {
88
+ const l = obj(root.link, "link");
89
+ const env = l.env;
90
+ if (env !== "dev" && env !== "staging" && env !== "release") {
91
+ throw new ConfigError("link.env", '"dev" | "staging" | "release"');
92
+ }
93
+ link = {
94
+ appId: str(l.appId, "link.appId"),
95
+ env,
96
+ apiBaseUrl: str(l.apiBaseUrl, "link.apiBaseUrl"),
97
+ // Normalize to the ORIGIN whatever shape was stored: the platform's
98
+ // deployment records carry the full `…/agent/invoke` URL, while this
99
+ // contract (and the probe) wants the base. The chat kit accepts
100
+ // either, so normalizing here makes both consumers correct.
101
+ endpointUrl: str(l.endpointUrl, "link.endpointUrl").replace(/\/agent\/invoke\/?$/, ""),
102
+ widgetOrigin: str(l.widgetOrigin, "link.widgetOrigin"),
103
+ portalUrl: str(l.portalUrl, "link.portalUrl"),
104
+ slug: typeof l.slug === "string" ? l.slug : null,
105
+ pageUrl: typeof l.pageUrl === "string" ? l.pageUrl : null,
106
+ };
107
+ }
108
+
109
+ return {
110
+ schema: 1,
111
+ bootstrapped: bool(root.bootstrapped, "bootstrapped"),
112
+ brand: {
113
+ name: str(brand.name, "brand.name"),
114
+ tagline: str(brand.tagline, "brand.tagline"),
115
+ logoText: str(brand.logoText, "brand.logoText"),
116
+ },
117
+ theme: { accent: str(theme.accent, "theme.accent"), mode },
118
+ copy: {
119
+ landing: { headline: str(landing.headline, "copy.landing.headline"), sub: str(landing.sub, "copy.landing.sub") },
120
+ login: { guestHint: str(login.guestHint, "copy.login.guestHint") },
121
+ },
122
+ auth: { oidc },
123
+ link,
124
+ demoMode: bool(root.demoMode ?? false, "demoMode"),
125
+ };
126
+ }
127
+
128
+ export const appConfig: AppConfig = validate(rawConfig);
129
+
130
+ /** The local `guuey dev --serve` router (scripts/dev.mjs boots it). */
131
+ export const DEV_AGENT_URL = "http://localhost:6790";
132
+
133
+ export const isLinked: boolean = appConfig.link !== null;
134
+
135
+ /** Live-chat base: the bound pod when linked, the local dev router otherwise. */
136
+ export function agentEndpointUrl(): string {
137
+ return appConfig.link?.endpointUrl ?? DEV_AGENT_URL;
138
+ }
139
+
140
+ /**
141
+ * History/read-plane base. When linked this is the public API (`…/v1`);
142
+ * in local dev, `guuey dev --serve` exposes the same read-plane route
143
+ * shape (`/threads/:id/messages`) on its own origin, so history and
144
+ * rehydration work locally too.
145
+ */
146
+ export function historyBaseUrl(): string {
147
+ return appConfig.link?.apiBaseUrl ?? DEV_AGENT_URL;
148
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * End-user identity for this app's chat surfaces.
3
+ *
4
+ * ONE mode per surface — never both resolvers at once (a bearer + a guest
5
+ * secret on the same request is a silent-downgrade hazard the platform
6
+ * refuses to guess about):
7
+ *
8
+ * - **Guest** (always available): a client-minted 64-hex secret stored at
9
+ * `localStorage["guuey:guest-secret:<appId>"]` and sent as the
10
+ * `x-guuey-guest` header. Per-browser and persistent, so the agent
11
+ * remembers the visitor across reloads. This is the same mechanic the
12
+ * guuey widget uses. "Log out" deletes the secret — a fresh one next
13
+ * visit is a fresh person as far as the agent is concerned.
14
+ * - **Signed in** (when `auth.oidc` is configured in guuey.app.json): an
15
+ * OIDC ID token from your IdP (see ./oidc.ts), sent as a Bearer. The
16
+ * bound guuey app must be in BYO auth mode for the same issuer
17
+ * (`guuey apps update <appId> --auth-mode byo --issuer-url … --audience <clientId>`).
18
+ */
19
+ import { appConfig } from "../config";
20
+
21
+ export type IdentityMode = "guest" | "oidc";
22
+
23
+ const scope = appConfig.link?.appId ?? "local";
24
+ const GUEST_KEY = `guuey:guest-secret:${scope}`;
25
+ const MODE_KEY = `guuey:identity-mode:${scope}`;
26
+
27
+ function mintSecret(): string {
28
+ const bytes = new Uint8Array(32);
29
+ crypto.getRandomValues(bytes);
30
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
31
+ }
32
+
33
+ /** The stored guest secret, minting one on first use. */
34
+ export function ensureGuestSecret(): string {
35
+ const existing = localStorage.getItem(GUEST_KEY);
36
+ if (existing && /^[0-9a-f]{64}$/.test(existing)) return existing;
37
+ const fresh = mintSecret();
38
+ localStorage.setItem(GUEST_KEY, fresh);
39
+ return fresh;
40
+ }
41
+
42
+ export function getStoredGuestSecret(): string | null {
43
+ const v = localStorage.getItem(GUEST_KEY);
44
+ return v && /^[0-9a-f]{64}$/.test(v) ? v : null;
45
+ }
46
+
47
+ export function currentIdentityMode(): IdentityMode | null {
48
+ const v = localStorage.getItem(MODE_KEY);
49
+ return v === "guest" || v === "oidc" ? v : null;
50
+ }
51
+
52
+ export function setIdentityMode(mode: IdentityMode | null): void {
53
+ if (mode === null) localStorage.removeItem(MODE_KEY);
54
+ else localStorage.setItem(MODE_KEY, mode);
55
+ }
56
+
57
+ /** "Continue as guest": ensure a secret exists and select guest mode. */
58
+ export function continueAsGuest(): void {
59
+ ensureGuestSecret();
60
+ setIdentityMode("guest");
61
+ }
62
+
63
+ /** Log out of whichever mode is active. Guest logout forgets the secret. */
64
+ export function logOut(): void {
65
+ if (currentIdentityMode() === "guest") localStorage.removeItem(GUEST_KEY);
66
+ setIdentityMode(null);
67
+ }