agent-relay 2.1.4 → 2.1.6
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/README.md +85 -236
- package/dist/index.cjs +281 -24
- package/package.json +19 -19
- package/packages/api-types/package.json +1 -1
- package/packages/benchmark/package.json +4 -4
- package/packages/bridge/dist/spawner.d.ts.map +1 -1
- package/packages/bridge/dist/spawner.js +39 -5
- package/packages/bridge/dist/spawner.js.map +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/bridge/src/spawner.ts +40 -5
- package/packages/cli-tester/package.json +1 -1
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/dist/server.d.ts +5 -0
- package/packages/daemon/dist/server.d.ts.map +1 -1
- package/packages/daemon/dist/server.js +31 -0
- package/packages/daemon/dist/server.js.map +1 -1
- package/packages/daemon/package.json +12 -12
- package/packages/daemon/src/server.ts +37 -0
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/cloud.d.ts +7 -114
- package/packages/mcp/dist/cloud.d.ts.map +1 -1
- package/packages/mcp/dist/cloud.js +21 -431
- package/packages/mcp/dist/cloud.js.map +1 -1
- package/packages/mcp/dist/errors.d.ts +4 -22
- package/packages/mcp/dist/errors.d.ts.map +1 -1
- package/packages/mcp/dist/errors.js +4 -43
- package/packages/mcp/dist/errors.js.map +1 -1
- package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
- package/packages/mcp/dist/hybrid-client.js +7 -1
- package/packages/mcp/dist/hybrid-client.js.map +1 -1
- package/packages/mcp/package.json +4 -3
- package/packages/mcp/src/cloud.ts +29 -511
- package/packages/mcp/src/errors.ts +12 -49
- package/packages/mcp/src/hybrid-client.ts +8 -1
- package/packages/mcp/tests/discover.test.ts +72 -11
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +17 -1
- package/packages/protocol/dist/types.d.ts.map +1 -1
- package/packages/protocol/package.json +1 -1
- package/packages/protocol/src/types.ts +23 -0
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/browser-client.d.ts +212 -0
- package/packages/sdk/dist/browser-client.d.ts.map +1 -0
- package/packages/sdk/dist/browser-client.js +750 -0
- package/packages/sdk/dist/browser-client.js.map +1 -0
- package/packages/sdk/dist/browser-framing.d.ts +46 -0
- package/packages/sdk/dist/browser-framing.d.ts.map +1 -0
- package/packages/sdk/dist/browser-framing.js +122 -0
- package/packages/sdk/dist/browser-framing.js.map +1 -0
- package/packages/sdk/dist/client.d.ts +129 -2
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +312 -2
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/discovery.d.ts +10 -0
- package/packages/sdk/dist/discovery.d.ts.map +1 -0
- package/packages/sdk/dist/discovery.js +22 -0
- package/packages/sdk/dist/discovery.js.map +1 -0
- package/packages/sdk/dist/errors.d.ts +9 -0
- package/packages/sdk/dist/errors.d.ts.map +1 -0
- package/packages/sdk/dist/errors.js +9 -0
- package/packages/sdk/dist/errors.js.map +1 -0
- package/packages/sdk/dist/index.d.ts +18 -2
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +27 -1
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/transports/index.d.ts +92 -0
- package/packages/sdk/dist/transports/index.d.ts.map +1 -0
- package/packages/sdk/dist/transports/index.js +129 -0
- package/packages/sdk/dist/transports/index.js.map +1 -0
- package/packages/sdk/dist/transports/socket-transport.d.ts +30 -0
- package/packages/sdk/dist/transports/socket-transport.d.ts.map +1 -0
- package/packages/sdk/dist/transports/socket-transport.js +94 -0
- package/packages/sdk/dist/transports/socket-transport.js.map +1 -0
- package/packages/sdk/dist/transports/types.d.ts +69 -0
- package/packages/sdk/dist/transports/types.d.ts.map +1 -0
- package/packages/sdk/dist/transports/types.js +10 -0
- package/packages/sdk/dist/transports/types.js.map +1 -0
- package/packages/sdk/dist/transports/websocket-transport.d.ts +55 -0
- package/packages/sdk/dist/transports/websocket-transport.d.ts.map +1 -0
- package/packages/sdk/dist/transports/websocket-transport.js +180 -0
- package/packages/sdk/dist/transports/websocket-transport.js.map +1 -0
- package/packages/sdk/package.json +28 -4
- package/packages/sdk/src/browser-client.ts +985 -0
- package/packages/sdk/src/browser-framing.test.ts +115 -0
- package/packages/sdk/src/browser-framing.ts +150 -0
- package/packages/sdk/src/client.test.ts +425 -0
- package/packages/sdk/src/client.ts +397 -3
- package/packages/sdk/src/discovery.ts +38 -0
- package/packages/sdk/src/errors.ts +17 -0
- package/packages/sdk/src/index.ts +82 -1
- package/packages/sdk/src/transports/index.ts +197 -0
- package/packages/sdk/src/transports/socket-transport.ts +115 -0
- package/packages/sdk/src/transports/types.ts +77 -0
- package/packages/sdk/src/transports/websocket-transport.ts +245 -0
- package/packages/sdk/tsconfig.json +1 -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 +8 -3
- 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/dist/cjs/discovery.js +328 -0
- package/packages/utils/dist/cjs/errors.js +81 -0
- package/packages/utils/dist/discovery.d.ts +123 -0
- package/packages/utils/dist/discovery.d.ts.map +1 -0
- package/packages/utils/dist/discovery.js +439 -0
- package/packages/utils/dist/discovery.js.map +1 -0
- package/packages/utils/dist/errors.d.ts +29 -0
- package/packages/utils/dist/errors.d.ts.map +1 -0
- package/packages/utils/dist/errors.js +50 -0
- package/packages/utils/dist/errors.js.map +1 -0
- package/packages/utils/package.json +15 -2
- package/packages/utils/src/consolidation.test.ts +125 -0
- package/packages/utils/src/discovery.test.ts +196 -0
- package/packages/utils/src/discovery.ts +524 -0
- package/packages/utils/src/errors.test.ts +83 -0
- package/packages/utils/src/errors.ts +56 -0
- package/packages/wrapper/dist/opencode-wrapper.d.ts +6 -2
- package/packages/wrapper/dist/opencode-wrapper.d.ts.map +1 -1
- package/packages/wrapper/dist/opencode-wrapper.js +34 -10
- package/packages/wrapper/dist/opencode-wrapper.js.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +22 -2
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.js +174 -4
- package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
- package/packages/wrapper/package.json +6 -6
- package/packages/wrapper/src/opencode-wrapper.ts +37 -9
- package/packages/wrapper/src/relay-pty-orchestrator.ts +197 -4
- package/relay-snippets/agent-relay-snippet.md +17 -5
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation Verification Tests
|
|
3
|
+
*
|
|
4
|
+
* These tests verify that:
|
|
5
|
+
* 1. Discovery logic is defined in @agent-relay/utils (single source of truth)
|
|
6
|
+
* 2. Error classes are defined in @agent-relay/utils (single source of truth)
|
|
7
|
+
* 3. All expected exports are present
|
|
8
|
+
* 4. No logic is duplicated - MCP and SDK should re-export from utils
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect } from 'vitest';
|
|
12
|
+
import * as discovery from './discovery.js';
|
|
13
|
+
import * as errors from './errors.js';
|
|
14
|
+
import * as clientHelpers from './client-helpers.js';
|
|
15
|
+
|
|
16
|
+
describe('Consolidation: Single Source of Truth', () => {
|
|
17
|
+
describe('Discovery exports from utils', () => {
|
|
18
|
+
it('exports discoverSocket function', () => {
|
|
19
|
+
expect(typeof discovery.discoverSocket).toBe('function');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('exports detectCloudWorkspace function', () => {
|
|
23
|
+
expect(typeof discovery.detectCloudWorkspace).toBe('function');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('exports isCloudWorkspace function', () => {
|
|
27
|
+
expect(typeof discovery.isCloudWorkspace).toBe('function');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('exports getCloudSocketPath function', () => {
|
|
31
|
+
expect(typeof discovery.getCloudSocketPath).toBe('function');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('exports getCloudOutboxPath function', () => {
|
|
35
|
+
expect(typeof discovery.getCloudOutboxPath).toBe('function');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('exports getConnectionInfo function', () => {
|
|
39
|
+
expect(typeof discovery.getConnectionInfo).toBe('function');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('exports getCloudEnvironmentSummary function', () => {
|
|
43
|
+
expect(typeof discovery.getCloudEnvironmentSummary).toBe('function');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('exports cloudApiRequest function', () => {
|
|
47
|
+
expect(typeof discovery.cloudApiRequest).toBe('function');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('exports getWorkspaceStatus function', () => {
|
|
51
|
+
expect(typeof discovery.getWorkspaceStatus).toBe('function');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('exports discoverAgentName function', () => {
|
|
55
|
+
expect(typeof discovery.discoverAgentName).toBe('function');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('Error classes from utils', () => {
|
|
60
|
+
it('exports RelayError class', () => {
|
|
61
|
+
expect(errors.RelayError).toBeDefined();
|
|
62
|
+
expect(new errors.RelayError('test')).toBeInstanceOf(Error);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('exports DaemonNotRunningError class', () => {
|
|
66
|
+
expect(errors.DaemonNotRunningError).toBeDefined();
|
|
67
|
+
expect(new errors.DaemonNotRunningError()).toBeInstanceOf(errors.RelayError);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('exports AgentNotFoundError class', () => {
|
|
71
|
+
expect(errors.AgentNotFoundError).toBeDefined();
|
|
72
|
+
expect(new errors.AgentNotFoundError('test')).toBeInstanceOf(errors.RelayError);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('exports TimeoutError class', () => {
|
|
76
|
+
expect(errors.TimeoutError).toBeDefined();
|
|
77
|
+
expect(new errors.TimeoutError('op', 1000)).toBeInstanceOf(errors.RelayError);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('exports ConnectionError class', () => {
|
|
81
|
+
expect(errors.ConnectionError).toBeDefined();
|
|
82
|
+
expect(new errors.ConnectionError('msg')).toBeInstanceOf(errors.RelayError);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('exports ChannelNotFoundError class', () => {
|
|
86
|
+
expect(errors.ChannelNotFoundError).toBeDefined();
|
|
87
|
+
expect(new errors.ChannelNotFoundError('#ch')).toBeInstanceOf(errors.RelayError);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('exports SpawnError class', () => {
|
|
91
|
+
expect(errors.SpawnError).toBeDefined();
|
|
92
|
+
expect(new errors.SpawnError('w', 'r')).toBeInstanceOf(errors.RelayError);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('Client helpers from utils', () => {
|
|
97
|
+
it('exports createRequestEnvelope function', () => {
|
|
98
|
+
expect(typeof clientHelpers.createRequestEnvelope).toBe('function');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('exports createRequestHandler function', () => {
|
|
102
|
+
expect(typeof clientHelpers.createRequestHandler).toBe('function');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('exports generateRequestId function', () => {
|
|
106
|
+
expect(typeof clientHelpers.generateRequestId).toBe('function');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('exports toSpawnResult function', () => {
|
|
110
|
+
expect(typeof clientHelpers.toSpawnResult).toBe('function');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('exports toReleaseResult function', () => {
|
|
114
|
+
expect(typeof clientHelpers.toReleaseResult).toBe('function');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('exports isMatchingResponse function', () => {
|
|
118
|
+
expect(typeof clientHelpers.isMatchingResponse).toBe('function');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('exports handleResponse function', () => {
|
|
122
|
+
expect(typeof clientHelpers.handleResponse).toBe('function');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
import {
|
|
4
|
+
discoverSocket,
|
|
5
|
+
detectCloudWorkspace,
|
|
6
|
+
isCloudWorkspace,
|
|
7
|
+
getCloudSocketPath,
|
|
8
|
+
getCloudOutboxPath,
|
|
9
|
+
getConnectionInfo,
|
|
10
|
+
getCloudEnvironmentSummary,
|
|
11
|
+
discoverAgentName,
|
|
12
|
+
} from './discovery.js';
|
|
13
|
+
|
|
14
|
+
// Mock the fs module
|
|
15
|
+
vi.mock('node:fs', async (importOriginal) => {
|
|
16
|
+
const actual = await importOriginal<typeof import('node:fs')>();
|
|
17
|
+
return {
|
|
18
|
+
...actual,
|
|
19
|
+
existsSync: vi.fn(),
|
|
20
|
+
readdirSync: vi.fn(),
|
|
21
|
+
readFileSync: vi.fn(),
|
|
22
|
+
statSync: vi.fn(),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Mock @agent-relay/config
|
|
27
|
+
vi.mock('@agent-relay/config', () => ({
|
|
28
|
+
findProjectRoot: vi.fn(() => null),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
describe('Discovery (single source of truth)', () => {
|
|
32
|
+
const originalEnv = process.env;
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.clearAllMocks();
|
|
36
|
+
process.env = { ...originalEnv };
|
|
37
|
+
delete process.env.WORKSPACE_ID;
|
|
38
|
+
delete process.env.CLOUD_API_URL;
|
|
39
|
+
delete process.env.WORKSPACE_TOKEN;
|
|
40
|
+
delete process.env.RELAY_SOCKET;
|
|
41
|
+
delete process.env.RELAY_PROJECT;
|
|
42
|
+
delete process.env.WORKSPACE_OWNER_USER_ID;
|
|
43
|
+
delete process.env.RELAY_AGENT_NAME;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
process.env = originalEnv;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('detectCloudWorkspace', () => {
|
|
51
|
+
it('returns null when cloud env vars are not set', () => {
|
|
52
|
+
expect(detectCloudWorkspace()).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('returns null when only WORKSPACE_ID is set', () => {
|
|
56
|
+
process.env.WORKSPACE_ID = 'test-workspace';
|
|
57
|
+
expect(detectCloudWorkspace()).toBeNull();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('returns null when only CLOUD_API_URL is set', () => {
|
|
61
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
62
|
+
expect(detectCloudWorkspace()).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('returns workspace info when both vars are set', () => {
|
|
66
|
+
process.env.WORKSPACE_ID = 'test-workspace';
|
|
67
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
68
|
+
process.env.WORKSPACE_TOKEN = 'secret-token';
|
|
69
|
+
process.env.WORKSPACE_OWNER_USER_ID = 'user-123';
|
|
70
|
+
|
|
71
|
+
const result = detectCloudWorkspace();
|
|
72
|
+
|
|
73
|
+
expect(result).toEqual({
|
|
74
|
+
workspaceId: 'test-workspace',
|
|
75
|
+
cloudApiUrl: 'https://api.example.com',
|
|
76
|
+
workspaceToken: 'secret-token',
|
|
77
|
+
ownerUserId: 'user-123',
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('isCloudWorkspace', () => {
|
|
83
|
+
it('returns false when not in cloud', () => {
|
|
84
|
+
expect(isCloudWorkspace()).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('returns true when in cloud', () => {
|
|
88
|
+
process.env.WORKSPACE_ID = 'test-workspace';
|
|
89
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
90
|
+
expect(isCloudWorkspace()).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('getCloudSocketPath', () => {
|
|
95
|
+
it('returns workspace-namespaced socket path', () => {
|
|
96
|
+
expect(getCloudSocketPath('my-ws')).toBe('/tmp/relay/my-ws/sockets/daemon.sock');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('getCloudOutboxPath', () => {
|
|
101
|
+
it('returns workspace-namespaced outbox path', () => {
|
|
102
|
+
expect(getCloudOutboxPath('my-ws', 'Agent1')).toBe('/tmp/relay/my-ws/outbox/Agent1');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('discoverSocket', () => {
|
|
107
|
+
it('uses override socketPath option', () => {
|
|
108
|
+
const result = discoverSocket({ socketPath: '/custom/path.sock' });
|
|
109
|
+
expect(result?.socketPath).toBe('/custom/path.sock');
|
|
110
|
+
expect(result?.source).toBe('env');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('uses RELAY_SOCKET env var', () => {
|
|
114
|
+
process.env.RELAY_SOCKET = '/tmp/test.sock';
|
|
115
|
+
const result = discoverSocket();
|
|
116
|
+
expect(result?.socketPath).toBe('/tmp/test.sock');
|
|
117
|
+
expect(result?.source).toBe('env');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('uses cloud workspace socket when in cloud (even without file)', () => {
|
|
121
|
+
process.env.WORKSPACE_ID = 'cloud-ws';
|
|
122
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
123
|
+
vi.mocked(existsSync).mockReturnValue(false);
|
|
124
|
+
|
|
125
|
+
const result = discoverSocket();
|
|
126
|
+
expect(result?.socketPath).toBe('/tmp/relay/cloud-ws/sockets/daemon.sock');
|
|
127
|
+
expect(result?.source).toBe('cloud');
|
|
128
|
+
expect(result?.isCloud).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('env override takes priority over cloud workspace', () => {
|
|
132
|
+
process.env.RELAY_SOCKET = '/explicit/override.sock';
|
|
133
|
+
process.env.WORKSPACE_ID = 'cloud-ws';
|
|
134
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
135
|
+
|
|
136
|
+
const result = discoverSocket();
|
|
137
|
+
expect(result?.socketPath).toBe('/explicit/override.sock');
|
|
138
|
+
expect(result?.source).toBe('env');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('uses RELAY_PROJECT env var', () => {
|
|
142
|
+
process.env.RELAY_PROJECT = 'myproject';
|
|
143
|
+
vi.mocked(existsSync).mockReturnValue(false);
|
|
144
|
+
|
|
145
|
+
const result = discoverSocket();
|
|
146
|
+
expect(result?.project).toBe('myproject');
|
|
147
|
+
expect(result?.source).toBe('env');
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('returns null when nothing found', () => {
|
|
151
|
+
vi.mocked(existsSync).mockReturnValue(false);
|
|
152
|
+
const result = discoverSocket();
|
|
153
|
+
expect(result).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('getConnectionInfo', () => {
|
|
158
|
+
it('returns null when no socket found', () => {
|
|
159
|
+
vi.mocked(existsSync).mockReturnValue(false);
|
|
160
|
+
expect(getConnectionInfo()).toBeNull();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('returns connection info with cloud details', () => {
|
|
164
|
+
process.env.WORKSPACE_ID = 'ws-123';
|
|
165
|
+
process.env.CLOUD_API_URL = 'https://api.example.com';
|
|
166
|
+
|
|
167
|
+
const result = getConnectionInfo();
|
|
168
|
+
expect(result?.isCloud).toBe(true);
|
|
169
|
+
expect(result?.daemonUrl).toBe('https://api.example.com');
|
|
170
|
+
expect(result?.workspace?.workspaceId).toBe('ws-123');
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('getCloudEnvironmentSummary', () => {
|
|
175
|
+
it('returns env var summary', () => {
|
|
176
|
+
process.env.WORKSPACE_ID = 'test';
|
|
177
|
+
process.env.WORKSPACE_TOKEN = 'secret';
|
|
178
|
+
|
|
179
|
+
const summary = getCloudEnvironmentSummary();
|
|
180
|
+
expect(summary.WORKSPACE_ID).toBe('test');
|
|
181
|
+
expect(summary.WORKSPACE_TOKEN).toBe('[set]');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('discoverAgentName', () => {
|
|
186
|
+
it('returns RELAY_AGENT_NAME env var when set', () => {
|
|
187
|
+
process.env.RELAY_AGENT_NAME = 'TestAgent';
|
|
188
|
+
expect(discoverAgentName()).toBe('TestAgent');
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('returns null when no identity found', () => {
|
|
192
|
+
vi.mocked(existsSync).mockReturnValue(false);
|
|
193
|
+
expect(discoverAgentName()).toBeNull();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|