@agentmeshhq/agent 0.2.0 → 0.3.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 (147) hide show
  1. package/README.md +39 -0
  2. package/dist/__tests__/context-template.test.d.ts +4 -0
  3. package/dist/__tests__/context-template.test.js +233 -0
  4. package/dist/__tests__/context-template.test.js.map +1 -0
  5. package/dist/__tests__/loader.test.js +140 -28
  6. package/dist/__tests__/loader.test.js.map +1 -1
  7. package/dist/__tests__/no-respawn.test.d.ts +1 -0
  8. package/dist/__tests__/no-respawn.test.js +254 -0
  9. package/dist/__tests__/no-respawn.test.js.map +1 -0
  10. package/dist/__tests__/onboard.test.d.ts +5 -0
  11. package/dist/__tests__/onboard.test.js +341 -0
  12. package/dist/__tests__/onboard.test.js.map +1 -0
  13. package/dist/__tests__/orphan-process.test.d.ts +11 -0
  14. package/dist/__tests__/orphan-process.test.js +286 -0
  15. package/dist/__tests__/orphan-process.test.js.map +1 -0
  16. package/dist/__tests__/runner.test.js +16 -0
  17. package/dist/__tests__/runner.test.js.map +1 -1
  18. package/dist/__tests__/shared-resource-guards.test.d.ts +7 -0
  19. package/dist/__tests__/shared-resource-guards.test.js +260 -0
  20. package/dist/__tests__/shared-resource-guards.test.js.map +1 -0
  21. package/dist/__tests__/watchdog.test.js +138 -12
  22. package/dist/__tests__/watchdog.test.js.map +1 -1
  23. package/dist/cli/status.js +11 -0
  24. package/dist/cli/status.js.map +1 -1
  25. package/dist/cli/stop.js +7 -2
  26. package/dist/cli/stop.js.map +1 -1
  27. package/dist/config/loader.d.ts +0 -4
  28. package/dist/config/loader.js +102 -42
  29. package/dist/config/loader.js.map +1 -1
  30. package/dist/config/schema.d.ts +6 -4
  31. package/dist/core/daemon/assignment-message.d.ts +12 -0
  32. package/dist/core/daemon/assignment-message.js +36 -0
  33. package/dist/core/daemon/assignment-message.js.map +1 -0
  34. package/dist/core/daemon/bootstrap.d.ts +35 -0
  35. package/dist/core/daemon/bootstrap.js +52 -0
  36. package/dist/core/daemon/bootstrap.js.map +1 -0
  37. package/dist/core/daemon/context-template.d.ts +11 -0
  38. package/dist/core/daemon/context-template.js +144 -0
  39. package/dist/core/daemon/context-template.js.map +1 -0
  40. package/dist/core/daemon/crash-log.d.ts +14 -0
  41. package/dist/core/daemon/crash-log.js +23 -0
  42. package/dist/core/daemon/crash-log.js.map +1 -0
  43. package/dist/core/daemon/git-auth.d.ts +18 -0
  44. package/dist/core/daemon/git-auth.js +88 -0
  45. package/dist/core/daemon/git-auth.js.map +1 -0
  46. package/dist/core/daemon/health-policy.d.ts +17 -0
  47. package/dist/core/daemon/health-policy.js +24 -0
  48. package/dist/core/daemon/health-policy.js.map +1 -0
  49. package/dist/core/daemon/sandbox-config.d.ts +9 -0
  50. package/dist/core/daemon/sandbox-config.js +17 -0
  51. package/dist/core/daemon/sandbox-config.js.map +1 -0
  52. package/dist/core/daemon/state.d.ts +33 -0
  53. package/dist/core/daemon/state.js +78 -0
  54. package/dist/core/daemon/state.js.map +1 -0
  55. package/dist/core/daemon/tmux-session.d.ts +17 -0
  56. package/dist/core/daemon/tmux-session.js +34 -0
  57. package/dist/core/daemon/tmux-session.js.map +1 -0
  58. package/dist/core/daemon/workspace.d.ts +23 -0
  59. package/dist/core/daemon/workspace.js +90 -0
  60. package/dist/core/daemon/workspace.js.map +1 -0
  61. package/dist/core/daemon.d.ts +9 -12
  62. package/dist/core/daemon.js +293 -393
  63. package/dist/core/daemon.js.map +1 -1
  64. package/dist/core/injector.d.ts +5 -1
  65. package/dist/core/injector.js +83 -0
  66. package/dist/core/injector.js.map +1 -1
  67. package/dist/core/registry.d.ts +62 -0
  68. package/dist/core/registry.js +18 -0
  69. package/dist/core/registry.js.map +1 -1
  70. package/dist/core/runner/build.d.ts +9 -0
  71. package/dist/core/runner/build.js +53 -0
  72. package/dist/core/runner/build.js.map +1 -0
  73. package/dist/core/runner/detect.d.ts +5 -0
  74. package/dist/core/runner/detect.js +14 -0
  75. package/dist/core/runner/detect.js.map +1 -0
  76. package/dist/core/runner/index.d.ts +5 -0
  77. package/dist/core/runner/index.js +5 -0
  78. package/dist/core/runner/index.js.map +1 -0
  79. package/dist/core/runner/model.d.ts +5 -0
  80. package/dist/core/runner/model.js +7 -0
  81. package/dist/core/runner/model.js.map +1 -0
  82. package/dist/core/runner/opencode-models.d.ts +15 -0
  83. package/dist/core/runner/opencode-models.js +70 -0
  84. package/dist/core/runner/opencode-models.js.map +1 -0
  85. package/dist/core/runner/types.d.ts +19 -0
  86. package/dist/core/runner/types.js +8 -0
  87. package/dist/core/runner/types.js.map +1 -0
  88. package/dist/core/runner.d.ts +5 -47
  89. package/dist/core/runner.js +5 -167
  90. package/dist/core/runner.js.map +1 -1
  91. package/dist/core/tmux-runtime.d.ts +13 -0
  92. package/dist/core/tmux-runtime.js +72 -0
  93. package/dist/core/tmux-runtime.js.map +1 -0
  94. package/dist/core/tmux.d.ts +7 -1
  95. package/dist/core/tmux.js +75 -45
  96. package/dist/core/tmux.js.map +1 -1
  97. package/dist/core/watchdog.d.ts +18 -1
  98. package/dist/core/watchdog.js +78 -29
  99. package/dist/core/watchdog.js.map +1 -1
  100. package/package.json +24 -4
  101. package/src/__tests__/context.test.ts +0 -464
  102. package/src/__tests__/injector.test.ts +0 -29
  103. package/src/__tests__/jwt.test.ts +0 -112
  104. package/src/__tests__/loader.test.ts +0 -239
  105. package/src/__tests__/runner.test.ts +0 -104
  106. package/src/__tests__/sandbox.test.ts +0 -435
  107. package/src/__tests__/watchdog.test.ts +0 -368
  108. package/src/cli/attach.ts +0 -22
  109. package/src/cli/build.ts +0 -145
  110. package/src/cli/config.ts +0 -148
  111. package/src/cli/context.ts +0 -231
  112. package/src/cli/deploy.ts +0 -155
  113. package/src/cli/index.ts +0 -376
  114. package/src/cli/init.ts +0 -75
  115. package/src/cli/list.ts +0 -70
  116. package/src/cli/local.ts +0 -183
  117. package/src/cli/logs.ts +0 -64
  118. package/src/cli/migrate.ts +0 -212
  119. package/src/cli/nudge.ts +0 -81
  120. package/src/cli/restart.ts +0 -59
  121. package/src/cli/slack.ts +0 -70
  122. package/src/cli/start.ts +0 -118
  123. package/src/cli/status.ts +0 -91
  124. package/src/cli/stop.ts +0 -48
  125. package/src/cli/test.ts +0 -143
  126. package/src/cli/token.ts +0 -188
  127. package/src/cli/whoami.ts +0 -142
  128. package/src/config/loader.ts +0 -121
  129. package/src/config/schema.ts +0 -68
  130. package/src/context/handoff.ts +0 -122
  131. package/src/context/index.ts +0 -8
  132. package/src/context/schema.ts +0 -111
  133. package/src/context/storage.ts +0 -197
  134. package/src/core/daemon.ts +0 -1317
  135. package/src/core/heartbeat.ts +0 -129
  136. package/src/core/injector.ts +0 -292
  137. package/src/core/registry.ts +0 -159
  138. package/src/core/runner.ts +0 -225
  139. package/src/core/sandbox.ts +0 -547
  140. package/src/core/session-id.ts +0 -111
  141. package/src/core/tmux.ts +0 -405
  142. package/src/core/watchdog.ts +0 -238
  143. package/src/core/websocket.ts +0 -94
  144. package/src/index.ts +0 -10
  145. package/src/utils/jwt.ts +0 -87
  146. package/tsconfig.json +0 -8
  147. package/vitest.config.ts +0 -12
