bazilion 0.0.0 → 0.1.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 (265) hide show
  1. package/README.md +53 -152
  2. package/dist/cli.js +2730 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/daemon.js +5888 -0
  5. package/dist/daemon.js.map +1 -0
  6. package/dist/worker.js +1830 -0
  7. package/dist/worker.js.map +1 -0
  8. package/package.json +57 -28
  9. package/.understand-anything/.understandignore +0 -25
  10. package/.understand-anything/fingerprints.json +0 -14267
  11. package/.understand-anything/knowledge-graph.json +0 -18128
  12. package/.understand-anything/meta.json +0 -6
  13. package/CLAUDE.md +0 -164
  14. package/apps/cli/package.json +0 -21
  15. package/apps/cli/src/auth-file.ts +0 -18
  16. package/apps/cli/src/client.ts +0 -37
  17. package/apps/cli/src/columnize.ts +0 -32
  18. package/apps/cli/src/commands/agent.ts +0 -574
  19. package/apps/cli/src/commands/auth.ts +0 -110
  20. package/apps/cli/src/commands/backup.ts +0 -135
  21. package/apps/cli/src/commands/completion.ts +0 -155
  22. package/apps/cli/src/commands/config.ts +0 -95
  23. package/apps/cli/src/commands/doctor.ts +0 -131
  24. package/apps/cli/src/commands/group.ts +0 -132
  25. package/apps/cli/src/commands/inbox.ts +0 -82
  26. package/apps/cli/src/commands/login.ts +0 -73
  27. package/apps/cli/src/commands/memory.ts +0 -106
  28. package/apps/cli/src/commands/profile.ts +0 -259
  29. package/apps/cli/src/commands/provider.ts +0 -170
  30. package/apps/cli/src/commands/send.ts +0 -24
  31. package/apps/cli/src/commands/serve.ts +0 -89
  32. package/apps/cli/src/commands/skill.ts +0 -120
  33. package/apps/cli/src/commands/token.ts +0 -148
  34. package/apps/cli/src/commands/trigger.ts +0 -129
  35. package/apps/cli/src/commands/uninstall.ts +0 -156
  36. package/apps/cli/src/index.ts +0 -196
  37. package/apps/cli/src/paths.ts +0 -12
  38. package/apps/cli/test/agent.test.ts +0 -213
  39. package/apps/cli/test/backup.test.ts +0 -95
  40. package/apps/cli/test/chat.test.ts +0 -539
  41. package/apps/cli/test/columnize.test.ts +0 -29
  42. package/apps/cli/test/completion.test.ts +0 -45
  43. package/apps/cli/test/config-page.test.ts +0 -151
  44. package/apps/cli/test/group.test.ts +0 -74
  45. package/apps/cli/test/helpers.ts +0 -70
  46. package/apps/cli/test/inbox-autodeliver.test.ts +0 -143
  47. package/apps/cli/test/inbox.test.ts +0 -147
  48. package/apps/cli/test/memory.test.ts +0 -69
  49. package/apps/cli/test/profile.test.ts +0 -110
  50. package/apps/cli/test/send.test.ts +0 -30
  51. package/apps/cli/test/server-fixture.ts +0 -212
  52. package/apps/cli/test/session-head.test.ts +0 -45
  53. package/apps/cli/test/skill.test.ts +0 -128
  54. package/apps/cli/test/token.test.ts +0 -109
  55. package/apps/cli/test/trigger.test.ts +0 -245
  56. package/apps/cli/tsconfig.json +0 -4
  57. package/apps/daemon/package.json +0 -31
  58. package/apps/daemon/src/app.ts +0 -41
  59. package/apps/daemon/src/core/agent/archive.ts +0 -8
  60. package/apps/daemon/src/core/agent/delete.ts +0 -30
  61. package/apps/daemon/src/core/agent/resolve.ts +0 -31
  62. package/apps/daemon/src/core/agent/spawn.ts +0 -95
  63. package/apps/daemon/src/core/agent/unarchive.ts +0 -11
  64. package/apps/daemon/src/core/availableModels.ts +0 -58
  65. package/apps/daemon/src/core/db/client.ts +0 -113
  66. package/apps/daemon/src/core/db/migrate.ts +0 -41
  67. package/apps/daemon/src/core/db/migrations/0001_init.sql +0 -179
  68. package/apps/daemon/src/core/group/delete.ts +0 -21
  69. package/apps/daemon/src/core/group/register.ts +0 -68
  70. package/apps/daemon/src/core/index.ts +0 -71
  71. package/apps/daemon/src/core/paths.ts +0 -56
  72. package/apps/daemon/src/core/profile/create.ts +0 -78
  73. package/apps/daemon/src/core/profile/delete.ts +0 -26
  74. package/apps/daemon/src/core/profile/identity.ts +0 -70
  75. package/apps/daemon/src/core/profile/load.ts +0 -45
  76. package/apps/daemon/src/core/profile/seed.ts +0 -74
  77. package/apps/daemon/src/core/profile/templates.ts +0 -60
  78. package/apps/daemon/src/core/profile/update.ts +0 -57
  79. package/apps/daemon/src/core/profile/validate.ts +0 -9
  80. package/apps/daemon/src/core/repos/agents.ts +0 -202
  81. package/apps/daemon/src/core/repos/config.ts +0 -78
  82. package/apps/daemon/src/core/repos/groups.ts +0 -55
  83. package/apps/daemon/src/core/repos/messages.ts +0 -127
  84. package/apps/daemon/src/core/repos/profiles.ts +0 -83
  85. package/apps/daemon/src/core/repos/providerModels.ts +0 -58
  86. package/apps/daemon/src/core/repos/providerState.ts +0 -37
  87. package/apps/daemon/src/core/repos/secrets.ts +0 -145
  88. package/apps/daemon/src/core/repos/skillMeta.ts +0 -49
  89. package/apps/daemon/src/core/repos/triggers.ts +0 -101
  90. package/apps/daemon/src/core/repos/webTokens.ts +0 -87
  91. package/apps/daemon/src/core/secrets.ts +0 -65
  92. package/apps/daemon/src/core/services.ts +0 -264
  93. package/apps/daemon/src/core/skills/discover.ts +0 -28
  94. package/apps/daemon/src/core/skills/import.ts +0 -136
  95. package/apps/daemon/src/core/skills/parse.ts +0 -52
  96. package/apps/daemon/src/core/skills/resolve.ts +0 -50
  97. package/apps/daemon/src/index.ts +0 -45
  98. package/apps/daemon/src/lib/agent-cancel.ts +0 -48
  99. package/apps/daemon/src/lib/agent-id.ts +0 -13
  100. package/apps/daemon/src/lib/agent-turn.ts +0 -56
  101. package/apps/daemon/src/lib/api-key.ts +0 -56
  102. package/apps/daemon/src/lib/auth.ts +0 -41
  103. package/apps/daemon/src/lib/cron.ts +0 -93
  104. package/apps/daemon/src/lib/ctx.ts +0 -80
  105. package/apps/daemon/src/lib/messaging-host.ts +0 -34
  106. package/apps/daemon/src/lib/middleware-auth.ts +0 -52
  107. package/apps/daemon/src/lib/scheduler.ts +0 -294
  108. package/apps/daemon/src/routes/agents.ts +0 -772
  109. package/apps/daemon/src/routes/auth-login.ts +0 -193
  110. package/apps/daemon/src/routes/config.ts +0 -267
  111. package/apps/daemon/src/routes/groups.ts +0 -133
  112. package/apps/daemon/src/routes/messages.ts +0 -29
  113. package/apps/daemon/src/routes/misc.ts +0 -239
  114. package/apps/daemon/src/routes/profiles.ts +0 -197
  115. package/apps/daemon/src/routes/skills.ts +0 -123
  116. package/apps/daemon/src/routes/triggers.ts +0 -29
  117. package/apps/daemon/src/runtime/auth/openai-codex.ts +0 -121
  118. package/apps/daemon/src/runtime/auto-reply/heartbeat.ts +0 -31
  119. package/apps/daemon/src/runtime/index.ts +0 -77
  120. package/apps/daemon/src/runtime/memory/files.ts +0 -103
  121. package/apps/daemon/src/runtime/memory/qmd.ts +0 -152
  122. package/apps/daemon/src/runtime/memory/types.ts +0 -16
  123. package/apps/daemon/src/runtime/pi/events.ts +0 -173
  124. package/apps/daemon/src/runtime/pi/session.ts +0 -536
  125. package/apps/daemon/src/runtime/pi/tools.ts +0 -85
  126. package/apps/daemon/src/runtime/providers/catalog.ts +0 -145
  127. package/apps/daemon/src/runtime/providers/pi-adapter.ts +0 -272
  128. package/apps/daemon/src/runtime/providers/registry.ts +0 -374
  129. package/apps/daemon/src/runtime/providers/retry.ts +0 -176
  130. package/apps/daemon/src/runtime/providers/types.ts +0 -33
  131. package/apps/daemon/src/runtime/session/prompt.ts +0 -83
  132. package/apps/daemon/src/runtime/tools/bootstrap.ts +0 -22
  133. package/apps/daemon/src/runtime/tools/home.ts +0 -114
  134. package/apps/daemon/src/runtime/tools/memory.ts +0 -81
  135. package/apps/daemon/src/runtime/tools/messaging.ts +0 -127
  136. package/apps/daemon/src/runtime/tools/registry.ts +0 -29
  137. package/apps/daemon/src/runtime/tools/types.ts +0 -13
  138. package/apps/daemon/src/runtime/tools/web-extract.ts +0 -110
  139. package/apps/daemon/src/runtime/tools/web-ssrf.ts +0 -245
  140. package/apps/daemon/src/runtime/tools/web.ts +0 -273
  141. package/apps/daemon/src/runtime/worker/entry.ts +0 -221
  142. package/apps/daemon/src/runtime/worker/ipc-protocol.ts +0 -75
  143. package/apps/daemon/src/runtime/worker/spawn.ts +0 -249
  144. package/apps/daemon/test/core/agents.test.ts +0 -319
  145. package/apps/daemon/test/core/available-models.test.ts +0 -63
  146. package/apps/daemon/test/core/config.test.ts +0 -99
  147. package/apps/daemon/test/core/groups.test.ts +0 -63
  148. package/apps/daemon/test/core/helpers.ts +0 -50
  149. package/apps/daemon/test/core/identity.test.ts +0 -85
  150. package/apps/daemon/test/core/migrations.test.ts +0 -83
  151. package/apps/daemon/test/core/profiles.test.ts +0 -182
  152. package/apps/daemon/test/core/provider-models.test.ts +0 -57
  153. package/apps/daemon/test/core/provider-state.test.ts +0 -36
  154. package/apps/daemon/test/core/skill-meta.test.ts +0 -45
  155. package/apps/daemon/test/core/skills.test.ts +0 -271
  156. package/apps/daemon/test/core/triggers.test.ts +0 -182
  157. package/apps/daemon/test/core/web-tokens.test.ts +0 -79
  158. package/apps/daemon/test/cron.test.ts +0 -90
  159. package/apps/daemon/test/runtime/heartbeat.test.ts +0 -34
  160. package/apps/daemon/test/runtime/memory-qmd.test.ts +0 -97
  161. package/apps/daemon/test/runtime/memory.test.ts +0 -78
  162. package/apps/daemon/test/runtime/messaging.test.ts +0 -213
  163. package/apps/daemon/test/runtime/mock-server.ts +0 -65
  164. package/apps/daemon/test/runtime/openai-codex-auth.test.ts +0 -116
  165. package/apps/daemon/test/runtime/providers.test.ts +0 -306
  166. package/apps/daemon/test/runtime/retry.test.ts +0 -191
  167. package/apps/daemon/test/runtime/session-head.test.ts +0 -90
  168. package/apps/daemon/test/runtime/tools-home.test.ts +0 -102
  169. package/apps/daemon/test/runtime/tools-web.test.ts +0 -206
  170. package/apps/daemon/tsconfig.json +0 -4
  171. package/apps/mobile/README.md +0 -60
  172. package/apps/mobile/app/_layout.tsx +0 -58
  173. package/apps/mobile/app/agents/[id]/chat.tsx +0 -486
  174. package/apps/mobile/app/agents/[id]/index.tsx +0 -166
  175. package/apps/mobile/app/agents/index.tsx +0 -212
  176. package/apps/mobile/app/index.tsx +0 -21
  177. package/apps/mobile/app/pair.tsx +0 -226
  178. package/apps/mobile/app/settings.tsx +0 -419
  179. package/apps/mobile/app.json +0 -49
  180. package/apps/mobile/assets/adaptive-icon.png +0 -0
  181. package/apps/mobile/assets/favicon.png +0 -0
  182. package/apps/mobile/assets/icon.png +0 -0
  183. package/apps/mobile/assets/splash-icon.png +0 -0
  184. package/apps/mobile/babel.config.js +0 -6
  185. package/apps/mobile/metro.config.js +0 -28
  186. package/apps/mobile/package.json +0 -44
  187. package/apps/mobile/src/auth.ts +0 -66
  188. package/apps/mobile/src/pair-url.ts +0 -48
  189. package/apps/mobile/src/theme-context.tsx +0 -88
  190. package/apps/mobile/src/theme.ts +0 -135
  191. package/apps/mobile/test/pair-url.test.ts +0 -46
  192. package/apps/mobile/tsconfig.json +0 -23
  193. package/apps/web/components.json +0 -25
  194. package/apps/web/package.json +0 -39
  195. package/apps/web/public/baziu.svg +0 -8
  196. package/apps/web/src/components/AgentTabs.tsx +0 -45
  197. package/apps/web/src/components/BaziuLogo.tsx +0 -21
  198. package/apps/web/src/components/ChatPane.tsx +0 -1033
  199. package/apps/web/src/components/ConfigTabs.tsx +0 -29
  200. package/apps/web/src/components/CopyButton.tsx +0 -68
  201. package/apps/web/src/components/CreateGroupDialog.tsx +0 -127
  202. package/apps/web/src/components/FieldRow.tsx +0 -94
  203. package/apps/web/src/components/Footer.tsx +0 -10
  204. package/apps/web/src/components/PawIcon.tsx +0 -15
  205. package/apps/web/src/components/Sidebar.tsx +0 -287
  206. package/apps/web/src/components/SpawnDialog.tsx +0 -129
  207. package/apps/web/src/components/ThemeToggle.tsx +0 -75
  208. package/apps/web/src/components/TopNav.tsx +0 -34
  209. package/apps/web/src/components/ui/button.tsx +0 -67
  210. package/apps/web/src/components/ui/card.tsx +0 -103
  211. package/apps/web/src/components/ui/checkbox.tsx +0 -31
  212. package/apps/web/src/components/ui/dialog.tsx +0 -168
  213. package/apps/web/src/components/ui/input.tsx +0 -19
  214. package/apps/web/src/components/ui/label.tsx +0 -22
  215. package/apps/web/src/components/ui/radio-group.tsx +0 -44
  216. package/apps/web/src/components/ui/select.tsx +0 -192
  217. package/apps/web/src/components/ui/separator.tsx +0 -26
  218. package/apps/web/src/components/ui/table.tsx +0 -116
  219. package/apps/web/src/components/ui/tabs.tsx +0 -88
  220. package/apps/web/src/components/ui/textarea.tsx +0 -18
  221. package/apps/web/src/lib/auth.ts +0 -50
  222. package/apps/web/src/lib/daemon-client.ts +0 -34
  223. package/apps/web/src/lib/md.ts +0 -45
  224. package/apps/web/src/lib/utils.ts +0 -6
  225. package/apps/web/src/lib/wire-constants.ts +0 -27
  226. package/apps/web/src/routeTree.gen.ts +0 -408
  227. package/apps/web/src/router.tsx +0 -20
  228. package/apps/web/src/routes/__root.tsx +0 -123
  229. package/apps/web/src/routes/agents/$id/inbox.tsx +0 -207
  230. package/apps/web/src/routes/agents/$id/index.tsx +0 -527
  231. package/apps/web/src/routes/agents/$id/triggers.tsx +0 -239
  232. package/apps/web/src/routes/agents/index.tsx +0 -265
  233. package/apps/web/src/routes/api/$.ts +0 -88
  234. package/apps/web/src/routes/config/index.tsx +0 -315
  235. package/apps/web/src/routes/config/services.tsx +0 -49
  236. package/apps/web/src/routes/config/tokens.tsx +0 -192
  237. package/apps/web/src/routes/groups/$id/index.tsx +0 -153
  238. package/apps/web/src/routes/groups/$id/memory.tsx +0 -321
  239. package/apps/web/src/routes/groups/index.tsx +0 -191
  240. package/apps/web/src/routes/index.tsx +0 -133
  241. package/apps/web/src/routes/login.tsx +0 -63
  242. package/apps/web/src/routes/profiles/$id.tsx +0 -549
  243. package/apps/web/src/routes/profiles/index.tsx +0 -458
  244. package/apps/web/src/routes/skills/index.tsx +0 -297
  245. package/apps/web/src/routes/welcome.tsx +0 -61
  246. package/apps/web/src/styles.css +0 -449
  247. package/apps/web/tsconfig.json +0 -25
  248. package/apps/web/vite.config.ts +0 -25
  249. package/biome.json +0 -23
  250. package/docs/agent-engine.md +0 -219
  251. package/docs/architecture.md +0 -627
  252. package/docs/backlog/README.md +0 -42
  253. package/docs/backlog/draft/BAZ-001-a2a-federation-spike.md +0 -125
  254. package/docs/openclaw-reference.md +0 -210
  255. package/packages/api-types/package.json +0 -11
  256. package/packages/api-types/src/entities.ts +0 -146
  257. package/packages/api-types/src/events.ts +0 -55
  258. package/packages/api-types/src/index.ts +0 -488
  259. package/packages/api-types/src/memory.ts +0 -15
  260. package/packages/client/package.json +0 -13
  261. package/packages/client/src/index.ts +0 -117
  262. package/pnpm-workspace.yaml +0 -3
  263. package/tsconfig.base.json +0 -23
  264. package/tsconfig.json +0 -11
  265. package/vitest.config.ts +0 -22
