Skip to content

@ufo-soft/caelus ​

Define a command once. Dispatch it from anywhere: a button, a key chord, a CLI subcommand, an MCP tool call.

A command registry: commands are self-describing runtime objects, so any surface can project them outward without core knowing that surface exists.

Core ​

Zero dependencies. src/core.ts is the whole thing.

ts
import { Registry, ok, failed } from '@ufo-soft/caelus'

const registry = new Registry()

registry.register({
  name: 'add',
  command: {
    description: 'Add a todo',
    parameters: [{ name: 'text', type: 'string', description: 'The todo text' }],
  },
  handler: ({ text }) => {
    if (typeof text !== 'string') return failed('text must be a string')
    store.add(text)
    return ok()
  },
})

await registry.invoke('add', { text: 'write it down' })

Keybindings ​

@ufo-soft/caelus/keybindings. Defaults are a plain object, the user patch is a parsed TOML file, and one keydown listener dispatches through the registry.

Modules ​