@@ -1,239 +0,0 @@
1
- import * as fs from "node:fs";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
3
- import {
4
- addAgentToState,
5
- getAgentState,
6
- loadConfig,
7
- loadState,
8
- removeAgentFromState,
9
- resetAgentRestartCount,
10
- updateAgentInState,
11
- } from "../config/loader.js";
12
- import type { AgentState, Config, State } from "../config/schema.js";
13
-
14
- // Mock the file system
15
- vi.mock("node:fs");
16
-
17
- describe("Config Loader", () => {
18
- const mockConfig: Config = {
19
- hubUrl: "https://test.agentmesh.dev",
20
- apiKey: "test-api-key",
21
- workspace: "test-workspace",
22
- defaults: {
23
- command: "opencode",
24
- model: "claude-sonnet-4",
25
- },
26
- agents: [],
27
- };
28
-
29
- const mockState: State = {
30
- agents: [
31
- {
32
- name: "test-agent",
33
- agentId: "agent-123",
34
- pid: 12345,
35
- tmuxSession: "agentmesh-test-agent",
36
- startedAt: "2024-01-01T00:00:00Z",
37
- token: "test-token",
38
- },
39
- ],
40
- };
41
-
42
- beforeEach(() => {
43
- vi.resetAllMocks();
44
- });
45
-
46
- describe("loadConfig", () => {
47
- it("should return null if config file does not exist", () => {
48
- vi.mocked(fs.existsSync).mockReturnValue(false);
49
- expect(loadConfig()).toBeNull();
50
- });
51
-
52
- it("should load and parse config file", () => {
53
- vi.mocked(fs.existsSync).mockReturnValue(true);
54
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockConfig));
55
-
56
- const config = loadConfig();
57
- expect(config).toEqual(mockConfig);
58
- });
59
-
60
- it("should return null on parse error", () => {
61
- vi.mocked(fs.existsSync).mockReturnValue(true);
62
- vi.mocked(fs.readFileSync).mockReturnValue("invalid json");
63
-
64
- expect(loadConfig()).toBeNull();
65
- });
66
- });
67
-
68
- describe("loadState", () => {
69
- it("should return empty state if file does not exist", () => {
70
- vi.mocked(fs.existsSync).mockReturnValue(false);
71
- expect(loadState()).toEqual({ agents: [] });
72
- });
73
-
74
- it("should load and parse state file", () => {
75
- vi.mocked(fs.existsSync).mockReturnValue(true);
76
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
77
-
78
- const state = loadState();
79
- expect(state).toEqual(mockState);
80
- });
81
- });
82
-
83
- describe("addAgentToState", () => {
84
- it("should add new agent to state", () => {
85
- vi.mocked(fs.existsSync).mockReturnValue(true);
86
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify({ agents: [] }));
87
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
88
-
89
- const newAgent: AgentState = {
90
- name: "new-agent",
91
- agentId: "agent-456",
92
- pid: 67890,
93
- tmuxSession: "agentmesh-new-agent",
94
- startedAt: "2024-01-02T00:00:00Z",
95
- token: "new-token",
96
- };
97
-
98
- addAgentToState(newAgent);
99
-
100
- expect(fs.writeFileSync).toHaveBeenCalled();
101
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
102
- const parsedState = JSON.parse(writtenContent);
103
- expect(parsedState.agents).toHaveLength(1);
104
- expect(parsedState.agents[0].name).toBe("new-agent");
105
- });
106
-
107
- it("should replace existing agent with same name", () => {
108
- vi.mocked(fs.existsSync).mockReturnValue(true);
109
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
110
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
111
-
112
- const updatedAgent: AgentState = {
113
- name: "test-agent",
114
- agentId: "agent-789",
115
- pid: 11111,
116
- tmuxSession: "agentmesh-test-agent",
117
- startedAt: "2024-01-03T00:00:00Z",
118
- token: "updated-token",
119
- };
120
-
121
- addAgentToState(updatedAgent);
122
-
123
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
124
- const parsedState = JSON.parse(writtenContent);
125
- expect(parsedState.agents).toHaveLength(1);
126
- expect(parsedState.agents[0].agentId).toBe("agent-789");
127
- });
128
- });
129
-
130
- describe("removeAgentFromState", () => {
131
- it("should remove agent from state", () => {
132
- vi.mocked(fs.existsSync).mockReturnValue(true);
133
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
134
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
135
-
136
- removeAgentFromState("test-agent");
137
-
138
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
139
- const parsedState = JSON.parse(writtenContent);
140
- expect(parsedState.agents).toHaveLength(0);
141
- });
142
- });
143
-
144
- describe("getAgentState", () => {
145
- it("should return agent by name", () => {
146
- vi.mocked(fs.existsSync).mockReturnValue(true);
147
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
148
-
149
- const agent = getAgentState("test-agent");
150
- expect(agent).toBeDefined();
151
- expect(agent?.agentId).toBe("agent-123");
152
- });
153
-
154
- it("should return undefined for non-existent agent", () => {
155
- vi.mocked(fs.existsSync).mockReturnValue(true);
156
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
157
-
158
- const agent = getAgentState("non-existent");
159
- expect(agent).toBeUndefined();
160
- });
161
- });
162
-
163
- describe("updateAgentInState", () => {
164
- it("should update agent fields", () => {
165
- vi.mocked(fs.existsSync).mockReturnValue(true);
166
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
167
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
168
-
169
- updateAgentInState("test-agent", { token: "new-token-123" });
170
-
171
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
172
- const parsedState = JSON.parse(writtenContent);
173
- expect(parsedState.agents[0].token).toBe("new-token-123");
174
- // Other fields should remain unchanged
175
- expect(parsedState.agents[0].agentId).toBe("agent-123");
176
- });
177
-
178
- it("should do nothing for non-existent agent", () => {
179
- vi.mocked(fs.existsSync).mockReturnValue(true);
180
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
181
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
182
-
183
- updateAgentInState("non-existent", { token: "new-token" });
184
-
185
- // writeFileSync should not be called since agent doesn't exist
186
- // Actually it will be called but the state will be unchanged
187
- });
188
-
189
- it("should update restart count and status fields", () => {
190
- vi.mocked(fs.existsSync).mockReturnValue(true);
191
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockState));
192
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
193
-
194
- updateAgentInState("test-agent", {
195
- restartCount: 2,
196
- status: "stuck",
197
- stuckSince: "2024-01-01T01:00:00Z",
198
- });
199
-
200
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
201
- const parsedState = JSON.parse(writtenContent);
202
- expect(parsedState.agents[0].restartCount).toBe(2);
203
- expect(parsedState.agents[0].status).toBe("stuck");
204
- expect(parsedState.agents[0].stuckSince).toBe("2024-01-01T01:00:00Z");
205
- });
206
- });
207
-
208
- describe("resetAgentRestartCount", () => {
209
- it("should reset restart count and clear stuck status", () => {
210
- const stuckState: State = {
211
- agents: [
212
- {
213
- name: "test-agent",
214
- agentId: "agent-123",
215
- pid: 12345,
216
- tmuxSession: "agentmesh-test-agent",
217
- startedAt: "2024-01-01T00:00:00Z",
218
- token: "test-token",
219
- restartCount: 3,
220
- status: "stuck",
221
- stuckSince: "2024-01-01T01:00:00Z",
222
- },
223
- ],
224
- };
225
-
226
- vi.mocked(fs.existsSync).mockReturnValue(true);
227
- vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(stuckState));
228
- vi.mocked(fs.writeFileSync).mockImplementation(() => {});
229
-
230
- resetAgentRestartCount("test-agent");
231
-
232
- const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1] as string;
233
- const parsedState = JSON.parse(writtenContent);
234
- expect(parsedState.agents[0].restartCount).toBe(0);
235
- expect(parsedState.agents[0].status).toBe("running");
236
- expect(parsedState.agents[0].stuckSince).toBeUndefined();
237
- });
238
- });
239
- });
@@ -1,104 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- buildRunnerConfig,
4
- detectRunner,
5
- getRunnerDisplayName,
6
- resolveModel,
7
- } from "../core/runner.js";
8
-
9
- describe("Runner Module", () => {
10
- describe("detectRunner", () => {
11
- it("should detect opencode runner", () => {
12
- expect(detectRunner("opencode")).toBe("opencode");
13
- expect(detectRunner("opencode --some-flag")).toBe("opencode");
14
- expect(detectRunner("OPENCODE")).toBe("opencode");
15
- });
16
-
17
- it("should detect claude runner", () => {
18
- expect(detectRunner("claude")).toBe("claude");
19
- expect(detectRunner("claude --some-flag")).toBe("claude");
20
- expect(detectRunner("CLAUDE")).toBe("claude");
21
- });
22
-
23
- it("should detect custom runner for unknown commands", () => {
24
- expect(detectRunner("aider")).toBe("custom");
25
- expect(detectRunner("cursor")).toBe("custom");
26
- expect(detectRunner("my-custom-tool")).toBe("custom");
27
- });
28
- });
29
-
30
- describe("resolveModel", () => {
31
- it("should prioritize CLI model over all others", () => {
32
- const result = resolveModel({
33
- cliModel: "cli-model",
34
- agentModel: "agent-model",
35
- defaultModel: "default-model",
36
- command: "opencode",
37
- });
38
- expect(result).toBe("cli-model");
39
- });
40
-
41
- it("should use agent model when CLI not provided", () => {
42
- const result = resolveModel({
43
- agentModel: "agent-model",
44
- defaultModel: "default-model",
45
- command: "opencode",
46
- });
47
- expect(result).toBe("agent-model");
48
- });
49
-
50
- it("should fall back to default model", () => {
51
- const result = resolveModel({
52
- defaultModel: "default-model",
53
- command: "opencode",
54
- });
55
- expect(result).toBe("default-model");
56
- });
57
- });
58
-
59
- describe("buildRunnerConfig", () => {
60
- it("should build config for opencode with OPENCODE_MODEL env", () => {
61
- const config = buildRunnerConfig({
62
- cliModel: "claude-sonnet-4",
63
- defaultModel: "claude-sonnet-4",
64
- command: "opencode",
65
- });
66
-
67
- expect(config.type).toBe("opencode");
68
- expect(config.model).toBe("claude-sonnet-4");
69
- expect(config.env.OPENCODE_MODEL).toBeDefined();
70
- });
71
-
72
- it("should build config for claude with CLAUDE_MODEL env", () => {
73
- const config = buildRunnerConfig({
74
- cliModel: "claude-sonnet-4",
75
- defaultModel: "claude-sonnet-4",
76
- command: "claude",
77
- });
78
-
79
- expect(config.type).toBe("claude");
80
- expect(config.model).toBe("claude-sonnet-4");
81
- expect(config.env.CLAUDE_MODEL).toBe("claude-sonnet-4");
82
- });
83
-
84
- it("should build config for custom runner without env vars", () => {
85
- const config = buildRunnerConfig({
86
- cliModel: "gpt-4",
87
- defaultModel: "claude-sonnet-4",
88
- command: "aider",
89
- });
90
-
91
- expect(config.type).toBe("custom");
92
- expect(config.model).toBe("gpt-4");
93
- expect(Object.keys(config.env)).toHaveLength(0);
94
- });
95
- });
96
-
97
- describe("getRunnerDisplayName", () => {
98
- it("should return correct display names", () => {
99
- expect(getRunnerDisplayName("opencode")).toBe("OpenCode");
100
- expect(getRunnerDisplayName("claude")).toBe("Claude CLI");
101
- expect(getRunnerDisplayName("custom")).toBe("Custom");
102
- });
103
- });
104
- });