pilothub 0.0.1

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 (272) hide show
  1. package/.env.local.example +19 -0
  2. package/.github/workflows/ci.yml +40 -0
  3. package/.oxlintrc.json +3 -0
  4. package/AGENTS.md +45 -0
  5. package/CHANGELOG.md +138 -0
  6. package/DEPRECATIONS.md +7 -0
  7. package/LICENSE +21 -0
  8. package/README.md +150 -0
  9. package/biome.json +41 -0
  10. package/convex/_generated/api.d.ts +153 -0
  11. package/convex/_generated/api.js +23 -0
  12. package/convex/_generated/dataModel.d.ts +60 -0
  13. package/convex/_generated/server.d.ts +143 -0
  14. package/convex/_generated/server.js +93 -0
  15. package/convex/auth.config.ts +8 -0
  16. package/convex/auth.ts +19 -0
  17. package/convex/comments.ts +88 -0
  18. package/convex/crons.ts +34 -0
  19. package/convex/devSeed.ts +459 -0
  20. package/convex/devSeedExtra.ts +541 -0
  21. package/convex/downloads.ts +78 -0
  22. package/convex/githubBackups.ts +170 -0
  23. package/convex/githubBackupsNode.ts +183 -0
  24. package/convex/githubImport.ts +317 -0
  25. package/convex/githubSoulBackups.ts +170 -0
  26. package/convex/githubSoulBackupsNode.ts +186 -0
  27. package/convex/http.ts +194 -0
  28. package/convex/httpApi.handlers.test.ts +488 -0
  29. package/convex/httpApi.test.ts +70 -0
  30. package/convex/httpApi.ts +305 -0
  31. package/convex/httpApiV1.handlers.test.ts +584 -0
  32. package/convex/httpApiV1.ts +1172 -0
  33. package/convex/leaderboards.ts +39 -0
  34. package/convex/lib/access.ts +36 -0
  35. package/convex/lib/apiTokenAuth.ts +36 -0
  36. package/convex/lib/badges.ts +50 -0
  37. package/convex/lib/changelog.test.ts +34 -0
  38. package/convex/lib/changelog.ts +278 -0
  39. package/convex/lib/embeddings.ts +38 -0
  40. package/convex/lib/githubBackup.ts +443 -0
  41. package/convex/lib/githubImport.test.ts +247 -0
  42. package/convex/lib/githubImport.ts +425 -0
  43. package/convex/lib/githubSoulBackup.ts +443 -0
  44. package/convex/lib/leaderboards.ts +103 -0
  45. package/convex/lib/moderation.ts +42 -0
  46. package/convex/lib/public.ts +89 -0
  47. package/convex/lib/searchText.test.ts +46 -0
  48. package/convex/lib/searchText.ts +27 -0
  49. package/convex/lib/skillBackfill.test.ts +34 -0
  50. package/convex/lib/skillBackfill.ts +67 -0
  51. package/convex/lib/skillPublish.test.ts +28 -0
  52. package/convex/lib/skillPublish.ts +284 -0
  53. package/convex/lib/skillStats.ts +80 -0
  54. package/convex/lib/skills.test.ts +197 -0
  55. package/convex/lib/skills.ts +273 -0
  56. package/convex/lib/soulChangelog.ts +273 -0
  57. package/convex/lib/soulPublish.ts +236 -0
  58. package/convex/lib/tokens.test.ts +33 -0
  59. package/convex/lib/tokens.ts +51 -0
  60. package/convex/lib/webhooks.test.ts +91 -0
  61. package/convex/lib/webhooks.ts +112 -0
  62. package/convex/maintenance.test.ts +270 -0
  63. package/convex/maintenance.ts +840 -0
  64. package/convex/rateLimits.ts +50 -0
  65. package/convex/schema.ts +472 -0
  66. package/convex/search.test.ts +12 -0
  67. package/convex/search.ts +254 -0
  68. package/convex/seed.test.ts +37 -0
  69. package/convex/seed.ts +254 -0
  70. package/convex/seedSouls.ts +111 -0
  71. package/convex/skillStatEvents.ts +568 -0
  72. package/convex/skills.ts +1606 -0
  73. package/convex/soulComments.ts +88 -0
  74. package/convex/soulDownloads.ts +14 -0
  75. package/convex/soulStars.ts +71 -0
  76. package/convex/souls.ts +570 -0
  77. package/convex/stars.ts +108 -0
  78. package/convex/statsMaintenance.ts +205 -0
  79. package/convex/telemetry.ts +434 -0
  80. package/convex/tokens.ts +88 -0
  81. package/convex/tsconfig.json +7 -0
  82. package/convex/uploads.ts +20 -0
  83. package/convex/users.ts +122 -0
  84. package/convex/webhooks.ts +50 -0
  85. package/convex.json +3 -0
  86. package/docs/README.md +32 -0
  87. package/docs/api.md +51 -0
  88. package/docs/architecture.md +61 -0
  89. package/docs/auth.md +54 -0
  90. package/docs/cli.md +117 -0
  91. package/docs/deploy.md +78 -0
  92. package/docs/diffing.md +84 -0
  93. package/docs/github-import.md +171 -0
  94. package/docs/http-api.md +187 -0
  95. package/docs/manual-testing.md +64 -0
  96. package/docs/mintlify.md +43 -0
  97. package/docs/quickstart.md +120 -0
  98. package/docs/skill-format.md +58 -0
  99. package/docs/soul-format.md +37 -0
  100. package/docs/spec.md +177 -0
  101. package/docs/telemetry.md +91 -0
  102. package/docs/troubleshooting.md +49 -0
  103. package/docs/webhook.md +51 -0
  104. package/e2e/menu-smoke.pw.test.ts +49 -0
  105. package/e2e/pilothub.e2e.test.ts +494 -0
  106. package/e2e/search-exact.pw.test.ts +97 -0
  107. package/package.json +84 -0
  108. package/packages/pilothub/LICENSE +22 -0
  109. package/packages/pilothub/README.md +57 -0
  110. package/packages/pilothub/bin/pilothub.js +2 -0
  111. package/packages/pilothub/package.json +41 -0
  112. package/packages/pilothub/src/browserAuth.test.ts +96 -0
  113. package/packages/pilothub/src/browserAuth.ts +174 -0
  114. package/packages/pilothub/src/cli/buildInfo.ts +94 -0
  115. package/packages/pilothub/src/cli/commands/auth.ts +97 -0
  116. package/packages/pilothub/src/cli/commands/delete.test.ts +73 -0
  117. package/packages/pilothub/src/cli/commands/delete.ts +83 -0
  118. package/packages/pilothub/src/cli/commands/publish.test.ts +122 -0
  119. package/packages/pilothub/src/cli/commands/publish.ts +108 -0
  120. package/packages/pilothub/src/cli/commands/skills.test.ts +191 -0
  121. package/packages/pilothub/src/cli/commands/skills.ts +380 -0
  122. package/packages/pilothub/src/cli/commands/star.ts +46 -0
  123. package/packages/pilothub/src/cli/commands/sync.test.ts +310 -0
  124. package/packages/pilothub/src/cli/commands/sync.ts +200 -0
  125. package/packages/pilothub/src/cli/commands/syncHelpers.test.ts +26 -0
  126. package/packages/pilothub/src/cli/commands/syncHelpers.ts +427 -0
  127. package/packages/pilothub/src/cli/commands/syncTypes.ts +27 -0
  128. package/packages/pilothub/src/cli/commands/unstar.ts +48 -0
  129. package/packages/pilothub/src/cli/helpStyle.ts +45 -0
  130. package/packages/pilothub/src/cli/pilotbotConfig.test.ts +159 -0
  131. package/packages/pilothub/src/cli/pilotbotConfig.ts +147 -0
  132. package/packages/pilothub/src/cli/registry.test.ts +63 -0
  133. package/packages/pilothub/src/cli/registry.ts +43 -0
  134. package/packages/pilothub/src/cli/scanSkills.test.ts +64 -0
  135. package/packages/pilothub/src/cli/scanSkills.ts +84 -0
  136. package/packages/pilothub/src/cli/slug.ts +16 -0
  137. package/packages/pilothub/src/cli/types.ts +12 -0
  138. package/packages/pilothub/src/cli/ui.ts +75 -0
  139. package/packages/pilothub/src/cli.ts +311 -0
  140. package/packages/pilothub/src/config.ts +36 -0
  141. package/packages/pilothub/src/discovery.test.ts +75 -0
  142. package/packages/pilothub/src/discovery.ts +19 -0
  143. package/packages/pilothub/src/http.test.ts +156 -0
  144. package/packages/pilothub/src/http.ts +301 -0
  145. package/packages/pilothub/src/schema/ark.ts +29 -0
  146. package/packages/pilothub/src/schema/index.ts +5 -0
  147. package/packages/pilothub/src/schema/routes.ts +22 -0
  148. package/packages/pilothub/src/schema/schemas.ts +260 -0
  149. package/packages/pilothub/src/schema/textFiles.test.ts +23 -0
  150. package/packages/pilothub/src/schema/textFiles.ts +66 -0
  151. package/packages/pilothub/src/skills.test.ts +191 -0
  152. package/packages/pilothub/src/skills.ts +172 -0
  153. package/packages/pilothub/src/types.ts +10 -0
  154. package/packages/pilothub/tsconfig.json +14 -0
  155. package/packages/schema/README.md +3 -0
  156. package/packages/schema/dist/ark.d.ts +4 -0
  157. package/packages/schema/dist/ark.js +26 -0
  158. package/packages/schema/dist/ark.js.map +1 -0
  159. package/packages/schema/dist/index.d.ts +5 -0
  160. package/packages/schema/dist/index.js +5 -0
  161. package/packages/schema/dist/index.js.map +1 -0
  162. package/packages/schema/dist/routes.d.ts +21 -0
  163. package/packages/schema/dist/routes.js +22 -0
  164. package/packages/schema/dist/routes.js.map +1 -0
  165. package/packages/schema/dist/schemas.d.ts +297 -0
  166. package/packages/schema/dist/schemas.js +243 -0
  167. package/packages/schema/dist/schemas.js.map +1 -0
  168. package/packages/schema/dist/textFiles.d.ts +5 -0
  169. package/packages/schema/dist/textFiles.js +66 -0
  170. package/packages/schema/dist/textFiles.js.map +1 -0
  171. package/packages/schema/package.json +26 -0
  172. package/packages/schema/src/ark.ts +29 -0
  173. package/packages/schema/src/index.ts +5 -0
  174. package/packages/schema/src/routes.ts +22 -0
  175. package/packages/schema/src/schemas.test.ts +123 -0
  176. package/packages/schema/src/schemas.ts +287 -0
  177. package/packages/schema/src/textFiles.test.ts +23 -0
  178. package/packages/schema/src/textFiles.ts +66 -0
  179. package/packages/schema/tsconfig.json +15 -0
  180. package/pilothub +46 -0
  181. package/playwright.config.ts +33 -0
  182. package/public/.well-known/pilothub.json +6 -0
  183. package/public/api/v1/openapi.json +379 -0
  184. package/public/favicon.ico +0 -0
  185. package/public/logo192.png +0 -0
  186. package/public/logo512.png +0 -0
  187. package/public/manifest.json +25 -0
  188. package/public/og.png +0 -0
  189. package/public/og.svg +98 -0
  190. package/public/pilot-logo.png +0 -0
  191. package/public/pilot-mark.png +0 -0
  192. package/public/robots.txt +3 -0
  193. package/public/tanstack-circle-logo.png +0 -0
  194. package/public/tanstack-word-logo-white.svg +1 -0
  195. package/scripts/check-peer-deps.ts +56 -0
  196. package/scripts/docs-list.ts +148 -0
  197. package/scripts/run-playwright-local.sh +14 -0
  198. package/server/og/fetchSkillOgMeta.ts +27 -0
  199. package/server/og/fetchSoulOgMeta.ts +27 -0
  200. package/server/og/ogAssets.ts +80 -0
  201. package/server/og/skillOgSvg.test.ts +59 -0
  202. package/server/og/skillOgSvg.ts +258 -0
  203. package/server/og/soulOgSvg.ts +209 -0
  204. package/server/routes/og/skill.png.ts +103 -0
  205. package/server/routes/og/soul.png.ts +111 -0
  206. package/src/__tests__/skill-detail-page.test.tsx +86 -0
  207. package/src/__tests__/skills-index.test.tsx +145 -0
  208. package/src/__tests__/upload.route.test.tsx +228 -0
  209. package/src/components/AppProviders.tsx +19 -0
  210. package/src/components/ClientOnly.tsx +18 -0
  211. package/src/components/Footer.tsx +29 -0
  212. package/src/components/Header.tsx +295 -0
  213. package/src/components/InstallSwitcher.tsx +53 -0
  214. package/src/components/SkillCard.tsx +36 -0
  215. package/src/components/SkillDetailPage.tsx +817 -0
  216. package/src/components/SkillDiffCard.tsx +485 -0
  217. package/src/components/SoulCard.tsx +19 -0
  218. package/src/components/SoulDetailPage.tsx +263 -0
  219. package/src/components/UserBootstrap.tsx +18 -0
  220. package/src/components/ui/dropdown-menu.tsx +67 -0
  221. package/src/components/ui/toggle-group.tsx +35 -0
  222. package/src/convex/client.ts +3 -0
  223. package/src/lib/badges.ts +29 -0
  224. package/src/lib/diffing.test.ts +163 -0
  225. package/src/lib/diffing.ts +106 -0
  226. package/src/lib/gravatar.test.ts +9 -0
  227. package/src/lib/gravatar.ts +158 -0
  228. package/src/lib/og.test.ts +142 -0
  229. package/src/lib/og.ts +156 -0
  230. package/src/lib/publicUser.ts +39 -0
  231. package/src/lib/roles.ts +19 -0
  232. package/src/lib/site.test.ts +130 -0
  233. package/src/lib/site.ts +84 -0
  234. package/src/lib/theme-transition.test.ts +134 -0
  235. package/src/lib/theme-transition.ts +134 -0
  236. package/src/lib/theme.test.tsx +88 -0
  237. package/src/lib/theme.ts +43 -0
  238. package/src/lib/uploadFiles.jsdom.test.ts +33 -0
  239. package/src/lib/uploadFiles.test.ts +123 -0
  240. package/src/lib/uploadFiles.ts +245 -0
  241. package/src/lib/uploadUtils.test.ts +78 -0
  242. package/src/lib/uploadUtils.ts +93 -0
  243. package/src/lib/useAuthStatus.ts +12 -0
  244. package/src/lib/utils.test.ts +9 -0
  245. package/src/lib/utils.ts +6 -0
  246. package/src/logo.svg +12 -0
  247. package/src/routeTree.gen.ts +345 -0
  248. package/src/router.tsx +17 -0
  249. package/src/routes/$owner/$slug.tsx +55 -0
  250. package/src/routes/__root.tsx +136 -0
  251. package/src/routes/admin.tsx +11 -0
  252. package/src/routes/cli/auth.tsx +168 -0
  253. package/src/routes/dashboard.tsx +97 -0
  254. package/src/routes/import.tsx +415 -0
  255. package/src/routes/index.tsx +252 -0
  256. package/src/routes/management.tsx +529 -0
  257. package/src/routes/settings.tsx +203 -0
  258. package/src/routes/skills/index.tsx +422 -0
  259. package/src/routes/souls/$slug.tsx +55 -0
  260. package/src/routes/souls/index.tsx +243 -0
  261. package/src/routes/stars.tsx +68 -0
  262. package/src/routes/u/$handle.tsx +307 -0
  263. package/src/routes/upload/utils.ts +81 -0
  264. package/src/routes/upload.tsx +499 -0
  265. package/src/styles.css +2718 -0
  266. package/tsconfig.json +24 -0
  267. package/tsconfig.oxlint.json +16 -0
  268. package/vercel.json +8 -0
  269. package/vite.config.ts +48 -0
  270. package/vitest.config.ts +47 -0
  271. package/vitest.e2e.config.ts +11 -0
  272. package/vitest.setup.ts +1 -0
