@swarmai/local-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/index.js +11 -0
- package/package.json +42 -0
- package/src/agenticChatClaudeMd.js +92 -0
- package/src/agenticChatHandler.js +566 -0
- package/src/aiProviderScanner.js +115 -0
- package/src/auth.js +180 -0
- package/src/cli.js +334 -0
- package/src/commands.js +1853 -0
- package/src/config.js +98 -0
- package/src/connection.js +470 -0
- package/src/mcpManager.js +276 -0
- package/src/startup.js +297 -0
- package/src/toolScanner.js +221 -0
- package/src/workspace.js +201 -0
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# SwarmAI Local Agent
|
|
2
|
+
|
|
3
|
+
CLI agent that runs on your computer (Windows/Mac/Linux) and connects to a SwarmAI server, giving the agentic AI direct access to your device — shell commands, file system, screenshots, clipboard, MCP tools, and CLI AI sessions.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Local Agent CLI → WebSocket (wss://{server}/local-agent) → SwarmAI Backend
|
|
9
|
+
├── systemInfo (OS, CPU, RAM, disk)
|
|
10
|
+
├── screenshot (desktop capture → upload)
|
|
11
|
+
├── shell (execute commands, streaming output)
|
|
12
|
+
├── fileRead / fileList (browse & read files)
|
|
13
|
+
├── fileTransfer (upload/download files)
|
|
14
|
+
├── clipboard (read/write system clipboard)
|
|
15
|
+
├── capture (camera/microphone, opt-in only)
|
|
16
|
+
├── cliSession (claude/gemini/opencode CLI)
|
|
17
|
+
├── mcp (MCP server tool execution)
|
|
18
|
+
├── aiChat (proxy to local Ollama/LM Studio)
|
|
19
|
+
└── kill (terminate running command)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
### Prerequisites
|
|
25
|
+
- Node.js 16+
|
|
26
|
+
|
|
27
|
+
### Install & Login
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd local-agent
|
|
31
|
+
npm install
|
|
32
|
+
|
|
33
|
+
# Authenticate with SwarmAI server (opens browser for OAuth)
|
|
34
|
+
node index.js login --api https://agents.northpeak.app --name "My Laptop"
|
|
35
|
+
|
|
36
|
+
# Start the agent
|
|
37
|
+
node index.js start
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Global Install (optional)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g .
|
|
44
|
+
swarmai-agent login --api https://agents.northpeak.app
|
|
45
|
+
swarmai-agent start
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## CLI Commands
|
|
49
|
+
|
|
50
|
+
| Command | Description |
|
|
51
|
+
|---------|-------------|
|
|
52
|
+
| `login` | Authenticate this device with SwarmAI server |
|
|
53
|
+
| `start` | Connect and begin listening for commands |
|
|
54
|
+
| `startup enable` | Auto-start on system boot |
|
|
55
|
+
| `startup disable` | Remove auto-start |
|
|
56
|
+
| `startup status` | Check auto-start status |
|
|
57
|
+
| `status` | Show connection status |
|
|
58
|
+
|
|
59
|
+
### Login Options
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
swarmai-agent login \
|
|
63
|
+
--api <url> # Server URL (default: https://agents.northpeak.app)
|
|
64
|
+
--name <name> # Device name (default: hostname)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Device Commands (AI Tools)
|
|
68
|
+
|
|
69
|
+
When connected, the SwarmAI agentic AI can execute these commands on your device:
|
|
70
|
+
|
|
71
|
+
| Command | Description | Security |
|
|
72
|
+
|---------|-------------|----------|
|
|
73
|
+
| `systemInfo` | OS, CPU, RAM, disk, network info | Always allowed |
|
|
74
|
+
| `notification` | Show desktop notification | Always allowed |
|
|
75
|
+
| `screenshot` | Capture desktop screenshot | Always allowed |
|
|
76
|
+
| `shell` | Execute shell commands (streaming) | Blocklist filtered |
|
|
77
|
+
| `fileRead` | Read file contents | Path-restricted (configurable) |
|
|
78
|
+
| `fileList` | List directory contents | Path-restricted (configurable) |
|
|
79
|
+
| `fileTransfer` | Upload/download files to/from server | Always allowed |
|
|
80
|
+
| `clipboard` | Read/write system clipboard | Requires approval |
|
|
81
|
+
| `capture` | Camera/microphone access | Opt-in only (`allowCapture`) |
|
|
82
|
+
| `cliSession` | Run Claude/Gemini/OpenCode CLI | Requires approval |
|
|
83
|
+
| `mcp` | Execute MCP server tools | Always allowed |
|
|
84
|
+
| `aiChat` | Chat with local AI (Ollama, LM Studio) | Always allowed |
|
|
85
|
+
| `kill` | Terminate a running command | Always allowed |
|
|
86
|
+
|
|
87
|
+
## MCP Server Integration
|
|
88
|
+
|
|
89
|
+
The agent can spawn and manage local MCP servers. Built-in recipes:
|
|
90
|
+
|
|
91
|
+
| Recipe | Description |
|
|
92
|
+
|--------|-------------|
|
|
93
|
+
| `playwright` | Browser automation via Playwright |
|
|
94
|
+
| `filesystem` | Local filesystem access |
|
|
95
|
+
| `sqlite` | SQLite database operations |
|
|
96
|
+
| `git` | Git repository operations |
|
|
97
|
+
| `docker` | Docker container management |
|
|
98
|
+
|
|
99
|
+
Custom MCP servers can be configured via the SwarmAI dashboard.
|
|
100
|
+
|
|
101
|
+
## Security
|
|
102
|
+
|
|
103
|
+
### Configuration
|
|
104
|
+
|
|
105
|
+
Security settings in `~/.swarmai/config.json`:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"security": {
|
|
110
|
+
"shellBlocklist": [],
|
|
111
|
+
"fileRootPaths": [],
|
|
112
|
+
"requireApprovalFor": ["cliSession", "clipboard"],
|
|
113
|
+
"allowCapture": false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Setting | Default | Description |
|
|
119
|
+
|---------|---------|-------------|
|
|
120
|
+
| `shellBlocklist` | `[]` | Additional blocked shell patterns (on top of built-in: `rm -rf /`, `format`, `mkfs`, etc.) |
|
|
121
|
+
| `fileRootPaths` | `[]` | Restrict file access to these paths. Empty = allow all. |
|
|
122
|
+
| `requireApprovalFor` | `["cliSession", "clipboard"]` | Commands that are blocked unless user opts in |
|
|
123
|
+
| `allowCapture` | `false` | Camera/mic access (must explicitly enable) |
|
|
124
|
+
|
|
125
|
+
### Workspace
|
|
126
|
+
|
|
127
|
+
The agent manages a local workspace for file operations:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
~/SwarmAI/ (Linux/Mac)
|
|
131
|
+
C:/SwarmAI/ (Windows)
|
|
132
|
+
├── temp/ # Temporary files (auto-cleanup: 24h)
|
|
133
|
+
├── downloads/ # Downloaded files (auto-cleanup: 7d)
|
|
134
|
+
└── workspace/ # Persistent working directory
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Configurable in `~/.swarmai/config.json` under `"workspace"` key.
|
|
138
|
+
|
|
139
|
+
## Project Structure
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
local-agent/
|
|
143
|
+
├── index.js # Entry point (CLI)
|
|
144
|
+
├── package.json
|
|
145
|
+
└── src/
|
|
146
|
+
├── cli.js # Commander.js CLI definitions
|
|
147
|
+
├── auth.js # OAuth browser login flow
|
|
148
|
+
├── config.js # ~/.swarmai/config.json management
|
|
149
|
+
├── connection.js # Socket.io WebSocket client
|
|
150
|
+
├── commands.js # Command handlers (shell, screenshot, etc.)
|
|
151
|
+
├── mcpManager.js # MCP server lifecycle management
|
|
152
|
+
├── toolScanner.js # Discover local CLI tools
|
|
153
|
+
├── aiProviderScanner.js # Detect local AI (Ollama, LM Studio)
|
|
154
|
+
├── workspace.js # Local workspace/file management
|
|
155
|
+
└── startup.js # OS auto-start (systemd, launchd, Task Scheduler)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Backend Integration
|
|
159
|
+
|
|
160
|
+
The server-side gateway lives at:
|
|
161
|
+
- **Gateway:** `server/services/LocalAgentGateway.cjs`
|
|
162
|
+
- **Routes:** `server/routes/local-agents.cjs`
|
|
163
|
+
- **AI Tools:** `executeOnLocalAgent`, `uploadToTempStorage` (available to agentic AI when a local agent is online)
|
|
164
|
+
|
|
165
|
+
### WebSocket Events
|
|
166
|
+
|
|
167
|
+
| Event | Direction | Description |
|
|
168
|
+
|-------|-----------|-------------|
|
|
169
|
+
| `command:execute` | Server → Agent | Execute a command |
|
|
170
|
+
| `command:result` | Agent → Server | Command result (sync) |
|
|
171
|
+
| `command:output` | Agent → Server | Streaming output chunk |
|
|
172
|
+
| `command:async-result` | Agent → Server | Async CLI completion |
|
|
173
|
+
| `agent:heartbeat` | Agent → Server | Health pulse (every 15s) |
|
|
174
|
+
| `agent:capabilities` | Agent → Server | Supported commands + MCP tools |
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@swarmai/local-agent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SwarmAI Local Agent CLI - Connect your device to SwarmAI",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"swarmai-agent": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"src/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node index.js start",
|
|
15
|
+
"login": "node index.js login"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
19
|
+
"chalk": "^4.1.2",
|
|
20
|
+
"commander": "^11.1.0",
|
|
21
|
+
"open": "^8.4.2",
|
|
22
|
+
"screenshot-desktop": "^1.5.3",
|
|
23
|
+
"socket.io-client": "^4.7.4"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=16.0.0"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"swarmai",
|
|
30
|
+
"local-agent",
|
|
31
|
+
"cli",
|
|
32
|
+
"ai-agent",
|
|
33
|
+
"swarm-intelligence"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/swarmai/swarmai.git",
|
|
38
|
+
"directory": "local-agent"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://agents.northpeak.app",
|
|
41
|
+
"license": "MIT"
|
|
42
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLAUDE.md Template Builder for Agentic Chat
|
|
3
|
+
*
|
|
4
|
+
* Generates workspace CLAUDE.md content for Claude Code CLI
|
|
5
|
+
* when running with Ollama as the backend provider.
|
|
6
|
+
*
|
|
7
|
+
* Pure function — no I/O, easily testable.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const SENTINEL = '<!-- swarm_agentic_chat_injected -->';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build CLAUDE.md content for an agenticChat workspace.
|
|
14
|
+
*
|
|
15
|
+
* @param {object} options
|
|
16
|
+
* @param {string} options.profileName - Agent profile name
|
|
17
|
+
* @param {string} [options.systemPrompt] - Agent personality / instructions
|
|
18
|
+
* @param {string} [options.model] - Ollama model being used
|
|
19
|
+
* @param {string} [options.taskContext] - Current task description
|
|
20
|
+
* @param {string} [options.outputDir] - Absolute path to output directory
|
|
21
|
+
* @returns {string} CLAUDE.md content
|
|
22
|
+
*/
|
|
23
|
+
function buildAgenticChatClaudeMd(options = {}) {
|
|
24
|
+
const {
|
|
25
|
+
profileName = 'SwarmAI Agent',
|
|
26
|
+
systemPrompt = '',
|
|
27
|
+
model = 'unknown',
|
|
28
|
+
taskContext = '',
|
|
29
|
+
outputDir = './output',
|
|
30
|
+
} = options;
|
|
31
|
+
|
|
32
|
+
const timestamp = new Date().toISOString();
|
|
33
|
+
|
|
34
|
+
const sections = [];
|
|
35
|
+
|
|
36
|
+
// Header
|
|
37
|
+
sections.push(`# ${profileName} — Agentic Workspace`);
|
|
38
|
+
sections.push('');
|
|
39
|
+
sections.push(SENTINEL);
|
|
40
|
+
sections.push('');
|
|
41
|
+
sections.push(`- Agent: ${profileName}`);
|
|
42
|
+
sections.push(`- Model: ${model}`);
|
|
43
|
+
sections.push(`- Updated: ${timestamp}`);
|
|
44
|
+
sections.push('');
|
|
45
|
+
|
|
46
|
+
// Agent Instructions
|
|
47
|
+
if (systemPrompt) {
|
|
48
|
+
sections.push('## Agent Instructions');
|
|
49
|
+
sections.push('');
|
|
50
|
+
sections.push(systemPrompt);
|
|
51
|
+
sections.push('');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Task Context
|
|
55
|
+
if (taskContext) {
|
|
56
|
+
sections.push('## Current Task');
|
|
57
|
+
sections.push('');
|
|
58
|
+
sections.push(taskContext);
|
|
59
|
+
sections.push('');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// File Generation Protocol
|
|
63
|
+
sections.push('## File Generation Protocol');
|
|
64
|
+
sections.push('');
|
|
65
|
+
sections.push('When you create or generate any file, you MUST:');
|
|
66
|
+
sections.push(`1. Save files to the \`${outputDir}\` directory`);
|
|
67
|
+
sections.push('2. After saving, output a marker on its own line: `[FILE_GENERATED: /absolute/path/to/file]`');
|
|
68
|
+
sections.push('3. This marker is required for the system to detect and deliver generated files');
|
|
69
|
+
sections.push('4. Always use absolute paths in the marker');
|
|
70
|
+
sections.push('');
|
|
71
|
+
|
|
72
|
+
// Output Rules
|
|
73
|
+
sections.push('## Output Rules');
|
|
74
|
+
sections.push('');
|
|
75
|
+
sections.push('- Be concise and direct in your responses');
|
|
76
|
+
sections.push('- If the task requires creating files, follow the File Generation Protocol above');
|
|
77
|
+
sections.push('- If you encounter an error, explain it clearly and suggest a fix');
|
|
78
|
+
sections.push('- Do not ask clarifying questions — work with the information given');
|
|
79
|
+
sections.push('- You have full filesystem access within this workspace');
|
|
80
|
+
sections.push('');
|
|
81
|
+
|
|
82
|
+
return sections.join('\n');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check if a CLAUDE.md content was generated by agenticChat
|
|
87
|
+
*/
|
|
88
|
+
function isAgenticChatClaudeMd(content) {
|
|
89
|
+
return typeof content === 'string' && content.includes(SENTINEL);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = { buildAgenticChatClaudeMd, isAgenticChatClaudeMd, SENTINEL };
|