kaddidlehopper 0.5.0 → 0.6.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 (296) hide show
  1. package/dist/cli.js +104 -208
  2. package/dist/index.js +1 -31
  3. package/dist/types/cli.d.ts +1 -8
  4. package/dist/types/types.d.ts +7 -12
  5. package/package.json +1 -2
  6. package/src/cli.ts +129 -271
  7. package/src/index.ts +1 -47
  8. package/src/types.ts +7 -13
  9. package/CONTEXT.md +0 -139
  10. package/add-ons/ai/README.md +0 -34
  11. package/add-ons/ai/assets/AGENTS.md.append +0 -24
  12. package/add-ons/ai/assets/_dot_env.local.append +0 -13
  13. package/add-ons/ai/assets/src/components/AIAssistant.tsx +0 -149
  14. package/add-ons/ai/assets/src/lib/ai-hook.ts +0 -21
  15. package/add-ons/ai/assets/src/lib/weather-tools.ts +0 -30
  16. package/add-ons/ai/assets/src/routes/api.chat.ts +0 -94
  17. package/add-ons/ai/assets/src/routes/chat.css +0 -175
  18. package/add-ons/ai/assets/src/routes/chat.tsx +0 -141
  19. package/add-ons/ai/info.json +0 -22
  20. package/add-ons/ai/package.json +0 -17
  21. package/add-ons/ai/small-logo.svg +0 -8
  22. package/add-ons/db/assets/AGENTS.md.append +0 -22
  23. package/add-ons/db/assets/DB-SETUP.md +0 -65
  24. package/add-ons/db/assets/_dot_env.local.append +0 -2
  25. package/add-ons/db/assets/drizzle.config.ts +0 -10
  26. package/add-ons/db/assets/src/db/index.ts +0 -8
  27. package/add-ons/db/assets/src/db/schema.ts +0 -8
  28. package/add-ons/db/assets/src/routes/db-example.tsx +0 -118
  29. package/add-ons/db/assets/src/server/guestbook.functions.ts +0 -23
  30. package/add-ons/db/info.json +0 -22
  31. package/add-ons/db/package.json +0 -10
  32. package/add-ons/forms/assets/AGENTS.md.append +0 -13
  33. package/add-ons/forms/assets/public/form-example.html +0 -14
  34. package/add-ons/forms/assets/src/routes/form-example.tsx +0 -76
  35. package/add-ons/forms/info.json +0 -18
  36. package/add-ons/forms/package.json +0 -3
  37. package/examples/ai-chat/README.md +0 -36
  38. package/examples/ai-chat/assets/AGENTS.md.append +0 -24
  39. package/examples/ai-chat/assets/src/lib/ai-hook.ts +0 -21
  40. package/examples/ai-chat/assets/src/lib/weather-tools.ts +0 -30
  41. package/examples/ai-chat/assets/src/routes/__root.tsx +0 -57
  42. package/examples/ai-chat/assets/src/routes/api.chat.ts +0 -94
  43. package/examples/ai-chat/assets/src/routes/index.tsx +0 -141
  44. package/examples/ai-chat/assets/src/styles.css +0 -165
  45. package/examples/ai-chat/info.json +0 -25
  46. package/examples/ai-chat/package.json +0 -14
  47. package/examples/blog/README.md +0 -60
  48. package/examples/blog/assets/AGENTS.md.append +0 -18
  49. package/examples/blog/assets/content/posts/beach.md +0 -12
  50. package/examples/blog/assets/content/posts/jungle.md.ejs +0 -12
  51. package/examples/blog/assets/content/posts/mountains.md.ejs +0 -12
  52. package/examples/blog/assets/content/posts/snorkeling.md.ejs +0 -12
  53. package/examples/blog/assets/content/posts/waterfall.md.ejs +0 -12
  54. package/examples/blog/assets/content-collections.ts +0 -30
  55. package/examples/blog/assets/public/beach.jpg +0 -0
  56. package/examples/blog/assets/public/jungle.jpg +0 -0
  57. package/examples/blog/assets/public/mountains.jpg +0 -0
  58. package/examples/blog/assets/public/snorkeling.jpg +0 -0
  59. package/examples/blog/assets/public/waterfall.jpg +0 -0
  60. package/examples/blog/assets/src/components/Header.tsx +0 -52
  61. package/examples/blog/assets/src/components/VacayAssistant.tsx +0 -205
  62. package/examples/blog/assets/src/components/blog-posts.tsx +0 -78
  63. package/examples/blog/assets/src/components/ui/card.tsx +0 -92
  64. package/examples/blog/assets/src/lib/blog-ai-hook.ts +0 -25
  65. package/examples/blog/assets/src/lib/blog-tools.ts +0 -111
  66. package/examples/blog/assets/src/lib/utils.ts +0 -6
  67. package/examples/blog/assets/src/routes/__root.tsx +0 -57
  68. package/examples/blog/assets/src/routes/api.blog-chat.ts +0 -117
  69. package/examples/blog/assets/src/routes/category.$category.tsx +0 -19
  70. package/examples/blog/assets/src/routes/index.tsx +0 -19
  71. package/examples/blog/assets/src/routes/posts.$slug.tsx +0 -63
  72. package/examples/blog/assets/src/styles.css +0 -138
  73. package/examples/blog/info.json +0 -40
  74. package/examples/blog/package.json +0 -23
  75. package/examples/calculator/README.md +0 -16
  76. package/examples/calculator/assets/AGENTS.md.append +0 -9
  77. package/examples/calculator/assets/src/components/Calculator.tsx +0 -238
  78. package/examples/calculator/assets/src/components/Header.tsx +0 -17
  79. package/examples/calculator/assets/src/routes/__root.tsx +0 -57
  80. package/examples/calculator/assets/src/routes/index.tsx +0 -14
  81. package/examples/calculator/info.json +0 -20
  82. package/examples/calculator/package.json +0 -1
  83. package/examples/dashboard/README.md +0 -17
  84. package/examples/dashboard/assets/AGENTS.md.append +0 -12
  85. package/examples/dashboard/assets/src/components/Header.tsx +0 -17
  86. package/examples/dashboard/assets/src/routes/__root.tsx +0 -57
  87. package/examples/dashboard/assets/src/routes/index.tsx +0 -158
  88. package/examples/dashboard/info.json +0 -19
  89. package/examples/dashboard/package.json +0 -6
  90. package/examples/ecommerce/README.md +0 -48
  91. package/examples/ecommerce/assets/AGENTS.md.append +0 -22
  92. package/examples/ecommerce/assets/public/logo.png +0 -0
  93. package/examples/ecommerce/assets/public/motorcycle-scooter.jpg +0 -0
  94. package/examples/ecommerce/assets/src/components/BuyButton.tsx +0 -35
  95. package/examples/ecommerce/assets/src/components/Header.tsx +0 -36
  96. package/examples/ecommerce/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
  97. package/examples/ecommerce/assets/src/components/MotorcycleRecommendation.tsx +0 -53
  98. package/examples/ecommerce/assets/src/data/motorcycles.ts +0 -27
  99. package/examples/ecommerce/assets/src/lib/motorcycle-ai-hook.ts +0 -24
  100. package/examples/ecommerce/assets/src/lib/motorcycle-tools.ts +0 -42
  101. package/examples/ecommerce/assets/src/lib/stripe.server.ts +0 -39
  102. package/examples/ecommerce/assets/src/routes/__root.tsx +0 -57
  103. package/examples/ecommerce/assets/src/routes/api.motorcycle-chat.ts +0 -78
  104. package/examples/ecommerce/assets/src/routes/checkout/cancel.tsx +0 -25
  105. package/examples/ecommerce/assets/src/routes/checkout/success.tsx +0 -25
  106. package/examples/ecommerce/assets/src/routes/index.tsx +0 -76
  107. package/examples/ecommerce/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -55
  108. package/examples/ecommerce/assets/src/store/motorcycle-assistant.ts +0 -3
  109. package/examples/ecommerce/assets/src/styles.css +0 -212
  110. package/examples/ecommerce/info.json +0 -38
  111. package/examples/ecommerce/package.json +0 -13
  112. package/examples/events/README.md +0 -110
  113. package/examples/events/assets/AGENTS.md.append +0 -21
  114. package/examples/events/assets/content/speakers/andre-costa.md +0 -22
  115. package/examples/events/assets/content/speakers/hans-mueller.md.ejs +0 -22
  116. package/examples/events/assets/content/speakers/isabella-martinez.md.ejs +0 -22
  117. package/examples/events/assets/content/speakers/kenji-nakamura.md.ejs +0 -22
  118. package/examples/events/assets/content/speakers/marie-dubois.md.ejs +0 -20
  119. package/examples/events/assets/content/speakers/priya-sharma.md.ejs +0 -22
  120. package/examples/events/assets/content/talks/croissant-lamination-secrets.md +0 -39
  121. package/examples/events/assets/content/talks/french-macaron-mastery.md.ejs +0 -39
  122. package/examples/events/assets/content/talks/neapolitan-pizza-tradition-meets-innovation.md.ejs +0 -39
  123. package/examples/events/assets/content/talks/savory-breads-of-the-mediterranean.md.ejs +0 -39
  124. package/examples/events/assets/content/talks/sourdough-from-starter-to-masterpiece.md.ejs +0 -36
  125. package/examples/events/assets/content/talks/the-art-of-the-perfect-tart.md.ejs +0 -32
  126. package/examples/events/assets/content/talks/the-science-of-sugar.md.ejs +0 -39
  127. package/examples/events/assets/content/talks/umami-in-pastry-east-meets-west.md.ejs +0 -39
  128. package/examples/events/assets/content-collections.ts +0 -56
  129. package/examples/events/assets/public/background-1.jpg +0 -0
  130. package/examples/events/assets/public/background-2.jpg +0 -0
  131. package/examples/events/assets/public/background-3.jpg +0 -0
  132. package/examples/events/assets/public/background-4.jpg +0 -0
  133. package/examples/events/assets/public/conference-logo.png +0 -0
  134. package/examples/events/assets/public/favicon.ico +0 -0
  135. package/examples/events/assets/public/speakers/andre-costa.jpg +0 -0
  136. package/examples/events/assets/public/speakers/hans-mueller.jpg +0 -0
  137. package/examples/events/assets/public/speakers/isabella-martinez.jpg +0 -0
  138. package/examples/events/assets/public/speakers/kenji-nakamura.jpg +0 -0
  139. package/examples/events/assets/public/speakers/marie-dubois.jpg +0 -0
  140. package/examples/events/assets/public/speakers/priya-sharma.jpg +0 -0
  141. package/examples/events/assets/public/talks/croissant-lamination-secrets.jpg +0 -0
  142. package/examples/events/assets/public/talks/french-macaron-mastery.jpg +0 -0
  143. package/examples/events/assets/public/talks/neapolitan-pizza-tradition-meets-innovation.jpg +0 -0
  144. package/examples/events/assets/public/talks/savory-breads-of-the-mediterranean.jpg +0 -0
  145. package/examples/events/assets/public/talks/sourdough-from-starter-to-masterpiece.jpg +0 -0
  146. package/examples/events/assets/public/talks/the-art-of-the-perfect-tart.jpg +0 -0
  147. package/examples/events/assets/public/talks/the-science-of-sugar.jpg +0 -0
  148. package/examples/events/assets/public/talks/umami-in-pastry-east-meets-west.jpg +0 -0
  149. package/examples/events/assets/public/tanstack-circle-logo.png +0 -0
  150. package/examples/events/assets/public/tanstack-word-logo-white.svg +0 -1
  151. package/examples/events/assets/src/components/Header.tsx +0 -59
  152. package/examples/events/assets/src/components/HeaderNav.tsx +0 -67
  153. package/examples/events/assets/src/components/HeroCarousel.tsx +0 -61
  154. package/examples/events/assets/src/components/RemyAssistant.tsx +0 -207
  155. package/examples/events/assets/src/components/SpeakerCard.tsx +0 -67
  156. package/examples/events/assets/src/components/TalkCard.tsx +0 -77
  157. package/examples/events/assets/src/components/ui/card.tsx +0 -92
  158. package/examples/events/assets/src/lib/conference-ai-hook.ts +0 -26
  159. package/examples/events/assets/src/lib/conference-tools.ts +0 -210
  160. package/examples/events/assets/src/lib/model-selection.ts +0 -1
  161. package/examples/events/assets/src/lib/utils.ts +0 -6
  162. package/examples/events/assets/src/routes/__root.tsx +0 -70
  163. package/examples/events/assets/src/routes/api.remy-chat.ts +0 -119
  164. package/examples/events/assets/src/routes/index.tsx +0 -192
  165. package/examples/events/assets/src/routes/schedule.index.tsx +0 -274
  166. package/examples/events/assets/src/routes/speakers.$slug.tsx +0 -122
  167. package/examples/events/assets/src/routes/speakers.index.tsx +0 -40
  168. package/examples/events/assets/src/routes/talks.$slug.tsx +0 -116
  169. package/examples/events/assets/src/routes/talks.index.tsx +0 -40
  170. package/examples/events/assets/src/styles.css +0 -182
  171. package/examples/events/info.json +0 -61
  172. package/examples/events/package.json +0 -23
  173. package/examples/marketing/README.md +0 -60
  174. package/examples/marketing/assets/AGENTS.md.append +0 -15
  175. package/examples/marketing/assets/public/logo.png +0 -0
  176. package/examples/marketing/assets/public/motorcycle-adventure.jpg +0 -0
  177. package/examples/marketing/assets/public/motorcycle-cruiser.jpg +0 -0
  178. package/examples/marketing/assets/public/motorcycle-scooter.jpg +0 -0
  179. package/examples/marketing/assets/public/motorcycle-sport.jpg +0 -0
  180. package/examples/marketing/assets/public/motorcycle-supersport.jpg +0 -0
  181. package/examples/marketing/assets/src/components/Header.tsx +0 -36
  182. package/examples/marketing/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
  183. package/examples/marketing/assets/src/components/MotorcycleRecommendation.tsx +0 -53
  184. package/examples/marketing/assets/src/data/motorcycles.ts.ejs +0 -77
  185. package/examples/marketing/assets/src/lib/motorcycle-ai-hook.ts +0 -24
  186. package/examples/marketing/assets/src/lib/motorcycle-tools.ts +0 -42
  187. package/examples/marketing/assets/src/routes/__root.tsx +0 -57
  188. package/examples/marketing/assets/src/routes/api.motorcycle-chat.ts +0 -78
  189. package/examples/marketing/assets/src/routes/index.tsx +0 -72
  190. package/examples/marketing/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -56
  191. package/examples/marketing/assets/src/store/motorcycle-assistant.ts +0 -3
  192. package/examples/marketing/assets/src/styles.css +0 -212
  193. package/examples/marketing/info.json +0 -33
  194. package/examples/marketing/package.json +0 -14
  195. package/examples/portfolio/README.md +0 -49
  196. package/examples/portfolio/assets/AGENTS.md.append +0 -21
  197. package/examples/portfolio/assets/content/blog/getting-started-with-tanstack.md +0 -53
  198. package/examples/portfolio/assets/content/blog/react-19-features.md +0 -78
  199. package/examples/portfolio/assets/content/blog/tailwind-css-v4-guide.md +0 -60
  200. package/examples/portfolio/assets/content/education/code-school.md +0 -17
  201. package/examples/portfolio/assets/content/jobs/initech-junior.md +0 -20
  202. package/examples/portfolio/assets/content/projects/portfolio-site.md +0 -15
  203. package/examples/portfolio/assets/content/projects/task-manager.md +0 -15
  204. package/examples/portfolio/assets/content-collections.ts +0 -65
  205. package/examples/portfolio/assets/public/contact.html +0 -6
  206. package/examples/portfolio/assets/public/headshot-on-white.jpg +0 -0
  207. package/examples/portfolio/assets/src/components/Header.tsx +0 -33
  208. package/examples/portfolio/assets/src/components/ResumeAssistant.tsx +0 -193
  209. package/examples/portfolio/assets/src/components/ui/badge.tsx +0 -46
  210. package/examples/portfolio/assets/src/components/ui/card.tsx +0 -92
  211. package/examples/portfolio/assets/src/components/ui/checkbox.tsx +0 -30
  212. package/examples/portfolio/assets/src/components/ui/hover-card.tsx +0 -44
  213. package/examples/portfolio/assets/src/components/ui/separator.tsx +0 -26
  214. package/examples/portfolio/assets/src/lib/resume-ai-hook.ts +0 -21
  215. package/examples/portfolio/assets/src/lib/resume-tools.ts +0 -165
  216. package/examples/portfolio/assets/src/lib/utils.ts +0 -6
  217. package/examples/portfolio/assets/src/routes/__root.tsx +0 -57
  218. package/examples/portfolio/assets/src/routes/api.resume-chat.ts +0 -116
  219. package/examples/portfolio/assets/src/routes/blog/$slug.tsx +0 -73
  220. package/examples/portfolio/assets/src/routes/contact.tsx +0 -121
  221. package/examples/portfolio/assets/src/routes/index.tsx +0 -55
  222. package/examples/portfolio/assets/src/routes/projects.tsx +0 -62
  223. package/examples/portfolio/assets/src/routes/resume.tsx +0 -220
  224. package/examples/portfolio/assets/src/styles.css +0 -138
  225. package/examples/portfolio/info.json +0 -50
  226. package/examples/portfolio/package.json +0 -26
  227. package/examples/resume/README.md +0 -82
  228. package/examples/resume/assets/AGENTS.md.append +0 -19
  229. package/examples/resume/assets/content/education/code-school.md +0 -17
  230. package/examples/resume/assets/content/jobs/freelance.md.ejs +0 -13
  231. package/examples/resume/assets/content/jobs/initech-junior.md +0 -20
  232. package/examples/resume/assets/content/jobs/initech-lead.md.ejs +0 -29
  233. package/examples/resume/assets/content/jobs/initrode-senior.md.ejs +0 -28
  234. package/examples/resume/assets/content-collections.ts +0 -36
  235. package/examples/resume/assets/public/headshot-on-white.jpg +0 -0
  236. package/examples/resume/assets/src/components/Header.tsx +0 -33
  237. package/examples/resume/assets/src/components/ResumeAssistant.tsx +0 -193
  238. package/examples/resume/assets/src/components/ui/badge.tsx +0 -46
  239. package/examples/resume/assets/src/components/ui/card.tsx +0 -92
  240. package/examples/resume/assets/src/components/ui/checkbox.tsx +0 -30
  241. package/examples/resume/assets/src/components/ui/hover-card.tsx +0 -44
  242. package/examples/resume/assets/src/components/ui/separator.tsx +0 -26
  243. package/examples/resume/assets/src/lib/resume-ai-hook.ts +0 -21
  244. package/examples/resume/assets/src/lib/resume-tools.ts +0 -165
  245. package/examples/resume/assets/src/lib/utils.ts +0 -6
  246. package/examples/resume/assets/src/routes/api.resume-chat.ts +0 -110
  247. package/examples/resume/assets/src/routes/index.tsx +0 -220
  248. package/examples/resume/assets/src/styles.css +0 -138
  249. package/examples/resume/info.json +0 -35
  250. package/examples/resume/package.json +0 -26
  251. package/examples/saas/README.md +0 -16
  252. package/examples/saas/assets/AGENTS.md.append +0 -9
  253. package/examples/saas/assets/src/components/Header.tsx +0 -17
  254. package/examples/saas/assets/src/routes/__root.tsx +0 -57
  255. package/examples/saas/assets/src/routes/faq.tsx +0 -94
  256. package/examples/saas/assets/src/routes/index.tsx +0 -197
  257. package/examples/saas/info.json +0 -23
  258. package/examples/saas/package.json +0 -1
  259. package/examples/survey/README.md +0 -20
  260. package/examples/survey/assets/AGENTS.md.append +0 -9
  261. package/examples/survey/assets/public/form-survey.html +0 -15
  262. package/examples/survey/assets/src/components/SurveyForm.tsx +0 -128
  263. package/examples/survey/assets/src/routes/index.tsx +0 -14
  264. package/examples/survey/info.json +0 -19
  265. package/examples/survey/package.json +0 -1
  266. package/project/base/AGENTS.md +0 -86
  267. package/project/base/_dot_claude/skills/content-collections/SKILL.md +0 -505
  268. package/project/base/_dot_claude/skills/netlify-blobs/SKILL.md +0 -410
  269. package/project/base/_dot_claude/skills/netlify-db/SKILL.md +0 -424
  270. package/project/base/_dot_claude/skills/netlify-debugging/SKILL.md +0 -419
  271. package/project/base/_dot_claude/skills/netlify-forms/SKILL.md +0 -243
  272. package/project/base/_dot_claude/skills/netlify-functions/SKILL.md +0 -372
  273. package/project/base/_dot_claude/skills/tanstack-start-api-routes/SKILL.md +0 -421
  274. package/project/base/_dot_claude/skills/tanstack-start-loaders/SKILL.md +0 -426
  275. package/project/base/_dot_claude/skills/tanstack-start-project-setup/SKILL.md +0 -493
  276. package/project/base/_dot_claude/skills/tanstack-start-routes/SKILL.md +0 -430
  277. package/project/base/_dot_claude/skills/tanstack-start-server-functions/SKILL.md +0 -445
  278. package/project/base/_dot_claude/skills/tanstack-start-typesafe-routing/SKILL.md +0 -494
  279. package/project/base/_dot_gitignore +0 -8
  280. package/project/base/netlify.toml +0 -7
  281. package/project/base/package.json +0 -33
  282. package/project/base/public/favicon.ico +0 -0
  283. package/project/base/public/tanstack-circle-logo.png +0 -0
  284. package/project/base/public/tanstack-word-logo-white.svg +0 -1
  285. package/project/base/src/components/Header.tsx +0 -17
  286. package/project/base/src/components/HeaderNav.tsx.ejs +0 -179
  287. package/project/base/src/router.tsx +0 -15
  288. package/project/base/src/routes/__root.tsx +0 -57
  289. package/project/base/src/routes/index.tsx +0 -48
  290. package/project/base/src/styles.css +0 -15
  291. package/project/base/tsconfig.json +0 -28
  292. package/project/base/vite.config.ts.ejs +0 -25
  293. package/project/info.json +0 -17
  294. package/project/packages.json +0 -22
  295. package/scripts/check-outdated-packages.js +0 -421
  296. package/src/agents-md.ts +0 -139
