* fix: simplify chat rendering, persist drawer size, fix auth guard
- Simplify chat-messages.tsx: remove dual-path tailContent rendering,
always use AssistantMessage for both stream and committed states
- Remove dead code: chat-status-state.ts (ThinkingGroup/ToolGroup/StatusTimer)
- Remove dead exports: busyStartedAt, composerPlaceholder from use-chat-session
- Fix ThinkingBlock label: remove hardcoded label="Thinking" so defaults
work ("Thinking" shimmer → "Thought" static)
- Persist resizable drawer panel size in localStorage alongside open state
to eliminate layout shift on page refresh
- Add busy grace period in use-chat-session for smooth stream→committed transition
- Accumulate reasoning parts across multi-step tool use in durable-chat-run
- Fix auth-guard: remove localSandboxMode bypass so login always works
- Fix chatThreads.getMessages: return [] instead of throwing when unauthenticated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove unnecessary busy grace period
Convex reactive queries handle data consistency — no need for a 600ms
grace period to bridge the stream→committed transition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove dead shouldShowToolsForAssistantSnapshot
Greptile P1: function was exported and tested but never called.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: stabilize resizable drawer defaultSize to prevent drag breakage
The aside panel's defaultSize prop included state.activeSize, which
changed on every drag frame. In react-resizable-panels, changing
defaultSize triggers panel de-registration and re-registration, which
destroys the active drag's panel references and prevents resizing.
Use useState initializer to capture the size once on mount and keep it
stable. The existing useEffect handles all open/close/resize via
panelRef imperatively.
Also clean up context-chip: split active/inactive into distinct
render paths, remove unused Plus import.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve ../ relative paths in file citations
Strip one leading ../ segment and resolve against rootPath's parent
instead of naively concatenating, which produced un-normalized routes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .husky | ||
| packages | ||
| scripts | ||
| .gitignore | ||
| AGENTS.md | ||
| biome.json | ||
| companion.code-workspace | ||
| CONTRIBUTING.md | ||
| install.sh | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| public-install.sh | ||
| README.md | ||
| tsconfig.base.json | ||
| tsconfig.json | ||
companion.dev domain graciously donated by
![]()
exe.dev
companion
Looking for the companion coding agent? See packages/coding-agent for installation and usage.
Tools for building AI agents and running the companion coding agent.
Packages
| Package | Description |
|---|---|
| @mariozechner/companion-ai | Unified multi-provider LLM API (OpenAI, Anthropic, Google, etc.) |
| @mariozechner/companion-agent-core | Agent runtime with tool calling and state management |
| @mariozechner/companion-coding-agent | Interactive coding agent CLI |
| @mariozechner/companion-tui | Terminal UI library with differential rendering |
| @mariozechner/companion-web-ui | Web components for AI chat interfaces |
Contributing
See CONTRIBUTING.md for contribution guidelines and AGENTS.md for project-specific rules (for both humans and agents).
Install
Public (binary)
Use this for users on production machines where you don't want to expose source.
curl -fsSL https://raw.githubusercontent.com/getcompanion-ai/co-mono/main/public-install.sh | bash
Install everything and keep it always-on (recommended for new devices):
curl -fsSL https://raw.githubusercontent.com/getcompanion-ai/co-mono/main/public-install.sh | bash -s -- --daemon --start
This installer:
- Downloads the latest release (or falls back to source when needed),
- writes
~/.local/bin/companionlauncher, - populates
~/.companion/agent/settings.jsonwith package list, - installs packages (if
npmis available), - and can install a user service for
companion daemonso it stays alive (systemdon Linux,launchdon macOS).
Preinstalled package sources are:
["npm:@e9n/companion-channels", "npm:companion-teams"]
If npm is available, it also installs these packages during install.
If no release asset is found, the installer falls back to source.
COMPANION_FALLBACK_TO_SOURCE=0 \
curl -fsSL https://raw.githubusercontent.com/getcompanion-ai/co-mono/main/public-install.sh | bash -s -- --daemon --start
public-install.sh options:
curl -fsSL https://raw.githubusercontent.com/getcompanion-ai/co-mono/main/public-install.sh | bash -s -- --help
Local (source)
git clone https://github.com/getcompanion-ai/co-mono.git
cd co-mono
./install.sh
Run:
./companion
Run in background with extensions active:
./companion daemon
For a user systemd setup, create ~/.config/systemd/user/companion.service with:
[Unit]
Description=companion daemon
After=network-online.target
[Service]
Type=simple
Environment=CO_MONO_AGENT_DIR=%h/.companion/agent
Environment=COMPANION_CODING_AGENT_DIR=%h/.companion/agent
ExecStart=/absolute/path/to/repo/companion daemon
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
Then enable:
systemctl --user daemon-reload
systemctl --user enable --now companion
On macOS, public-install.sh --daemon --start now provisions a per-user launchd agent automatically.
Optional:
npm run build # build all packages
npm run check # lint/format/typecheck
Development
npm install # Install all dependencies
npm run build # Build all packages
npm run check # Lint, format, and type check
./test.sh # Run tests (skips LLM-dependent tests without API keys)
./companion-test.sh # Run companion from sources (must be run from repo root)
Note:
npm run checkrequiresnpm run buildto be run first. The web-ui package usestscwhich needs compiled.d.tsfiles from dependencies.
License
MIT