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,83 +0,0 @@
1
- import type { Profile, SkillsMode } from '@bazilion/api-types'
2
- import type { BazilionDb } from '../db/client.ts'
3
-
4
- interface RawProfile {
5
- id: string
6
- name: string
7
- dir: string
8
- default_model: string
9
- skills_mode: string
10
- created_at: number
11
- updated_at: number
12
- }
13
-
14
- function toProfile(r: RawProfile): Profile {
15
- return {
16
- id: r.id,
17
- name: r.name,
18
- dir: r.dir,
19
- defaultModel: r.default_model,
20
- skillsMode: r.skills_mode as SkillsMode,
21
- createdAt: r.created_at,
22
- updatedAt: r.updated_at,
23
- }
24
- }
25
-
26
- export function insert(db: BazilionDb, p: Omit<Profile, 'createdAt' | 'updatedAt'>): Profile {
27
- const now = Date.now()
28
- db.raw.run(
29
- `INSERT INTO profiles (id, name, dir, default_model, skills_mode, created_at, updated_at)
30
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
31
- [p.id, p.name, p.dir, p.defaultModel, p.skillsMode, now, now],
32
- )
33
- return { ...p, createdAt: now, updatedAt: now }
34
- }
35
-
36
- export function get(db: BazilionDb, id: string): Profile | null {
37
- const row = db.raw.query<RawProfile, [string]>('SELECT * FROM profiles WHERE id = ?').get(id)
38
- return row ? toProfile(row) : null
39
- }
40
-
41
- export function list(db: BazilionDb): Profile[] {
42
- return db.raw
43
- .query<RawProfile, []>('SELECT * FROM profiles ORDER BY created_at ASC')
44
- .all()
45
- .map(toProfile)
46
- }
47
-
48
- export function remove(db: BazilionDb, id: string): void {
49
- db.raw.run('DELETE FROM profiles WHERE id = ?', [id])
50
- }
51
-
52
- export function update(
53
- db: BazilionDb,
54
- id: string,
55
- fields: { name: string; defaultModel: string; skillsMode: SkillsMode },
56
- ): void {
57
- db.raw.run(
58
- `UPDATE profiles
59
- SET name = ?, default_model = ?, skills_mode = ?, updated_at = ?
60
- WHERE id = ?`,
61
- [fields.name, fields.defaultModel, fields.skillsMode, Date.now(), id],
62
- )
63
- }
64
-
65
- export function setDefaultSkills(db: BazilionDb, profileId: string, skills: string[]): void {
66
- const tx = db.raw.transaction(() => {
67
- db.raw.run('DELETE FROM profile_default_skills WHERE profile_id = ?', [profileId])
68
- const stmt = db.raw.query(
69
- 'INSERT INTO profile_default_skills (profile_id, skill_name) VALUES (?, ?)',
70
- )
71
- for (const s of skills) stmt.run(profileId, s)
72
- })
73
- tx()
74
- }
75
-
76
- export function getDefaultSkills(db: BazilionDb, profileId: string): string[] {
77
- return db.raw
78
- .query<{ skill_name: string }, [string]>(
79
- 'SELECT skill_name FROM profile_default_skills WHERE profile_id = ? ORDER BY skill_name',
80
- )
81
- .all(profileId)
82
- .map((r) => r.skill_name)
83
- }
@@ -1,58 +0,0 @@
1
- import type { BazilionDb } from '../db/client.ts'
2
-
3
- interface RawRow {
4
- provider: string
5
- model: string
6
- added_at: number
7
- }
8
-
9
- /** Curated model names for one provider, in insertion order. */
10
- export function list(db: BazilionDb, provider: string): string[] {
11
- return db.raw
12
- .query<RawRow, [string]>(
13
- 'SELECT * FROM provider_models WHERE provider = ? ORDER BY added_at ASC',
14
- )
15
- .all(provider)
16
- .map((r) => r.model)
17
- }
18
-
19
- /** All curated models grouped by provider. Empty providers are omitted. */
20
- export function listAll(db: BazilionDb): Record<string, string[]> {
21
- const out: Record<string, string[]> = {}
22
- for (const row of db.raw
23
- .query<RawRow, []>('SELECT * FROM provider_models ORDER BY provider ASC, added_at ASC')
24
- .all()) {
25
- const bucket = out[row.provider] ?? []
26
- bucket.push(row.model)
27
- out[row.provider] = bucket
28
- }
29
- return out
30
- }
31
-
32
- /**
33
- * Replace the curated list for one provider atomically. Empty `models` clears
34
- * the list. De-dupes (case-sensitive) and preserves incoming order.
35
- */
36
- export function replace(db: BazilionDb, provider: string, models: string[]): void {
37
- const seen = new Set<string>()
38
- const clean = models
39
- .map((m) => m.trim())
40
- .filter((m) => m.length > 0 && !seen.has(m) && seen.add(m))
41
- db.raw.transaction(() => {
42
- db.raw.run('DELETE FROM provider_models WHERE provider = ?', [provider])
43
- const now = Date.now()
44
- for (let i = 0; i < clean.length; i++) {
45
- // Offset by index so ordering is preserved by added_at.
46
- db.raw.run('INSERT INTO provider_models (provider, model, added_at) VALUES (?, ?, ?)', [
47
- provider,
48
- clean[i] as string,
49
- now + i,
50
- ])
51
- }
52
- })()
53
- }
54
-
55
- /** Remove a single curated model. No-op if not present. */
56
- export function remove(db: BazilionDb, provider: string, model: string): void {
57
- db.raw.run('DELETE FROM provider_models WHERE provider = ? AND model = ?', [provider, model])
58
- }
@@ -1,37 +0,0 @@
1
- import type { BazilionDb } from '../db/client.ts'
2
-
3
- interface RawRow {
4
- provider_id: string
5
- enabled: number
6
- updated_at: number
7
- }
8
-
9
- export function isEnabled(db: BazilionDb, providerId: string): boolean {
10
- const row = db.raw
11
- .query<RawRow, [string]>('SELECT * FROM provider_state WHERE provider_id = ?')
12
- .get(providerId)
13
- return row?.enabled === 1
14
- }
15
-
16
- export function setEnabled(db: BazilionDb, providerId: string, enabled: boolean): void {
17
- db.raw.run(
18
- `INSERT INTO provider_state (provider_id, enabled, updated_at)
19
- VALUES (?, ?, ?)
20
- ON CONFLICT (provider_id) DO UPDATE SET
21
- enabled = excluded.enabled,
22
- updated_at = excluded.updated_at`,
23
- [providerId, enabled ? 1 : 0, Date.now()],
24
- )
25
- }
26
-
27
- /** Set of provider ids currently toggled on. Convenience for batch checks. */
28
- export function listEnabled(db: BazilionDb): Set<string> {
29
- return new Set(
30
- db.raw
31
- .query<{ provider_id: string }, []>(
32
- 'SELECT provider_id FROM provider_state WHERE enabled = 1',
33
- )
34
- .all()
35
- .map((r) => r.provider_id),
36
- )
37
- }
@@ -1,145 +0,0 @@
1
- // Encrypted secrets store, backed by the `secrets` table.
2
- //
3
- // Layout: one row per env-var-shaped key (`ANTHROPIC_API_KEY`,
4
- // `OPENAI_CODEX_OAUTH`, …). Each value is an AES-256-GCM envelope (salt +
5
- // iv + tag + data, hex-encoded JSON), with the key derived from the
6
- // bootstrap token via PBKDF2-SHA256 (100k iterations). The crypto matches
7
- // the previous `secrets.enc` file format byte-for-byte — only the storage
8
- // medium changed.
9
- //
10
- // Why encrypt at all when the password lives in `~/.bazilion/auth.json`
11
- // next to the DB? Same reason as before: it's defense against accidental
12
- // exposure (cat'd dumps, screenshares, naive backups), not against an
13
- // attacker with filesystem read. Anyone who can read both files wins.
14
- //
15
- // Caching: `deriveKey` runs PBKDF2 once per (password, salt) pair and the
16
- // salt is per-row, so a busy daemon does ~one PBKDF2 per secret read. The
17
- // `secretCache` keeps decrypted values in-memory keyed by row id so repeated
18
- // reads inside one process don't repeat the work; mutations clear the cache
19
- // row.
20
-
21
- import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from 'node:crypto'
22
- import type { BazilionDb } from '../db/client.ts'
23
-
24
- const ALGORITHM = 'aes-256-gcm'
25
- const KEY_LEN = 32
26
- const ITERATIONS = 100_000
27
- const DIGEST = 'sha256'
28
-
29
- interface EncryptedEnvelope {
30
- salt: string
31
- iv: string
32
- tag: string
33
- data: string
34
- }
35
-
36
- function deriveKey(password: string, salt: Buffer): Buffer {
37
- return pbkdf2Sync(password, salt, ITERATIONS, KEY_LEN, DIGEST)
38
- }
39
-
40
- function encrypt(plaintext: string, password: string): EncryptedEnvelope {
41
- const salt = randomBytes(16)
42
- const key = deriveKey(password, salt)
43
- const iv = randomBytes(12)
44
- const cipher = createCipheriv(ALGORITHM, key, iv)
45
- let data = cipher.update(plaintext, 'utf8', 'hex')
46
- data += cipher.final('hex')
47
- const tag = cipher.getAuthTag()
48
- return {
49
- salt: salt.toString('hex'),
50
- iv: iv.toString('hex'),
51
- tag: tag.toString('hex'),
52
- data,
53
- }
54
- }
55
-
56
- function decrypt(envelope: EncryptedEnvelope, password: string): string {
57
- const salt = Buffer.from(envelope.salt, 'hex')
58
- const key = deriveKey(password, salt)
59
- const iv = Buffer.from(envelope.iv, 'hex')
60
- const tag = Buffer.from(envelope.tag, 'hex')
61
- const decipher = createDecipheriv(ALGORITHM, key, iv)
62
- decipher.setAuthTag(tag)
63
- let plaintext = decipher.update(envelope.data, 'hex', 'utf8')
64
- plaintext += decipher.final('utf8')
65
- return plaintext
66
- }
67
-
68
- interface RawRow {
69
- key: string
70
- envelope: string
71
- updated_at: number
72
- }
73
-
74
- export interface SecretsStore {
75
- get(key: string): string | undefined
76
- set(key: string, value: string): void
77
- remove(key: string): void
78
- has(key: string): boolean
79
- list(): { key: string; preview: string }[]
80
- getAll(): Record<string, string>
81
- }
82
-
83
- /**
84
- * Open the encrypted secrets store. `password` is the bootstrap token
85
- * (read from `auth.json` by the caller). Throws on individual-row decrypt
86
- * failures only when actively reading that row — bad rows show as
87
- * `undefined` from `get`, the caller can `set` to overwrite.
88
- */
89
- export function openSecrets(db: BazilionDb, password: string): SecretsStore {
90
- function getRow(key: string): RawRow | null {
91
- return db.raw.query<RawRow, [string]>('SELECT * FROM secrets WHERE key = ?').get(key)
92
- }
93
-
94
- function listAll(): RawRow[] {
95
- return db.raw.query<RawRow, []>('SELECT * FROM secrets ORDER BY key ASC').all()
96
- }
97
-
98
- function tryDecrypt(row: RawRow): string | undefined {
99
- try {
100
- const envelope = JSON.parse(row.envelope) as EncryptedEnvelope
101
- return decrypt(envelope, password)
102
- } catch {
103
- return undefined
104
- }
105
- }
106
-
107
- return {
108
- get(key) {
109
- const row = getRow(key)
110
- if (!row) return undefined
111
- return tryDecrypt(row)
112
- },
113
- set(key, value) {
114
- const envelope = JSON.stringify(encrypt(value, password))
115
- db.raw.run(
116
- `INSERT INTO secrets (key, envelope, updated_at) VALUES (?, ?, ?)
117
- ON CONFLICT(key) DO UPDATE SET envelope = excluded.envelope, updated_at = excluded.updated_at`,
118
- [key, envelope, Date.now()],
119
- )
120
- },
121
- remove(key) {
122
- db.raw.run('DELETE FROM secrets WHERE key = ?', [key])
123
- },
124
- has(key) {
125
- return getRow(key) !== null
126
- },
127
- list() {
128
- return listAll().map((r) => {
129
- const value = tryDecrypt(r)
130
- return {
131
- key: r.key,
132
- preview: value ? (value.length > 8 ? `${value.slice(0, 6)}…` : '***') : '(unreadable)',
133
- }
134
- })
135
- },
136
- getAll() {
137
- const out: Record<string, string> = {}
138
- for (const r of listAll()) {
139
- const v = tryDecrypt(r)
140
- if (v !== undefined) out[r.key] = v
141
- }
142
- return out
143
- },
144
- }
145
- }
@@ -1,49 +0,0 @@
1
- import type { SkillMeta } from '@bazilion/api-types'
2
- import type { BazilionDb } from '../db/client.ts'
3
-
4
- interface RawMeta {
5
- name: string
6
- source: string | null
7
- imported_at: number | null
8
- }
9
-
10
- function toMeta(r: RawMeta): SkillMeta {
11
- return {
12
- name: r.name,
13
- source: r.source,
14
- importedAt: r.imported_at,
15
- }
16
- }
17
-
18
- export function get(db: BazilionDb, name: string): SkillMeta | null {
19
- const row = db.raw.query<RawMeta, [string]>('SELECT * FROM skill_meta WHERE name = ?').get(name)
20
- return row ? toMeta(row) : null
21
- }
22
-
23
- export function listAll(db: BazilionDb): SkillMeta[] {
24
- return db.raw.query<RawMeta, []>('SELECT * FROM skill_meta ORDER BY name ASC').all().map(toMeta)
25
- }
26
-
27
- export interface UpsertInput {
28
- name: string
29
- source?: string | null
30
- importedAt?: number | null
31
- }
32
-
33
- export function upsert(db: BazilionDb, input: UpsertInput): SkillMeta {
34
- const existing = get(db, input.name)
35
- const source = input.source !== undefined ? input.source : (existing?.source ?? null)
36
- const importedAt =
37
- input.importedAt !== undefined ? input.importedAt : (existing?.importedAt ?? null)
38
- db.raw.run(
39
- `INSERT INTO skill_meta (name, source, imported_at)
40
- VALUES (?, ?, ?)
41
- ON CONFLICT(name) DO UPDATE SET source = excluded.source, imported_at = excluded.imported_at`,
42
- [input.name, source, importedAt],
43
- )
44
- return { name: input.name, source, importedAt }
45
- }
46
-
47
- export function remove(db: BazilionDb, name: string): void {
48
- db.raw.run('DELETE FROM skill_meta WHERE name = ?', [name])
49
- }
@@ -1,101 +0,0 @@
1
- import { randomUUID } from 'node:crypto'
2
- import type { AgentTrigger, TriggerKind } from '@bazilion/api-types'
3
- import type { BazilionDb } from '../db/client.ts'
4
-
5
- interface RawTrigger {
6
- id: string
7
- agent_id: string
8
- kind: string
9
- interval_sec: number | null
10
- cron_expr: string | null
11
- message: string
12
- enabled: number
13
- last_fired_at: number | null
14
- created_at: number
15
- }
16
-
17
- function toTrigger(r: RawTrigger): AgentTrigger {
18
- return {
19
- id: r.id,
20
- agentId: r.agent_id,
21
- kind: r.kind as TriggerKind,
22
- intervalSec: r.interval_sec,
23
- cronExpr: r.cron_expr,
24
- message: r.message,
25
- enabled: r.enabled === 1,
26
- lastFiredAt: r.last_fired_at,
27
- createdAt: r.created_at,
28
- }
29
- }
30
-
31
- export interface InsertTriggerInput {
32
- agentId: string
33
- kind: TriggerKind
34
- intervalSec: number | null
35
- cronExpr: string | null
36
- message: string
37
- enabled?: boolean
38
- }
39
-
40
- export function insert(db: BazilionDb, input: InsertTriggerInput): AgentTrigger {
41
- const id = randomUUID()
42
- const now = Date.now()
43
- const enabled = input.enabled === false ? 0 : 1
44
- db.raw.run(
45
- `INSERT INTO agent_triggers
46
- (id, agent_id, kind, interval_sec, cron_expr, message, enabled, last_fired_at, created_at)
47
- VALUES (?, ?, ?, ?, ?, ?, ?, NULL, ?)`,
48
- [id, input.agentId, input.kind, input.intervalSec, input.cronExpr, input.message, enabled, now],
49
- )
50
- return {
51
- id,
52
- agentId: input.agentId,
53
- kind: input.kind,
54
- intervalSec: input.intervalSec,
55
- cronExpr: input.cronExpr,
56
- message: input.message,
57
- enabled: enabled === 1,
58
- lastFiredAt: null,
59
- createdAt: now,
60
- }
61
- }
62
-
63
- export function get(db: BazilionDb, id: string): AgentTrigger | null {
64
- const row = db.raw
65
- .query<RawTrigger, [string]>('SELECT * FROM agent_triggers WHERE id = ?')
66
- .get(id)
67
- return row ? toTrigger(row) : null
68
- }
69
-
70
- export function listForAgent(db: BazilionDb, agentId: string): AgentTrigger[] {
71
- return db.raw
72
- .query<RawTrigger, [string]>(
73
- 'SELECT * FROM agent_triggers WHERE agent_id = ? ORDER BY created_at ASC',
74
- )
75
- .all(agentId)
76
- .map(toTrigger)
77
- }
78
-
79
- export function listEnabled(db: BazilionDb): AgentTrigger[] {
80
- return db.raw
81
- .query<RawTrigger, []>(
82
- `SELECT t.* FROM agent_triggers t
83
- JOIN agents a ON a.id = t.agent_id
84
- WHERE t.enabled = 1 AND a.status != 'archived'
85
- ORDER BY t.created_at ASC`,
86
- )
87
- .all()
88
- .map(toTrigger)
89
- }
90
-
91
- export function setEnabled(db: BazilionDb, id: string, enabled: boolean): void {
92
- db.raw.run('UPDATE agent_triggers SET enabled = ? WHERE id = ?', [enabled ? 1 : 0, id])
93
- }
94
-
95
- export function markFired(db: BazilionDb, id: string, when: number = Date.now()): void {
96
- db.raw.run('UPDATE agent_triggers SET last_fired_at = ? WHERE id = ?', [when, id])
97
- }
98
-
99
- export function remove(db: BazilionDb, id: string): void {
100
- db.raw.run('DELETE FROM agent_triggers WHERE id = ?', [id])
101
- }
@@ -1,87 +0,0 @@
1
- import { createHash, randomBytes, randomUUID } from 'node:crypto'
2
- import type { WebToken } from '@bazilion/api-types'
3
- import type { BazilionDb } from '../db/client.ts'
4
-
5
- interface RawToken {
6
- id: string
7
- label: string
8
- token_hash: string
9
- created_at: number
10
- last_used_at: number | null
11
- revoked_at: number | null
12
- }
13
-
14
- function toToken(r: RawToken): WebToken {
15
- return {
16
- id: r.id,
17
- label: r.label,
18
- createdAt: r.created_at,
19
- lastUsedAt: r.last_used_at,
20
- revokedAt: r.revoked_at,
21
- }
22
- }
23
-
24
- export function hashToken(token: string): string {
25
- return createHash('sha256').update(token).digest('hex')
26
- }
27
-
28
- export interface CreatedToken {
29
- meta: WebToken
30
- /** Plaintext token — shown exactly once, never re-queryable. */
31
- token: string
32
- }
33
-
34
- export function create(db: BazilionDb, label: string): CreatedToken {
35
- const id = randomUUID()
36
- const token = randomBytes(24).toString('hex')
37
- const tokenHash = hashToken(token)
38
- const now = Date.now()
39
- db.raw.run(
40
- `INSERT INTO web_tokens (id, label, token_hash, created_at, last_used_at, revoked_at)
41
- VALUES (?, ?, ?, ?, NULL, NULL)`,
42
- [id, label, tokenHash, now],
43
- )
44
- return {
45
- token,
46
- meta: { id, label, createdAt: now, lastUsedAt: null, revokedAt: null },
47
- }
48
- }
49
-
50
- export function list(db: BazilionDb, opts?: { includeRevoked?: boolean }): WebToken[] {
51
- const sql = opts?.includeRevoked
52
- ? 'SELECT * FROM web_tokens ORDER BY created_at ASC'
53
- : 'SELECT * FROM web_tokens WHERE revoked_at IS NULL ORDER BY created_at ASC'
54
- return db.raw.query<RawToken, []>(sql).all().map(toToken)
55
- }
56
-
57
- export function get(db: BazilionDb, id: string): WebToken | null {
58
- const row = db.raw.query<RawToken, [string]>('SELECT * FROM web_tokens WHERE id = ?').get(id)
59
- return row ? toToken(row) : null
60
- }
61
-
62
- /**
63
- * Returns the active token row matching the given plaintext, or null.
64
- * Does NOT bump last_used_at — call markUsed separately once the caller
65
- * has decided the request is authorized.
66
- */
67
- export function findActiveByToken(db: BazilionDb, token: string): WebToken | null {
68
- const tokenHash = hashToken(token)
69
- const row = db.raw
70
- .query<RawToken, [string]>(
71
- 'SELECT * FROM web_tokens WHERE token_hash = ? AND revoked_at IS NULL',
72
- )
73
- .get(tokenHash)
74
- return row ? toToken(row) : null
75
- }
76
-
77
- export function markUsed(db: BazilionDb, id: string, when: number = Date.now()): void {
78
- db.raw.run('UPDATE web_tokens SET last_used_at = ? WHERE id = ?', [when, id])
79
- }
80
-
81
- export function revoke(db: BazilionDb, id: string, when: number = Date.now()): boolean {
82
- const res = db.raw.run(
83
- 'UPDATE web_tokens SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL',
84
- [when, id],
85
- )
86
- return res.changes > 0
87
- }
@@ -1,65 +0,0 @@
1
- // Auth / secrets entry points keyed off the bootstrap `auth.json` file.
2
- //
3
- // `auth.json` carries one mandatory field — `token` — written by the daemon's
4
- // first-run bootstrap. The daemon uses it as the PBKDF2 seed for the `secrets`
5
- // table; the CLI uses it as the bearer for loopback HTTP. CLI-side `remote`
6
- // overrides (set by `bazilion login`) coexist in the same file.
7
-
8
- import { existsSync, readFileSync } from 'node:fs'
9
- import type { BazilionDb } from './db/client.ts'
10
- import { openConfig } from './repos/config.ts'
11
- import { openSecrets } from './repos/secrets.ts'
12
-
13
- export interface AuthFile {
14
- token: string
15
- remote?: { server: string; token: string } | null
16
- }
17
-
18
- /**
19
- * Read `auth.json` and return the parsed contents. Throws when missing or
20
- * malformed — callers should treat that as "bazilion not initialized."
21
- */
22
- export function readAuthFile(authFile: string): AuthFile {
23
- if (!existsSync(authFile)) {
24
- throw new Error(`${authFile} not found. Start the daemon (\`bazilion serve\`) — it auto-bootstraps on first run.`)
25
- }
26
- const raw = readFileSync(authFile, 'utf8')
27
- const parsed = JSON.parse(raw) as Partial<AuthFile>
28
- if (typeof parsed.token !== 'string' || !parsed.token) {
29
- throw new Error(`${authFile} is missing the "token" field`)
30
- }
31
- return {
32
- token: parsed.token,
33
- remote: parsed.remote ?? null,
34
- }
35
- }
36
-
37
- /**
38
- * Merge plaintext config + decrypted secrets + process env into a single
39
- * env-shaped record. Precedence (low → high): config → secrets → env. The
40
- * caller supplies the bootstrap `password` (typically `readAuthFile().token`)
41
- * because the secrets table is encrypted with it.
42
- *
43
- * Either layer may fail to read (corrupt row, wrong key, table absent at
44
- * fixture-bootstrap time); failures are swallowed per-layer so a single bad
45
- * value never blocks the merge.
46
- */
47
- export function mergeSecretsIntoEnv(
48
- db: BazilionDb,
49
- password: string,
50
- env: NodeJS.ProcessEnv = process.env,
51
- ): NodeJS.ProcessEnv {
52
- let configValues: Record<string, string> = {}
53
- let secretValues: Record<string, string> = {}
54
- try {
55
- configValues = openConfig(db).getAll()
56
- } catch {
57
- // table missing or unreadable — continue without the layer
58
- }
59
- try {
60
- secretValues = openSecrets(db, password).getAll()
61
- } catch {
62
- // table missing or wrong password — continue without the layer
63
- }
64
- return { ...configValues, ...secretValues, ...env }
65
- }