@agentmeshhq/agent 0.1.11 → 0.1.13
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/dist/__tests__/injector.test.d.ts +1 -0
- package/dist/__tests__/injector.test.js +26 -0
- package/dist/__tests__/injector.test.js.map +1 -0
- package/dist/__tests__/sandbox.test.d.ts +1 -0
- package/dist/__tests__/sandbox.test.js +362 -0
- package/dist/__tests__/sandbox.test.js.map +1 -0
- package/dist/cli/build.d.ts +6 -0
- package/dist/cli/build.js +111 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/deploy.d.ts +9 -0
- package/dist/cli/deploy.js +130 -0
- package/dist/cli/deploy.js.map +1 -0
- package/dist/cli/inbox.d.ts +5 -0
- package/dist/cli/inbox.js +123 -0
- package/dist/cli/inbox.js.map +1 -0
- package/dist/cli/index.js +159 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/issue.d.ts +42 -0
- package/dist/cli/issue.js +297 -0
- package/dist/cli/issue.js.map +1 -0
- package/dist/cli/local.d.ts +9 -0
- package/dist/cli/local.js +139 -0
- package/dist/cli/local.js.map +1 -0
- package/dist/cli/migrate.d.ts +8 -0
- package/dist/cli/migrate.js +167 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/ready.d.ts +5 -0
- package/dist/cli/ready.js +131 -0
- package/dist/cli/ready.js.map +1 -0
- package/dist/cli/slack.d.ts +3 -0
- package/dist/cli/slack.js +57 -0
- package/dist/cli/slack.js.map +1 -0
- package/dist/cli/start.d.ts +12 -0
- package/dist/cli/start.js +14 -0
- package/dist/cli/start.js.map +1 -1
- package/dist/cli/sync.d.ts +8 -0
- package/dist/cli/sync.js +154 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/test.d.ts +8 -0
- package/dist/cli/test.js +110 -0
- package/dist/cli/test.js.map +1 -0
- package/dist/core/daemon.d.ts +31 -0
- package/dist/core/daemon.js +188 -28
- package/dist/core/daemon.js.map +1 -1
- package/dist/core/injector.d.ts +6 -1
- package/dist/core/injector.js +64 -1
- package/dist/core/injector.js.map +1 -1
- package/dist/core/issue-cache.d.ts +44 -0
- package/dist/core/issue-cache.js +75 -0
- package/dist/core/issue-cache.js.map +1 -0
- package/dist/core/registry.d.ts +5 -0
- package/dist/core/registry.js +8 -1
- package/dist/core/registry.js.map +1 -1
- package/dist/core/sandbox.d.ts +127 -0
- package/dist/core/sandbox.js +377 -0
- package/dist/core/sandbox.js.map +1 -0
- package/dist/core/tmux.js +8 -10
- package/dist/core/tmux.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/injector.test.ts +29 -0
- package/src/__tests__/sandbox.test.ts +435 -0
- package/src/cli/build.ts +137 -0
- package/src/cli/deploy.ts +153 -0
- package/src/cli/index.ts +163 -0
- package/src/cli/local.ts +174 -0
- package/src/cli/migrate.ts +210 -0
- package/src/cli/slack.ts +69 -0
- package/src/cli/start.ts +22 -0
- package/src/cli/test.ts +141 -0
- package/src/core/daemon.ts +228 -37
- package/src/core/injector.ts +98 -1
- package/src/core/registry.ts +14 -1
- package/src/core/sandbox.ts +505 -0
- package/src/core/tmux.ts +9 -11
package/dist/core/registry.js
CHANGED
|
@@ -13,6 +13,7 @@ export async function registerAgent(options) {
|
|
|
13
13
|
model: options.model,
|
|
14
14
|
capabilities: options.capabilities || ["coding", "review", "debugging"],
|
|
15
15
|
workspace: options.workspace,
|
|
16
|
+
restore_context: options.restoreContext ?? true,
|
|
16
17
|
}),
|
|
17
18
|
});
|
|
18
19
|
if (!response.ok) {
|
|
@@ -24,7 +25,13 @@ export async function registerAgent(options) {
|
|
|
24
25
|
if (!token) {
|
|
25
26
|
throw new Error("No token in registration response");
|
|
26
27
|
}
|
|
27
|
-
return {
|
|
28
|
+
return {
|
|
29
|
+
agentId,
|
|
30
|
+
token,
|
|
31
|
+
status: data.status,
|
|
32
|
+
context: data.context,
|
|
33
|
+
assignments: data.assignments,
|
|
34
|
+
};
|
|
28
35
|
}
|
|
29
36
|
export async function checkInbox(url, workspace, token) {
|
|
30
37
|
const response = await fetch(`${url}/api/v1/workspaces/${workspace}/inbox`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker Sandbox Runtime
|
|
3
|
+
*
|
|
4
|
+
* Provides containerized execution of agents with filesystem isolation.
|
|
5
|
+
* Each agent runs in its own container with only the allowed workspace mounted.
|
|
6
|
+
*/
|
|
7
|
+
import { type ChildProcess } from "node:child_process";
|
|
8
|
+
export interface SandboxConfig {
|
|
9
|
+
/** Agent name (used for container naming) */
|
|
10
|
+
agentName: string;
|
|
11
|
+
/** Image to use for the container */
|
|
12
|
+
image: string;
|
|
13
|
+
/** Workspace path on host to mount */
|
|
14
|
+
workspacePath: string;
|
|
15
|
+
/** Container mount point for workspace (default: /workspace) */
|
|
16
|
+
containerWorkdir?: string;
|
|
17
|
+
/** CPU limit (e.g., "0.5" for half a CPU) */
|
|
18
|
+
cpuLimit?: string;
|
|
19
|
+
/** Memory limit (e.g., "512m", "1g") */
|
|
20
|
+
memoryLimit?: string;
|
|
21
|
+
/** Environment variables to pass to container */
|
|
22
|
+
env?: Record<string, string>;
|
|
23
|
+
/** Network mode (default: bridge) */
|
|
24
|
+
networkMode?: string;
|
|
25
|
+
/** Additional mounts (host:container format) */
|
|
26
|
+
additionalMounts?: string[];
|
|
27
|
+
/** Run opencode serve instead of TUI */
|
|
28
|
+
serveMode?: boolean;
|
|
29
|
+
/** Port for serve mode */
|
|
30
|
+
servePort?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface SandboxMountPolicy {
|
|
33
|
+
/** Paths that are allowed to be mounted */
|
|
34
|
+
allowedPaths: string[];
|
|
35
|
+
/** Paths that are explicitly denied (checked first) */
|
|
36
|
+
deniedPaths: string[];
|
|
37
|
+
}
|
|
38
|
+
export declare class DockerSandbox {
|
|
39
|
+
private config;
|
|
40
|
+
private containerId;
|
|
41
|
+
private containerName;
|
|
42
|
+
private process;
|
|
43
|
+
constructor(config: SandboxConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Validates that the workspace path is allowed based on policy
|
|
46
|
+
*/
|
|
47
|
+
validateMountPolicy(policy?: SandboxMountPolicy): void;
|
|
48
|
+
/**
|
|
49
|
+
* Expands ~ to home directory
|
|
50
|
+
*/
|
|
51
|
+
private expandPath;
|
|
52
|
+
/**
|
|
53
|
+
* Checks if Docker is available
|
|
54
|
+
*/
|
|
55
|
+
static checkDockerAvailable(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Pulls the sandbox image if not present
|
|
58
|
+
*/
|
|
59
|
+
pullImage(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Creates and starts the sandbox container
|
|
62
|
+
*/
|
|
63
|
+
start(): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Executes a command in the running container
|
|
66
|
+
*/
|
|
67
|
+
exec(command: string[], options?: {
|
|
68
|
+
interactive?: boolean;
|
|
69
|
+
}): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Spawns opencode in the container (for non-serve mode)
|
|
72
|
+
*/
|
|
73
|
+
spawnOpencode(): Promise<ChildProcess>;
|
|
74
|
+
/**
|
|
75
|
+
* Attaches to the container's opencode process
|
|
76
|
+
*/
|
|
77
|
+
attach(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Gets container logs
|
|
80
|
+
*/
|
|
81
|
+
getLogs(lines?: number): string;
|
|
82
|
+
/**
|
|
83
|
+
* Follows container logs
|
|
84
|
+
*/
|
|
85
|
+
followLogs(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Checks if container is running
|
|
88
|
+
*/
|
|
89
|
+
isRunning(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Gets container status
|
|
92
|
+
*/
|
|
93
|
+
getStatus(): {
|
|
94
|
+
running: boolean;
|
|
95
|
+
status: string;
|
|
96
|
+
health?: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Stops the container
|
|
100
|
+
*/
|
|
101
|
+
stop(): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Removes the container
|
|
104
|
+
*/
|
|
105
|
+
destroy(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Gets container name
|
|
108
|
+
*/
|
|
109
|
+
getContainerName(): string;
|
|
110
|
+
/**
|
|
111
|
+
* Gets container ID
|
|
112
|
+
*/
|
|
113
|
+
getContainerId(): string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Finds existing sandbox container for an agent
|
|
116
|
+
*/
|
|
117
|
+
static findExisting(agentName: string): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Lists all sandbox containers
|
|
120
|
+
*/
|
|
121
|
+
static listAll(): Array<{
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
status: string;
|
|
125
|
+
image: string;
|
|
126
|
+
}>;
|
|
127
|
+
}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker Sandbox Runtime
|
|
3
|
+
*
|
|
4
|
+
* Provides containerized execution of agents with filesystem isolation.
|
|
5
|
+
* Each agent runs in its own container with only the allowed workspace mounted.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync, spawn, spawnSync } from "node:child_process";
|
|
8
|
+
import crypto from "node:crypto";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
// Default mount policy - deny sensitive paths
|
|
13
|
+
const DEFAULT_DENY_PATHS = [
|
|
14
|
+
"~/.ssh",
|
|
15
|
+
"~/.gnupg",
|
|
16
|
+
"~/.aws",
|
|
17
|
+
"~/.config/gcloud",
|
|
18
|
+
"~/.kube",
|
|
19
|
+
"~/.docker",
|
|
20
|
+
"/etc/passwd",
|
|
21
|
+
"/etc/shadow",
|
|
22
|
+
"/etc/hosts",
|
|
23
|
+
"/var/run/docker.sock",
|
|
24
|
+
];
|
|
25
|
+
export class DockerSandbox {
|
|
26
|
+
config;
|
|
27
|
+
containerId = null;
|
|
28
|
+
containerName;
|
|
29
|
+
process = null;
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.config = {
|
|
32
|
+
containerWorkdir: "/workspace",
|
|
33
|
+
cpuLimit: "1",
|
|
34
|
+
memoryLimit: "2g",
|
|
35
|
+
networkMode: "bridge",
|
|
36
|
+
...config,
|
|
37
|
+
};
|
|
38
|
+
// Generate unique container name
|
|
39
|
+
const suffix = crypto.randomBytes(4).toString("hex");
|
|
40
|
+
this.containerName = `agentmesh-sandbox-${config.agentName}-${suffix}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates that the workspace path is allowed based on policy
|
|
44
|
+
*/
|
|
45
|
+
validateMountPolicy(policy) {
|
|
46
|
+
const workspacePath = this.expandPath(this.config.workspacePath);
|
|
47
|
+
// Check denied paths first
|
|
48
|
+
const deniedPaths = policy?.deniedPaths || DEFAULT_DENY_PATHS;
|
|
49
|
+
for (const denied of deniedPaths) {
|
|
50
|
+
const expandedDenied = this.expandPath(denied);
|
|
51
|
+
if (workspacePath.startsWith(expandedDenied) || workspacePath === expandedDenied) {
|
|
52
|
+
throw new Error(`Mount denied: ${workspacePath} matches denied path ${denied}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check allowed paths if specified
|
|
56
|
+
if (policy?.allowedPaths && policy.allowedPaths.length > 0) {
|
|
57
|
+
const isAllowed = policy.allowedPaths.some((allowed) => {
|
|
58
|
+
const expandedAllowed = this.expandPath(allowed);
|
|
59
|
+
return workspacePath.startsWith(expandedAllowed);
|
|
60
|
+
});
|
|
61
|
+
if (!isAllowed) {
|
|
62
|
+
throw new Error(`Mount denied: ${workspacePath} is not in allowed paths`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Verify path exists
|
|
66
|
+
if (!fs.existsSync(workspacePath)) {
|
|
67
|
+
throw new Error(`Workspace path does not exist: ${workspacePath}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Expands ~ to home directory
|
|
72
|
+
*/
|
|
73
|
+
expandPath(p) {
|
|
74
|
+
if (p.startsWith("~")) {
|
|
75
|
+
return path.join(os.homedir(), p.slice(1));
|
|
76
|
+
}
|
|
77
|
+
return path.resolve(p);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Checks if Docker is available
|
|
81
|
+
*/
|
|
82
|
+
static checkDockerAvailable() {
|
|
83
|
+
try {
|
|
84
|
+
const result = spawnSync("docker", ["--version"], {
|
|
85
|
+
encoding: "utf-8",
|
|
86
|
+
timeout: 5000,
|
|
87
|
+
});
|
|
88
|
+
return result.status === 0;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Pulls the sandbox image if not present
|
|
96
|
+
*/
|
|
97
|
+
async pullImage() {
|
|
98
|
+
console.log(`Checking for image: ${this.config.image}`);
|
|
99
|
+
// Check if image exists locally
|
|
100
|
+
const result = spawnSync("docker", ["image", "inspect", this.config.image], {
|
|
101
|
+
encoding: "utf-8",
|
|
102
|
+
});
|
|
103
|
+
if (result.status === 0) {
|
|
104
|
+
console.log("Image found locally");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
console.log(`Pulling image: ${this.config.image}...`);
|
|
108
|
+
const pullResult = spawnSync("docker", ["pull", this.config.image], {
|
|
109
|
+
encoding: "utf-8",
|
|
110
|
+
stdio: "inherit",
|
|
111
|
+
});
|
|
112
|
+
if (pullResult.status !== 0) {
|
|
113
|
+
throw new Error(`Failed to pull image: ${this.config.image}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Creates and starts the sandbox container
|
|
118
|
+
*/
|
|
119
|
+
async start() {
|
|
120
|
+
// Validate mount policy
|
|
121
|
+
this.validateMountPolicy();
|
|
122
|
+
const workspacePath = this.expandPath(this.config.workspacePath);
|
|
123
|
+
// Build docker run arguments
|
|
124
|
+
const args = [
|
|
125
|
+
"run",
|
|
126
|
+
"-d", // Detached
|
|
127
|
+
"--name",
|
|
128
|
+
this.containerName,
|
|
129
|
+
"--hostname",
|
|
130
|
+
`sandbox-${this.config.agentName}`,
|
|
131
|
+
// Resource limits
|
|
132
|
+
"--cpus",
|
|
133
|
+
this.config.cpuLimit,
|
|
134
|
+
"--memory",
|
|
135
|
+
this.config.memoryLimit,
|
|
136
|
+
// Security: run as non-root
|
|
137
|
+
"--user",
|
|
138
|
+
"1000:1000",
|
|
139
|
+
// Network
|
|
140
|
+
"--network",
|
|
141
|
+
this.config.networkMode,
|
|
142
|
+
// Mount workspace
|
|
143
|
+
"-v",
|
|
144
|
+
`${workspacePath}:${this.config.containerWorkdir}:rw`,
|
|
145
|
+
// Working directory
|
|
146
|
+
"-w",
|
|
147
|
+
this.config.containerWorkdir,
|
|
148
|
+
];
|
|
149
|
+
// Add environment variables
|
|
150
|
+
if (this.config.env) {
|
|
151
|
+
for (const [key, value] of Object.entries(this.config.env)) {
|
|
152
|
+
args.push("-e", `${key}=${value}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Add additional mounts
|
|
156
|
+
if (this.config.additionalMounts) {
|
|
157
|
+
for (const mount of this.config.additionalMounts) {
|
|
158
|
+
args.push("-v", mount);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Expose port for serve mode
|
|
162
|
+
if (this.config.serveMode && this.config.servePort) {
|
|
163
|
+
args.push("-p", `${this.config.servePort}:${this.config.servePort}`);
|
|
164
|
+
}
|
|
165
|
+
// Image and command
|
|
166
|
+
args.push(this.config.image);
|
|
167
|
+
// Command: either serve mode or keep container alive for tmux-style attach
|
|
168
|
+
if (this.config.serveMode) {
|
|
169
|
+
args.push("opencode", "serve", "--port", String(this.config.servePort || 3001), "--hostname", "0.0.0.0");
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Keep container running for attach capability
|
|
173
|
+
args.push("tail", "-f", "/dev/null");
|
|
174
|
+
}
|
|
175
|
+
console.log(`Starting sandbox container: ${this.containerName}`);
|
|
176
|
+
const result = spawnSync("docker", args, {
|
|
177
|
+
encoding: "utf-8",
|
|
178
|
+
});
|
|
179
|
+
if (result.status !== 0) {
|
|
180
|
+
throw new Error(`Failed to start container: ${result.stderr || result.stdout}`);
|
|
181
|
+
}
|
|
182
|
+
this.containerId = result.stdout.trim();
|
|
183
|
+
console.log(`Container started: ${this.containerId.substring(0, 12)}`);
|
|
184
|
+
return this.containerId;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Executes a command in the running container
|
|
188
|
+
*/
|
|
189
|
+
async exec(command, options) {
|
|
190
|
+
if (!this.containerId && !this.containerName) {
|
|
191
|
+
throw new Error("Container not started");
|
|
192
|
+
}
|
|
193
|
+
const target = this.containerId || this.containerName;
|
|
194
|
+
const args = ["exec"];
|
|
195
|
+
if (options?.interactive) {
|
|
196
|
+
args.push("-it");
|
|
197
|
+
}
|
|
198
|
+
args.push(target, ...command);
|
|
199
|
+
const result = spawnSync("docker", args, {
|
|
200
|
+
encoding: "utf-8",
|
|
201
|
+
stdio: options?.interactive ? "inherit" : "pipe",
|
|
202
|
+
});
|
|
203
|
+
if (result.status !== 0 && !options?.interactive) {
|
|
204
|
+
throw new Error(`Exec failed: ${result.stderr || result.stdout}`);
|
|
205
|
+
}
|
|
206
|
+
return result.stdout || "";
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Spawns opencode in the container (for non-serve mode)
|
|
210
|
+
*/
|
|
211
|
+
async spawnOpencode() {
|
|
212
|
+
if (!this.containerId && !this.containerName) {
|
|
213
|
+
throw new Error("Container not started");
|
|
214
|
+
}
|
|
215
|
+
const target = this.containerId || this.containerName;
|
|
216
|
+
// Build environment args
|
|
217
|
+
const envArgs = [];
|
|
218
|
+
if (this.config.env) {
|
|
219
|
+
for (const [key, value] of Object.entries(this.config.env)) {
|
|
220
|
+
envArgs.push("-e", `${key}=${value}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
this.process = spawn("docker", ["exec", "-it", ...envArgs, target, "opencode"], {
|
|
224
|
+
stdio: "inherit",
|
|
225
|
+
});
|
|
226
|
+
return this.process;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Attaches to the container's opencode process
|
|
230
|
+
*/
|
|
231
|
+
attach() {
|
|
232
|
+
if (!this.containerId && !this.containerName) {
|
|
233
|
+
throw new Error("Container not started");
|
|
234
|
+
}
|
|
235
|
+
const target = this.containerId || this.containerName;
|
|
236
|
+
// Exec into container interactively
|
|
237
|
+
execSync(`docker exec -it ${target} opencode`, {
|
|
238
|
+
stdio: "inherit",
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Gets container logs
|
|
243
|
+
*/
|
|
244
|
+
getLogs(lines = 100) {
|
|
245
|
+
if (!this.containerId && !this.containerName) {
|
|
246
|
+
throw new Error("Container not started");
|
|
247
|
+
}
|
|
248
|
+
const target = this.containerId || this.containerName;
|
|
249
|
+
const result = spawnSync("docker", ["logs", "--tail", String(lines), target], {
|
|
250
|
+
encoding: "utf-8",
|
|
251
|
+
});
|
|
252
|
+
return result.stdout + result.stderr;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Follows container logs
|
|
256
|
+
*/
|
|
257
|
+
followLogs() {
|
|
258
|
+
if (!this.containerId && !this.containerName) {
|
|
259
|
+
throw new Error("Container not started");
|
|
260
|
+
}
|
|
261
|
+
const target = this.containerId || this.containerName;
|
|
262
|
+
execSync(`docker logs -f ${target}`, { stdio: "inherit" });
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Checks if container is running
|
|
266
|
+
*/
|
|
267
|
+
isRunning() {
|
|
268
|
+
if (!this.containerId && !this.containerName) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
const target = this.containerId || this.containerName;
|
|
272
|
+
const result = spawnSync("docker", ["inspect", "-f", "{{.State.Running}}", target], {
|
|
273
|
+
encoding: "utf-8",
|
|
274
|
+
});
|
|
275
|
+
return result.stdout.trim() === "true";
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Gets container status
|
|
279
|
+
*/
|
|
280
|
+
getStatus() {
|
|
281
|
+
if (!this.containerId && !this.containerName) {
|
|
282
|
+
return { running: false, status: "not created" };
|
|
283
|
+
}
|
|
284
|
+
const target = this.containerId || this.containerName;
|
|
285
|
+
const result = spawnSync("docker", ["inspect", "-f", "{{.State.Running}}|{{.State.Status}}|{{.State.Health.Status}}", target], { encoding: "utf-8" });
|
|
286
|
+
if (result.status !== 0) {
|
|
287
|
+
return { running: false, status: "not found" };
|
|
288
|
+
}
|
|
289
|
+
const [running, status, health] = result.stdout.trim().split("|");
|
|
290
|
+
return {
|
|
291
|
+
running: running === "true",
|
|
292
|
+
status,
|
|
293
|
+
health: health || undefined,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Stops the container
|
|
298
|
+
*/
|
|
299
|
+
async stop() {
|
|
300
|
+
if (!this.containerId && !this.containerName) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const target = this.containerId || this.containerName;
|
|
304
|
+
console.log(`Stopping container: ${target}`);
|
|
305
|
+
spawnSync("docker", ["stop", "-t", "10", target], {
|
|
306
|
+
encoding: "utf-8",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Removes the container
|
|
311
|
+
*/
|
|
312
|
+
async destroy() {
|
|
313
|
+
if (!this.containerId && !this.containerName) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const target = this.containerId || this.containerName;
|
|
317
|
+
console.log(`Destroying container: ${target}`);
|
|
318
|
+
// Stop if running
|
|
319
|
+
await this.stop();
|
|
320
|
+
// Remove
|
|
321
|
+
spawnSync("docker", ["rm", "-f", target], {
|
|
322
|
+
encoding: "utf-8",
|
|
323
|
+
});
|
|
324
|
+
this.containerId = null;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Gets container name
|
|
328
|
+
*/
|
|
329
|
+
getContainerName() {
|
|
330
|
+
return this.containerName;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Gets container ID
|
|
334
|
+
*/
|
|
335
|
+
getContainerId() {
|
|
336
|
+
return this.containerId;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Finds existing sandbox container for an agent
|
|
340
|
+
*/
|
|
341
|
+
static findExisting(agentName) {
|
|
342
|
+
const result = spawnSync("docker", [
|
|
343
|
+
"ps",
|
|
344
|
+
"-aq",
|
|
345
|
+
"--filter",
|
|
346
|
+
`name=agentmesh-sandbox-${agentName}-`,
|
|
347
|
+
"--filter",
|
|
348
|
+
"status=running",
|
|
349
|
+
], { encoding: "utf-8" });
|
|
350
|
+
const containerId = result.stdout.trim().split("\n")[0];
|
|
351
|
+
return containerId || null;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Lists all sandbox containers
|
|
355
|
+
*/
|
|
356
|
+
static listAll() {
|
|
357
|
+
const result = spawnSync("docker", [
|
|
358
|
+
"ps",
|
|
359
|
+
"-a",
|
|
360
|
+
"--filter",
|
|
361
|
+
"name=agentmesh-sandbox-",
|
|
362
|
+
"--format",
|
|
363
|
+
"{{.ID}}|{{.Names}}|{{.Status}}|{{.Image}}",
|
|
364
|
+
], { encoding: "utf-8" });
|
|
365
|
+
if (result.status !== 0 || !result.stdout.trim()) {
|
|
366
|
+
return [];
|
|
367
|
+
}
|
|
368
|
+
return result.stdout
|
|
369
|
+
.trim()
|
|
370
|
+
.split("\n")
|
|
371
|
+
.map((line) => {
|
|
372
|
+
const [id, name, status, image] = line.split("|");
|
|
373
|
+
return { id, name, status, image };
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/core/sandbox.ts"],"names":[],"mappings":"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"}
|
package/dist/core/tmux.js
CHANGED
|
@@ -36,7 +36,8 @@ export function createSession(agentName, command, workdir, env) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
const fullCommand = `${envPrefix}${command}`;
|
|
39
|
-
|
|
39
|
+
// Set reasonable terminal size for TUI applications
|
|
40
|
+
const args = ["new-session", "-d", "-s", sessionName, "-x", "200", "-y", "50"];
|
|
40
41
|
if (workdir) {
|
|
41
42
|
args.push("-c", workdir);
|
|
42
43
|
}
|
|
@@ -96,15 +97,12 @@ export function sendKeys(agentName, message) {
|
|
|
96
97
|
return false;
|
|
97
98
|
}
|
|
98
99
|
try {
|
|
99
|
-
//
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// Send the message, then press Enter separately to submit to the AI
|
|
106
|
-
execSync(`tmux send-keys -t "${sessionName}" "${escapedMessage}"`);
|
|
107
|
-
execSync(`tmux send-keys -t "${sessionName}" Enter`);
|
|
100
|
+
// Replace newlines with " | " to keep message on single line (newlines would act as Enter)
|
|
101
|
+
const cleanMessage = message.replace(/\n/g, " | ");
|
|
102
|
+
// Use execFileSync with array args to avoid shell escaping issues
|
|
103
|
+
// The -l flag sends keys literally
|
|
104
|
+
execFileSync("tmux", ["send-keys", "-t", sessionName, "-l", cleanMessage]);
|
|
105
|
+
execFileSync("tmux", ["send-keys", "-t", sessionName, "Enter"]);
|
|
108
106
|
return true;
|
|
109
107
|
}
|
|
110
108
|
catch (error) {
|
package/dist/core/tmux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/core/tmux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEtF,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,GAAG,cAAc,GAAG,SAAS,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,IAAI,CAAC;QACH,QAAQ,CAAC,wBAAwB,WAAW,eAAe,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAUD,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,OAAe,EACf,OAAgB,EAChB,GAAgB;IAEhB,MAAM,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE9C,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,WAAW,WAAW,iBAAiB,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,2CAA2C;QAC3C,0DAA0D;QAC1D,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;oBACxC,qCAAqC;oBACrC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBAChD,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,YAAY,GAAG,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;YACvC,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC;QAE7C,MAAM,IAAI,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/core/tmux.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { handleWebSocketEvent } from "../core/injector.js";
|
|
3
|
+
|
|
4
|
+
const { sendKeysMock } = vi.hoisted(() => ({
|
|
5
|
+
sendKeysMock: vi.fn(),
|
|
6
|
+
}));
|
|
7
|
+
|
|
8
|
+
vi.mock("../core/tmux.js", () => ({
|
|
9
|
+
sendKeys: sendKeysMock,
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
describe("injector slack message handling", () => {
|
|
13
|
+
it("injects Slack message event into agent terminal", () => {
|
|
14
|
+
handleWebSocketEvent("concierge", {
|
|
15
|
+
type: "slack.message",
|
|
16
|
+
user: "U123",
|
|
17
|
+
channel: "C123",
|
|
18
|
+
text: "Can you check deployment status?",
|
|
19
|
+
ts: "1730000000.1234",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(sendKeysMock).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(sendKeysMock.mock.calls[0]?.[0]).toBe("concierge");
|
|
24
|
+
const injected = String(sendKeysMock.mock.calls[0]?.[1] ?? "");
|
|
25
|
+
// The injector formats as: [Slack from {user} in {channel}] {text}
|
|
26
|
+
expect(injected).toContain("[Slack from U123 in C123]");
|
|
27
|
+
expect(injected).toContain("Can you check deployment status?");
|
|
28
|
+
});
|
|
29
|
+
});
|