diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2137321cd..304c2691f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,6 @@ jobs: 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 ../.. diff --git a/Makefile b/Makefile index ac07dc36c..9ef8e4959 100644 --- a/Makefile +++ b/Makefile @@ -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 client sdk agent-worker openclaw-plugin embeddings connector-worker promptfoo-provider; do \ + @for pkg in core pgvector-embedded connector-sdk client agent-worker openclaw-plugin embeddings connector-worker promptfoo-provider; do \ echo " 📦 Building packages/$$pkg..."; \ ( cd packages/$$pkg && bun run build ) || exit $$?; \ done diff --git a/bun.lock b/bun.lock index c0989a94b..7a45939be 100644 --- a/bun.lock +++ b/bun.lock @@ -16,7 +16,7 @@ }, "packages/agent-worker": { "name": "@lobu/worker", - "version": "9.1.1", + "version": "9.2.0", "bin": { "lobu-worker": "./dist/index.js", }, @@ -43,7 +43,7 @@ }, "packages/cli": { "name": "@lobu/cli", - "version": "9.1.1", + "version": "9.2.0", "bin": { "lobu": "bin/lobu.js", }, @@ -66,7 +66,6 @@ "@lobu/connector-worker": "workspace:*", "@lobu/core": "workspace:*", "@lobu/embeddings": "workspace:*", - "@lobu/sdk": "workspace:*", "@lobu/worker": "workspace:*", "@mariozechner/pi-ai": "^0.51.6", "@modelcontextprotocol/sdk": "^1.27.1", @@ -129,7 +128,7 @@ }, "packages/client": { "name": "@lobu/client", - "version": "9.1.1", + "version": "9.2.0", "devDependencies": { "@hey-api/client-fetch": "^0.13.1", "@hey-api/openapi-ts": "^0.86.5", @@ -138,7 +137,7 @@ }, "packages/connector-sdk": { "name": "@lobu/connector-sdk", - "version": "9.1.1", + "version": "9.2.0", "dependencies": { "@lobu/core": "workspace:*", "@sinclair/typebox": "^0.34.41", @@ -162,7 +161,7 @@ }, "packages/connector-worker": { "name": "@lobu/connector-worker", - "version": "9.1.1", + "version": "9.2.0", "bin": { "connector-worker": "./dist/bin.js", }, @@ -185,7 +184,7 @@ }, "packages/connectors": { "name": "@lobu/connectors", - "version": "9.1.1", + "version": "9.2.0", "dependencies": { "@lobu/connector-sdk": "workspace:*", "baileys": "7.0.0-rc.9", @@ -199,7 +198,7 @@ }, "packages/core": { "name": "@lobu/core", - "version": "9.1.1", + "version": "9.2.0", "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0", @@ -218,7 +217,7 @@ }, "packages/embeddings": { "name": "@lobu/embeddings", - "version": "9.1.1", + "version": "9.2.0", "dependencies": { "@hono/node-server": "^1.13.7", "@xenova/transformers": "^2.17.2", @@ -250,7 +249,7 @@ }, "packages/openclaw-plugin": { "name": "@lobu/openclaw-plugin", - "version": "9.1.1", + "version": "9.2.0", "dependencies": { "@lobu/core": "workspace:*", }, @@ -335,7 +334,7 @@ }, "packages/pgvector-embedded": { "name": "@lobu/pgvector-embedded", - "version": "9.1.1", + "version": "9.2.0", "devDependencies": { "@types/node": "20.19.9", "typescript": "^5.7.2", @@ -343,19 +342,7 @@ }, "packages/promptfoo-provider": { "name": "@lobu/promptfoo-provider", - "version": "9.1.1", - "devDependencies": { - "@types/node": "^20.10.0", - "typescript": "^5.3.3", - }, - }, - "packages/sdk": { - "name": "@lobu/sdk", - "version": "9.1.1", - "dependencies": { - "@lobu/connector-sdk": "workspace:*", - "@sinclair/typebox": "^0.34.41", - }, + "version": "9.2.0", "devDependencies": { "@types/node": "^20.10.0", "typescript": "^5.3.3", @@ -1119,8 +1106,6 @@ "@lobu/promptfoo-provider": ["@lobu/promptfoo-provider@workspace:packages/promptfoo-provider"], - "@lobu/sdk": ["@lobu/sdk@workspace:packages/sdk"], - "@lobu/server": ["@lobu/server@workspace:packages/server"], "@lobu/worker": ["@lobu/worker@workspace:packages/agent-worker"], diff --git a/codex-skills/lobu-builder/SKILL.md b/codex-skills/lobu-builder/SKILL.md index 6172526e9..33b4602cc 100644 --- a/codex-skills/lobu-builder/SKILL.md +++ b/codex-skills/lobu-builder/SKILL.md @@ -14,7 +14,7 @@ If you are inside the Lobu monorepo rather than a generated Lobu project, follow ## First Pass 1. Read `AGENTS.md` first. If it redirects to another file such as `@TESTING.md`, open that too. -2. Read `lobu.config.ts`. It is TypeScript: `defineConfig` from `@lobu/sdk` is the default export. +2. Read `lobu.config.ts`. It is TypeScript: `defineConfig` from `@lobu/cli/config` is the default export. 3. Enumerate agent directories under `agents/` and inspect the target agent's `IDENTITY.md`, `SOUL.md`, and `USER.md`. 4. Check whether the repo has shared `skills/` or agent-local `agents//skills/`. 5. Look for evals under `agents//evals/promptfooconfig.yaml` (the project may also have legacy YAML files — those don't run). @@ -26,7 +26,7 @@ Do not assume there is only one agent or one platform connection. - `IDENTITY.md`: who the agent is - `SOUL.md`: rules, workflows, guardrails - `USER.md`: user or tenant context -- `lobu.config.ts`: providers, connections, enabled skills, MCP servers, network allowlist (authored with `define*` from `@lobu/sdk`) +- `lobu.config.ts`: providers, connections, enabled skills, MCP servers, network allowlist (authored with `define*` from `@lobu/cli/config`) - `skills/.../SKILL.md`: shared reusable capabilities - `agents//skills/.../SKILL.md`: agent-specific capabilities - `agents//evals/promptfooconfig.yaml`: promptfoo eval suite (runs via `bunx promptfoo eval` with `@lobu/promptfoo-provider`) diff --git a/examples/agent-community/lobu.config.ts b/examples/agent-community/lobu.config.ts index 585e10241..133535768 100644 --- a/examples/agent-community/lobu.config.ts +++ b/examples/agent-community/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const agentCommunity = defineAgent({ id: "agent-community", diff --git a/examples/atlas/lobu.config.ts b/examples/atlas/lobu.config.ts index 47a9d2dda..d2afb03d5 100644 --- a/examples/atlas/lobu.config.ts +++ b/examples/atlas/lobu.config.ts @@ -4,7 +4,7 @@ import { defineEntityType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const atlasCurator = defineAgent({ id: "atlas-curator", diff --git a/examples/delivery/lobu.config.ts b/examples/delivery/lobu.config.ts index 8a9e488c5..5c3b9f942 100644 --- a/examples/delivery/lobu.config.ts +++ b/examples/delivery/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const delivery = defineAgent({ id: "delivery", diff --git a/examples/ecommerce/lobu.config.ts b/examples/ecommerce/lobu.config.ts index 114470922..4f66e55bc 100644 --- a/examples/ecommerce/lobu.config.ts +++ b/examples/ecommerce/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const ecommerceOps = defineAgent({ id: "ecommerce-ops", diff --git a/examples/finance/lobu.config.ts b/examples/finance/lobu.config.ts index 1d026ff6c..3278f4956 100644 --- a/examples/finance/lobu.config.ts +++ b/examples/finance/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const finance = defineAgent({ id: "finance", diff --git a/examples/leadership/lobu.config.ts b/examples/leadership/lobu.config.ts index ff026b65b..fa277dfb2 100644 --- a/examples/leadership/lobu.config.ts +++ b/examples/leadership/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const leadership = defineAgent({ id: "leadership", diff --git a/examples/legal/lobu.config.ts b/examples/legal/lobu.config.ts index 0733f17b1..e3c2ed685 100644 --- a/examples/legal/lobu.config.ts +++ b/examples/legal/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const legalReview = defineAgent({ id: "legal-review", diff --git a/examples/lobu-crm/lobu.config.ts b/examples/lobu-crm/lobu.config.ts index 90ae49c73..ed489b33e 100644 --- a/examples/lobu-crm/lobu.config.ts +++ b/examples/lobu-crm/lobu.config.ts @@ -7,7 +7,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const crm = defineAgent({ id: "crm", diff --git a/examples/market/lobu.config.ts b/examples/market/lobu.config.ts index 9a6603145..6f491f66e 100644 --- a/examples/market/lobu.config.ts +++ b/examples/market/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const SECTOR_ENUM = ["bio-health", "ai", "fintech", "crypto", "consumer"]; diff --git a/examples/office-bot/lobu.config.ts b/examples/office-bot/lobu.config.ts index a5b73f60d..bc5334525 100644 --- a/examples/office-bot/lobu.config.ts +++ b/examples/office-bot/lobu.config.ts @@ -4,7 +4,7 @@ import { defineEntityType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const DELIVEROO_JUDGE = "Allow GET requests that read restaurant listings, menus, item details, and the\ncurrent basket. Allow POST/PUT requests whose effect is limited to building or\nmodifying a basket / group order (adding, removing, changing quantity of items;\ncreating a shareable group-order link). DENY anything that completes checkout,\nsubmits payment, reads or writes saved payment methods, changes the delivery\naddress, or modifies the account profile. If the request's effect is unclear,\nfail closed and deny with a reason.\n"; diff --git a/examples/personal-finance/lobu.config.ts b/examples/personal-finance/lobu.config.ts index b1e9cd0ad..46f6ff4c7 100644 --- a/examples/personal-finance/lobu.config.ts +++ b/examples/personal-finance/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const personal_finance = defineAgent({ id: "personal-finance", diff --git a/examples/sales/lobu.config.ts b/examples/sales/lobu.config.ts index 30abbcff0..24c96552e 100644 --- a/examples/sales/lobu.config.ts +++ b/examples/sales/lobu.config.ts @@ -5,7 +5,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const sales = defineAgent({ id: "sales", diff --git a/package.json b/package.json index d59517225..196455a83 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,11 @@ "check": "biome check --config-path config/biome.config.json .", "check:fix": "biome check --config-path config/biome.config.json --write .", "prepare": "husky || true", - "test": "bun test packages/core/src packages/client/src packages/sdk/src packages/agent-worker/src packages/landing/src", - "test:coverage": "bun test packages/core/src packages/client/src packages/sdk/src packages/agent-worker/src packages/landing/src --coverage", + "test": "bun test packages/core/src packages/client/src packages/agent-worker/src packages/landing/src", + "test:coverage": "bun test packages/core/src packages/client/src packages/agent-worker/src packages/landing/src --coverage", "typecheck": "tsc --noEmit", "dev": "./scripts/dev-native.sh", - "build:packages": "cd packages/core && bun run build && cd ../pgvector-embedded && bun run build && cd ../connector-sdk && bun run build && cd ../client && bun run build && cd ../sdk && bun run build && cd ../agent-worker && bun run build && cd ../openclaw-plugin && bun run build && cd ../embeddings && bun run build && cd ../connector-worker && bun run build && cd ../promptfoo-provider && bun run build && cd ../server && bun run build:server && cd .. && if [ -f owletto/package.json ]; then (cd owletto && bun run build); else echo '[build:packages] owletto submodule absent — CLI ships headless (API only)'; fi && cd cli && bun run build", + "build:packages": "cd packages/core && bun run build && cd ../pgvector-embedded && bun run build && cd ../connector-sdk && bun run build && cd ../client && bun run build && cd ../agent-worker && bun run build && cd ../openclaw-plugin && bun run build && cd ../embeddings && bun run build && cd ../connector-worker && bun run build && cd ../promptfoo-provider && bun run build && cd ../server && bun run build:server && cd .. && if [ -f owletto/package.json ]; then (cd owletto && bun run build); else echo '[build:packages] owletto submodule absent — CLI ships headless (API only)'; fi && cd cli && bun run build", "build:lobu": "cd packages/embeddings && bun run build && cd ../..", "watch:packages": "tsc -b --watch packages/core packages/agent-worker", "test:packages": "cd packages/core && bun run test && cd ../agent-worker && bun run test", diff --git a/packages/cli/package.json b/packages/cli/package.json index 8fb5dd82f..07f7688b0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -4,6 +4,18 @@ "description": "CLI for deploying and managing AI agents on Lobu", "type": "module", "main": "dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./config": { + "types": "./dist/config/index.d.ts", + "bun": "./src/config/index.ts", + "import": "./dist/config/index.js" + }, + "./package.json": "./package.json" + }, "bin": { "lobu": "bin/lobu.js" }, @@ -43,7 +55,6 @@ "@lobu/connector-worker": "workspace:*", "@lobu/core": "workspace:*", "@lobu/embeddings": "workspace:*", - "@lobu/sdk": "workspace:*", "@lobu/worker": "workspace:*", "@mariozechner/pi-ai": "^0.51.6", "@modelcontextprotocol/sdk": "^1.27.1", @@ -104,7 +115,8 @@ "files": [ "dist", "bin", - "README.md" + "README.md", + "src/config" ], "engines": { "node": ">=22 <25" diff --git a/packages/cli/src/__tests__/cli-ux.test.ts b/packages/cli/src/__tests__/cli-ux.test.ts index 14dc81677..223f9005d 100644 --- a/packages/cli/src/__tests__/cli-ux.test.ts +++ b/packages/cli/src/__tests__/cli-ux.test.ts @@ -97,11 +97,11 @@ describe("lobu init --yes", () => { ); const env = readFileSync(join(proj, ".env"), "utf-8"); expect(env.includes("SENTRY_DSN=")).toBe(false); - // The generated lobu.config.ts imports @lobu/sdk, so the scaffolded - // package.json MUST declare it — else `lobu apply` (jiti) can't resolve it - // outside this monorepo. Regression guard for that blocker. + // The generated lobu.config.ts imports @lobu/cli/config, so the scaffolded + // package.json MUST declare @lobu/cli — else `lobu apply` (jiti) can't + // resolve it outside this monorepo. Regression guard for that blocker. const pkg = JSON.parse(readFileSync(join(proj, "package.json"), "utf-8")); - expect(pkg.devDependencies["@lobu/sdk"]).toBeDefined(); + expect(pkg.devDependencies["@lobu/cli"]).toBeDefined(); expect(pkg.devDependencies["@lobu/connector-sdk"]).toBeDefined(); const tsconfig = JSON.parse( readFileSync(join(proj, "tsconfig.json"), "utf-8") @@ -110,7 +110,7 @@ describe("lobu init --yes", () => { }); test("scaffolded lobu.config.ts loads into desired state", async () => { - // jiti resolves the externalized `@lobu/sdk` import relative to the config + // jiti resolves the externalized `@lobu/cli/config` import relative to the config // file, so scaffold inside the package tree (where node_modules is // reachable), not the tmpdir() used by the other init tests. const fixtureRoot = mkdtempSync(join(import.meta.dir, "init-load-")); @@ -173,7 +173,7 @@ describe("agent scaffold", () => { test("scaffolds the agent dir and prints a defineAgent block", async () => { writeFileSync( join(cwd, "lobu.config.ts"), - 'import { defineConfig } from "@lobu/sdk";\nexport default defineConfig({ agents: [] });\n' + 'import { defineConfig } from "@lobu/cli/config";\nexport default defineConfig({ agents: [] });\n' ); const logs: string[] = []; const original = console.log; @@ -198,7 +198,7 @@ describe("agent scaffold", () => { test("escapes quotes in --name so the printed snippet stays valid TS", async () => { writeFileSync( join(cwd, "lobu.config.ts"), - 'import { defineConfig } from "@lobu/sdk";\nexport default defineConfig({ agents: [] });\n' + 'import { defineConfig } from "@lobu/cli/config";\nexport default defineConfig({ agents: [] });\n' ); const logs: string[] = []; const original = console.log; diff --git a/packages/cli/src/commands/_lib/apply/__tests__/apply-cmd-dryrun.test.ts b/packages/cli/src/commands/_lib/apply/__tests__/apply-cmd-dryrun.test.ts index b678abed0..dae1201c1 100644 --- a/packages/cli/src/commands/_lib/apply/__tests__/apply-cmd-dryrun.test.ts +++ b/packages/cli/src/commands/_lib/apply/__tests__/apply-cmd-dryrun.test.ts @@ -46,7 +46,7 @@ function silenceOutput() { } // Fixtures live under the worktree (next to this test) so the externalized -// `@lobu/sdk` import in the generated config bundle resolves from node_modules. +// `@lobu/cli/config` import in the generated config bundle resolves from node_modules. function mkProject(config: string): string { const dir = mkdtempSync(join(import.meta.dir, "fixture-")); tempDirs.push(dir); @@ -66,7 +66,7 @@ function minimalConfig( ] .filter(Boolean) .join("\n"); - return `import { defineAgent, defineConfig } from "@lobu/sdk"; + return `import { defineAgent, defineConfig } from "@lobu/cli/config"; export default defineConfig({ ${extra ? `${extra}\n` : ""} agents: [defineAgent({ id: ${JSON.stringify(agentId)}, name: "Triage", dir: "./agents/${agentId}" })], }); diff --git a/packages/cli/src/commands/_lib/apply/__tests__/load-config.test.ts b/packages/cli/src/commands/_lib/apply/__tests__/load-config.test.ts index 20b694681..05d364fa4 100644 --- a/packages/cli/src/commands/_lib/apply/__tests__/load-config.test.ts +++ b/packages/cli/src/commands/_lib/apply/__tests__/load-config.test.ts @@ -4,7 +4,7 @@ import { join } from "node:path"; import { loadDesiredStateFromConfig } from "../desired-state.js"; // Fixtures live under the worktree (next to this test) so that the externalized -// `@lobu/sdk` import in the generated bundle resolves from node_modules. +// `@lobu/cli/config` import in the generated bundle resolves from node_modules. describe("loadDesiredStateFromConfig", () => { let dir = ""; afterEach(() => { @@ -17,7 +17,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig, defineEntityType } from "@lobu/sdk";`, + `import { defineAgent, defineConfig, defineEntityType } from "@lobu/cli/config";`, `const person = defineEntityType({ key: "person" });`, `export default defineConfig({`, ` org: "test-org",`, @@ -72,7 +72,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig, defineConnection } from "@lobu/sdk";`, + `import { defineAgent, defineConfig, defineConnection } from "@lobu/cli/config";`, `export default defineConfig({`, ` agents: [defineAgent({ id: "crm" })],`, ` connections: [defineConnection({ slug: "weather", connector: "weather" })],`, @@ -107,7 +107,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({ agents: [defineAgent({ id: "crm" })] });`, ``, ].join("\n") @@ -142,7 +142,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({ agents: [defineAgent({ id: "crm" })] });`, ``, ].join("\n") @@ -177,7 +177,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({`, ` agents: [defineAgent({ id: "crm", network: { allowed: ["github.com"] } })],`, `});`, @@ -214,7 +214,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({`, ` agents: [`, ` defineAgent({ id: "a", dir: "./custom-a" }),`, @@ -255,7 +255,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({ agents: [defineAgent({ id: "a" })] });`, ``, ].join("\n") @@ -285,7 +285,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig, defineWatcher } from "@lobu/sdk";`, + `import { defineAgent, defineConfig, defineWatcher } from "@lobu/cli/config";`, `const crm = defineAgent({ id: "crm" });`, `export default defineConfig({`, ` agents: [crm],`, @@ -310,7 +310,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig, defineWatcher } from "@lobu/sdk";`, + `import { defineAgent, defineConfig, defineWatcher } from "@lobu/cli/config";`, `const crm = defineAgent({ id: "crm" });`, `export default defineConfig({ agents: [crm], watchers: [defineWatcher({`, ` agent: crm, slug: "w", prompt: "p", extractionSchema: {}, reaction: ${JSON.stringify(reaction)},`, @@ -347,7 +347,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig, defineWatcher } from "@lobu/sdk";`, + `import { defineAgent, defineConfig, defineWatcher } from "@lobu/cli/config";`, `const a = defineAgent({ id: "a" });`, `export default defineConfig({ agents: [a], watchers: [`, ` defineWatcher({ agent: a, slug: "first", prompt: "p", extractionSchema: {} }),`, @@ -371,7 +371,7 @@ describe("loadDesiredStateFromConfig", () => { writeFileSync( join(dir, "lobu.config.ts"), [ - `import { defineAgent, defineConfig } from "@lobu/sdk";`, + `import { defineAgent, defineConfig } from "@lobu/cli/config";`, `export default defineConfig({ agents: [defineAgent({ id: "crm" })] });`, ``, ].join("\n") diff --git a/packages/cli/src/commands/_lib/apply/__tests__/map-config.test.ts b/packages/cli/src/commands/_lib/apply/__tests__/map-config.test.ts index b00f48332..66760addc 100644 --- a/packages/cli/src/commands/_lib/apply/__tests__/map-config.test.ts +++ b/packages/cli/src/commands/_lib/apply/__tests__/map-config.test.ts @@ -9,7 +9,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; import { mapProjectToDesiredState, mergeAgentDirArtifacts, diff --git a/packages/cli/src/commands/_lib/apply/desired-state.ts b/packages/cli/src/commands/_lib/apply/desired-state.ts index 3aaf5657e..6bc8b83bf 100644 --- a/packages/cli/src/commands/_lib/apply/desired-state.ts +++ b/packages/cli/src/commands/_lib/apply/desired-state.ts @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs"; import { readdir, readFile, stat } from "node:fs/promises"; import { isAbsolute, join, relative, resolve, sep } from "node:path"; import { pathToFileURL } from "node:url"; -import type { Project } from "@lobu/sdk"; +import type { Project } from "../../../config/index.js"; import type { ConnectorAuthSchema, ConnectorDefinition, @@ -782,9 +782,9 @@ function resolveReactionScript( * * Uses jiti — the same runtime TypeScript loader Next.js/Nuxt use for their * `*.config.ts` — which transpiles on import and resolves the config's imports - * (`@lobu/sdk`, `@lobu/connector-sdk`, relative reaction/connector files) from - * the project. No bundling, no temp file. The dynamic `import("jiti")` is lazy - * + allow-listed (AGENTS.md). + * (`@lobu/cli/config`, `@lobu/connector-sdk`, relative reaction/connector files) + * from the project. No bundling, no temp file. The dynamic `import("jiti")` is + * lazy + allow-listed (AGENTS.md). */ export async function loadProjectConfig( cwd: string @@ -800,15 +800,15 @@ export async function loadProjectConfig( project = await jiti.import(configPath, { default: true }); } catch (err) { const message = err instanceof Error ? err.message : String(err); - // A fresh `lobu init` writes package.json declaring @lobu/sdk but doesn't + // A fresh `lobu init` writes package.json declaring @lobu/cli but doesn't // install — jiti then can't resolve the import. Point the user at the fix // instead of surfacing a raw module-resolution error. if ( - /@lobu\/(sdk|connector-sdk)/.test(message) && + /@lobu\/(cli|connector-sdk)/.test(message) && !existsSync(resolve(cwd, "node_modules")) ) { throw new ValidationError( - `Failed to load lobu.config.ts — its @lobu/sdk import can't be resolved because dependencies aren't installed. Run \`bun install\` (or npm/pnpm install) in ${cwd} first.` + `Failed to load lobu.config.ts — its @lobu/cli/config import can't be resolved because dependencies aren't installed. Run \`bun install\` (or npm/pnpm install) in ${cwd} first.` ); } throw new ValidationError(`Failed to load lobu.config.ts — ${message}`); diff --git a/packages/cli/src/commands/_lib/apply/map-config.ts b/packages/cli/src/commands/_lib/apply/map-config.ts index c567da8f4..8078fa4f5 100644 --- a/packages/cli/src/commands/_lib/apply/map-config.ts +++ b/packages/cli/src/commands/_lib/apply/map-config.ts @@ -1,6 +1,6 @@ /** - * Map a `@lobu/sdk` authoring project (the default export of `lobu.config.ts`, - * built by `defineConfig`) to the apply `DesiredState`. + * Map an authoring project (the default export of `lobu.config.ts`, built by + * `defineConfig` from `@lobu/cli/config`) to the apply `DesiredState`. * * `DesiredState` is an apply-internal IR and stays CLI-private; this is the one * place that translates the public authoring objects into it. The mapping is @@ -20,8 +20,8 @@ import type { Project, RelationshipType, Watcher, -} from "@lobu/sdk"; -import { isSecretRef } from "@lobu/sdk"; +} from "../../../config/index.js"; +import { isSecretRef } from "../../../config/index.js"; import { CronExpressionParser } from "cron-parser"; import { ValidationError } from "../../memory/_lib/errors.js"; import type { @@ -660,7 +660,7 @@ function mapConnection(connection: Connection): DesiredConnection { } /** - * Translate a `@lobu/sdk` project into the apply `DesiredState`. When `only` is + * Translate an authoring project into the apply `DesiredState`. When `only` is * set, connector definitions/connections/auth-profiles are skipped (and their * secrets not collected), matching the TOML loader's `--only` behavior so * `lobu apply --only agents` doesn't demand connector secrets. diff --git a/packages/cli/src/commands/_lib/init-from-org/__tests__/init-from-org.test.ts b/packages/cli/src/commands/_lib/init-from-org/__tests__/init-from-org.test.ts index dbf9b6a18..d1cae4268 100644 --- a/packages/cli/src/commands/_lib/init-from-org/__tests__/init-from-org.test.ts +++ b/packages/cli/src/commands/_lib/init-from-org/__tests__/init-from-org.test.ts @@ -9,7 +9,7 @@ * * Network is stubbed through an injected fetch impl returning the canned * responses listAgents / listEntityTypes / etc. produce. The fixture dir lives - * UNDER `import.meta.dir` so jiti resolves the externalized `@lobu/sdk`. + * UNDER `import.meta.dir` so jiti resolves the externalized `@lobu/cli/config`. */ import { afterEach, beforeEach, describe, expect, test } from "bun:test"; import { mkdtempSync, readFileSync, rmSync } from "node:fs"; @@ -618,7 +618,7 @@ describe("lobu init --from-org", () => { expect(source).not.toContain("super-secret"); // ...AND the `secret` import is present so the file compiles. expect(source).toMatch( - /import\s*\{[^}]*\bsecret\b[^}]*\}\s*from\s*"@lobu\/sdk"/s + /import\s*\{[^}]*\bsecret\b[^}]*\}\s*from\s*"@lobu\/cli\/config"/s ); // Round-trips: jiti loads the regenerated config without a missing-import diff --git a/packages/cli/src/commands/_lib/init-from-org/bootstrap.ts b/packages/cli/src/commands/_lib/init-from-org/bootstrap.ts index 0403d6750..2839441bd 100644 --- a/packages/cli/src/commands/_lib/init-from-org/bootstrap.ts +++ b/packages/cli/src/commands/_lib/init-from-org/bootstrap.ts @@ -246,7 +246,7 @@ class ImportTracker { } render(): string { const names = IMPORTABLE.filter((n) => this.used.has(n)).sort(); - return `import {\n${names.map((n) => ` ${n}`).join(",\n")},\n} from "@lobu/sdk";`; + return `import {\n${names.map((n) => ` ${n}`).join(",\n")},\n} from "@lobu/cli/config";`; } } diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 943a7db06..a56c4841f 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -186,9 +186,10 @@ export async function scaffoldProjectPackaging( } pkgJson.devDependencies = { ...((pkgJson.devDependencies as Record | undefined) ?? {}), - // lobu.config.ts imports @lobu/sdk; connectors import @lobu/connector-sdk. - // Both must be declared so `lobu apply` (jiti) + the editor resolve them. - "@lobu/sdk": `^${cliVersion}`, + // lobu.config.ts imports @lobu/cli/config; connectors import + // @lobu/connector-sdk. Both must be declared so `lobu apply` (jiti) + the + // editor resolve them. + "@lobu/cli": `^${cliVersion}`, "@lobu/connector-sdk": `^${cliVersion}`, }; await writeFile(pkgJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`); @@ -334,7 +335,7 @@ export async function initCommand( url: options.url, }); // Same package.json/tsconfig the blank scaffold writes, so the bootstrapped - // lobu.config.ts can resolve @lobu/sdk + re-apply outside this monorepo. + // lobu.config.ts can resolve @lobu/cli/config + re-apply outside this monorepo. await scaffoldProjectPackaging(projectDir, projectName, cliVersion); if (!here) { console.log(chalk.cyan(`\n Next: cd ${projectName}\n`)); @@ -1078,7 +1079,7 @@ export async function generateLobuConfig( "// optional skills/ directory. Shared skills in the root skills/ directory", "// are available to every agent. Run `lobu apply` to sync this to your org.", "", - 'import { defineAgent, defineConfig, secret } from "@lobu/sdk";', + 'import { defineAgent, defineConfig, secret } from "@lobu/cli/config";', "", "const agent = defineAgent({", ...agentFields, diff --git a/packages/cli/src/commands/memory/_lib/schema.ts b/packages/cli/src/commands/memory/_lib/schema.ts index 96db591ac..f111f24aa 100644 --- a/packages/cli/src/commands/memory/_lib/schema.ts +++ b/packages/cli/src/commands/memory/_lib/schema.ts @@ -1,7 +1,7 @@ /** * Schema + validation for `lobu memory seed` data records (`./data/*.yaml` — * seed entity + relationship instances). Entity/relationship/watcher *types* - * are declared in `lobu.config.ts` (via `@lobu/sdk`), not here. + * are declared in `lobu.config.ts` (via `@lobu/cli/config`), not here. * * Bump CURRENT_SCHEMA_VERSION when making breaking changes. */ diff --git a/packages/cli/src/config/__tests__/config-isolation.test.ts b/packages/cli/src/config/__tests__/config-isolation.test.ts new file mode 100644 index 000000000..539ac2c20 --- /dev/null +++ b/packages/cli/src/config/__tests__/config-isolation.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, test } from "bun:test"; +import { readdirSync, readFileSync } from "node:fs"; +import { join } from "node:path"; + +// `@lobu/cli/config` is loaded by jiti from a project's node_modules at +// `lobu apply` time. It MUST stay dependency-light: importing any heavy CLI +// internal (the server bundle, embedded-postgres, the chat adapters, esbuild, +// playwright, …) would drag that whole graph into a user's `lobu.config.ts` +// load + typecheck. The only allowed imports are relative siblings, the +// connector authoring subpath, and TypeBox. +const ALLOWED_BARE = new Set([ + "@lobu/connector-sdk", + "@lobu/connector-sdk/define-connector", + "@sinclair/typebox", +]); + +const configDir = join(import.meta.dir, ".."); + +function importSpecifiers(source: string): string[] { + const specs: string[] = []; + // Matches `from "x"` (static import/export-from) and `import("x")`. + const re = /(?:from|import)\s*\(?\s*["']([^"']+)["']/g; + let m: RegExpExecArray | null; + // biome-ignore lint/suspicious/noAssignInExpressions: standard regex loop + while ((m = re.exec(source)) !== null) { + if (m[1]) specs.push(m[1]); + } + return specs; +} + +describe("@lobu/cli/config isolation", () => { + test("imports only relative siblings, connector-sdk, and typebox", () => { + const files = readdirSync(configDir).filter( + (f) => f.endsWith(".ts") && f !== "__tests__" + ); + expect(files.length).toBeGreaterThan(0); + + const offenders: string[] = []; + for (const file of files) { + const source = readFileSync(join(configDir, file), "utf-8"); + for (const spec of importSpecifiers(source)) { + const isRelative = spec.startsWith("."); + if (!isRelative && !ALLOWED_BARE.has(spec)) { + offenders.push(`${file}: ${spec}`); + } + } + } + + expect(offenders).toEqual([]); + }); +}); diff --git a/packages/sdk/src/__tests__/define.test.ts b/packages/cli/src/config/__tests__/define.test.ts similarity index 100% rename from packages/sdk/src/__tests__/define.test.ts rename to packages/cli/src/config/__tests__/define.test.ts diff --git a/packages/sdk/src/define.ts b/packages/cli/src/config/define.ts similarity index 100% rename from packages/sdk/src/define.ts rename to packages/cli/src/config/define.ts diff --git a/packages/sdk/src/index.ts b/packages/cli/src/config/index.ts similarity index 52% rename from packages/sdk/src/index.ts rename to packages/cli/src/config/index.ts index 9a6427e78..47b50350b 100644 --- a/packages/sdk/src/index.ts +++ b/packages/cli/src/config/index.ts @@ -1,9 +1,16 @@ -// Lobu authoring SDK — define agents, connectors, watchers, and connections in -// TypeScript. `lobu apply` imports a project entrypoint (default export of -// `defineConfig`) and maps it to the server's desired state. +// Lobu authoring config API — define agents, connectors, watchers, and +// connections in TypeScript. `lobu apply` imports a project entrypoint (default +// export of `defineConfig`) and maps it to the server's desired state. +// +// This is the `@lobu/cli/config` subpath: a project installs `@lobu/cli` (the +// tool it already runs `apply` with) and authors `lobu.config.ts` against this +// entry. The module is intentionally dependency-light — it must NOT import any +// heavy CLI internals (server bundle, embedded-postgres, etc.), since jiti +// loads it from the project's node_modules at apply time. The +// `config-isolation.test.ts` guard enforces that. // Connector authoring is re-exported so a project imports its whole authoring -// surface from one package. Deep-imported from the `define-connector` subpath +// surface from one entry. Deep-imported from the `define-connector` subpath // (not the package barrel) to avoid bun's ESM linker flakily failing to resolve // names through connector-sdk's large re-export barrel (issue #976). export { defineConnector } from "@lobu/connector-sdk/define-connector"; diff --git a/packages/sdk/src/secret.ts b/packages/cli/src/config/secret.ts similarity index 100% rename from packages/sdk/src/secret.ts rename to packages/cli/src/config/secret.ts diff --git a/packages/landing/scripts/gen-landing-snippets.ts b/packages/landing/scripts/gen-landing-snippets.ts index 68921ca78..b89a097a3 100644 --- a/packages/landing/scripts/gen-landing-snippets.ts +++ b/packages/landing/scripts/gen-landing-snippets.ts @@ -4,7 +4,7 @@ * landing page imports at build time. * * The whole declarative project now lives in a single TypeScript file per - * example: `examples//lobu.config.ts` (using `@lobu/sdk`: + * example: `examples//lobu.config.ts` (using `@lobu/cli/config`: * `defineConfig`, `defineAgent`, `defineEntityType`, `defineWatcher`, ...). * The landing page shows SOURCE CODE, so we slice the raw `.ts` text into * budget-sized sections; we never import/execute the config. @@ -122,7 +122,7 @@ function githubTreeUrl(slug: string): string { /* -------------------------------------------------------------------------- */ /** - * Slice the leading `import ... from "@lobu/sdk";` block out of a config file. + * Slice the leading `import ... from "@lobu/cli/config";` block out of a config file. * Returns the import statement lines (the first `import` through its closing * `from "...";`), or an empty array if none is found. */ diff --git a/packages/landing/src/content/docs/getting-started/index.mdx b/packages/landing/src/content/docs/getting-started/index.mdx index 0b33538bd..c13ea1214 100644 --- a/packages/landing/src/content/docs/getting-started/index.mdx +++ b/packages/landing/src/content/docs/getting-started/index.mdx @@ -31,7 +31,7 @@ LOBU_TOKEN=$(npx @lobu/cli@latest token) bunx promptfoo eval \ ``` my-agent/ ├── lobu.config.ts # agents, providers, network, memory schema (TypeScript) -├── package.json # declares @lobu/sdk + @lobu/connector-sdk +├── package.json # declares @lobu/cli/config + @lobu/connector-sdk ├── tsconfig.json ├── .env # secrets (API keys, optional DATABASE_URL) ├── AGENTS.md # briefing for coding agents @@ -81,7 +81,7 @@ See [Skills](/getting-started/skills/) for which coding agents this supports and ## Configuration -`lobu.config.ts` plus the files under `agents//` are the source of truth: agents, providers, network policy, tool policy, MCP servers, and (optionally) the memory schema. `lobu.config.ts` is a TypeScript module that default-exports `defineConfig({...})` and imports its authoring functions from `@lobu/sdk`. Edit it locally and `lobu run` picks it up immediately. +`lobu.config.ts` plus the files under `agents//` are the source of truth: agents, providers, network policy, tool policy, MCP servers, and (optionally) the memory schema. `lobu.config.ts` is a TypeScript module that default-exports `defineConfig({...})` and imports its authoring functions from `@lobu/cli/config`. Edit it locally and `lobu run` picks it up immediately. To run an agent on **Lobu Cloud**, push the same project up with `lobu apply`: diff --git a/packages/landing/src/content/docs/getting-started/reaction-sdk.md b/packages/landing/src/content/docs/getting-started/reaction-sdk.md index 6287bacc5..b6fbc7c9f 100644 --- a/packages/landing/src/content/docs/getting-started/reaction-sdk.md +++ b/packages/landing/src/content/docs/getting-started/reaction-sdk.md @@ -132,7 +132,7 @@ my-agent/ **The watcher names its reaction.** Point a watcher at a reaction with the `reaction` field in `defineWatcher`: ```ts -import { defineWatcher } from "@lobu/sdk"; +import { defineWatcher } from "@lobu/cli/config"; const criticalDetection = defineWatcher({ agent: myAgent, diff --git a/packages/landing/src/content/docs/guides/agent-prompts.md b/packages/landing/src/content/docs/guides/agent-prompts.md index 148afef1d..0b9588586 100644 --- a/packages/landing/src/content/docs/guides/agent-prompts.md +++ b/packages/landing/src/content/docs/guides/agent-prompts.md @@ -149,7 +149,7 @@ See [Memory](/getting-started/memory/) for the full model. With multiple agents in `lobu.config.ts`, each one gets its own workspace: ```ts -import { defineAgent, defineConfig } from "@lobu/sdk"; +import { defineAgent, defineConfig } from "@lobu/cli/config"; const support = defineAgent({ id: "support", diff --git a/packages/landing/src/content/docs/guides/egress-judge.md b/packages/landing/src/content/docs/guides/egress-judge.md index dd10eb6c7..97d2bb6fb 100644 --- a/packages/landing/src/content/docs/guides/egress-judge.md +++ b/packages/landing/src/content/docs/guides/egress-judge.md @@ -30,7 +30,7 @@ The same shape is available to operators in [`lobu.config.ts`](/reference/lobu-c Operators layer a project-wide policy on top of whatever the skill author declared, via `defineAgent({ egress })`: ```ts -import { defineAgent } from "@lobu/sdk"; +import { defineAgent } from "@lobu/cli/config"; const assistant = defineAgent({ id: "assistant", diff --git a/packages/landing/src/content/docs/guides/guardrails.md b/packages/landing/src/content/docs/guides/guardrails.md index 03f60d0b8..4260dc97a 100644 --- a/packages/landing/src/content/docs/guides/guardrails.md +++ b/packages/landing/src/content/docs/guides/guardrails.md @@ -42,7 +42,7 @@ Three primitives ship from the gateway and are registered at boot. Reference the List built-in (or globally-registered) guardrail names on the agent in [`lobu.config.ts`](/reference/lobu-config/): ```ts -import { defineAgent } from "@lobu/sdk"; +import { defineAgent } from "@lobu/cli/config"; const assistant = defineAgent({ id: "assistant", diff --git a/packages/landing/src/content/docs/guides/sync-from-github.md b/packages/landing/src/content/docs/guides/sync-from-github.md index 50d365d7b..a05a1b26b 100644 --- a/packages/landing/src/content/docs/guides/sync-from-github.md +++ b/packages/landing/src/content/docs/guides/sync-from-github.md @@ -74,7 +74,7 @@ my-agents/ `lobu.config.ts` references each agent's directory: ```ts -import { defineAgent, defineConfig, secret } from "@lobu/sdk"; +import { defineAgent, defineConfig, secret } from "@lobu/cli/config"; const supportBot = defineAgent({ id: "support-bot", diff --git a/packages/landing/src/content/docs/guides/tool-policy.md b/packages/landing/src/content/docs/guides/tool-policy.md index c0dc1f34a..e2bf6518c 100644 --- a/packages/landing/src/content/docs/guides/tool-policy.md +++ b/packages/landing/src/content/docs/guides/tool-policy.md @@ -11,7 +11,7 @@ Use the `tools` field for two separate concerns: - **MCP approval bypass**: `preApproved` ```ts -import { defineAgent } from "@lobu/sdk"; +import { defineAgent } from "@lobu/cli/config"; const support = defineAgent({ id: "support", diff --git a/packages/landing/src/content/docs/reference/cli.md b/packages/landing/src/content/docs/reference/cli.md index b31694065..c217b17b8 100644 --- a/packages/landing/src/content/docs/reference/cli.md +++ b/packages/landing/src/content/docs/reference/cli.md @@ -30,8 +30,8 @@ npx @lobu/cli@latest init my-agent Generates: -- `lobu.config.ts`: the TypeScript project entrypoint (`defineConfig` from `@lobu/sdk`) -- `package.json` + `tsconfig.json`: declare `@lobu/sdk` / `@lobu/connector-sdk` and give the editor type resolution +- `lobu.config.ts`: the TypeScript project entrypoint (`defineConfig` from `@lobu/cli/config`) +- `package.json` + `tsconfig.json`: declare `@lobu/cli` / `@lobu/connector-sdk` and give the editor type resolution - `.env` — local environment variables (API keys, optional external `DATABASE_URL`) - `agents/{name}/` — `IDENTITY.md`, `SOUL.md`, `USER.md`, local skills, and evals - `skills/` — shared local skills directory diff --git a/packages/landing/src/content/docs/reference/lobu-apply.md b/packages/landing/src/content/docs/reference/lobu-apply.md index 36b7b7561..d7b2b7ec6 100644 --- a/packages/landing/src/content/docs/reference/lobu-apply.md +++ b/packages/landing/src/content/docs/reference/lobu-apply.md @@ -47,7 +47,7 @@ import { defineEntityType, defineRelationshipType, defineWatcher, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const account = defineEntityType({ key: "account", name: "Account" }); const owns = defineRelationshipType({ key: "owns", name: "Owns" }); diff --git a/packages/landing/src/content/docs/reference/lobu-config.md b/packages/landing/src/content/docs/reference/lobu-config.md index e20b94b35..b186ca73b 100644 --- a/packages/landing/src/content/docs/reference/lobu-config.md +++ b/packages/landing/src/content/docs/reference/lobu-config.md @@ -1,18 +1,18 @@ --- title: lobu.config.ts reference -description: Complete reference for the lobu.config.ts authoring file and the @lobu/sdk API. +description: Complete reference for the lobu.config.ts authoring file and the @lobu/cli/config API. sidebar: order: 1 --- -`lobu.config.ts` is the project configuration file created by `lobu init`. It is a TypeScript module that default-exports `defineConfig({...})`. You author agents, providers, network access (including the LLM egress judge), guardrails, worker settings, the Lobu memory schema (entity types, relationship types, watchers), connections, and auth profiles by calling the `define*` functions from `@lobu/sdk`. +`lobu.config.ts` is the project configuration file created by `lobu init`. It is a TypeScript module that default-exports `defineConfig({...})`. You author agents, providers, network access (including the LLM egress judge), guardrails, worker settings, the Lobu memory schema (entity types, relationship types, watchers), connections, and auth profiles by calling the `define*` functions from `@lobu/cli/config`. -`lobu apply` (and `lobu run`) import this entrypoint, read the default export, and map it to your org's desired state. `lobu init` also scaffolds a `package.json` that declares `@lobu/sdk` and `@lobu/connector-sdk` as devDependencies, plus a `tsconfig.json`, so your editor and `lobu apply` can resolve the SDK imports. +`lobu apply` (and `lobu run`) import this entrypoint, read the default export, and map it to your org's desired state. `lobu init` also scaffolds a `package.json` that declares `@lobu/cli` and `@lobu/connector-sdk` as devDependencies, plus a `tsconfig.json`, so your editor and `lobu apply` can resolve the config imports. ## Minimal example ```ts -import { defineAgent, defineConfig, secret } from "@lobu/sdk"; +import { defineAgent, defineConfig, secret } from "@lobu/cli/config"; const agent = defineAgent({ id: "my-agent", @@ -39,7 +39,7 @@ import { defineRelationshipType, defineWatcher, secret, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const assistant = defineAgent({ id: "assistant", @@ -149,9 +149,9 @@ export default defineConfig({ }); ``` -## The `@lobu/sdk` API +## The `@lobu/cli/config` API -Every authoring function is imported from `@lobu/sdk`: +Every authoring function is imported from `@lobu/cli/config`: ```ts import { @@ -164,7 +164,7 @@ import { defineAuthProfile, secret, Type, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; ``` Each `define*` returns a branded handle. Assign it to a `const` and pass that handle wherever a reference is needed (for example a `defineWatcher` takes the `defineAgent` handle as its `agent`). diff --git a/packages/landing/src/content/docs/reference/lobu-memory.md b/packages/landing/src/content/docs/reference/lobu-memory.md index 790e6ebd9..1a6389a9f 100644 --- a/packages/landing/src/content/docs/reference/lobu-memory.md +++ b/packages/landing/src/content/docs/reference/lobu-memory.md @@ -144,7 +144,7 @@ import { defineEntityType, defineRelationshipType, defineWatcher, -} from "@lobu/sdk"; +} from "@lobu/cli/config"; const account = defineEntityType({ key: "account", name: "Account" }); const owns = defineRelationshipType({ key: "owns", name: "Owns" }); diff --git a/packages/landing/src/generated/landing-snippets.json b/packages/landing/src/generated/landing-snippets.json index b0a19918a..2a4176fb2 100644 --- a/packages/landing/src/generated/landing-snippets.json +++ b/packages/landing/src/generated/landing-snippets.json @@ -24,7 +24,7 @@ "language": "typescript" }, "agentConfig": { - "code": "import {\n defineAgent,\n defineConfig,\n defineEntityType,\n defineRelationshipType,\n defineWatcher,\n secret,\n} from \"@lobu/sdk\";\n\nconst sales = defineAgent({\n id: \"sales\",\n name: \"sales\",\n description:\n \"Help revenue teams track account health, rollout progress, and renewal signals\",\n dir: \"./agents/sales\",\n providers: [\n {\n id: \"anthropic\",\n model: \"claude/sonnet-4-5\",\n key: secret(\"ANTHROPIC_API_KEY\"),\n },\n ],\n network: {\n allowed: [\n \"github.com\",\n \".github.com\",\n \".githubusercontent.com\",\n \"registry.npmjs.org\",\n \".npmjs.org\",\n ],\n },\n});", + "code": "import {\n defineAgent,\n defineConfig,\n defineEntityType,\n defineRelationshipType,\n defineWatcher,\n secret,\n} from \"@lobu/cli/config\";\n\nconst sales = defineAgent({\n id: \"sales\",\n name: \"sales\",\n description:\n \"Help revenue teams track account health, rollout progress, and renewal signals\",\n dir: \"./agents/sales\",\n providers: [\n {\n id: \"anthropic\",\n model: \"claude/sonnet-4-5\",\n key: secret(\"ANTHROPIC_API_KEY\"),\n },\n ],\n network: {\n allowed: [\n \"github.com\",\n \".github.com\",\n \".githubusercontent.com\",\n \"registry.npmjs.org\",\n \".npmjs.org\",\n ],\n },\n});", "path": "lobu.config.ts", "githubUrl": "https://github.com/lobu-ai/lobu/blob/main/examples/sales/lobu.config.ts", "language": "typescript" diff --git a/packages/sdk/package.json b/packages/sdk/package.json deleted file mode 100644 index 0b36c1785..000000000 --- a/packages/sdk/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@lobu/sdk", - "version": "9.2.0", - "description": "Lobu authoring SDK — define agents, connectors, watchers, and connections in TypeScript", - "type": "module", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "exports": { - ".": { - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - } - }, - "files": [ - "dist" - ], - "scripts": { - "build": "tsc", - "typecheck": "tsc --noEmit", - "test": "bun test src", - "clean": "rm -rf dist" - }, - "dependencies": { - "@lobu/connector-sdk": "workspace:*", - "@sinclair/typebox": "^0.34.41" - }, - "devDependencies": { - "@types/node": "^20.10.0", - "typescript": "^5.3.3" - }, - "engines": { - "node": ">=18" - }, - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "homepage": "https://github.com/lobu-ai/lobu", - "repository": { - "type": "git", - "url": "git+https://github.com/lobu-ai/lobu.git", - "directory": "packages/sdk" - } -} diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json deleted file mode 100644 index 0ea5b6081..000000000 --- a/packages/sdk/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "target": "ES2022", - "moduleResolution": "bundler", - "esModuleInterop": true, - "skipLibCheck": true, - "strict": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "./dist", - "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "emitDeclarationOnly": false - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/__tests__/**", "**/*.test.ts"] -} diff --git a/release-please-config.json b/release-please-config.json index 099544f8c..e0161ed93 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -41,11 +41,6 @@ "path": "packages/client/package.json", "jsonpath": "$.version" }, - { - "type": "json", - "path": "packages/sdk/package.json", - "jsonpath": "$.version" - }, { "type": "json", "path": "packages/openclaw-plugin/package.json", diff --git a/scripts/bump-version.mjs b/scripts/bump-version.mjs index a591b0af6..501f07872 100644 --- a/scripts/bump-version.mjs +++ b/scripts/bump-version.mjs @@ -9,7 +9,6 @@ const PACKAGES = [ "packages/cli", "packages/connector-sdk", "packages/client", - "packages/sdk", "packages/openclaw-plugin", "packages/connectors", "packages/connector-worker", diff --git a/scripts/gen-use-case-data.ts b/scripts/gen-use-case-data.ts index 655edfd31..fe802f9e1 100644 --- a/scripts/gen-use-case-data.ts +++ b/scripts/gen-use-case-data.ts @@ -4,7 +4,7 @@ * packages/landing/src/generated/use-case-models.ts * * Each example ships a `lobu.config.ts` (a `defineConfig(...)` default export - * from `@lobu/sdk`). We load it the same way the CLI does — via jiti, the + * from `@lobu/cli/config`). We load it the same way the CLI does — via jiti, the * runtime TypeScript loader (see * `packages/cli/src/commands/_lib/apply/desired-state.ts` `loadProjectConfig`) * — and project the SDK `Project` shape down to the minimal model the landing @@ -23,8 +23,8 @@ import { } from "node:fs"; import { join, resolve } from "node:path"; import { pathToFileURL } from "node:url"; -import type { Project, ProviderConfig, Watcher } from "@lobu/sdk"; -import { isSecretRef } from "@lobu/sdk"; +import type { Project, ProviderConfig, Watcher } from "@lobu/cli/config"; +import { isSecretRef } from "@lobu/cli/config"; import { createJiti } from "jiti"; const ROOT = resolve(import.meta.dir, ".."); @@ -39,7 +39,7 @@ const OUTPUT_PATH = join( /** * Import an example's `lobu.config.ts` and return its `defineConfig` default * export. Mirrors `loadProjectConfig` in the CLI: jiti transpiles the config on - * import and resolves its `@lobu/sdk` import from the monorepo. Returns null + * import and resolves its `@lobu/cli/config` import from the monorepo. Returns null * when the example has no config (skipped, not an error). */ async function loadExampleConfig(exampleDir: string): Promise { diff --git a/scripts/publish-packages.mjs b/scripts/publish-packages.mjs index 2b9d22d31..9462c2f0d 100644 --- a/scripts/publish-packages.mjs +++ b/scripts/publish-packages.mjs @@ -23,7 +23,6 @@ const PACKAGES = [ { dir: "packages/core", transform: transformCorePublish }, { dir: "packages/connector-sdk", transform: rewriteWorkspaceRefs }, { dir: "packages/client", transform: rewriteWorkspaceRefs }, - { dir: "packages/sdk", transform: rewriteWorkspaceRefs }, { dir: "packages/agent-worker", transform: rewriteWorkspaceRefs }, { dir: "packages/embeddings", transform: rewriteWorkspaceRefs }, // @lobu/pgvector-embedded is NOT published: it's `private` and ships its diff --git a/scripts/sdk-e2e.sh b/scripts/sdk-e2e.sh index 2da4c55db..370cab9b6 100755 --- a/scripts/sdk-e2e.sh +++ b/scripts/sdk-e2e.sh @@ -75,12 +75,12 @@ done curl -fsS -X POST "http://127.0.0.1:$MOCK_PORT/v1/chat/completions" -H 'content-type: application/json' -d '{}' >/dev/null 2>&1 || fail "mock server did not come up" echo "✓ mock provider up" -# 2) Scaffold a project (inside the repo so jiti resolves the workspace @lobu/sdk). +# 2) Scaffold a project (inside the repo so jiti resolves the workspace @lobu/cli/config). PROJ="$RUN_DIR/proj"; mkdir -p "$PROJ" ( cd "$PROJ" && $LOBU init . -y --here --provider gemini >/dev/null 2>&1 ) rm -f "$PROJ/package.json" cat > "$PROJ/lobu.config.ts" <<'TS' -import { defineAgent, defineConfig, defineConnection, defineEntityType, defineRelationshipType, defineWatcher, secret } from "@lobu/sdk"; +import { defineAgent, defineConfig, defineConnection, defineEntityType, defineRelationshipType, defineWatcher, secret } from "@lobu/cli/config"; const agent = defineAgent({ id: "echo", name: "Echo", dir: "./agents/echo", diff --git a/skills/lobu/SKILL.md b/skills/lobu/SKILL.md index 2ba845eeb..73482a7c3 100644 --- a/skills/lobu/SKILL.md +++ b/skills/lobu/SKILL.md @@ -44,7 +44,7 @@ npx @lobu/cli@latest init cd ``` -The CLI generates the directory layout, including `lobu.config.ts`, `package.json`, and `tsconfig.json`. All authoring is TypeScript: import `defineConfig`, `defineAgent`, `defineEntityType`, `defineRelationshipType`, `defineWatcher`, `defineConnection`, `defineAuthProfile`, and `secret` from `@lobu/sdk`. Read `examples/lobu-crm/lobu.config.ts` in the lobu repo for a complete, working reference before editing. Then edit: +The CLI generates the directory layout, including `lobu.config.ts`, `package.json`, and `tsconfig.json`. All authoring is TypeScript: import `defineConfig`, `defineAgent`, `defineEntityType`, `defineRelationshipType`, `defineWatcher`, `defineConnection`, `defineAuthProfile`, and `secret` from `@lobu/cli/config`. Read `examples/lobu-crm/lobu.config.ts` in the lobu repo for a complete, working reference before editing. Then edit: - **`lobu.config.ts`** — set the agent name + description from question 1 on `defineAgent`; add the chosen provider with `providers: [{ id, model, key: secret("X_API_KEY") }]`; set `org` / `orgName` in `defineConfig` from a slug of the user's choice. - **`.env`** — fill in `DATABASE_URL` and the provider API key from Phase 1. @@ -78,7 +78,7 @@ If anything fails, do not silently move on — surface the error, propose a fix, ## Core Model - **Lobu** is the agent framework, runtime, deployment layer, and memory surface. -- Keep framework configuration in `lobu.config.ts` (TypeScript, `defineConfig` from `@lobu/sdk`). +- Keep framework configuration in `lobu.config.ts` (TypeScript, `defineConfig` from `@lobu/cli/config`). - Keep agent identity and behavior in `IDENTITY.md`, `SOUL.md`, and `USER.md`. - Keep reusable capability bundles in `skills//SKILL.md` or `agents//skills//SKILL.md`. - Use `lobu login` for CLI authentication. Do not use a separate memory login command. @@ -117,7 +117,7 @@ Your long-term memory is powered by Lobu. Do NOT use local files (memory/, MEMOR Configure project-scoped memory in `lobu.config.ts` by setting the org on `defineConfig` and declaring the schema with the `define*` helpers: ```ts -import { defineConfig, defineEntityType } from "@lobu/sdk"; +import { defineConfig, defineEntityType } from "@lobu/cli/config"; const ticket = defineEntityType({ key: "ticket", diff --git a/tsconfig.json b/tsconfig.json index 1ad0747f9..ee6610817 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,7 +53,6 @@ "packages/landing/**/*", "packages/server/**/*", "packages/connector-sdk/**/*", - "packages/sdk/**/*", "packages/openclaw-plugin/**/*", "packages/connector-worker/**/*", "packages/connectors/**/*",