The four team tools (tool/team_tools.ts) on the rules of team/team.ts,
driven from real turns by team/runtime.ts:
- Members run on the subagent job machinery (app.ts spawn with `member`):
background, unattended, their own prompt from blocks/team_member.md
(the whole of team_lead.md for one with lead: true), team_send and
team_read (team_add and team_stop for one that leads). Not jobs to the
model: job_list and the job_* tools skip them; a client over the link
still sees them as subagent jobs named "<name>: <role>".
- The room: messages and reports with their marks, delivered at the next
step boundary or waking a finished member or the idle lead; report
posts to the manager.
- A manager's work calls answer the refusal before the permission check,
by risk class (an MCP tool by its readOnlyHint); the tool list is
unchanged. job_stop and reading bash stay.
- Slots: the lead waits for one before its turn (Esc stops the wait);
members wait in order; task helpers in a team count toward the size
and hold a slot; job_send restarting a helper is refused when full.
- The offer is decided with the prompt and kept with it: a resumed
session takes it from its kept tool list.
- The size: agents.min/max settings, refused outside 1 <= min <= max <=
cap, kept across /new and resume; said in a note on the first message,
after a change, after a compaction and a rewind.
- TUI: /team (tree and room, size, stop a member, dialogs for both), an
"agents" row beside the effort in /effort, "team n/max" in the status
bar. /team works over ACP too.
tests/team.test.ts runs a lead, a member and its report through the app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Levels (models/schema.json levels): provider/effort.ts levelsOf/levelFields/
readLevel — `off` only with thinking_switch and sends enable_thinking false
and no effort, `default` for a model that takes no efforts and sends
nothing, a level not offered is read as the start level. The engine's
effort is a level; /effort shows nothing for one level, a Thinking switch
for [off, X], a list otherwise; the status bar follows. /v1/models'
thinking_switch, efforts [] and capacity.parallel are read
(lembas/webui.ts); session/capacity.ts counts parallel slots.
Reasoning (context.md §8): an assistant message of the current turn
carries reasoning_content (provider/common.ts turnReasoning,
openai-chat.ts); step-boundary deliveries, nudges and the wrap-up are
marked turn: false and do not start a turn.
Paths (context.md §11): the <env> block names the project and, started
below the root, that directory relative to it (assemble.ts envLines);
instruction files and @ attachments are named from the root or as ~/…;
file tools and bash resolve relative paths against the project root.
The team rules (team/team.ts) and conformance runners for levels,
reasoning, paths and team; the team runtime follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The system prompt is made once per session (start, compaction, model
switch), kept in session_meta and resent byte for byte; it holds no
date. What changes mid-session -- the date, a mode the person chose, a
plan or memory or instruction file they edited, a personality, MCP
instructions that arrived later -- is a <session-note> on the next user
message, stored with it. The tool list is fixed for the session:
plan_submit is always offered and answers unavailable outside plan
mode, the wrap-up keeps the tools and runs no call, a withdrawn tool
stays listed and answers its refusal; the first request waits up to
mcp_wait_ms for MCP servers. Compaction asks for its summary as the
next turn of the same conversation. Cached input tokens are parsed
(incl. llama.cpp timings), stored per request and shown in /context.
Spec: context.md §7/§10, loop.json context.note (+ plan_ended,
plan_own, personal, empty, mcp_wait_ms), modes.json plan.refused,
compact.md without the transcript heading. Conformance area prefix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The login asks the server for the memory scope in place of library (the
server accepts both; library is no longer offered for new tokens).
/v1/usage is read in the server's 2.0 shape: no plan, balance, credit
costs or windows. The status bar shows what the month has cost so far and
/usage the month's tokens and cost and this device's tokens, each
currency's amount on its own (month.cost_by_currency, else cost_money in
currency). The credit wording is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Harness spec 3.0.0 (acp.md *Memory*): memory records are the server's for the
device as for a chat; everything else in the library is the device's own.
- `library: lembas` (the default when the login's token has the `memory`
scope, or the older `library`) adds the server's /mcp with its `memory`
tool alone, in place of this machine's memory tool; notes_*, knowledge_*
and skill_* are always this machine's. No prompts, resources or
instructions are taken from it.
- The memory in the prompt is the server's: the resource lembas://memory,
read as a session starts (McpManager.readResource) and kept for it — put in
while nothing has been sent, so the prompt never changes under a session.
- A session the client opened (session/new, or opened from the store) sends
its id as `_meta.lembas.scope` on every memory call and on the resource
read (App.setScope); a session of the device's own sends none.
- An instance's `library` context (its knowledge bases) is no longer read:
the knowledge block names this machine's bases only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LLeMbas CLI 2.0 is LLeMbas-server-specific (CLI rule 2). Removed: the
anthropic, gemini, ollama and responses clients, context discovery and
llama-swap unloading (discover.ts), the Connection schema with its dialect,
auth, key_cmd, discover, unload_url and one_model_at_a_time, the model
`fallback` (it only ever moved to another server), effort_map and cache, and
the multi-connection refs. Kept: openai-chat, http, sse, think, effort,
tokens and all of src/lembas.
- connections.yaml holds the login (`type: webui`, as lembas login writes
it). A custom entry from 1.x is read past with a warning that says how to
log in, so an old file still starts; with several logins left, the latest
is used and the others named.
- A model's ref is the id the server serves it under; the older forms
(`<login>/<id>`, `<login>/<model>`) still resolve and config.yaml is
rewritten once. Without a login there is no model, and the error (and the
first-run screen, now the sign-in alone) says `lembas login <address>`.
- A login to another server signs this machine out of the previous one.
- The window is the server's word (no discovery); a capacity group comes
from the server's `capacity.group` alone; embeddings use the server's
/v1/embeddings.
- `lembas models` lists the server's models; install.sh's starter files, the
README and the JSON schemas say the same.
Tests: every fixture is a login now (the fake server lists models, answers
other GETs with 404, and can hand one model to another script, as a server
with several backends); the dialect suites and the cross-connection tests are
gone with their code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Harness spec 3.0.0 (context.md, loop.json `context`), in session/results.ts,
applied by the engine when a result goes into the conversation and never
afterwards:
- every result is headed by its id ([#0001]); a read also by the path as
given, its lines, the file's length and the first 8 hex digits of the
content's SHA-256; an empty file says so;
- a read of an unchanged file whose lines lie inside an earlier full read is
a stub naming it; a list/glob/grep repeated with the same arguments and the
same result is "Same result as #…";
- output over 400 lines or 40,000 characters keeps head and tail with the
elided line; the full result is kept with the session (a new `results`
table in sessions.db, gone with the session);
- edit, multiedit, write and apply_patch answer with their hunks under a
bracket with the new content's hash; a new file is "Created, N lines.";
- recall (new built-in tool) shows any stored result, or a range of it, also
after a resume; ids are never reused;
- compaction appends the table of the reads still in the conversation to the
summary.
A stub only ever points at a result still in the conversation, so after a
compaction, an /undo or a rewind the file is read in full. compaction.prune
is gone: cutting old outputs in place threw the prompt cache away (an old
config's key is dropped with a warning). blocks/context.md is in the prompt
wherever recall is offered. Conformance runner for the `context` area (11
cases pass).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One registry per process, every job owned by a session: bash's background commands (and a command
still running at its timeout, which now goes to the background instead of being killed) and
subagents started with task background: true. job_list, job_output, job_stop (the former
bash_list, bash_output, bash_kill) and the new job_send and report; a finished job wakes the owning
session in every front end with its marked note. The TUI counts jobs, lists them (/jobs), opens a
command's output, enters a subagent and messages it, moves a command to the background (ctrl+b)
and asks before quitting with jobs running. The link gains the jobs capability. Subagents get a
session row of their own, the spec's preamble and agent texts, and their errors reach the report.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The CLI's facts in memory, notes_search, note_manage, skills_list,
skill_view and skill_manage are `variables` now, filled with the CLI's own
values (src/tool/spec-vars.ts): every description and parameter list the CLI
sends is word for word what 1.1.0 said, except note and document ids, which
are strings on both sides (a number is still taken). Descriptions are
filled by the prompt texts' rules, parameter descriptions too. `narrow`
says what a project offers of a shared tool's parameters. Memory's changes
are one pure function (applyOps). Conformance: fill, narrow, memory.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The spec: plan_write and plan_update (new, shared, offered in every mode) and
plan_submit (now shared) keep one structured plan — findings, objectives,
phases of tasks — in place of the todo list, which lives on as a former name
of plan_write. The shared system text is one text for both projects, with
variables for what differs; the mode texts, a prototypes block and a library
block are shared. acp.md: the client hands the device what only it knows
(context, library, prototypes), the plan travels as a structure (plan_state),
library calls carry the chat's scope, and a client may rewind a session.
loop.json says its numbers as numbers. Four conformance areas: plan,
prototype, library_scope, toolcall_index.
The CLI: the plan is kept per session in the store and drawn above the prompt
and on the approval card; the prompt is assembled from the spec's texts with
their variables filled; the link reads the instance's instructions,
personalization, knowledge scope and prototype offer, sends the plan as a
structure and answers rewind; library calls to the instance carry the session
as scope; a prototype written in the terminal is saved as a file and named in
the transcript; a tool-call fragment without an index continues the last call;
the default theme is Moria; dead exports and Hermes leftovers removed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The first public release of LLeMbas CLI: a terminal coding agent and project manager for any LLM
API, with permission modes, git snapshots, memory and skills, knowledge bases, MCP, voice, and a
link to a LLeMbas instance whose web UI can work its sessions too. Signed Linux binaries for x64
and arm64.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>