bazilion 0.0.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 (260) hide show
  1. package/.understand-anything/.understandignore +25 -0
  2. package/.understand-anything/fingerprints.json +14267 -0
  3. package/.understand-anything/knowledge-graph.json +18128 -0
  4. package/.understand-anything/meta.json +6 -0
  5. package/CLAUDE.md +164 -0
  6. package/LICENSE +21 -0
  7. package/README.md +195 -0
  8. package/apps/cli/package.json +21 -0
  9. package/apps/cli/src/auth-file.ts +18 -0
  10. package/apps/cli/src/client.ts +37 -0
  11. package/apps/cli/src/columnize.ts +32 -0
  12. package/apps/cli/src/commands/agent.ts +574 -0
  13. package/apps/cli/src/commands/auth.ts +110 -0
  14. package/apps/cli/src/commands/backup.ts +135 -0
  15. package/apps/cli/src/commands/completion.ts +155 -0
  16. package/apps/cli/src/commands/config.ts +95 -0
  17. package/apps/cli/src/commands/doctor.ts +131 -0
  18. package/apps/cli/src/commands/group.ts +132 -0
  19. package/apps/cli/src/commands/inbox.ts +82 -0
  20. package/apps/cli/src/commands/login.ts +73 -0
  21. package/apps/cli/src/commands/memory.ts +106 -0
  22. package/apps/cli/src/commands/profile.ts +259 -0
  23. package/apps/cli/src/commands/provider.ts +170 -0
  24. package/apps/cli/src/commands/send.ts +24 -0
  25. package/apps/cli/src/commands/serve.ts +89 -0
  26. package/apps/cli/src/commands/skill.ts +120 -0
  27. package/apps/cli/src/commands/token.ts +148 -0
  28. package/apps/cli/src/commands/trigger.ts +129 -0
  29. package/apps/cli/src/commands/uninstall.ts +156 -0
  30. package/apps/cli/src/index.ts +196 -0
  31. package/apps/cli/src/paths.ts +12 -0
  32. package/apps/cli/test/agent.test.ts +213 -0
  33. package/apps/cli/test/backup.test.ts +95 -0
  34. package/apps/cli/test/chat.test.ts +539 -0
  35. package/apps/cli/test/columnize.test.ts +29 -0
  36. package/apps/cli/test/completion.test.ts +45 -0
  37. package/apps/cli/test/config-page.test.ts +151 -0
  38. package/apps/cli/test/group.test.ts +74 -0
  39. package/apps/cli/test/helpers.ts +70 -0
  40. package/apps/cli/test/inbox-autodeliver.test.ts +143 -0
  41. package/apps/cli/test/inbox.test.ts +147 -0
  42. package/apps/cli/test/memory.test.ts +69 -0
  43. package/apps/cli/test/profile.test.ts +110 -0
  44. package/apps/cli/test/send.test.ts +30 -0
  45. package/apps/cli/test/server-fixture.ts +212 -0
  46. package/apps/cli/test/session-head.test.ts +45 -0
  47. package/apps/cli/test/skill.test.ts +128 -0
  48. package/apps/cli/test/token.test.ts +109 -0
  49. package/apps/cli/test/trigger.test.ts +245 -0
  50. package/apps/cli/tsconfig.json +4 -0
  51. package/apps/daemon/package.json +31 -0
  52. package/apps/daemon/src/app.ts +41 -0
  53. package/apps/daemon/src/core/agent/archive.ts +8 -0
  54. package/apps/daemon/src/core/agent/delete.ts +30 -0
  55. package/apps/daemon/src/core/agent/resolve.ts +31 -0
  56. package/apps/daemon/src/core/agent/spawn.ts +95 -0
  57. package/apps/daemon/src/core/agent/unarchive.ts +11 -0
  58. package/apps/daemon/src/core/availableModels.ts +58 -0
  59. package/apps/daemon/src/core/db/client.ts +113 -0
  60. package/apps/daemon/src/core/db/migrate.ts +41 -0
  61. package/apps/daemon/src/core/db/migrations/0001_init.sql +179 -0
  62. package/apps/daemon/src/core/group/delete.ts +21 -0
  63. package/apps/daemon/src/core/group/register.ts +68 -0
  64. package/apps/daemon/src/core/index.ts +71 -0
  65. package/apps/daemon/src/core/paths.ts +56 -0
  66. package/apps/daemon/src/core/profile/create.ts +78 -0
  67. package/apps/daemon/src/core/profile/delete.ts +26 -0
  68. package/apps/daemon/src/core/profile/identity.ts +70 -0
  69. package/apps/daemon/src/core/profile/load.ts +45 -0
  70. package/apps/daemon/src/core/profile/seed.ts +74 -0
  71. package/apps/daemon/src/core/profile/templates.ts +60 -0
  72. package/apps/daemon/src/core/profile/update.ts +57 -0
  73. package/apps/daemon/src/core/profile/validate.ts +9 -0
  74. package/apps/daemon/src/core/repos/agents.ts +202 -0
  75. package/apps/daemon/src/core/repos/config.ts +78 -0
  76. package/apps/daemon/src/core/repos/groups.ts +55 -0
  77. package/apps/daemon/src/core/repos/messages.ts +127 -0
  78. package/apps/daemon/src/core/repos/profiles.ts +83 -0
  79. package/apps/daemon/src/core/repos/providerModels.ts +58 -0
  80. package/apps/daemon/src/core/repos/providerState.ts +37 -0
  81. package/apps/daemon/src/core/repos/secrets.ts +145 -0
  82. package/apps/daemon/src/core/repos/skillMeta.ts +49 -0
  83. package/apps/daemon/src/core/repos/triggers.ts +101 -0
  84. package/apps/daemon/src/core/repos/webTokens.ts +87 -0
  85. package/apps/daemon/src/core/secrets.ts +65 -0
  86. package/apps/daemon/src/core/services.ts +264 -0
  87. package/apps/daemon/src/core/skills/discover.ts +28 -0
  88. package/apps/daemon/src/core/skills/import.ts +136 -0
  89. package/apps/daemon/src/core/skills/parse.ts +52 -0
  90. package/apps/daemon/src/core/skills/resolve.ts +50 -0
  91. package/apps/daemon/src/index.ts +45 -0
  92. package/apps/daemon/src/lib/agent-cancel.ts +48 -0
  93. package/apps/daemon/src/lib/agent-id.ts +13 -0
  94. package/apps/daemon/src/lib/agent-turn.ts +56 -0
  95. package/apps/daemon/src/lib/api-key.ts +56 -0
  96. package/apps/daemon/src/lib/auth.ts +41 -0
  97. package/apps/daemon/src/lib/cron.ts +93 -0
  98. package/apps/daemon/src/lib/ctx.ts +80 -0
  99. package/apps/daemon/src/lib/messaging-host.ts +34 -0
  100. package/apps/daemon/src/lib/middleware-auth.ts +52 -0
  101. package/apps/daemon/src/lib/scheduler.ts +294 -0
  102. package/apps/daemon/src/routes/agents.ts +772 -0
  103. package/apps/daemon/src/routes/auth-login.ts +193 -0
  104. package/apps/daemon/src/routes/config.ts +267 -0
  105. package/apps/daemon/src/routes/groups.ts +133 -0
  106. package/apps/daemon/src/routes/messages.ts +29 -0
  107. package/apps/daemon/src/routes/misc.ts +239 -0
  108. package/apps/daemon/src/routes/profiles.ts +197 -0
  109. package/apps/daemon/src/routes/skills.ts +123 -0
  110. package/apps/daemon/src/routes/triggers.ts +29 -0
  111. package/apps/daemon/src/runtime/auth/openai-codex.ts +121 -0
  112. package/apps/daemon/src/runtime/auto-reply/heartbeat.ts +31 -0
  113. package/apps/daemon/src/runtime/index.ts +77 -0
  114. package/apps/daemon/src/runtime/memory/files.ts +103 -0
  115. package/apps/daemon/src/runtime/memory/qmd.ts +152 -0
  116. package/apps/daemon/src/runtime/memory/types.ts +16 -0
  117. package/apps/daemon/src/runtime/pi/events.ts +173 -0
  118. package/apps/daemon/src/runtime/pi/session.ts +536 -0
  119. package/apps/daemon/src/runtime/pi/tools.ts +85 -0
  120. package/apps/daemon/src/runtime/providers/catalog.ts +145 -0
  121. package/apps/daemon/src/runtime/providers/pi-adapter.ts +272 -0
  122. package/apps/daemon/src/runtime/providers/registry.ts +374 -0
  123. package/apps/daemon/src/runtime/providers/retry.ts +176 -0
  124. package/apps/daemon/src/runtime/providers/types.ts +33 -0
  125. package/apps/daemon/src/runtime/session/prompt.ts +83 -0
  126. package/apps/daemon/src/runtime/tools/bootstrap.ts +22 -0
  127. package/apps/daemon/src/runtime/tools/home.ts +114 -0
  128. package/apps/daemon/src/runtime/tools/memory.ts +81 -0
  129. package/apps/daemon/src/runtime/tools/messaging.ts +127 -0
  130. package/apps/daemon/src/runtime/tools/registry.ts +29 -0
  131. package/apps/daemon/src/runtime/tools/types.ts +13 -0
  132. package/apps/daemon/src/runtime/tools/web-extract.ts +110 -0
  133. package/apps/daemon/src/runtime/tools/web-ssrf.ts +245 -0
  134. package/apps/daemon/src/runtime/tools/web.ts +273 -0
  135. package/apps/daemon/src/runtime/worker/entry.ts +221 -0
  136. package/apps/daemon/src/runtime/worker/ipc-protocol.ts +75 -0
  137. package/apps/daemon/src/runtime/worker/spawn.ts +249 -0
  138. package/apps/daemon/test/core/agents.test.ts +319 -0
  139. package/apps/daemon/test/core/available-models.test.ts +63 -0
  140. package/apps/daemon/test/core/config.test.ts +99 -0
  141. package/apps/daemon/test/core/groups.test.ts +63 -0
  142. package/apps/daemon/test/core/helpers.ts +50 -0
  143. package/apps/daemon/test/core/identity.test.ts +85 -0
  144. package/apps/daemon/test/core/migrations.test.ts +83 -0
  145. package/apps/daemon/test/core/profiles.test.ts +182 -0
  146. package/apps/daemon/test/core/provider-models.test.ts +57 -0
  147. package/apps/daemon/test/core/provider-state.test.ts +36 -0
  148. package/apps/daemon/test/core/skill-meta.test.ts +45 -0
  149. package/apps/daemon/test/core/skills.test.ts +271 -0
  150. package/apps/daemon/test/core/triggers.test.ts +182 -0
  151. package/apps/daemon/test/core/web-tokens.test.ts +79 -0
  152. package/apps/daemon/test/cron.test.ts +90 -0
  153. package/apps/daemon/test/runtime/heartbeat.test.ts +34 -0
  154. package/apps/daemon/test/runtime/memory-qmd.test.ts +97 -0
  155. package/apps/daemon/test/runtime/memory.test.ts +78 -0
  156. package/apps/daemon/test/runtime/messaging.test.ts +213 -0
  157. package/apps/daemon/test/runtime/mock-server.ts +65 -0
  158. package/apps/daemon/test/runtime/openai-codex-auth.test.ts +116 -0
  159. package/apps/daemon/test/runtime/providers.test.ts +306 -0
  160. package/apps/daemon/test/runtime/retry.test.ts +191 -0
  161. package/apps/daemon/test/runtime/session-head.test.ts +90 -0
  162. package/apps/daemon/test/runtime/tools-home.test.ts +102 -0
  163. package/apps/daemon/test/runtime/tools-web.test.ts +206 -0
  164. package/apps/daemon/tsconfig.json +4 -0
  165. package/apps/mobile/README.md +60 -0
  166. package/apps/mobile/app/_layout.tsx +58 -0
  167. package/apps/mobile/app/agents/[id]/chat.tsx +486 -0
  168. package/apps/mobile/app/agents/[id]/index.tsx +166 -0
  169. package/apps/mobile/app/agents/index.tsx +212 -0
  170. package/apps/mobile/app/index.tsx +21 -0
  171. package/apps/mobile/app/pair.tsx +226 -0
  172. package/apps/mobile/app/settings.tsx +419 -0
  173. package/apps/mobile/app.json +49 -0
  174. package/apps/mobile/assets/adaptive-icon.png +0 -0
  175. package/apps/mobile/assets/favicon.png +0 -0
  176. package/apps/mobile/assets/icon.png +0 -0
  177. package/apps/mobile/assets/splash-icon.png +0 -0
  178. package/apps/mobile/babel.config.js +6 -0
  179. package/apps/mobile/metro.config.js +28 -0
  180. package/apps/mobile/package.json +44 -0
  181. package/apps/mobile/src/auth.ts +66 -0
  182. package/apps/mobile/src/pair-url.ts +48 -0
  183. package/apps/mobile/src/theme-context.tsx +88 -0
  184. package/apps/mobile/src/theme.ts +135 -0
  185. package/apps/mobile/test/pair-url.test.ts +46 -0
  186. package/apps/mobile/tsconfig.json +23 -0
  187. package/apps/web/components.json +25 -0
  188. package/apps/web/package.json +39 -0
  189. package/apps/web/public/baziu.svg +8 -0
  190. package/apps/web/src/components/AgentTabs.tsx +45 -0
  191. package/apps/web/src/components/BaziuLogo.tsx +21 -0
  192. package/apps/web/src/components/ChatPane.tsx +1033 -0
  193. package/apps/web/src/components/ConfigTabs.tsx +29 -0
  194. package/apps/web/src/components/CopyButton.tsx +68 -0
  195. package/apps/web/src/components/CreateGroupDialog.tsx +127 -0
  196. package/apps/web/src/components/FieldRow.tsx +94 -0
  197. package/apps/web/src/components/Footer.tsx +10 -0
  198. package/apps/web/src/components/PawIcon.tsx +15 -0
  199. package/apps/web/src/components/Sidebar.tsx +287 -0
  200. package/apps/web/src/components/SpawnDialog.tsx +129 -0
  201. package/apps/web/src/components/ThemeToggle.tsx +75 -0
  202. package/apps/web/src/components/TopNav.tsx +34 -0
  203. package/apps/web/src/components/ui/button.tsx +67 -0
  204. package/apps/web/src/components/ui/card.tsx +103 -0
  205. package/apps/web/src/components/ui/checkbox.tsx +31 -0
  206. package/apps/web/src/components/ui/dialog.tsx +168 -0
  207. package/apps/web/src/components/ui/input.tsx +19 -0
  208. package/apps/web/src/components/ui/label.tsx +22 -0
  209. package/apps/web/src/components/ui/radio-group.tsx +44 -0
  210. package/apps/web/src/components/ui/select.tsx +192 -0
  211. package/apps/web/src/components/ui/separator.tsx +26 -0
  212. package/apps/web/src/components/ui/table.tsx +116 -0
  213. package/apps/web/src/components/ui/tabs.tsx +88 -0
  214. package/apps/web/src/components/ui/textarea.tsx +18 -0
  215. package/apps/web/src/lib/auth.ts +50 -0
  216. package/apps/web/src/lib/daemon-client.ts +34 -0
  217. package/apps/web/src/lib/md.ts +45 -0
  218. package/apps/web/src/lib/utils.ts +6 -0
  219. package/apps/web/src/lib/wire-constants.ts +27 -0
  220. package/apps/web/src/routeTree.gen.ts +408 -0
  221. package/apps/web/src/router.tsx +20 -0
  222. package/apps/web/src/routes/__root.tsx +123 -0
  223. package/apps/web/src/routes/agents/$id/inbox.tsx +207 -0
  224. package/apps/web/src/routes/agents/$id/index.tsx +527 -0
  225. package/apps/web/src/routes/agents/$id/triggers.tsx +239 -0
  226. package/apps/web/src/routes/agents/index.tsx +265 -0
  227. package/apps/web/src/routes/api/$.ts +88 -0
  228. package/apps/web/src/routes/config/index.tsx +315 -0
  229. package/apps/web/src/routes/config/services.tsx +49 -0
  230. package/apps/web/src/routes/config/tokens.tsx +192 -0
  231. package/apps/web/src/routes/groups/$id/index.tsx +153 -0
  232. package/apps/web/src/routes/groups/$id/memory.tsx +321 -0
  233. package/apps/web/src/routes/groups/index.tsx +191 -0
  234. package/apps/web/src/routes/index.tsx +133 -0
  235. package/apps/web/src/routes/login.tsx +63 -0
  236. package/apps/web/src/routes/profiles/$id.tsx +549 -0
  237. package/apps/web/src/routes/profiles/index.tsx +458 -0
  238. package/apps/web/src/routes/skills/index.tsx +297 -0
  239. package/apps/web/src/routes/welcome.tsx +61 -0
  240. package/apps/web/src/styles.css +449 -0
  241. package/apps/web/tsconfig.json +25 -0
  242. package/apps/web/vite.config.ts +25 -0
  243. package/biome.json +23 -0
  244. package/docs/agent-engine.md +219 -0
  245. package/docs/architecture.md +627 -0
  246. package/docs/backlog/README.md +42 -0
  247. package/docs/backlog/draft/BAZ-001-a2a-federation-spike.md +125 -0
  248. package/docs/openclaw-reference.md +210 -0
  249. package/package.json +38 -0
  250. package/packages/api-types/package.json +11 -0
  251. package/packages/api-types/src/entities.ts +146 -0
  252. package/packages/api-types/src/events.ts +55 -0
  253. package/packages/api-types/src/index.ts +488 -0
  254. package/packages/api-types/src/memory.ts +15 -0
  255. package/packages/client/package.json +13 -0
  256. package/packages/client/src/index.ts +117 -0
  257. package/pnpm-workspace.yaml +3 -0
  258. package/tsconfig.base.json +23 -0
  259. package/tsconfig.json +11 -0
  260. package/vitest.config.ts +22 -0
