ufoo is a project-scoped multi-agent workspace runtime. It wraps Claude Code,
OpenAI Codex, Antigravity, and ufoo's native ucode agent with a shared chat
dashboard, daemon, event bus, memory, reports, group orchestration, and terminal
launch modes.
Package: u-foo on npm
- One TUI dashboard for launching, watching, messaging, and resuming agents.
- One user-scoped daemon over
~/.ufoo/run/ufoo.sock, hosting isolated project runtimes for launch/resume, reports, groups, cron, and controller routing. - Project-local event bus for agent-to-agent messages, wakeups, queue checks, and activation.
- Shared context primitives: decisions, durable memory, prompt history, reports, and agent registry state.
- Launch modes for internal, tmux, host, Terminal.app, and iTerm2 workflows.
- Built-in group templates for launching and orchestrating multi-agent workflows.
ucode, a native ufoo coding-agent runtime.- One loopback Streamable HTTP MCP server inside the home-scoped global
controller daemon, plus a disposable
ufoo mcpstdio compatibility proxy.
- Node.js 18 or newer.
- macOS for Terminal.app/iTerm2 integration.
- Claude Code, Codex CLI, or Antigravity CLI installed when using the matching
wrappers:
uclaude,ucodex, oruagy.
Install the published package:
npm install -g u-fooOr link this repository for local development:
git clone https://github.com/Icyoung/ufoo.git
cd ufoo
npm install
npm linkInstalled binaries:
| Binary | Purpose |
|---|---|
ufoo |
Main CLI, chat dashboard, daemons, global MCP server/proxy, groups, bus, context, memory, reports, and online helpers. |
uclaude |
Claude Code wrapper with ufoo bootstrap and bus identity. |
ucodex |
Codex wrapper with ufoo bootstrap and bus identity. |
uagy |
Antigravity wrapper with ufoo bootstrap and bus identity. |
ukimi |
Kimi Code wrapper with ufoo bootstrap and bus identity. |
ucode |
Native ufoo coding-agent CLI/TUI. |
Initialize a project and open the chat dashboard:
cd your-project
ufoo init --targets context,bus
ufooLaunch agents from chat:
> /launch codex reviewer
> /launch claude builder
> /launch ucode fixer
> @reviewer inspect the current diff and list release risks
Or launch wrappers directly inside a project:
uclaude
ucodex
uagy
ukimi
ucodeUse global chat mode to switch between registered projects:
ufoo -gFor Codex App, Codex CLI, and the Codex IDE extension, start global mode once and install the shared direct HTTP configuration:
ufoo -g
ufoo mcp configure codexThe configuration points all three Codex surfaces at the same authenticated loopback endpoint. Restart the Codex surface after configuring it.
For a host that has not been verified with direct HTTP, keep the compatible stdio configuration:
ufoo mcpThis command is a stateless transport proxy into the same global server. It
does not own Agent registrations or project state. Inspect or restart the
singleton listener with ufoo mcp status and ufoo mcp restart.
ufoo / ufoo chat
-> src/app/chat + src/ui/rustChatHost + crates/ufoo-tui
-> global daemon over ~/.ufoo/run/ufoo.sock
-> isolated ProjectRuntime selected by project_root
-> runtime launch/resume/recover/reports/cron/groups
-> orchestration router, group templates, solo roles
-> agents launch/providers/internal/controller/activity
-> coordination bus/context/memory/history/report/state/status
-> shared controller/worker tools and native ucode tools
Codex App / CLI / IDE -> Streamable HTTP --+
ufoo mcp stdio proxy ----------------------+
-> home-scoped global controller daemon
(one MCP listener and tool router)
-> ~/.ufoo/projects/runtime
-> managed ProjectRuntimeGateway
-> selected in-process ProjectRuntime for bus/report/activity/wait state
Global topology is the default. ufoo daemon --topology hybrid temporarily
enables project compatibility sockets, and --topology project selects the
legacy per-project daemon rollback path.
ufoo supports two Agent delivery modes, selected only from the host Agent's
inherited UFOO_SUBSCRIBER_ID before any helper terminal is started:
- Wrapper-managed Agents start through
ucodex,uclaude,uagy,ukimi, orucode. The wrapper providesUFOO_SUBSCRIBER_ID; ufoo monitors the shell activity and injection endpoint, so bus messages can be injected directly. These Agents reuse the environment identity and do not register through MCP or run a resident bus poll. - Externally hosted Agents have no wrapper-provided subscriber environment.
They register themselves once through MCP
register_agent, retain the returned subscriber plus opaqueagent_handle, and select the host App's native no-token wait: Codex App keeps MCPwait_for_messagepending, while Cursor monitorsufoo bus poll --followbackground output withnotify_on_output.
Agent type names and subscriber prefixes are routing metadata, not capability
signals. After an external Cursor Agent registers through MCP, its dedicated
listener terminal may export the returned subscriber as
UFOO_SUBSCRIBER_ID so CLI operations share one identity. That child-shell
binding does not alter the host Agent's already selected external mode and is
not evidence of wrapper injection.
Chat is a UI client. The daemon owns project runtime state. Agents communicate through bus queues, prompt injection, shared memory, reports, and tool handlers instead of importing chat UI code.
The normal workflow is to enter chat first, then launch agents and run project commands inside the dashboard:
ufoo
ufoo -gufoo opens the current project chat. ufoo -g opens global chat for switching
between registered projects. The global daemon starts once and project runtimes
activate lazily.
/launch codex reviewer
/launch claude builder
/launch ucode fixer
@reviewer inspect the current diff and list release risks
/status
/settings
/multi
/resume list
/project list
/project switch 2
/open /path/to/project
Direct wrapper commands such as uclaude, ucodex, uagy, and ucode are
still available, but the normal ufoo workflow is to work from chat.
These are setup or troubleshooting commands. In chat, use slash commands:
/init context bus
/doctor
/status
/daemon status
/daemon restart
/daemon stop
/daemon start
ufoo init creates .ufoo/, ensures AGENTS.md and CLAUDE.md, initializes
selected workspace state, and prepares shared storage. CLAUDE.md may be a
symlink; edit project instructions in AGENTS.md.
Before a project has been initialized, the equivalent CLI form is also useful:
ufoo init --targets context,bus.
The default agent skill set is intentionally limited to ufoo, ufoo-bus,
ufoo-context, and ufoo-online. They are installed only as skills, not as a
second command catalog. Initialization and unified status are handled by
ufoo.
/bus list
/bus status
/bus send codex:abc123 Please implement the approved slice.
/bus activate reviewer
/bus rename codex:abc123 reviewer
Use /bus status to find the real subscriber ID or resolvable nickname
before sending. Agents should handle pending work, reply to the sender, and
acknowledge their queue.
Externally hosted Agents with no UFOO_SUBSCRIBER_ID use the opt-in
ufoo-bus-poll skill to select their host App's queue-read-only wait and
self-wake mechanism:
ufoo skills list --optional
ufoo skills install ufoo-bus-poll --target /path/to/that/agent/skillsRegister once through MCP register_agent and retain its returned subscriber
and agent_handle. Include the handle in heartbeat, activity, send, receive,
acknowledgement, report, and unregister calls. The handle is an ownership
capability: do not send it to peers or print it in reports.
- Codex App: call MCP
wait_for_messagein the foreground with the registered subscriber and handle,after_seq: 0, andtimeout_seconds: 0. The tool call stays pending inside the dedicatedufoo_waitMCP connection until a message arrives or the caller cancels it; idle time produces no periodic model wake or token consumption. A message returns immediately and wakes the task without shell stdout. After handling a message response, call MCPack_buswith the same handle and itslast_seqasthrough_seq, then re-arm with thatlast_seqwhen the Agent is idle again. - Cursor: bind the MCP subscriber and run
export UFOO_SUBSCRIBER_ID="<subscriber-id>"; exec ufoo bus poll "$UFOO_SUBSCRIBER_ID" --follow --interval 30through the monitored background shell withblock_until_ms: 0, and configurenotify_on_outputto match\[ufoo\]. Startup and empty intervals are silent; only ufoo-delivered messages wake the model.
Both paths keep idle queue checks outside the LLM. A background PTY alone is not a wake mechanism in Codex App.
The poll skill is not installed by postinstall or skills install all.
Wrapper-managed Agents skip MCP registration and external waiting when
UFOO_SUBSCRIBER_ID was present in the Agent's inherited launch environment.
A value exported later inside a Cursor listener terminal does not rerun this
classification. Receive-path selection depends on host App capabilities, never
on whether the external Agent calls itself Codex, Claude, Cursor, or another
type.
Inside chat:
/ctx status
/ctx doctor
/ctx decisions
Memory, history, and report management are CLI utilities:
ufoo memory add "Provider contract" --body "Durable fact..." --tags provider,contract
ufoo memory list --tag provider
ufoo memory show mem-0001
ufoo history build
ufoo history show 20
ufoo history prompt 30
ufoo report start "Implement README refresh" --task docs-readme --agent builder
ufoo report done "README updated" --task docs-readme --agent builder
ufoo report listUse decisions only for plan-level constraints. Durable project facts belong in memory.
Built-in group templates live in templates/groups/.
/group templates
/group template show build-lane
/group template validate templates/groups/build-lane.json
/group run build-lane dry_run=true
/group run build-lane instance=docs-refresh
/group status
/group diagram build-lane mermaid
/group stop docs-refresh
ufoo online server --host 127.0.0.1 --port 8787
ufoo online token codex:abc123 --nickname builder
ufoo online room create --nickname builder --name review-room --type private --password secret
ufoo online connect --nickname builder --room <room_id> --room-password secret
ufoo online send --nickname builder --room <room_id> --text "handoff ready"
ufoo online inbox builder --unreadThe default public service URL is https://online.ufoo.dev. Local development
can run its own relay with ufoo online server.
ufoo ucode doctor
ufoo ucode prepare
ufoo ucode builducode can discover built-in and local SKILL.md workflow capabilities. Full
skill bodies are loaded only when explicitly referenced.
Project configuration is stored in .ufoo/config.json. ucode provider
credentials are stored globally in ~/.ufoo/config.json and merged at load time.
Common project settings:
{
"launchMode": "auto",
"agentProvider": "codex-cli",
"controllerMode": "main",
"codexInternalThreadMode": "api",
"codexAuthPath": "",
"codexOauthRefreshWindowSec": 300,
"claudeOauthProfile": "",
"claudeOauthTokenPath": "",
"claudeOauthRefreshWindowSec": 300,
"routerProvider": "",
"routerModel": "",
"agentModel": "",
"autoResume": true
}Supported launchMode values: auto, internal, tmux, terminal, and
host. controllerMode accepts main, shadow, loop, and legacy
compatibility values.
Global ucode settings:
{
"ucodeProvider": "openai",
"ucodeModel": "gpt-4.1",
"ucodeBaseUrl": "https://api.openai.com/v1",
"ucodeApiKey": "sk-...",
"ucodeAgentDir": ""
}src/
app/ chat client state and CLI command entry
ui/ Rust TUI hosts + pure formatting helpers
crates/ufoo-tui Rust ratatui child (required for chat/ucode)
runtime/ daemon, projects, terminal adapters, contracts, privacy, process helpers
coordination/ bus, context, memory, history, reports, state, status
orchestration/ router/controller logic, groups, solo roles
agents/ launchers, providers, prompts, internal runner, activity, controller
code/ native ucode runtime, launcher, skills, file/shell tools
tools/ shared controller/worker tool registry and handlers
online/ relay client/server/runner/token helpers
See PROJECT.md for the maintainer-facing map and detailed package ownership.
npm install
npm link
node bin/ufoo.js --help
npm testUseful checks:
npm run test:watch
npm run test:coverageThe repository is CommonJS, targets Node.js 18+, and ships a Rust TTY UI
(crates/ufoo-tui) as platform binaries under dist/tui/.
Releases are published by GitHub Actions (.github/workflows/release.yml).
The workflow builds ufoo-tui for darwin-arm64, darwin-x64, linux-x64,
and linux-arm64, stages them under dist/tui/<platform>/, then runs
npm publish.
- Bump the version and push a matching tag:
npm test
npm version patch # commits package.json + creates tag vX.Y.Z
git push --follow-tags- Ensure the repo secret
NPM_TOKENis set (npm automation token with publish rights foru-foo). - The
Releaseworkflow runs on thev*tag. Use Actions → Release → Run workflow for a manual dry-run (dry_run=truepacks but does not publish).
Local one-platform staging (dev only):
npm run pack:tui # cargo build + copy into dist/tui/$PLATFORM
npm pack --dry-run # requires at least one staged binary (prepack check)Publishing without the GitHub workflow still requires an npm account/token with
permission for u-foo, plus staged dist/tui/ binaries.
Run a local entry directly if the linked binary is not on PATH:
node bin/ufoo.js --helpIf Codex cannot write under its default home, point it at a project-local directory before launching chat or agents:
export CODEX_HOME="$PWD/.ufoo/codex"
ufooFor Codex-friendly notifications, prefer bus helpers over raw terminal text injection:
ufoo bus alert codex:abc123 --daemon
ufoo bus listen codex:abc123UNLICENSED. See LICENSE.