akemon 0.2.16 → 0.2.18

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.
@@ -4,6 +4,53 @@ const DEFAULT_RELAY_URL = "wss://relay.akemon.dev";
4
4
  // Pending agent_call results (callId → resolve function)
5
5
  const pendingAgentCalls = new Map();
6
6
  let relayWsRef = null;
7
+ // ---------------------------------------------------------------------------
8
+ // Terminal (PTY) — spawned on demand when relay sends terminal_start
9
+ // ---------------------------------------------------------------------------
10
+ let ptyProcess = null;
11
+ function startPTY(ws, cols, rows) {
12
+ if (ptyProcess) {
13
+ console.log("[terminal] PTY already running, ignoring duplicate start");
14
+ return;
15
+ }
16
+ // Dynamic import so node-pty is only loaded when needed
17
+ import("node-pty").then((pty) => {
18
+ const shell = process.env.SHELL || "/bin/bash";
19
+ ptyProcess = pty.spawn(shell, [], {
20
+ name: "xterm-256color",
21
+ cols: cols || 80,
22
+ rows: rows || 24,
23
+ cwd: process.cwd(),
24
+ env: process.env,
25
+ });
26
+ console.log(`[terminal] PTY started (${cols}x${rows}, shell=${shell})`);
27
+ ptyProcess.onData((data) => {
28
+ if (ws.readyState === WebSocket.OPEN) {
29
+ ws.send(JSON.stringify({
30
+ type: "terminal_data",
31
+ body: data,
32
+ }));
33
+ }
34
+ });
35
+ ptyProcess.onExit(({ exitCode }) => {
36
+ console.log(`[terminal] PTY exited (code=${exitCode})`);
37
+ if (ws.readyState === WebSocket.OPEN) {
38
+ ws.send(JSON.stringify({ type: "terminal_exit" }));
39
+ }
40
+ ptyProcess = null;
41
+ });
42
+ }).catch((err) => {
43
+ console.error(`[terminal] Failed to start PTY: ${err.message}`);
44
+ ws.send(JSON.stringify({ type: "terminal_exit", error: err.message }));
45
+ });
46
+ }
47
+ function stopPTY() {
48
+ if (ptyProcess) {
49
+ console.log("[terminal] Stopping PTY");
50
+ ptyProcess.kill();
51
+ ptyProcess = null;
52
+ }
53
+ }
7
54
  /** Call another agent through the relay. Available to any engine. */
8
55
  export function callAgent(target, task) {
9
56
  return new Promise((resolve, reject) => {
@@ -142,6 +189,20 @@ export function connectRelay(options) {
142
189
  options.onOrderNotify(msg.order_id);
143
190
  }
144
191
  break;
192
+ case "terminal_start":
193
+ startPTY(ws, msg.cols || 80, msg.rows || 24);
194
+ break;
195
+ case "terminal_data":
196
+ if (ptyProcess)
197
+ ptyProcess.write(msg.body);
198
+ break;
199
+ case "terminal_resize":
200
+ if (ptyProcess)
201
+ ptyProcess.resize(msg.cols || 80, msg.rows || 24);
202
+ break;
203
+ case "terminal_stop":
204
+ stopPTY();
205
+ break;
145
206
  default:
146
207
  console.log(`[relay-ws] Unknown message type: ${msg.type}`);
147
208
  }
package/dist/self.js CHANGED
@@ -137,6 +137,7 @@ export async function initAgentConfig(workdir, agentName) {
137
137
  await readFile(p, "utf-8");
138
138
  }
139
139
  catch {
140
+ await mkdir(join(workdir, ".akemon", "agents", agentName), { recursive: true });
140
141
  await writeFile(p, JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n");
141
142
  console.log(`[self] Created config.json with defaults`);
142
143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,6 +33,7 @@
33
33
  "dependencies": {
34
34
  "@modelcontextprotocol/sdk": "^1.0.0",
35
35
  "commander": "^12.0.0",
36
+ "node-pty": "^1.0.0",
36
37
  "ws": "^8.19.0"
37
38
  },
38
39
  "devDependencies": {