agent-relay 2.1.13 → 2.1.15

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 (165) hide show
  1. package/dist/index.cjs +37571 -50918
  2. package/dist/src/cli/index.js +1 -1
  3. package/dist/src/cli/index.js.map +1 -1
  4. package/package.json +18 -18
  5. package/packages/acp-bridge/package.json +2 -2
  6. package/packages/api-types/package.json +1 -1
  7. package/packages/benchmark/datasets/quick-test.yaml +20 -0
  8. package/packages/benchmark/dist/runners/base.d.ts.map +1 -1
  9. package/packages/benchmark/dist/runners/base.js +1 -0
  10. package/packages/benchmark/dist/runners/base.js.map +1 -1
  11. package/packages/benchmark/package.json +4 -4
  12. package/packages/benchmark/src/runners/base.ts +1 -0
  13. package/packages/bridge/dist/spawner.d.ts.map +1 -1
  14. package/packages/bridge/dist/spawner.js +2 -30
  15. package/packages/bridge/dist/spawner.js.map +1 -1
  16. package/packages/bridge/package.json +7 -8
  17. package/packages/bridge/src/spawner.ts +2 -29
  18. package/packages/cli-tester/package.json +1 -1
  19. package/packages/config/dist/teams-config.d.ts +7 -1
  20. package/packages/config/dist/teams-config.d.ts.map +1 -1
  21. package/packages/config/dist/teams-config.js +88 -34
  22. package/packages/config/dist/teams-config.js.map +1 -1
  23. package/packages/config/package.json +2 -2
  24. package/packages/config/src/teams-config.ts +106 -39
  25. package/packages/continuity/package.json +2 -2
  26. package/packages/daemon/dist/server.d.ts.map +1 -1
  27. package/packages/daemon/dist/server.js +18 -0
  28. package/packages/daemon/dist/server.js.map +1 -1
  29. package/packages/daemon/dist/spawn-manager.d.ts +8 -0
  30. package/packages/daemon/dist/spawn-manager.d.ts.map +1 -1
  31. package/packages/daemon/dist/spawn-manager.js +14 -3
  32. package/packages/daemon/dist/spawn-manager.js.map +1 -1
  33. package/packages/daemon/package.json +12 -12
  34. package/packages/daemon/src/server.ts +17 -0
  35. package/packages/daemon/src/spawn-manager.ts +21 -3
  36. package/packages/hooks/package.json +4 -4
  37. package/packages/mcp/CHANGELOG.md +28 -0
  38. package/packages/mcp/README.md +31 -0
  39. package/packages/mcp/dist/bin.js +18 -5
  40. package/packages/mcp/dist/bin.js.map +1 -1
  41. package/packages/mcp/dist/{client.d.ts → client-adapter.d.ts} +22 -36
  42. package/packages/mcp/dist/client-adapter.d.ts.map +1 -0
  43. package/packages/mcp/dist/client-adapter.js +227 -0
  44. package/packages/mcp/dist/client-adapter.js.map +1 -0
  45. package/packages/mcp/dist/hybrid-client.d.ts +1 -31
  46. package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
  47. package/packages/mcp/dist/hybrid-client.js +3 -153
  48. package/packages/mcp/dist/hybrid-client.js.map +1 -1
  49. package/packages/mcp/dist/index.d.ts +2 -3
  50. package/packages/mcp/dist/index.d.ts.map +1 -1
  51. package/packages/mcp/dist/index.js +4 -3
  52. package/packages/mcp/dist/index.js.map +1 -1
  53. package/packages/mcp/dist/resources/agents.d.ts +1 -1
  54. package/packages/mcp/dist/resources/agents.d.ts.map +1 -1
  55. package/packages/mcp/dist/resources/inbox.d.ts +1 -1
  56. package/packages/mcp/dist/resources/inbox.d.ts.map +1 -1
  57. package/packages/mcp/dist/resources/project.d.ts +1 -1
  58. package/packages/mcp/dist/resources/project.d.ts.map +1 -1
  59. package/packages/mcp/dist/server.d.ts +5 -1
  60. package/packages/mcp/dist/server.d.ts.map +1 -1
  61. package/packages/mcp/dist/server.js.map +1 -1
  62. package/packages/mcp/dist/simple.d.ts +1 -1
  63. package/packages/mcp/dist/simple.d.ts.map +1 -1
  64. package/packages/mcp/dist/simple.js +1 -1
  65. package/packages/mcp/dist/simple.js.map +1 -1
  66. package/packages/mcp/dist/tools/relay-broadcast.d.ts +1 -1
  67. package/packages/mcp/dist/tools/relay-broadcast.d.ts.map +1 -1
  68. package/packages/mcp/dist/tools/relay-channel.d.ts +1 -1
  69. package/packages/mcp/dist/tools/relay-channel.d.ts.map +1 -1
  70. package/packages/mcp/dist/tools/relay-connected.d.ts +1 -1
  71. package/packages/mcp/dist/tools/relay-connected.d.ts.map +1 -1
  72. package/packages/mcp/dist/tools/relay-consensus.d.ts +7 -7
  73. package/packages/mcp/dist/tools/relay-consensus.d.ts.map +1 -1
  74. package/packages/mcp/dist/tools/relay-continuity.d.ts +1 -1
  75. package/packages/mcp/dist/tools/relay-continuity.d.ts.map +1 -1
  76. package/packages/mcp/dist/tools/relay-health.d.ts +1 -1
  77. package/packages/mcp/dist/tools/relay-health.d.ts.map +1 -1
  78. package/packages/mcp/dist/tools/relay-inbox.d.ts +2 -2
  79. package/packages/mcp/dist/tools/relay-inbox.d.ts.map +1 -1
  80. package/packages/mcp/dist/tools/relay-logs.d.ts +1 -1
  81. package/packages/mcp/dist/tools/relay-logs.d.ts.map +1 -1
  82. package/packages/mcp/dist/tools/relay-messages.d.ts +7 -7
  83. package/packages/mcp/dist/tools/relay-messages.d.ts.map +1 -1
  84. package/packages/mcp/dist/tools/relay-metrics.d.ts +1 -1
  85. package/packages/mcp/dist/tools/relay-metrics.d.ts.map +1 -1
  86. package/packages/mcp/dist/tools/relay-metrics.js +4 -4
  87. package/packages/mcp/dist/tools/relay-metrics.js.map +1 -1
  88. package/packages/mcp/dist/tools/relay-release.d.ts +1 -1
  89. package/packages/mcp/dist/tools/relay-release.d.ts.map +1 -1
  90. package/packages/mcp/dist/tools/relay-remove-agent.d.ts +1 -1
  91. package/packages/mcp/dist/tools/relay-remove-agent.d.ts.map +1 -1
  92. package/packages/mcp/dist/tools/relay-send.d.ts +3 -3
  93. package/packages/mcp/dist/tools/relay-send.d.ts.map +1 -1
  94. package/packages/mcp/dist/tools/relay-shadow.d.ts +1 -1
  95. package/packages/mcp/dist/tools/relay-shadow.d.ts.map +1 -1
  96. package/packages/mcp/dist/tools/relay-spawn.d.ts +3 -3
  97. package/packages/mcp/dist/tools/relay-spawn.d.ts.map +1 -1
  98. package/packages/mcp/dist/tools/relay-status.d.ts +1 -1
  99. package/packages/mcp/dist/tools/relay-status.d.ts.map +1 -1
  100. package/packages/mcp/dist/tools/relay-subscribe.d.ts +1 -1
  101. package/packages/mcp/dist/tools/relay-subscribe.d.ts.map +1 -1
  102. package/packages/mcp/dist/tools/relay-who.d.ts +1 -1
  103. package/packages/mcp/dist/tools/relay-who.d.ts.map +1 -1
  104. package/packages/mcp/package.json +13 -4
  105. package/packages/mcp/src/bin.ts +21 -6
  106. package/packages/mcp/src/client-adapter.ts +346 -0
  107. package/packages/mcp/src/hybrid-client.ts +3 -202
  108. package/packages/mcp/src/index.ts +12 -5
  109. package/packages/mcp/src/resources/agents.ts +1 -1
  110. package/packages/mcp/src/resources/inbox.ts +1 -1
  111. package/packages/mcp/src/resources/project.ts +1 -1
  112. package/packages/mcp/src/server.ts +5 -1
  113. package/packages/mcp/src/simple.ts +1 -1
  114. package/packages/mcp/src/tools/relay-broadcast.ts +1 -1
  115. package/packages/mcp/src/tools/relay-channel.ts +1 -1
  116. package/packages/mcp/src/tools/relay-connected.ts +1 -1
  117. package/packages/mcp/src/tools/relay-consensus.ts +1 -1
  118. package/packages/mcp/src/tools/relay-continuity.ts +1 -1
  119. package/packages/mcp/src/tools/relay-health.ts +1 -1
  120. package/packages/mcp/src/tools/relay-inbox.ts +1 -1
  121. package/packages/mcp/src/tools/relay-logs.ts +1 -1
  122. package/packages/mcp/src/tools/relay-messages.ts +1 -1
  123. package/packages/mcp/src/tools/relay-metrics.ts +7 -5
  124. package/packages/mcp/src/tools/relay-release.ts +1 -1
  125. package/packages/mcp/src/tools/relay-remove-agent.ts +1 -1
  126. package/packages/mcp/src/tools/relay-send.ts +1 -1
  127. package/packages/mcp/src/tools/relay-shadow.ts +1 -1
  128. package/packages/mcp/src/tools/relay-spawn.ts +1 -1
  129. package/packages/mcp/src/tools/relay-status.ts +1 -1
  130. package/packages/mcp/src/tools/relay-subscribe.ts +1 -1
  131. package/packages/mcp/src/tools/relay-who.ts +1 -1
  132. package/packages/mcp/tests/client.test.ts +332 -432
  133. package/packages/memory/package.json +2 -2
  134. package/packages/policy/package.json +2 -2
  135. package/packages/protocol/package.json +1 -1
  136. package/packages/resiliency/package.json +1 -1
  137. package/packages/sdk/README.md +185 -0
  138. package/packages/sdk/dist/client.d.ts +1 -1
  139. package/packages/sdk/dist/client.d.ts.map +1 -1
  140. package/packages/sdk/dist/client.js +2 -1
  141. package/packages/sdk/dist/client.js.map +1 -1
  142. package/packages/sdk/dist/standalone.d.ts +2 -0
  143. package/packages/sdk/dist/standalone.d.ts.map +1 -1
  144. package/packages/sdk/dist/standalone.js +6 -1
  145. package/packages/sdk/dist/standalone.js.map +1 -1
  146. package/packages/sdk/package.json +3 -4
  147. package/packages/sdk/src/client.ts +2 -2
  148. package/packages/sdk/src/standalone.ts +8 -1
  149. package/packages/spawner/package.json +1 -1
  150. package/packages/state/package.json +1 -1
  151. package/packages/storage/package.json +2 -2
  152. package/packages/storage/src/jsonl-adapter.test.ts +3 -1
  153. package/packages/telemetry/package.json +1 -1
  154. package/packages/trajectory/package.json +2 -2
  155. package/packages/user-directory/package.json +2 -2
  156. package/packages/utils/package.json +3 -3
  157. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
  158. package/packages/wrapper/dist/relay-pty-orchestrator.js +13 -0
  159. package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
  160. package/packages/wrapper/package.json +6 -6
  161. package/packages/wrapper/src/relay-pty-orchestrator.ts +14 -0
  162. package/packages/mcp/dist/client.d.ts.map +0 -1
  163. package/packages/mcp/dist/client.js +0 -320
  164. package/packages/mcp/dist/client.js.map +0 -1
  165. package/packages/mcp/src/client.ts +0 -485
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import fs from 'node:fs';
10
10
  import path from 'node:path';
