@agentmeshhq/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 +111 -0
- package/dist/cli/attach.d.ts +1 -0
- package/dist/cli/attach.js +18 -0
- package/dist/cli/attach.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +98 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +55 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/list.d.ts +1 -0
- package/dist/cli/list.js +45 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/nudge.d.ts +1 -0
- package/dist/cli/nudge.js +72 -0
- package/dist/cli/nudge.js.map +1 -0
- package/dist/cli/start.d.ts +8 -0
- package/dist/cli/start.js +37 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/cli/stop.d.ts +1 -0
- package/dist/cli/stop.js +33 -0
- package/dist/cli/stop.js.map +1 -0
- package/dist/config/loader.d.ts +10 -0
- package/dist/config/loader.js +65 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +32 -0
- package/dist/config/schema.js +11 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/daemon.d.ts +20 -0
- package/dist/core/daemon.js +164 -0
- package/dist/core/daemon.js.map +1 -0
- package/dist/core/heartbeat.d.ts +14 -0
- package/dist/core/heartbeat.js +42 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/injector.d.ts +8 -0
- package/dist/core/injector.js +84 -0
- package/dist/core/injector.js.map +1 -0
- package/dist/core/registry.d.ts +27 -0
- package/dist/core/registry.js +52 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/tmux.d.ts +11 -0
- package/dist/core/tmux.js +112 -0
- package/dist/core/tmux.js.map +1 -0
- package/dist/core/websocket.d.ts +25 -0
- package/dist/core/websocket.js +65 -0
- package/dist/core/websocket.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
- package/src/cli/attach.ts +22 -0
- package/src/cli/index.ts +101 -0
- package/src/cli/init.ts +87 -0
- package/src/cli/list.ts +62 -0
- package/src/cli/nudge.ts +84 -0
- package/src/cli/start.ts +50 -0
- package/src/cli/stop.ts +39 -0
- package/src/config/loader.ts +81 -0
- package/src/config/schema.ts +44 -0
- package/src/core/daemon.ts +213 -0
- package/src/core/heartbeat.ts +54 -0
- package/src/core/injector.ts +128 -0
- package/src/core/registry.ts +105 -0
- package/src/core/tmux.ts +139 -0
- package/src/core/websocket.ts +94 -0
- package/src/index.ts +9 -0
- package/tsconfig.json +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# @agentmesh/agent
|
|
2
|
+
|
|
3
|
+
AgentMesh Agent Wrapper - Turn any AI coding assistant into a dispatchable, nudge-able agent.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Auto-register** agents with AgentMesh HQ
|
|
8
|
+
- **Background heartbeats** to maintain online status
|
|
9
|
+
- **Real-time nudges** via WebSocket -> tmux send-keys
|
|
10
|
+
- **Handoff notifications** injected directly into agent session
|
|
11
|
+
- **Works with any AI assistant**: OpenCode, Claude Code, Cursor, etc.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @agentmesh/agent
|
|
17
|
+
# or
|
|
18
|
+
pnpm add -g @agentmesh/agent
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Initialize Configuration
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
agentmesh init
|
|
27
|
+
# Prompts for:
|
|
28
|
+
# - API Key (from agentmeshhq.dev/settings/api-keys)
|
|
29
|
+
# - Workspace
|
|
30
|
+
# - Default command (opencode, claude, etc.)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Start an Agent
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
agentmesh start --name backend-agent
|
|
37
|
+
|
|
38
|
+
# With options:
|
|
39
|
+
agentmesh start \
|
|
40
|
+
--name backend-agent \
|
|
41
|
+
--command "opencode" \
|
|
42
|
+
--workdir ~/Dev/myproject \
|
|
43
|
+
--model claude-sonnet-4
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. List Running Agents
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
agentmesh list
|
|
50
|
+
|
|
51
|
+
# Output:
|
|
52
|
+
# NAME STATUS SESSION PENDING
|
|
53
|
+
# backend-agent online agentmesh-backend-agent 1 handoff
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Attach to Agent Session
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
agentmesh attach backend-agent
|
|
60
|
+
# Opens tmux session - see the AI working
|
|
61
|
+
# Detach with: Ctrl+B, D
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 5. Nudge an Agent
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
agentmesh nudge backend-agent "Check the failing CI tests"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 6. Stop an Agent
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
agentmesh stop backend-agent
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
Config is stored at `~/.agentmesh/config.json`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"apiKey": "am_live_xxxx",
|
|
83
|
+
"workspace": "agentmesh",
|
|
84
|
+
"hubUrl": "https://agentmeshhq.dev",
|
|
85
|
+
"defaults": {
|
|
86
|
+
"command": "opencode",
|
|
87
|
+
"model": "claude-sonnet-4"
|
|
88
|
+
},
|
|
89
|
+
"agents": []
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## How It Works
|
|
94
|
+
|
|
95
|
+
1. **Start**: Creates a tmux session running your AI assistant
|
|
96
|
+
2. **Register**: Registers the agent with AgentMesh HQ
|
|
97
|
+
3. **Heartbeat**: Sends heartbeats every 30s to maintain online status
|
|
98
|
+
4. **WebSocket**: Listens for real-time events (handoffs, nudges, blockers)
|
|
99
|
+
5. **Inject**: When events arrive, injects messages via `tmux send-keys`
|
|
100
|
+
|
|
101
|
+
The AI assistant sees the injected message as if you typed it, maintaining full conversation context.
|
|
102
|
+
|
|
103
|
+
## Requirements
|
|
104
|
+
|
|
105
|
+
- tmux (must be installed and in PATH)
|
|
106
|
+
- Node.js 18+
|
|
107
|
+
- An AgentMesh HQ account with API key
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function attach(name: string): void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { attachSession, sessionExists, getSessionName } from "../core/tmux.js";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
export function attach(name) {
|
|
4
|
+
if (!name) {
|
|
5
|
+
console.log(pc.red("Agent name is required."));
|
|
6
|
+
process.exit(1);
|
|
7
|
+
}
|
|
8
|
+
const sessionName = getSessionName(name);
|
|
9
|
+
if (!sessionExists(sessionName)) {
|
|
10
|
+
console.log(pc.red(`Agent "${name}" is not running.`));
|
|
11
|
+
console.log(`Start it with: ${pc.cyan(`agentmesh start --name ${name}`)}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
console.log(`Attaching to ${sessionName}...`);
|
|
15
|
+
console.log(pc.dim("Detach with: Ctrl+B, D\n"));
|
|
16
|
+
attachSession(name);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=attach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/cli/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAEzC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,0BAA0B,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEhD,aAAa,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { init } from "./init.js";
|
|
4
|
+
import { start } from "./start.js";
|
|
5
|
+
import { stop } from "./stop.js";
|
|
6
|
+
import { list } from "./list.js";
|
|
7
|
+
import { attach } from "./attach.js";
|
|
8
|
+
import { nudge } from "./nudge.js";
|
|
9
|
+
import pc from "picocolors";
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name("agentmesh")
|
|
13
|
+
.description("AgentMesh Agent Wrapper - Turn any AI assistant into a dispatchable agent")
|
|
14
|
+
.version("0.1.0");
|
|
15
|
+
program
|
|
16
|
+
.command("init")
|
|
17
|
+
.description("Initialize AgentMesh configuration")
|
|
18
|
+
.action(async () => {
|
|
19
|
+
try {
|
|
20
|
+
await init();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(pc.red(error.message));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
program
|
|
28
|
+
.command("start")
|
|
29
|
+
.description("Start an agent")
|
|
30
|
+
.requiredOption("-n, --name <name>", "Agent name")
|
|
31
|
+
.option("-c, --command <command>", "Command to run (default: opencode)")
|
|
32
|
+
.option("-w, --workdir <path>", "Working directory")
|
|
33
|
+
.option("-m, --model <model>", "Model identifier")
|
|
34
|
+
.option("-d, --daemonize", "Run in background")
|
|
35
|
+
.action(async (options) => {
|
|
36
|
+
try {
|
|
37
|
+
await start(options);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(pc.red(error.message));
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
program
|
|
45
|
+
.command("stop")
|
|
46
|
+
.description("Stop an agent")
|
|
47
|
+
.argument("<name>", "Agent name")
|
|
48
|
+
.action(async (name) => {
|
|
49
|
+
try {
|
|
50
|
+
await stop(name);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error(pc.red(error.message));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
program
|
|
58
|
+
.command("list")
|
|
59
|
+
.alias("ls")
|
|
60
|
+
.description("List running agents")
|
|
61
|
+
.action(async () => {
|
|
62
|
+
try {
|
|
63
|
+
await list();
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console.error(pc.red(error.message));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
program
|
|
71
|
+
.command("attach")
|
|
72
|
+
.description("Attach to an agent's tmux session")
|
|
73
|
+
.argument("<name>", "Agent name")
|
|
74
|
+
.action((name) => {
|
|
75
|
+
try {
|
|
76
|
+
attach(name);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(pc.red(error.message));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
program
|
|
84
|
+
.command("nudge")
|
|
85
|
+
.description("Send a nudge to an agent")
|
|
86
|
+
.argument("<name>", "Agent name")
|
|
87
|
+
.argument("<message>", "Message to send")
|
|
88
|
+
.action(async (name, message) => {
|
|
89
|
+
try {
|
|
90
|
+
await nudge(name, message);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(pc.red(error.message));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
program.parse();
|
|
98
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function init(): Promise<void>;
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as readline from "node:readline";
|
|
2
|
+
import { loadConfig, saveConfig, createDefaultConfig } from "../config/loader.js";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
function question(rl, prompt) {
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
rl.question(prompt, resolve);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export async function init() {
|
|
10
|
+
const existingConfig = loadConfig();
|
|
11
|
+
if (existingConfig) {
|
|
12
|
+
console.log(pc.yellow("Config already exists at ~/.agentmesh/config.json"));
|
|
13
|
+
console.log("Current workspace:", pc.cyan(existingConfig.workspace));
|
|
14
|
+
const rl = readline.createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout,
|
|
17
|
+
});
|
|
18
|
+
const overwrite = await question(rl, "Overwrite? (y/N): ");
|
|
19
|
+
rl.close();
|
|
20
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
21
|
+
console.log("Aborted.");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
console.log(pc.bold("\nAgentMesh Agent Setup\n"));
|
|
26
|
+
const rl = readline.createInterface({
|
|
27
|
+
input: process.stdin,
|
|
28
|
+
output: process.stdout,
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
const apiKey = await question(rl, `API Key ${pc.dim("(from agentmeshhq.dev/settings/api-keys)")}: `);
|
|
32
|
+
if (!apiKey) {
|
|
33
|
+
console.log(pc.red("API Key is required."));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const workspace = await question(rl, `Workspace ${pc.dim("(default: agentmesh)")}: `);
|
|
37
|
+
const command = await question(rl, `Default command ${pc.dim("(default: opencode)")}: `);
|
|
38
|
+
const model = await question(rl, `Default model ${pc.dim("(default: claude-sonnet-4)")}: `);
|
|
39
|
+
const config = createDefaultConfig(apiKey.trim(), workspace.trim() || "agentmesh");
|
|
40
|
+
if (command.trim()) {
|
|
41
|
+
config.defaults.command = command.trim();
|
|
42
|
+
}
|
|
43
|
+
if (model.trim()) {
|
|
44
|
+
config.defaults.model = model.trim();
|
|
45
|
+
}
|
|
46
|
+
saveConfig(config);
|
|
47
|
+
console.log(pc.green("\nConfig saved to ~/.agentmesh/config.json"));
|
|
48
|
+
console.log("\nNext steps:");
|
|
49
|
+
console.log(` ${pc.cyan("agentmesh start --name my-agent")}`);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
rl.close();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAElF,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,SAAS,QAAQ,CAAC,EAAsB,EAAE,MAAc;IACtD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,cAAc,GAAG,UAAU,EAAE,CAAC;IAEpC,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;QAErE,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC3D,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B,EAAE,EACF,WAAW,EAAE,CAAC,GAAG,CAAC,0CAA0C,CAAC,IAAI,CAClE,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAC9B,EAAE,EACF,aAAa,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,CAChD,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAC5B,EAAE,EACF,mBAAmB,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CACrD,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAC1B,EAAE,EACF,iBAAiB,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,CAC1D,CAAC;QAEF,MAAM,MAAM,GAAW,mBAAmB,CACxC,MAAM,CAAC,IAAI,EAAE,EACb,SAAS,CAAC,IAAI,EAAE,IAAI,WAAW,CAChC,CAAC;QAEF,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3C,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QACvC,CAAC;QAED,UAAU,CAAC,MAAM,CAAC,CAAC;QAEnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,iCAAiC,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function list(): Promise<void>;
|
package/dist/cli/list.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { loadState, loadConfig } from "../config/loader.js";
|
|
2
|
+
import { sessionExists, getSessionName, getSessionInfo } from "../core/tmux.js";
|
|
3
|
+
import { checkInbox } from "../core/registry.js";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
export async function list() {
|
|
6
|
+
const state = loadState();
|
|
7
|
+
const config = loadConfig();
|
|
8
|
+
if (state.agents.length === 0) {
|
|
9
|
+
console.log(pc.dim("No agents running."));
|
|
10
|
+
console.log(`Start one with: ${pc.cyan("agentmesh start --name <name>")}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log(pc.bold("Running Agents:\n"));
|
|
14
|
+
console.log(`${"NAME".padEnd(20)} ${"STATUS".padEnd(10)} ${"SESSION".padEnd(25)} ${"PENDING"}`);
|
|
15
|
+
console.log("-".repeat(70));
|
|
16
|
+
for (const agent of state.agents) {
|
|
17
|
+
const sessionName = getSessionName(agent.name);
|
|
18
|
+
const exists = sessionExists(sessionName);
|
|
19
|
+
const info = getSessionInfo(agent.name);
|
|
20
|
+
let status = pc.green("online");
|
|
21
|
+
if (!exists) {
|
|
22
|
+
status = pc.red("offline");
|
|
23
|
+
}
|
|
24
|
+
let pending = pc.dim("-");
|
|
25
|
+
// Try to check inbox if we have a token
|
|
26
|
+
if (config && agent.token) {
|
|
27
|
+
try {
|
|
28
|
+
const items = await checkInbox(config.hubUrl, config.workspace, agent.token);
|
|
29
|
+
if (items.length > 0) {
|
|
30
|
+
pending = pc.yellow(`${items.length} handoff${items.length === 1 ? "" : "s"}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Ignore errors
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const command = info.command ? pc.dim(`(${info.command})`) : "";
|
|
38
|
+
console.log(`${agent.name.padEnd(20)} ${status.padEnd(19)} ${sessionName.padEnd(25)} ${pending}`);
|
|
39
|
+
if (command) {
|
|
40
|
+
console.log(`${"".padEnd(20)} ${command}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
console.log("");
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/cli/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function nudge(name: string, message: string): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { loadConfig, getAgentState, loadState } from "../config/loader.js";
|
|
2
|
+
import { sendKeys, sessionExists, getSessionName } from "../core/tmux.js";
|
|
3
|
+
import { registerAgent } from "../core/registry.js";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
export async function nudge(name, message) {
|
|
6
|
+
const config = loadConfig();
|
|
7
|
+
if (!config) {
|
|
8
|
+
console.log(pc.red("No config found. Run 'agentmesh init' first."));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
if (!name) {
|
|
12
|
+
console.log(pc.red("Agent name is required."));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
if (!message) {
|
|
16
|
+
console.log(pc.red("Message is required."));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
// Check if this is a local agent
|
|
20
|
+
const localAgent = getAgentState(name);
|
|
21
|
+
if (localAgent && sessionExists(getSessionName(name))) {
|
|
22
|
+
// Local nudge via tmux send-keys
|
|
23
|
+
const formatted = `[AgentMesh] Nudge from CLI:
|
|
24
|
+
${message}`;
|
|
25
|
+
const sent = sendKeys(name, formatted);
|
|
26
|
+
if (sent) {
|
|
27
|
+
console.log(pc.green(`Nudged "${name}" locally.`));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(pc.red(`Failed to nudge "${name}".`));
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Remote nudge via API
|
|
35
|
+
// First we need to find the agent ID
|
|
36
|
+
const state = loadState();
|
|
37
|
+
const agentState = state.agents.find((a) => a.name === name);
|
|
38
|
+
if (!agentState?.agentId) {
|
|
39
|
+
console.log(pc.red(`Agent "${name}" not found.`));
|
|
40
|
+
console.log(pc.dim("For remote nudges, provide the agent ID instead."));
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// Register ourselves to get a token
|
|
44
|
+
try {
|
|
45
|
+
const registration = await registerAgent({
|
|
46
|
+
url: config.hubUrl,
|
|
47
|
+
apiKey: config.apiKey,
|
|
48
|
+
workspace: config.workspace,
|
|
49
|
+
agentName: "cli-nudger",
|
|
50
|
+
model: "cli",
|
|
51
|
+
});
|
|
52
|
+
const response = await fetch(`${config.hubUrl}/api/v1/agents/${agentState.agentId}/nudge`, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: {
|
|
55
|
+
Authorization: `Bearer ${registration.token}`,
|
|
56
|
+
"Content-Type": "application/json",
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify({ message }),
|
|
59
|
+
});
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
console.log(pc.green(`Nudged "${name}" via API.`));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const error = await response.text();
|
|
65
|
+
console.log(pc.red(`Failed to nudge: ${error}`));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.log(pc.red(`Failed to nudge: ${error.message}`));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=nudge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nudge.js","sourceRoot":"","sources":["../../src/cli/nudge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY,EAAE,OAAe;IACvD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,iCAAiC;IACjC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEvC,IAAI,UAAU,IAAI,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACtD,iCAAiC;QACjC,MAAM,SAAS,GAAG;EACpB,OAAO,EAAE,CAAC;QAER,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEvC,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;IACT,CAAC;IAED,uBAAuB;IACvB,qCAAqC;IACrC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAE7D,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,cAAc,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC;YACvC,GAAG,EAAE,MAAM,CAAC,MAAM;YAClB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,SAAS,EAAE,YAAY;YACvB,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,MAAM,CAAC,MAAM,kBAAkB,UAAU,CAAC,OAAO,QAAQ,EAC5D;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,YAAY,CAAC,KAAK,EAAE;gBAC7C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;SAClC,CACF,CAAC;QAEF,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAqB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AgentDaemon } from "../core/daemon.js";
|
|
2
|
+
import { loadConfig, getAgentState } from "../config/loader.js";
|
|
3
|
+
import { sessionExists, getSessionName } from "../core/tmux.js";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
export async function start(options) {
|
|
6
|
+
const config = loadConfig();
|
|
7
|
+
if (!config) {
|
|
8
|
+
console.log(pc.red("No config found. Run 'agentmesh init' first."));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
if (!options.name) {
|
|
12
|
+
console.log(pc.red("Agent name is required. Use --name <name>"));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Check if already running
|
|
16
|
+
const existingState = getAgentState(options.name);
|
|
17
|
+
const sessionName = getSessionName(options.name);
|
|
18
|
+
if (existingState && sessionExists(sessionName)) {
|
|
19
|
+
console.log(pc.yellow(`Agent "${options.name}" is already running.`));
|
|
20
|
+
console.log(`Attach with: ${pc.cyan(`agentmesh attach ${options.name}`)}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const daemon = new AgentDaemon(options);
|
|
25
|
+
await daemon.start();
|
|
26
|
+
// Keep process alive in foreground mode
|
|
27
|
+
if (!options.daemonize) {
|
|
28
|
+
// Process will stay alive due to intervals and WebSocket
|
|
29
|
+
await new Promise(() => { }); // Never resolves
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error(pc.red(`Failed to start agent: ${error.message}`));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,MAAM,YAAY,CAAC;AAU5B,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAqB;IAC/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,IAAI,aAAa,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,OAAO,CAAC,IAAI,uBAAuB,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,oBAAoB,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAErB,wCAAwC;QACxC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACvB,yDAAyD;YACzD,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB;QAChD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,0BAA2B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function stop(name: string): Promise<void>;
|
package/dist/cli/stop.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { destroySession } from "../core/tmux.js";
|
|
2
|
+
import { removeAgentFromState, getAgentState } from "../config/loader.js";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
export async function stop(name) {
|
|
5
|
+
if (!name) {
|
|
6
|
+
console.log(pc.red("Agent name is required."));
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
const state = getAgentState(name);
|
|
10
|
+
if (!state) {
|
|
11
|
+
console.log(pc.yellow(`Agent "${name}" is not running.`));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
// Try to kill the daemon process
|
|
15
|
+
if (state.pid) {
|
|
16
|
+
try {
|
|
17
|
+
process.kill(state.pid, "SIGTERM");
|
|
18
|
+
console.log(`Sent SIGTERM to daemon process ${state.pid}`);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Process might already be dead
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Destroy tmux session
|
|
25
|
+
const destroyed = destroySession(name);
|
|
26
|
+
if (destroyed) {
|
|
27
|
+
console.log(pc.green(`Destroyed tmux session for "${name}"`));
|
|
28
|
+
}
|
|
29
|
+
// Remove from state
|
|
30
|
+
removeAgentFromState(name);
|
|
31
|
+
console.log(pc.green(`Agent "${name}" stopped.`));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/cli/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAY;IACrC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,iCAAiC;IACjC,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,kCAAkC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAEvC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,oBAAoB;IACpB,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,IAAI,YAAY,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Config, type State, type AgentState } from "./schema.js";
|
|
2
|
+
export declare function ensureConfigDir(): void;
|
|
3
|
+
export declare function loadConfig(): Config | null;
|
|
4
|
+
export declare function saveConfig(config: Config): void;
|
|
5
|
+
export declare function loadState(): State;
|
|
6
|
+
export declare function saveState(state: State): void;
|
|
7
|
+
export declare function addAgentToState(agent: AgentState): void;
|
|
8
|
+
export declare function removeAgentFromState(name: string): void;
|
|
9
|
+
export declare function getAgentState(name: string): AgentState | undefined;
|
|
10
|
+
export declare function createDefaultConfig(apiKey: string, workspace: string): Config;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { CONFIG_PATH, STATE_PATH, DEFAULT_CONFIG, } from "./schema.js";
|
|
4
|
+
export function ensureConfigDir() {
|
|
5
|
+
const configDir = path.dirname(CONFIG_PATH);
|
|
6
|
+
if (!fs.existsSync(configDir)) {
|
|
7
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function loadConfig() {
|
|
11
|
+
try {
|
|
12
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const content = fs.readFileSync(CONFIG_PATH, "utf-8");
|
|
16
|
+
return JSON.parse(content);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function saveConfig(config) {
|
|
23
|
+
ensureConfigDir();
|
|
24
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
25
|
+
}
|
|
26
|
+
export function loadState() {
|
|
27
|
+
try {
|
|
28
|
+
if (!fs.existsSync(STATE_PATH)) {
|
|
29
|
+
return { agents: [] };
|
|
30
|
+
}
|
|
31
|
+
const content = fs.readFileSync(STATE_PATH, "utf-8");
|
|
32
|
+
return JSON.parse(content);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { agents: [] };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function saveState(state) {
|
|
39
|
+
ensureConfigDir();
|
|
40
|
+
fs.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
41
|
+
}
|
|
42
|
+
export function addAgentToState(agent) {
|
|
43
|
+
const state = loadState();
|
|
44
|
+
// Remove existing entry with same name
|
|
45
|
+
state.agents = state.agents.filter((a) => a.name !== agent.name);
|
|
46
|
+
state.agents.push(agent);
|
|
47
|
+
saveState(state);
|
|
48
|
+
}
|
|
49
|
+
export function removeAgentFromState(name) {
|
|
50
|
+
const state = loadState();
|
|
51
|
+
state.agents = state.agents.filter((a) => a.name !== name);
|
|
52
|
+
saveState(state);
|
|
53
|
+
}
|
|
54
|
+
export function getAgentState(name) {
|
|
55
|
+
const state = loadState();
|
|
56
|
+
return state.agents.find((a) => a.name === name);
|
|
57
|
+
}
|
|
58
|
+
export function createDefaultConfig(apiKey, workspace) {
|
|
59
|
+
return {
|
|
60
|
+
...DEFAULT_CONFIG,
|
|
61
|
+
apiKey,
|
|
62
|
+
workspace,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface AgentConfig {
|
|
2
|
+
name: string;
|
|
3
|
+
agentId?: string;
|
|
4
|
+
command: string;
|
|
5
|
+
workdir?: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
teams?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface Config {
|
|
10
|
+
apiKey: string;
|
|
11
|
+
workspace: string;
|
|
12
|
+
hubUrl: string;
|
|
13
|
+
defaults: {
|
|
14
|
+
command: string;
|
|
15
|
+
model: string;
|
|
16
|
+
};
|
|
17
|
+
agents: AgentConfig[];
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_CONFIG: Partial<Config>;
|
|
20
|
+
export declare const CONFIG_PATH: string;
|
|
21
|
+
export declare const STATE_PATH: string;
|
|
22
|
+
export interface AgentState {
|
|
23
|
+
name: string;
|
|
24
|
+
agentId: string;
|
|
25
|
+
pid: number;
|
|
26
|
+
tmuxSession: string;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
token?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface State {
|
|
31
|
+
agents: AgentState[];
|
|
32
|
+
}
|