agent-relay 1.3.1 → 1.3.3
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/.trajectories/active/traj_3yx9dy148mge.json +42 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.json +49 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.md +31 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.json +49 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.md +31 -0
- package/.trajectories/completed/2026-01/traj_6unwwmgyj5sq.json +109 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.json +49 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.md +31 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.json +66 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.md +36 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.json +49 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.md +31 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.json +65 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.md +37 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.json +36 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.md +21 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.json +101 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.md +52 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.json +61 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.md +36 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.json +73 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.md +41 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.json +77 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.md +42 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.json +109 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.md +56 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.json +113 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.md +57 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.json +61 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.md +36 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.json +49 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.md +31 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.json +49 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.md +31 -0
- package/.trajectories/index.json +140 -1
- package/README.md +23 -9
- package/TRAIL_GIT_AUTH_FIX.md +113 -0
- package/deploy/workspace/codex.config.toml +1 -1
- package/deploy/workspace/entrypoint.sh +20 -79
- package/deploy/workspace/gh-relay +156 -0
- package/deploy/workspace/git-credential-relay +5 -1
- package/dist/bridge/multi-project-client.js +13 -10
- package/dist/bridge/spawner.d.ts +2 -0
- package/dist/bridge/spawner.js +58 -76
- package/dist/bridge/types.d.ts +2 -0
- package/dist/cli/index.d.ts +8 -6
- package/dist/cli/index.js +297 -30
- package/dist/cloud/api/admin.js +16 -3
- package/dist/cloud/api/codex-auth-helper.js +28 -8
- package/dist/cloud/api/consensus.d.ts +13 -0
- package/dist/cloud/api/consensus.js +259 -0
- package/dist/cloud/api/daemons.js +205 -1
- package/dist/cloud/api/git.js +37 -7
- package/dist/cloud/api/onboarding.js +4 -1
- package/dist/cloud/api/provider-env.d.ts +5 -0
- package/dist/cloud/api/provider-env.js +27 -0
- package/dist/cloud/api/providers.js +2 -0
- package/dist/cloud/api/test-helpers.js +130 -0
- package/dist/cloud/api/workspaces.js +38 -3
- package/dist/cloud/db/bulk-ingest.d.ts +88 -0
- package/dist/cloud/db/bulk-ingest.js +268 -0
- package/dist/cloud/db/drizzle.d.ts +33 -0
- package/dist/cloud/db/drizzle.js +174 -2
- package/dist/cloud/db/index.d.ts +24 -5
- package/dist/cloud/db/index.js +19 -4
- package/dist/cloud/db/schema.d.ts +397 -3
- package/dist/cloud/db/schema.js +75 -1
- package/dist/cloud/provisioner/index.d.ts +8 -0
- package/dist/cloud/provisioner/index.js +256 -50
- package/dist/cloud/server.js +47 -3
- package/dist/cloud/services/index.d.ts +1 -0
- package/dist/cloud/services/index.js +2 -0
- package/dist/cloud/services/nango.d.ts +3 -4
- package/dist/cloud/services/nango.js +11 -33
- package/dist/cloud/services/workspace-keepalive.d.ts +76 -0
- package/dist/cloud/services/workspace-keepalive.js +234 -0
- package/dist/config/relay-config.d.ts +23 -0
- package/dist/config/relay-config.js +23 -0
- package/dist/daemon/agent-manager.d.ts +20 -1
- package/dist/daemon/agent-manager.js +51 -0
- package/dist/daemon/agent-registry.js +4 -4
- package/dist/daemon/agent-signing.d.ts +158 -0
- package/dist/daemon/agent-signing.js +523 -0
- package/dist/daemon/api.js +18 -1
- package/dist/daemon/cli-auth.d.ts +4 -1
- package/dist/daemon/cli-auth.js +55 -11
- package/dist/daemon/cloud-sync.d.ts +47 -1
- package/dist/daemon/cloud-sync.js +152 -3
- package/dist/daemon/connection.d.ts +28 -0
- package/dist/daemon/connection.js +113 -22
- package/dist/daemon/consensus-integration.d.ts +167 -0
- package/dist/daemon/consensus-integration.js +371 -0
- package/dist/daemon/consensus.d.ts +271 -0
- package/dist/daemon/consensus.js +632 -0
- package/dist/daemon/delivery-tracker.d.ts +34 -0
- package/dist/daemon/delivery-tracker.js +104 -0
- package/dist/daemon/enhanced-features.d.ts +118 -0
- package/dist/daemon/enhanced-features.js +178 -0
- package/dist/daemon/index.d.ts +4 -0
- package/dist/daemon/index.js +5 -0
- package/dist/daemon/rate-limiter.d.ts +68 -0
- package/dist/daemon/rate-limiter.js +130 -0
- package/dist/daemon/router.d.ts +18 -11
- package/dist/daemon/router.js +57 -113
- package/dist/daemon/server.d.ts +13 -1
- package/dist/daemon/server.js +71 -9
- package/dist/daemon/sync-queue.d.ts +116 -0
- package/dist/daemon/sync-queue.js +361 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/116-de2a4ac06e5000dc.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/919-87d604a5d76c1fbd.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/{page-c617745b81344f4f.js → page-7f64824ae7d06707.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-3f559d393902aad2.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-16d1715ddaa874ee.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/{page-dc786c183425c2ac.js → page-814efc4d77b4191d.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-2ee6beb2ae96d210.js → main-5a40a5ae29646e1b.js} +1 -1
- package/dist/dashboard/out/_next/static/css/44d2b52637b511bc.css +1 -0
- package/dist/dashboard/out/app/onboarding.html +1 -1
- package/dist/dashboard/out/app/onboarding.txt +1 -1
- package/dist/dashboard/out/app.html +1 -1
- package/dist/dashboard/out/app.txt +2 -2
- package/dist/dashboard/out/cloud/link.html +1 -0
- package/dist/dashboard/out/cloud/link.txt +7 -0
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +1 -1
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +2 -2
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/login.html +2 -3
- package/dist/dashboard/out/login.txt +2 -2
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +2 -2
- package/dist/dashboard/out/pricing.txt +1 -1
- package/dist/dashboard/out/providers/setup/claude.html +1 -1
- package/dist/dashboard/out/providers/setup/claude.txt +1 -1
- package/dist/dashboard/out/providers/setup/codex.html +1 -1
- package/dist/dashboard/out/providers/setup/codex.txt +1 -1
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +1 -1
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +1 -1
- package/dist/dashboard-server/server.js +244 -28
- package/dist/health-worker-manager.d.ts +62 -0
- package/dist/health-worker-manager.js +144 -0
- package/dist/health-worker.d.ts +9 -0
- package/dist/health-worker.js +79 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/memory/context-compaction.d.ts +156 -0
- package/dist/memory/context-compaction.js +453 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +1 -0
- package/dist/protocol/channels.js +4 -4
- package/dist/protocol/framing.d.ts +72 -10
- package/dist/protocol/framing.js +194 -25
- package/dist/storage/adapter.d.ts +8 -1
- package/dist/storage/adapter.js +11 -0
- package/dist/storage/batched-sqlite-adapter.d.ts +71 -0
- package/dist/storage/batched-sqlite-adapter.js +183 -0
- package/dist/storage/dead-letter-queue.d.ts +196 -0
- package/dist/storage/dead-letter-queue.js +427 -0
- package/dist/storage/dlq-adapter.d.ts +195 -0
- package/dist/storage/dlq-adapter.js +664 -0
- package/dist/trajectory/config.d.ts +32 -14
- package/dist/trajectory/config.js +38 -16
- package/dist/trajectory/integration.js +217 -64
- package/dist/utils/git-remote.d.ts +47 -0
- package/dist/utils/git-remote.js +125 -0
- package/dist/utils/id-generator.d.ts +35 -0
- package/dist/utils/id-generator.js +60 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/precompiled-patterns.d.ts +110 -0
- package/dist/utils/precompiled-patterns.js +322 -0
- package/dist/wrapper/auth-detection.js +1 -1
- package/dist/wrapper/base-wrapper.d.ts +40 -0
- package/dist/wrapper/base-wrapper.js +60 -6
- package/dist/wrapper/client.d.ts +14 -4
- package/dist/wrapper/client.js +89 -31
- package/dist/wrapper/idle-detector.d.ts +102 -0
- package/dist/wrapper/idle-detector.js +279 -0
- package/dist/wrapper/parser.d.ts +4 -0
- package/dist/wrapper/parser.js +19 -1
- package/dist/wrapper/pty-wrapper.d.ts +14 -2
- package/dist/wrapper/pty-wrapper.js +132 -32
- package/dist/wrapper/shared.d.ts +1 -1
- package/dist/wrapper/shared.js +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +20 -2
- package/dist/wrapper/tmux-wrapper.js +163 -40
- package/package.json +3 -1
- package/scripts/run-migrations.js +43 -0
- package/scripts/verify-schema.js +134 -0
- package/tests/benchmarks/protocol.bench.ts +310 -0
- package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/899-fc02ed79e3de4302.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +0 -1
- package/dist/dashboard/out/_next/static/css/48a8fbe3e659080e.css +0 -1
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_ssgManifest.js +0 -0
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import net from 'node:net';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
|
-
import {
|
|
7
|
+
import { generateId } from '../utils/id-generator.js';
|
|
8
8
|
import { PROTOCOL_VERSION, } from '../protocol/types.js';
|
|
9
|
-
import { encodeFrame, FrameParser } from '../protocol/framing.js';
|
|
9
|
+
import { encodeFrameLegacy as encodeFrame, FrameParser } from '../protocol/framing.js';
|
|
10
10
|
export class MultiProjectClient {
|
|
11
11
|
projects;
|
|
12
12
|
connections = new Map();
|
|
@@ -49,10 +49,12 @@ export class MultiProjectClient {
|
|
|
49
49
|
const socket = net.createConnection(project.socketPath, () => {
|
|
50
50
|
this.sendHello(conn);
|
|
51
51
|
});
|
|
52
|
+
const parser = new FrameParser();
|
|
53
|
+
parser.setLegacyMode(true); // Use 4-byte header for backwards compatibility
|
|
52
54
|
const conn = {
|
|
53
55
|
config: project,
|
|
54
56
|
socket,
|
|
55
|
-
parser
|
|
57
|
+
parser,
|
|
56
58
|
ready: false,
|
|
57
59
|
};
|
|
58
60
|
socket.on('data', (data) => this.handleData(conn, data));
|
|
@@ -96,7 +98,7 @@ export class MultiProjectClient {
|
|
|
96
98
|
const hello = {
|
|
97
99
|
v: PROTOCOL_VERSION,
|
|
98
100
|
type: 'HELLO',
|
|
99
|
-
id:
|
|
101
|
+
id: generateId(),
|
|
100
102
|
ts: Date.now(),
|
|
101
103
|
payload: {
|
|
102
104
|
agent: this.options.agentName,
|
|
@@ -142,7 +144,7 @@ export class MultiProjectClient {
|
|
|
142
144
|
this.send(conn, {
|
|
143
145
|
v: PROTOCOL_VERSION,
|
|
144
146
|
type: 'PONG',
|
|
145
|
-
id:
|
|
147
|
+
id: generateId(),
|
|
146
148
|
ts: Date.now(),
|
|
147
149
|
payload: envelope.payload ?? {},
|
|
148
150
|
});
|
|
@@ -157,7 +159,7 @@ export class MultiProjectClient {
|
|
|
157
159
|
this.send(conn, {
|
|
158
160
|
v: PROTOCOL_VERSION,
|
|
159
161
|
type: 'ACK',
|
|
160
|
-
id:
|
|
162
|
+
id: generateId(),
|
|
161
163
|
ts: Date.now(),
|
|
162
164
|
payload: {
|
|
163
165
|
ack_id: envelope.id,
|
|
@@ -212,7 +214,7 @@ export class MultiProjectClient {
|
|
|
212
214
|
const envelope = {
|
|
213
215
|
v: PROTOCOL_VERSION,
|
|
214
216
|
type: 'SEND',
|
|
215
|
-
id:
|
|
217
|
+
id: generateId(),
|
|
216
218
|
ts: Date.now(),
|
|
217
219
|
to: targetAgent,
|
|
218
220
|
payload: {
|
|
@@ -239,7 +241,7 @@ export class MultiProjectClient {
|
|
|
239
241
|
const envelope = {
|
|
240
242
|
v: PROTOCOL_VERSION,
|
|
241
243
|
type: 'SEND',
|
|
242
|
-
id:
|
|
244
|
+
id: generateId(),
|
|
243
245
|
ts: Date.now(),
|
|
244
246
|
to: '*',
|
|
245
247
|
payload: {
|
|
@@ -313,9 +315,10 @@ export class MultiProjectClient {
|
|
|
313
315
|
const socket = net.createConnection(conn.config.socketPath, () => {
|
|
314
316
|
this.sendHello(conn);
|
|
315
317
|
});
|
|
316
|
-
// Update connection with new socket
|
|
318
|
+
// Update connection with new socket and fresh parser
|
|
317
319
|
conn.socket = socket;
|
|
318
320
|
conn.parser = new FrameParser();
|
|
321
|
+
conn.parser.setLegacyMode(true); // Use 4-byte header for backwards compatibility
|
|
319
322
|
socket.on('data', (data) => this.handleData(conn, data));
|
|
320
323
|
socket.on('close', () => {
|
|
321
324
|
const wasReady = conn.ready;
|
|
@@ -369,7 +372,7 @@ export class MultiProjectClient {
|
|
|
369
372
|
this.send(conn, {
|
|
370
373
|
v: PROTOCOL_VERSION,
|
|
371
374
|
type: 'BYE',
|
|
372
|
-
id:
|
|
375
|
+
id: generateId(),
|
|
373
376
|
ts: Date.now(),
|
|
374
377
|
payload: {},
|
|
375
378
|
});
|
package/dist/bridge/spawner.d.ts
CHANGED
package/dist/bridge/spawner.js
CHANGED
|
@@ -12,17 +12,35 @@ import { PtyWrapper } from '../wrapper/pty-wrapper.js';
|
|
|
12
12
|
import { selectShadowCli } from './shadow-cli.js';
|
|
13
13
|
import { AgentPolicyService } from '../policy/agent-policy.js';
|
|
14
14
|
import { buildClaudeArgs } from '../utils/agent-config.js';
|
|
15
|
+
import { getUserDirectoryService } from '../daemon/user-directory.js';
|
|
15
16
|
/**
|
|
16
|
-
* Get a
|
|
17
|
-
*
|
|
18
|
-
* Loading full docs (400+ lines) overwhelms agents and causes "meandering".
|
|
17
|
+
* Get relay protocol instructions for a spawned agent.
|
|
18
|
+
* This provides the agent with the communication protocol it needs to work with the relay.
|
|
19
19
|
*/
|
|
20
|
-
function
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
function getRelayInstructions(agentName) {
|
|
21
|
+
return [
|
|
22
|
+
'# Agent Relay Protocol',
|
|
23
|
+
'',
|
|
24
|
+
`You are agent "${agentName}" connected to Agent Relay for multi-agent coordination.`,
|
|
25
|
+
'',
|
|
26
|
+
'## Sending Messages',
|
|
27
|
+
'',
|
|
28
|
+
'Use fenced format for all messages:',
|
|
29
|
+
'->relay:TargetAgent <<<',
|
|
30
|
+
'Your message here.>>>',
|
|
31
|
+
'',
|
|
32
|
+
'## Communication Rules',
|
|
33
|
+
'',
|
|
34
|
+
'1. **ACK immediately** - When you receive a task:',
|
|
35
|
+
' ->relay:Sender <<<',
|
|
36
|
+
' ACK: Brief description of task received>>>',
|
|
37
|
+
'',
|
|
38
|
+
'2. **Report completion** - When done:',
|
|
39
|
+
' ->relay:Sender <<<',
|
|
40
|
+
' DONE: Brief summary of what was completed>>>',
|
|
41
|
+
'',
|
|
42
|
+
'3. Close >>> must immediately follow content (no blank lines before it)',
|
|
43
|
+
].join('\n');
|
|
26
44
|
}
|
|
27
45
|
export class AgentSpawner {
|
|
28
46
|
activeWorkers = new Map();
|
|
@@ -150,7 +168,7 @@ export class AgentSpawner {
|
|
|
150
168
|
* Spawn a new worker agent using node-pty
|
|
151
169
|
*/
|
|
152
170
|
async spawn(request) {
|
|
153
|
-
const { name, cli, task, team, spawnerName } = request;
|
|
171
|
+
const { name, cli, task, team, spawnerName, userId } = request;
|
|
154
172
|
const debug = process.env.DEBUG_SPAWN === '1';
|
|
155
173
|
// Check if worker already exists
|
|
156
174
|
if (this.activeWorkers.has(name)) {
|
|
@@ -208,6 +226,14 @@ export class AgentSpawner {
|
|
|
208
226
|
if (isCodexCli && !args.includes('--dangerously-bypass-approvals-and-sandbox')) {
|
|
209
227
|
args.push('--dangerously-bypass-approvals-and-sandbox');
|
|
210
228
|
}
|
|
229
|
+
// Inject relay protocol instructions via CLI-specific system prompt
|
|
230
|
+
const relayInstructions = getRelayInstructions(name);
|
|
231
|
+
if (isClaudeCli && !args.includes('--append-system-prompt')) {
|
|
232
|
+
args.push('--append-system-prompt', relayInstructions);
|
|
233
|
+
}
|
|
234
|
+
else if (isCodexCli && !args.some(a => a.includes('developer_instructions'))) {
|
|
235
|
+
args.push('--config', `developer_instructions=${relayInstructions}`);
|
|
236
|
+
}
|
|
211
237
|
if (debug)
|
|
212
238
|
console.log(`[spawner:debug] Spawning ${name} with: ${command} ${args.join(' ')}`);
|
|
213
239
|
// Create PtyWrapper config
|
|
@@ -219,6 +245,19 @@ export class AgentSpawner {
|
|
|
219
245
|
const agentCwd = request.cwd || this.projectRoot;
|
|
220
246
|
// Log whether nested spawning will be enabled for this agent
|
|
221
247
|
console.log(`[spawner] Spawning ${name}: dashboardPort=${this.dashboardPort || 'none'} (${this.dashboardPort ? 'nested spawns enabled' : 'nested spawns disabled'})`);
|
|
248
|
+
let userEnv;
|
|
249
|
+
if (userId) {
|
|
250
|
+
try {
|
|
251
|
+
const userDirService = getUserDirectoryService();
|
|
252
|
+
userEnv = userDirService.getUserEnvironment(userId);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
console.warn('[spawner] Failed to resolve user environment, using default', {
|
|
256
|
+
userId,
|
|
257
|
+
error: err instanceof Error ? err.message : String(err),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
222
261
|
const ptyConfig = {
|
|
223
262
|
name,
|
|
224
263
|
command,
|
|
@@ -227,11 +266,14 @@ export class AgentSpawner {
|
|
|
227
266
|
cwd: agentCwd,
|
|
228
267
|
logsDir: this.logsDir,
|
|
229
268
|
dashboardPort: this.dashboardPort,
|
|
269
|
+
env: userEnv,
|
|
230
270
|
// Interactive mode - disables auto-accept for auth setup flows
|
|
231
271
|
interactive: request.interactive,
|
|
232
272
|
// Shadow agent configuration
|
|
233
273
|
shadowOf: request.shadowOf,
|
|
234
274
|
shadowSpeakOn: request.shadowSpeakOn,
|
|
275
|
+
// Skip continuity for spawned agents - they're short-lived workers
|
|
276
|
+
skipContinuity: true,
|
|
235
277
|
// Only use callbacks if dashboardPort is not set (for backwards compatibility)
|
|
236
278
|
onSpawn: this.dashboardPort ? undefined : async (workerName, workerCli, workerTask) => {
|
|
237
279
|
// Handle nested spawn requests (legacy path, may fail in non-TTY)
|
|
@@ -242,6 +284,7 @@ export class AgentSpawner {
|
|
|
242
284
|
cli: workerCli,
|
|
243
285
|
task: workerTask,
|
|
244
286
|
// Nested spawns don't inherit team - they're flat by default
|
|
287
|
+
userId,
|
|
245
288
|
});
|
|
246
289
|
},
|
|
247
290
|
onRelease: this.dashboardPort ? undefined : async (workerName) => {
|
|
@@ -314,78 +357,16 @@ export class AgentSpawner {
|
|
|
314
357
|
error,
|
|
315
358
|
};
|
|
316
359
|
}
|
|
317
|
-
//
|
|
318
|
-
//
|
|
319
|
-
|
|
320
|
-
// Only prepend relay reminder if we have an actual task
|
|
321
|
-
// Empty task = interactive mode, user will respond to prompts directly
|
|
322
|
-
if (fullMessage.trim()) {
|
|
323
|
-
// Prepend a brief relay reminder (agents have full docs via CLAUDE.md)
|
|
324
|
-
// Note: Previously loaded full 400+ line docs which overwhelmed agents
|
|
325
|
-
const relayReminder = getMinimalRelayReminder();
|
|
326
|
-
if (relayReminder) {
|
|
327
|
-
fullMessage = `${relayReminder}\n\n---\n\n${fullMessage}`;
|
|
328
|
-
if (debug)
|
|
329
|
-
console.log(`[spawner:debug] Prepended relay reminder for ${name}`);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
// Prepend policy instructions if enforcement is enabled (only if we have a task)
|
|
333
|
-
if (fullMessage.trim() && this.policyEnforcementEnabled && this.policyService) {
|
|
334
|
-
const policyInstruction = await this.policyService.getPolicyInstruction(name);
|
|
335
|
-
if (policyInstruction) {
|
|
336
|
-
fullMessage = `${policyInstruction}\n\n${fullMessage}`;
|
|
337
|
-
if (debug)
|
|
338
|
-
console.log(`[spawner:debug] Prepended policy instructions to task for ${name}`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
// Send task via relay message if provided (not via direct PTY injection)
|
|
342
|
-
// This ensures the agent is ready to receive before processing the task
|
|
343
|
-
if (fullMessage && fullMessage.trim()) {
|
|
344
|
-
if (debug)
|
|
345
|
-
console.log(`[spawner:debug] Will send task via relay: ${fullMessage.substring(0, 50)}...`);
|
|
346
|
-
// If we have dashboard API, send task as relay message
|
|
347
|
-
if (this.dashboardPort) {
|
|
348
|
-
// Wait a moment for the agent's relay client to be ready
|
|
349
|
-
await sleep(1000);
|
|
350
|
-
try {
|
|
351
|
-
const response = await fetch(`http://localhost:${this.dashboardPort}/api/send`, {
|
|
352
|
-
method: 'POST',
|
|
353
|
-
headers: { 'Content-Type': 'application/json' },
|
|
354
|
-
body: JSON.stringify({
|
|
355
|
-
to: name,
|
|
356
|
-
message: fullMessage,
|
|
357
|
-
from: '__spawner__',
|
|
358
|
-
}),
|
|
359
|
-
});
|
|
360
|
-
const result = await response.json();
|
|
361
|
-
if (result.success) {
|
|
362
|
-
if (debug)
|
|
363
|
-
console.log(`[spawner:debug] Task sent via relay to ${name}`);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
console.warn(`[spawner] Failed to send task via relay: ${result.error}`);
|
|
367
|
-
// Fall back to direct injection
|
|
368
|
-
pty.write(fullMessage + '\r');
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
catch (err) {
|
|
372
|
-
console.warn(`[spawner] Relay send failed, falling back to direct injection: ${err.message}`);
|
|
373
|
-
pty.write(fullMessage + '\r');
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
// No dashboard API available - use direct injection as fallback
|
|
378
|
-
if (debug)
|
|
379
|
-
console.log(`[spawner:debug] No dashboard API, using direct injection`);
|
|
380
|
-
pty.write(fullMessage + '\r');
|
|
381
|
-
}
|
|
382
|
-
}
|
|
360
|
+
// Note: Task is NOT sent here. The spawning agent (wrapper) waits for the worker
|
|
361
|
+
// to come online and then sends the task via normal relay message.
|
|
362
|
+
// This avoids race conditions with the agent's readyForMessages state.
|
|
383
363
|
// Track the worker
|
|
384
364
|
const workerInfo = {
|
|
385
365
|
name,
|
|
386
366
|
cli,
|
|
387
367
|
task,
|
|
388
368
|
team,
|
|
369
|
+
userId,
|
|
389
370
|
spawnedAt: Date.now(),
|
|
390
371
|
pid: pty.pid,
|
|
391
372
|
pty,
|
|
@@ -674,6 +655,7 @@ export class AgentSpawner {
|
|
|
674
655
|
cli: w.cli,
|
|
675
656
|
task: w.task,
|
|
676
657
|
team: w.team,
|
|
658
|
+
userId: w.userId,
|
|
677
659
|
spawnedAt: w.spawnedAt,
|
|
678
660
|
pid: w.pid,
|
|
679
661
|
logFile: w.logFile,
|
package/dist/bridge/types.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ export interface SpawnRequest {
|
|
|
53
53
|
shadowTriggers?: Array<'SESSION_END' | 'CODE_WRITTEN' | 'REVIEW_REQUEST' | 'EXPLICIT_ASK' | 'ALL_MESSAGES'>;
|
|
54
54
|
/** When the shadow should speak (default: ['EXPLICIT_ASK']) */
|
|
55
55
|
shadowSpeakOn?: Array<'SESSION_END' | 'CODE_WRITTEN' | 'REVIEW_REQUEST' | 'EXPLICIT_ASK' | 'ALL_MESSAGES'>;
|
|
56
|
+
/** User ID for per-user credential storage in shared workspaces */
|
|
57
|
+
userId?: string;
|
|
56
58
|
}
|
|
57
59
|
/** Policy decision details */
|
|
58
60
|
export interface PolicyDecision {
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Agent Relay CLI
|
|
4
4
|
*
|
|
5
5
|
* Commands:
|
|
6
|
-
* relay
|
|
7
|
-
* relay -
|
|
8
|
-
* relay
|
|
9
|
-
* relay
|
|
10
|
-
* relay
|
|
11
|
-
* relay
|
|
6
|
+
* relay claude - Start daemon + Dashboard coordinator with Claude
|
|
7
|
+
* relay codex - Start daemon + Dasbboard coordinator with Codex
|
|
8
|
+
* relay create-agent <cmd> - Wrap agent with real-time messaging
|
|
9
|
+
* relay create-agent -n Name cmd - Wrap with specific agent name
|
|
10
|
+
* relay up - Start daemon + dashboard
|
|
11
|
+
* relay read <id> - Read full message by ID
|
|
12
|
+
* relay agents - List connected agents
|
|
13
|
+
* relay who - Show currently active agents
|
|
12
14
|
*/
|
|
13
15
|
export {};
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|