11
+ let configCache = null;
11
12
  /**
12
13
  * Possible locations for teams.json (in order of precedence)
13
14
  */
@@ -19,50 +20,103 @@ function getTeamsConfigPaths(projectRoot) {
19
20
  }
20
21
  /**
21
22
  * Load teams.json from project root or .agent-relay directory
22
- * Returns null if no config found
23
+ * Returns null if no config found.
24
+ * Results are cached and only reloaded when the file changes.
23
25
  */
24
26
  export function loadTeamsConfig(projectRoot) {
25
27
  const configPaths = getTeamsConfigPaths(projectRoot);
28
+ // Find which config file exists
29
+ let foundConfigPath = null;
30
+ let foundMtime = 0;
26
31
  for (const configPath of configPaths) {
27
32
  if (fs.existsSync(configPath)) {
28
33
  try {
29
- const content = fs.readFileSync(configPath, 'utf-8');
30
- const config = JSON.parse(content);
31
- // Validate required fields
32
- if (!config.team || typeof config.team !== 'string') {
33
- console.error(`[teams-config] Invalid teams.json at ${configPath}: missing or invalid 'team' field`);
34
- continue;
35
- }
36
- if (!Array.isArray(config.agents)) {
37
- console.error(`[teams-config] Invalid teams.json at ${configPath}: 'agents' must be an array`);
38
- continue;
39
- }
40
- // Validate agents
41
- const validAgents = [];
42
- for (const agent of config.agents) {
43
- if (!agent.name || typeof agent.name !== 'string') {
44
- console.warn(`[teams-config] Skipping agent with missing name in ${configPath}`);
45
- continue;
46
- }
47
- if (!agent.cli || typeof agent.cli !== 'string') {
48
- console.warn(`[teams-config] Agent '${agent.name}' missing 'cli' field, defaulting to 'claude'`);
49
- agent.cli = 'claude';
50
- }
51
- validAgents.push(agent);
52
- }
53
- console.log(`[teams-config] Loaded team '${config.team}' from ${configPath} (${validAgents.length} agents)`);
54
- return {
55
- team: config.team,
56
- agents: validAgents,
57
- autoSpawn: config.autoSpawn ?? false,
58
- };
34
+ const stat = fs.statSync(configPath);
35
+ foundConfigPath = configPath;
36
+ foundMtime = stat.mtimeMs;
37
+ break;
59
38
  }
60
- catch (err) {
61
- console.error(`[teams-config] Failed to parse ${configPath}:`, err);
39
+ catch {
40
+ // Ignore stat errors, try next path
62
41
  }
63
42
  }
64
43
  }
65
- return null;
44
+ // Check cache validity
45
+ if (configCache && configCache.projectRoot === projectRoot) {
46
+ // If no config file found, return cached null result
47
+ if (!foundConfigPath && !configCache.configPath) {
48
+ return null;
49
+ }
50
+ // If same file and not modified, return cached config
51
+ if (foundConfigPath === configCache.configPath && foundMtime === configCache.mtime) {
52
+ return configCache.config;
53
+ }
54
+ }
55
+ // No config file found
56
+ if (!foundConfigPath) {
57
+ configCache = {
58
+ config: null,
59
+ projectRoot,
60
+ configPath: null,
61
+ mtime: 0,
62
+ };
63
+ return null;
64
+ }
65
+ // Load and parse config
66
+ try {
67
+ const content = fs.readFileSync(foundConfigPath, 'utf-8');
68
+ const config = JSON.parse(content);
69
+ // Validate required fields
70
+ if (!config.team || typeof config.team !== 'string') {
71
+ console.error(`[teams-config] Invalid teams.json at ${foundConfigPath}: missing or invalid 'team' field`);
72
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
73
+ return null;
74
+ }
75
+ if (!Array.isArray(config.agents)) {
76
+ console.error(`[teams-config] Invalid teams.json at ${foundConfigPath}: 'agents' must be an array`);
77
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
78
+ return null;
79
+ }
80
+ // Validate agents
81
+ const validAgents = [];
82
+ for (const agent of config.agents) {
83
+ if (!agent.name || typeof agent.name !== 'string') {
84
+ console.warn(`[teams-config] Skipping agent with missing name in ${foundConfigPath}`);
85
+ continue;
86
+ }
87
+ if (!agent.cli || typeof agent.cli !== 'string') {
88
+ console.warn(`[teams-config] Agent '${agent.name}' missing 'cli' field, defaulting to 'claude'`);
89
+ agent.cli = 'claude';
90
+ }
91
+ validAgents.push(agent);
92
+ }
93
+ console.log(`[teams-config] Loaded team '${config.team}' from ${foundConfigPath} (${validAgents.length} agents)`);
94
+ const result = {
95
+ team: config.team,
96
+ agents: validAgents,
97
+ autoSpawn: config.autoSpawn ?? false,
98
+ };
99
+ // Update cache
100
+ configCache = {
101
+ config: result,
102
+ projectRoot,
103
+ configPath: foundConfigPath,
104
+ mtime: foundMtime,
105
+ };
106
+ return result;
107
+ }
108
+ catch (err) {
109
+ console.error(`[teams-config] Failed to parse ${foundConfigPath}:`, err);
110
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
111
+ return null;
112
+ }
113
+ }
114
+ /**
115
+ * Clear the teams config cache.
116
+ * Useful for testing or when you know the config has changed.
117
+ */
118
+ export function clearTeamsConfigCache() {
119
+ configCache = null;
66
120
  }
67
121
  /**
68
122
  * Check if an agent name is valid according to teams.json
@@ -1 +1 @@
1
- {"version":3,"file":"teams-config.js","sourceRoot":"","sources":["../src/teams-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"teams-config.js","sourceRoot":"","sources":["../src/teams-config.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/config",
3
- "version": "2.1.13",
3
+ "version": "2.1.15",
4
4
  "description": "Shared configuration schemas and loaders for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -83,7 +83,7 @@
83
83
  "test:watch": "vitest"
84
84
  },
85
85
  "dependencies": {
86
- "@agent-relay/protocol": "2.1.13",
86
+ "@agent-relay/protocol": "2.1.15",
87
87
  "zod": "^3.23.8",
88
88
  "zod-to-json-schema": "^3.23.1"
89
89
  },
@@ -10,6 +10,16 @@
10
10
  import fs from 'node:fs';
11
11
  import path from 'node:path';
12
12
 
13
+ /** Cache for teams config to avoid repeated file reads and log spam */
14
+ interface TeamsConfigCache {
15
+ config: TeamsConfig | null;
16
+ projectRoot: string;
17
+ configPath: string | null;
18
+ mtime: number;
19
+ }
20
+
21
+ let configCache: TeamsConfigCache | null = null;
22
+
13
23
  /** Agent definition in teams.json */
14
24
  export interface TeamAgentConfig {
15
25
  /** Agent name (used for spawn and validation) */
@@ -44,56 +54,113 @@ function getTeamsConfigPaths(projectRoot: string): string[] {
44
54
 
45
55
  /**
46
56
  * Load teams.json from project root or .agent-relay directory
47
- * Returns null if no config found
57
+ * Returns null if no config found.
58
+ * Results are cached and only reloaded when the file changes.
48
59
  */
49
60
  export function loadTeamsConfig(projectRoot: string): TeamsConfig | null {
50
61
  const configPaths = getTeamsConfigPaths(projectRoot);
51
62
 
63
+ // Find which config file exists
64
+ let foundConfigPath: string | null = null;
65
+ let foundMtime = 0;
52
66
  for (const configPath of configPaths) {
53
67
  if (fs.existsSync(configPath)) {
54
68
  try {
55
- const content = fs.readFileSync(configPath, 'utf-8');
56
- const config = JSON.parse(content) as TeamsConfig;
57
-
58
- // Validate required fields
59
- if (!config.team || typeof config.team !== 'string') {
60
- console.error(`[teams-config] Invalid teams.json at ${configPath}: missing or invalid 'team' field`);
61
- continue;
62
- }
63
-
64
- if (!Array.isArray(config.agents)) {
65
- console.error(`[teams-config] Invalid teams.json at ${configPath}: 'agents' must be an array`);
66
- continue;
67
- }
68
-
69
- // Validate agents
70
- const validAgents: TeamAgentConfig[] = [];
71
- for (const agent of config.agents) {
72
- if (!agent.name || typeof agent.name !== 'string') {
73
- console.warn(`[teams-config] Skipping agent with missing name in ${configPath}`);
74
- continue;
75
- }
76
- if (!agent.cli || typeof agent.cli !== 'string') {
77
- console.warn(`[teams-config] Agent '${agent.name}' missing 'cli' field, defaulting to 'claude'`);
78
- agent.cli = 'claude';
79
- }
80
- validAgents.push(agent);
81
- }
82
-
83
- console.log(`[teams-config] Loaded team '${config.team}' from ${configPath} (${validAgents.length} agents)`);
84
-
85
- return {
86
- team: config.team,
87
- agents: validAgents,
88
- autoSpawn: config.autoSpawn ?? false,
89
- };
90
- } catch (err) {
91
- console.error(`[teams-config] Failed to parse ${configPath}:`, err);
69
+ const stat = fs.statSync(configPath);
70
+ foundConfigPath = configPath;
71
+ foundMtime = stat.mtimeMs;
72
+ break;
73
+ } catch {
74
+ // Ignore stat errors, try next path
92
75
  }
93
76
  }
94
77
  }
95
78
 
96
- return null;
79
+ // Check cache validity
80
+ if (configCache && configCache.projectRoot === projectRoot) {
81
+ // If no config file found, return cached null result
82
+ if (!foundConfigPath && !configCache.configPath) {
83
+ return null;
84
+ }
85
+ // If same file and not modified, return cached config
86
+ if (foundConfigPath === configCache.configPath && foundMtime === configCache.mtime) {
87
+ return configCache.config;
88
+ }
89
+ }
90
+
91
+ // No config file found
92
+ if (!foundConfigPath) {
93
+ configCache = {
94
+ config: null,
95
+ projectRoot,
96
+ configPath: null,
97
+ mtime: 0,
98
+ };
99
+ return null;
100
+ }
101
+
102
+ // Load and parse config
103
+ try {
104
+ const content = fs.readFileSync(foundConfigPath, 'utf-8');
105
+ const config = JSON.parse(content) as TeamsConfig;
106
+
107
+ // Validate required fields
108
+ if (!config.team || typeof config.team !== 'string') {
109
+ console.error(`[teams-config] Invalid teams.json at ${foundConfigPath}: missing or invalid 'team' field`);
110
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
111
+ return null;
112
+ }
113
+
114
+ if (!Array.isArray(config.agents)) {
115
+ console.error(`[teams-config] Invalid teams.json at ${foundConfigPath}: 'agents' must be an array`);
116
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
117
+ return null;
118
+ }
119
+
120
+ // Validate agents
121
+ const validAgents: TeamAgentConfig[] = [];
122
+ for (const agent of config.agents) {
123
+ if (!agent.name || typeof agent.name !== 'string') {
124
+ console.warn(`[teams-config] Skipping agent with missing name in ${foundConfigPath}`);
125
+ continue;
126
+ }
127
+ if (!agent.cli || typeof agent.cli !== 'string') {
128
+ console.warn(`[teams-config] Agent '${agent.name}' missing 'cli' field, defaulting to 'claude'`);
129
+ agent.cli = 'claude';
130
+ }
131
+ validAgents.push(agent);
132
+ }
133
+
134
+ console.log(`[teams-config] Loaded team '${config.team}' from ${foundConfigPath} (${validAgents.length} agents)`);
135
+
136
+ const result: TeamsConfig = {
137
+ team: config.team,
138
+ agents: validAgents,
139
+ autoSpawn: config.autoSpawn ?? false,
140
+ };
141
+
142
+ // Update cache
143
+ configCache = {
144
+ config: result,
145
+ projectRoot,
146
+ configPath: foundConfigPath,
147
+ mtime: foundMtime,
148
+ };
149
+
150
+ return result;
151
+ } catch (err) {
152
+ console.error(`[teams-config] Failed to parse ${foundConfigPath}:`, err);
153
+ configCache = { config: null, projectRoot, configPath: foundConfigPath, mtime: foundMtime };
154
+ return null;
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Clear the teams config cache.
160
+ * Useful for testing or when you know the config has changed.
161
+ */
162
+ export function clearTeamsConfigCache(): void {
163
+ configCache = null;
97
164
  }
98
165
 
99
166
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/continuity",
3
- "version": "2.1.13",
3
+ "version": "2.1.15",
4
4
  "description": "Session continuity manager for Relay (ledgers, handoffs, resume)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/memory": "2.1.13"
25
+ "@agent-relay/memory": "2.1.15"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAc,KAAK,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AA+BpF,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAsB,MAAM,8BAA8B,CAAC;AAIjI,OAAO,EAAuC,KAAK,WAAW,EAAuD,MAAM,iBAAiB,CAAC;AAG7I,OAAO,EACL,oBAAoB,EAEpB,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AAqBpC,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,8CAA8C;IAC9C,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kGAAkG;IAClG,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC1D,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACtD;AAED,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AASF,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,OAAO,CAAC,CAAiB;IACjC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,CAAC,uBAAuB,CAAC,CAAiB;IACjD,OAAO,CAAC,SAAS,CAAC,CAAmB;IACrC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAC,CAAuB;IACzC,OAAO,CAAC,sBAAsB,CAAC,CAAiB;IAChD,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAgB;IAEtC,yBAAyB;IACzB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAK;IAE5B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAE3E,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAO;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAS;gBAE5C,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAyB9C;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA+BhC;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC;;;OAGG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAItC;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAY5C;;OAEG;YACW,WAAW;IAiFzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8L5B;;OAEG;YACW,aAAa;IA0G3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAuCjC;;OAEG;IACG,uBAAuB,CAC3B,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,OAAO,CAAC;IAqBnB;;OAEG;IACH,eAAe,IAAI,WAAW,EAAE;IAIhC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIzD;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIvD;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAmCnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsE3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4KxB;;OAEG;IACH,OAAO,CAAC,aAAa;IA6jBrB,OAAO,CAAC,SAAS;IAyBjB,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,6BAA6B;IAQrC,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI7E;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0B3B;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,YAAY,IAAI,oBAAoB,GAAG,SAAS;CAGjD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -275,6 +275,24 @@ export class Daemon {
275
275
  // Wire spawn tracking to router so messages are queued during spawn
276
276
  onMarkSpawning: (name) => this.router.markSpawning(name),
277
277
  onClearSpawning: (name) => this.router.clearSpawning(name),
278
+ // Fallback for releasing agents not spawned by this instance
279
+ onReleaseFallback: async (agentName, _reason) => {
280
+ // Check if agent is connected to the router
281
+ if (this.router.forceRemoveAgent(agentName)) {
282
+ log.info(`Release fallback: force-disconnected agent ${agentName}`);
283
+ // Also clean up from storage if available
284
+ if (this.storage?.removeAgent) {
285
+ try {
286
+ await this.storage.removeAgent(agentName);
287
+ }
288
+ catch (err) {
289
+ log.warn(`Failed to remove agent ${agentName} from storage:`, { error: String(err) });
290
+ }
291
+ }
292
+ return true;
293
+ }
294
+ return false;
295
+ },
278
296
  });
279
297
  log.info('SpawnManager initialized with spawn tracking callbacks');
280
298
  }