lembas -l / --local: everything in the project, nothing written elsewhere

Config, data and state are rooted at <project>/.agent/local/lembas (or
.lembas/), kept out of git; a local directory the repository carries is
refused. The user's logins and connections.yaml are read, never written; the
user's config.yaml is not read. The TUI is started with TMPDIR inside it (the
compiled binary unpacks its native library there) and OpenTUI's cache goes
there too; the agent's commands keep the user's TMPDIR.

An instance serves models, chat, speech and the balance only: the link,
/remote, the service and the hub are off, deletes are not sent, and the server
library, search, fetch, embeddings and personalization are not used.
Self-update and uninstall are refused. hardline_disable is ignored, and tools
treat the local directory as outside the project.

The smoke test runs a whole local session in the compiled binary and checks
that HOME, the XDG directories and TMPDIR gained nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
HomerandClaude Opus 5.5 committed 2026-10-14 18:16:28 +00:00
1 parent 479f647cc9
commit b75923e724
27 files changed
+636 -105

No files matched your search

+2 -1
View File
@@ -3,6 +3,7 @@ import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
import { createEffect, createMemo, createSignal, onCleanup, Show } from "solid-js"
import { jobNote, onJobExit } from "../tool/jobs.ts"
import { stricterMode, type App as Runtime } from "../app.ts"
import { isLocal } from "../config/paths.ts"
import type { Effort, Mode } from "../config/schema.ts"
import { COMMANDS, findCommand, type CommandCtx } from "./commands.ts"
import { Dialog, type DialogSpec } from "./components/dialog.tsx"
@@ -178,7 +179,7 @@ export function Root(p: { app: Runtime; view: View; theme: Theme; onQuit: () =>
if (!p.onReload) return view.info("/reload is not available here", "warn")
// Back on this session, with what it was using; everything else comes from the files again.
const e = app.engine
const args = [...(e.sessionId ? ["-s", e.sessionId] : []), "-m", e.model.ref, "--mode", e.mode, "-e", e.effort ?? "off"]
const args = [...(isLocal() ? ["-l"] : []), ...(e.sessionId ? ["-s", e.sessionId] : []), "-m", e.model.ref, "--mode", e.mode, "-e", e.effort ?? "off"]
void app
.close()
.catch(() => {})