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,77 +0,0 @@
1
- export interface Motorcycle {
2
- id: number;
3
- name: string;
4
- image: string;
5
- description: string;
6
- shortDescription: string;
7
- price: number;
8
- engineSize: number; // in CCs
9
- type: "scooter" | "cruiser" | "adventure" | "sport" | "supersport";
10
- }
11
-
12
- const motorcycles: Array<Motorcycle> = [
13
- {
14
- id: 1,
15
- name: "Luna-C Urbanite",
16
- image: "/motorcycle-scooter.jpg",
17
- description:
18
- "The Luna-C Urbanite is the perfect city companion, combining style and practicality in a compact package. With its 125cc engine, it delivers excellent fuel efficiency while maintaining enough power for urban commuting. The comfortable seating position and lightweight frame make it easy to maneuver through city traffic, while the under-seat storage provides ample space for your daily essentials.",
19
- shortDescription:
20
- "A stylish and practical 125cc scooter perfect for urban commuting with excellent fuel efficiency.",
21
- price: 3000,
22
- engineSize: 125,
23
- type: "scooter",
24
- },
25
- <% if (!addOnOption.project?.bareBones) { %>
26
- {
27
- id: 2,
28
- name: "Luna-C Voyager",
29
- image: "/motorcycle-cruiser.jpg",
30
- description:
31
- "The Luna-C Voyager is a classic cruiser that combines comfort with style. Its 750cc engine provides smooth, reliable power for long-distance rides, while the ergonomic design ensures comfort even on extended journeys. The classic cruiser styling with modern touches makes it stand out on any road.",
32
- shortDescription:
33
- "A comfortable 750cc cruiser perfect for long-distance rides with classic styling.",
34
- price: 12000,
35
- engineSize: 750,
36
- type: "cruiser",
37
- },
38
- {
39
- id: 3,
40
- name: "Luna-C Explorer",
41
- image: "/motorcycle-adventure.jpg",
42
- description:
43
- "The Luna-C Explorer is built for adventure, whether you're tackling city streets or exploring off-road trails. Its 850cc engine provides the perfect balance of power and control, while the dual-sport suspension system ensures a smooth ride in any condition. The upright riding position and comfortable seat make it ideal for long journeys.",
44
- shortDescription:
45
- "An 850cc adventure bike designed for both on-road and off-road exploration.",
46
- price: 15000,
47
- engineSize: 850,
48
- type: "adventure",
49
- },
50
- {
51
- id: 4,
52
- name: "Luna-C Velocity",
53
- image: "/motorcycle-sport.jpg",
54
- description:
55
- "The Luna-C Velocity is a high-performance sport bike that delivers thrilling acceleration and precise handling. Its 1000cc engine provides exceptional power, while the aerodynamic design and advanced suspension system ensure optimal performance on the track or the open road. The aggressive styling and premium components make it a true performance machine.",
56
- shortDescription:
57
- "A high-performance 1000cc sport bike with exceptional power and handling.",
58
- price: 20000,
59
- engineSize: 1000,
60
- type: "sport",
61
- },
62
- {
63
- id: 5,
64
- name: "Luna-C Supersport",
65
- image: "/motorcycle-supersport.jpg",
66
- description:
67
- "The Luna-C Supersport represents the pinnacle of motorcycle engineering. Its 1300cc engine delivers breathtaking power and acceleration, while the cutting-edge aerodynamics and race-inspired components ensure maximum performance. This machine is designed for experienced riders who demand the ultimate in speed and handling.",
68
- shortDescription:
69
- "The ultimate 1300cc supersport machine with race-inspired performance and aerodynamics.",
70
- price: 25000,
71
- engineSize: 1300,
72
- type: "supersport",
73
- },
74
- <% } %>
75
- ];
76
-
77
- export default motorcycles;
@@ -1,24 +0,0 @@
1
- import {
2
- fetchServerSentEvents,
3
- useChat,
4
- createChatClientOptions,
5
- } from "@tanstack/ai-react";
6
- import type { InferChatMessages } from "@tanstack/ai-react";
7
- import { clientTools } from "@tanstack/ai-client";
8
-
9
- import { recommendMotorcycleToolDef } from "@/lib/motorcycle-tools";
10
-
11
- const recommendMotorcycleToolClient = recommendMotorcycleToolDef.client(
12
- ({ id }) => ({
13
- id: +id,
14
- })
15
- );
16
-
17
- const chatOptions = createChatClientOptions({
18
- connection: fetchServerSentEvents("/api/motorcycle-chat"),
19
- tools: clientTools(recommendMotorcycleToolClient),
20
- });
21
-
22
- export type ChatMessages = InferChatMessages<typeof chatOptions>;
23
-
24
- export const useMotorcycleChat = () => useChat(chatOptions);
@@ -1,42 +0,0 @@
1
- import { toolDefinition } from "@tanstack/ai";
2
- import { z } from "zod";
3
- import motorcycles from "@/data/motorcycles";
4
-
5
- // Tool definition for getting motorcycles
6
- export const getMotorcyclesToolDef = toolDefinition({
7
- name: "getMotorcycles",
8
- description: "Get all motorcycles from the database",
9
- inputSchema: z.object({}),
10
- outputSchema: z.array(
11
- z.object({
12
- id: z.number(),
13
- name: z.string(),
14
- image: z.string(),
15
- description: z.string(),
16
- shortDescription: z.string(),
17
- price: z.number(),
18
- engineSize: z.number(),
19
- type: z.enum(["scooter", "cruiser", "adventure", "sport", "supersport"]),
20
- })
21
- ),
22
- });
23
-
24
- // Server implementation
25
- export const getMotorcycles = getMotorcyclesToolDef.server(() => motorcycles);
26
-
27
- // Tool definition for motorcycle recommendation
28
- export const recommendMotorcycleToolDef = toolDefinition({
29
- name: "recommendMotorcycle",
30
- description:
31
- "REQUIRED tool to display a motorcycle recommendation to the user. This tool MUST be used whenever recommending a motorcycle - do NOT write recommendations yourself. This displays the motorcycle in a special appealing format with a view details button.",
32
- inputSchema: z.object({
33
- id: z
34
- .union([z.string(), z.number()])
35
- .describe(
36
- "The ID of the motorcycle to recommend (from the getMotorcycles results)"
37
- ),
38
- }),
39
- outputSchema: z.object({
40
- id: z.number(),
41
- }),
42
- });
@@ -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 Header from '@/components/Header'
6
-
7
- import appCss from '@/styles.css?url'
8
-
9
- export const Route = createRootRoute({
10
- head: () => ({
11
- meta: [
12
- {
13
- charSet: 'utf-8',
14
- },
15
- {
16
- name: 'viewport',
17
- content: 'width=device-width, initial-scale=1',
18
- },
19
- {
20
- title: 'Luna-C Motorcycles',
21
- },
22
- ],
23
- links: [
24
- {
25
- rel: 'stylesheet',
26
- href: appCss,
27
- },
28
- ],
29
- }),
30
- shellComponent: RootDocument,
31
- })
32
-
33
- function RootDocument({ children }: { children: React.ReactNode }) {
34
- return (
35
- <html lang="en">
36
- <head>
37
- <HeadContent />
38
- </head>
39
- <body className="bg-black">
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
- }
@@ -1,78 +0,0 @@
1
- import { createFileRoute } from "@tanstack/react-router";
2
- import { chat, maxIterations, toServerSentEventsResponse } from "@tanstack/ai";
3
- import { anthropicText } from "@tanstack/ai-anthropic";
4
-
5
- import {
6
- getMotorcycles,
7
- recommendMotorcycleToolDef,
8
- } from "@/lib/motorcycle-tools";
9
-
10
- const SYSTEM_PROMPT = `You are a helpful assistant for a store that sells motorcycles.
11
-
12
- You are also a motorcycle enthusiast who is passionate about our products and how they can bring joy to people's lives, the excitement of the open road and adventure. Emphasize these aspects in your responses.
13
-
14
- CRITICAL INSTRUCTIONS - YOU MUST FOLLOW THIS EXACT WORKFLOW:
15
-
16
- When a user asks for a motorcycle recommendation:
17
- 1. FIRST: Use the getMotorcycles tool (no parameters needed)
18
- 2. SECOND: Use the recommendMotorcycle tool with the ID of the motorcycle you want to recommend
19
- 3. NEVER write a recommendation directly - ALWAYS use the recommendMotorcycle tool
20
-
21
- IMPORTANT:
22
- - The recommendMotorcycle tool will display the motorcycle in a special, appealing format
23
- - You MUST use recommendMotorcycle for ANY motorcycle recommendation
24
- - ONLY recommend motorcycles from our inventory (use getMotorcycles first)
25
- - The recommendMotorcycle tool has a view details button - this is how customers can learn more
26
- - Do NOT describe the motorcycle yourself - let the recommendMotorcycle tool do it
27
- `;
28
-
29
- export const Route = createFileRoute("/api/motorcycle-chat")({
30
- server: {
31
- handlers: {
32
- POST: async ({ request }) => {
33
- // Capture request signal before reading body (it may be aborted after body is consumed)
34
- const requestSignal = request.signal;
35
-
36
- // If request is already aborted, return early
37
- if (requestSignal.aborted) {
38
- return new Response(null, { status: 499 }); // 499 = Client Closed Request
39
- }
40
-
41
- const abortController = new AbortController();
42
-
43
- try {
44
- const body = await request.json();
45
- const { messages } = body;
46
-
47
- const adapter = anthropicText("claude-haiku-4-5");
48
-
49
- const stream = chat({
50
- adapter,
51
- tools: [
52
- getMotorcycles, // Server tool
53
- recommendMotorcycleToolDef, // No server execute - client will handle
54
- ],
55
- systemPrompts: [SYSTEM_PROMPT],
56
- agentLoopStrategy: maxIterations(5),
57
- messages,
58
- abortController,
59
- });
60
-
61
- return toServerSentEventsResponse(stream, { abortController });
62
- } catch (error: any) {
63
- // If request was aborted, return early (don't send error response)
64
- if (error.name === "AbortError" || abortController.signal.aborted) {
65
- return new Response(null, { status: 499 }); // 499 = Client Closed Request
66
- }
67
- return new Response(
68
- JSON.stringify({ error: "Failed to process chat request" }),
69
- {
70
- status: 500,
71
- headers: { "Content-Type": "application/json" },
72
- }
73
- );
74
- }
75
- },
76
- },
77
- },
78
- });
@@ -1,72 +0,0 @@
1
- import { Link, createFileRoute } from '@tanstack/react-router'
2
- import motorcycles from '@/data/motorcycles'
3
-
4
- export const Route = createFileRoute('/')({
5
- component: MotorcyclesIndex,
6
- })
7
-
8
- function MotorcyclesIndex() {
9
- return (
10
- <div className="bg-black text-white p-5">
11
- <h1 className="text-3xl font-bold mb-16 text-center">
12
- Luna-C Motorcycles
13
- </h1>
14
- <div className="max-w-7xl mx-auto">
15
- {motorcycles.map((motorcycle, index) => (
16
- <div
17
- key={motorcycle.id}
18
- className={`relative flex flex-col md:flex-row items-stretch gap-8 mb-32 ${
19
- index % 2 === 1 ? 'md:flex-row-reverse' : ''
20
- }`}
21
- >
22
- <div className="w-full md:w-[60%] relative">
23
- <Link
24
- to="/motorcycles/$motorcycleId"
25
- params={{
26
- motorcycleId: motorcycle.id.toString(),
27
- }}
28
- className="group block relative"
29
- >
30
- <div className="relative z-0 w-full aspect-[4/3]">
31
- <div className="w-full h-full overflow-hidden rounded-2xl border border-gray-800/50 shadow-2xl">
32
- <img
33
- src={motorcycle.image}
34
- alt={motorcycle.name}
35
- className="w-full h-full object-cover motorcycle-image group-hover:scale-105 transition-transform duration-500"
36
- />
37
- <div className="absolute inset-0 bg-linear-to-t from-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
38
- </div>
39
- <div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 bg-emerald-500/80 text-white px-4 py-2 rounded-full text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity duration-300 backdrop-blur-sm">
40
- View Details
41
- </div>
42
- </div>
43
- </Link>
44
- </div>
45
-
46
- <div
47
- className={`w-full md:w-[50%] relative ${index % 2 === 0 ? 'md:-ml-24' : 'md:-mr-24'} md:my-12`}
48
- >
49
- <div className="bg-gray-900/40 backdrop-blur-xl rounded-2xl p-8 border border-gray-500/20 shadow-2xl relative z-10">
50
- <div className="absolute inset-0 rounded-2xl bg-linear-to-br from-white/5 to-white/0"></div>
51
- <div className="relative z-10">
52
- <h2 className="text-2xl font-bold mb-3">{motorcycle.name}</h2>
53
- <p className="text-gray-300 mb-2 font-medium">
54
- {motorcycle.engineSize}cc •{' '}
55
- {motorcycle.type.charAt(0).toUpperCase() +
56
- motorcycle.type.slice(1)}
57
- </p>
58
- <p className="text-gray-100 mb-4 leading-relaxed">
59
- {motorcycle.shortDescription}
60
- </p>
61
- <div className="text-2xl font-bold text-emerald-400">
62
- ${motorcycle.price.toLocaleString()}
63
- </div>
64
- </div>
65
- </div>
66
- </div>
67
- </div>
68
- ))}
69
- </div>
70
- </div>
71
- )
72
- }
@@ -1,56 +0,0 @@
1
- import { Link, createFileRoute } from "@tanstack/react-router";
2
- import motorcycles from "../../data/motorcycles";
3
-
4
- export const Route = createFileRoute("/motorcycles/$motorcycleId")({
5
- component: RouteComponent,
6
- loader: async ({ params }) => {
7
- const motorcycle = motorcycles.find(
8
- (motorcycle) => motorcycle.id === +params.motorcycleId
9
- );
10
- if (!motorcycle) {
11
- throw new Error("Motorcycle not found");
12
- }
13
- return motorcycle;
14
- },
15
- });
16
-
17
- function RouteComponent() {
18
- const motorcycle = Route.useLoaderData();
19
-
20
- return (
21
- <div className="relative min-h-[100vh] flex items-center bg-black text-white p-5">
22
- <div className="relative z-10 w-[60%] bg-gray-900/60 backdrop-blur-md rounded-2xl p-8 border border-gray-800/50 shadow-xl">
23
- <Link
24
- to="/"
25
- className="inline-block mb-4 text-emerald-400 hover:text-emerald-300"
26
- >
27
- &larr; Back to all motorcycles
28
- </Link>
29
- <h1 className="text-3xl font-bold mb-2">{motorcycle.name}</h1>
30
- <p className="text-gray-400 mb-2">
31
- {motorcycle.engineSize}cc •{" "}
32
- {motorcycle.type.charAt(0).toUpperCase() + motorcycle.type.slice(1)}
33
- </p>
34
- <p className="text-gray-300 mb-6">{motorcycle.description}</p>
35
- <div className="flex items-center justify-between">
36
- <div className="text-2xl font-bold text-emerald-400">
37
- ${motorcycle.price.toLocaleString()}
38
- </div>
39
- <button className="bg-emerald-600 hover:bg-emerald-500 text-white px-6 py-2 rounded-lg transition-colors">
40
- Add to Cart
41
- </button>
42
- </div>
43
- </div>
44
-
45
- <div className="absolute top-0 right-0 w-[55%] h-full z-0">
46
- <div className="w-full h-full overflow-hidden rounded-2xl border-4 border-gray-800 shadow-2xl">
47
- <img
48
- src={motorcycle.image}
49
- alt={motorcycle.name}
50
- className="w-full h-full object-cover motorcycle-image"
51
- />
52
- </div>
53
- </div>
54
- </div>
55
- );
56
- }
@@ -1,3 +0,0 @@
1
- import { Store } from '@tanstack/store'
2
-
3
- export const showMotorcycleAIAssistant = new Store(false)
@@ -1,212 +0,0 @@
1
- @import "tailwindcss";
2
- @import "highlight.js/styles/github-dark.css";
3
-
4
- /* Custom scrollbar styles */
5
- ::-webkit-scrollbar {
6
- width: 8px;
7
- }
8
-
9
- ::-webkit-scrollbar-track {
10
- background: transparent;
11
- }
12
-
13
- ::-webkit-scrollbar-thumb {
14
- background-color: rgba(156, 163, 175, 0.5);
15
- border-radius: 4px;
16
- }
17
-
18
- ::-webkit-scrollbar-thumb:hover {
19
- background-color: rgba(156, 163, 175, 0.7);
20
- }
21
-
22
- /* Smooth transitions for dark mode */
23
- html {
24
- transition: background-color 0.3s ease;
25
- }
26
-
27
- /* Markdown content styles */
28
- .prose {
29
- max-width: none;
30
- color: #e5e7eb; /* text-gray-200 */
31
- }
32
-
33
- .prose code {
34
- color: #e5e7eb;
35
- background-color: rgba(31, 41, 55, 0.5);
36
- padding: 0.2em 0.4em;
37
- border-radius: 0.375rem;
38
- font-size: 0.875em;
39
- }
40
-
41
- .prose pre {
42
- background-color: rgba(31, 41, 55, 0.5);
43
- border-radius: 0.5rem;
44
- padding: 1rem;
45
- margin: 1.25em 0;
46
- overflow-x: auto;
47
- }
48
-
49
- .prose pre code {
50
- background-color: transparent;
51
- padding: 0;
52
- border-radius: 0;
53
- color: inherit;
54
- }
55
-
56
- .prose h1, .prose h2, .prose h3, .prose h4 {
57
- color: #f9fafb; /* text-gray-50 */
58
- }
59
-
60
- .prose ul, .prose ol {
61
- margin-top: 1.25em;
62
- margin-bottom: 1.25em;
63
- padding-left: 1.625em;
64
- }
65
-
66
- .prose li {
67
- margin-top: 0.5em;
68
- margin-bottom: 0.5em;
69
- }
70
-
71
- .prose blockquote {
72
- border-left-color: #f97316; /* orange-500 */
73
- background-color: rgba(249, 115, 22, 0.1);
74
- padding: 1em;
75
- margin: 1.25em 0;
76
- border-radius: 0.5rem;
77
- }
78
-
79
- .prose hr {
80
- border-color: rgba(249, 115, 22, 0.2);
81
- margin: 2em 0;
82
- }
83
-
84
- .prose a {
85
- color: #f97316; /* orange-500 */
86
- text-decoration: underline;
87
- text-decoration-thickness: 0.1em;
88
- text-underline-offset: 0.2em;
89
- }
90
-
91
- .prose a:hover {
92
- color: #fb923c; /* orange-400 */
93
- }
94
-
95
- .prose table {
96
- width: 100%;
97
- border-collapse: collapse;
98
- margin: 1.25em 0;
99
- }
100
-
101
- .prose th, .prose td {
102
- padding: 0.75em;
103
- border: 1px solid rgba(249, 115, 22, 0.2);
104
- }
105
-
106
- .prose th {
107
- background-color: rgba(249, 115, 22, 0.1);
108
- font-weight: 600;
109
- }
110
-
111
- /* Message transition animations */
112
- .message-enter {
113
- opacity: 0;
114
- transform: translateY(10px);
115
- }
116
-
117
- .message-enter-active {
118
- opacity: 1;
119
- transform: translateY(0);
120
- transition: opacity 300ms, transform 300ms;
121
- }
122
-
123
- .message-exit {
124
- opacity: 1;
125
- }
126
-
127
- .message-exit-active {
128
- opacity: 0;
129
- transition: opacity 300ms;
130
- }
131
-
132
- /* Add/update these styles to match AI formatting capabilities */
133
- .prose h1 {
134
- font-size: 2em;
135
- margin-bottom: 0.5em;
136
- }
137
-
138
- .prose h2 {
139
- font-size: 1.5em;
140
- margin-top: 1em;
141
- margin-bottom: 0.5em;
142
- }
143
-
144
- .prose h3 {
145
- font-size: 1.25em;
146
- margin-top: 1em;
147
- margin-bottom: 0.5em;
148
- }
149
-
150
- .prose ul {
151
- list-style-type: disc;
152
- padding-left: 1.5em;
153
- }
154
-
155
- .prose ol {
156
- list-style-type: decimal;
157
- padding-left: 1.5em;
158
- }
159
-
160
- .prose table {
161
- width: 100%;
162
- border-collapse: collapse;
163
- margin: 1em 0;
164
- }
165
-
166
- .prose th,
167
- .prose td {
168
- border: 1px solid rgba(249, 115, 22, 0.2);
169
- padding: 0.5em;
170
- }
171
-
172
- .prose th {
173
- background-color: rgba(249, 115, 22, 0.1);
174
- }
175
-
176
- .prose strong {
177
- color: #f9fafb; /* text-gray-50 */
178
- font-weight: 600;
179
- }
180
-
181
- .prose em {
182
- font-style: italic;
183
- }
184
-
185
- .prose blockquote {
186
- border-left: 4px solid #f97316; /* orange-500 */
187
- padding-left: 1em;
188
- margin: 1em 0;
189
- color: #d1d5db; /* text-gray-300 */
190
- }
191
-
192
- /* Ensure code blocks match the AI's formatting */
193
- .prose code {
194
- color: #e5e7eb;
195
- background-color: rgba(31, 41, 55, 0.5);
196
- padding: 0.2em 0.4em;
197
- border-radius: 0.375rem;
198
- font-size: 0.875em;
199
- }
200
-
201
- .prose pre {
202
- background-color: rgba(31, 41, 55, 0.5);
203
- border-radius: 0.5rem;
204
- padding: 1rem;
205
- margin: 1em 0;
206
- }
207
-
208
- .prose pre code {
209
- background-color: transparent;
210
- padding: 0;
211
- border-radius: 0;
212
- }
@@ -1,33 +0,0 @@
1
- {
2
- "name": "Marketing",
3
- "description": "AI-powered motorcycle marketing site with TanStack AI chat assistant for Netlify.",
4
- "phase": "example",
5
- "modes": ["file-router"],
6
- "type": "example",
7
- "priority": 10,
8
- "link": "",
9
- "routes": [
10
- {"url": "/", "name": "Home", "path": "src/routes/index.tsx", "jsName": "MotorcyclesIndex"},
11
- {"url": "/motorcycles/$motorcycleId", "path": "src/routes/motorcycles/$motorcycleId.tsx", "jsName": "MotorcycleDetail"},
12
- {"url": "/api/motorcycle-chat", "path": "src/routes/api.motorcycle-chat.ts", "jsName": "MotorcycleChatAPI"}
13
- ],
14
- "features": ["tanstack-start", "tanstack-ai"],
15
- "integrations": [],
16
- "dependsOn": [],
17
- "variables": [],
18
- "bareBones": {"deleteFiles": ["public/motorcycle-adventure.jpg", "public/motorcycle-cruiser.jpg", "public/motorcycle-sport.jpg", "public/motorcycle-supersport.jpg"]},
19
- "packageFileDescriptions": {
20
- "src/routes/index.tsx": "Marketing home: motorcycle showcase, MotorcycleAIAssistant.",
21
- "src/routes/motorcycles/$motorcycleId.tsx": "Motorcycle detail page with recommendation.",
22
- "src/routes/api.motorcycle-chat.ts": "POST handler for motorcycle AI chat.",
23
- "src/routes/__root.tsx": "Root layout: Header, styles.",
24
- "src/styles.css": "Global styles.",
25
- "src/data/motorcycles.ts.ejs": "Motorcycle catalog data template.",
26
- "src/lib/motorcycle-tools.ts": "AI tools: getMotorcycles, recommendMotorcycle.",
27
- "src/lib/motorcycle-ai-hook.ts": "useMotorcycleChat hook.",
28
- "src/store/motorcycle-assistant.ts": "Zustand store for assistant state.",
29
- "src/components/Header.tsx": "Header.",
30
- "src/components/MotorcycleAIAssistant.tsx": "AI marketing assistant.",
31
- "src/components/MotorcycleRecommendation.tsx": "Motorcycle recommendation card."
32
- }
33
- }
@@ -1,14 +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-react": "0.2.2",
7
- "@tanstack/react-ai-devtools": "0.2.1",
8
- "@tanstack/react-store": "^0.8.0",
9
- "@tanstack/store": "^0.8.0",
10
- "highlight.js": "^11.11.1",
11
- "streamdown": "^2.1.0",
12
- "zod": "^4.3.6"
13
- }
14
- }