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.
- package/README.md +53 -152
- package/dist/cli.js +2730 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon.js +5888 -0
- package/dist/daemon.js.map +1 -0
- package/dist/worker.js +1830 -0
- package/dist/worker.js.map +1 -0
- package/package.json +57 -28
- package/.understand-anything/.understandignore +0 -25
- package/.understand-anything/fingerprints.json +0 -14267
- package/.understand-anything/knowledge-graph.json +0 -18128
- package/.understand-anything/meta.json +0 -6
- package/CLAUDE.md +0 -164
- package/apps/cli/package.json +0 -21
- package/apps/cli/src/auth-file.ts +0 -18
- package/apps/cli/src/client.ts +0 -37
- package/apps/cli/src/columnize.ts +0 -32
- package/apps/cli/src/commands/agent.ts +0 -574
- package/apps/cli/src/commands/auth.ts +0 -110
- package/apps/cli/src/commands/backup.ts +0 -135
- package/apps/cli/src/commands/completion.ts +0 -155
- package/apps/cli/src/commands/config.ts +0 -95
- package/apps/cli/src/commands/doctor.ts +0 -131
- package/apps/cli/src/commands/group.ts +0 -132
- package/apps/cli/src/commands/inbox.ts +0 -82
- package/apps/cli/src/commands/login.ts +0 -73
- package/apps/cli/src/commands/memory.ts +0 -106
- package/apps/cli/src/commands/profile.ts +0 -259
- package/apps/cli/src/commands/provider.ts +0 -170
- package/apps/cli/src/commands/send.ts +0 -24
- package/apps/cli/src/commands/serve.ts +0 -89
- package/apps/cli/src/commands/skill.ts +0 -120
- package/apps/cli/src/commands/token.ts +0 -148
- package/apps/cli/src/commands/trigger.ts +0 -129
- package/apps/cli/src/commands/uninstall.ts +0 -156
- package/apps/cli/src/index.ts +0 -196
- package/apps/cli/src/paths.ts +0 -12
- package/apps/cli/test/agent.test.ts +0 -213
- package/apps/cli/test/backup.test.ts +0 -95
- package/apps/cli/test/chat.test.ts +0 -539
- package/apps/cli/test/columnize.test.ts +0 -29
- package/apps/cli/test/completion.test.ts +0 -45
- package/apps/cli/test/config-page.test.ts +0 -151
- package/apps/cli/test/group.test.ts +0 -74
- package/apps/cli/test/helpers.ts +0 -70
- package/apps/cli/test/inbox-autodeliver.test.ts +0 -143
- package/apps/cli/test/inbox.test.ts +0 -147
- package/apps/cli/test/memory.test.ts +0 -69
- package/apps/cli/test/profile.test.ts +0 -110
- package/apps/cli/test/send.test.ts +0 -30
- package/apps/cli/test/server-fixture.ts +0 -212
- package/apps/cli/test/session-head.test.ts +0 -45
- package/apps/cli/test/skill.test.ts +0 -128
- package/apps/cli/test/token.test.ts +0 -109
- package/apps/cli/test/trigger.test.ts +0 -245
- package/apps/cli/tsconfig.json +0 -4
- package/apps/daemon/package.json +0 -31
- package/apps/daemon/src/app.ts +0 -41
- package/apps/daemon/src/core/agent/archive.ts +0 -8
- package/apps/daemon/src/core/agent/delete.ts +0 -30
- package/apps/daemon/src/core/agent/resolve.ts +0 -31
- package/apps/daemon/src/core/agent/spawn.ts +0 -95
- package/apps/daemon/src/core/agent/unarchive.ts +0 -11
- package/apps/daemon/src/core/availableModels.ts +0 -58
- package/apps/daemon/src/core/db/client.ts +0 -113
- package/apps/daemon/src/core/db/migrate.ts +0 -41
- package/apps/daemon/src/core/db/migrations/0001_init.sql +0 -179
- package/apps/daemon/src/core/group/delete.ts +0 -21
- package/apps/daemon/src/core/group/register.ts +0 -68
- package/apps/daemon/src/core/index.ts +0 -71
- package/apps/daemon/src/core/paths.ts +0 -56
- package/apps/daemon/src/core/profile/create.ts +0 -78
- package/apps/daemon/src/core/profile/delete.ts +0 -26
- package/apps/daemon/src/core/profile/identity.ts +0 -70
- package/apps/daemon/src/core/profile/load.ts +0 -45
- package/apps/daemon/src/core/profile/seed.ts +0 -74
- package/apps/daemon/src/core/profile/templates.ts +0 -60
- package/apps/daemon/src/core/profile/update.ts +0 -57
- package/apps/daemon/src/core/profile/validate.ts +0 -9
- package/apps/daemon/src/core/repos/agents.ts +0 -202
- package/apps/daemon/src/core/repos/config.ts +0 -78
- package/apps/daemon/src/core/repos/groups.ts +0 -55
- package/apps/daemon/src/core/repos/messages.ts +0 -127
- package/apps/daemon/src/core/repos/profiles.ts +0 -83
- package/apps/daemon/src/core/repos/providerModels.ts +0 -58
- package/apps/daemon/src/core/repos/providerState.ts +0 -37
- package/apps/daemon/src/core/repos/secrets.ts +0 -145
- package/apps/daemon/src/core/repos/skillMeta.ts +0 -49
- package/apps/daemon/src/core/repos/triggers.ts +0 -101
- package/apps/daemon/src/core/repos/webTokens.ts +0 -87
- package/apps/daemon/src/core/secrets.ts +0 -65
- package/apps/daemon/src/core/services.ts +0 -264
- package/apps/daemon/src/core/skills/discover.ts +0 -28
- package/apps/daemon/src/core/skills/import.ts +0 -136
- package/apps/daemon/src/core/skills/parse.ts +0 -52
- package/apps/daemon/src/core/skills/resolve.ts +0 -50
- package/apps/daemon/src/index.ts +0 -45
- package/apps/daemon/src/lib/agent-cancel.ts +0 -48
- package/apps/daemon/src/lib/agent-id.ts +0 -13
- package/apps/daemon/src/lib/agent-turn.ts +0 -56
- package/apps/daemon/src/lib/api-key.ts +0 -56
- package/apps/daemon/src/lib/auth.ts +0 -41
- package/apps/daemon/src/lib/cron.ts +0 -93
- package/apps/daemon/src/lib/ctx.ts +0 -80
- package/apps/daemon/src/lib/messaging-host.ts +0 -34
- package/apps/daemon/src/lib/middleware-auth.ts +0 -52
- package/apps/daemon/src/lib/scheduler.ts +0 -294
- package/apps/daemon/src/routes/agents.ts +0 -772
- package/apps/daemon/src/routes/auth-login.ts +0 -193
- package/apps/daemon/src/routes/config.ts +0 -267
- package/apps/daemon/src/routes/groups.ts +0 -133
- package/apps/daemon/src/routes/messages.ts +0 -29
- package/apps/daemon/src/routes/misc.ts +0 -239
- package/apps/daemon/src/routes/profiles.ts +0 -197
- package/apps/daemon/src/routes/skills.ts +0 -123
- package/apps/daemon/src/routes/triggers.ts +0 -29
- package/apps/daemon/src/runtime/auth/openai-codex.ts +0 -121
- package/apps/daemon/src/runtime/auto-reply/heartbeat.ts +0 -31
- package/apps/daemon/src/runtime/index.ts +0 -77
- package/apps/daemon/src/runtime/memory/files.ts +0 -103
- package/apps/daemon/src/runtime/memory/qmd.ts +0 -152
- package/apps/daemon/src/runtime/memory/types.ts +0 -16
- package/apps/daemon/src/runtime/pi/events.ts +0 -173
- package/apps/daemon/src/runtime/pi/session.ts +0 -536
- package/apps/daemon/src/runtime/pi/tools.ts +0 -85
- package/apps/daemon/src/runtime/providers/catalog.ts +0 -145
- package/apps/daemon/src/runtime/providers/pi-adapter.ts +0 -272
- package/apps/daemon/src/runtime/providers/registry.ts +0 -374
- package/apps/daemon/src/runtime/providers/retry.ts +0 -176
- package/apps/daemon/src/runtime/providers/types.ts +0 -33
- package/apps/daemon/src/runtime/session/prompt.ts +0 -83
- package/apps/daemon/src/runtime/tools/bootstrap.ts +0 -22
- package/apps/daemon/src/runtime/tools/home.ts +0 -114
- package/apps/daemon/src/runtime/tools/memory.ts +0 -81
- package/apps/daemon/src/runtime/tools/messaging.ts +0 -127
- package/apps/daemon/src/runtime/tools/registry.ts +0 -29
- package/apps/daemon/src/runtime/tools/types.ts +0 -13
- package/apps/daemon/src/runtime/tools/web-extract.ts +0 -110
- package/apps/daemon/src/runtime/tools/web-ssrf.ts +0 -245
- package/apps/daemon/src/runtime/tools/web.ts +0 -273
- package/apps/daemon/src/runtime/worker/entry.ts +0 -221
- package/apps/daemon/src/runtime/worker/ipc-protocol.ts +0 -75
- package/apps/daemon/src/runtime/worker/spawn.ts +0 -249
- package/apps/daemon/test/core/agents.test.ts +0 -319
- package/apps/daemon/test/core/available-models.test.ts +0 -63
- package/apps/daemon/test/core/config.test.ts +0 -99
- package/apps/daemon/test/core/groups.test.ts +0 -63
- package/apps/daemon/test/core/helpers.ts +0 -50
- package/apps/daemon/test/core/identity.test.ts +0 -85
- package/apps/daemon/test/core/migrations.test.ts +0 -83
- package/apps/daemon/test/core/profiles.test.ts +0 -182
- package/apps/daemon/test/core/provider-models.test.ts +0 -57
- package/apps/daemon/test/core/provider-state.test.ts +0 -36
- package/apps/daemon/test/core/skill-meta.test.ts +0 -45
- package/apps/daemon/test/core/skills.test.ts +0 -271
- package/apps/daemon/test/core/triggers.test.ts +0 -182
- package/apps/daemon/test/core/web-tokens.test.ts +0 -79
- package/apps/daemon/test/cron.test.ts +0 -90
- package/apps/daemon/test/runtime/heartbeat.test.ts +0 -34
- package/apps/daemon/test/runtime/memory-qmd.test.ts +0 -97
- package/apps/daemon/test/runtime/memory.test.ts +0 -78
- package/apps/daemon/test/runtime/messaging.test.ts +0 -213
- package/apps/daemon/test/runtime/mock-server.ts +0 -65
- package/apps/daemon/test/runtime/openai-codex-auth.test.ts +0 -116
- package/apps/daemon/test/runtime/providers.test.ts +0 -306
- package/apps/daemon/test/runtime/retry.test.ts +0 -191
- package/apps/daemon/test/runtime/session-head.test.ts +0 -90
- package/apps/daemon/test/runtime/tools-home.test.ts +0 -102
- package/apps/daemon/test/runtime/tools-web.test.ts +0 -206
- package/apps/daemon/tsconfig.json +0 -4
- package/apps/mobile/README.md +0 -60
- package/apps/mobile/app/_layout.tsx +0 -58
- package/apps/mobile/app/agents/[id]/chat.tsx +0 -486
- package/apps/mobile/app/agents/[id]/index.tsx +0 -166
- package/apps/mobile/app/agents/index.tsx +0 -212
- package/apps/mobile/app/index.tsx +0 -21
- package/apps/mobile/app/pair.tsx +0 -226
- package/apps/mobile/app/settings.tsx +0 -419
- package/apps/mobile/app.json +0 -49
- package/apps/mobile/assets/adaptive-icon.png +0 -0
- package/apps/mobile/assets/favicon.png +0 -0
- package/apps/mobile/assets/icon.png +0 -0
- package/apps/mobile/assets/splash-icon.png +0 -0
- package/apps/mobile/babel.config.js +0 -6
- package/apps/mobile/metro.config.js +0 -28
- package/apps/mobile/package.json +0 -44
- package/apps/mobile/src/auth.ts +0 -66
- package/apps/mobile/src/pair-url.ts +0 -48
- package/apps/mobile/src/theme-context.tsx +0 -88
- package/apps/mobile/src/theme.ts +0 -135
- package/apps/mobile/test/pair-url.test.ts +0 -46
- package/apps/mobile/tsconfig.json +0 -23
- package/apps/web/components.json +0 -25
- package/apps/web/package.json +0 -39
- package/apps/web/public/baziu.svg +0 -8
- package/apps/web/src/components/AgentTabs.tsx +0 -45
- package/apps/web/src/components/BaziuLogo.tsx +0 -21
- package/apps/web/src/components/ChatPane.tsx +0 -1033
- package/apps/web/src/components/ConfigTabs.tsx +0 -29
- package/apps/web/src/components/CopyButton.tsx +0 -68
- package/apps/web/src/components/CreateGroupDialog.tsx +0 -127
- package/apps/web/src/components/FieldRow.tsx +0 -94
- package/apps/web/src/components/Footer.tsx +0 -10
- package/apps/web/src/components/PawIcon.tsx +0 -15
- package/apps/web/src/components/Sidebar.tsx +0 -287
- package/apps/web/src/components/SpawnDialog.tsx +0 -129
- package/apps/web/src/components/ThemeToggle.tsx +0 -75
- package/apps/web/src/components/TopNav.tsx +0 -34
- package/apps/web/src/components/ui/button.tsx +0 -67
- package/apps/web/src/components/ui/card.tsx +0 -103
- package/apps/web/src/components/ui/checkbox.tsx +0 -31
- package/apps/web/src/components/ui/dialog.tsx +0 -168
- package/apps/web/src/components/ui/input.tsx +0 -19
- package/apps/web/src/components/ui/label.tsx +0 -22
- package/apps/web/src/components/ui/radio-group.tsx +0 -44
- package/apps/web/src/components/ui/select.tsx +0 -192
- package/apps/web/src/components/ui/separator.tsx +0 -26
- package/apps/web/src/components/ui/table.tsx +0 -116
- package/apps/web/src/components/ui/tabs.tsx +0 -88
- package/apps/web/src/components/ui/textarea.tsx +0 -18
- package/apps/web/src/lib/auth.ts +0 -50
- package/apps/web/src/lib/daemon-client.ts +0 -34
- package/apps/web/src/lib/md.ts +0 -45
- package/apps/web/src/lib/utils.ts +0 -6
- package/apps/web/src/lib/wire-constants.ts +0 -27
- package/apps/web/src/routeTree.gen.ts +0 -408
- package/apps/web/src/router.tsx +0 -20
- package/apps/web/src/routes/__root.tsx +0 -123
- package/apps/web/src/routes/agents/$id/inbox.tsx +0 -207
- package/apps/web/src/routes/agents/$id/index.tsx +0 -527
- package/apps/web/src/routes/agents/$id/triggers.tsx +0 -239
- package/apps/web/src/routes/agents/index.tsx +0 -265
- package/apps/web/src/routes/api/$.ts +0 -88
- package/apps/web/src/routes/config/index.tsx +0 -315
- package/apps/web/src/routes/config/services.tsx +0 -49
- package/apps/web/src/routes/config/tokens.tsx +0 -192
- package/apps/web/src/routes/groups/$id/index.tsx +0 -153
- package/apps/web/src/routes/groups/$id/memory.tsx +0 -321
- package/apps/web/src/routes/groups/index.tsx +0 -191
- package/apps/web/src/routes/index.tsx +0 -133
- package/apps/web/src/routes/login.tsx +0 -63
- package/apps/web/src/routes/profiles/$id.tsx +0 -549
- package/apps/web/src/routes/profiles/index.tsx +0 -458
- package/apps/web/src/routes/skills/index.tsx +0 -297
- package/apps/web/src/routes/welcome.tsx +0 -61
- package/apps/web/src/styles.css +0 -449
- package/apps/web/tsconfig.json +0 -25
- package/apps/web/vite.config.ts +0 -25
- package/biome.json +0 -23
- package/docs/agent-engine.md +0 -219
- package/docs/architecture.md +0 -627
- package/docs/backlog/README.md +0 -42
- package/docs/backlog/draft/BAZ-001-a2a-federation-spike.md +0 -125
- package/docs/openclaw-reference.md +0 -210
- package/packages/api-types/package.json +0 -11
- package/packages/api-types/src/entities.ts +0 -146
- package/packages/api-types/src/events.ts +0 -55
- package/packages/api-types/src/index.ts +0 -488
- package/packages/api-types/src/memory.ts +0 -15
- package/packages/client/package.json +0 -13
- package/packages/client/src/index.ts +0 -117
- package/pnpm-workspace.yaml +0 -3
- package/tsconfig.base.json +0 -23
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -22
package/docs/backlog/README.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Bazilion — Product Backlog
|
|
2
|
-
|
|
3
|
-
Backlog items live in this directory, one file per item, organised by state.
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
docs/backlog/
|
|
7
|
-
├── draft/ ← needs more definition / open questions / explicitly deferred
|
|
8
|
-
├── todo/ ← refined, ready to pull into a sprint
|
|
9
|
-
├── in_progress/ ← actively being worked on right now
|
|
10
|
-
└── done/ ← shipped, kept as a historical record
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Conventions
|
|
14
|
-
|
|
15
|
-
- **Naming:** `BAZ-NNN-short-slug.md` (sequential at creation time so codes don't shift when priority changes).
|
|
16
|
-
- **Frontmatter** (every file): `id`, `title`, `status`, `size`, `created`, optional `shipped` / `priority` / `deferred` / `deferred_reason` / `note`.
|
|
17
|
-
- **Body shape:** User stories (As a / I want / So that) → Goal → Why → Scope → Out of scope → Tests. Open items add Open Questions; shipped items add an As-built block.
|
|
18
|
-
- **Sizes** (solo-dev pace): XS ≈ afternoon, S ≈ 1–2 days, M ≈ ~1 week, L ≈ 1–2 weeks, XL > 2 weeks → split into multiple BAZs.
|
|
19
|
-
- **State transitions:** to move an item, `git mv` it between dirs and update the `status:` field in frontmatter.
|
|
20
|
-
|
|
21
|
-
## State definitions
|
|
22
|
-
|
|
23
|
-
- **Draft** — captured but not committed-to. Has open questions, missing acceptance criteria, or no forcing function. Don't start work without resolving the open questions.
|
|
24
|
-
- **Todo** — refined and ready. User stories + scope are clear; pulling it into a sprint is a yes/no decision, not a "let's first figure out what this means" decision.
|
|
25
|
-
- **In Progress** — actively being worked on right now. Move here from `todo/` when implementation starts, so it's clear what's in flight. There's no enforced limit — solo-dev pace usually keeps this folder at 0–1 items, but a refactor with multiple side BAZs in parallel is fine. Move to `done/` when shipped.
|
|
26
|
-
- **Done** — shipped. The file becomes part of the project's release history; the `As-built` block records what actually happened (vs. what was planned).
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Draft (1)
|
|
31
|
-
|
|
32
|
-
| ID | Title | Size | Notes |
|
|
33
|
-
|----|-------|------|-------|
|
|
34
|
-
| [BAZ-001](draft/BAZ-001-a2a-federation-spike.md) | Spike — federated multi-employee Bazilion via A2A | S | Investigation only; output is a follow-up implementation BAZ |
|
|
35
|
-
|
|
36
|
-
## Todo (0)
|
|
37
|
-
|
|
38
|
-
_None yet._
|
|
39
|
-
|
|
40
|
-
## Done (0)
|
|
41
|
-
|
|
42
|
-
_None yet._
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: BAZ-001
|
|
3
|
-
title: Spike — federated multi-employee Bazilion via A2A
|
|
4
|
-
status: draft
|
|
5
|
-
size: S (timebox 1–2 days, investigation only)
|
|
6
|
-
created: 2026-05-17
|
|
7
|
-
note: Spike — output is a recommendation + a follow-up BAZ with the chosen approach scoped, not shipped code. Do not pull this BAZ expecting deliverable software.
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# BAZ-001 — Spike — federated multi-employee Bazilion via A2A
|
|
11
|
-
|
|
12
|
-
**Status:** Backlog (draft, spike). Today Bazilion is single-tenant per install: one operator, one bootstrap token (= god mode), all state under `~/.bazilion/` on one box. Inter-agent communication (`send_message` / `read_inbox` / `wait_for_reply`) is in-process inside the daemon, with `MessagingHost` injected either as `createDbMessagingHost(db)` (compact/context routes) or `createIpcMessagingHost()` (worker subprocess, proxied over Node IPC). To make Bazilion usable inside a company without rebuilding it as multi-tenant SaaS, an alternative direction is: every employee runs their own Bazilion, installs speak to each other over A2A (Google's Agent-to-Agent protocol, or a comparable open spec) so that `alice@acme/refactor-helper` can be invoked from Bob's box. This spike resolves the open questions before an implementation BAZ is written.
|
|
13
|
-
|
|
14
|
-
**Dependency:** None on code; depends on a product decision that federation is the target shape (vs. SaaS or hardened multi-user self-hosted).
|
|
15
|
-
|
|
16
|
-
## User stories (spike)
|
|
17
|
-
|
|
18
|
-
- **As the operator considering company adoption**, I want a documented, decided answer to "is A2A-based federation viable as Bazilion's company-deployment story, and what's the smallest end-to-end slice that proves it", so the implementation BAZ can be scoped + estimated without revisiting the protocol choice mid-flight.
|
|
19
|
-
- **As a future employee installing Bazilion on my laptop**, I want the spike to define how my install discovers and trusts other employees' installs without each pair needing manual setup, so the onboarding step is "install + join company directory", not "exchange certs with every coworker".
|
|
20
|
-
- **As the operator legally responsible for audit and offboarding**, I want the spike to surface what minimum centralised infrastructure is required (directory? PKI? audit sink?) even in a peer-to-peer runtime, so the "central infra footprint" decision is informed, not accidental.
|
|
21
|
-
|
|
22
|
-
## Goal
|
|
23
|
-
|
|
24
|
-
Produce a written recommendation that answers the questions below with enough detail that a follow-up implementation BAZ can be drafted, sized, and pulled. **Strict timebox: 1–2 days.** No code lands from this BAZ beyond a throwaway sandbox proof-of-concept if needed to validate the wire model (e.g. a minimal A2A endpoint serving one agent card and round-tripping one message between two local installs on different ports).
|
|
25
|
-
|
|
26
|
-
## Why now
|
|
27
|
-
|
|
28
|
-
The exploratory conversation surfaced federation as a credible alternative to SaaS that preserves Bazilion's single-tenant ethos ("bleeding-edge personal software, skip compat shims"). Before committing direction — and before any of the existing internals (the in-process `MessagingHost`, the `~/.bazilion/groups/<slug>/` filesystem-rooted group model, the bootstrap-token-equals-god-mode auth) get refactored in ways that prematurely lock in either direction — confirm whether federation actually answers the company-deployment question or whether it just punts the hard problems to a different layer.
|
|
29
|
-
|
|
30
|
-
## Questions to answer
|
|
31
|
-
|
|
32
|
-
1. **Protocol choice — A2A vs. alternatives.**
|
|
33
|
-
- Google A2A (agent cards, task lifecycle, SSE-based streaming responses): the obvious candidate, openly published, framework-agnostic, maps directly onto Bazilion's existing `ChatFrame` NDJSON shape.
|
|
34
|
-
- MCP (Model Context Protocol): solves agent ↔ tool, not agent ↔ agent. Probably wrong for this use case but document the rejection.
|
|
35
|
-
- Custom HTTP + WebSocket between Bazilion installs: maximum control, minimum interop. Reject unless A2A has a hard incompatibility with Bazilion's existing shapes.
|
|
36
|
-
- Matrix / NATS / similar message bus: solves the async-delivery problem (laptops sleep) but doesn't define agent semantics; could compose with A2A rather than replace it.
|
|
37
|
-
- Decision criterion: pick the option that gives the smallest delta from the existing in-process `MessagingHost` shape while interoperating with non-Bazilion agents (a third-party A2A-speaking agent should be addressable too).
|
|
38
|
-
|
|
39
|
-
2. **Discovery — how does Alice's install resolve `bob@acme/code-reviewer`?**
|
|
40
|
-
- Static config (each install lists every other install): trivial, doesn't scale past a handful of employees.
|
|
41
|
-
- mDNS / Tailscale magic DNS: works on shared networks (Tailnet, office LAN), breaks across geographies and home networks.
|
|
42
|
-
- Thin company "directory" service: a small centralised HTTP service that maps `<user>@<company>` to a current endpoint URL + presence + public key fingerprint. Each install registers itself on startup and refreshes a TTL.
|
|
43
|
-
- DNS-based (SRV records under `acme.com`): elegant but requires DNS ops and doesn't carry presence.
|
|
44
|
-
- Recommendation expected: thin directory service. Confirm the smallest surface (probably 3 endpoints: register, lookup, list).
|
|
45
|
-
|
|
46
|
-
3. **Identity / trust — what authenticates an A2A call from Alice's install to Bob's?**
|
|
47
|
-
- mTLS with per-install certs issued by a company CA: standard, secure, requires CA infrastructure.
|
|
48
|
-
- Signed messages (per-install Ed25519 key, signature over the request body): simpler than mTLS, no CA per se but still needs key distribution → back to directory service holding pubkeys.
|
|
49
|
-
- OIDC + JWT bearer per call (the directory service issues short-lived tokens after the operator authenticates via SSO): heavier on the directory, lighter on the install.
|
|
50
|
-
- Today's bootstrap-token-equals-god-mode is incompatible with any of the above — `isValidToken` in `apps/daemon/src/lib/auth.ts` will need to grow a "remote A2A peer" code path that does NOT grant the same powers as a loopback bearer.
|
|
51
|
-
- Decision criterion: pick the option with the smallest surface that still supports per-agent ACLs (next question).
|
|
52
|
-
|
|
53
|
-
4. **Per-agent authorization — who can invoke which of my agents.**
|
|
54
|
-
- Today: token holders can do everything. A federated story needs `alice` to expose `refactor-helper` to "the whole company", `code-reviewer` to "team-platform", and `personal-todo` to nobody.
|
|
55
|
-
- Schema sketch: an `agent_exposures(agent_id, audience, capability)` table on each install. `audience` could be `*`, `@company`, `@group:platform`, `@user:bob@acme`. `capability` could be `chat`, `read_inbox`, `read_skills_list`.
|
|
56
|
-
- Default-deny: a newly spawned agent is local-only until the operator publishes it.
|
|
57
|
-
- Open question: where does the audience definition live? On the directory service (single source of truth) or on each install (federated and possibly inconsistent)?
|
|
58
|
-
|
|
59
|
-
5. **Async delivery — laptops sleep.**
|
|
60
|
-
- Bazilion's existing inbox model (`send_message`, `read_inbox`, `wait_for_reply`) is already async-friendly within a single install. Extending it cross-install means: when Alice sends to `bob@acme/code-reviewer` and Bob's box is offline, the message must be durably queued somewhere.
|
|
61
|
-
- Option A: sender retries with backoff until receiver online. Simple but requires sender to stay online too.
|
|
62
|
-
- Option B: directory service has a per-user store-and-forward inbox (HTTP PUT to deposit, HTTP GET to drain when online). The directory grows from "thin registry" into "small message broker"; design implication for question 2.
|
|
63
|
-
- Option C: third-party message bus (Matrix federation, NATS JetStream). External dep, but separates concerns cleanly.
|
|
64
|
-
- Recommendation expected: option B for the first cut (operationally simpler than running a Matrix homeserver), with the door left open to swap in C later.
|
|
65
|
-
|
|
66
|
-
6. **Cross-install group state — the deepest problem.**
|
|
67
|
-
- Today: a Bazilion group is `~/.bazilion/groups/<slug>/` (real dir or symlink) + the `groups.user_md` DB column + shared qmd memory at `<group.path>/memory/`. Every member of the group writes to the same store.
|
|
68
|
-
- Federated equivalent: "Alice and Bob both belong to the platform-team group" — where does the group filesystem live? Where do the shared memory writes go?
|
|
69
|
-
- Option A — **single-owner groups**: a group lives on exactly one employee's install (its "host"). Other employees join as remote guests via A2A; their `memory_*` tool calls become A2A round-trips to the host. Loses local availability for guests when the host is offline. Simple to implement, big UX limitation.
|
|
70
|
-
- Option B — **mirrored groups with sync**: each member's install has a local copy of group state; changes sync via CRDT or last-writer-wins. Genuinely hard (qmd index conflicts, USER.md merge conflicts, file content conflicts) and changes the on-disk model materially.
|
|
71
|
-
- Option C — **directory-hosted groups**: the directory service stores group memory and USER.md; every install reads/writes via the directory. Centralises the most contested piece of state.
|
|
72
|
-
- Recommendation expected: option A for the first cut (smallest delta from today's code). Explicitly document the limitation; revisit if the limitation becomes the dominant complaint.
|
|
73
|
-
|
|
74
|
-
7. **Offboarding + audit — the compliance angle.**
|
|
75
|
-
- When Alice leaves Acme: who can revoke her A2A access? Who gets her agent transcripts? Who shuts down her install's group-host role for groups she was hosting (option A from question 6)?
|
|
76
|
-
- Pure peer-to-peer makes this brittle. A central component (the directory) is the natural revocation point — yanking Alice's directory entry makes her unaddressable.
|
|
77
|
-
- Centralised audit: even with a federated runtime, compliance will likely want all transcripts streamed to a central audit sink. pi's session JSONL files are local-only today; the design should at least define the streaming hook (a webhook fired per `SessionEvent`?), even if the spike doesn't implement it.
|
|
78
|
-
- Output of the spike: a one-paragraph plain-English summary of "what central infra is mandatory for a viable company deployment" so the operator can decide whether to commit to running a directory + audit sink, or whether that footprint reframes the decision toward SaaS.
|
|
79
|
-
|
|
80
|
-
8. **Implementation surface — what changes in the current codebase.**
|
|
81
|
-
- `apps/daemon/src/lib/messaging-host.ts`: a third host shape (`createA2AMessagingHost(directoryUrl)`) that resolves `alice@acme/...` addresses via the directory, then makes A2A calls.
|
|
82
|
-
- `apps/daemon/src/routes/`: a new `a2a.ts` exposing this install's agents over A2A's task/streaming endpoints, gated by the per-agent authorization model (question 4).
|
|
83
|
-
- `apps/daemon/src/lib/middleware-auth.ts`: a second code path for A2A peer auth that does NOT grant bootstrap-token powers (question 3).
|
|
84
|
-
- The `MessagingHost` interface itself probably needs to grow remote addressing semantics (address parsing for `<user>@<company>/<agent>`) — confirm whether the existing signatures cover this or need a v2.
|
|
85
|
-
- Worker IPC: workers today RPC the daemon for messaging via `createIpcMessagingHost`. Cross-install calls still resolve at the daemon (workers don't speak A2A directly), so the worker side likely doesn't change.
|
|
86
|
-
|
|
87
|
-
## Out of scope (for the spike)
|
|
88
|
-
|
|
89
|
-
- **Picking the directory hosting model** (self-hosted by the operator vs. a hosted service). That's an ops decision the implementation BAZ inherits.
|
|
90
|
-
- **Identity provider integration** (SSO via Okta / Azure AD / Google Workspace). The spike assumes the directory has *some* way to authenticate users; which IDP is plumbing for the implementation BAZ.
|
|
91
|
-
- **Billing / cost attribution.** Each install uses its own provider keys today; that's the federated default and doesn't need solving at the spike stage.
|
|
92
|
-
- **A2A spec compliance certification.** The spike validates that the protocol fits Bazilion's shape; full conformance testing is implementation work.
|
|
93
|
-
- **Mobile client A2A.** `apps/mobile` today talks only to its paired daemon. Federated mobile is a follow-on concern, not a spike concern.
|
|
94
|
-
- **Multi-tenant within a single install.** Federation deliberately avoids this — each install stays single-tenant; multi-tenant per-install is the SaaS direction and would be a different BAZ.
|
|
95
|
-
|
|
96
|
-
## Deliverable
|
|
97
|
-
|
|
98
|
-
A new BAZ file `docs/backlog/todo/BAZ-NNN-a2a-federation-implementation.md` (number assigned at spike-completion time) containing:
|
|
99
|
-
|
|
100
|
-
1. The chosen protocol (A2A vs. alternative) + one-paragraph rationale.
|
|
101
|
-
2. The directory service shape: language/runtime, hosting model, endpoint surface, auth model. (Could itself be a separate BAZ if the directory turns out to be a non-trivial service.)
|
|
102
|
-
3. The per-install changes: routes added, middleware changes, `MessagingHost` shape, schema additions for `agent_exposures` + remote-peer auth.
|
|
103
|
-
4. The cross-install group model decision (single-owner / mirrored / directory-hosted) + rationale + a one-paragraph description of the limitation it accepts.
|
|
104
|
-
5. The async-delivery model (sender-retries / directory-inbox / external-bus) + rationale.
|
|
105
|
-
6. The compliance hook (audit-streaming webhook? per-`SessionEvent` outbound?) — at minimum, a defined surface even if implementation is deferred.
|
|
106
|
-
7. A size estimate (S/M/L/XL) and explicit dependencies. If the answer is XL, split into multiple BAZs at this point.
|
|
107
|
-
8. The smallest end-to-end slice that proves the model works (e.g. "two local installs on ports 4321/4421, each exposes one agent over A2A, one invokes the other through the directory, audit log captures the call") — this is what the first implementation BAZ ships.
|
|
108
|
-
|
|
109
|
-
The implementation BAZ (or BAZs) is what gets pulled into a sprint. **This BAZ (BAZ-001) closes when that file lands.**
|
|
110
|
-
|
|
111
|
-
## Open questions to confirm with the operator before starting the spike
|
|
112
|
-
|
|
113
|
-
1. **Is federation actually the chosen direction**, or is this spike comparing federation against hardened-multi-user-self-hosted and SaaS as siblings? If sibling-comparison, the spike's deliverable is a three-way recommendation, not a federation implementation plan — which roughly doubles the timebox.
|
|
114
|
-
2. **Target company size for the first deployment** — 5 employees? 50? 500? The directory service shape and the group-state decision both flex significantly between those numbers.
|
|
115
|
-
3. **Operator's appetite for running central infrastructure** — "I'll happily run a small directory + audit sink on Kamal / Fly / a VPS" keeps federation in play; "I want zero central infra" forces the spike to investigate fully peer-to-peer alternatives (BitTorrent-style DHT discovery, gossip-based presence) which are research-grade and probably push the size to L or XL.
|
|
116
|
-
4. **Interop ambition** — does Bazilion want to be addressable from non-Bazilion A2A clients (a Google ADK agent, a LangGraph agent), or is A2A just an internal wire format between Bazilion installs? Affects strictness of spec compliance and how much of A2A's surface needs implementing.
|
|
117
|
-
|
|
118
|
-
## Tests (sketch — for the eventual implementation BAZ, not the spike itself)
|
|
119
|
-
|
|
120
|
-
- Two Bazilion installs on the same machine, different ports, register with a local directory; install A invokes an agent on install B via A2A; the `ChatFrame` NDJSON stream round-trips end-to-end through the new `MessagingHost`.
|
|
121
|
-
- Per-agent ACL: an agent published to `@group:platform` rejects a call from a peer not in that group; the rejection is logged on both sides.
|
|
122
|
-
- Offline-recipient delivery: install A sends to an agent on install B while B is down; B comes online and drains the queued message via whatever path question 5 picks.
|
|
123
|
-
- Cross-install group memory: a `memory_write` from install A appears in subsequent `memory_search` results from install B (assuming the chosen group-state model supports it; if option A from question 6 wins, the test instead asserts that B's `memory_*` tool calls correctly proxy to A as host).
|
|
124
|
-
- Peer-auth code path: an A2A call presenting a valid peer credential CANNOT escalate to bootstrap-token actions (e.g. cannot mint new tokens, cannot read `auth.json`, cannot list other agents not exposed to it).
|
|
125
|
-
- Compliance hook (if scoped into the first implementation BAZ): an A2A-initiated turn produces an audit event with the remote caller's identity stamped on it.
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
# OpenClaw — reference for Bazilion contributors
|
|
2
|
-
|
|
3
|
-
Bazilion's README and `CLAUDE.md` call the project "OpenClaw-inspired", and the daemon literally reads `~/.openclaw/skills/` when you run `bazilion skill import --from openclaw`. This doc captures what upstream OpenClaw actually is, so contributors know what we borrowed, what we deliberately didn't, and where the format we accept comes from.
|
|
4
|
-
|
|
5
|
-
Snapshot date: 2026-05-17. Source: `docs.openclaw.ai` + `github.com/openclaw/openclaw` `main`. Re-fetch before relying on exact counts.
|
|
6
|
-
|
|
7
|
-
## 1. What OpenClaw is
|
|
8
|
-
|
|
9
|
-
A self-hosted personal AI-assistant gateway — *not* a Claude Code clone. Repo: `github.com/openclaw/openclaw`. Docs: `docs.openclaw.ai`. License: MIT. Runs on Node 22.12+. Install: `npm i -g openclaw && openclaw onboard` (or `curl -fsSL https://openclaw.ai/install.sh | bash`).
|
|
10
|
-
|
|
11
|
-
It speaks to the user over channels they already use (WhatsApp, Telegram, iMessage, Signal, IRC, Mattermost, voice), holds persistent memory, and is LLM-agnostic (~35 model-provider plugins). The mascot is a lobster; the slogan is "the lobster way".
|
|
12
|
-
|
|
13
|
-
The two extensibility surfaces are **skills** and **plugins**. They are *not* interchangeable.
|
|
14
|
-
|
|
15
|
-
## 2. Skills vs plugins — the actual difference
|
|
16
|
-
|
|
17
|
-
From the docs, verbatim: *"Skills tell the agent how to do things. Plugins give the agent new abilities it couldn't have otherwise."*
|
|
18
|
-
|
|
19
|
-
| Axis | Skill | Plugin |
|
|
20
|
-
|---|---|---|
|
|
21
|
-
| What it is | A directory with a `SKILL.md` (YAML frontmatter + markdown body) | An npm-shaped TypeScript package loaded in-process by the gateway |
|
|
22
|
-
| What it adds | New *knowledge* — instructions the LLM follows using already-available tools | New *capability* — new channels, model providers, tools, memory backends, lifecycle hooks |
|
|
23
|
-
| Runtime cost | Zero — only text is injected into the prompt (progressive disclosure: YAML metadata loaded eagerly, body loaded on description match) | Live code running inside the gateway process |
|
|
24
|
-
| Author writes | Markdown | TypeScript |
|
|
25
|
-
| Manifest | YAML frontmatter inside `SKILL.md` | Separate `openclaw.plugin.json` (declarative) + the npm package's `package.json` (code + deps) |
|
|
26
|
-
| Install source | ClawHub registry, local dir, bundled | `clawhub:<pkg>`, `npm:<pkg>`, `git:<repo>@<ref>`, `./local` |
|
|
27
|
-
| Discovery | Directory scan (precedence-ordered, see §5) | Listed in `openclaw.json`, loaded at gateway start |
|
|
28
|
-
| Hooks | None — skills are pure prompt content | 28 lifecycle hooks across model/agent/message/tool/session/sub-agent layers |
|
|
29
|
-
| Failure blast radius | A bad skill produces bad answers | A bad plugin can crash the gateway, leak secrets, intercept every tool call |
|
|
30
|
-
| Trust gate needed | No (text only) | Yes (arbitrary code) |
|
|
31
|
-
| Can ship the other? | No — a skill cannot register code | Yes — a plugin may bundle skills via a `skills` directory referenced in its manifest |
|
|
32
|
-
|
|
33
|
-
**Rule of thumb:** if the new behavior can be expressed as "tell the agent, in English, how to use existing tools to do X", it's a skill. If it needs to register a new model provider, a new transport, a custom tool, or hook into the request/tool lifecycle, it's a plugin. The split exists because most "I want my agent to know how to do X" requests are content, not code — and content is far cheaper to author, distribute, and trust.
|
|
34
|
-
|
|
35
|
-
## 3. Default skills (~57 bundled in `skills/` on `main`)
|
|
36
|
-
|
|
37
|
-
Grouped by purpose (slugs match `github.com/openclaw/openclaw/tree/main/skills`):
|
|
38
|
-
|
|
39
|
-
| Category | Skills |
|
|
40
|
-
|---|---|
|
|
41
|
-
| Messaging / chat | `imsg`, `wacli` (WhatsApp), `discord`, `slack`, `voice-call`, `xurl` (X/Twitter) |
|
|
42
|
-
| Productivity / tasks | `apple-notes`, `apple-reminders`, `bear-notes`, `notion`, `obsidian`, `things-mac`, `trello`, `taskflow`, `taskflow-inbox-triage`, `spike` |
|
|
43
|
-
| Google / Office | `gog` (Gmail/Calendar/Drive/Docs/Sheets), `goplaces`, `gh-issues`, `github` |
|
|
44
|
-
| Smart-home / hardware | `openhue` (Hue), `eightctl` (Eight Sleep), `sonoscli`, `blucli` (BluOS), `camsnap` (RTSP cams) |
|
|
45
|
-
| Media / generation | `canvas`, `diagram-maker`, `meme-maker`, `gifgrep`, `nano-pdf`, `video-frames`, `songsee`, `summarize` |
|
|
46
|
-
| Speech | `openai-whisper`, `openai-whisper-api`, `sherpa-onnx-tts`, `sag` (ElevenLabs TTS) |
|
|
47
|
-
| Coding / dev | `coding-agent`, `gemini` (Gemini CLI), `tmux`, `node-connect`, `node-inspect-debugger`, `python-debugpy`, `oracle`, `peekaboo` (macOS UI automation) |
|
|
48
|
-
| Email / RSS | `himalaya` (IMAP/SMTP), `blogwatcher` |
|
|
49
|
-
| Utility / infra | `1password`, `clawhub` (registry mgmt), `healthcheck`, `mcporter` (MCP bridge), `model-usage`, `session-logs`, `skill-creator`, `weather`, `spotify-player`, `ordercli` |
|
|
50
|
-
|
|
51
|
-
### Skill file layout
|
|
52
|
-
|
|
53
|
-
A skill is a directory whose only required file is `SKILL.md`. Helper scripts are optional and referenced via `{baseDir}`. No separate `metadata.json` — everything lives in YAML frontmatter:
|
|
54
|
-
|
|
55
|
-
```yaml
|
|
56
|
-
---
|
|
57
|
-
name: summarize
|
|
58
|
-
description: "Summarize or transcribe URLs, YouTube/videos, podcasts, articles, transcripts, PDFs, and local files."
|
|
59
|
-
homepage: https://summarize.sh
|
|
60
|
-
metadata:
|
|
61
|
-
{
|
|
62
|
-
"openclaw":
|
|
63
|
-
{
|
|
64
|
-
"emoji": "🧾",
|
|
65
|
-
"requires": { "bins": ["summarize"] },
|
|
66
|
-
"install":
|
|
67
|
-
[ { "id": "brew", "kind": "brew",
|
|
68
|
-
"formula": "steipete/tap/summarize",
|
|
69
|
-
"bins": ["summarize"],
|
|
70
|
-
"label": "Install summarize (brew)" } ]
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
---
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Required frontmatter: `name`, `description`. Optional: `homepage`, `version`, `user-invocable` (slash command), `hidden`, `command-dispatch` / `command-dispatch-tool` (bypass model — direct tool dispatch), `command-arg-mode`, `disable-model-invocation`, and a **single-line JSON** `metadata.openclaw` object holding `emoji`, `requires.{bins,env}`, `primaryEnv`, `os`, and `install[]` recipes (brew/npm/pip/etc.). The parser only supports single-line frontmatter values.
|
|
77
|
-
|
|
78
|
-
## 4. Default plugins (~120 in the inventory)
|
|
79
|
-
|
|
80
|
-
From `docs.openclaw.ai/plugins/plugin-inventory`. The inventory doesn't flag which are on by default — only that model providers, speech, and the browser plugin are auto-enabled.
|
|
81
|
-
|
|
82
|
-
| Category | Plugins |
|
|
83
|
-
|---|---|
|
|
84
|
-
| Model providers (~35) | Anthropic, OpenAI, Google, Groq, Cerebras, DeepSeek, Fireworks, GitHub Copilot, Hugging Face, LM Studio, Ollama, Mistral, Moonshot, OpenRouter, Qwen, Together, vLLM, xAI, Z.AI, Arcee, BytePlus, Chutes, DeepInfra, Kilocode, Kimi, LiteLLM, NVIDIA, OpenCode, OpenCode Go, Qianfan, StepFun, Synthetic, Venice, Vercel AI Gateway, Volcengine, Xiaomi |
|
|
85
|
-
| Channels | Clickclack, iMessage, IRC, Mattermost, Signal, Telegram |
|
|
86
|
-
| Speech / media | Azure Speech, Deepgram, ElevenLabs, Gradium, Inworld, Microsoft Speech, TTS Local CLI |
|
|
87
|
-
| Web / search | DuckDuckGo, Exa, Firecrawl, Perplexity, SearXNG, Web Readability |
|
|
88
|
-
| Image / video gen | Alibaba, ComfyUI, FAL, Minimax, OpenRouter, Runway, Together |
|
|
89
|
-
| Memory | Memory Core, Memory Wiki, Voyage |
|
|
90
|
-
| Infra / utilities | Admin HTTP RPC, Bonjour, Browser, Canvas, Document Extract, File Transfer, LLM Task, Migrate Claude, Migrate Hermes, OC Path, Open Prose, Skill Workshop, Tokenjuice, Webhooks |
|
|
91
|
-
|
|
92
|
-
### Plugin manifest (`openclaw.plugin.json`)
|
|
93
|
-
|
|
94
|
-
Declarative only — runtime code lives in the npm package itself. Minimum:
|
|
95
|
-
|
|
96
|
-
```json
|
|
97
|
-
{
|
|
98
|
-
"id": "plugin-name",
|
|
99
|
-
"configSchema": { "type": "object", "additionalProperties": false, "properties": {} }
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Optional fields: `name`, `description`, `version`, `providers[]`, `channels[]`, `contracts` (capability snapshot), `activation` (activation-planner metadata), `setup`, `uiHints`.
|
|
104
|
-
|
|
105
|
-
### Plugin hooks (28, six categories)
|
|
106
|
-
|
|
107
|
-
- **Model resolution:** `before_model_resolve`
|
|
108
|
-
- **Agent lifecycle:** `agent_turn_prepare`, `before_prompt_build`, `before_agent_{start,run,reply,finalize}`, `agent_end`, `heartbeat_prompt_contribution`
|
|
109
|
-
- **Message flow:** `model_call_{started,ended}`, `llm_{input,output}`, `message_{received,sending,sent}`, `before_dispatch`, `reply_dispatch`, `inbound_claim`
|
|
110
|
-
- **Tools:** `before_tool_call` (rewrite params, block, or require approval), `after_tool_call`, `tool_result_persist`, `before_message_write`
|
|
111
|
-
- **Sessions / compaction:** `session_{start,end}`, `before_compaction`, `after_compaction`, `before_reset`
|
|
112
|
-
- **Sub-agents / gateway:** `subagent_{spawning,delivery_target,spawned,ended}`, `gateway_{start,stop}`, `cron_changed`, `before_install`
|
|
113
|
-
|
|
114
|
-
Bundled hook packs: `session-memory`, `command-logger`, `bootstrap-extra-files`. Plugins may also ship hooks inline.
|
|
115
|
-
|
|
116
|
-
## 5. On-disk layout, config, discovery
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
~/.openclaw/
|
|
120
|
-
openclaw.json # JSON5 config
|
|
121
|
-
skills/ # managed/local skills
|
|
122
|
-
credentials/ # channel + provider creds
|
|
123
|
-
agents/<id>/agent/auth-profiles.json
|
|
124
|
-
workspace/ # default workspace (overridable)
|
|
125
|
-
skills/<name>/SKILL.md
|
|
126
|
-
.agents/skills/<name>/SKILL.md
|
|
127
|
-
~/.agents/skills/ # personal (non-workspace) agent skills
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Config — `openclaw.json`** (JSON5):
|
|
131
|
-
|
|
132
|
-
```json5
|
|
133
|
-
{
|
|
134
|
-
skills: {
|
|
135
|
-
entries: {
|
|
136
|
-
"image-lab": { enabled: true },
|
|
137
|
-
"peekaboo": { enabled: true },
|
|
138
|
-
"sag": { enabled: false },
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Skill load order (highest precedence wins):**
|
|
145
|
-
|
|
146
|
-
1. `<workspace>/skills`
|
|
147
|
-
2. `<workspace>/.agents/skills`
|
|
148
|
-
3. `~/.agents/skills`
|
|
149
|
-
4. `~/.openclaw/skills`
|
|
150
|
-
5. Bundled (shipped with install)
|
|
151
|
-
6. `skills.load.extraDirs`
|
|
152
|
-
|
|
153
|
-
Discovery is a directory scan — no index file. On name collision, the higher source wins. Enable/disable is **config-only**: `skills.entries.<name>.enabled` in `openclaw.json` overrides even bundled skills. SKILL.md frontmatter has no `enabled` flag.
|
|
154
|
-
|
|
155
|
-
### CLI surface
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
openclaw skills search "calendar" [--limit 20] [--json]
|
|
159
|
-
openclaw skills install <slug> [--version <v>] [--force] [--agent <id>]
|
|
160
|
-
openclaw skills update <slug> | --all [--agent <id>]
|
|
161
|
-
openclaw skills list [--eligible] [--json] [--verbose] [--agent <id>]
|
|
162
|
-
openclaw skills info <name> [--json] [--agent <id>]
|
|
163
|
-
openclaw skills check [--agent <id>] [--json]
|
|
164
|
-
|
|
165
|
-
openclaw plugins install clawhub:<pkg>
|
|
166
|
-
openclaw plugins install npm:<pkg>
|
|
167
|
-
openclaw plugins install git:github.com/<owner>/<repo>@<ref>
|
|
168
|
-
openclaw plugins install ./local-dir [--link]
|
|
169
|
-
openclaw plugins install <pkg> --marketplace <source>
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
No `remove` / `enable` / `disable` subcommands — those flow through `openclaw.json` edits and filesystem cleanup.
|
|
173
|
-
|
|
174
|
-
### ClawHub
|
|
175
|
-
|
|
176
|
-
Official registry: `github.com/openclaw/clawhub`. ~13,729 third-party skills as of Feb 2026. Community-curated lists include `awesome-openclaw-plugins`, `awesome-openclaw-skills`, `awesome-openclaw`.
|
|
177
|
-
|
|
178
|
-
## 6. What Bazilion borrows, and what it doesn't
|
|
179
|
-
|
|
180
|
-
**Borrowed:**
|
|
181
|
-
|
|
182
|
-
- The **prompt-only skill model.** `apps/daemon/src/core/skills/` reads `SKILL.md` and injects the body into the system prompt of every attached agent. Helper scripts run via the agent's generic `bash` tool. See `CLAUDE.md` → "OpenClaw skill model: prompt-only".
|
|
183
|
-
- The **`SKILL.md` + YAML frontmatter format.** Upstream skills "drop in unchanged" per the README — `bazilion skill import --from openclaw` resolves to `~/.openclaw/skills/` (see `apps/daemon/src/routes/skills.ts`).
|
|
184
|
-
- The general idea of a per-user state root with a workspace concept. Bazilion's `~/.bazilion/groups/<slug>/` is roughly the analogue of OpenClaw's `<workspace>/`.
|
|
185
|
-
|
|
186
|
-
**Bazilion-only extensions on top of the upstream format:**
|
|
187
|
-
|
|
188
|
-
- `entry:` frontmatter field + the `run_skill` tool. Upstream OpenClaw skills don't have these; that's why imported skills surface as `docs-only` in Bazilion (memory: `project_skill_model.md`).
|
|
189
|
-
|
|
190
|
-
**Deliberately *not* borrowed:**
|
|
191
|
-
|
|
192
|
-
- The **plugin model** (28 hooks, TypeScript in-process modules, `openclaw.plugin.json`). Bazilion has no plugin SDK — all extensibility goes through skills + native daemon code.
|
|
193
|
-
- **Channels.** Upstream's first-class WhatsApp/Telegram/iMessage/Signal transports have no Bazilion equivalent; we expose HTTP only.
|
|
194
|
-
- **ClawHub.** No registry integration.
|
|
195
|
-
- **JSON5 `openclaw.json`** config surface. Bazilion stores config in the daemon's SQLite (`config` table) + secrets in the encrypted `secrets` table (see `CLAUDE.md` → "Secrets and config").
|
|
196
|
-
- The richer skill frontmatter (`user-invocable`, `command-dispatch`, `disable-model-invocation`, install recipes). Bazilion's skill loader only consumes `name` + `description` + body today.
|
|
197
|
-
|
|
198
|
-
## 7. Authoritative sources
|
|
199
|
-
|
|
200
|
-
- `https://github.com/openclaw/openclaw` — main repo (`AGENTS.md`, `skills/`)
|
|
201
|
-
- `https://github.com/openclaw/openclaw/tree/main/skills` — bundled skills
|
|
202
|
-
- `https://docs.openclaw.ai/tools/skills` — SKILL.md format + load-path precedence
|
|
203
|
-
- `https://docs.openclaw.ai/tools/skills-config` — `openclaw.json` skills config
|
|
204
|
-
- `https://docs.openclaw.ai/tools/plugin` — plugin overview + install CLI
|
|
205
|
-
- `https://docs.openclaw.ai/plugins/manifest` — `openclaw.plugin.json` schema
|
|
206
|
-
- `https://docs.openclaw.ai/plugins/plugin-inventory` — bundled plugin list
|
|
207
|
-
- `https://docs.openclaw.ai/plugins/hooks` — 28-hook SDK reference
|
|
208
|
-
- `https://docs.openclaw.ai/cli/skills` — `openclaw skills …` CLI surface
|
|
209
|
-
- `https://docs.openclaw.ai/clawhub/skill-format` — registry skill format
|
|
210
|
-
- `https://github.com/openclaw/clawhub` — registry
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// Canonical entity shapes. The daemon's DB schema (apps/daemon/src/core/db)
|
|
2
|
-
// produces these, the daemon serialises them onto the wire, every client
|
|
3
|
-
// (web, mobile, cli, future SDKs) consumes them. Owned here so clients never
|
|
4
|
-
// have to reach into daemon source (which carries node:sqlite) just to know
|
|
5
|
-
// what an Agent is.
|
|
6
|
-
|
|
7
|
-
export type Timestamp = number
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A group is a collaboration context: one filesystem root, one USER.md
|
|
11
|
-
* (read-only to agents, edited by the human), one roster of member agents.
|
|
12
|
-
* Every agent belongs to exactly one group.
|
|
13
|
-
*/
|
|
14
|
-
export interface Group {
|
|
15
|
-
id: string
|
|
16
|
-
name: string
|
|
17
|
-
path: string
|
|
18
|
-
/** Read-only context about the human for all agents in this group.
|
|
19
|
-
* Injected into the system prompt; never exposed as a file on disk. */
|
|
20
|
-
userMd: string
|
|
21
|
-
createdAt: Timestamp
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type SkillsMode = 'all' | 'selected'
|
|
25
|
-
|
|
26
|
-
export interface Profile {
|
|
27
|
-
id: string
|
|
28
|
-
name: string
|
|
29
|
-
dir: string
|
|
30
|
-
defaultModel: string
|
|
31
|
-
skillsMode: SkillsMode
|
|
32
|
-
createdAt: Timestamp
|
|
33
|
-
updatedAt: Timestamp
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export type AgentStatus = 'idle' | 'running' | 'archived'
|
|
37
|
-
|
|
38
|
-
export type ReasoningLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
|
|
39
|
-
|
|
40
|
-
export const REASONING_LEVELS: ReasoningLevel[] = [
|
|
41
|
-
'off',
|
|
42
|
-
'minimal',
|
|
43
|
-
'low',
|
|
44
|
-
'medium',
|
|
45
|
-
'high',
|
|
46
|
-
'xhigh',
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
export interface Agent {
|
|
50
|
-
id: string
|
|
51
|
-
profileId: string
|
|
52
|
-
name: string
|
|
53
|
-
modelOverride: string | null
|
|
54
|
-
reasoningLevel: ReasoningLevel
|
|
55
|
-
status: AgentStatus
|
|
56
|
-
dir: string
|
|
57
|
-
/** The group this agent belongs to. Every agent has exactly one. */
|
|
58
|
-
groupId: string
|
|
59
|
-
createdAt: Timestamp
|
|
60
|
-
archivedAt: Timestamp | null
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface AgentSkillAttachment {
|
|
64
|
-
agentId: string
|
|
65
|
-
skillName: string
|
|
66
|
-
attachedAt: Timestamp
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface SkillMeta {
|
|
70
|
-
name: string
|
|
71
|
-
source: string | null
|
|
72
|
-
importedAt: Timestamp | null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface Message {
|
|
76
|
-
id: string
|
|
77
|
-
fromAgentId: string
|
|
78
|
-
toAgentId: string
|
|
79
|
-
replyTo: string | null
|
|
80
|
-
payload: string
|
|
81
|
-
createdAt: Timestamp
|
|
82
|
-
readAt: Timestamp | null
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface WebToken {
|
|
86
|
-
id: string
|
|
87
|
-
label: string
|
|
88
|
-
createdAt: Timestamp
|
|
89
|
-
lastUsedAt: Timestamp | null
|
|
90
|
-
revokedAt: Timestamp | null
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export type TriggerKind = 'interval' | 'cron'
|
|
94
|
-
|
|
95
|
-
export interface AgentTrigger {
|
|
96
|
-
id: string
|
|
97
|
-
agentId: string
|
|
98
|
-
kind: TriggerKind
|
|
99
|
-
intervalSec: number | null
|
|
100
|
-
cronExpr: string | null
|
|
101
|
-
message: string
|
|
102
|
-
enabled: boolean
|
|
103
|
-
lastFiredAt: Timestamp | null
|
|
104
|
-
createdAt: Timestamp
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export interface OpenAICodexStatus {
|
|
108
|
-
connected: boolean
|
|
109
|
-
/** Unix ms expiry of the current access token; null if disconnected. */
|
|
110
|
-
expiresAt: number | null
|
|
111
|
-
/** chatgpt_account_id extracted from the JWT, when available. */
|
|
112
|
-
accountId: string | null
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface AgentIdentityFile {
|
|
116
|
-
name?: string
|
|
117
|
-
emoji?: string
|
|
118
|
-
theme?: string
|
|
119
|
-
creature?: string
|
|
120
|
-
vibe?: string
|
|
121
|
-
avatar?: string
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface ResolvedAgent {
|
|
125
|
-
agent: Agent
|
|
126
|
-
profile: Profile
|
|
127
|
-
model: string
|
|
128
|
-
reasoningLevel: ReasoningLevel
|
|
129
|
-
group: Group
|
|
130
|
-
skills: string[]
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface LoadedProfile {
|
|
134
|
-
profile: Profile
|
|
135
|
-
defaultSkills: string[]
|
|
136
|
-
files: {
|
|
137
|
-
soul: string
|
|
138
|
-
identity: string
|
|
139
|
-
bootstrap: string | null
|
|
140
|
-
agents: string | null
|
|
141
|
-
tools: string | null
|
|
142
|
-
heartbeat: string | null
|
|
143
|
-
}
|
|
144
|
-
/** Structured fields parsed from IDENTITY.md — null when no values are set. */
|
|
145
|
-
identity: AgentIdentityFile | null
|
|
146
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Wire shapes for chat streaming and provider message exchange. The worker
|
|
2
|
-
// emits `ChatFrame`s as NDJSON, the daemon forwards them verbatim, every UI
|
|
3
|
-
// renders the contained `SessionEvent`s. `ProviderMessage` is the shape both
|
|
4
|
-
// the worker (in `done` frames) and clients (when displaying history) speak.
|
|
5
|
-
|
|
6
|
-
export type Role = 'system' | 'user' | 'assistant' | 'tool'
|
|
7
|
-
|
|
8
|
-
export interface ToolCall {
|
|
9
|
-
id: string
|
|
10
|
-
name: string
|
|
11
|
-
/** JSON-serialized arguments object */
|
|
12
|
-
arguments: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ProviderMessage {
|
|
16
|
-
role: Role
|
|
17
|
-
content: string
|
|
18
|
-
toolCalls?: ToolCall[]
|
|
19
|
-
/** for role='tool': links the result back to the originating call */
|
|
20
|
-
toolCallId?: string
|
|
21
|
-
/** for role='tool': name of the tool that produced this result. Pi requires it on ToolResultMessage. */
|
|
22
|
-
toolName?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface ToolDef {
|
|
26
|
-
name: string
|
|
27
|
-
description: string
|
|
28
|
-
/** JSON Schema for the tool's arguments object */
|
|
29
|
-
parameters: object
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type SessionEvent =
|
|
33
|
-
| { type: 'user_message'; text: string }
|
|
34
|
-
| { type: 'assistant_delta'; delta: string }
|
|
35
|
-
| { type: 'assistant_message'; text: string }
|
|
36
|
-
| { type: 'tool_call'; id: string; name: string; arguments: string }
|
|
37
|
-
| { type: 'tool_result'; id: string; name: string; result: string }
|
|
38
|
-
| { type: 'tool_error'; id: string; name: string; error: string }
|
|
39
|
-
| { type: 'error'; error: string }
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* The wire envelope the worker emits on stdout (NDJSON, one per line) and
|
|
43
|
-
* the chat HTTP endpoint forwards verbatim to clients.
|
|
44
|
-
*
|
|
45
|
-
* - `event`: one per SessionEvent emitted during the turn
|
|
46
|
-
* - `done`: sent exactly once at the end of a successful turn with the
|
|
47
|
-
* final message list
|
|
48
|
-
* - `fatal`: sent at most once when the worker itself fails before/after
|
|
49
|
-
* the turn can run — distinct from an `error` SessionEvent which
|
|
50
|
-
* lives within a completed turn
|
|
51
|
-
*/
|
|
52
|
-
export type ChatFrame =
|
|
53
|
-
| { kind: 'event'; event: SessionEvent }
|
|
54
|
-
| { kind: 'done'; messages: ProviderMessage[] }
|
|
55
|
-
| { kind: 'fatal'; error: string }
|