@@ -0,0 +1,44 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function RadioGroup({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
12
+ return (
13
+ <RadioGroupPrimitive.Root
14
+ data-slot="radio-group"
15
+ className={cn("grid w-full gap-2", className)}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ function RadioGroupItem({
22
+ className,
23
+ ...props
24
+ }: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
25
+ return (
26
+ <RadioGroupPrimitive.Item
27
+ data-slot="radio-group-item"
28
+ className={cn(
29
+ "group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
30
+ className
31
+ )}
32
+ {...props}
33
+ >
34
+ <RadioGroupPrimitive.Indicator
35
+ data-slot="radio-group-indicator"
36
+ className="flex size-4 items-center justify-center"
37
+ >
38
+ <span className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground" />
39
+ </RadioGroupPrimitive.Indicator>
40
+ </RadioGroupPrimitive.Item>
41
+ )
42
+ }
43
+
44
+ export { RadioGroup, RadioGroupItem }
@@ -0,0 +1,192 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Select as SelectPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
8
+
9
+ function Select({
10
+ ...props
11
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
12
+ return <SelectPrimitive.Root data-slot="select" {...props} />
13
+ }
14
+
15
+ function SelectGroup({
16
+ className,
17
+ ...props
18
+ }: React.ComponentProps<typeof SelectPrimitive.Group>) {
19
+ return (
20
+ <SelectPrimitive.Group
21
+ data-slot="select-group"
22
+ className={cn("scroll-my-1 p-1", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function SelectValue({
29
+ ...props
30
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
31
+ return <SelectPrimitive.Value data-slot="select-value" {...props} />
32
+ }
33
+
34
+ function SelectTrigger({
35
+ className,
36
+ size = "default",
37
+ children,
38
+ ...props
39
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
40
+ size?: "sm" | "default"
41
+ }) {
42
+ return (
43
+ <SelectPrimitive.Trigger
44
+ data-slot="select-trigger"
45
+ data-size={size}
46
+ className={cn(
47
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
48
+ className
49
+ )}
50
+ {...props}
51
+ >
52
+ {children}
53
+ <SelectPrimitive.Icon asChild>
54
+ <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
55
+ </SelectPrimitive.Icon>
56
+ </SelectPrimitive.Trigger>
57
+ )
58
+ }
59
+
60
+ function SelectContent({
61
+ className,
62
+ children,
63
+ position = "item-aligned",
64
+ align = "center",
65
+ ...props
66
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
67
+ return (
68
+ <SelectPrimitive.Portal>
69
+ <SelectPrimitive.Content
70
+ data-slot="select-content"
71
+ data-align-trigger={position === "item-aligned"}
72
+ className={cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
73
+ position={position}
74
+ align={align}
75
+ {...props}
76
+ >
77
+ <SelectScrollUpButton />
78
+ <SelectPrimitive.Viewport
79
+ data-position={position}
80
+ className={cn(
81
+ "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
82
+ position === "popper" && ""
83
+ )}
84
+ >
85
+ {children}
86
+ </SelectPrimitive.Viewport>
87
+ <SelectScrollDownButton />
88
+ </SelectPrimitive.Content>
89
+ </SelectPrimitive.Portal>
90
+ )
91
+ }
92
+
93
+ function SelectLabel({
94
+ className,
95
+ ...props
96
+ }: React.ComponentProps<typeof SelectPrimitive.Label>) {
97
+ return (
98
+ <SelectPrimitive.Label
99
+ data-slot="select-label"
100
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
101
+ {...props}
102
+ />
103
+ )
104
+ }
105
+
106
+ function SelectItem({
107
+ className,
108
+ children,
109
+ ...props
110
+ }: React.ComponentProps<typeof SelectPrimitive.Item>) {
111
+ return (
112
+ <SelectPrimitive.Item
113
+ data-slot="select-item"
114
+ className={cn(
115
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
116
+ className
117
+ )}
118
+ {...props}
119
+ >
120
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
121
+ <SelectPrimitive.ItemIndicator>
122
+ <CheckIcon className="pointer-events-none" />
123
+ </SelectPrimitive.ItemIndicator>
124
+ </span>
125
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
126
+ </SelectPrimitive.Item>
127
+ )
128
+ }
129
+
130
+ function SelectSeparator({
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
134
+ return (
135
+ <SelectPrimitive.Separator
136
+ data-slot="select-separator"
137
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
138
+ {...props}
139
+ />
140
+ )
141
+ }
142
+
143
+ function SelectScrollUpButton({
144
+ className,
145
+ ...props
146
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
147
+ return (
148
+ <SelectPrimitive.ScrollUpButton
149
+ data-slot="select-scroll-up-button"
150
+ className={cn(
151
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
152
+ className
153
+ )}
154
+ {...props}
155
+ >
156
+ <ChevronUpIcon
157
+ />
158
+ </SelectPrimitive.ScrollUpButton>
159
+ )
160
+ }
161
+
162
+ function SelectScrollDownButton({
163
+ className,
164
+ ...props
165
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
166
+ return (
167
+ <SelectPrimitive.ScrollDownButton
168
+ data-slot="select-scroll-down-button"
169
+ className={cn(
170
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
171
+ className
172
+ )}
173
+ {...props}
174
+ >
175
+ <ChevronDownIcon
176
+ />
177
+ </SelectPrimitive.ScrollDownButton>
178
+ )
179
+ }
180
+
181
+ export {
182
+ Select,
183
+ SelectContent,
184
+ SelectGroup,
185
+ SelectItem,
186
+ SelectLabel,
187
+ SelectScrollDownButton,
188
+ SelectScrollUpButton,
189
+ SelectSeparator,
190
+ SelectTrigger,
191
+ SelectValue,
192
+ }
@@ -0,0 +1,26 @@
1
+ import * as React from "react"
2
+ import { Separator as SeparatorPrimitive } from "radix-ui"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ function Separator({
7
+ className,
8
+ orientation = "horizontal",
9
+ decorative = true,
10
+ ...props
11
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
12
+ return (
13
+ <SeparatorPrimitive.Root
14
+ data-slot="separator"
15
+ decorative={decorative}
16
+ orientation={orientation}
17
+ className={cn(
18
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ export { Separator }
@@ -0,0 +1,116 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ function Table({ className, ...props }: React.ComponentProps<"table">) {
8
+ return (
9
+ <div
10
+ data-slot="table-container"
11
+ className="relative w-full overflow-x-auto"
12
+ >
13
+ <table
14
+ data-slot="table"
15
+ className={cn("w-full caption-bottom text-sm", className)}
16
+ {...props}
17
+ />
18
+ </div>
19
+ )
20
+ }
21
+
22
+ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
23
+ return (
24
+ <thead
25
+ data-slot="table-header"
26
+ className={cn("[&_tr]:border-b", className)}
27
+ {...props}
28
+ />
29
+ )
30
+ }
31
+
32
+ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
33
+ return (
34
+ <tbody
35
+ data-slot="table-body"
36
+ className={cn("[&_tr:last-child]:border-0", className)}
37
+ {...props}
38
+ />
39
+ )
40
+ }
41
+
42
+ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
43
+ return (
44
+ <tfoot
45
+ data-slot="table-footer"
46
+ className={cn(
47
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ )
53
+ }
54
+
55
+ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
56
+ return (
57
+ <tr
58
+ data-slot="table-row"
59
+ className={cn(
60
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
69
+ return (
70
+ <th
71
+ data-slot="table-head"
72
+ className={cn(
73
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
74
+ className
75
+ )}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+
81
+ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
82
+ return (
83
+ <td
84
+ data-slot="table-cell"
85
+ className={cn(
86
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
87
+ className
88
+ )}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function TableCaption({
95
+ className,
96
+ ...props
97
+ }: React.ComponentProps<"caption">) {
98
+ return (
99
+ <caption
100
+ data-slot="table-caption"
101
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
102
+ {...props}
103
+ />
104
+ )
105
+ }
106
+
107
+ export {
108
+ Table,
109
+ TableHeader,
110
+ TableBody,
111
+ TableFooter,
112
+ TableHead,
113
+ TableRow,
114
+ TableCell,
115
+ TableCaption,
116
+ }
@@ -0,0 +1,88 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Tabs as TabsPrimitive } from "radix-ui"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ function Tabs({
8
+ className,
9
+ orientation = "horizontal",
10
+ ...props
11
+ }: React.ComponentProps<typeof TabsPrimitive.Root>) {
12
+ return (
13
+ <TabsPrimitive.Root
14
+ data-slot="tabs"
15
+ data-orientation={orientation}
16
+ className={cn(
17
+ "group/tabs flex gap-2 data-horizontal:flex-col",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ const tabsListVariants = cva(
26
+ "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
27
+ {
28
+ variants: {
29
+ variant: {
30
+ default: "bg-muted",
31
+ line: "gap-1 bg-transparent",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: "default",
36
+ },
37
+ }
38
+ )
39
+
40
+ function TabsList({
41
+ className,
42
+ variant = "default",
43
+ ...props
44
+ }: React.ComponentProps<typeof TabsPrimitive.List> &
45
+ VariantProps<typeof tabsListVariants>) {
46
+ return (
47
+ <TabsPrimitive.List
48
+ data-slot="tabs-list"
49
+ data-variant={variant}
50
+ className={cn(tabsListVariants({ variant }), className)}
51
+ {...props}
52
+ />
53
+ )
54
+ }
55
+
56
+ function TabsTrigger({
57
+ className,
58
+ ...props
59
+ }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
60
+ return (
61
+ <TabsPrimitive.Trigger
62
+ data-slot="tabs-trigger"
63
+ className={cn(
64
+ "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
65
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
66
+ "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
67
+ "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ function TabsContent({
76
+ className,
77
+ ...props
78
+ }: React.ComponentProps<typeof TabsPrimitive.Content>) {
79
+ return (
80
+ <TabsPrimitive.Content
81
+ data-slot="tabs-content"
82
+ className={cn("flex-1 text-sm outline-none", className)}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
@@ -0,0 +1,18 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
+ return (
7
+ <textarea
8
+ data-slot="textarea"
9
+ className={cn(
10
+ "flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ export { Textarea }
@@ -0,0 +1,50 @@
1
+ // Auth + first-run gate plumbing.
2
+ //
3
+ // `fetchAuthState` is a server fn that pings the daemon's /api/auth/me with
4
+ // the current request's bz_token cookie. It returns a typed result the root
5
+ // route's `beforeLoad` consumes to decide whether to redirect (`/login` for
6
+ // unauthenticated, `/welcome` until setup is complete). Keeping the daemon
7
+ // call in a server fn means the client bundle never ships the daemon URL or
8
+ // cookie machinery.
9
+
10
+ import { ApiClientError } from '@bazilion/client'
11
+ import { createServerFn } from '@tanstack/react-start'
12
+ import { daemonClient } from './daemon-client'
13
+
14
+ export interface AuthState {
15
+ authed: boolean
16
+ setupComplete: boolean
17
+ }
18
+
19
+ export const fetchAuthState = createServerFn({ method: 'GET' }).handler(
20
+ async (): Promise<AuthState> => {
21
+ try {
22
+ const res = await daemonClient().get<{ authed: boolean; setupComplete: boolean }>(
23
+ '/api/auth/me',
24
+ )
25
+ return { authed: res.authed, setupComplete: res.setupComplete }
26
+ } catch (err) {
27
+ if (err instanceof ApiClientError && err.status === 401) {
28
+ return { authed: false, setupComplete: false }
29
+ }
30
+ throw err
31
+ }
32
+ },
33
+ )
34
+
35
+ // Reachable without a token. The login form posts here (well, to /api/login).
36
+ // Note: /api/* is handled by the catch-all proxy + daemon's own auth, so we
37
+ // don't gate it from beforeLoad — it shortcircuits before the auth fetch.
38
+ export const PUBLIC_PATHS = new Set(['/login'])
39
+
40
+ // Authenticated users can still reach these prefixes before setup is done.
41
+ // Everything else redirects to /welcome until at least one provider has ≥1
42
+ // curated model.
43
+ const SETUP_OPEN_PREFIXES = ['/welcome', '/config']
44
+
45
+ export function isSetupOpen(path: string): boolean {
46
+ for (const prefix of SETUP_OPEN_PREFIXES) {
47
+ if (path === prefix || path.startsWith(`${prefix}/`)) return true
48
+ }
49
+ return false
50
+ }
@@ -0,0 +1,34 @@
1
+ // SSR-side daemon client for TanStack Start. SERVER-ONLY — do not import
2
+ // from any code path that ends up in the client bundle. The `getCookie`
3
+ // dependency reads request-scoped storage that doesn't exist in the
4
+ // browser, and Vite's import-protection enforces this at build time.
5
+ //
6
+ // For client-safe wire constants (DEFAULT_GROUP_ID, REASONING_LEVELS, …)
7
+ // import from `./wire-constants` instead.
8
+ //
9
+ // Server fns and route loaders running on the server can call
10
+ // `daemonClient()` to get a `BazilionClient` that auto-forwards the
11
+ // current request's `bz_token` cookie as a Bearer token to the daemon.
12
+ // That keeps daemon audit logs reflecting the actual user identity end
13
+ // to end, and lets the daemon's middleware do the auth + first-run check
14
+ // uniformly.
15
+ //
16
+ // Usage inside a server fn or beforeLoad:
17
+ //
18
+ // import { createServerFn } from '@tanstack/react-start'
19
+ // import { daemonClient } from '~/lib/daemon-client'
20
+ //
21
+ // const listAgents = createServerFn({ method: 'GET' })
22
+ // .handler(() => daemonClient().get<Agent[]>('/api/agents'))
23
+
24
+ import { type BazilionClient, createClient } from '@bazilion/client'
25
+ import { getCookie } from '@tanstack/react-start/server'
26
+
27
+ const DAEMON_URL = process.env.BAZILION_DAEMON ?? 'http://127.0.0.1:4321'
28
+
29
+ export function daemonClient(): BazilionClient {
30
+ const token = getCookie('bz_token') ?? ''
31
+ return createClient({ serverUrl: DAEMON_URL, token })
32
+ }
33
+
34
+ export const DAEMON_BASE_URL = DAEMON_URL
@@ -0,0 +1,45 @@
1
+ // Markdown rendering for chat output. marked produces HTML; DOMPurify strips
2
+ // any <script>, <iframe>, event handlers, and javascript: URIs. The LLM can
3
+ // emit arbitrary text — a prompt-injected response or a tool output echoing
4
+ // untrusted content could otherwise execute in this tab.
5
+
6
+ import DOMPurify from 'dompurify'
7
+ import { marked } from 'marked'
8
+
9
+ let installed = false
10
+
11
+ function install(): void {
12
+ if (installed) return
13
+ marked.setOptions({ breaks: true, gfm: true })
14
+ // Route every rendered <a> through a new tab. Clicking a link mid-stream in
15
+ // the same tab aborts the fetch and loses the in-flight turn; target=_blank
16
+ // + rel=noopener noreferrer keeps the chat alive and follows the standard
17
+ // security recommendation for user-content links.
18
+ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
19
+ if (node.nodeName === 'A') {
20
+ node.setAttribute('target', '_blank')
21
+ node.setAttribute('rel', 'noopener noreferrer')
22
+ }
23
+ })
24
+ installed = true
25
+ }
26
+
27
+ export function renderMd(text: string): string {
28
+ if (!text) return ''
29
+ if (typeof window === 'undefined') {
30
+ // SSR — DOMPurify needs a DOM. Return escaped text; the client will
31
+ // re-render once it hydrates.
32
+ return escapeHtml(text)
33
+ }
34
+ install()
35
+ try {
36
+ const html = marked.parse(text, { async: false }) as string
37
+ return DOMPurify.sanitize(html)
38
+ } catch {
39
+ return escapeHtml(text)
40
+ }
41
+ }
42
+
43
+ export function escapeHtml(s: string): string {
44
+ return String(s).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;')
45
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,27 @@
1
+ // Plain wire constants safe to import from any bundle (client or server).
2
+ //
3
+ // These mirror values defined in the daemon's core layer
4
+ // (`apps/daemon/src/core`) and re-exported through `@bazilion/api-types`. We
5
+ // re-declare them here rather than reaching into daemon source so the web
6
+ // app stays decoupled from Node-only deps (the architecture mandate is
7
+ // "apps/web never reaches into daemon source" — see CLAUDE.md). Daemon-side
8
+ // validation re-checks every wire string against the source of truth, so
9
+ // a drift here surfaces as a 4xx, never as silent corruption.
10
+
11
+ import type { ReasoningLevel } from '@bazilion/api-types'
12
+
13
+ /** Stable id for the auto-seeded `default` profile. */
14
+ export const DEFAULT_PROFILE_ID = 'default'
15
+
16
+ /** Stable id for the auto-seeded `default` group. */
17
+ export const DEFAULT_GROUP_ID = 'default'
18
+
19
+ /** Mirrors the daemon's REASONING_LEVELS (apps/daemon/src/core). */
20
+ export const REASONING_LEVELS: ReasoningLevel[] = [
21
+ 'off',
22
+ 'minimal',
23
+ 'low',
24
+ 'medium',
25
+ 'high',
26
+ 'xhigh',
27
+ ]