bazilion 0.0.0 → 0.1.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 (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 +6460 -0
  5. package/dist/daemon.js.map +1 -0
  6. package/dist/worker.js +2176 -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,419 +0,0 @@
1
- import type { CreateTokenResponse, ListTokensResponse, WebToken } from '@bazilion/api-types'
2
- import { ApiClientError } from '@bazilion/client'
3
- import { router } from 'expo-router'
4
- import { useCallback, useEffect, useMemo, useState } from 'react'
5
- import {
6
- ActivityIndicator,
7
- Alert,
8
- FlatList,
9
- Pressable,
10
- ScrollView,
11
- StyleSheet,
12
- Text,
13
- TextInput,
14
- View,
15
- } from 'react-native'
16
- import { clearCredentials, clientFor, type Credentials, loadCredentials } from '@/src/auth'
17
- import { useColors, useThemeMode } from '@/src/theme-context'
18
- import { type Colors, fonts, radii, type ThemeMode } from '@/src/theme'
19
-
20
- type Load =
21
- | { kind: 'loading' }
22
- | { kind: 'ready'; creds: Credentials; tokens: WebToken[]; bootstrapId: string | null }
23
- | { kind: 'error'; message: string }
24
-
25
- export default function Settings() {
26
- const [load, setLoad] = useState<Load>({ kind: 'loading' })
27
- const [newLabel, setNewLabel] = useState('')
28
- const [minting, setMinting] = useState(false)
29
- const [mintedSecret, setMintedSecret] = useState<{ token: string; meta: WebToken } | null>(null)
30
- const colors = useColors()
31
- const styles = useMemo(() => makeStyles(colors), [colors])
32
-
33
- const fetchTokens = useCallback(async () => {
34
- setLoad({ kind: 'loading' })
35
- const creds = await loadCredentials()
36
- if (!creds) {
37
- router.replace('/pair')
38
- return
39
- }
40
- try {
41
- const res = await clientFor(creds).get<ListTokensResponse>('/api/tokens')
42
- // Identify the bootstrap row so the UI can hide its revoke button
43
- // (matches the daemon's 409-on-revoke guard).
44
- const bootstrap = res.tokens.find((t) => t.label === 'bootstrap')
45
- setLoad({
46
- kind: 'ready',
47
- creds,
48
- tokens: res.tokens,
49
- bootstrapId: bootstrap?.id ?? null,
50
- })
51
- } catch (err) {
52
- if (err instanceof ApiClientError && err.status === 401) {
53
- await clearCredentials()
54
- router.replace('/pair')
55
- return
56
- }
57
- const message = err instanceof Error ? err.message : 'unknown error'
58
- setLoad({ kind: 'error', message })
59
- }
60
- }, [])
61
-
62
- useEffect(() => {
63
- fetchTokens()
64
- }, [fetchTokens])
65
-
66
- const onMint = useCallback(async () => {
67
- if (load.kind !== 'ready' || minting) return
68
- const label = newLabel.trim()
69
- if (!label) return
70
- setMinting(true)
71
- try {
72
- const res = await clientFor(load.creds).post<CreateTokenResponse>('/api/tokens', { label })
73
- setMintedSecret({ token: res.token, meta: res.meta })
74
- setNewLabel('')
75
- await fetchTokens()
76
- } catch (err) {
77
- const message = err instanceof Error ? err.message : 'unknown error'
78
- Alert.alert('Could not mint token', message)
79
- } finally {
80
- setMinting(false)
81
- }
82
- }, [load, minting, newLabel, fetchTokens])
83
-
84
- const onRevoke = useCallback(
85
- async (id: string) => {
86
- if (load.kind !== 'ready') return
87
- Alert.alert(
88
- 'Revoke token?',
89
- 'Devices using this token will lose access immediately.',
90
- [
91
- { text: 'Cancel', style: 'cancel' },
92
- {
93
- text: 'Revoke',
94
- style: 'destructive',
95
- onPress: async () => {
96
- try {
97
- await clientFor(load.creds).del(`/api/tokens/${id}`)
98
- await fetchTokens()
99
- } catch (err) {
100
- const message = err instanceof Error ? err.message : 'unknown error'
101
- Alert.alert('Could not revoke', message)
102
- }
103
- },
104
- },
105
- ],
106
- { cancelable: true },
107
- )
108
- },
109
- [load, fetchTokens],
110
- )
111
-
112
- const onUnpair = useCallback(() => {
113
- Alert.alert(
114
- 'Unpair this device?',
115
- 'You will need to scan a new pairing QR to reconnect.',
116
- [
117
- { text: 'Cancel', style: 'cancel' },
118
- {
119
- text: 'Unpair',
120
- style: 'destructive',
121
- onPress: async () => {
122
- await clearCredentials()
123
- router.replace('/pair')
124
- },
125
- },
126
- ],
127
- { cancelable: true },
128
- )
129
- }, [])
130
-
131
- if (load.kind === 'loading') {
132
- return (
133
- <View style={styles.centered}>
134
- <ActivityIndicator />
135
- </View>
136
- )
137
- }
138
-
139
- if (load.kind === 'error') {
140
- return (
141
- <View style={styles.centered}>
142
- <Text style={styles.errorTitle}>Couldn't load settings</Text>
143
- <Text style={styles.errorBody}>{load.message}</Text>
144
- <Pressable style={styles.primaryBtn} onPress={fetchTokens}>
145
- <Text style={styles.primaryBtnText}>Retry</Text>
146
- </Pressable>
147
- <Pressable style={styles.linkBtn} onPress={onUnpair}>
148
- <Text style={styles.linkBtnText}>Unpair</Text>
149
- </Pressable>
150
- </View>
151
- )
152
- }
153
-
154
- const tokenPreview = `${load.creds.token.slice(0, 6)}…${load.creds.token.slice(-4)}`
155
-
156
- return (
157
- <ScrollView style={styles.screen} contentContainerStyle={styles.content}>
158
- <Section label="server">
159
- <Text style={styles.mono}>{load.creds.server}</Text>
160
- </Section>
161
-
162
- <Section label="this device's token">
163
- <Text style={styles.mono}>{tokenPreview}</Text>
164
- </Section>
165
-
166
- <View style={styles.divider} />
167
-
168
- <Section label="theme">
169
- <ThemePicker />
170
- </Section>
171
-
172
- <View style={styles.divider} />
173
-
174
- <Section label="mint a new token">
175
- <View style={styles.mintRow}>
176
- <TextInput
177
- value={newLabel}
178
- onChangeText={setNewLabel}
179
- placeholder="e.g. tablet, laptop"
180
- placeholderTextColor="#aaa"
181
- style={styles.mintInput}
182
- editable={!minting}
183
- autoCapitalize="none"
184
- />
185
- <Pressable
186
- onPress={onMint}
187
- disabled={minting || !newLabel.trim()}
188
- style={({ pressed }) => [
189
- styles.mintBtn,
190
- (minting || !newLabel.trim()) && styles.mintBtnDisabled,
191
- pressed && styles.mintBtnPressed,
192
- ]}
193
- >
194
- <Text style={styles.mintBtnText}>{minting ? '…' : 'Mint'}</Text>
195
- </Pressable>
196
- </View>
197
- {mintedSecret ? (
198
- <View style={styles.mintedBox}>
199
- <Text style={styles.mintedLabel}>new token (shown once):</Text>
200
- <Text style={styles.mintedToken} selectable>
201
- {mintedSecret.token}
202
- </Text>
203
- <Text style={styles.mintedHint}>
204
- copy this now — it cannot be retrieved later. label: {mintedSecret.meta.label}
205
- </Text>
206
- </View>
207
- ) : null}
208
- </Section>
209
-
210
- <Section label={`tokens (${load.tokens.length})`}>
211
- <FlatList
212
- data={load.tokens}
213
- scrollEnabled={false}
214
- keyExtractor={(t) => t.id}
215
- renderItem={({ item }) => (
216
- <TokenRow
217
- token={item}
218
- isBootstrap={item.id === load.bootstrapId}
219
- onRevoke={() => onRevoke(item.id)}
220
- />
221
- )}
222
- ItemSeparatorComponent={() => <View style={styles.tokenSep} />}
223
- />
224
- </Section>
225
-
226
- <View style={styles.divider} />
227
-
228
- <Pressable
229
- onPress={onUnpair}
230
- style={({ pressed }) => [styles.dangerBtn, pressed && styles.dangerBtnPressed]}
231
- >
232
- <Text style={styles.dangerBtnText}>Unpair this device</Text>
233
- </Pressable>
234
- </ScrollView>
235
- )
236
- }
237
-
238
- function Section({ label, children }: { label: string; children: React.ReactNode }) {
239
- const colors = useColors()
240
- const styles = useMemo(() => makeStyles(colors), [colors])
241
- return (
242
- <View style={styles.section}>
243
- <Text style={styles.sectionLabel}>{label}</Text>
244
- <View style={styles.sectionBody}>{children}</View>
245
- </View>
246
- )
247
- }
248
-
249
- function TokenRow({
250
- token,
251
- isBootstrap,
252
- onRevoke,
253
- }: {
254
- token: WebToken
255
- isBootstrap: boolean
256
- onRevoke: () => void
257
- }) {
258
- const colors = useColors()
259
- const styles = useMemo(() => makeStyles(colors), [colors])
260
- const status = token.revokedAt ? 'revoked' : 'active'
261
- const last = token.lastUsedAt ? new Date(token.lastUsedAt).toLocaleString() : '(never used)'
262
- return (
263
- <View style={styles.tokenRow}>
264
- <View style={styles.tokenInfo}>
265
- <Text style={styles.tokenLabel}>
266
- {token.label} {isBootstrap ? <Text style={styles.tokenBootstrap}>· bootstrap</Text> : null}
267
- </Text>
268
- <Text style={styles.tokenMeta}>
269
- {status} · {last}
270
- </Text>
271
- </View>
272
- {!isBootstrap && !token.revokedAt ? (
273
- <Pressable onPress={onRevoke} hitSlop={10}>
274
- <Text style={styles.tokenRevoke}>Revoke</Text>
275
- </Pressable>
276
- ) : null}
277
- </View>
278
- )
279
- }
280
-
281
- const THEME_OPTIONS: { value: ThemeMode; label: string }[] = [
282
- { value: 'system', label: 'System' },
283
- { value: 'light', label: 'Light' },
284
- { value: 'dark', label: 'Dark' },
285
- ]
286
-
287
- function ThemePicker() {
288
- const colors = useColors()
289
- const styles = useMemo(() => makeStyles(colors), [colors])
290
- const [mode, setMode] = useThemeMode()
291
- return (
292
- <View style={styles.segmentedRow}>
293
- {THEME_OPTIONS.map((opt) => {
294
- const active = mode === opt.value
295
- return (
296
- <Pressable
297
- key={opt.value}
298
- onPress={() => {
299
- void setMode(opt.value)
300
- }}
301
- style={[styles.segment, active && styles.segmentActive]}
302
- >
303
- <Text style={[styles.segmentText, active && styles.segmentTextActive]}>{opt.label}</Text>
304
- </Pressable>
305
- )
306
- })}
307
- </View>
308
- )
309
- }
310
-
311
- const makeStyles = (colors: Colors) =>
312
- StyleSheet.create({
313
- screen: { flex: 1, backgroundColor: colors.background },
314
- content: { padding: 20, gap: 4 },
315
- centered: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 24, gap: 12 },
316
- section: { marginTop: 16 },
317
- sectionLabel: {
318
- fontSize: 11,
319
- color: colors.mocha,
320
- textTransform: 'uppercase',
321
- letterSpacing: 0.5,
322
- marginBottom: 6,
323
- fontFamily: fonts.bodyMedium,
324
- },
325
- sectionBody: { gap: 4 },
326
- mono: { fontFamily: fonts.mono, fontSize: 13, color: colors.charcoal },
327
- divider: { height: StyleSheet.hairlineWidth, backgroundColor: colors.border, marginVertical: 16 },
328
- mintRow: { flexDirection: 'row', gap: 8, alignItems: 'center' },
329
- mintInput: {
330
- flex: 1,
331
- paddingHorizontal: 12,
332
- paddingVertical: 10,
333
- borderRadius: radii.md,
334
- backgroundColor: colors.ivory,
335
- fontSize: 14,
336
- color: colors.foreground,
337
- fontFamily: fonts.body,
338
- },
339
- mintBtn: {
340
- paddingHorizontal: 16,
341
- paddingVertical: 10,
342
- borderRadius: radii.md,
343
- backgroundColor: colors.sapphire,
344
- },
345
- mintBtnDisabled: { backgroundColor: colors.mochaLight },
346
- mintBtnPressed: { backgroundColor: colors.sapphireDeep },
347
- mintBtnText: { color: colors.primaryForeground, fontSize: 14, fontFamily: fonts.bodyMedium },
348
- mintedBox: {
349
- marginTop: 10,
350
- padding: 12,
351
- borderRadius: radii.md,
352
- backgroundColor: colors.sapphireGlow,
353
- borderWidth: StyleSheet.hairlineWidth,
354
- borderColor: colors.sapphire,
355
- gap: 6,
356
- },
357
- mintedLabel: {
358
- fontSize: 11,
359
- color: colors.accentForeground,
360
- textTransform: 'uppercase',
361
- letterSpacing: 0.5,
362
- fontFamily: fonts.bodyMedium,
363
- },
364
- mintedToken: { fontFamily: fonts.mono, fontSize: 12, color: colors.charcoal },
365
- mintedHint: { fontSize: 11, color: colors.accentForeground, fontFamily: fonts.body },
366
- tokenRow: {
367
- flexDirection: 'row',
368
- alignItems: 'center',
369
- paddingVertical: 10,
370
- gap: 12,
371
- },
372
- tokenSep: { height: StyleSheet.hairlineWidth, backgroundColor: colors.frost },
373
- tokenInfo: { flex: 1 },
374
- tokenLabel: { fontSize: 14, color: colors.foreground, fontFamily: fonts.body },
375
- tokenBootstrap: { color: colors.mochaLight, fontSize: 11, fontFamily: fonts.body },
376
- tokenMeta: { fontSize: 11, color: colors.mochaLight, marginTop: 2, fontFamily: fonts.body },
377
- tokenRevoke: { color: colors.destructive, fontSize: 13, fontFamily: fonts.bodyMedium },
378
- primaryBtn: {
379
- marginTop: 12,
380
- paddingHorizontal: 20,
381
- paddingVertical: 10,
382
- borderRadius: radii.md,
383
- backgroundColor: colors.sapphire,
384
- },
385
- primaryBtnText: { color: colors.primaryForeground, fontSize: 14, fontFamily: fonts.bodyMedium },
386
- linkBtn: { marginTop: 4, padding: 8 },
387
- linkBtnText: { color: colors.mocha, fontSize: 13, fontFamily: fonts.body },
388
- dangerBtn: {
389
- marginTop: 8,
390
- paddingVertical: 12,
391
- borderRadius: radii.md,
392
- backgroundColor: colors.card,
393
- borderWidth: 1,
394
- borderColor: colors.destructive,
395
- alignItems: 'center',
396
- },
397
- // ~10% destructive tint, tracks theme via the hex-alpha-suffix trick.
398
- dangerBtnPressed: { backgroundColor: `${colors.destructive}1A` },
399
- dangerBtnText: { color: colors.destructive, fontSize: 14, fontFamily: fonts.bodyMedium },
400
- errorTitle: { fontSize: 18, fontFamily: fonts.bodyBold, color: colors.foreground },
401
- errorBody: { color: colors.destructive, textAlign: 'center', fontFamily: fonts.body },
402
- segmentedRow: {
403
- flexDirection: 'row',
404
- backgroundColor: colors.ivory,
405
- borderRadius: radii.md,
406
- padding: 2,
407
- gap: 2,
408
- },
409
- segment: {
410
- flex: 1,
411
- paddingVertical: 8,
412
- paddingHorizontal: 12,
413
- borderRadius: radii.sm,
414
- alignItems: 'center',
415
- },
416
- segmentActive: { backgroundColor: colors.card },
417
- segmentText: { color: colors.mocha, fontSize: 13, fontFamily: fonts.body },
418
- segmentTextActive: { color: colors.foreground, fontFamily: fonts.bodyMedium },
419
- })
@@ -1,49 +0,0 @@
1
- {
2
- "expo": {
3
- "name": "Bazilion",
4
- "slug": "bazilion",
5
- "version": "0.0.1",
6
- "orientation": "portrait",
7
- "scheme": "bazilion",
8
- "userInterfaceStyle": "automatic",
9
- "newArchEnabled": true,
10
- "icon": "./assets/icon.png",
11
- "splash": {
12
- "image": "./assets/splash-icon.png",
13
- "resizeMode": "contain",
14
- "backgroundColor": "#F5F0E8"
15
- },
16
- "ios": {
17
- "supportsTablet": true,
18
- "bundleIdentifier": "dev.bazilion.mobile"
19
- },
20
- "android": {
21
- "package": "dev.bazilion.mobile",
22
- "adaptiveIcon": {
23
- "foregroundImage": "./assets/adaptive-icon.png",
24
- "backgroundColor": "#F5F0E8"
25
- }
26
- },
27
- "web": {
28
- "favicon": "./assets/favicon.png"
29
- },
30
- "plugins": [
31
- "expo-router",
32
- [
33
- "expo-camera",
34
- {
35
- "cameraPermission": "Allow Bazilion to use the camera to scan pairing QR codes."
36
- }
37
- ],
38
- [
39
- "expo-secure-store",
40
- {
41
- "faceIDPermission": "Allow Bazilion to authenticate with Face ID to unlock stored credentials."
42
- }
43
- ]
44
- ],
45
- "experiments": {
46
- "typedRoutes": true
47
- }
48
- }
49
- }
Binary file
Binary file
Binary file
@@ -1,6 +0,0 @@
1
- module.exports = (api) => {
2
- api.cache(true)
3
- return {
4
- presets: ['babel-preset-expo'],
5
- }
6
- }
@@ -1,28 +0,0 @@
1
- // pnpm + Expo monorepo config.
2
- //
3
- // - `watchFolders` gets the workspace root APPENDED (not replaced) so Metro
4
- // picks up live edits to `@bazilion/client` / `@bazilion/api-types` during
5
- // dev while still keeping Expo's own watched paths.
6
- //
7
- // - `nodeModulesPaths` also includes the workspace root's `node_modules` so
8
- // hoisted deps resolve. Hierarchical lookup stays enabled (the Expo
9
- // default) — this lets Metro fall back to pnpm's `.pnpm/*` symlink store
10
- // for transitive peers that aren't hoisted to `apps/mobile/node_modules`.
11
- // Safe as long as there's exactly one copy of `react-native` / `react` in
12
- // the tree; a fresh `pnpm install` after SDK bumps keeps it that way.
13
-
14
- const { getDefaultConfig } = require('expo/metro-config')
15
- const path = require('node:path')
16
-
17
- const projectRoot = __dirname
18
- const workspaceRoot = path.resolve(projectRoot, '../..')
19
-
20
- const config = getDefaultConfig(projectRoot)
21
-
22
- config.watchFolders = [...(config.watchFolders ?? []), workspaceRoot]
23
- config.resolver.nodeModulesPaths = [
24
- path.resolve(projectRoot, 'node_modules'),
25
- path.resolve(workspaceRoot, 'node_modules'),
26
- ]
27
-
28
- module.exports = config
@@ -1,44 +0,0 @@
1
- {
2
- "name": "@bazilion/mobile",
3
- "version": "0.0.0",
4
- "private": true,
5
- "main": "expo-router/entry",
6
- "scripts": {
7
- "start": "expo start",
8
- "ios": "expo start --ios",
9
- "android": "expo start --android",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "@babel/runtime": "^7.25.0",
14
- "@bazilion/api-types": "workspace:*",
15
- "@bazilion/client": "workspace:*",
16
- "@expo-google-fonts/dm-sans": "^0.4.2",
17
- "@expo-google-fonts/dm-serif-display": "^0.4.2",
18
- "@expo-google-fonts/jetbrains-mono": "^0.4.1",
19
- "@expo/metro-runtime": "^6.1.2",
20
- "@react-navigation/elements": "^2.9.14",
21
- "expo": "^54.0.0",
22
- "expo-camera": "~17.0.10",
23
- "expo-constants": "~18.0.13",
24
- "expo-font": "^55.0.6",
25
- "expo-linking": "~8.0.11",
26
- "expo-router": "~6.0.23",
27
- "expo-secure-store": "~15.0.8",
28
- "expo-status-bar": "~3.0.9",
29
- "react": "19.1.0",
30
- "react-dom": "19.1.0",
31
- "react-native": "0.81.5",
32
- "react-native-gesture-handler": "~2.28.0",
33
- "react-native-markdown-display": "^7.0.2",
34
- "react-native-reanimated": "~4.1.1",
35
- "react-native-safe-area-context": "~5.6.0",
36
- "react-native-screens": "~4.16.0",
37
- "react-native-web": "^0.21.0",
38
- "react-native-worklets": "0.5.1"
39
- },
40
- "devDependencies": {
41
- "@types/react": "~19.1.10",
42
- "typescript": "^5.7.0"
43
- }
44
- }
@@ -1,66 +0,0 @@
1
- import { type BazilionClient, createClient } from '@bazilion/client'
2
- import * as SecureStore from 'expo-secure-store'
3
-
4
- const KEY_SERVER = 'bazilion.server'
5
- const KEY_TOKEN = 'bazilion.token'
6
-
7
- export interface Credentials {
8
- server: string
9
- token: string
10
- }
11
-
12
- export async function loadCredentials(): Promise<Credentials | null> {
13
- const [server, token] = await Promise.all([
14
- SecureStore.getItemAsync(KEY_SERVER),
15
- SecureStore.getItemAsync(KEY_TOKEN),
16
- ])
17
- if (!server || !token) return null
18
- return { server, token }
19
- }
20
-
21
- export async function saveCredentials(creds: Credentials): Promise<void> {
22
- await Promise.all([
23
- SecureStore.setItemAsync(KEY_SERVER, creds.server),
24
- SecureStore.setItemAsync(KEY_TOKEN, creds.token),
25
- ])
26
- }
27
-
28
- export async function clearCredentials(): Promise<void> {
29
- await Promise.all([
30
- SecureStore.deleteItemAsync(KEY_SERVER),
31
- SecureStore.deleteItemAsync(KEY_TOKEN),
32
- ])
33
- }
34
-
35
- /**
36
- * Probe the daemon so we surface a clear error on the pairing screen instead
37
- * of a confusing network failure on the first protected request. 5-second
38
- * timeout because the daemon is a local-network service — if it can't answer
39
- * in that long, something's wrong.
40
- */
41
- export async function verifyCredentials(creds: Credentials): Promise<void> {
42
- const ctrl = new AbortController()
43
- const timer = setTimeout(() => ctrl.abort(), 5000)
44
- try {
45
- const res = await fetch(`${creds.server}/api/health`, {
46
- headers: {
47
- authorization: `Bearer ${creds.token}`,
48
- origin: creds.server,
49
- },
50
- signal: ctrl.signal,
51
- })
52
- if (res.status === 401) throw new Error('server rejected the token')
53
- if (!res.ok) throw new Error(`server returned ${res.status} from /api/health`)
54
- } catch (err) {
55
- if (err instanceof Error && err.name === 'AbortError') {
56
- throw new Error(`could not reach ${creds.server} within 5s`)
57
- }
58
- throw err
59
- } finally {
60
- clearTimeout(timer)
61
- }
62
- }
63
-
64
- export function clientFor(creds: Credentials): BazilionClient {
65
- return createClient({ serverUrl: creds.server, token: creds.token })
66
- }
@@ -1,48 +0,0 @@
1
- export interface ParsedPairing {
2
- server: string
3
- token: string
4
- }
5
-
6
- export class PairUrlError extends Error {
7
- constructor(message: string) {
8
- super(message)
9
- this.name = 'PairUrlError'
10
- }
11
- }
12
-
13
- /**
14
- * Parse a `bazilion://pair?server=<url>&token=<t>` URL emitted by
15
- * `bazilion token create --qr`. The scheme and host are both mandatory so a
16
- * stray http(s) URL or a typo surfaces as a clear error instead of a
17
- * confusing downstream network failure.
18
- */
19
- export function parsePairingUrl(raw: string): ParsedPairing {
20
- let url: URL
21
- try {
22
- url = new URL(raw)
23
- } catch {
24
- throw new PairUrlError(`not a valid URL: ${raw}`)
25
- }
26
- if (url.protocol !== 'bazilion:') {
27
- throw new PairUrlError(`expected bazilion:// scheme, got ${url.protocol}`)
28
- }
29
- // Custom-scheme URLs parse `pair` as the hostname, not pathname.
30
- if (url.hostname !== 'pair') {
31
- throw new PairUrlError(`expected bazilion://pair, got bazilion://${url.hostname}`)
32
- }
33
- const server = url.searchParams.get('server')
34
- const token = url.searchParams.get('token')
35
- if (!server) throw new PairUrlError('missing ?server=')
36
- if (!token) throw new PairUrlError('missing ?token=')
37
- try {
38
- const serverUrl = new URL(server)
39
- if (serverUrl.protocol !== 'http:' && serverUrl.protocol !== 'https:') {
40
- throw new PairUrlError(`server must be http(s), got ${serverUrl.protocol}`)
41
- }
42
- } catch (err) {
43
- if (err instanceof PairUrlError) throw err
44
- throw new PairUrlError(`server is not a valid URL: ${server}`)
45
- }
46
- // Strip trailing slash so `${server}${path}` never produces `//`.
47
- return { server: server.replace(/\/$/, ''), token }
48
- }