AI Developer Toolkit
fusion-agent
Vibe coder, live debugger, autonomous agent, and session manager — in one
package. Supports OpenAI, Anthropic, and Google Gemini.
TypeScript
Node.js 18+
MIT License
OpenAI · Anthropic · Gemini
Modules
⚡
Vibe Coder
Chat with AI, auto-write files to disk in real time.
◎
Autonomous Agent
Give it a requirements file and walk away.
⊙
Live Debugger
Tail logs, AI analysis, dedup, Jira & GitHub.
⟐
Integrations
GitHub API, Jira, Copilot agent assignment.
Quick start
# Install globally
npm install -g fusion-agent
# Set an API key (pick any provider)
export OPENAI_API_KEY=sk-...
# Interactive vibe coder
ai-agent chat
# Live debugger on a Docker container
ai-agent debug --docker my-api --ui
# Web dashboard
ai-agent ui
Architecture
CLI ai-agent
Web UI ai-agent ui
↓
⚡ Vibe Coder
◎ Autonomous
⊙ Live Debugger
☸ Cluster Monitor
↓
▣ Session Manager
◈ AI Providers
⟐ Integrations
Getting Started
Install, configure an API key, and run your first session in under two minutes.
ℹ
Requirements: Node.js 18+, npm 9+, and an API key for at least one provider.
Installation
# Global CLI
npm install -g fusion-agent
# Project dependency
npm install fusion-agent
# From source
git clone https://github.com/fury-r/fusion-agent.git
cd fusion-agent
npm install && npm run build
Configuration
Set environment variables or create .fusion-agent.json in your project root.
# Pick at least one
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export GEMINI_API_KEY=AIza...
{
"provider": "openai",
"model": "gpt-4o",
"port": 3000,
"sessionDir": "~/.fusion-agent/sessions",
"github": {
"token": "ghp_...",
"repoUrl": "https://github.com/org/repo",
"autoAssignCopilot": false
}
}
Config search order
.fusion-agent.json — current working directory
.fusion-agent.yaml — current working directory
~/.fusion-agent/config.json
~/.fusion-agent/config.yaml
CLI flags and environment variables (AI_PROVIDER, AI_MODEL,
AI_AGENT_PORT) always override the config file.
Verify setup
ai-agent config --show # print resolved config
ai-agent chat # start interactive vibe coder
Vibe Coder
An AI pair-programmer that reads your project, generates code, and automatically writes files to
disk. Two modes: interactive chat and autonomous.
How file generation works
AI responds
→
Detect ```lang:path```
→
Guardrail check
→
Write to disk
→
Record in session
The AI must produce code blocks in this exact format for files to be written:
```typescript:src/middleware/auth.ts
// full corrected file content here
```
CLI flags
ai-agent chat [options]
-p, --provider <name> openai | anthropic | gemini
-m, --model <name> e.g. gpt-4o, claude-3-5-sonnet-20241022
-s, --session <name> create or resume a named session
-k, --speckit <name> agent persona (default: vibe-coder)
-g, --guardrail <rule> add a guardrail rule (repeatable)
--context inject project dir structure upfront
# Anthropic with guardrails + session resume
ai-agent chat \
--provider anthropic \
--model claude-3-5-sonnet-20241022 \
--session my-project \
--guardrail "Use TypeScript strict mode" \
--guardrail "No inline styles" \
--context
In-session commands
| Command |
Action |
| /exit |
End session and save to disk |
| /save |
Save without ending the session |
| /turns |
Show full conversation history |
| /context |
Inject current project directory tree |
Programmatic — session-based
import { AgentCLI, createGuardrail } from 'fusion-agent';
const agent = new AgentCLI({ provider: 'openai' });
const session = agent.createSession({
name: 'my-project',
speckit: 'vibe-coder',
projectDir: process.cwd(),
guardrails: [
createGuardrail('custom', 'Use TypeScript strict mode'),
createGuardrail('deny-paths', ['secrets/', '.env']),
],
});
// Streaming turn
const turn = await session.chat('Add JWT authentication middleware', {
stream: true,
onChunk: (chunk) => process.stdout.write(chunk),
});
console.log('Files written:', turn.fileChanges?.map(f => f.filePath));
// Revert all changes from this turn
session.revertTurnChanges(turn.id);
// Persist session
agent.sessionManager.persistSession(session);
Autonomous Agent
Reads a requirements file, implements it step-by-step by writing files to disk, detects loops, and
requests human guidance via a Human-in-the-Loop (HIL) modal when stuck.
Execution flow
Read requirements
→
Plan steps
→
Implement step N
→
Write files
→
Loop detect?
→
COMPLETE
ℹ
The agent stops when it outputs REQUIREMENTS_COMPLETE, hits the step/time limit,
or you stop it manually.
Programmatic usage
import { AgentCLI, AutonomousVibeAgent } from 'fusion-agent';
const agent = new AgentCLI({ provider: 'openai' });
const session = agent.createSession({
name: 'auto-build',
speckit: 'vibe-coder',
projectDir: process.cwd(),
});
const auto = new AutonomousVibeAgent(session, {
requirementsFile: './REQUIREMENTS.md',
maxSteps: 50,
timeLimitSeconds: 600,
rules: [
{ id: 'ts', description: 'All files must be TypeScript' },
{ id: 'no-class', description: 'Use functional patterns, no classes' },
],
});
auto.on('step', (step) => console.log(`Step ${step.stepNumber}`, step.filesChanged));
auto.on('complete', (steps) => { console.log(`✓ Done in ${steps.length} steps`); });
auto.on('hil', (req) => console.log('HIL:', req.confusionSummary));
auto.on('error', (err) => console.error(err.message));
await auto.run();
Inline requirements
const auto = new AutonomousVibeAgent(session, {
requirementsContent: `
## Build a REST API
- Express server on port 3000
- GET /users returns list of users
- POST /users creates a user
- Use TypeScript, Zod for validation
`,
maxSteps: 20,
});
Configuration
| Option |
Type |
Description |
| requirementsFile |
string |
Path to .md or .txt file |
| requirementsContent |
string |
Inline requirements text |
| rules |
Rule[] |
Constraints injected into every step |
| timeLimitSeconds |
number |
0 = no time limit |
| maxSteps |
number |
Default: 50 |
| stuckThreshold |
number |
No-file-change steps before HIL fires |
| loopSimilarityThreshold |
number |
Jaccard similarity ≥ N triggers loop (0–1) |
Live Debugger
Tails log sources (files, Docker containers, spawned processes), batches lines, calls AI for
analysis, deduplicates repeated errors, and streams results to the Web UI via Socket.IO. Three
post-analysis actions: Create Jira Issue, Apply Git Fix,
Assign to Copilot.
Pipeline
Log source
→
Level filter
→
Batch buffer
→
Deduplicate
→
AI analysis
→
Web UI + Notify
Log sources
| Source |
Flag |
Example |
| File tail |
--file |
--file /var/log/app.log |
| Docker container |
--docker |
--docker my-api-container |
| Spawned process |
--cmd |
--cmd "node server.js" |
| HTTP poll |
programmatic |
connectToService({ type: 'http', url, intervalMs }) |
File log
# Tail a log file, notify Slack on error
ai-agent debug \
--file /var/log/api.log \
--log-level ERROR,FATAL \
--batch 20 \
--notify-slack https://hooks.slack.com/services/XXX/YYY/ZZZ \
--ui --port 3000
Docker container
# Attach to a running Docker container by name or ID
ai-agent debug \
--docker my-api \
--log-level ERROR,WARN \
--batch 15 \
--session my-api-prod \
--ui --port 3000
# Multiple containers — start separate debuggers
ai-agent debug --docker api-service --port 3000 &
ai-agent debug --docker worker-service --port 3001 &
ℹ
The Docker connector runs docker logs -f <container> internally. The Docker
CLI must be available in PATH and the container must be running.
Spawned process
# Spawn a command and capture its stdout + stderr
ai-agent debug --cmd "node dist/server.js"
All CLI flags
ai-agent debug [options]
-f, --file <path> watch a log file
-d, --docker <name> attach to Docker stdout/stderr
-c, --cmd <command> spawn a process and capture output
-p, --provider <name> openai | anthropic | gemini
-m, --model <name> model name override
-s, --session <name> named session (saved to disk)
--log-level <lvls> comma-separated: ERROR,FATAL,WARN,INFO
--batch <n> lines per AI call (default: 20)
--retry <n> max retries per AI call (default: 3)
--notify-slack <url> Slack incoming webhook URL
--notify-teams <url> Microsoft Teams webhook URL
--ui launch web dashboard
--port <port> dashboard port (default: 3000)
Log level filtering
Only lines that contain at least one of the specified level tokens are forwarded to
the AI. Matching is case-insensitive.
# Only send ERROR and FATAL lines for AI analysis
ai-agent debug --docker my-api --log-level ERROR,FATAL
# Include warnings too
ai-agent debug --docker my-api --log-level ERROR,FATAL,WARN
ℹ
Omitting --log-level passes all lines to the AI (no filter).
Notifications
| Channel |
CLI flag |
Programmatic key |
| Slack |
--notify-slack <webhook-url> |
notifications.slack.webhookUrl |
| Microsoft Teams |
--notify-teams <webhook-url> |
notifications.teams.webhookUrl |
Each notification includes the full AI analysis text and a link to the Web UI dashboard.
Programmatic usage
import { AgentCLI, LiveDebugger } from 'fusion-agent';
const agent = new AgentCLI({ provider: 'openai' });
const session = agent.createSession({ name: 'prod', speckit: 'debugger' });
const dbg = new LiveDebugger({
session,
batchSize: 15,
maxWaitSeconds: 30,
logLevels: ['ERROR', 'FATAL'],
notifications: {
slack: { enabled: true, webhookUrl: process.env.SLACK_WEBHOOK },
teams: { enabled: true, webhookUrl: process.env.TEAMS_WEBHOOK },
},
onAnalysis: (analysis, meta) => {
console.log('Analysis:', analysis);
console.log('Repeats:', meta?.repeatCount);
console.log('Fingerprint:', meta?.errorFingerprint);
},
});
dbg.on('error', (err) => console.error(err.message));
// Pick one source:
dbg.watchLogFile('/var/log/app.log', 50);
// dbg.connectToService({ type: 'docker', container: 'my-api' });
// dbg.connectToService({ type: 'process', command: 'node server.js' });
// dbg.connectToService({ type: 'http', url: 'http://...', intervalMs: 5000 });
process.on('SIGINT', () => dbg.stop());
Web UI — analysis cards
Each AI analysis appears as a card in the Live Debugger panel. Every card has three action buttons:
Analysis card
→
Create Jira Issue
|
Apply Git Fix
|
Assign to Copilot
Create Jira Issue
Opens a modal pre-populated with the AI analysis. Required fields:
| Field |
Required |
Notes |
| Jira base URL |
✓ |
https://your-org.atlassian.net |
| Email |
✓ |
Atlassian account email |
| API token |
✓ |
Generate at id.atlassian.com |
| Project key |
✓ |
e.g. ENG, OPS, PLAT |
| Issue type |
✓ |
Bug · Task · Story · Incident |
| Priority |
— |
Highest · High · Medium · Low |
| Labels |
— |
comma-separated: auto-detected,live-debugger |
ℹ
Jira credentials are sent to the backend in the POST body and are never stored to disk.
Configure them in .fusion-agent.json to have the modal pre-filled on load.
Apply Git Fix — 3-step wizard
AI generates corrected file contents; the wizard lets you review before committing.
Step 1 — Preview diffs
→
Step 2 — Review & confirm
→
Step 3 — Commit to GitHub API
| Config field |
Required |
Description |
| GitHub token |
✓ |
PAT with repo scope |
| Remote URL |
✓ |
https://github.com/org/repo |
| Branch |
— |
Default: fusion-agent/auto-fix |
| Commit message |
— |
Auto-generated from AI analysis summary |
| Base branch |
— |
Default: main |
⚠
The Apply Git Fix button is disabled (greyed out) when
autoAssignCopilot: true in config — to avoid competing pull requests with the
Copilot-assigned issue.
Assign to Copilot
Creates a GitHub issue and assigns the Copilot coding agent to it. The issue body is
the full AI analysis.
| Config field |
Required |
Description |
| GitHub token |
✓ |
PAT with issues:write scope |
| Repo URL |
✓ |
https://github.com/org/repo |
| autoAssignCopilot |
— |
Set true to enable the button; disables Apply Git Fix |
✓
After assignment the analysis card shows a Copilot Blocked badge — a visual
reminder that Git Fix is disabled while Copilot is working on the issue.
Events
| Event |
Payload |
Description |
| log |
(line: string) |
Raw log line received |
| analysis |
(text, meta) |
AI analysis complete |
| analysis-chunk |
(chunk) |
Streaming token |
| error |
(err) |
Error — debugger keeps running |
| exit |
(code) |
Watched process exited (process source only) |
Session Manager
Sessions persist conversation history, file changes, and debugger metadata to disk. They can be
resumed, exported, and deleted.
Programmatic
import { AgentCLI } from 'fusion-agent';
const agent = new AgentCLI({ provider: 'openai' });
const sm = agent.sessionManager;
// Create + chat
const session = agent.createSession({ name: 'my-project' });
await session.chat('Hello');
sm.persistSession(session);
// List all sessions
const all = sm.listSessions(); // SessionMeta[]
// Resume an existing session
const loaded = sm.loadSession(all[0].id);
loaded.getTurns().forEach(t => console.log(t.userMessage));
// Export to JSON string
const json = sm.exportSession(all[0].id);
// Delete
sm.deleteSession(all[0].id);
Turn shape
interface SessionTurn {
id: string;
timestamp: string; // ISO 8601
userMessage: string;
assistantMessage: string;
fileChanges?: {
filePath: string;
previousContent: string | null; // null = new file
newContent: string;
}[];
usage?: {
promptTokens: number;
completionTokens: number;
totalTokens: number;
};
debuggerMeta?: {
matchedLogLines: string[];
promptSentAt: string;
repeatCount: number;
errorFingerprint: string;
};
}
REST API
| Method |
Path |
Description |
| GET |
/api/sessions |
List all sessions |
| GET |
/api/sessions/:id |
Get session with all turns |
| POST |
/api/sessions |
Create a new session |
| DELETE |
/api/sessions/:id |
Delete one session |
| DELETE |
/api/sessions |
Delete all sessions |
| GET |
/api/sessions/:id/export |
Export session as JSON |
AI Providers
fusion-agent supports three AI providers. Switch per session or globally in config.
🟢
OpenAI
gpt-4o · gpt-4o-mini
gpt-4-turbo · o1-mini
export OPENAI_API_KEY=sk-...
🟠
Anthropic
claude-3-5-sonnet-20241022
claude-3-haiku-20240307
export ANTHROPIC_API_KEY=sk-ant-...
🔵
Google Gemini
gemini-1.5-pro · gemini-1.5-flash
gemini-2.0-flash
export GEMINI_API_KEY=AIza...
Switching provider
const agent = new AgentCLI({
provider: 'anthropic',
model: 'claude-3-5-sonnet-20241022',
apiKey: process.env.ANTHROPIC_API_KEY,
});
Streaming
const turn = await session.chat('Refactor this file', {
stream: true,
onChunk: (chunk) => process.stdout.write(chunk),
});
Integrations
fusion-agent ships built-in integrations for GitHub (direct API commits + Copilot agent assignment)
and Jira. Configure in .fusion-agent.json or pass programmatically.
GitHub — direct API commits
Commits AI-proposed fixes directly to GitHub via the Git Data API. No local clone required.
import { GitHubPatcher } from 'fusion-agent';
const patcher = new GitHubPatcher({
token: process.env.GITHUB_TOKEN,
remoteUrl: 'https://github.com/org/my-repo',
branch: 'fusion-agent/auto-fix',
});
const result = await patcher.applyAndCommit({
files: {
'src/services/user.ts': newContent,
'src/utils/auth.ts': otherContent,
},
commitMessage: 'fix: resolve null-pointer in UserService',
pullRequestTitle: 'Auto-fix from Live Debugger',
baseBranch: 'main',
});
console.log('Branch:', result.branch);
console.log('Commit:', result.commitSha);
console.log('PR URL:', result.pullRequestUrl);
| Field |
Required |
Description |
| token |
✓ |
GitHub PAT with repo scope |
| remoteUrl |
✓ |
https://github.com/owner/repo |
| branch |
— |
Target branch (default: fusion-agent/auto-fix) |
| baseBranch |
— |
Branch to open PR against (default: main) |
| pullRequestTitle |
— |
If set, a PR is opened automatically |
GitHub — local clone commit
Applies patches using the local filesystem and Git CLI. Requires a checked-out repo and Git in PATH.
import { GitPatchApplier } from 'fusion-agent';
const applier = new GitPatchApplier({
repoDir: process.cwd(),
branch: 'fusion-agent/auto-fix',
remote: 'origin',
pushAfterCommit: true,
});
await applier.applyAndCommit({
files: { 'src/utils/auth.ts': newContent },
commitMessage: 'fix: auth token expiry bug',
});
Jira
import { JiraClient } from 'fusion-agent';
const jira = new JiraClient({
baseUrl: 'https://your-org.atlassian.net',
email: 'you@example.com',
apiToken: process.env.JIRA_TOKEN,
projectKey: 'ENG',
issueType: 'Bug',
});
const issue = await jira.createIssue({
summary: 'NullPointerException in UserService.getById',
description: aiAnalysisText,
priority: 'High',
labels: ['auto-detected', 'live-debugger'],
});
console.log('Created:', issue.key, issue.url);
To pre-configure Jira in your config file (so the Web UI modal is pre-filled):
{
"jira": {
"baseUrl": "https://your-org.atlassian.net",
"email": "you@example.com",
"apiToken": "<jira-api-token>",
"projectKey": "ENG",
"issueType": "Bug"
}
}
GitHub Copilot Agent
Creates a GitHub issue and assigns @copilot as the assignee. The issue body is the
full AI analysis text from the debugger.
import { GitHubClient } from 'fusion-agent';
const gh = new GitHubClient({
token: process.env.GITHUB_TOKEN,
repoUrl: 'https://github.com/org/my-repo',
});
const result = await gh.createIssueForCopilot(
'[Auto] Fix NullPointerException in UserService',
aiAnalysisText,
['bug', 'auto-detected'],
);
console.log('Issue #' + result.issueNumber, result.issueUrl);
console.log('Copilot assigned:', result.copilotAssigned);
Enable auto-assignment in config to activate the Assign to Copilot button in the Web
UI:
{
"github": {
"token": "ghp_...",
"repoUrl": "https://github.com/org/repo",
"autoAssignCopilot": true
}
}
⚠
When autoAssignCopilot is true, the Apply Git Fix
button on every analysis card is disabled with a Copilot Blocked badge — to avoid
competing pull requests.
Guardrail rules to control what Copilot issues are allowed:
| Rule |
Effect |
| deny-keyword:password |
Block if issue title or body contains the word |
| require-label:bug |
Issue must include the bug label |
| max-title-length:120 |
Title must be ≤ 120 characters |
| max-body-length:5000 |
Body must be ≤ 5000 characters |
Guardrails
Safety rules that gate file writes, git commits, and issue creation. Evaluated before every
irreversible action.
File and git rules
| Rule format |
Effect |
| allow-path:src/ |
Only files under src/ may be modified |
| deny-path:secrets/ |
Files under secrets/ are never touched |
| max-files:5 |
At most 5 files per commit/turn |
| Any other string |
Injected as an AI constraint in the system prompt |
Copilot issue rules
| Rule format |
Effect |
| deny-keyword:password |
Block if title or body contains the word |
| require-label:bug |
Issue must include the bug label |
| max-title-length:120 |
Title must be ≤ 120 chars |
| max-body-length:5000 |
Body must be ≤ 5000 chars |
Adding guardrails
ai-agent chat \
--guardrail "deny-path:secrets/" \
--guardrail "max-files:5" \
--guardrail "Use TypeScript strict mode"
import { createGuardrail } from 'fusion-agent';
const session = agent.createSession({
guardrails: [
createGuardrail('custom', 'Use TypeScript strict mode'),
createGuardrail('deny-paths', ['secrets/', '.env', '*.pem']),
createGuardrail('max-files', 5),
],
});
✓
Guardrail violations throw an error with a human-readable message explaining which rule was
broken and why.
Speckits
Prebuilt agent personas — a name, description, system prompt, and example prompts. Set when creating
a session; they shape the AI's behaviour for the entire conversation.
Built-in speckits
| Name |
Best for |
Example prompt |
| vibe-coder |
Coding, file generation, refactoring |
"Add JWT auth middleware" |
| debugger |
Log analysis, root cause, code fixes |
"Why is my service OOMKilled?" |
| code-review |
PR review, security, performance |
"Review this route for SQL injection" |
| cluster-debugger |
Kubernetes / multi-service remediation |
"CrashLoopBackOff in payments pod" |
Using a speckit
ai-agent chat --speckit debugger
const session = agent.createSession({ speckit: 'code-review' });
Custom speckits
import { registerSpeckit } from 'fusion-agent';
registerSpeckit({
name: 'security-auditor',
description: 'Reviews code for OWASP Top 10 vulnerabilities',
systemPrompt: `You are a security expert specialising in web application security.
When reviewing code:
1. Check for injection vulnerabilities (SQL, XSS, SSTI)
2. Verify authentication and authorisation
3. Look for insecure direct object references
For every vulnerability, provide:
- Severity: Critical / High / Medium / Low
- CWE reference
- Minimal PoC exploit
- Exact fix with \`\`\`language:filepath\`\`\` blocks`,
examples: [
'Review this Express route for SQL injection',
'Is this JWT verification correct?',
],
});
REST API
The Web UI server (ai-agent ui) exposes a REST API and Socket.IO. Base:
http://localhost:3000.
Sessions
| Method |
Path |
Description |
| GET |
/api/sessions |
List all sessions |
| GET |
/api/sessions/:id |
Full session with turns |
| POST |
/api/sessions |
Create session — body: { name, speckit?, provider? } |
| DELETE |
/api/sessions/:id |
Delete one session |
| DELETE |
/api/sessions |
Delete all sessions |
| GET |
/api/sessions/:id/export |
Full JSON export |
Live Debugger
| Method |
Path |
Description |
| POST |
/api/debugger/:id/jira |
Create Jira issue from turn |
| POST |
/api/debugger/:id/git-fix |
Apply AI fix to GitHub |
| POST |
/api/debugger/:id/preview-git-fix |
Preview file diffs before applying |
| POST |
/api/debugger/:id/copilot-issue |
Create + assign Copilot issue |
Socket.IO events
| Event |
Direction |
Key fields |
| debugger:subscribe |
Client → Server |
{ sessionId } |
| debugger:log |
Server → Client |
{ sessionId, line } |
| debugger:analysis |
Server → Client |
{ sessionId, analysis, meta } |
| debugger:error-repeated |
Server → Client |
{ turnId, repeatCount, lastSeen } |
| vibe:chat |
Client → Server |
{ sessionId, message } |
| vibe:chunk |
Server → Client |
{ sessionId, chunk } |
| vibe:file-changed |
Server → Client |
{ sessionId, filePath, content } |
Example: preview git fix
const res = await fetch(`/api/debugger/${sessionId}/preview-git-fix`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ turnId: 'turn-abc123' }),
});
// { changes: [{ filePath, before, after }] }
const { changes } = await res.json();
changes.forEach(c =>
console.log(c.filePath, c.before === null ? 'NEW' : 'MODIFIED')
);
Cluster Monitor
Watches a Kubernetes cluster (or a plain set of Docker services) for rule violations, calls the AI to
diagnose problems, and optionally applies automatic remediation.
Modes
| Mode |
Description |
| monitor |
Watch only — logs violations, sends notifications |
| diagnose |
Watch + AI diagnosis on each violation |
| remediate |
Watch + diagnose + auto-apply fixes (restart pod, scale, etc.) |
CLI
# Watch cluster with rules file, auto-remediate
ai-agent cluster \
--rules ./cluster-debug-rules.yaml \
--mode remediate \
--namespace production \
--notify-slack https://hooks.slack.com/services/XXX/YYY/ZZZ \
--ui --port 3000
ai-agent cluster [options]
--rules <path> YAML rules file (default: ./cluster-debug-rules.yaml)
--mode <mode> monitor | diagnose | remediate
--namespace <ns> Kubernetes namespace (default: default)
--interval <secs> poll interval seconds (default: 30)
--notify-slack <url> Slack webhook for alerts
--notify-teams <url> Teams webhook for alerts
--ui open web dashboard
--port <port> dashboard port (default: 3000)
Rules file
rules:
- id: crash-loop
description: Detect CrashLoopBackOff pods
condition: pod.status == "CrashLoopBackOff"
severity: critical
actions:
- type: restart-pod
- type: notify
- type: ai-diagnose
- id: high-cpu
description: Pod CPU usage above 90%
condition: pod.cpu > 90
severity: warning
actions:
- type: scale-up
replicas: 2
- type: notify
- id: oom-killed
description: OOMKilled containers
condition: pod.status == "OOMKilled"
severity: critical
actions:
- type: ai-diagnose
- type: notify
Action types
| Type |
Description |
| restart-pod |
Delete the pod so Kubernetes restarts it |
| scale-up |
Increase deployment replicas |
| scale-down |
Decrease deployment replicas |
| notify |
Send Slack/Teams notification |
| ai-diagnose |
Call AI provider for root-cause analysis |
Programmatic
import { ClusterMonitor } from 'fusion-agent';
const monitor = new ClusterMonitor({
mode: 'remediate',
namespace: 'production',
rulesFile: './cluster-debug-rules.yaml',
intervalMs: 30_000,
notifications: {
slack: { enabled: true, webhookUrl: process.env.SLACK_WEBHOOK },
},
});
monitor.on('violation', (v) => console.log('Rule violated:', v.ruleId, v.podName));
monitor.on('remediation', (r) => console.log('Action taken:', r.action, r.outcome));
monitor.on('analysis', (a) => console.log('AI diagnosis:', a.text));
await monitor.start();
process.on('SIGINT', () => monitor.stop());
Skills Registry
Skills are named, reusable prompt fragments injected into the AI system prompt at session creation.
Unlike speckits (full personas), skills are composable — combine multiple per session.
Registering a skill
import { registerSkill, getSkill, listSkills } from 'fusion-agent';
registerSkill({
name: 'typescript-strict',
description: 'Enforce TypeScript strict mode patterns',
prompt: `Always use TypeScript strict mode.
- Avoid \`any\` type; use \`unknown\` + type guards
- Prefer \`const\` over \`let\`
- Use \`readonly\` on all interface properties`,
});
// Attach skills to a session
const session = agent.createSession({
speckit: 'vibe-coder',
skills: ['typescript-strict', 'prefer-zod'],
});
console.log(listSkills()); // all registered skill names
console.log(getSkill('typescript-strict').prompt);
ℹ
Skills are injected after the speckit system prompt. A speckit's persona instructions always
take precedence over skill fragments.
Cron Scheduler
Schedule recurring AI tasks using standard cron expressions. Each job runs in its own session;
results are available via REST or Socket.IO.
CLI
# Add a recurring job (9 AM Mon–Fri)
ai-agent cron add \
--name daily-review \
--cron "0 9 * * 1-5" \
--message "Review pull requests opened yesterday and summarise" \
--speckit code-review
ai-agent cron list # list all jobs
ai-agent cron remove --name daily-review # remove a job
ai-agent cron run --name daily-review # run immediately
Programmatic
import { CronManager } from 'fusion-agent';
const cron = new CronManager(agent);
cron.addJob({
name: 'daily-review',
expression: '0 9 * * 1-5',
message: 'Review open PRs and summarise',
speckit: 'code-review',
});
cron.on('job:start', (name) => console.log(`Job started: ${name}`));
cron.on('job:complete', (name, turn) => console.log(turn.assistantMessage));
cron.on('job:error', (name, err) => console.error(err.message));
cron.start();
console.log(cron.listJobs());
cron.removeJob('daily-review');
REST API
| Method |
Path |
Description |
| GET |
/api/cron |
List all jobs |
| POST |
/api/cron |
Add a job — body: { name, expression, message, speckit? } |
| DELETE |
/api/cron/:name |
Remove a job |
| POST |
/api/cron/:name/run |
Run job immediately |
Webhooks
Register external webhook URLs that fusion-agent calls when key events occur (analysis ready, job
complete, violation detected).
Registering webhooks
import { WebhookStore } from 'fusion-agent';
const store = new WebhookStore();
store.register({
id: 'my-hook',
url: 'https://my-service.example.com/hooks/agent',
events: ['debugger:analysis', 'cluster:violation'],
secret: process.env.WEBHOOK_SECRET, // HMAC-SHA256 signing
});
console.log(store.list());
store.unregister('my-hook');
Event types
| Event |
Key payload fields |
| debugger:analysis |
sessionId, analysis, meta (repeatCount, fingerprint) |
| debugger:error-repeated |
sessionId, turnId, repeatCount, lastSeen |
| cluster:violation |
ruleId, podName, namespace, severity |
| cluster:remediation |
ruleId, action, outcome |
| cron:complete |
jobName, sessionId, turnId |
| vibe:file-changed |
sessionId, filePath, content |
ℹ
If secret is set, every POST includes an X-Fusion-Signature header —
an HMAC-SHA256 hex digest of the body. Verify it on your server before trusting the payload.
REST API
| Method |
Path |
Description |
| GET |
/api/webhooks |
List registered webhooks |
| POST |
/api/webhooks |
Register — body: { id, url, events, secret? } |
| DELETE |
/api/webhooks/:id |
Unregister |
Browser Control & Agent Bus
Browser Controller
Drives a headless Chromium browser (via Playwright) from the AI. The agent can emit browser action
blocks; fusion-agent executes them and returns the result.
ℹ
Requires @playwright/test. Run npx playwright install chromium once
before first use.
AI action block format
<browser-action type="navigate" url="https://example.com" />
<browser-action type="click" selector="#login-btn" />
<browser-action type="fill" selector="#email" value="user@example.com" />
<browser-action type="fill" selector="#password" value="secret" />
<browser-action type="click" selector="button[type=submit]" />
<browser-action type="screenshot" />
Programmatic usage
import { BrowserController } from 'fusion-agent';
const browser = new BrowserController({ headless: true });
await browser.launch();
await browser.navigate('https://example.com');
await browser.click('#login-btn');
await browser.fill('#email', 'user@example.com');
const screenshot = await browser.screenshot(); // base64 PNG
const html = await browser.getPageSource();
await browser.close();
Agent Bus
An in-process publish/subscribe bus that lets multiple agent sessions communicate — useful for
multi-agent workflows where one agent triggers another.
import { AgentBus } from 'fusion-agent';
const bus = new AgentBus();
// Agent A publishes
bus.publish('review-done', {
sessionId: 'review-123',
summary: 'Found 2 high severity issues',
files: ['src/auth.ts'],
});
// Agent B subscribes and reacts
bus.subscribe('review-done', async (payload) => {
await fixerAgent.chat(`Fix issues in ${payload.files.join(', ')}`);
});
// Unsubscribe: call the returned function
const unsub = bus.subscribe('review-done', handler);
unsub();
Docker Deployment Examples
Two ready-made Docker Compose setups ship in deploy/: a self-fix debugger and a Copilot
auto-assign monitor.
Self-Fix Debugger
Watches a Docker container, generates AI fixes, and commits them as a GitHub PR automatically.
Docker logs
→
AI analysis
→
Generate fix
→
GitHub PR
# 1. Copy and fill in the config
cp deploy/live-debugger-selffix/config.example.json config.json
# 2. Edit config.json — set provider, GitHub token, repo URL
# 3. Start
cd deploy/live-debugger-selffix
docker compose up -d
{
"provider": "openai",
"model": "gpt-4o",
"container": "my-api",
"logLevels": ["ERROR", "FATAL"],
"github": {
"token": "ghp_...",
"repoUrl": "https://github.com/org/repo",
"branch": "fusion-agent/auto-fix",
"baseBranch": "main"
},
"notifications": {
"slack": { "enabled": true, "webhookUrl": "https://hooks.slack.com/..." }
}
}
Copilot Auto-Assign
Creates a GitHub issue and assigns Copilot instead of opening a PR directly. Apply Git
Fix is blocked in the Web UI when this mode is active.
Docker logs
→
AI analysis
→
Create issue
→
Copilot assigned
cp deploy/live-debugger-copilot-autoassign/config.example.json config.json
# Set autoAssignCopilot: true, fill in github token + repoUrl
cd deploy/live-debugger-copilot-autoassign
docker compose up -d
{
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"container": "my-api",
"logLevels": ["ERROR", "FATAL"],
"github": {
"token": "ghp_...",
"repoUrl": "https://github.com/org/repo",
"autoAssignCopilot": true
}
}
Environment variables
| Variable |
Config key |
| AI_PROVIDER |
provider |
| AI_MODEL |
model |
| OPENAI_API_KEY |
apiKey (OpenAI) |
| ANTHROPIC_API_KEY |
apiKey (Anthropic) |
| GEMINI_API_KEY |
apiKey (Gemini) |
| GITHUB_TOKEN |
github.token |
| GITHUB_REPO_URL |
github.repoUrl |
| JIRA_TOKEN |
jira.apiToken |
| SLACK_WEBHOOK |
notifications.slack.webhookUrl |
| TEAMS_WEBHOOK |
notifications.teams.webhookUrl |
| AI_AGENT_PORT |
port |