Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
7fab532
feat(client): add TypeScript SDK
buremba May 21, 2026
065e723
feat(connector-sdk): add defineConnector functional authoring API
buremba May 21, 2026
9f2155a
feat(connector-sdk): support optional authenticate flow in defineConn…
buremba May 21, 2026
a0bd4a8
feat(sdk): add @lobu/sdk authoring package (define* + secret)
buremba May 21, 2026
9a7aef4
feat(cli): map @lobu/sdk authoring project to DesiredState
buremba May 21, 2026
15b7f81
feat(cli): load DesiredState from a lobu.config.ts entrypoint
buremba May 21, 2026
e3e909e
feat(cli): apply prefers lobu.config.ts over lobu.toml
buremba May 21, 2026
530cb0c
fix(sdk,cli): address codex + pi review of the TS authoring path
buremba May 21, 2026
ecf4f34
fix(cli): enforce 1-minute minimum cron interval in TS config (TOML p…
buremba May 21, 2026
99b2315
feat(cli): ship local connectors/*.connector.ts source from lobu.conf…
buremba May 21, 2026
edf0e26
feat(sdk,cli): express full agent settings + org metadata in the TS c…
buremba May 21, 2026
f17c688
feat(cli): load agent-dir markdown + skills in the TS config path
buremba May 21, 2026
93f8895
feat(sdk,cli): map watcher reactionsGuidance + agentKind
buremba May 21, 2026
dc15904
fix(sdk): drop unwired Agent.connections + Agent.schema (pi review)
buremba May 21, 2026
2236e5a
chore(client): move @hey-api/client-fetch to devDependencies (pi review)
buremba May 21, 2026
1b52cc6
feat(sdk,cli): watcher reaction scripts in the TS config path
buremba May 21, 2026
41bb046
fix(cli): resolve non-interactive auth-profile credentials to env values
buremba May 22, 2026
9d866be
feat(examples): author all 12 examples in lobu.config.ts (@lobu/sdk)
buremba May 22, 2026
2d80189
refactor(cli): migrate every command off the TOML loader to lobu.conf…
buremba May 22, 2026
9d2daa2
refactor(cli): seed memory from lobu.config.ts instead of lobu.toml +…
buremba May 22, 2026
00419ef
refactor: delete the dead TOML/YAML config path
buremba May 22, 2026
a907d2e
docs(cli): refresh DesiredState comments for the lobu.config.ts world
buremba May 22, 2026
37a99ea
refactor(landing): source landing snippets from lobu.config.ts
buremba May 22, 2026
7517665
refactor(cli): load lobu.config.ts with jiti (the Next.js way)
buremba May 22, 2026
a383b61
feat(cli): migrate producers to lobu.config.ts (init, agent add, root…
buremba May 22, 2026
81e30e8
feat(cli): lobu init --from-org bootstraps a project from cloud; remo…
buremba May 22, 2026
e7ece65
chore(cli): remove dead YAML-model code + de-toml stale comments/strings
buremba May 22, 2026
a7a913c
fix(cli): scaffold @lobu/sdk + type-check lobu.config.ts (pi-review b…
buremba May 22, 2026
6727a4b
feat(cli): code-managed prune — apply deletes definitions removed fro…
buremba May 22, 2026
5b38aa7
feat(server): organization.managed_by + managed-by endpoint for code-…
buremba May 22, 2026
0733142
docs: migrate all user-facing docs from lobu.toml/YAML to lobu.config…
buremba May 22, 2026
5f98426
chore: remove remaining lobu.toml references repo-wide
buremba May 22, 2026
c751a9b
chore: drop dead smol-toml direct dependency
buremba May 22, 2026
470fd53
fix(apply): defer code-managed flip until after plan confirmation; st…
buremba May 22, 2026
a29fb34
fix(prune): harden code-managed prune (multi-angle pi review findings)
buremba May 22, 2026
e686960
fix(cli): persist entity-type properties via metadata_schema (idempot…
buremba May 22, 2026
92399f9
test(cli): init-from-org mock returns server's metadata_schema shape
buremba May 22, 2026
b397fb2
fix(prune): never prune public entity/relationship types owned by ano…
buremba May 22, 2026
203cbdc
fix(prune): match entity/relationship types against the org's own def…
buremba May 22, 2026
e455490
fix(server): org-scope relationship-type write resolution + create dedup
buremba May 22, 2026
a010c1c
fix: init-from-org auth-profile safety + complete rel-type inverse or…
buremba May 22, 2026
7b5603f
feat(sdk): restore config-authored chat platforms (defineAgent platfo…
buremba May 22, 2026
42dce0a
fix(cli): platform config diff ignores redacted/secret-ref values (id…
buremba May 22, 2026
e7ebff9
test(cli): platform config diff treats redacted/secret-ref values as …
buremba May 22, 2026
647790f
fix(cli): init-from-org emits secret() for redacted platform config v…
buremba May 22, 2026
cd6e6df
style(cli): biome formatting for platform diff tests
buremba May 22, 2026
1090ce0
fix(platforms): store the resolved secret value, not the $VAR placeho…
buremba May 22, 2026
6f98f4b
docs(cli): correct generateLobuConfig comment — platforms ARE config-…
buremba May 22, 2026
f6eb2b6
fix(cli): init-from-org emits real auth-schema credential keys
buremba May 22, 2026
76d560f
fix(server): manage_feeds delete proves feed ownership before cancell…
buremba May 22, 2026
0b9d625
docs(server): explain the space delimiter in sync-channels composite key
buremba May 22, 2026
cc1fbf5
fix(client): SSE stream rejects on non-OK/aborted instead of hanging
buremba May 22, 2026
c0bb701
feat(apply): config-declared prune, replacing org managed_by flag
buremba May 22, 2026
c680592
Merge remote-tracking branch 'origin/main' into feat/client-sdk
buremba May 22, 2026
bb48e49
fix(ci): build @lobu/sdk + @lobu/client before downstream typecheck/unit
buremba May 22, 2026
67a0e19
fix(cli): commit warnings field in loadDesiredStateFromConfig return
buremba May 22, 2026
05571f9
fix(apply,init,schema): close 6 review blockers in the TS-SDK apply/i…
buremba May 22, 2026
bcde255
fix(apply): make re-apply converge to noop (idempotency)
buremba May 22, 2026
a5dc5ff
fix(apply,schema): second-round review fixes (tenant isolation + decl…
buremba May 22, 2026
2033dc3
fix(init,apply): sanitize derived secret env-var names + drop stray N…
buremba May 22, 2026
4d68e26
fix(apply): never prune system ($-prefixed) definitions like $member
buremba May 22, 2026
d7d1558
test(e2e): add SDK lifecycle e2e gate (apply + prune + real worker turn)
buremba May 22, 2026
13426a1
ci(sdk-e2e): install libicu60 so embedded-postgres initdb can load
buremba May 22, 2026
bf9dc07
ci(sdk-e2e): disable systemd-run + install bubblewrap so the worker s…
buremba May 22, 2026
5df871b
style(init-from-org): use optional chain for platform name recovery
buremba May 22, 2026
6d6c399
test(sdk-e2e): self-contained embedded-PG ICU + connector-sync & watc…
buremba May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ WORKER_DISALLOWED_DOMAINS=
PUBLIC_GATEWAY_URL=https://app.lobu.ai

# Optional Lobu base MCP URL override.
# File-first projects can enable Lobu with [memory] in lobu.toml;
# File-first projects can enable Lobu with [memory] in lobu.config.ts;
# when set, Lobu scopes this base URL to the org declared there.
MEMORY_URL=https://lobu.com/mcp

Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
run: |
cd packages/core && bun run build && cd ../..
cd packages/connector-sdk && bun run build && cd ../..
cd packages/sdk && bun run build && cd ../..
cd packages/embeddings && bun run build && cd ../..
cd packages/connector-worker && bun run build && cd ../..

Expand Down Expand Up @@ -100,6 +101,61 @@
files: coverage/lcov.info
fail_ci_if_error: false

# SDK lifecycle e2e — the hard gate that the WHOLE TypeScript-SDK path runs,
# not just that config maps (unit/integration cover that). Boots `lobu run`
# (embedded Postgres — the linux binary ships as an @embedded-postgres
# optional dep, the same engine prod uses), auto-applies a prune:true fixture,
# and drives a real agent turn through a spawned worker against a deterministic
# mock OpenAI-compatible provider (no provider key needed). A failure here
# fails CI → the PR goes red. See scripts/sdk-e2e.sh.
sdk-e2e:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/setup-submodule
with:
deploy-key: ${{ secrets.OWLETTO_WEB_DEPLOY_KEY }}

- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.5

# Node 22 — the worker uses isolated-vm (abi127 prebuild); the runner's
# default Node major would segfault the sandbox runtime.
- uses: actions/setup-node@v4
with:
node-version: "22"

- name: Install dependencies
run: bun install

# The worker's exec-sandbox uses bwrap on Linux; ubuntu-latest blocks
# unprivileged user namespaces via AppArmor, so flip the sysctl too.
- name: Install bubblewrap (worker exec-sandbox)
run: |
sudo apt-get update
sudo apt-get install -y bubblewrap coreutils
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
bwrap --version

# NOTE: `lobu run`'s embedded Postgres (PG18) is NEEDED-linked against
# ICU 60, which ubuntu-latest no longer carries. We do NOT install a
# system libicu60 (the old archive .deb was fragile and didn't help local
# Linux devs) — instead scripts/sdk-e2e.sh runs
# scripts/sdk-e2e/fix-embedded-pg-icu.mjs, which creates the missing
# `.so.60` SONAME symlinks in the embedded-postgres native/lib dir (it
# already ships libicu*.so.60.2). The binaries' `$ORIGIN/../lib` rpath then
# resolves their bundled ICU with zero system deps. Prod is unaffected
# (external Postgres; embedded-postgres pruned from the app image).

- name: Build all packages (CLI + server bundle + sdk + pgvector-embedded)
run: make build-packages

- name: SDK lifecycle e2e (apply + prune + real worker turn)
run: bash scripts/sdk-e2e.sh

# Frontend tests run under jsdom via vitest. owletto is a submodule;
# forks without the deploy key get a stub package and skip these.
frontend:
Expand Down Expand Up @@ -187,29 +243,29 @@
- uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install dependencies
run: bun install

- name: Build packages server depends on
# embeddings → connector-worker order matters: connector-worker's
# src/embeddings.ts imports `@lobu/embeddings` and resolves it via
# the workspace symlink → dist. connector-worker itself is required
# because `packages/server/src/utils/connector-catalog.ts` imports
# `@lobu/connector-worker/compile` (the shared compile pipeline),
# which resolves via the package's `exports` field to
# `./dist/compile/index.js`. Vitest's vite-node resolver follows
# the `import` condition and fails to load if dist is absent —
# which transitively breaks every integration file whose import
# graph touches `queue-helpers` / `worker-api` / `connector-catalog`.
#
# pgvector-embedded must build too: the test backend
# (src/__tests__/setup/embedded-postgres-backend.ts) imports
# `@lobu/pgvector-embedded`, so vite resolves its `import` condition
# (./dist/index.js) at transform time even though the embedded backend
# is never started when DATABASE_URL points at the external Postgres.
run: |
cd packages/core && bun run build && cd ../..

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
cd packages/connector-sdk && bun run build && cd ../..
cd packages/embeddings && bun run build && cd ../..
cd packages/connector-worker && bun run build && cd ../..
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,4 @@ packages/*/~/

# Embedded PGlite dev data (make dev without DATABASE_URL)
.lobu-dev/
.sdk-e2e-run/
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
- **MCP:** providers from `config/providers.json`; MCP servers from per-agent settings or `SKILL.md`. Workers discover MCP tools at startup and call them via the gateway proxy (JWT). Built-ins: `AskUser`, `UploadFile`. Integration auth (OAuth/refresh) lives in Lobu MCP servers — workers never see tokens.
- **`events` is append-only.** Never `DELETE FROM events`; tombstone via `client.knowledge.delete()` / `save_knowledge({ supersedes_event_id, ... })`. `current_event_records` masks superseded rows.
- **Connectors:** `*.connector.ts` extending `ConnectorRuntime`. npm deps → project `package.json`, bundled by esbuild at compile time; native deps → `runtime.nix.packages` (nixpkgs refs), provisioned via `nix-shell` at run. Compile happens on the CLI (`lobu apply` → `bun install --ignore-scripts`); `@lobu/connector-sdk` is externalized (runtime-provided).
- **Guardrails** (`packages/core/src/guardrails/`): stages `input`/`output`/`pre-tool`; built-ins `secret-scan`, `pii-scan`, `forbidden-tools` (see `gateway/guardrails/builtins.ts` + `aggregator.ts`). Configure in `[agents.<id>].guardrails` (lobu.toml); all fail open on infra errors; each trip writes a `guardrail-trip` event.
- **Guardrails** (`packages/core/src/guardrails/`): stages `input`/`output`/`pre-tool`; built-ins `secret-scan`, `pii-scan`, `forbidden-tools` (see `gateway/guardrails/builtins.ts` + `aggregator.ts`). Configure via `defineAgent({ guardrails: [...] })` in `lobu.config.ts`; all fail open on infra errors; each trip writes a `guardrail-trip` event.
- **Network/egress:** worker subprocesses get `HTTP_PROXY=http://localhost:8118`. Access via `WORKER_ALLOWED_DOMAINS`: empty=no net (default), `github.com`=allowlist, `*`=all (not prod), `*`+`WORKER_DISALLOWED_DOMAINS`=blocklist; domains exact or `.wildcard`. Linux prod adds kernel `IPAddressDeny=any` + allow 127.0.0.1. Risky domains can route through an LLM egress judge (Haiku, 5-min cache, fail-closed; needs `ANTHROPIC_API_KEY`; `gateway/proxy/http-proxy.ts`).

## Releasing
Expand All @@ -38,4 +38,4 @@ release-please owns it: land conventional commits on `main`, merge the generated
- **E2E before merge (hard gate)** for bug fixes: red→fix→green reproducer in the PR body; if you can't reproduce, BAIL (post the dead-end, don't open a PR). Native-app UI exempt (compile-check + draft, say so).
- Bot behavior → `./scripts/test-bot.sh "@me ..."` (dev `@clawdotfreebot`, prod `@lobuaibot`; clear stale history via `chat_state_lists`). Prompt/behavior → promptfoo (`bun run evals`). Auth'd UI → `docs/BROWSER_TESTING.md`.
- **Owletto e2e (Chrome/Mac):** Chrome → `make e2e-browser` launches/reuses the stable `owletto` agent-browser harness (persistent `~/.config/lobu-dev/chrome` profile + `--extension` from this worktree); drive it with `agent-browser --session owletto <cmd>`, `RESTART=1` to pick up extension/worktree changes. The extension's fixed manifest `key` pins its ID, so chrome.storage.local (gateway URL + auth) persists — pair once, reuse across sessions/worktrees, like the installed Mac app. Mac → use the installed `Owletto.app`; it reads `~/.config/lobu/config.json` each popover so task-setup-registered worktree contexts appear in its picker. Don't reintroduce a per-worktree extension symlink.
- `.env` is the single source of truth for secrets (restart `make dev` after changes). Worker sessions persist via `./workspaces/{agentId}/`. Skills declare network/nix needs that merge into the allowlist — review skills before installing; destructive MCP calls need in-thread approval unless pre-approved in `lobu.toml`.
- `.env` is the single source of truth for secrets (restart `make dev` after changes). Worker sessions persist via `./workspaces/{agentId}/`. Skills declare network/nix needs that merge into the allowlist — review skills before installing; destructive MCP calls need in-thread approval unless pre-approved in `lobu.config.ts`.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Development Makefile for Lobu

