@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.
Files changed (67) hide show
  1. package/README.md +111 -0
  2. package/dist/cli/attach.d.ts +1 -0
  3. package/dist/cli/attach.js +18 -0
  4. package/dist/cli/attach.js.map +1 -0
  5. package/dist/cli/index.d.ts +2 -0
  6. package/dist/cli/index.js +98 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/cli/init.d.ts +1 -0
  9. package/dist/cli/init.js +55 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/cli/list.d.ts +1 -0
  12. package/dist/cli/list.js +45 -0
  13. package/dist/cli/list.js.map +1 -0
  14. package/dist/cli/nudge.d.ts +1 -0
  15. package/dist/cli/nudge.js +72 -0
  16. package/dist/cli/nudge.js.map +1 -0
  17. package/dist/cli/start.d.ts +8 -0
  18. package/dist/cli/start.js +37 -0
  19. package/dist/cli/start.js.map +1 -0
  20. package/dist/cli/stop.d.ts +1 -0
  21. package/dist/cli/stop.js +33 -0
  22. package/dist/cli/stop.js.map +1 -0
  23. package/dist/config/loader.d.ts +10 -0
  24. package/dist/config/loader.js +65 -0
  25. package/dist/config/loader.js.map +1 -0
  26. package/dist/config/schema.d.ts +32 -0
  27. package/dist/config/schema.js +11 -0
  28. package/dist/config/schema.js.map +1 -0
  29. package/dist/core/daemon.d.ts +20 -0
  30. package/dist/core/daemon.js +164 -0
  31. package/dist/core/daemon.js.map +1 -0
  32. package/dist/core/heartbeat.d.ts +14 -0
  33. package/dist/core/heartbeat.js +42 -0
  34. package/dist/core/heartbeat.js.map +1 -0
  35. package/dist/core/injector.d.ts +8 -0
  36. package/dist/core/injector.js +84 -0
  37. package/dist/core/injector.js.map +1 -0
  38. package/dist/core/registry.d.ts +27 -0
  39. package/dist/core/registry.js +52 -0
  40. package/dist/core/registry.js.map +1 -0
  41. package/dist/core/tmux.d.ts +11 -0
  42. package/dist/core/tmux.js +112 -0
  43. package/dist/core/tmux.js.map +1 -0
  44. package/dist/core/websocket.d.ts +25 -0
  45. package/dist/core/websocket.js +65 -0
  46. package/dist/core/websocket.js.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.js +10 -0
  49. package/dist/index.js.map +1 -0
  50. package/package.json +35 -0
  51. package/src/cli/attach.ts +22 -0
  52. package/src/cli/index.ts +101 -0
  53. package/src/cli/init.ts +87 -0
  54. package/src/cli/list.ts +62 -0
  55. package/src/cli/nudge.ts +84 -0
  56. package/src/cli/start.ts +50 -0
  57. package/src/cli/stop.ts +39 -0
  58. package/src/config/loader.ts +81 -0
  59. package/src/config/schema.ts +44 -0
  60. package/src/core/daemon.ts +213 -0
  61. package/src/core/heartbeat.ts +54 -0
  62. package/src/core/injector.ts +128 -0
  63. package/src/core/registry.ts +105 -0
  64. package/src/core/tmux.ts +139 -0
  65. package/src/core/websocket.ts +94 -0
  66. package/src/index.ts +9 -0
  67. 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,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -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>;
@@ -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":"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"}
@@ -0,0 +1 @@
1
+ export declare function list(): Promise<void>;
@@ -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":"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"}
@@ -0,0 +1,8 @@
1
+ export interface StartOptions {
2
+ name: string;
3
+ command?: string;
4
+ workdir?: string;
5
+ model?: string;
6
+ daemonize?: boolean;
7
+ }
8
+ export declare function start(options: StartOptions): Promise<void>;
@@ -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>;
@@ -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":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAIL,WAAW,EACX,UAAU,EACV,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,eAAe;IAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACxB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAY;IACpC,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,uCAAuC;IACvC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;IACjE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC3D,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,SAAiB;IAEjB,OAAO;QACL,GAAG,cAAc;QACjB,MAAM;QACN,SAAS;KACA,CAAC;AACd,CAAC"}
@@ -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
+ }