zerg-ztc
v0.1.52
Published
Zerg Terminal Client - CLI agent for continual AI systems
Readme
ZTC - Zerg Terminal Client
A full-screen terminal-based AI agent interface for interacting with the Zerg continual AI system and managing local development tasks.
◆ Zerg Terminal Client ◆ v0.1.0 Ctrl+C exit • /help
────────────────────────────────────────────────────────────────────────
● System • 14:23
Welcome to ZTC - Zerg Terminal Client.
Type a message to begin, or /help for commands.
❯ You • 14:24
Can you read the package.json and summarize it?
◆ Zerg • 14:24
I'll read that file for you.
⚙ read_file (a3f8b2c1) [0.2s]
path: package.json
→ {"name":"ztc","version":"0.1.0"...
This is ZTC v0.1.0, a Node.js CLI application using Ink for the
terminal UI and React 18. It has 5 tools available for file
operations, shell commands, and Zerg queries.
❯ _
● Ready ◉ ZTC v0.1.0 • a3f8b2c1Features
- Full-screen terminal UI - Built with Ink (React for CLIs)
- Agentic tool use - File I/O, shell commands, directory listing, Zerg integration
- Streaming responses - Real-time output with status indicators
- Session management - Unique session IDs, message history
- In-app configuration - Set API keys and model preferences without restarting
- Persistent config - Settings saved to
~/.ztc/config.json - Debug mode - Toggle layout borders for development
- Web UI - Browser-based interface for easier debugging
Installation
# Clone or create the project
mkdir ztc && cd ztc
# Copy all source files to their respective locations (see Project Structure)
# Install dependencies
npm install
# Run in development mode
npm run devRequirements
- Node.js >= 18
- npm or yarn
- Anthropic API key (can be configured in-app)
Usage
Terminal UI
# Development (with hot reload via tsx)
npm run dev
# Production
npm run build
npm start
# Or install globally
npm link
ztcWeb UI (for debugging)
npm run web
# Opens at http://localhost:3000The web UI provides the same interface in a browser, making it easier to debug layouts and inspect state.
Configuration
ZTC stores configuration in ~/.ztc/config.json. You can manage it via commands:
/config show # View current configuration
/config key sk-ant-... # Set Anthropic API key
/config model claude-opus-4-20250514 # Change modelOr set via environment variable:
export ANTHROPIC_API_KEY=sk-ant-your-key-here
npm run devConfig Options
| Option | Description | Default |
|--------|-------------|---------|
| apiKey | Anthropic API key | $ANTHROPIC_API_KEY |
| model | Claude model to use | claude-sonnet-4-20250514 |
| maxTokens | Max response tokens | 4096 |
| zergEndpoint | Zerg API endpoint | undefined |
Commands
| Command | Description |
|---------|-------------|
| /help | Show available commands |
| /config <show\|key\|model> [value] | Manage configuration |
| /status | Show current status |
| /clear | Clear message history |
| /debug <on\|off> | Toggle layout debug borders |
| /exit | Exit ZTC |
Keyboard Shortcuts
| Shortcut | Action |
|----------|--------|
| Enter | Submit message |
| Ctrl+C | Exit |
| Ctrl+L | Clear screen |
| ↑ / ↓ | Navigate command history |
| ← / → | Move cursor |
| Ctrl+← / Ctrl+→ | Move by word |
| Ctrl+A | Move to start of line |
| Ctrl+E | Move to end of line |
| Ctrl+U | Clear input line |
| Ctrl+W | Delete word before cursor |
Available Tools
The agent has access to these tools:
read_file
Read contents of a file.
Arguments:
path: string (required) - File path to read
encoding: string - File encoding (default: utf-8)write_file
Write content to a file, creating directories if needed.
Arguments:
path: string (required) - File path to write
content: string (required) - Content to write
append: "true" | "false" - Append instead of overwritelist_directory
List contents of a directory.
Arguments:
path: string (required) - Directory path
recursive: "true" | "false" - List recursively (max 3 levels)run_command
Execute a shell command.
Arguments:
command: string (required) - Shell command to execute
cwd: string - Working directory
timeout: string - Timeout in ms (default: 30000)zerg_query
Query the Zerg continual AI system.
Arguments:
query: string (required) - Query for Zerg
context: string - Additional context
project: string - Project identifier
wait: "true" | "false" - Wait for completionProject Structure
ztc/
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── README.md
└── src/
├── cli.tsx # CLI entry point
├── App.tsx # Main application component
├── types.ts # TypeScript type definitions
├── config.ts # Configuration store (sync file I/O)
│
├── components/
│ ├── index.ts # Barrel export
│ ├── Header.tsx # Top header bar
│ ├── MessageList.tsx # Scrolling message area
│ ├── InputArea.tsx # Text input with cursor handling
│ └── StatusBar.tsx # Bottom status bar with spinner
│
├── agent/
│ ├── index.ts # Barrel export
│ ├── agent.ts # Agent loop, API calls, event emitter
│ └── tools.ts # Tool definitions and executors
│
└── web/
└── index.html # Standalone browser UI for debuggingArchitecture
Terminal Rendering
ZTC uses Ink which leverages Yoga (the same Flexbox layout engine used by React Native) to render React components to the terminal. This provides:
- Familiar React component model
- Flexbox-based layouts
- Hooks for input handling
- Efficient differential updates
Agent Loop
User Input → Agent.run() → API Call → Tool Use? → Execute Tools → Continue
↑ │ │
└─────────────────────────┴──────────────┘The agent implements a standard ReAct-style loop:
- Send conversation to Claude API
- If response contains tool calls, execute them
- Append results and continue until no more tools
- Return final response to UI
Event System
The agent emits events for UI updates:
thinking_start/thinking_endtool_start/tool_end/tool_errorstream_start/stream_delta/stream_enderror
Avoiding Flicker
Terminal UIs can flicker during re-renders. ZTC prevents this by:
- Loading config synchronously at startup
- Capturing terminal dimensions once at module load
- Avoiding hooks that cause re-renders (
useStdout) - Using
useMemofor computed values
Development
Adding a New Tool
- Define the tool in
src/agent/tools.ts:
export const myTool: Tool = {
definition: {
name: 'my_tool',
description: 'Does something useful',
parameters: {
type: 'object',
properties: {
arg1: { type: 'string', description: 'First argument' }
},
required: ['arg1']
}
},
execute: async (args) => {
// Implementation
return JSON.stringify({ result: 'done' });
}
};- Add to
defaultToolsarray in the same file.
Adding a New Command
Add to the commands array in src/App.tsx:
{
name: 'mycommand',
description: 'Does something',
usage: '<arg>',
handler: (args, ctx) => {
ctx.addMessage({
role: 'system',
content: `You said: ${args.join(' ')}`
});
}
}Building
npm run build # Compile TypeScript to dist/
npm run clean # Remove dist/Roadmap
- [ ] Streaming responses - Token-by-token output
- [ ] Session persistence - Save/load conversation history
- [ ] Multi-line input - Support for longer prompts
- [ ] Zerg integration - Connect to actual Zerg backend
- [ ] Git tools - Commit, diff, branch operations
- [ ] Search tools - Web search, codebase search
- [ ] Shared state module - Extract core logic for terminal + web UIs
- [ ] Plugin system - Dynamic tool loading
Troubleshooting
"No API key configured"
Set your key with:
/config key sk-ant-your-key-hereOr via environment:
export ANTHROPIC_API_KEY=sk-ant-..."Authentication failed"
Your API key may be invalid or expired. Update it with /config key <new-key>.
Flickering display
This shouldn't happen with current code. If it does:
- Ensure you're using the latest source
- Check terminal compatibility (works best with modern terminals)
- Try the web UI for debugging:
npm run web
TypeScript errors
npm run buildIf you see type errors, ensure all files match the artifacts exactly.
License
MIT
Built for the Zerg continual AI system.