@@ -0,0 +1,345 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as UploadRouteImport } from './routes/upload'
13
+ import { Route as StarsRouteImport } from './routes/stars'
14
+ import { Route as SettingsRouteImport } from './routes/settings'
15
+ import { Route as ManagementRouteImport } from './routes/management'
16
+ import { Route as ImportRouteImport } from './routes/import'
17
+ import { Route as DashboardRouteImport } from './routes/dashboard'
18
+ import { Route as AdminRouteImport } from './routes/admin'
19
+ import { Route as IndexRouteImport } from './routes/index'
20
+ import { Route as SoulsIndexRouteImport } from './routes/souls/index'
21
+ import { Route as SkillsIndexRouteImport } from './routes/skills/index'
22
+ import { Route as UHandleRouteImport } from './routes/u/$handle'
23
+ import { Route as SoulsSlugRouteImport } from './routes/souls/$slug'
24
+ import { Route as CliAuthRouteImport } from './routes/cli/auth'
25
+ import { Route as OwnerSlugRouteImport } from './routes/$owner/$slug'
26
+
27
+ const UploadRoute = UploadRouteImport.update({
28
+ id: '/upload',
29
+ path: '/upload',
30
+ getParentRoute: () => rootRouteImport,
31
+ } as any)
32
+ const StarsRoute = StarsRouteImport.update({
33
+ id: '/stars',
34
+ path: '/stars',
35
+ getParentRoute: () => rootRouteImport,
36
+ } as any)
37
+ const SettingsRoute = SettingsRouteImport.update({
38
+ id: '/settings',
39
+ path: '/settings',
40
+ getParentRoute: () => rootRouteImport,
41
+ } as any)
42
+ const ManagementRoute = ManagementRouteImport.update({
43
+ id: '/management',
44
+ path: '/management',
45
+ getParentRoute: () => rootRouteImport,
46
+ } as any)
47
+ const ImportRoute = ImportRouteImport.update({
48
+ id: '/import',
49
+ path: '/import',
50
+ getParentRoute: () => rootRouteImport,
51
+ } as any)
52
+ const DashboardRoute = DashboardRouteImport.update({
53
+ id: '/dashboard',
54
+ path: '/dashboard',
55
+ getParentRoute: () => rootRouteImport,
56
+ } as any)
57
+ const AdminRoute = AdminRouteImport.update({
58
+ id: '/admin',
59
+ path: '/admin',
60
+ getParentRoute: () => rootRouteImport,
61
+ } as any)
62
+ const IndexRoute = IndexRouteImport.update({
63
+ id: '/',
64
+ path: '/',
65
+ getParentRoute: () => rootRouteImport,
66
+ } as any)
67
+ const SoulsIndexRoute = SoulsIndexRouteImport.update({
68
+ id: '/souls/',
69
+ path: '/souls/',
70
+ getParentRoute: () => rootRouteImport,
71
+ } as any)
72
+ const SkillsIndexRoute = SkillsIndexRouteImport.update({
73
+ id: '/skills/',
74
+ path: '/skills/',
75
+ getParentRoute: () => rootRouteImport,
76
+ } as any)
77
+ const UHandleRoute = UHandleRouteImport.update({
78
+ id: '/u/$handle',
79
+ path: '/u/$handle',
80
+ getParentRoute: () => rootRouteImport,
81
+ } as any)
82
+ const SoulsSlugRoute = SoulsSlugRouteImport.update({
83
+ id: '/souls/$slug',
84
+ path: '/souls/$slug',
85
+ getParentRoute: () => rootRouteImport,
86
+ } as any)
87
+ const CliAuthRoute = CliAuthRouteImport.update({
88
+ id: '/cli/auth',
89
+ path: '/cli/auth',
90
+ getParentRoute: () => rootRouteImport,
91
+ } as any)
92
+ const OwnerSlugRoute = OwnerSlugRouteImport.update({
93
+ id: '/$owner/$slug',
94
+ path: '/$owner/$slug',
95
+ getParentRoute: () => rootRouteImport,
96
+ } as any)
97
+
98
+ export interface FileRoutesByFullPath {
99
+ '/': typeof IndexRoute
100
+ '/admin': typeof AdminRoute
101
+ '/dashboard': typeof DashboardRoute
102
+ '/import': typeof ImportRoute
103
+ '/management': typeof ManagementRoute
104
+ '/settings': typeof SettingsRoute
105
+ '/stars': typeof StarsRoute
106
+ '/upload': typeof UploadRoute
107
+ '/$owner/$slug': typeof OwnerSlugRoute
108
+ '/cli/auth': typeof CliAuthRoute
109
+ '/souls/$slug': typeof SoulsSlugRoute
110
+ '/u/$handle': typeof UHandleRoute
111
+ '/skills/': typeof SkillsIndexRoute
112
+ '/souls/': typeof SoulsIndexRoute
113
+ }
114
+ export interface FileRoutesByTo {
115
+ '/': typeof IndexRoute
116
+ '/admin': typeof AdminRoute
117
+ '/dashboard': typeof DashboardRoute
118
+ '/import': typeof ImportRoute
119
+ '/management': typeof ManagementRoute
120
+ '/settings': typeof SettingsRoute
121
+ '/stars': typeof StarsRoute
122
+ '/upload': typeof UploadRoute
123
+ '/$owner/$slug': typeof OwnerSlugRoute
124
+ '/cli/auth': typeof CliAuthRoute
125
+ '/souls/$slug': typeof SoulsSlugRoute
126
+ '/u/$handle': typeof UHandleRoute
127
+ '/skills': typeof SkillsIndexRoute
128
+ '/souls': typeof SoulsIndexRoute
129
+ }
130
+ export interface FileRoutesById {
131
+ __root__: typeof rootRouteImport
132
+ '/': typeof IndexRoute
133
+ '/admin': typeof AdminRoute
134
+ '/dashboard': typeof DashboardRoute
135
+ '/import': typeof ImportRoute
136
+ '/management': typeof ManagementRoute
137
+ '/settings': typeof SettingsRoute
138
+ '/stars': typeof StarsRoute
139
+ '/upload': typeof UploadRoute
140
+ '/$owner/$slug': typeof OwnerSlugRoute
141
+ '/cli/auth': typeof CliAuthRoute
142
+ '/souls/$slug': typeof SoulsSlugRoute
143
+ '/u/$handle': typeof UHandleRoute
144
+ '/skills/': typeof SkillsIndexRoute
145
+ '/souls/': typeof SoulsIndexRoute
146
+ }
147
+ export interface FileRouteTypes {
148
+ fileRoutesByFullPath: FileRoutesByFullPath
149
+ fullPaths:
150
+ | '/'
151
+ | '/admin'
152
+ | '/dashboard'
153
+ | '/import'
154
+ | '/management'
155
+ | '/settings'
156
+ | '/stars'
157
+ | '/upload'
158
+ | '/$owner/$slug'
159
+ | '/cli/auth'
160
+ | '/souls/$slug'
161
+ | '/u/$handle'
162
+ | '/skills/'
163
+ | '/souls/'
164
+ fileRoutesByTo: FileRoutesByTo
165
+ to:
166
+ | '/'
167
+ | '/admin'
168
+ | '/dashboard'
169
+ | '/import'
170
+ | '/management'
171
+ | '/settings'
172
+ | '/stars'
173
+ | '/upload'
174
+ | '/$owner/$slug'
175
+ | '/cli/auth'
176
+ | '/souls/$slug'
177
+ | '/u/$handle'
178
+ | '/skills'
179
+ | '/souls'
180
+ id:
181
+ | '__root__'
182
+ | '/'
183
+ | '/admin'
184
+ | '/dashboard'
185
+ | '/import'
186
+ | '/management'
187
+ | '/settings'
188
+ | '/stars'
189
+ | '/upload'
190
+ | '/$owner/$slug'
191
+ | '/cli/auth'
192
+ | '/souls/$slug'
193
+ | '/u/$handle'
194
+ | '/skills/'
195
+ | '/souls/'
196
+ fileRoutesById: FileRoutesById
197
+ }
198
+ export interface RootRouteChildren {
199
+ IndexRoute: typeof IndexRoute
200
+ AdminRoute: typeof AdminRoute
201
+ DashboardRoute: typeof DashboardRoute
202
+ ImportRoute: typeof ImportRoute
203
+ ManagementRoute: typeof ManagementRoute
204
+ SettingsRoute: typeof SettingsRoute
205
+ StarsRoute: typeof StarsRoute
206
+ UploadRoute: typeof UploadRoute
207
+ OwnerSlugRoute: typeof OwnerSlugRoute
208
+ CliAuthRoute: typeof CliAuthRoute
209
+ SoulsSlugRoute: typeof SoulsSlugRoute
210
+ UHandleRoute: typeof UHandleRoute
211
+ SkillsIndexRoute: typeof SkillsIndexRoute
212
+ SoulsIndexRoute: typeof SoulsIndexRoute
213
+ }
214
+
215
+ declare module '@tanstack/react-router' {
216
+ interface FileRoutesByPath {
217
+ '/upload': {
218
+ id: '/upload'
219
+ path: '/upload'
220
+ fullPath: '/upload'
221
+ preLoaderRoute: typeof UploadRouteImport
222
+ parentRoute: typeof rootRouteImport
223
+ }
224
+ '/stars': {
225
+ id: '/stars'
226
+ path: '/stars'
227
+ fullPath: '/stars'
228
+ preLoaderRoute: typeof StarsRouteImport
229
+ parentRoute: typeof rootRouteImport
230
+ }
231
+ '/settings': {
232
+ id: '/settings'
233
+ path: '/settings'
234
+ fullPath: '/settings'
235
+ preLoaderRoute: typeof SettingsRouteImport
236
+ parentRoute: typeof rootRouteImport
237
+ }
238
+ '/management': {
239
+ id: '/management'
240
+ path: '/management'
241
+ fullPath: '/management'
242
+ preLoaderRoute: typeof ManagementRouteImport
243
+ parentRoute: typeof rootRouteImport
244
+ }
245
+ '/import': {
246
+ id: '/import'
247
+ path: '/import'
248
+ fullPath: '/import'
249
+ preLoaderRoute: typeof ImportRouteImport
250
+ parentRoute: typeof rootRouteImport
251
+ }
252
+ '/dashboard': {
253
+ id: '/dashboard'
254
+ path: '/dashboard'
255
+ fullPath: '/dashboard'
256
+ preLoaderRoute: typeof DashboardRouteImport
257
+ parentRoute: typeof rootRouteImport
258
+ }
259
+ '/admin': {
260
+ id: '/admin'
261
+ path: '/admin'
262
+ fullPath: '/admin'
263
+ preLoaderRoute: typeof AdminRouteImport
264
+ parentRoute: typeof rootRouteImport
265
+ }
266
+ '/': {
267
+ id: '/'
268
+ path: '/'
269
+ fullPath: '/'
270
+ preLoaderRoute: typeof IndexRouteImport
271
+ parentRoute: typeof rootRouteImport
272
+ }
273
+ '/souls/': {
274
+ id: '/souls/'
275
+ path: '/souls'
276
+ fullPath: '/souls/'
277
+ preLoaderRoute: typeof SoulsIndexRouteImport
278
+ parentRoute: typeof rootRouteImport
279
+ }
280
+ '/skills/': {
281
+ id: '/skills/'
282
+ path: '/skills'
283
+ fullPath: '/skills/'
284
+ preLoaderRoute: typeof SkillsIndexRouteImport
285
+ parentRoute: typeof rootRouteImport
286
+ }
287
+ '/u/$handle': {
288
+ id: '/u/$handle'
289
+ path: '/u/$handle'
290
+ fullPath: '/u/$handle'
291
+ preLoaderRoute: typeof UHandleRouteImport
292
+ parentRoute: typeof rootRouteImport
293
+ }
294
+ '/souls/$slug': {
295
+ id: '/souls/$slug'
296
+ path: '/souls/$slug'
297
+ fullPath: '/souls/$slug'
298
+ preLoaderRoute: typeof SoulsSlugRouteImport
299
+ parentRoute: typeof rootRouteImport
300
+ }
301
+ '/cli/auth': {
302
+ id: '/cli/auth'
303
+ path: '/cli/auth'
304
+ fullPath: '/cli/auth'
305
+ preLoaderRoute: typeof CliAuthRouteImport
306
+ parentRoute: typeof rootRouteImport
307
+ }
308
+ '/$owner/$slug': {
309
+ id: '/$owner/$slug'
310
+ path: '/$owner/$slug'
311
+ fullPath: '/$owner/$slug'
312
+ preLoaderRoute: typeof OwnerSlugRouteImport
313
+ parentRoute: typeof rootRouteImport
314
+ }
315
+ }
316
+ }
317
+
318
+ const rootRouteChildren: RootRouteChildren = {
319
+ IndexRoute: IndexRoute,
320
+ AdminRoute: AdminRoute,
321
+ DashboardRoute: DashboardRoute,
322
+ ImportRoute: ImportRoute,
323
+ ManagementRoute: ManagementRoute,
324
+ SettingsRoute: SettingsRoute,
325
+ StarsRoute: StarsRoute,
326
+ UploadRoute: UploadRoute,
327
+ OwnerSlugRoute: OwnerSlugRoute,
328
+ CliAuthRoute: CliAuthRoute,
329
+ SoulsSlugRoute: SoulsSlugRoute,
330
+ UHandleRoute: UHandleRoute,
331
+ SkillsIndexRoute: SkillsIndexRoute,
332
+ SoulsIndexRoute: SoulsIndexRoute,
333
+ }
334
+ export const routeTree = rootRouteImport
335
+ ._addFileChildren(rootRouteChildren)
336
+ ._addFileTypes<FileRouteTypes>()
337
+
338
+ import type { getRouter } from './router.tsx'
339
+ import type { createStart } from '@tanstack/react-start'
340
+ declare module '@tanstack/react-start' {
341
+ interface Register {
342
+ ssr: true
343
+ router: Awaited<ReturnType<typeof getRouter>>
344
+ }
345
+ }
package/src/router.tsx ADDED
@@ -0,0 +1,17 @@
1
+ import { createRouter } from '@tanstack/react-router'
2
+
3
+ // Import the generated route tree
4
+ import { routeTree } from './routeTree.gen'
5
+
6
+ // Create a new router instance
7
+ export const getRouter = () => {
8
+ const router = createRouter({
9
+ routeTree,
10
+ context: {},
11
+
12
+ scrollRestoration: true,
13
+ defaultPreloadStaleTime: 0,
14
+ })
15
+
16
+ return router
17
+ }
@@ -0,0 +1,55 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { SkillDetailPage } from '../../components/SkillDetailPage'
3
+ import { buildSkillMeta, fetchSkillMeta } from '../../lib/og'
4
+
5
+ export const Route = createFileRoute('/$owner/$slug')({
6
+ loader: async ({ params }) => {
7
+ const data = await fetchSkillMeta(params.slug)
8
+ return {
9
+ owner: data?.owner ?? params.owner,
10
+ displayName: data?.displayName ?? null,
11
+ summary: data?.summary ?? null,
12
+ version: data?.version ?? null,
13
+ }
14
+ },
15
+ head: ({ params, loaderData }) => {
16
+ const meta = buildSkillMeta({
17
+ slug: params.slug,
18
+ owner: loaderData?.owner ?? params.owner,
19
+ displayName: loaderData?.displayName,
20
+ summary: loaderData?.summary,
21
+ version: loaderData?.version ?? null,
22
+ })
23
+ return {
24
+ links: [
25
+ {
26
+ rel: 'canonical',
27
+ href: meta.url,
28
+ },
29
+ ],
30
+ meta: [
31
+ { title: meta.title },
32
+ { name: 'description', content: meta.description },
33
+ { property: 'og:title', content: meta.title },
34
+ { property: 'og:description', content: meta.description },
35
+ { property: 'og:type', content: 'website' },
36
+ { property: 'og:url', content: meta.url },
37
+ { property: 'og:image', content: meta.image },
38
+ { property: 'og:image:width', content: '1200' },
39
+ { property: 'og:image:height', content: '630' },
40
+ { property: 'og:image:alt', content: meta.title },
41
+ { name: 'twitter:card', content: 'summary_large_image' },
42
+ { name: 'twitter:title', content: meta.title },
43
+ { name: 'twitter:description', content: meta.description },
44
+ { name: 'twitter:image', content: meta.image },
45
+ { name: 'twitter:image:alt', content: meta.title },
46
+ ],
47
+ }
48
+ },
49
+ component: OwnerSkill,
50
+ })
51
+
52
+ function OwnerSkill() {
53
+ const { owner, slug } = Route.useParams()
54
+ return <SkillDetailPage slug={slug} canonicalOwner={owner} />
55
+ }
@@ -0,0 +1,136 @@
1
+ import { TanStackDevtools } from '@tanstack/react-devtools'
2
+ import { createRootRoute, HeadContent, Scripts } from '@tanstack/react-router'
3
+ import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
4
+ import { Analytics } from '@vercel/analytics/react'
5
+ import { AppProviders } from '../components/AppProviders'
6
+ import { ClientOnly } from '../components/ClientOnly'
7
+ import { Footer } from '../components/Footer'
8
+ import Header from '../components/Header'
9
+ import { getSiteDescription, getSiteMode, getSiteName, getSiteUrlForMode } from '../lib/site'
10
+
11
+ import appCss from '../styles.css?url'
12
+
13
+ export const Route = createRootRoute({
14
+ head: () => {
15
+ const mode = getSiteMode()
16
+ const siteName = getSiteName(mode)
17
+ const siteDescription = getSiteDescription(mode)
18
+ const siteUrl = getSiteUrlForMode(mode)
19
+ const ogImage = `${siteUrl}/og.png`
20
+
21
+ return {
22
+ meta: [
23
+ {
24
+ charSet: 'utf-8',
25
+ },
26
+ {
27
+ name: 'viewport',
28
+ content: 'width=device-width, initial-scale=1',
29
+ },
30
+ {
31
+ title: siteName,
32
+ },
33
+ {
34
+ name: 'description',
35
+ content: siteDescription,
36
+ },
37
+ {
38
+ property: 'og:site_name',
39
+ content: siteName,
40
+ },
41
+ {
42
+ property: 'og:type',
43
+ content: 'website',
44
+ },
45
+ {
46
+ property: 'og:title',
47
+ content: siteName,
48
+ },
49
+ {
50
+ property: 'og:description',
51
+ content: siteDescription,
52
+ },
53
+ {
54
+ property: 'og:image',
55
+ content: ogImage,
56
+ },
57
+ {
58
+ property: 'og:image:width',
59
+ content: '1200',
60
+ },
61
+ {
62
+ property: 'og:image:height',
63
+ content: '630',
64
+ },
65
+ {
66
+ property: 'og:image:alt',
67
+ content: `${siteName} — ${siteDescription}`,
68
+ },
69
+ {
70
+ name: 'twitter:card',
71
+ content: 'summary_large_image',
72
+ },
73
+ {
74
+ name: 'twitter:title',
75
+ content: siteName,
76
+ },
77
+ {
78
+ name: 'twitter:description',
79
+ content: siteDescription,
80
+ },
81
+ {
82
+ name: 'twitter:image',
83
+ content: ogImage,
84
+ },
85
+ {
86
+ name: 'twitter:image:alt',
87
+ content: `${siteName} — ${siteDescription}`,
88
+ },
89
+ ],
90
+ links: [
91
+ {
92
+ rel: 'stylesheet',
93
+ href: appCss,
94
+ },
95
+ ],
96
+ }
97
+ },
98
+
99
+ shellComponent: RootDocument,
100
+ })
101
+
102
+ function RootDocument({ children }: { children: React.ReactNode }) {
103
+ return (
104
+ <html lang="en">
105
+ <head>
106
+ <HeadContent />
107
+ </head>
108
+ <body>
109
+ <ClientOnly>
110
+ <AppProviders>
111
+ <div className="app-shell">
112
+ <Header />
113
+ {children}
114
+ <Footer />
115
+ </div>
116
+ <Analytics />
117
+ {import.meta.env.DEV ? (
118
+ <TanStackDevtools
119
+ config={{
120
+ position: 'bottom-right',
121
+ }}
122
+ plugins={[
123
+ {
124
+ name: 'Tanstack Router',
125
+ render: <TanStackRouterDevtoolsPanel />,
126
+ },
127
+ ]}
128
+ />
129
+ ) : null}
130
+ </AppProviders>
131
+ </ClientOnly>
132
+ <Scripts />
133
+ </body>
134
+ </html>
135
+ )
136
+ }
@@ -0,0 +1,11 @@
1
+ import { createFileRoute, redirect } from '@tanstack/react-router'
2
+
3
+ export const Route = createFileRoute('/admin')({
4
+ beforeLoad: () => {
5
+ throw redirect({
6
+ to: '/management',
7
+ search: { skill: undefined },
8
+ replace: true,
9
+ })
10
+ },
11
+ })