.PHONY: help setup build test clean dev build-packages ensure-submodule clean-workers test-unit test-integration test-e2e typecheck task-setup task-clean e2e-browser bump review
.PHONY: help setup build test clean dev build-packages ensure-submodule clean-workers test-unit test-integration test-e2e test-e2e-sdk typecheck task-setup task-clean e2e-browser bump review

# Default target
help:
Expand Down Expand Up @@ -34,7 +34,7 @@ typecheck:
# Build all TypeScript packages in dependency order
build-packages:
@echo "📦 Building all TypeScript packages..."
@for pkg in core pgvector-embedded connector-sdk agent-worker openclaw-plugin embeddings connector-worker promptfoo-provider; do \
@for pkg in core pgvector-embedded connector-sdk client sdk agent-worker openclaw-plugin embeddings connector-worker promptfoo-provider; do \
echo " 📦 Building packages/$$pkg..."; \
( cd packages/$$pkg && bun run build ) || exit $$?; \
done
Expand Down Expand Up @@ -141,6 +141,13 @@ test-e2e:
@: $${DATABASE_URL?Set DATABASE_URL=postgres://… (with pgvector) before running}
@./scripts/run-e2e.sh

# SDK lifecycle e2e: boots `lobu run` (embedded Postgres), auto-applies a
# prune:true fixture, and drives a real agent turn through a spawned worker
# against a deterministic mock provider (no key needed). Self-contained. This is
# the CI `sdk-e2e` gate; run it locally the same way.
test-e2e-sdk:
@./scripts/sdk-e2e.sh

# Stop any embedded worker subprocesses left over from a crashed gateway.
# Workers are normally cleaned up when the gateway exits; this target is a
# safety net for orphaned bun processes spawned by EmbeddedDeploymentManager.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ npx @lobu/cli@latest run # boots the stack and applies your
npx @lobu/cli@latest chat -c local "hello" # talk to it
```

`lobu run` (embedded) auto-applies your `lobu.toml`, so the scaffolded agent is usable immediately. To use an external Postgres, set `DATABASE_URL` in `.env`; to push later config changes, run `lobu apply`.
`lobu run` (embedded) auto-applies your `lobu.config.ts`, so the scaffolded agent is usable immediately. To use an external Postgres, set `DATABASE_URL` in `.env`; to push later config changes, run `lobu apply`.

## Agent configuration

Expand All @@ -42,7 +42,7 @@ npx @lobu/cli@latest org set my-org
npx @lobu/cli@latest agent list
```

Local `lobu.toml` projects are still useful for `lobu validate` and `lobu apply` workflows.
Local `lobu.config.ts` projects are still useful for `lobu validate` and `lobu apply` workflows.

### Deployment

Expand Down Expand Up @@ -94,7 +94,7 @@ Every Lobu agent ships with tools for autonomous execution and persistence:
| **Full Linux toolbox** — sandboxed shell, file edit, search | `bash`, `read`, `write`, `edit`, `grep`, `find`, `ls` |
| **Conversation context** — pull earlier thread messages | `GetChannelHistory` |
| **File & media delivery** — share reports, charts, audio | `UploadUserFile`, `GenerateAudio` |
| **Skills** — extend via `lobu.toml` or admin settings | `lobu.toml`, Settings UI |
| **Skills** — extend via `lobu.config.ts` or admin settings | `lobu.config.ts`, Settings UI |
| **Connected APIs** — GitHub, Google, etc. with Lobu-managed OAuth | MCP tools via Lobu |
| **Managed MCP proxy** — any MCP server with secret injection | [MCP Proxy](docs/SECURITY.md#credentials) |
| **Nix + external MCP** — browsing, headless UI, custom tools | `bash` (Nix), MCP servers |
Expand Down
Loading
Loading