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,41 +0,0 @@
1
- import { readdirSync, readFileSync } from 'node:fs'
2
- import { dirname, join } from 'node:path'
3
- import { fileURLToPath } from 'node:url'
4
- import type { BazilionDb } from './client.ts'
5
-
6
- const migrationsDir = join(dirname(fileURLToPath(import.meta.url)), 'migrations')
7
-
8
- export function runMigrations(db: BazilionDb): void {
9
- db.raw.exec(`
10
- CREATE TABLE IF NOT EXISTS schema_migrations (
11
- version TEXT PRIMARY KEY,
12
- applied_at INTEGER NOT NULL
13
- )
14
- `)
15
-
16
- const applied = new Set(
17
- db.raw
18
- .query<{ version: string }, []>('SELECT version FROM schema_migrations')
19
- .all()
20
- .map((r) => r.version),
21
- )
22
-
23
- const files = readdirSync(migrationsDir)
24
- .filter((f) => f.endsWith('.sql'))
25
- .sort()
26
-
27
- for (const file of files) {
28
- const version = file.replace(/\.sql$/, '')
29
- if (applied.has(version)) continue
30
-
31
- const sql = readFileSync(join(migrationsDir, file), 'utf8')
32
- const tx = db.raw.transaction(() => {
33
- db.raw.exec(sql)
34
- db.raw.run('INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)', [
35
- version,
36
- Date.now(),
37
- ])
38
- })
39
- tx()
40
- }
41
- }
@@ -1,179 +0,0 @@
1
- -- Bazilion initial schema (consolidated, post-IPC + secrets-in-DB cleanup).
2
- --
3
- -- The daemon is the sole owner of `~/.bazilion/`. All state — entity
4
- -- metadata, inbox, scheduler, web tokens, encrypted secrets, plaintext
5
- -- config — lives in this single SQLite file. The only other file at the
6
- -- bazilion home root is `auth.json`: a tiny bootstrap shared by the daemon
7
- -- (which uses its `token` as the PBKDF2 seed for the `secrets` table) and
8
- -- the CLI (which uses the same token as its loopback bearer).
9
- --
10
- -- On-disk layout owned by the daemon:
11
- -- ~/.bazilion/bazilion.db
12
- -- ~/.bazilion/groups/<slug>/ — group root, mounted as cwd; may be a
13
- -- symlink for "agents working on my
14
- -- existing project tree" use cases
15
- -- /memory/ — qmd index for the group (shared by
16
- -- all member agents)
17
- -- ~/.bazilion/agents/<id>/ — agent's private home (NEVER inside
18
- -- the group tree, so the cwd-rooted
19
- -- coding tools can't see/clobber it)
20
- -- /sessions/*.jsonl — pi transcripts
21
- -- ~/.bazilion/profiles/<id>/ — profile templates
22
- -- ~/.bazilion/skills/<name>/ — installed skills
23
- -- ~/.bazilion/logs/ — daemon logs
24
-
25
- -- Groups are collaboration contexts: one filesystem root, one USER.md, one
26
- -- roster of member agents. The id IS the slug IS the directory name under
27
- -- `~/.bazilion/groups/`. No `path` column — paths derive from id.
28
- -- `user_md` is read-only context about the human (edited via web UI; never
29
- -- exposed as a file the agent could clobber via `edit`/`write`).
30
- CREATE TABLE groups (
31
- id TEXT PRIMARY KEY,
32
- name TEXT NOT NULL,
33
- user_md TEXT NOT NULL DEFAULT '',
34
- created_at INTEGER NOT NULL
35
- );
36
-
37
- -- Profiles are agent templates. `dir` is the on-disk directory for the
38
- -- profile's SOUL.md / IDENTITY.md / etc. master files, derived from id.
39
- -- `skills_mode = 'all'` attaches every installed skill at spawn;
40
- -- `'selected'` attaches only those listed in `profile_default_skills`.
41
- CREATE TABLE profiles (
42
- id TEXT PRIMARY KEY,
43
- name TEXT NOT NULL,
44
- dir TEXT NOT NULL,
45
- default_model TEXT NOT NULL,
46
- skills_mode TEXT NOT NULL DEFAULT 'selected' CHECK (skills_mode IN ('all','selected')),
47
- created_at INTEGER NOT NULL,
48
- updated_at INTEGER NOT NULL
49
- );
50
-
51
- CREATE TABLE profile_default_skills (
52
- profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
53
- skill_name TEXT NOT NULL,
54
- PRIMARY KEY (profile_id, skill_name)
55
- );
56
-
57
- -- Agents have exactly one group. `dir` is the agent's private home,
58
- -- ~/.bazilion/agents/<id>/ — strictly outside the group tree so that
59
- -- pi's coding tools (rooted at the group dir) can't reach into it.
60
- -- `reasoning_level` feeds pi-ai's streamSimple `reasoning` option;
61
- -- 'medium' is the sensible default.
62
- CREATE TABLE agents (
63
- id TEXT PRIMARY KEY,
64
- profile_id TEXT NOT NULL REFERENCES profiles(id),
65
- name TEXT NOT NULL,
66
- model_override TEXT,
67
- status TEXT NOT NULL CHECK (status IN ('idle','running','archived')),
68
- dir TEXT NOT NULL,
69
- reasoning_level TEXT NOT NULL DEFAULT 'medium',
70
- group_id TEXT NOT NULL REFERENCES groups(id) ON DELETE RESTRICT,
71
- created_at INTEGER NOT NULL,
72
- archived_at INTEGER
73
- );
74
-
75
- CREATE TABLE agent_skills (
76
- agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
77
- skill_name TEXT NOT NULL,
78
- attached_at INTEGER NOT NULL,
79
- PRIMARY KEY (agent_id, skill_name)
80
- );
81
-
82
- -- Periodic / scheduled wake-up triggers. The scheduler picks rows whose
83
- -- next-fire time has elapsed and kicks off a turn with `message` as the
84
- -- user input.
85
- --
86
- -- kind='interval' → interval_sec holds seconds between fires (cron_expr NULL)
87
- -- kind='cron' → cron_expr holds a 5-field cron expression (interval_sec NULL)
88
- --
89
- -- last_fired_at is bumped *before* the run kicks off so a daemon restart
90
- -- mid-fire doesn't double-trigger.
91
- CREATE TABLE agent_triggers (
92
- id TEXT PRIMARY KEY,
93
- agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
94
- kind TEXT NOT NULL CHECK (kind IN ('interval','cron')),
95
- interval_sec INTEGER,
96
- cron_expr TEXT,
97
- message TEXT NOT NULL,
98
- enabled INTEGER NOT NULL DEFAULT 1,
99
- last_fired_at INTEGER,
100
- created_at INTEGER NOT NULL
101
- );
102
- CREATE INDEX agent_triggers_agent ON agent_triggers(agent_id);
103
- CREATE INDEX agent_triggers_enabled ON agent_triggers(enabled) WHERE enabled = 1;
104
-
105
- -- Inter-agent inbox. The scheduler's auto-deliver loop polls
106
- -- `messages_to_unread` to fan out wakeup turns; the messaging tools insert
107
- -- here when one agent sends another a message.
108
- CREATE TABLE messages (
109
- id TEXT PRIMARY KEY,
110
- from_agent_id TEXT NOT NULL REFERENCES agents(id),
111
- to_agent_id TEXT NOT NULL REFERENCES agents(id),
112
- reply_to TEXT REFERENCES messages(id),
113
- payload TEXT NOT NULL,
114
- created_at INTEGER NOT NULL,
115
- read_at INTEGER
116
- );
117
- CREATE INDEX messages_to_unread ON messages(to_agent_id) WHERE read_at IS NULL;
118
-
119
- -- Per-skill import provenance. Skills live on disk under ~/.bazilion/skills/<name>/;
120
- -- this table records where each was imported from and when.
121
- CREATE TABLE skill_meta (
122
- name TEXT PRIMARY KEY,
123
- source TEXT,
124
- imported_at INTEGER
125
- );
126
-
127
- -- Per-client web tokens. Each row stores SHA-256(token) hex; the plaintext
128
- -- is returned exactly once at creation time and never persisted in this
129
- -- table. The CLI's bootstrap token is one row here — its plaintext lives
130
- -- in `~/.bazilion/auth.json` so both the daemon (PBKDF2 seed for the
131
- -- secrets table) and the CLI (loopback bearer) can read it.
132
- -- `revoked_at` is a soft-delete marker to keep audit trail intact.
133
- CREATE TABLE web_tokens (
134
- id TEXT PRIMARY KEY,
135
- label TEXT NOT NULL,
136
- token_hash TEXT NOT NULL UNIQUE,
137
- created_at INTEGER NOT NULL,
138
- last_used_at INTEGER,
139
- revoked_at INTEGER
140
- );
141
- CREATE INDEX web_tokens_active ON web_tokens(token_hash) WHERE revoked_at IS NULL;
142
-
143
- -- Curated list of models per provider. Drives the model dropdowns in
144
- -- profile creation and agent spawn/edit forms.
145
- CREATE TABLE provider_models (
146
- provider TEXT NOT NULL,
147
- model TEXT NOT NULL,
148
- added_at INTEGER NOT NULL,
149
- PRIMARY KEY (provider, model)
150
- );
151
- CREATE INDEX idx_provider_models_provider ON provider_models (provider);
152
-
153
- -- Admin-toggled enabled state per provider.
154
- CREATE TABLE provider_state (
155
- provider_id TEXT NOT NULL PRIMARY KEY,
156
- enabled INTEGER NOT NULL DEFAULT 0,
157
- updated_at INTEGER NOT NULL
158
- );
159
-
160
- -- Encrypted secrets. AES-256-GCM envelopes (salt+iv+tag+data hex JSON),
161
- -- one row per env-var-shaped key (`ANTHROPIC_API_KEY`, `OPENAI_CODEX_OAUTH`, …).
162
- -- The encryption key is derived from the bootstrap web token (PBKDF2-SHA256,
163
- -- 100k iterations) — same crypto as the previous file-based secrets.enc,
164
- -- now atomic with the rest of the DB.
165
- CREATE TABLE secrets (
166
- key TEXT PRIMARY KEY,
167
- envelope TEXT NOT NULL,
168
- updated_at INTEGER NOT NULL
169
- );
170
-
171
- -- Plaintext config. Same env-var-shaped keys as secrets, but for values
172
- -- that don't need confidentiality (server URLs, region slugs, project IDs).
173
- -- The application layer enforces a CONFIG_KEYS allowlist on writes so a
174
- -- typo can't put a secret in this table.
175
- CREATE TABLE config (
176
- key TEXT PRIMARY KEY,
177
- value TEXT NOT NULL,
178
- updated_at INTEGER NOT NULL
179
- );
@@ -1,21 +0,0 @@
1
- import type { BazilionDb } from '../db/client.ts'
2
- import type { Paths } from '../paths.ts'
3
- import * as agentRepo from '../repos/agents.ts'
4
- import * as groupRepo from '../repos/groups.ts'
5
-
6
- export function deleteGroup(db: BazilionDb, paths: Paths, id: string): void {
7
- const g = groupRepo.get(db, id, paths)
8
- if (!g) throw new Error(`group not found: ${id}`)
9
-
10
- // ON DELETE RESTRICT on agents.group_id enforces this at the SQL layer,
11
- // but we surface a friendlier error listing the blocking members.
12
- const members = agentRepo.list(db, { includeArchived: true }).filter((a) => a.groupId === id)
13
- if (members.length > 0) {
14
- const names = members.map((a) => `${a.name} (${a.id.slice(0, 8)})`).join(', ')
15
- throw new Error(
16
- `cannot delete group "${id}": ${members.length} agent(s) still belong to it: ${names}. Move or archive them first.`,
17
- )
18
- }
19
-
20
- groupRepo.remove(db, id)
21
- }
@@ -1,68 +0,0 @@
1
- // Register a group: pick a slug, materialize `~/.bazilion/groups/<slug>/`
2
- // (real dir or symlink), insert the row.
3
- //
4
- // Two modes:
5
- // - default: creates a real directory at `paths.groupDir(slug)`.
6
- // - `--link <target>`: creates a symlink at `paths.groupDir(slug)` →
7
- // `<target>`. The link target must exist and be a directory — that's
8
- // the "I want my agents working on my existing project tree" path.
9
- //
10
- // Slug = the row's id. Names are humanized labels separate from the slug;
11
- // callers may pass `name` explicitly or let it default to the slug.
12
-
13
- import { existsSync, mkdirSync, statSync, symlinkSync } from 'node:fs'
14
- import { resolve } from 'node:path'
15
- import type { Group } from '@bazilion/api-types'
16
- import type { BazilionDb } from '../db/client.ts'
17
- import type { Paths } from '../paths.ts'
18
- import { validateSlug } from '../profile/validate.ts'
19
- import * as groupRepo from '../repos/groups.ts'
20
-
21
- export interface RegisterGroupInput {
22
- /** Slug. Becomes the row id AND the directory name under `groups/`. */
23
- id: string
24
- /** Human-readable label. Defaults to `id`. */
25
- name?: string
26
- /**
27
- * If set, materialize `paths.groupDir(id)` as a symlink to this absolute
28
- * path instead of as a real directory. Target must exist and be a dir.
29
- */
30
- link?: string
31
- }
32
-
33
- export function registerGroup(db: BazilionDb, input: RegisterGroupInput, paths: Paths): Group {
34
- validateSlug(input.id)
35
-
36
- if (groupRepo.get(db, input.id, paths)) {
37
- throw new Error(`group already registered: ${input.id}`)
38
- }
39
-
40
- const slot = paths.groupDir(input.id)
41
- if (existsSync(slot)) {
42
- throw new Error(`group slot already on disk at ${slot} (move or remove it first)`)
43
- }
44
-
45
- // Make sure the parent `groups/` dir exists — the daemon's bootstrap creates
46
- // it but tests sometimes resolve a custom $BAZILION_HOME without going
47
- // through bootstrap.
48
- mkdirSync(paths.groupsDir, { recursive: true })
49
-
50
- if (input.link) {
51
- const target = resolve(input.link)
52
- if (!existsSync(target)) {
53
- throw new Error(`--link target does not exist: ${target}`)
54
- }
55
- if (!statSync(target).isDirectory()) {
56
- throw new Error(`--link target is not a directory: ${target}`)
57
- }
58
- symlinkSync(target, slot, 'dir')
59
- } else {
60
- mkdirSync(slot, { recursive: true })
61
- }
62
-
63
- // Memory subdir is the qmd index root for this group — created here so
64
- // the first tool call doesn't have to ensure it.
65
- mkdirSync(resolve(slot, 'memory'), { recursive: true })
66
-
67
- return groupRepo.insert(db, { id: input.id, name: input.name ?? input.id }, paths)
68
- }
@@ -1,71 +0,0 @@
1
- export { archiveAgent } from './agent/archive.ts'
2
- export { deleteAgent } from './agent/delete.ts'
3
- export { resolveAgent } from './agent/resolve.ts'
4
- export type { SpawnAgentInput } from './agent/spawn.ts'
5
- export { spawnAgent } from './agent/spawn.ts'
6
- export { unarchiveAgent } from './agent/unarchive.ts'
7
- export type { AvailableModel } from './availableModels.ts'
8
- export {
9
- groupAvailableModels,
10
- isSetupComplete,
11
- listAvailableModels,
12
- } from './availableModels.ts'
13
- export type { BazilionDb } from './db/client.ts'
14
- export { openDb, openInMemoryDb } from './db/client.ts'
15
- export { runMigrations } from './db/migrate.ts'
16
- export { deleteGroup } from './group/delete.ts'
17
- export type { RegisterGroupInput } from './group/register.ts'
18
- export { registerGroup } from './group/register.ts'
19
- export type { Paths } from './paths.ts'
20
- export { resolvePaths } from './paths.ts'
21
- export type { CreateProfileInput } from './profile/create.ts'
22
- export { createProfile } from './profile/create.ts'
23
- export { deleteProfile } from './profile/delete.ts'
24
- export {
25
- identityHasValues,
26
- loadIdentityFromFile,
27
- parseIdentityMarkdown,
28
- } from './profile/identity.ts'
29
- export { loadProfile } from './profile/load.ts'
30
- export {
31
- DEFAULT_GROUP_ID,
32
- DEFAULT_PROFILE_ID,
33
- ensureSetupSeeded,
34
- type SeedResult,
35
- seedDefaults,
36
- } from './profile/seed.ts'
37
- export {
38
- DEFAULT_AGENTS,
39
- DEFAULT_BOOTSTRAP,
40
- DEFAULT_HEARTBEAT,
41
- DEFAULT_IDENTITY,
42
- DEFAULT_SOUL,
43
- DEFAULT_TOOLS,
44
- } from './profile/templates.ts'
45
- export type { UpdateProfileInput } from './profile/update.ts'
46
- export { updateProfile } from './profile/update.ts'
47
- export * as agentRepo from './repos/agents.ts'
48
- export type { ConfigStore } from './repos/config.ts'
49
- export { CONFIG_KEYS, isConfigKey, openConfig } from './repos/config.ts'
50
- export * as groupRepo from './repos/groups.ts'
51
- export * as messageRepo from './repos/messages.ts'
52
- export * as profileRepo from './repos/profiles.ts'
53
- export * as providerModelRepo from './repos/providerModels.ts'
54
- export * as providerStateRepo from './repos/providerState.ts'
55
- export type { SecretsStore } from './repos/secrets.ts'
56
- export { openSecrets } from './repos/secrets.ts'
57
- export * as skillMetaRepo from './repos/skillMeta.ts'
58
- export * as triggerRepo from './repos/triggers.ts'
59
- export * as webTokenRepo from './repos/webTokens.ts'
60
- export type { AuthFile } from './secrets.ts'
61
- export { mergeSecretsIntoEnv, readAuthFile } from './secrets.ts'
62
- export type { FieldKind, ServiceCategory, ServiceDef, ServiceField } from './services.ts'
63
- export { findFieldByEnvVar, SERVICES, servicesByCategory } from './services.ts'
64
- export type { DiscoveredSkill } from './skills/discover.ts'
65
- export { discoverSkills } from './skills/discover.ts'
66
- export type { ImportResult, ImportSkillsInput } from './skills/import.ts'
67
- export { importSkills } from './skills/import.ts'
68
- export type { ParsedSkill, SkillFrontmatter } from './skills/parse.ts'
69
- export { parseSkillFile } from './skills/parse.ts'
70
- export type { ResolvedSkill, ResolvedSkillSet } from './skills/resolve.ts'
71
- export { resolveAgentSkills } from './skills/resolve.ts'
@@ -1,56 +0,0 @@
1
- import { homedir } from 'node:os'
2
- import { join } from 'node:path'
3
-
4
- export interface Paths {
5
- home: string
6
- db: string
7
- /**
8
- * Bootstrap auth file shared by the daemon and the CLI: `{token, remote?}`.
9
- * - `token` is the plaintext of the bootstrap web token. The daemon reads
10
- * it once at startup to derive the encryption key for the `secrets`
11
- * table (PBKDF2 over it) and to validate that it matches a row in
12
- * `web_tokens` (so a corrupted file fails loudly). The CLI reads it as
13
- * its loopback bearer.
14
- * - `remote` (set via `bazilion login`) is a CLI-only override pointing at
15
- * a remote daemon. The local daemon ignores this field.
16
- *
17
- * One file replaces the previous `config.json` + `secrets.enc` split:
18
- * encrypted secrets and plaintext config now live as DB rows.
19
- */
20
- authFile: string
21
- profilesDir: string
22
- agentsDir: string
23
- skillsDir: string
24
- groupsDir: string
25
- logsDir: string
26
- profileDir(id: string): string
27
- agentDir(id: string): string
28
- skillDir(name: string): string
29
- groupDir(slug: string): string
30
- }
31
-
32
- export function resolvePaths(home?: string): Paths {
33
- const root = home ?? process.env.BAZILION_HOME ?? join(homedir(), '.bazilion')
34
- return {
35
- home: root,
36
- db: join(root, 'bazilion.db'),
37
- authFile: join(root, 'auth.json'),
38
- profilesDir: join(root, 'profiles'),
39
- agentsDir: join(root, 'agents'),
40
- skillsDir: join(root, 'skills'),
41
- groupsDir: join(root, 'groups'),
42
- logsDir: join(root, 'logs'),
43
- profileDir(id) {
44
- return join(root, 'profiles', id)
45
- },
46
- agentDir(id) {
47
- return join(root, 'agents', id)
48
- },
49
- skillDir(name) {
50
- return join(root, 'skills', name)
51
- },
52
- groupDir(slug) {
53
- return join(root, 'groups', slug)
54
- },
55
- }
56
- }
@@ -1,78 +0,0 @@
1
- import { mkdirSync, writeFileSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import type { Profile, SkillsMode } from '@bazilion/api-types'
4
- import type { BazilionDb } from '../db/client.ts'
5
- import type { Paths } from '../paths.ts'
6
- import * as profileRepo from '../repos/profiles.ts'
7
- import { DEFAULT_BOOTSTRAP, DEFAULT_IDENTITY, DEFAULT_SOUL } from './templates.ts'
8
- import { validateSlug } from './validate.ts'
9
-
10
- export interface CreateProfileInput {
11
- id: string
12
- name?: string
13
- defaultModel: string
14
- skillsMode?: SkillsMode
15
- defaultSkills?: string[]
16
- templates?: {
17
- soul?: string
18
- identity?: string
19
- /** undefined = default bootstrap, null = skip bootstrap, string = override */
20
- bootstrap?: string | null
21
- /** undefined = skip, string = seed with this content */
22
- agents?: string
23
- /** undefined = skip, string = seed with this content */
24
- tools?: string
25
- /** undefined = skip, string = seed with this content */
26
- heartbeat?: string
27
- }
28
- }
29
-
30
- export function createProfile(db: BazilionDb, paths: Paths, input: CreateProfileInput): Profile {
31
- validateSlug(input.id)
32
-
33
- const dir = paths.profileDir(input.id)
34
- mkdirSync(dir, { recursive: true })
35
-
36
- const soul = input.templates?.soul ?? DEFAULT_SOUL
37
- const identity = input.templates?.identity ?? DEFAULT_IDENTITY
38
- const bootstrap =
39
- input.templates?.bootstrap === null ? null : (input.templates?.bootstrap ?? DEFAULT_BOOTSTRAP)
40
-
41
- writeFileSync(join(dir, 'SOUL.md'), soul)
42
- writeFileSync(join(dir, 'IDENTITY.md'), identity)
43
- if (bootstrap !== null) {
44
- writeFileSync(join(dir, 'BOOTSTRAP.md'), bootstrap)
45
- }
46
- if (typeof input.templates?.agents === 'string') {
47
- writeFileSync(join(dir, 'AGENTS.md'), input.templates.agents)
48
- }
49
- if (typeof input.templates?.tools === 'string') {
50
- writeFileSync(join(dir, 'TOOLS.md'), input.templates.tools)
51
- }
52
- if (typeof input.templates?.heartbeat === 'string') {
53
- writeFileSync(join(dir, 'HEARTBEAT.md'), input.templates.heartbeat)
54
- }
55
-
56
- const skillsMode: SkillsMode = input.skillsMode ?? 'selected'
57
- const profileJson = {
58
- name: input.name ?? input.id,
59
- defaultModel: input.defaultModel,
60
- skillsMode,
61
- defaultSkills: input.defaultSkills ?? [],
62
- }
63
- writeFileSync(join(dir, 'profile.json'), `${JSON.stringify(profileJson, null, 2)}\n`)
64
-
65
- const profile = profileRepo.insert(db, {
66
- id: input.id,
67
- name: profileJson.name,
68
- dir,
69
- defaultModel: input.defaultModel,
70
- skillsMode,
71
- })
72
-
73
- if (skillsMode === 'selected' && input.defaultSkills && input.defaultSkills.length > 0) {
74
- profileRepo.setDefaultSkills(db, input.id, input.defaultSkills)
75
- }
76
-
77
- return profile
78
- }
@@ -1,26 +0,0 @@
1
- import { existsSync, rmSync } from 'node:fs'
2
- import type { BazilionDb } from '../db/client.ts'
3
- import * as agentRepo from '../repos/agents.ts'
4
- import * as profileRepo from '../repos/profiles.ts'
5
-
6
- export function deleteProfile(db: BazilionDb, id: string): void {
7
- const profile = profileRepo.get(db, id)
8
- if (!profile) throw new Error(`profile not found: ${id}`)
9
-
10
- // Check for agents still using this profile
11
- const agents = agentRepo.list(db, { includeArchived: true }).filter((a) => a.profileId === id)
12
- if (agents.length > 0) {
13
- const names = agents.map((a) => `${a.name} (${a.id.slice(0, 8)})`).join(', ')
14
- throw new Error(
15
- `cannot delete profile "${id}": ${agents.length} agent(s) still reference it: ${names}. Delete or re-profile them first.`,
16
- )
17
- }
18
-
19
- // Remove from DB (CASCADE deletes profile_default_skills)
20
- profileRepo.remove(db, id)
21
-
22
- // Remove the profile directory from disk
23
- if (existsSync(profile.dir)) {
24
- rmSync(profile.dir, { recursive: true, force: true })
25
- }
26
- }
@@ -1,70 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import type { AgentIdentityFile } from '@bazilion/api-types'
3
-
4
- const IDENTITY_PLACEHOLDER_VALUES = new Set([
5
- 'pick something you like',
6
- 'ai? robot? familiar? ghost in the machine? something weirder?',
7
- 'how do you come across? sharp? warm? chaotic? calm?',
8
- 'your signature - pick one that feels right',
9
- 'workspace-relative path, http(s) url, or data uri',
10
- ])
11
-
12
- function normalizeIdentityValue(value: string): string {
13
- let normalized = value.trim()
14
- normalized = normalized.replace(/^[*_]+|[*_]+$/g, '').trim()
15
- if (normalized.startsWith('(') && normalized.endsWith(')')) {
16
- normalized = normalized.slice(1, -1).trim()
17
- }
18
- normalized = normalized.replace(/[\u2013\u2014]/g, '-')
19
- normalized = normalized.replace(/\s+/g, ' ').toLowerCase()
20
- return normalized
21
- }
22
-
23
- function isIdentityPlaceholder(value: string): boolean {
24
- return IDENTITY_PLACEHOLDER_VALUES.has(normalizeIdentityValue(value))
25
- }
26
-
27
- export function parseIdentityMarkdown(content: string): AgentIdentityFile {
28
- const identity: AgentIdentityFile = {}
29
- for (const line of content.split(/\r?\n/)) {
30
- const cleaned = line.trim().replace(/^\s*-\s*/, '')
31
- const colonIndex = cleaned.indexOf(':')
32
- if (colonIndex === -1) continue
33
- const label = cleaned.slice(0, colonIndex).replace(/[*_]/g, '').trim().toLowerCase()
34
- const value = cleaned
35
- .slice(colonIndex + 1)
36
- .replace(/^[*_]+|[*_]+$/g, '')
37
- .trim()
38
- if (!value) continue
39
- if (isIdentityPlaceholder(value)) continue
40
- if (label === 'name') identity.name = value
41
- else if (label === 'emoji') identity.emoji = value
42
- else if (label === 'creature') identity.creature = value
43
- else if (label === 'vibe') identity.vibe = value
44
- else if (label === 'theme') identity.theme = value
45
- else if (label === 'avatar') identity.avatar = value
46
- }
47
- return identity
48
- }
49
-
50
- export function identityHasValues(identity: AgentIdentityFile): boolean {
51
- return Boolean(
52
- identity.name ||
53
- identity.emoji ||
54
- identity.theme ||
55
- identity.creature ||
56
- identity.vibe ||
57
- identity.avatar,
58
- )
59
- }
60
-
61
- export function loadIdentityFromFile(path: string): AgentIdentityFile | null {
62
- let content: string
63
- try {
64
- content = readFileSync(path, 'utf8')
65
- } catch {
66
- return null
67
- }
68
- const parsed = parseIdentityMarkdown(content)
69
- return identityHasValues(parsed) ? parsed : null
70
- }
@@ -1,45 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import type { LoadedProfile } from '@bazilion/api-types'
4
- import type { BazilionDb } from '../db/client.ts'
5
- import * as profileRepo from '../repos/profiles.ts'
6
- import { parseIdentityMarkdown } from './identity.ts'
7
-
8
- function readOptional(path: string): string | null {
9
- return existsSync(path) ? readFileSync(path, 'utf8') : null
10
- }
11
-
12
- export function loadProfile(db: BazilionDb, id: string): LoadedProfile {
13
- const profile = profileRepo.get(db, id)
14
- if (!profile) throw new Error(`profile not found: ${id}`)
15
-
16
- const soul = readFileSync(join(profile.dir, 'SOUL.md'), 'utf8')
17
- const identityRaw = readFileSync(join(profile.dir, 'IDENTITY.md'), 'utf8')
18
- const bootstrap = readOptional(join(profile.dir, 'BOOTSTRAP.md'))
19
- const agents = readOptional(join(profile.dir, 'AGENTS.md'))
20
- const tools = readOptional(join(profile.dir, 'TOOLS.md'))
21
- const heartbeat = readOptional(join(profile.dir, 'HEARTBEAT.md'))
22
-
23
- const parsedIdentity = parseIdentityMarkdown(identityRaw)
24
- const anyIdentity =
25
- parsedIdentity.name ||
26
- parsedIdentity.emoji ||
27
- parsedIdentity.theme ||
28
- parsedIdentity.creature ||
29
- parsedIdentity.vibe ||
30
- parsedIdentity.avatar
31
-
32
- return {
33
- profile,
34
- defaultSkills: profileRepo.getDefaultSkills(db, id),
35
- files: {
36
- soul,
37
- identity: identityRaw,
38
- bootstrap,
39
- agents,
40
- tools,
41
- heartbeat,
42
- },
43
- identity: anyIdentity ? parsedIdentity : null,
44
- }
45
- }