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.
- package/dist/index.cjs +37571 -50918
- package/dist/src/cli/index.js +1 -1
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +18 -18
- package/packages/acp-bridge/package.json +2 -2
- package/packages/api-types/package.json +1 -1
- package/packages/benchmark/datasets/quick-test.yaml +20 -0
- package/packages/benchmark/dist/runners/base.d.ts.map +1 -1
- package/packages/benchmark/dist/runners/base.js +1 -0
- package/packages/benchmark/dist/runners/base.js.map +1 -1
- package/packages/benchmark/package.json +4 -4
- package/packages/benchmark/src/runners/base.ts +1 -0
- package/packages/bridge/dist/spawner.d.ts.map +1 -1
- package/packages/bridge/dist/spawner.js +2 -30
- package/packages/bridge/dist/spawner.js.map +1 -1
- package/packages/bridge/package.json +7 -8
- package/packages/bridge/src/spawner.ts +2 -29
- package/packages/cli-tester/package.json +1 -1
- package/packages/config/dist/teams-config.d.ts +7 -1
- package/packages/config/dist/teams-config.d.ts.map +1 -1
- package/packages/config/dist/teams-config.js +88 -34
- package/packages/config/dist/teams-config.js.map +1 -1
- package/packages/config/package.json +2 -2
- package/packages/config/src/teams-config.ts +106 -39
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/dist/server.d.ts.map +1 -1
- package/packages/daemon/dist/server.js +18 -0
- package/packages/daemon/dist/server.js.map +1 -1
- package/packages/daemon/dist/spawn-manager.d.ts +8 -0
- package/packages/daemon/dist/spawn-manager.d.ts.map +1 -1
- package/packages/daemon/dist/spawn-manager.js +14 -3
- package/packages/daemon/dist/spawn-manager.js.map +1 -1
- package/packages/daemon/package.json +12 -12
- package/packages/daemon/src/server.ts +17 -0
- package/packages/daemon/src/spawn-manager.ts +21 -3
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/CHANGELOG.md +28 -0
- package/packages/mcp/README.md +31 -0
- package/packages/mcp/dist/bin.js +18 -5
- package/packages/mcp/dist/bin.js.map +1 -1
- package/packages/mcp/dist/{client.d.ts → client-adapter.d.ts} +22 -36
- package/packages/mcp/dist/client-adapter.d.ts.map +1 -0
- package/packages/mcp/dist/client-adapter.js +227 -0
- package/packages/mcp/dist/client-adapter.js.map +1 -0
- package/packages/mcp/dist/hybrid-client.d.ts +1 -31
- package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
- package/packages/mcp/dist/hybrid-client.js +3 -153
- package/packages/mcp/dist/hybrid-client.js.map +1 -1
- package/packages/mcp/dist/index.d.ts +2 -3
- package/packages/mcp/dist/index.d.ts.map +1 -1
- package/packages/mcp/dist/index.js +4 -3
- package/packages/mcp/dist/index.js.map +1 -1
- package/packages/mcp/dist/resources/agents.d.ts +1 -1
- package/packages/mcp/dist/resources/agents.d.ts.map +1 -1
- package/packages/mcp/dist/resources/inbox.d.ts +1 -1
- package/packages/mcp/dist/resources/inbox.d.ts.map +1 -1
- package/packages/mcp/dist/resources/project.d.ts +1 -1
- package/packages/mcp/dist/resources/project.d.ts.map +1 -1
- package/packages/mcp/dist/server.d.ts +5 -1
- package/packages/mcp/dist/server.d.ts.map +1 -1
- package/packages/mcp/dist/server.js.map +1 -1
- package/packages/mcp/dist/simple.d.ts +1 -1
- package/packages/mcp/dist/simple.d.ts.map +1 -1
- package/packages/mcp/dist/simple.js +1 -1
- package/packages/mcp/dist/simple.js.map +1 -1
- package/packages/mcp/dist/tools/relay-broadcast.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-broadcast.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-channel.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-channel.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-connected.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-connected.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-consensus.d.ts +7 -7
- package/packages/mcp/dist/tools/relay-consensus.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-continuity.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-continuity.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-health.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-health.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-inbox.d.ts +2 -2
- package/packages/mcp/dist/tools/relay-inbox.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-logs.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-logs.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-messages.d.ts +7 -7
- package/packages/mcp/dist/tools/relay-messages.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-metrics.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-metrics.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-metrics.js +4 -4
- package/packages/mcp/dist/tools/relay-metrics.js.map +1 -1
- package/packages/mcp/dist/tools/relay-release.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-release.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-remove-agent.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-remove-agent.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-send.d.ts +3 -3
- package/packages/mcp/dist/tools/relay-send.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-shadow.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-shadow.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-spawn.d.ts +3 -3
- package/packages/mcp/dist/tools/relay-spawn.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-status.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-status.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-subscribe.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-subscribe.d.ts.map +1 -1
- package/packages/mcp/dist/tools/relay-who.d.ts +1 -1
- package/packages/mcp/dist/tools/relay-who.d.ts.map +1 -1
- package/packages/mcp/package.json +13 -4
- package/packages/mcp/src/bin.ts +21 -6
- package/packages/mcp/src/client-adapter.ts +346 -0
- package/packages/mcp/src/hybrid-client.ts +3 -202
- package/packages/mcp/src/index.ts +12 -5
- package/packages/mcp/src/resources/agents.ts +1 -1
- package/packages/mcp/src/resources/inbox.ts +1 -1
- package/packages/mcp/src/resources/project.ts +1 -1
- package/packages/mcp/src/server.ts +5 -1
- package/packages/mcp/src/simple.ts +1 -1
- package/packages/mcp/src/tools/relay-broadcast.ts +1 -1
- package/packages/mcp/src/tools/relay-channel.ts +1 -1
- package/packages/mcp/src/tools/relay-connected.ts +1 -1
- package/packages/mcp/src/tools/relay-consensus.ts +1 -1
- package/packages/mcp/src/tools/relay-continuity.ts +1 -1
- package/packages/mcp/src/tools/relay-health.ts +1 -1
- package/packages/mcp/src/tools/relay-inbox.ts +1 -1
- package/packages/mcp/src/tools/relay-logs.ts +1 -1
- package/packages/mcp/src/tools/relay-messages.ts +1 -1
- package/packages/mcp/src/tools/relay-metrics.ts +7 -5
- package/packages/mcp/src/tools/relay-release.ts +1 -1
- package/packages/mcp/src/tools/relay-remove-agent.ts +1 -1
- package/packages/mcp/src/tools/relay-send.ts +1 -1
- package/packages/mcp/src/tools/relay-shadow.ts +1 -1
- package/packages/mcp/src/tools/relay-spawn.ts +1 -1
- package/packages/mcp/src/tools/relay-status.ts +1 -1
- package/packages/mcp/src/tools/relay-subscribe.ts +1 -1
- package/packages/mcp/src/tools/relay-who.ts +1 -1
- package/packages/mcp/tests/client.test.ts +332 -432
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/README.md +185 -0
- package/packages/sdk/dist/client.d.ts +1 -1
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +2 -1
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/standalone.d.ts +2 -0
- package/packages/sdk/dist/standalone.d.ts.map +1 -1
- package/packages/sdk/dist/standalone.js +6 -1
- package/packages/sdk/dist/standalone.js.map +1 -1
- package/packages/sdk/package.json +3 -4
- package/packages/sdk/src/client.ts +2 -2
- package/packages/sdk/src/standalone.ts +8 -1
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/storage/src/jsonl-adapter.test.ts +3 -1
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +3 -3
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.js +13 -0
- package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
- package/packages/wrapper/package.json +6 -6
- package/packages/wrapper/src/relay-pty-orchestrator.ts +14 -0
- package/packages/mcp/dist/client.d.ts.map +0 -1
- package/packages/mcp/dist/client.js +0 -320
- package/packages/mcp/dist/client.js.map +0 -1
- 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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
61
|
-
|
|
39
|
+
catch {
|
|
40
|
+
// Ignore stat errors, try next path
|
|
62
41
|
}
|
|
63
42
|
}
|
|
64
43
|
}
|
|
65
|
-
|
|
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":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"teams-config.js","sourceRoot":"","sources":["../src/teams-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,IAAI,WAAW,GAA4B,IAAI,CAAC;AAwBhD;;GAEG;AACH,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;KACrC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAErD,gCAAgC;IAChC,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACrC,eAAe,GAAG,UAAU,CAAC;gBAC7B,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,MAAM;YACR,CAAC;YAAC,MAAM,CAAC;gBACP,oCAAoC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,WAAW,IAAI,WAAW,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;QAC3D,qDAAqD;QACrD,IAAI,CAAC,eAAe,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,sDAAsD;QACtD,IAAI,eAAe,KAAK,WAAW,CAAC,UAAU,IAAI,UAAU,KAAK,WAAW,CAAC,KAAK,EAAE,CAAC;YACnF,OAAO,WAAW,CAAC,MAAM,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,WAAW,GAAG;YACZ,MAAM,EAAE,IAAI;YACZ,WAAW;YACX,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,CAAC;SACT,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAElD,2BAA2B;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,wCAAwC,eAAe,mCAAmC,CAAC,CAAC;YAC1G,WAAW,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YAC5F,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,wCAAwC,eAAe,6BAA6B,CAAC,CAAC;YACpG,WAAW,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YAC5F,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB;QAClB,MAAM,WAAW,GAAsB,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,sDAAsD,eAAe,EAAE,CAAC,CAAC;gBACtF,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,IAAI,+CAA+C,CAAC,CAAC;gBACjG,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;YACvB,CAAC;YACD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,IAAI,UAAU,eAAe,KAAK,WAAW,CAAC,MAAM,UAAU,CAAC,CAAC;QAElH,MAAM,MAAM,GAAgB;YAC1B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;SACrC,CAAC;QAEF,eAAe;QACf,WAAW,GAAG;YACZ,MAAM,EAAE,MAAM;YACd,WAAW;YACX,UAAU,EAAE,eAAe;YAC3B,KAAK,EAAE,UAAU;SAClB,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,eAAe,GAAG,EAAE,GAAG,CAAC,CAAC;QACzE,WAAW,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAC5F,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,SAAiB;IACrE,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE5C,8BAA8B;IAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,SAAiB;IACnE,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACrD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/config",
|
|
3
|
-
"version": "2.1.
|
|
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.
|
|
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
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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;
|
|
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
|
}
|