@@ -1,22 +0,0 @@
1
- {
2
- "name": "AI Chat",
3
- "phase": "add-on",
4
- "description": "Add AI chat capabilities with multi-vendor support (OpenAI, Anthropic, Gemini, Ollama). Includes a chat page and pop-up assistant.",
5
- "link": "https://tanstack.com/ai",
6
- "modes": ["file-router"],
7
- "type": "add-on",
8
- "priority": 20,
9
- "routes": [{"icon": "MessagesSquare", "url": "/chat", "name": "Chat", "path": "src/routes/chat.tsx", "jsName": "ChatPage"}],
10
- "features": ["tanstack-ai"],
11
- "integrations": [{"type": "header-user", "path": "src/components/AIAssistant.tsx", "jsName": "AIAssistant"}],
12
- "dependsOn": [],
13
- "variables": [],
14
- "packageFileDescriptions": {
15
- "src/lib/ai-hook.ts": "useAIChat hook: useChat with fetchServerSentEvents connection to /api/chat.",
16
- "src/routes/chat.tsx": "Chat page route (/chat): Weather Chat UI with messages, input form, send/stop.",
17
- "src/routes/api.chat.ts": "POST handler for /api/chat: multi-provider AI (Anthropic, OpenAI, Gemini, Ollama) with getWeather tool and SSE streaming.",
18
- "src/lib/weather-tools.ts": "TanStack AI getWeather tool definition; server returns mock temperature, condition, humidity for a city.",
19
- "src/routes/chat.css": "Chat page styles: prose/markdown, scrollbar, message animations.",
20
- "src/components/AIAssistant.tsx": "Pop-up AI assistant component for header; toggleable chat panel with useAIChat."
21
- }
22
- }
@@ -1,17 +0,0 @@
1
- {
2
- "dependencies": {
3
- "@tanstack/ai": "0.2.2",
4
- "@tanstack/ai-anthropic": "0.2.0",
5
- "@tanstack/ai-client": "0.2.2",
6
- "@tanstack/ai-gemini": "0.3.2",
7
- "@tanstack/ai-ollama": "0.3.0",
8
- "@tanstack/ai-openai": "0.3.0",
9
- "@tanstack/ai-react": "0.2.2",
10
- "@tanstack/react-store": "^0.8.0",
11
- "@tanstack/store": "^0.8.0",
12
- "highlight.js": "^11.11.1",
13
- "streamdown": "^2.1.0",
14
- "lucide-react": "^0.563.0",
15
- "zod": "^4.3.5"
16
- }
17
- }
@@ -1,8 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2
- <path d="M12 8V4H8"/>
3
- <rect width="16" height="12" x="4" y="8" rx="2"/>
4
- <path d="M2 14h2"/>
5
- <path d="M20 14h2"/>
6
- <path d="M15 13v2"/>
7
- <path d="M9 13v2"/>
8
- </svg>
@@ -1,22 +0,0 @@
1
- ### Netlify DB Integration
2
-
3
- Guestbook demo powered by Netlify DB (Neon Postgres) with Drizzle ORM.
4
-
5
- **Setup:**
6
- 1. Link project: `netlify login` then `netlify init`
7
- 2. Provision database: `netlify db init` (creates Neon Postgres, sets `DATABASE_URL`)
8
- 3. Push schema: `npx drizzle-kit push` (creates `guestbook` table from `src/db/schema.ts`)
9
- 4. Run locally: `netlify dev` (visit `/db-example`)
10
-
11
- **Key files:**
12
- - `src/db/schema.ts` - Guestbook table (id, name, message, createdAt)
13
- - `src/server/guestbook.functions.ts` - Server functions: `getEntries`, `addEntry`
14
- - `drizzle.config.ts` - Drizzle Kit config for migrations
15
-
16
- **Dependencies:** drizzle-orm, @neondatabase/serverless, drizzle-kit
17
-
18
- ## Environment Variables
19
-
20
- ```
21
- DATABASE_URL=... # Auto-set by netlify db init; pull with netlify env:pull
22
- ```
@@ -1,65 +0,0 @@
1
- # Netlify DB Setup
2
-
3
- After scaffolding your project with the DB add-on, follow these steps to get Netlify DB running.
4
-
5
- ## Prerequisites
6
-
7
- - A [Netlify](https://www.netlify.com/) account
8
- - The [Netlify CLI](https://docs.netlify.com/cli/get-started/) installed (`npm install -g netlify-cli`)
9
-
10
- ## 1. Link Your Project to Netlify
11
-
12
- If you haven't already, link your local project to a Netlify site:
13
-
14
- ```sh
15
- netlify login
16
- netlify init
17
- ```
18
-
19
- Follow the prompts to create a new site or link to an existing one.
20
-
21
- ## 2. Initialize the Database
22
-
23
- Run the Netlify DB initialization command to provision a Postgres database for your site:
24
-
25
- ```sh
26
- netlify db init
27
- ```
28
-
29
- This creates a Neon Postgres database attached to your Netlify site and sets the `DATABASE_URL` environment variable automatically.
30
-
31
- ## 3. Push the Schema to the Database
32
-
33
- Use Drizzle Kit to push your schema to the database:
34
-
35
- ```sh
36
- npx drizzle-kit push
37
- ```
38
-
39
- This creates the `guestbook` table defined in `src/db/schema.ts`.
40
-
41
- ## 4. Run the Dev Server
42
-
43
- Start local development via the Netlify CLI:
44
-
45
- ```sh
46
- netlify dev
47
- ```
48
-
49
- Then visit [http://localhost:8888/db-example](http://localhost:8888/db-example) to see the guestbook demo.
50
-
51
- ## 5. Deploy
52
-
53
- When you're ready, deploy to Netlify:
54
-
55
- ```sh
56
- netlify deploy --build --prod
57
- ```
58
-
59
- Or push to your git remote and Netlify will build and deploy automatically if continuous deployment is configured.
60
-
61
- ## Troubleshooting
62
-
63
- - **`DATABASE_URL` not set** — Make sure you've run `netlify db:init` and `netlify env:pull`.
64
- - **Table not found errors** — Run `npx drizzle-kit push` to ensure the schema is applied.
65
- - **Connection errors locally** — Confirm `.env.local` has the correct `DATABASE_URL` and that your IP is not blocked by the Neon project settings.
@@ -1,2 +0,0 @@
1
- # Netlify DB - run `netlify db:init` to set up your database
2
- # DATABASE_URL is automatically set by Netlify after initialization
@@ -1,10 +0,0 @@
1
- import { defineConfig } from "drizzle-kit";
2
-
3
- export default defineConfig({
4
- schema: "./src/db/schema.ts",
5
- out: "./drizzle",
6
- dialect: "postgresql",
7
- dbCredentials: {
8
- url: process.env.DATABASE_URL!,
9
- },
10
- });
@@ -1,8 +0,0 @@
1
- import { drizzle } from "drizzle-orm/neon-http";
2
- import { neon } from "@neondatabase/serverless";
3
- import * as schema from "./schema";
4
-
5
- const sql = neon(process.env.DATABASE_URL!);
6
- export const db = drizzle(sql, { schema });
7
-
8
- export { schema };
@@ -1,8 +0,0 @@
1
- import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
2
-
3
- export const guestbook = pgTable("guestbook", {
4
- id: serial("id").primaryKey(),
5
- name: text("name").notNull(),
6
- message: text("message").notNull(),
7
- createdAt: timestamp("created_at").defaultNow().notNull(),
8
- });
@@ -1,118 +0,0 @@
1
- import { createFileRoute } from "@tanstack/react-router";
2
- import { useRouter } from "@tanstack/react-router";
3
- import { useState } from "react";
4
- import { getEntries, addEntry } from "@/server/guestbook.functions";
5
-
6
- export const Route = createFileRoute("/db-example")({
7
- loader: async () => {
8
- const entries = await getEntries();
9
- return { entries };
10
- },
11
- component: DBExample,
12
- });
13
-
14
- function DBExample() {
15
- const { entries } = Route.useLoaderData();
16
- const router = useRouter();
17
- const [isSubmitting, setIsSubmitting] = useState(false);
18
-
19
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
20
- e.preventDefault();
21
- const form = e.currentTarget;
22
- setIsSubmitting(true);
23
-
24
- const formData = new FormData(form);
25
- const name = formData.get("name") as string;
26
- const message = formData.get("message") as string;
27
-
28
- try {
29
- await addEntry({ data: { name, message } });
30
- form.reset();
31
- await router.invalidate();
32
- } catch (error) {
33
- console.error("Failed to add entry:", error);
34
- } finally {
35
- setIsSubmitting(false);
36
- }
37
- };
38
-
39
- return (
40
- <div className="min-h-screen bg-linear-to-br from-teal-900 via-emerald-800 to-cyan-900 flex items-center justify-center">
41
- <div className="w-full max-w-lg px-4 py-12">
42
- <h1 className="text-4xl md:text-5xl font-black text-white mb-2 tracking-tight">
43
- Guestbook
44
- </h1>
45
- <p className="text-teal-100/80 mb-8">
46
- Sign the guestbook — powered by Netlify DB with Drizzle ORM.
47
- </p>
48
-
49
- <form onSubmit={handleSubmit} className="space-y-6 mb-12">
50
- <div>
51
- <label
52
- htmlFor="name"
53
- className="block text-sm font-medium text-teal-200 mb-2"
54
- >
55
- Name
56
- </label>
57
- <input
58
- type="text"
59
- id="name"
60
- name="name"
61
- required
62
- className="w-full px-4 py-3 rounded-lg bg-white/10 border border-white/20 text-white placeholder-teal-300/50 focus:outline-none focus:ring-2 focus:ring-teal-400 focus:border-transparent"
63
- placeholder="Your name"
64
- />
65
- </div>
66
-
67
- <div>
68
- <label
69
- htmlFor="message"
70
- className="block text-sm font-medium text-teal-200 mb-2"
71
- >
72
- Message
73
- </label>
74
- <textarea
75
- id="message"
76
- name="message"
77
- required
78
- rows={3}
79
- className="w-full px-4 py-3 rounded-lg bg-white/10 border border-white/20 text-white placeholder-teal-300/50 focus:outline-none focus:ring-2 focus:ring-teal-400 focus:border-transparent resize-none"
80
- placeholder="Leave a message..."
81
- />
82
- </div>
83
-
84
- <button
85
- type="submit"
86
- disabled={isSubmitting}
87
- className="w-full px-8 py-3 bg-teal-500 hover:bg-teal-600 disabled:bg-teal-500/50 text-white font-semibold rounded-lg transition-colors shadow-lg shadow-teal-500/30"
88
- >
89
- {isSubmitting ? "Signing..." : "Sign Guestbook"}
90
- </button>
91
- </form>
92
-
93
- <div className="space-y-4">
94
- <h2 className="text-xl font-bold text-white">
95
- {entries.length === 0
96
- ? "No entries yet — be the first!"
97
- : `${entries.length} ${entries.length === 1 ? "entry" : "entries"}`}
98
- </h2>
99
-
100
- {entries.map((entry) => (
101
- <div
102
- key={entry.id}
103
- className="rounded-lg bg-white/10 border border-white/10 p-4"
104
- >
105
- <div className="flex items-baseline justify-between mb-1">
106
- <span className="font-semibold text-white">{entry.name}</span>
107
- <span className="text-xs text-teal-300/60">
108
- {new Date(entry.createdAt).toLocaleDateString()}
109
- </span>
110
- </div>
111
- <p className="text-teal-100/80 text-sm">{entry.message}</p>
112
- </div>
113
- ))}
114
- </div>
115
- </div>
116
- </div>
117
- );
118
- }
@@ -1,23 +0,0 @@
1
- import { createServerFn } from "@tanstack/react-start";
2
- import { db, schema } from "@/db";
3
- import { desc } from "drizzle-orm";
4
-
5
- export const getEntries = createServerFn({ method: "POST" }).handler(
6
- async () => {
7
- const entries = await db
8
- .select()
9
- .from(schema.guestbook)
10
- .orderBy(desc(schema.guestbook.createdAt));
11
- return entries;
12
- }
13
- );
14
-
15
- export const addEntry = createServerFn({ method: "POST" })
16
- .inputValidator((data: { name: string; message: string }) => data)
17
- .handler(async ({ data }) => {
18
- const result = await db
19
- .insert(schema.guestbook)
20
- .values({ name: data.name, message: data.message })
21
- .returning();
22
- return result[0];
23
- });
@@ -1,22 +0,0 @@
1
- {
2
- "name": "Netlify DB",
3
- "phase": "add-on",
4
- "description": "Add a guestbook demo powered by Netlify DB (Postgres) with Drizzle ORM. Demonstrates full CRUD with a serverless database.",
5
- "link": "https://docs.netlify.com/database/overview/",
6
- "modes": ["file-router"],
7
- "type": "add-on",
8
- "priority": 20,
9
- "routes": [{"icon": "Database", "url": "/db-example", "name": "DB Example", "path": "src/routes/db-example.tsx", "jsName": "DBExample"}],
10
- "features": ["netlify-db"],
11
- "integrations": [],
12
- "dependsOn": [],
13
- "variables": [],
14
- "packageFileDescriptions": {
15
- "DB-SETUP.md": "Setup guide: link to Netlify, run netlify db init, configure DATABASE_URL.",
16
- "src/routes/db-example.tsx": "Guestbook route (/db-example): form to add entries, list from getEntries/addEntry.",
17
- "src/server/guestbook.functions.ts": "Server functions: getEntries (list), addEntry (create) for guestbook via Drizzle.",
18
- "src/db/index.ts": "Drizzle + Neon client; exports db and schema.",
19
- "src/db/schema.ts": "Guestbook table schema: id, name, message, createdAt.",
20
- "drizzle.config.ts": "Drizzle Kit config for migrations; postgres, schema path, DATABASE_URL."
21
- }
22
- }
@@ -1,10 +0,0 @@
1
- {
2
- "dependencies": {
3
- "drizzle-orm": "^0.44.0",
4
- "@neondatabase/serverless": "^1.0.0",
5
- "@netlify/neon": "^0.1.2"
6
- },
7
- "devDependencies": {
8
- "drizzle-kit": "^0.31.0"
9
- }
10
- }
@@ -1,13 +0,0 @@
1
- ### Netlify Forms Integration
2
-
3
- Signup form powered by Netlify Forms with honeypot spam protection. No server-side code required.
4
-
5
- **How it works:**
6
- - Form submissions are handled by Netlify at build/deploy
7
- - Add `data-netlify="true"` to the form
8
- - Spam protection: `netlify-honeypot="bot-field"` + hidden input with `name="bot-field"`
9
- - `public/form-example.html` declares the form (hidden) so Netlify detects it during build
10
-
11
- **Route:** `/form-example` - Signup form (name, email)
12
-
13
- No environment variables required. Works after deploy to Netlify.
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <title>Form</title>
6
- </head>
7
- <body>
8
- <form name="signup" method="POST" data-netlify="true" netlify-honeypot="bot-field" hidden>
9
- <input type="text" name="name" />
10
- <input type="email" name="email" />
11
- <input name="bot-field" />
12
- </form>
13
- </body>
14
- </html>
@@ -1,76 +0,0 @@
1
- import { createFileRoute } from '@tanstack/react-router'
2
-
3
- export const Route = createFileRoute('/form-example')({
4
- component: FormExample,
5
- })
6
-
7
- function FormExample() {
8
- return (
9
- <div className="min-h-screen bg-linear-to-br from-teal-900 via-emerald-800 to-cyan-900 flex items-center justify-center">
10
- <div className="w-full max-w-md px-4">
11
- <h1 className="text-4xl md:text-5xl font-black text-white mb-2 tracking-tight">
12
- Sign up
13
- </h1>
14
- <p className="text-teal-100/80 mb-8">
15
- Enter your name and email to get started.
16
- </p>
17
-
18
- <form
19
- name="signup"
20
- method="POST"
21
- data-netlify="true"
22
- netlify-honeypot="bot-field"
23
- className="space-y-6"
24
- >
25
- <input type="hidden" name="form-name" value="signup" />
26
- <p className="hidden" style={{ display: 'none' }}>
27
- <label>
28
- Don&apos;t fill this out: <input name="bot-field" />
29
- </label>
30
- </p>
31
-
32
- <div>
33
- <label
34
- htmlFor="name"
35
- className="block text-sm font-medium text-teal-200 mb-2"
36
- >
37
- Name
38
- </label>
39
- <input
40
- type="text"
41
- id="name"
42
- name="name"
43
- required
44
- className="w-full px-4 py-3 rounded-lg bg-white/10 border border-white/20 text-white placeholder-teal-300/50 focus:outline-none focus:ring-2 focus:ring-teal-400 focus:border-transparent"
45
- placeholder="Your name"
46
- />
47
- </div>
48
-
49
- <div>
50
- <label
51
- htmlFor="email"
52
- className="block text-sm font-medium text-teal-200 mb-2"
53
- >
54
- Email
55
- </label>
56
- <input
57
- type="email"
58
- id="email"
59
- name="email"
60
- required
61
- className="w-full px-4 py-3 rounded-lg bg-white/10 border border-white/20 text-white placeholder-teal-300/50 focus:outline-none focus:ring-2 focus:ring-teal-400 focus:border-transparent"
62
- placeholder="you@example.com"
63
- />
64
- </div>
65
-
66
- <button
67
- type="submit"
68
- className="w-full px-8 py-3 bg-teal-500 hover:bg-teal-600 text-white font-semibold rounded-lg transition-colors shadow-lg shadow-teal-500/30"
69
- >
70
- Submit
71
- </button>
72
- </form>
73
- </div>
74
- </div>
75
- )
76
- }
@@ -1,18 +0,0 @@
1
- {
2
- "name": "Netlify Forms",
3
- "phase": "add-on",
4
- "description": "Add a signup form powered by Netlify Forms with spam protection via honeypot field. No server-side code required.",
5
- "link": "https://docs.netlify.com/forms/setup/",
6
- "modes": ["file-router"],
7
- "type": "add-on",
8
- "priority": 20,
9
- "routes": [{"icon": "FormInput", "url": "/form-example", "name": "Form Example", "path": "src/routes/form-example.tsx", "jsName": "FormExample"}],
10
- "features": ["netlify-forms"],
11
- "integrations": [],
12
- "dependsOn": [],
13
- "variables": [],
14
- "packageFileDescriptions": {
15
- "src/routes/form-example.tsx": "Form example route (/form-example): Netlify Forms signup with honeypot spam protection.",
16
- "public/form-example.html": "Static HTML form declaration for Netlify Forms; name, email, bot-field."
17
- }
18
- }
@@ -1,3 +0,0 @@
1
- {
2
- "dependencies": {}
3
- }
@@ -1,36 +0,0 @@
1
- # AI Chat Example
2
-
3
- A weather chat assistant built with TanStack Start and TanStack AI for Netlify deployment.
4
-
5
- ## Features
6
-
7
- - **AI Chat Interface**: Conversational weather assistant with streaming responses
8
- - **Multi-Provider Support**: Works with Anthropic, OpenAI, Gemini, or Ollama
9
- - **Tool Calling**: AI uses a getWeather tool to fetch weather data
10
- - **Markdown Rendering**: Rich message formatting with syntax highlighting
11
-
12
- ## Project Structure
13
-
14
- ```
15
- ├── src/
16
- │ ├── lib/
17
- │ │ ├── ai-hook.ts # Chat hook setup
18
- │ │ └── weather-tools.ts # Weather tool definition
19
- │ └── routes/
20
- │ ├── __root.tsx # Root layout
21
- │ ├── index.tsx # Chat UI
22
- │ └── api.chat.ts # Chat API endpoint
23
- ```
24
-
25
- ## Development
26
-
27
- ```bash
28
- npm run dev
29
- ```
30
-
31
- Set one of these environment variables to use a cloud provider:
32
- - `ANTHROPIC_API_KEY`
33
- - `OPENAI_API_KEY`
34
- - `GEMINI_API_KEY`
35
-
36
- Falls back to Ollama (local) if no API key is set.
@@ -1,24 +0,0 @@
1
- ### AI Integration
2
-
3
- Multi-provider AI chat with fallback chain:
4
-
5
- 1. Anthropic Claude (preferred)
6
- 2. OpenAI GPT-4o
7
- 3. Google Gemini
8
- 4. Ollama (local)
9
-
10
- **Tools available to AI:**
11
- - `getWeather` - Get the current weather for a city. Returns temperature, condition, and humidity.
12
-
13
- ## Environment Variables
14
-
15
- For AI functionality, set one or more:
16
-
17
- ```
18
- ANTHROPIC_API_KEY=...
19
- OPENAI_API_KEY=...
20
- GOOGLE_GENERATIVE_AI_API_KEY=...
21
- OLLAMA_BASE_URL=...
22
- ```
23
-
24
- The application uses the first available provider in the fallback chain.
@@ -1,21 +0,0 @@
1
- import {
2
- fetchServerSentEvents,
3
- useChat,
4
- createChatClientOptions,
5
- } from '@tanstack/ai-react'
6
- import type { InferChatMessages } from '@tanstack/ai-react'
7
-
8
- // Default chat options for simple usage
9
- const defaultChatOptions = createChatClientOptions({
10
- connection: fetchServerSentEvents('/api/chat'),
11
- })
12
-
13
- export type ChatMessages = InferChatMessages<typeof defaultChatOptions>
14
-
15
- export const useAIChat = () => {
16
- const chatOptions = createChatClientOptions({
17
- connection: fetchServerSentEvents('/api/chat'),
18
- })
19
-
20
- return useChat(chatOptions)
21
- }
@@ -1,30 +0,0 @@
1
- import { toolDefinition } from '@tanstack/ai'
2
- import { z } from 'zod'
3
-
4
- // Tool definition for getting weather
5
- export const getWeatherToolDef = toolDefinition({
6
- name: 'getWeather',
7
- description:
8
- 'Get the current weather for a city. Returns temperature, condition, and humidity.',
9
- inputSchema: z.object({
10
- city: z.string().describe('The city to get weather for'),
11
- }),
12
- outputSchema: z.object({
13
- city: z.string(),
14
- temperature: z.number(),
15
- condition: z.string(),
16
- humidity: z.number(),
17
- }),
18
- })
19
-
20
- // Server implementation - mock weather data
21
- export const getWeather = getWeatherToolDef.server(({ city }) => {
22
- // Mock weather data - in a real app, call a weather API
23
- const conditions = ['sunny', 'cloudy', 'rainy', 'partly cloudy', 'windy']
24
- return {
25
- city,
26
- temperature: Math.floor(Math.random() * 30) + 5,
27
- condition: conditions[Math.floor(Math.random() * conditions.length)],
28
- humidity: Math.floor(Math.random() * 50) + 30,
29
- }
30
- })
@@ -1,57 +0,0 @@
1
- import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'
2
- import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
3
- import { TanStackDevtools } from '@tanstack/react-devtools'
4
-
5
- import appCss from '../styles.css?url'
6
-
7
- export const Route = createRootRoute({
8
- head: () => ({
9
- meta: [
10
- {
11
- charSet: 'utf-8',
12
- },
13
- {
14
- name: 'viewport',
15
- content: 'width=device-width, initial-scale=1',
16
- },
17
- {
18
- title: 'Weather Chat',
19
- },
20
- ],
21
- links: [
22
- {
23
- rel: 'stylesheet',
24
- href: appCss,
25
- },
26
- ],
27
- }),
28
- shellComponent: RootDocument,
29
- })
30
-
31
- function RootDocument({ children }: { children: React.ReactNode }) {
32
- return (
33
- <html lang="en">
34
- <head>
35
- <HeadContent />
36
- </head>
37
- <body>
38
- <header className="p-4 flex items-center justify-between bg-gray-800 text-white shadow-lg">
39
- <h1 className="text-xl font-semibold">Weather Chat</h1>
40
- </header>
41
- {children}
42
- <TanStackDevtools
43
- config={{
44
- position: 'bottom-right',
45
- }}
46
- plugins={[
47
- {
48
- name: 'Tanstack Router',
49
- render: <TanStackRouterDevtoolsPanel />,
50
- },
51
- ]}
52
- />
53
- <Scripts />
54
- </body>
55
- </html>
56
- )
57
- }