Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
# commands
every session command is one definition with three faces: the CLI menu, user invocation, and the model's typed `commands` bindings. adding a command adds all three; nothing about a command is reimplemented per surface.
## the catalog
`GET /sessions/:id/commands` lists the materialized catalog: name (the slash spelling), description, the minted python `method`, its `usage` line, declared `arguments`, and the `modelCallable` / `userTurn` flags. the CLI menu renders it (merged with its presentation-only entries like `/login` and `/sessions`), `GET`'s list mints the kernel bindings at boot, and the prompt's `<session_commands>` block summarizes it. all three read the same list.
`POST /sessions/:id/commands` runs one command. the body is `{name, arguments}` with raw invocation text (`{"name": "/model", "arguments": "gpt-5 anthropic"}`) or `{name, args}` with declared names (`{"name": "/model", "args": {"model": "gpt-5"}}`); `clientId` labels a submitted turn. the answer is `{"result": ...}` with the command's JSON value or `{"submitted": true}` when a user invocation submitted its turn.
## contributing commands
`CommandPlugin` in an extension declares static commands; a `ManagedPlugin` contributes dynamic ones through `Managed.commands` (this is how skills registers its slash commands). the type lives in [`command.gleam`](../src/albedo/harness/command.gleam):
```gleam
Command(
"/usage",
"Show token and cost usage for this session",
[Argument("window", "reporting window", False)],
True,
False,
fn(context, _caller, args) { ... Ok(command.Data(value)) },
)
```
a run executes **outside** the session actor — on the kernel's host-call process or an HTTP request process — and reaches session state only through `Context.state`, whose operations are the `StateOp` variant type in [`command.gleam`](../src/albedo/harness/command.gleam) (the exhaustive case in `session.gleam` answers them). a handler running inside the session actor must never run a command: its state calls would deadlock against its…