@@ -1,315 +0,0 @@
1
- import type { ProviderConfigEntry, ProviderConfigResponse } from '@bazilion/api-types'
2
- import { createFileRoute, useRouter } from '@tanstack/react-router'
3
- import { createServerFn } from '@tanstack/react-start'
4
- import { useState } from 'react'
5
- import { ConfigTabs } from '../../components/ConfigTabs'
6
- import { FieldRow } from '../../components/FieldRow'
7
- import { daemonClient } from '../../lib/daemon-client'
8
-
9
- interface OpenAICodexStatus {
10
- connected: boolean
11
- expiresAt: number | null
12
- accountId: string | null
13
- }
14
-
15
- interface ProvidersData {
16
- providers: ProviderConfigEntry[]
17
- openaiCodex: OpenAICodexStatus
18
- }
19
-
20
- const fetchProvidersData = createServerFn({ method: 'GET' }).handler(
21
- async (): Promise<ProvidersData> => {
22
- const c = daemonClient()
23
- const [{ providers }, openaiCodex] = await Promise.all([
24
- c.get<ProviderConfigResponse>('/api/config/providers'),
25
- c.get<OpenAICodexStatus>('/api/auth/openai'),
26
- ])
27
- return { providers, openaiCodex }
28
- },
29
- )
30
-
31
- export const Route = createFileRoute('/config/')({
32
- loader: () => fetchProvidersData(),
33
- component: ProvidersPage,
34
- })
35
-
36
- function ProvidersPage() {
37
- const { providers, openaiCodex } = Route.useLoaderData()
38
- return (
39
- <main className="mx-auto max-w-5xl px-6 py-8">
40
- <h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
41
- <ConfigTabs active="providers" />
42
- <p className="text-muted-foreground text-sm mb-6">
43
- Each card configures one LLM provider end to end: credentials (encrypted in the{' '}
44
- <code className="font-mono">secrets</code> table), URLs and IDs (plaintext in the{' '}
45
- <code className="font-mono">config</code> table), and the curated model list that
46
- powers profile / agent dropdowns.
47
- </p>
48
- {providers.map((p) => (
49
- <ProviderCard
50
- key={p.id}
51
- p={p}
52
- openaiCodexStatus={p.id === 'openai-codex' ? openaiCodex : undefined}
53
- />
54
- ))}
55
- </main>
56
- )
57
- }
58
-
59
- function ProviderCard({
60
- p,
61
- openaiCodexStatus,
62
- }: {
63
- p: ProviderConfigEntry
64
- openaiCodexStatus: OpenAICodexStatus | undefined
65
- }) {
66
- const router = useRouter()
67
- const [enabled, setEnabled] = useState(p.enabled)
68
- const [models, setModels] = useState(p.curated.join('\n'))
69
- const [savingModels, setSavingModels] = useState(false)
70
- const [modelStatus, setModelStatus] = useState<string | null>(null)
71
-
72
- async function toggle(next: boolean) {
73
- setEnabled(next)
74
- try {
75
- await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/enabled`, {
76
- method: 'PUT',
77
- headers: { 'content-type': 'application/json' },
78
- body: JSON.stringify({ enabled: next }),
79
- })
80
- await router.invalidate()
81
- } catch {
82
- setEnabled(!next)
83
- }
84
- }
85
-
86
- async function saveModels(e: React.FormEvent) {
87
- e.preventDefault()
88
- setSavingModels(true)
89
- setModelStatus(null)
90
- try {
91
- const list = models
92
- .split(/\r?\n/)
93
- .map((s) => s.trim())
94
- .filter(Boolean)
95
- const res = await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/models`, {
96
- method: 'PUT',
97
- headers: { 'content-type': 'application/json' },
98
- body: JSON.stringify({ models: list }),
99
- })
100
- if (!res.ok) {
101
- const j = (await res.json().catch(() => ({}))) as { error?: string }
102
- throw new Error(j.error ?? `${res.status} ${res.statusText}`)
103
- }
104
- setModelStatus('saved ✓')
105
- await router.invalidate()
106
- } catch (e) {
107
- setModelStatus(`error: ${(e as Error).message}`)
108
- } finally {
109
- setSavingModels(false)
110
- }
111
- }
112
-
113
- return (
114
- <section className="rounded-lg border bg-card mb-3 overflow-hidden">
115
- <header className="flex items-center gap-3 px-4 py-3">
116
- <span className="font-mono font-semibold">{p.id}</span>
117
- <span className="text-muted-foreground text-sm">· {p.displayName}</span>
118
- <label className="flex items-center gap-1.5 text-xs uppercase tracking-wide font-semibold cursor-pointer">
119
- <input
120
- type="checkbox"
121
- checked={enabled}
122
- onChange={(e) => toggle(e.target.checked)}
123
- className="size-4"
124
- />
125
- <span className={enabled ? 'text-emerald-700' : 'text-muted-foreground'}>
126
- {enabled ? 'enabled' : 'disabled'}
127
- </span>
128
- </label>
129
- <span className="ml-auto text-xs text-muted-foreground">
130
- {p.curated.length > 0 && <span>{p.curated.length} curated</span>}
131
- {p.catalog.length > 0 && <span> · {p.catalog.length} catalog</span>}
132
- {p.live && !p.live.error && <span> · {p.live.models.length} live</span>}
133
- </span>
134
- </header>
135
-
136
- {enabled && (
137
- <div className="border-t border-dashed px-4 py-3">
138
- {p.hint && <p className="text-xs text-muted-foreground mb-2">{p.hint}</p>}
139
-
140
- {p.id === 'openai-codex' && openaiCodexStatus && (
141
- <OpenAICodexCard status={openaiCodexStatus} />
142
- )}
143
-
144
- {p.fields.length === 0 && p.envHint && p.id !== 'openai-codex' && (
145
- <p className="text-xs text-muted-foreground">
146
- Credentials come from the process env: <code className="font-mono">{p.envHint}</code>
147
- </p>
148
- )}
149
-
150
- {p.fields.map((f) => (
151
- <FieldRow key={f.envVar} field={f} />
152
- ))}
153
-
154
- <h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
155
- curated models (one per line)
156
- </h4>
157
- <form onSubmit={saveModels}>
158
- <textarea
159
- value={models}
160
- onChange={(e) => setModels(e.target.value)}
161
- rows={Math.max(3, Math.min(8, models.split('\n').length))}
162
- className="w-full rounded-md border bg-background px-2 py-1.5 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30"
163
- placeholder={
164
- p.catalog.length === 0 && !p.live
165
- ? 'Type model names one per line, e.g. qwen3-coder-30b'
166
- : 'Click catalog chips below, or type names one per line'
167
- }
168
- />
169
- <div className="flex items-center gap-3 mt-2">
170
- <button
171
- type="submit"
172
- disabled={savingModels}
173
- className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50"
174
- >
175
- save models
176
- </button>
177
- {modelStatus && (
178
- <span className="text-xs text-muted-foreground">{modelStatus}</span>
179
- )}
180
- </div>
181
- </form>
182
-
183
- {p.catalog.length > 0 && (
184
- <>
185
- <h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
186
- catalog
187
- </h4>
188
- <ChipList
189
- items={p.catalog}
190
- onPick={(name) => setModels((m) => (m.includes(name) ? m : `${m}\n${name}`.trim()))}
191
- />
192
- </>
193
- )}
194
- {p.live && !p.live.error && p.live.models.length > 0 && (
195
- <>
196
- <h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
197
- live
198
- </h4>
199
- <ChipList
200
- items={p.live.models}
201
- onPick={(name) => setModels((m) => (m.includes(name) ? m : `${m}\n${name}`.trim()))}
202
- />
203
- </>
204
- )}
205
- {p.live?.error && (
206
- <p className="text-xs text-rose-700 mt-2">could not fetch: {p.live.error}</p>
207
- )}
208
- </div>
209
- )}
210
- </section>
211
- )
212
- }
213
-
214
- function ChipList({ items, onPick }: { items: string[]; onPick: (name: string) => void }) {
215
- return (
216
- <div className="flex flex-wrap gap-1.5 max-h-40 overflow-y-auto rounded-md border bg-background p-1.5">
217
- {items.map((m) => (
218
- <button
219
- key={m}
220
- type="button"
221
- onClick={() => onPick(m)}
222
- className="rounded border bg-card px-2 py-0.5 font-mono text-xs hover:border-primary hover:bg-accent"
223
- >
224
- {m}
225
- </button>
226
- ))}
227
- </div>
228
- )
229
- }
230
-
231
- function OpenAICodexCard({ status }: { status: OpenAICodexStatus }) {
232
- const router = useRouter()
233
- const [busy, setBusy] = useState(false)
234
- const [err, setErr] = useState<string | null>(null)
235
-
236
- async function connect() {
237
- setBusy(true)
238
- setErr(null)
239
- try {
240
- const res = await fetch('/api/auth/openai/login', { method: 'POST' })
241
- if (!res.ok) {
242
- const j = (await res.json().catch(() => ({}))) as { error?: string }
243
- throw new Error(j.error ?? `${res.status} ${res.statusText}`)
244
- }
245
- await router.invalidate()
246
- } catch (e) {
247
- setErr((e as Error).message)
248
- } finally {
249
- setBusy(false)
250
- }
251
- }
252
- async function disconnect() {
253
- setBusy(true)
254
- setErr(null)
255
- try {
256
- await fetch('/api/auth/openai', { method: 'DELETE' })
257
- await router.invalidate()
258
- } catch (e) {
259
- setErr((e as Error).message)
260
- } finally {
261
- setBusy(false)
262
- }
263
- }
264
-
265
- return (
266
- <div className="rounded-md border bg-muted/30 p-3 mb-3">
267
- {status.connected ? (
268
- <>
269
- <div className="flex flex-wrap gap-2 items-center mb-2">
270
- <span className="rounded-full bg-emerald-100 text-emerald-800 px-2 py-0.5 text-xs font-semibold uppercase">
271
- connected
272
- </span>
273
- {status.accountId && (
274
- <span className="text-xs text-muted-foreground">
275
- account <code className="font-mono">{status.accountId}</code>
276
- </span>
277
- )}
278
- {status.expiresAt && (
279
- <span className="text-xs text-muted-foreground">
280
- token expires{' '}
281
- {new Date(status.expiresAt).toISOString().replace(/\.\d+Z$/, 'Z')}
282
- </span>
283
- )}
284
- </div>
285
- <button
286
- type="button"
287
- onClick={disconnect}
288
- disabled={busy}
289
- className="rounded-md border px-3 py-1.5 text-sm text-rose-700 hover:bg-rose-50 disabled:opacity-50"
290
- >
291
- disconnect
292
- </button>
293
- </>
294
- ) : (
295
- <>
296
- <p className="text-xs text-muted-foreground mb-2">
297
- Sign in with your ChatGPT account — the OAuth flow opens a new browser tab. The
298
- loopback callback at <code className="font-mono">localhost:1455</code> only works
299
- when you're using the web UI on the same machine as the daemon. For remote setups,
300
- run <code className="font-mono">bazilion auth openai login</code> on the client.
301
- </p>
302
- <button
303
- type="button"
304
- onClick={connect}
305
- disabled={busy}
306
- className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50"
307
- >
308
- {busy ? 'opening browser…' : 'Connect ChatGPT →'}
309
- </button>
310
- </>
311
- )}
312
- {err && <p className="text-sm text-rose-700 mt-2">{err}</p>}
313
- </div>
314
- )
315
- }
@@ -1,49 +0,0 @@
1
- import type { ServiceConfigResponse } from '@bazilion/api-types'
2
- import { createFileRoute } from '@tanstack/react-router'
3
- import { createServerFn } from '@tanstack/react-start'
4
- import { ConfigTabs } from '../../components/ConfigTabs'
5
- import { FieldRow } from '../../components/FieldRow'
6
- import { daemonClient } from '../../lib/daemon-client'
7
-
8
- const fetchServices = createServerFn({ method: 'GET' }).handler(() =>
9
- daemonClient().get<ServiceConfigResponse>('/api/config/services'),
10
- )
11
-
12
- export const Route = createFileRoute('/config/services')({
13
- loader: () => fetchServices(),
14
- component: ServicesPage,
15
- })
16
-
17
- function ServicesPage() {
18
- const { services } = Route.useLoaderData()
19
- return (
20
- <main className="mx-auto max-w-5xl px-6 py-8">
21
- <h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
22
- <ConfigTabs active="services" />
23
-
24
- <p className="text-muted-foreground text-sm mb-6">
25
- Configuration for non-LLM integrations — web search, crawlers, and similar. Fields
26
- marked as secrets are encrypted in the <code className="font-mono">secrets</code>{' '}
27
- table; plaintext URLs and IDs live in the <code className="font-mono">config</code>{' '}
28
- table.
29
- </p>
30
-
31
- {services.length === 0 && (
32
- <p className="text-muted-foreground italic">(no services registered)</p>
33
- )}
34
-
35
- {services.map((s) => (
36
- <section key={s.id} className="rounded-lg border bg-card p-5 mb-3">
37
- <header className="flex items-center gap-2 mb-3">
38
- <span className="font-mono font-semibold">{s.id}</span>
39
- <span className="text-muted-foreground text-sm">· {s.displayName}</span>
40
- </header>
41
- {s.hint && <p className="text-xs text-muted-foreground mb-2">{s.hint}</p>}
42
- {s.fields.map((f) => (
43
- <FieldRow key={f.envVar} field={f} />
44
- ))}
45
- </section>
46
- ))}
47
- </main>
48
- )
49
- }
@@ -1,192 +0,0 @@
1
- import type { ListTokensResponse } from '@bazilion/api-types'
2
- import { createFileRoute, useRouter } from '@tanstack/react-router'
3
- import { createServerFn } from '@tanstack/react-start'
4
- import { useState } from 'react'
5
- import { ConfigTabs } from '../../components/ConfigTabs'
6
- import { daemonClient } from '../../lib/daemon-client'
7
-
8
- const fetchTokens = createServerFn({ method: 'POST' })
9
- .inputValidator((d: { all: boolean }) => d)
10
- .handler(({ data }) =>
11
- daemonClient().get<ListTokensResponse>(
12
- `/api/tokens${data.all ? '?includeRevoked=1' : ''}`,
13
- ),
14
- )
15
-
16
- export const Route = createFileRoute('/config/tokens')({
17
- validateSearch: (s: Record<string, unknown>): { all?: '1' } => ({
18
- all: s.all === '1' ? '1' : undefined,
19
- }),
20
- loaderDeps: ({ search }) => ({ all: search.all === '1' }),
21
- loader: ({ deps }) => fetchTokens({ data: deps }),
22
- component: TokensPage,
23
- })
24
-
25
- function fmtTs(ts: number): string {
26
- return new Date(ts).toISOString().slice(0, 16).replace('T', ' ')
27
- }
28
-
29
- function TokensPage() {
30
- const { tokens } = Route.useLoaderData()
31
- const { all } = Route.useSearch()
32
- const includeRevoked = all === '1'
33
- const router = useRouter()
34
- const [label, setLabel] = useState('')
35
- const [created, setCreated] = useState<string | null>(null)
36
- const [err, setErr] = useState<string | null>(null)
37
- const [busy, setBusy] = useState(false)
38
-
39
- async function mint(e: React.FormEvent) {
40
- e.preventDefault()
41
- setErr(null)
42
- setBusy(true)
43
- try {
44
- const res = await fetch('/api/tokens', {
45
- method: 'POST',
46
- headers: { 'content-type': 'application/json' },
47
- body: JSON.stringify({ label }),
48
- })
49
- if (!res.ok) {
50
- const j = (await res.json().catch(() => ({}))) as { error?: string }
51
- throw new Error(j.error ?? `${res.status} ${res.statusText}`)
52
- }
53
- const body = (await res.json()) as { token: string }
54
- setCreated(body.token)
55
- setLabel('')
56
- await router.invalidate()
57
- } catch (e) {
58
- setErr((e as Error).message)
59
- } finally {
60
- setBusy(false)
61
- }
62
- }
63
-
64
- async function revoke(id: string) {
65
- await fetch(`/api/tokens/${id}`, { method: 'DELETE' })
66
- await router.invalidate()
67
- }
68
-
69
- return (
70
- <main className="mx-auto max-w-5xl px-6 py-8">
71
- <h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
72
- <ConfigTabs active="tokens" />
73
-
74
- <p className="text-muted-foreground text-sm mb-6">
75
- Per-client credentials for the HTTP API and CLI. The row labelled{' '}
76
- <code className="font-mono">bootstrap</code> is the loopback token in{' '}
77
- <code className="font-mono">~/.bazilion/auth.json</code> — revoking it locks the local
78
- CLI out, so it can't be revoked from this page. Mint additional tokens here for
79
- Tailscale/LAN clients (mobile, remote machines); revoke any of those at any time.
80
- </p>
81
-
82
- <section className="rounded-lg border bg-card p-5 mb-6">
83
- <h3 className="font-serif text-xl mb-3">Mint a new token</h3>
84
- <form onSubmit={mint} className="flex gap-2 items-end mb-3">
85
- <label className="text-sm">
86
- Label
87
- <input
88
- type="text"
89
- value={label}
90
- onChange={(e) => setLabel(e.target.value)}
91
- required
92
- placeholder="e.g. laptop-tailscale"
93
- autoComplete="off"
94
- className="block mt-1 rounded-md border bg-background px-3 py-2 text-sm w-72"
95
- />
96
- </label>
97
- <button
98
- type="submit"
99
- disabled={busy}
100
- className="rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground disabled:opacity-50"
101
- >
102
- {busy ? 'creating…' : 'create'}
103
- </button>
104
- </form>
105
- {created && (
106
- <div className="rounded-md border border-amber-200 bg-amber-50 p-3">
107
- <p className="text-xs text-amber-800 mb-1">
108
- copy this token now — it is not recoverable later.
109
- </p>
110
- <pre className="font-mono text-xs whitespace-pre-wrap break-all">{created}</pre>
111
- </div>
112
- )}
113
- {err && <p className="text-sm text-rose-700">{err}</p>}
114
- </section>
115
-
116
- <div className="mb-3">
117
- <label className="text-sm flex items-center gap-2">
118
- <input
119
- type="checkbox"
120
- checked={includeRevoked}
121
- onChange={(e) => {
122
- window.location.assign(e.target.checked ? '/config/tokens?all=1' : '/config/tokens')
123
- }}
124
- />
125
- show revoked
126
- </label>
127
- </div>
128
-
129
- <table className="w-full text-sm">
130
- <thead className="text-left text-muted-foreground border-b">
131
- <tr>
132
- <th className="py-2">label</th>
133
- <th>id</th>
134
- <th>state</th>
135
- <th>created</th>
136
- <th>last used</th>
137
- <th />
138
- </tr>
139
- </thead>
140
- <tbody>
141
- {tokens.length === 0 && (
142
- <tr>
143
- <td colSpan={6} className="py-6 text-center text-muted-foreground italic">
144
- no tokens yet — mint one above
145
- </td>
146
- </tr>
147
- )}
148
- {tokens.map((t) => {
149
- const isBootstrap = t.label === 'bootstrap'
150
- return (
151
- <tr key={t.id} className="border-b last:border-0 hover:bg-accent/30">
152
- <td className="py-2">
153
- {t.label}
154
- {isBootstrap && (
155
- <span className="ml-2 text-[0.7em] uppercase tracking-wide text-muted-foreground">
156
- auth.json
157
- </span>
158
- )}
159
- </td>
160
- <td>
161
- <code className="font-mono text-xs">{t.id}</code>
162
- </td>
163
- <td>
164
- {t.revokedAt ? (
165
- <span className="text-muted-foreground">revoked</span>
166
- ) : (
167
- <span className="text-emerald-700">active</span>
168
- )}
169
- </td>
170
- <td className="text-muted-foreground text-xs">{fmtTs(t.createdAt)}</td>
171
- <td className="text-muted-foreground text-xs">
172
- {t.lastUsedAt ? fmtTs(t.lastUsedAt) : '(never)'}
173
- </td>
174
- <td>
175
- {!t.revokedAt && !isBootstrap && (
176
- <button
177
- type="button"
178
- onClick={() => revoke(t.id)}
179
- className="rounded-md border px-2 py-1 text-xs text-rose-700 hover:bg-rose-50"
180
- >
181
- revoke
182
- </button>
183
- )}
184
- </td>
185
- </tr>
186
- )
187
- })}
188
- </tbody>
189
- </table>
190
- </main>
191
- )
192
- }