| name | pixel-agents-vscode |
| description | Visualize and manage Claude Code AI agents as pixel art characters in a VS Code extension office interface |
| triggers | ["set up pixel agents for claude code","visualize my AI agents in VS Code","create a pixel office for agents","customize agent characters and office layout","manage multiple claude code agents visually","track agent activity with pixel agents","add furniture to my agent office","debug agent connections in pixel agents"] |
Pixel Agents VSCode Extension
Skill by ara.so — AI Agent Skills collection.
Pixel Agents is a VS Code extension that visualizes multi-agent AI systems (currently Claude Code) as pixel art characters in a customizable office environment. Each agent becomes an animated character that reflects its real-time activity — typing when writing code, reading when searching files, and displaying speech bubbles when waiting for input.
Installation
From VS Code Marketplace
- Open VS Code
- Go to Extensions (Ctrl+Shift+X / Cmd+Shift+X)
- Search for "Pixel Agents"
- Click Install
Or install via command line:
code --install-extension pablodelucca.pixel-agents
From Source
git clone https://github.com/pablodelucca/pixel-agents.git
cd pixel-agents
npm install
cd webview-ui && npm install && cd ..
npm run build
Then press F5 in VS Code to launch the Extension Development Host.
Prerequisites
Key Features and Usage
Spawning Agents
Open the Pixel Agents panel (appears in bottom panel area alongside terminal):
Create normal agent:
Create agent with skip permissions:
Managing Characters
Assign character to a seat:
View agent status:
- Walking: Agent is navigating to desk/idle
- Typing: Writing code, creating files, making changes
- Reading: Searching files, analyzing code
- Speech bubble: Waiting for user input or permission
- Idle: No current activity
Office Layout Editor
Open editor:
Editor tools:
- Select (S): Select and move furniture
- Paint (P): Paint floor tiles
- Erase (E): Remove items
- Place (F): Add furniture
- Eyedropper (I): Pick colors/tiles
- Pick (K): Select furniture type
Keyboard shortcuts:
Ctrl+Z / Cmd+Z: Undo (50 levels)
Ctrl+Y / Cmd+Y: Redo
Delete: Remove selected item
- Arrow keys: Fine-tune placement
Expand grid:
Configuration
Access settings via gear icon in Pixel Agents panel:
Sound notifications:
Debug view:
Export/Import layouts:
Add external assets:
Working with Assets
Asset Structure
All assets are in webview-ui/public/assets/:
assets/
├── furniture/
│ ├── desk-01/
│ │ ├── manifest.json
│ │ └── sprite.png
│ └── chair-01/
│ ├── manifest.json
│ └── sprite.png
├── floors/
│ └── tile-wood.png
└── walls/
└── brick/
├── manifest.json
└── tileset.png
Creating Custom Furniture
Manifest structure:
{
"id": "desk-modern",
"name": "Modern Desk",
"category": "desks",
"width": 2,
"height": 1,
"isSeat": true,
"seatOffset": { "x": 0, "y": -16 },
"rotationGroups": [
{
"rotations": ["north", "east", "south", "west"],
"sprite": "desk-modern.png"
}
],
Add to project:
mkdir webview-ui/public/assets/furniture/desk-modern
npm run build
Using External Asset Directories
External manifest.json:
{
"id": "custom-plant",
"name": "Custom Plant",
"category": "decorations",
"width": 1,
"height": 1,
"isSeat": false,
"rotationGroups": [
{
"rotations": ["north"],
"sprite": "plant.png"
}
]
}
Code Examples
Monitoring Agent Activity (Extension Side)
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
function watchAgentTranscript(projectPath: string, agentId: string): vscode.Disposable {
const jsonlPath = path.join(
projectPath,
'.claude',
'projects',
agentId,
'transcript.jsonl'
);
let lastPosition = 0;
const interval = setInterval(() => {
if (!fs.existsSync(jsonlPath)) {
return;
}
const stats = fs.statSync(jsonlPath);
if (stats.size <= lastPosition) {
return;
}
const buffer = Buffer.alloc(stats.size - lastPosition);
const fd = fs.openSync(jsonlPath, 'r');
fs.readSync(fd, buffer, 0, buffer.length, lastPosition);
fs.(fd);
lines = buffer.().().( l.());
lines.( {
{
record = .(line);
(agentId, record);
} (err) {
.(, err);
}
});
lastPosition = stats.;
}, );
vscode.( (interval));
}
(): {
(record. === ) {
toolName = record.?.;
(toolName === || toolName === ) {
(agentId, );
} (toolName === || toolName === ) {
(agentId, );
} (toolName === ) {
(agentId, );
}
} (record. === ) {
(agentId, );
}
}
(): {
webviewPanel..({
: ,
agentId,
state
});
}
Character Animation (Webview Side)
interface Character {
id: string;
x: number;
y: number;
targetX: number;
targetY: number;
state: 'idle' | 'walking' | 'typing' | 'reading';
direction: 'north' | 'south' | 'east' | 'west';
frame: number;
spriteSheet: HTMLImageElement;
}
class CharacterRenderer {
private characters: Map<string, Character> = new Map();
private readonly TILE_SIZE = 16;
private readonly FRAME_RATE = 8;
private frameCounter = 0;
update(deltaTime: number): void {
this.frameCounter += deltaTime;
const frameInterval = / .;
..( {
(char. === ) {
dx = char. - char.;
dy = char. - char.;
distance = .(dx * dx + dy * dy);
(distance < ) {
char. = char.;
char. = char.;
char. = ;
} {
speed = ;
char. += (dx / distance) * speed;
char. += (dy / distance) * speed;
(.(dx) > .(dy)) {
char. = dx > ? : ;
} {
char. = dy > ? : ;
}
}
}
(. >= frameInterval) {
char. = (char. + ) % .(char.);
}
});
(. >= frameInterval) {
. = ;
}
}
(: ): {
..( {
spriteX = .(char);
spriteY = .(char);
ctx.(
char.,
spriteX, spriteY,
., . * ,
.(char.), .(char.),
., . *
);
});
}
(: ): {
char. * .;
}
(: ): {
directionOffsets = {
: ,
: ,
: ,
:
};
stateOffsets = {
: ,
: ,
: ,
:
};
(stateOffsets[char.] + directionOffsets[char.])
* . * ;
}
(: ): {
(state === ) ;
(state === || state === ) ;
;
}
(: , : , : ): {
char = ..(id);
(char) {
char. = targetX;
char. = targetY;
char. = ;
}
}
(: , : []): {
char = ..(id);
(char) {
char. = state;
char. = ;
}
}
}
Pathfinding (BFS for Agent Movement)
interface Point {
x: number;
y: number;
}
class Pathfinder {
private grid: boolean[][];
private width: number;
private height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
this.grid = Array(height).fill(null).map(() => Array(width).fill(true));
}
setObstacle(x: number, y: number, blocked: boolean): void {
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
this.[y][x] = !blocked;
}
}
(: , : ): [] | {
(!.(end., end.)) ;
: { : ; : [] }[] = [
{ : start, : [start] }
];
visited = <>();
visited.();
directions = [
{ : , : - },
{ : , : },
{ : , : },
{ : -, : }
];
(queue. > ) {
{ point, path } = queue.()!;
(point. === end. && point. === end.) {
path;
}
( dir directions) {
next = { : point. + dir., : point. + dir. };
key = ;
(
.(next., next.) &&
!visited.(key)
) {
visited.(key);
queue.({
: next,
: [...path, next]
});
}
}
}
;
}
(: , : ): {
(
x >= &&
x < . &&
y >= &&
y < . &&
.[y][x]
);
}
}
pathfinder = (, );
pathfinder.(, , );
pathfinder.(, , );
path = pathfinder.({ : , : }, { : , : });
(path) {
path.( {
( {
renderer.(, point. * , point. * );
}, index * );
});
}
Troubleshooting
Agent Not Appearing
Enable Debug View:
Check Debug Console:
Agent Stuck on Idle
Common causes:
-
JSONL file not found: Claude Code session hasn't created transcript yet
ls ~/.claude/projects/*/transcript.jsonl
-
Polling lag: Extension polls every 500ms, brief delays are normal
-
Unrecognized record type: Claude Code may emit new JSONL types
Agent-Terminal Desync
Symptoms:
- Character appears but terminal is closed
- Terminal exists but no character
- Multiple characters for one terminal
Fixes:
Speech Bubble Not Clearing
Heuristic-based detection limitations:
The extension uses idle timers to detect when agents wait for input. If speech bubble persists:
Linux/macOS Home Directory Confusion
If you launch VS Code without opening a folder:
code
~/.claude/projects/<home-directory-hash>/
Solution:
code /path/to/project
Common Patterns
Multi-Agent Workflow
Custom Office for Team Visualization
Sub-Agent Visualization
When Claude Code uses the task tool to spawn sub-agents:
External Asset Workflow
mkdir -p /my-assets/furniture/custom-furniture
cat > /my-assets/furniture/custom-furniture/manifest.json << 'EOF'
{
"id": "gaming-chair",
"name": "Gaming Chair",
"category": "seats",
"width": 1,
"height": 1,
"isSeat": true,
"seatOffset": { "x": 0, "y": -8 },
"rotationGroups": [
{
"rotations": ["north", "south", "east", "west"],
"sprite": "chair.png"
}
]
}
EOF
Extension Commands
Pixel Agents registers the following VS Code commands:
"pixelAgents.openPanel"
"pixelAgents.spawnAgent"
"pixelAgents.spawnAgentSkipPermissions"
"pixelAgents.openLayoutEditor"
"pixelAgents.openSettings"
"pixelAgents.toggleDebug"
Access via Command Palette (Ctrl+Shift+P / Cmd+Shift+P):
> Pixel Agents: Open Panel
> Pixel Agents: Spawn Agent
Performance Considerations
JSONL polling:
- Polls every 500ms per agent
- Minimal CPU impact for <10 agents
- For 10+ agents, consider increasing interval in source
Canvas rendering:
- 60 FPS target, degrades gracefully
- Tested up to 64×64 grid with 20 characters
- Use integer zoom levels for pixel-perfect rendering
Memory usage:
- ~5-10 MB per agent (JSONL tracking + character state)
- Asset cache: ~20-50 MB depending on furniture count
Future Roadmap
Pixel Agents is evolving toward a fully agent-agnostic, platform-agnostic interface:
- Agent-agnostic adapters: Support for Codex, Cursor, Copilot, Gemini
- Platform flexibility: Electron app, web app, beyond VS Code
- Advanced features:
- Desks as directories (drag agent to desk = assign to project)
- Kanban board for autonomous task picking
- Deep agent inspection (model, context, history, prompts)
- Token health bars (rate limits, context windows)
- 3D/VR office environments
See GitHub Discussions for ongoing architecture work.