@nebular-ai/lume
v0.3.0
Published
Lume — Nebular's coding coach for the terminal. Materialises a managed opencode workspace + Nebular MCP wiring + a guardian plugin so learners can be coached against their Nebular skill graph in the opencode TUI.
Maintainers
Readme
@nebular-ai/lume
Nebular's coding coach for the terminal. Materialises a managed opencode workspace, wires the Nebular MCP, ships a guardian plugin, and exec's the opencode TUI so learners can be coached against their Nebular skill graph.
lume is the production CLI. v0.2.0 introduced a new architecture:
instead of embedding opencode via the SDK and rolling a custom REPL,
lume is now a thin pre-launch shim that materialises a .opencode/
config tree and exec's opencode tui directly. Real diffs, syntax
highlighting, native session resume, declarative permissions.
Install
npm install -g @nebular-ai/lumeRequires Node ≥ 22. opencode is installed transitively (the
launcher resolves ~/.opencode/bin/opencode by default; override
with OPENCODE_BIN).
Quickstart
lume login # device-flow PAT mint via your browser
mkdir my-proj && cd my-proj
lume scaffold # the agent walks you through picking a programme + scope
lume # coach mode against the scaffolded projectCommands
| Command | What it does |
|---|---|
| lume | Coach mode. Requires .nebular/project.json in cwd. |
| lume --continue | Resume the most recent opencode session for this project. |
| lume -s <id> | Resume a specific opencode session. |
| lume scaffold | Generate a new project from a Nebular programme. |
| lume scaffold --force | Iterate on an existing scaffold (preserves your work). |
| lume init | Attach an existing project to a Nebular programme. |
| lume init --force | Re-attach (e.g. to switch programmes). |
| lume validate | Run each deliverable's validator, print status. |
| lume login | Mint a PAT via browser; saves to ~/.config/lume/credentials. |
| lume logout | Remove the local credentials file. |
Useful flags:
--reset— force-overwrite the.opencode/tree (managed files are rewritten on every launch anyway;--resetalso overwrites user-customised files)--debug— surface env-file resolution, materialise counts, and the per-launchLUME_SESSIONid--programme <slug>/--scope <s>— pre-select for scaffold/init
How it works
On each lume launch:
- Print the Nebular banner
- Load env + credentials (
~/.config/lume/credentials) - Inspect the project manifest (
.nebular/project.json) - Call
session_bootstrapover MCP (coach mode only) to get a fresh protocol body + setup actions - Materialise the workspace:
- Force-rewrite managed files in
.opencode/(agents, guardian plugin, theme, commands, opencode.jsonc), thenchmod 0444so casual edits get reverted on next launch - Leave user-created non-managed files alone
- Always rewrite
.nebular/protocol.md(preamble + bootstrap body- project addendum + final reassertion)
- Force-rewrite managed files in
- Inject
LUME_SESSION=<random-id>into the spawn env exec opencode --agent <mode-agent> --prompt <kickoff>
Inside the opencode TUI, the nebular-guardian plugin runs every
turn:
- Sentinel check — refuses every tool call if
LUME_SESSIONis missing (caught directopencode -sinvocations) - Per-mode bash policy — coach/init use a narrow allowlist with
curl/wget/printenv/envdenied; scaffold widens for asset downloads but blocksnc/ssh/fork-bombs - Sensitive-path reads — blocks
.env,.ssh,*.pem, AWS, GPG, etc. - Telemetry — every decision appends a JSONL line to
.nebular/telemetry.ndjson
Configuration
After lume login, credentials live at ~/.config/lume/credentials
(mode 0600). Optional overrides:
| Var | Default |
|---|---|
| NEBULAR_PAT | set by lume login; can be exported manually |
| NEBULAR_API_URL | https://nebular.live |
| NEBULAR_MCP_URL | https://nebular.live/api/v1/mcp/ |
| NEBULAR_LLM_PROXY_URL | https://nebular.live/api/v1/llm/openai |
| OPENCODE_BIN | ~/.opencode/bin/opencode |
LLM calls route through Nebular's backend proxy — your local environment never needs a DeepInfra key.
Architecture
packages/lume/
├── src/ # ~250 lines of orchestration (vs ~1100 in v0.1)
│ ├── index.ts # CLI entry
│ ├── launcher.ts # bootstrap + materialise + exec opencode
│ ├── materialise.ts # managed-file rewrite + chmod 0444
│ ├── env.ts, credentials.ts, login.ts, bootstrap.ts,
│ ├── mcp-client.ts, project-manifest.ts, validation.ts
│ ├── setup-actions.ts, config.ts, ui.ts, spinner.ts, version.ts
│ └── __tests__/ # vitest: materialise / policy / sentinel
└── templates/ # copied to <cwd>/.opencode/ on every launch
├── opencode.jsonc
└── .opencode/
├── themes/nebular.json
├── agents/nebular-{coach,scaffold,init,validator}.md
├── commands/{start,check,hint,status,wrap}.md
└── plugins/nebular-guardian.tsTroubleshooting
Missing NEBULAR_PAT— runlume login, orexport NEBULAR_PAT=….Could not bootstrap a Nebular session— backend unreachable. CheckNEBULAR_MCP_URL.cannot determine the current working directory— your shell's CWD inode is stale (the dir was deleted+recreated). Runcd "$(pwd)"then re-run.- TUI is grey / nothing happens — plugin probably failed to load.
Check
~/.local/share/opencode/log/forservice=plugin path=... error=....
License
UNLICENSED — internal Nebular distribution.
