@openclaw-cloud/agent-controller 0.1.4 → 0.1.5
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/.husky/pre-commit +1 -0
- package/__tests__/api.test.ts +123 -0
- package/__tests__/chat.test.ts +191 -0
- package/__tests__/config.test.ts +100 -0
- package/__tests__/file-write.test.ts +119 -0
- package/__tests__/gateway-adapter.test.ts +366 -0
- package/__tests__/gateway-client.test.ts +272 -0
- package/__tests__/onboarding.test.ts +55 -0
- package/__tests__/package-install.test.ts +109 -0
- package/__tests__/pair.test.ts +60 -0
- package/__tests__/self-update.test.ts +123 -0
- package/__tests__/stop.test.ts +38 -0
- package/bin/agent-controller.js +15 -2
- package/dist/commands/self-update.d.ts +1 -0
- package/dist/commands/self-update.js +41 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/connection.js +24 -0
- package/dist/connection.js.map +1 -1
- package/dist/handlers/board-handler.d.ts +1 -0
- package/dist/handlers/board-handler.js +5 -2
- package/dist/handlers/board-handler.js.map +1 -1
- package/dist/handlers/chat.d.ts +4 -0
- package/dist/handlers/chat.js +62 -0
- package/dist/handlers/chat.js.map +1 -0
- package/dist/handlers/file-write.d.ts +2 -0
- package/dist/handlers/file-write.js +59 -0
- package/dist/handlers/file-write.js.map +1 -0
- package/dist/handlers/onboarding.d.ts +2 -0
- package/dist/handlers/onboarding.js +18 -0
- package/dist/handlers/onboarding.js.map +1 -0
- package/dist/handlers/package-install.d.ts +2 -0
- package/dist/handlers/package-install.js +59 -0
- package/dist/handlers/package-install.js.map +1 -0
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/openclaw/gateway-adapter.d.ts +22 -0
- package/dist/openclaw/gateway-adapter.js +108 -0
- package/dist/openclaw/gateway-adapter.js.map +1 -0
- package/dist/openclaw/gateway-client.d.ts +21 -0
- package/dist/openclaw/gateway-client.js +114 -0
- package/dist/openclaw/gateway-client.js.map +1 -0
- package/dist/openclaw/index.d.ts +8 -0
- package/dist/openclaw/index.js +12 -0
- package/dist/openclaw/index.js.map +1 -0
- package/dist/openclaw/types.d.ts +36 -0
- package/dist/openclaw/types.js +2 -0
- package/dist/openclaw/types.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/package.json +4 -2
- package/src/commands/self-update.ts +43 -0
- package/src/connection.ts +6 -0
- package/src/handlers/file-write.ts +65 -0
- package/src/handlers/onboarding.ts +19 -0
- package/src/handlers/package-install.ts +69 -0
- package/src/types.ts +2 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { handlePackageInstall } from '../src/handlers/package-install';
|
|
2
|
+
import type { AgentCommand } from '../src/types';
|
|
3
|
+
import childProcess from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
jest.mock('node:child_process');
|
|
6
|
+
|
|
7
|
+
const mockExec = childProcess.exec as unknown as jest.Mock;
|
|
8
|
+
|
|
9
|
+
function fakeExec(error: Error | null) {
|
|
10
|
+
mockExec.mockImplementation((_cmd: string, _opts: unknown, cb: Function) => {
|
|
11
|
+
cb(error, Buffer.from(''), Buffer.from(''));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const baseCmd: AgentCommand = { id: '1', type: 'package_install', payload: {} };
|
|
16
|
+
|
|
17
|
+
describe('handlePackageInstall', () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('returns success with empty installed when no packages provided', async () => {
|
|
23
|
+
const cmd: AgentCommand = { ...baseCmd, payload: { packages: {} } };
|
|
24
|
+
const res = await handlePackageInstall(cmd);
|
|
25
|
+
expect(res.success).toBe(true);
|
|
26
|
+
expect(res.data?.installed).toEqual({ apt: [], npm: [], pip: [] });
|
|
27
|
+
expect(res.data?.errors).toEqual([]);
|
|
28
|
+
expect(mockExec).not.toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('returns success with empty installed when packages key is missing', async () => {
|
|
32
|
+
const cmd: AgentCommand = { ...baseCmd, payload: {} };
|
|
33
|
+
const res = await handlePackageInstall(cmd);
|
|
34
|
+
expect(res.success).toBe(true);
|
|
35
|
+
expect(res.data?.installed).toEqual({ apt: [], npm: [], pip: [] });
|
|
36
|
+
expect(mockExec).not.toHaveBeenCalled();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('installs apt packages and runs apt-get install -y per package', async () => {
|
|
40
|
+
fakeExec(null);
|
|
41
|
+
const cmd: AgentCommand = { ...baseCmd, payload: { packages: { apt: ['curl', 'git'] } } };
|
|
42
|
+
const res = await handlePackageInstall(cmd);
|
|
43
|
+
expect(res.success).toBe(true);
|
|
44
|
+
expect((res.data?.installed as any).apt).toEqual(['curl', 'git']);
|
|
45
|
+
expect(mockExec).toHaveBeenCalledWith('apt-get install -y curl', expect.any(Object), expect.any(Function));
|
|
46
|
+
expect(mockExec).toHaveBeenCalledWith('apt-get install -y git', expect.any(Object), expect.any(Function));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('installs npm packages with npm install -g', async () => {
|
|
50
|
+
fakeExec(null);
|
|
51
|
+
const cmd: AgentCommand = { ...baseCmd, payload: { packages: { npm: ['typescript'] } } };
|
|
52
|
+
const res = await handlePackageInstall(cmd);
|
|
53
|
+
expect(res.success).toBe(true);
|
|
54
|
+
expect((res.data?.installed as any).npm).toEqual(['typescript']);
|
|
55
|
+
expect(mockExec).toHaveBeenCalledWith('npm install -g typescript', expect.any(Object), expect.any(Function));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('installs pip packages with pip install', async () => {
|
|
59
|
+
fakeExec(null);
|
|
60
|
+
const cmd: AgentCommand = { ...baseCmd, payload: { packages: { pip: ['requests'] } } };
|
|
61
|
+
const res = await handlePackageInstall(cmd);
|
|
62
|
+
expect(res.success).toBe(true);
|
|
63
|
+
expect((res.data?.installed as any).pip).toEqual(['requests']);
|
|
64
|
+
expect(mockExec).toHaveBeenCalledWith('pip install requests', expect.any(Object), expect.any(Function));
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('continues with other packages when one npm package fails (partial failure)', async () => {
|
|
68
|
+
let call = 0;
|
|
69
|
+
mockExec.mockImplementation((_cmd: string, _opts: unknown, cb: Function) => {
|
|
70
|
+
call === 0
|
|
71
|
+
? cb(new Error('package not found'), Buffer.from(''), Buffer.from(''))
|
|
72
|
+
: cb(null, Buffer.from(''), Buffer.from(''));
|
|
73
|
+
call++;
|
|
74
|
+
});
|
|
75
|
+
const cmd: AgentCommand = { ...baseCmd, payload: { packages: { npm: ['bad-pkg', 'typescript'] } } };
|
|
76
|
+
const res = await handlePackageInstall(cmd);
|
|
77
|
+
expect(res.success).toBe(false);
|
|
78
|
+
expect((res.data?.installed as any).npm).toEqual(['typescript']);
|
|
79
|
+
expect((res.data?.errors as any[]).length).toBe(1);
|
|
80
|
+
expect((res.data?.errors as any[])[0].name).toBe('bad-pkg');
|
|
81
|
+
expect((res.data?.errors as any[])[0].error).toContain('package not found');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('collects errors across all package types when all fail', async () => {
|
|
85
|
+
fakeExec(new Error('install failed'));
|
|
86
|
+
const cmd: AgentCommand = {
|
|
87
|
+
...baseCmd,
|
|
88
|
+
payload: { packages: { apt: ['pkg1'], npm: ['pkg2'], pip: ['pkg3'] } },
|
|
89
|
+
};
|
|
90
|
+
const res = await handlePackageInstall(cmd);
|
|
91
|
+
expect(res.success).toBe(false);
|
|
92
|
+
expect((res.data?.errors as any[]).length).toBe(3);
|
|
93
|
+
expect((res.data?.installed as any)).toEqual({ apt: [], npm: [], pip: [] });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('succeeds with success:true when all packages across all types install', async () => {
|
|
97
|
+
fakeExec(null);
|
|
98
|
+
const cmd: AgentCommand = {
|
|
99
|
+
...baseCmd,
|
|
100
|
+
payload: { packages: { apt: ['curl'], npm: ['ts-node'], pip: ['boto3'] } },
|
|
101
|
+
};
|
|
102
|
+
const res = await handlePackageInstall(cmd);
|
|
103
|
+
expect(res.success).toBe(true);
|
|
104
|
+
expect((res.data?.errors as any[]).length).toBe(0);
|
|
105
|
+
expect((res.data?.installed as any).apt).toEqual(['curl']);
|
|
106
|
+
expect((res.data?.installed as any).npm).toEqual(['ts-node']);
|
|
107
|
+
expect((res.data?.installed as any).pip).toEqual(['boto3']);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { handlePair } from '../src/handlers/pair';
|
|
2
|
+
import type { AgentCommand } from '../src/types';
|
|
3
|
+
|
|
4
|
+
describe('handlePair', () => {
|
|
5
|
+
const originalEnv = process.env;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
process.env = { ...originalEnv, AGENT_ID: 'agent-uuid-123' };
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
process.env = originalEnv;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('rejects when token is missing', async () => {
|
|
16
|
+
const cmd: AgentCommand = { id: '1', type: 'pair', payload: { targetId: 'target-1' } };
|
|
17
|
+
const res = await handlePair(cmd);
|
|
18
|
+
expect(res.success).toBe(false);
|
|
19
|
+
expect(res.error).toContain('Missing');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('rejects when targetId is missing', async () => {
|
|
23
|
+
const cmd: AgentCommand = { id: '2', type: 'pair', payload: { token: 'abc' } };
|
|
24
|
+
const res = await handlePair(cmd);
|
|
25
|
+
expect(res.success).toBe(false);
|
|
26
|
+
expect(res.error).toContain('Missing');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('rejects when both token and targetId are missing', async () => {
|
|
30
|
+
const cmd: AgentCommand = { id: '3', type: 'pair', payload: {} };
|
|
31
|
+
const res = await handlePair(cmd);
|
|
32
|
+
expect(res.success).toBe(false);
|
|
33
|
+
expect(res.error).toContain('Missing');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('returns paired:true with targetId and agentId from env', async () => {
|
|
37
|
+
const cmd: AgentCommand = {
|
|
38
|
+
id: '4',
|
|
39
|
+
type: 'pair',
|
|
40
|
+
payload: { token: 'my-token', targetId: 'target-42' },
|
|
41
|
+
};
|
|
42
|
+
const res = await handlePair(cmd);
|
|
43
|
+
expect(res.success).toBe(true);
|
|
44
|
+
expect(res.data?.paired).toBe(true);
|
|
45
|
+
expect(res.data?.targetId).toBe('target-42');
|
|
46
|
+
expect(res.data?.agentId).toBe('agent-uuid-123');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('returns agentId as undefined when AGENT_ID env var is not set', async () => {
|
|
50
|
+
delete process.env.AGENT_ID;
|
|
51
|
+
const cmd: AgentCommand = {
|
|
52
|
+
id: '5',
|
|
53
|
+
type: 'pair',
|
|
54
|
+
payload: { token: 'tok', targetId: 'target-1' },
|
|
55
|
+
};
|
|
56
|
+
const res = await handlePair(cmd);
|
|
57
|
+
expect(res.success).toBe(true);
|
|
58
|
+
expect(res.data?.agentId).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { selfUpdate } from '../src/commands/self-update';
|
|
2
|
+
import childProcess from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
jest.mock('node:child_process');
|
|
5
|
+
|
|
6
|
+
const mockExec = childProcess.exec as unknown as jest.Mock;
|
|
7
|
+
|
|
8
|
+
type ExecFakeResult = { error: Error | null; stdout: string };
|
|
9
|
+
|
|
10
|
+
function fakeExecSequence(results: ExecFakeResult[]) {
|
|
11
|
+
let call = 0;
|
|
12
|
+
mockExec.mockImplementation((_cmd: string, _opts: unknown, cb: Function) => {
|
|
13
|
+
const result = results[call++] ?? { error: new Error('unexpected call'), stdout: '' };
|
|
14
|
+
cb(result.error, Buffer.from(result.stdout), Buffer.from(''));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('selfUpdate', () => {
|
|
19
|
+
let exitSpy: jest.SpyInstance;
|
|
20
|
+
let logSpy: jest.SpyInstance;
|
|
21
|
+
let errorSpy: jest.SpyInstance;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
jest.clearAllMocks();
|
|
25
|
+
exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
26
|
+
logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
27
|
+
errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
jest.restoreAllMocks();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('prints "Already up to date" and does not exit when version matches', async () => {
|
|
35
|
+
fakeExecSequence([{ error: null, stdout: '1.2.3' }]);
|
|
36
|
+
|
|
37
|
+
await selfUpdate('1.2.3');
|
|
38
|
+
|
|
39
|
+
expect(mockExec).toHaveBeenCalledTimes(1);
|
|
40
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
41
|
+
'npm view @openclaw-cloud/agent-controller version',
|
|
42
|
+
expect.any(Object),
|
|
43
|
+
expect.any(Function),
|
|
44
|
+
);
|
|
45
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Already up to date'));
|
|
46
|
+
expect(exitSpy).not.toHaveBeenCalled();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('installs latest and calls process.exit(0) when a new version is available', async () => {
|
|
50
|
+
fakeExecSequence([
|
|
51
|
+
{ error: null, stdout: '1.3.0' },
|
|
52
|
+
{ error: null, stdout: '' },
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
await selfUpdate('1.2.3');
|
|
56
|
+
|
|
57
|
+
expect(mockExec).toHaveBeenCalledTimes(2);
|
|
58
|
+
expect(mockExec).toHaveBeenNthCalledWith(
|
|
59
|
+
1,
|
|
60
|
+
'npm view @openclaw-cloud/agent-controller version',
|
|
61
|
+
expect.any(Object),
|
|
62
|
+
expect.any(Function),
|
|
63
|
+
);
|
|
64
|
+
expect(mockExec).toHaveBeenNthCalledWith(
|
|
65
|
+
2,
|
|
66
|
+
'npm install -g @openclaw-cloud/agent-controller@latest',
|
|
67
|
+
expect.any(Object),
|
|
68
|
+
expect.any(Function),
|
|
69
|
+
);
|
|
70
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Updating from 1.2.3 to 1.3.0'));
|
|
71
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Successfully updated to 1.3.0'));
|
|
72
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('calls process.exit(1) when npm view fails', async () => {
|
|
76
|
+
fakeExecSequence([{ error: new Error('network error'), stdout: '' }]);
|
|
77
|
+
|
|
78
|
+
await selfUpdate('1.2.3');
|
|
79
|
+
|
|
80
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
81
|
+
expect(errorSpy).toHaveBeenCalledWith(
|
|
82
|
+
expect.stringContaining('Failed to fetch latest version'),
|
|
83
|
+
'network error',
|
|
84
|
+
);
|
|
85
|
+
expect(mockExec).toHaveBeenCalledTimes(1);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('calls process.exit(1) when npm install fails', async () => {
|
|
89
|
+
fakeExecSequence([
|
|
90
|
+
{ error: null, stdout: '1.3.0' },
|
|
91
|
+
{ error: new Error('npm install failed'), stdout: '' },
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
await selfUpdate('1.2.3');
|
|
95
|
+
|
|
96
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
97
|
+
expect(errorSpy).toHaveBeenCalledWith(
|
|
98
|
+
expect.stringContaining('Update failed'),
|
|
99
|
+
'npm install failed',
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('logs current and latest versions before updating', async () => {
|
|
104
|
+
fakeExecSequence([
|
|
105
|
+
{ error: null, stdout: '2.0.0' },
|
|
106
|
+
{ error: null, stdout: '' },
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
await selfUpdate('1.0.0');
|
|
110
|
+
|
|
111
|
+
expect(logSpy).toHaveBeenCalledWith('Current version: 1.0.0');
|
|
112
|
+
expect(logSpy).toHaveBeenCalledWith('Latest version: 2.0.0');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('trims whitespace from npm view output before comparing', async () => {
|
|
116
|
+
fakeExecSequence([{ error: null, stdout: '1.2.3\n' }]);
|
|
117
|
+
|
|
118
|
+
await selfUpdate('1.2.3');
|
|
119
|
+
|
|
120
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Already up to date'));
|
|
121
|
+
expect(exitSpy).not.toHaveBeenCalled();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { handleStop } from '../src/handlers/stop';
|
|
2
|
+
import type { AgentCommand } from '../src/types';
|
|
3
|
+
|
|
4
|
+
describe('handleStop', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
jest.useFakeTimers();
|
|
7
|
+
jest.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
jest.useRealTimers();
|
|
12
|
+
jest.restoreAllMocks();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns success response with graceful shutdown message', async () => {
|
|
16
|
+
const cmd: AgentCommand = { id: '1', type: 'stop', payload: {} };
|
|
17
|
+
const res = await handleStop(cmd);
|
|
18
|
+
expect(res.success).toBe(true);
|
|
19
|
+
expect(res.data?.message).toContain('gracefully');
|
|
20
|
+
expect(res.id).toBe('1');
|
|
21
|
+
expect(res.type).toBe('stop');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('does not call process.exit before 500ms', async () => {
|
|
25
|
+
const cmd: AgentCommand = { id: '2', type: 'stop', payload: {} };
|
|
26
|
+
await handleStop(cmd);
|
|
27
|
+
jest.advanceTimersByTime(499);
|
|
28
|
+
expect(process.exit).not.toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('calls process.exit(0) after 500ms', async () => {
|
|
32
|
+
const cmd: AgentCommand = { id: '3', type: 'stop', payload: {} };
|
|
33
|
+
await handleStop(cmd);
|
|
34
|
+
expect(process.exit).not.toHaveBeenCalled();
|
|
35
|
+
jest.advanceTimersByTime(500);
|
|
36
|
+
expect(process.exit).toHaveBeenCalledWith(0);
|
|
37
|
+
});
|
|
38
|
+
});
|
package/bin/agent-controller.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const pkg = require(join(dirname(fileURLToPath(import.meta.url)), '../package.json'));
|
|
9
|
+
|
|
10
|
+
const [,, command] = process.argv;
|
|
11
|
+
|
|
12
|
+
if (command === 'self-update') {
|
|
13
|
+
const { selfUpdate } = await import('../dist/commands/self-update.js');
|
|
14
|
+
await selfUpdate(pkg.version);
|
|
15
|
+
} else {
|
|
16
|
+
const { main } = await import('../dist/index.js');
|
|
17
|
+
main();
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function selfUpdate(currentVersion: string): Promise<void>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
const PACKAGE_NAME = '@openclaw-cloud/agent-controller';
|
|
3
|
+
function execAsync(cmd, timeout) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
exec(cmd, { timeout }, (err, stdout) => {
|
|
6
|
+
if (err)
|
|
7
|
+
reject(err);
|
|
8
|
+
else
|
|
9
|
+
resolve(stdout.toString().trim());
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export async function selfUpdate(currentVersion) {
|
|
14
|
+
console.log(`Current version: ${currentVersion}`);
|
|
15
|
+
let latestVersion;
|
|
16
|
+
try {
|
|
17
|
+
latestVersion = await execAsync(`npm view ${PACKAGE_NAME} version`, 10_000);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
console.error('Failed to fetch latest version:', err instanceof Error ? err.message : err);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
return; // unreachable in production; guards test flow when process.exit is mocked
|
|
23
|
+
}
|
|
24
|
+
console.log(`Latest version: ${latestVersion}`);
|
|
25
|
+
if (currentVersion === latestVersion) {
|
|
26
|
+
console.log('Already up to date.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
console.log(`Updating from ${currentVersion} to ${latestVersion}...`);
|
|
30
|
+
try {
|
|
31
|
+
await execAsync(`npm install -g ${PACKAGE_NAME}@latest`, 120_000);
|
|
32
|
+
console.log(`Successfully updated to ${latestVersion}. Restarting...`);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
return; // unreachable in production; guards test flow when process.exit is mocked
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.error('Update failed:', err instanceof Error ? err.message : err);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=self-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../src/commands/self-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,MAAM,YAAY,GAAG,kCAAkC,CAAC;AAExD,SAAS,SAAS,CAAC,GAAW,EAAE,OAAe;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;gBAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,cAAsB;IACrD,OAAO,CAAC,GAAG,CAAC,oBAAoB,cAAc,EAAE,CAAC,CAAC;IAElD,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,MAAM,SAAS,CAAC,YAAY,YAAY,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO,CAAC,0EAA0E;IACpF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,aAAa,EAAE,CAAC,CAAC;IAEhD,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,cAAc,OAAO,aAAa,KAAK,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,kBAAkB,YAAY,SAAS,EAAE,OAAO,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,2BAA2B,aAAa,iBAAiB,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO,CAAC,0EAA0E;IACpF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/connection.js
CHANGED
|
@@ -7,6 +7,10 @@ import { handleConfig } from './handlers/config.js';
|
|
|
7
7
|
import { handlePair } from './handlers/pair.js';
|
|
8
8
|
import { handleStop } from './handlers/stop.js';
|
|
9
9
|
import { handleBackup } from './handlers/backup.js';
|
|
10
|
+
import { handleChatListSessions, handleChatHistory, handleChatSend } from './handlers/chat.js';
|
|
11
|
+
import { handlePackageInstall } from './handlers/package-install.js';
|
|
12
|
+
import { handleFileWrite } from './handlers/file-write.js';
|
|
13
|
+
import { handleOnboardingComplete } from './handlers/onboarding.js';
|
|
10
14
|
const handlers = {
|
|
11
15
|
exec: handleExec,
|
|
12
16
|
restart: handleRestart,
|
|
@@ -15,6 +19,9 @@ const handlers = {
|
|
|
15
19
|
pair: handlePair,
|
|
16
20
|
stop: handleStop,
|
|
17
21
|
backup: handleBackup,
|
|
22
|
+
package_install: handlePackageInstall,
|
|
23
|
+
file_write: handleFileWrite,
|
|
24
|
+
onboarding_complete: handleOnboardingComplete,
|
|
18
25
|
};
|
|
19
26
|
async function fetchCentrifugoToken(backendUrl, agentToken, agentId) {
|
|
20
27
|
const controller = new AbortController();
|
|
@@ -85,6 +92,23 @@ export function createConnection(opts) {
|
|
|
85
92
|
console.warn('[WS] Ignoring message without type:', JSON.stringify(ctx.data));
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
95
|
+
// Chat commands — handle before generic dispatch
|
|
96
|
+
if (command.type === 'chat_list_sessions' || command.type === 'chat_history' || command.type === 'chat_send') {
|
|
97
|
+
const publishFn = async (data) => { await client.publish(commandChannel, data); };
|
|
98
|
+
console.log(`[WS] Handling chat command: type=${command.type} id=${command.id}`);
|
|
99
|
+
switch (command.type) {
|
|
100
|
+
case 'chat_list_sessions':
|
|
101
|
+
handleChatListSessions(command, publishFn).catch(console.error);
|
|
102
|
+
break;
|
|
103
|
+
case 'chat_history':
|
|
104
|
+
handleChatHistory(command, publishFn).catch(console.error);
|
|
105
|
+
break;
|
|
106
|
+
case 'chat_send':
|
|
107
|
+
handleChatSend(command, publishFn, opts.agentId).catch(console.error);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
88
112
|
const handler = handlers[command.type];
|
|
89
113
|
if (!handler) {
|
|
90
114
|
console.error(`[WS] Unknown command type: ${command.type}`);
|
package/dist/connection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,MAAM,YAAY,CAAC;AACtD,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ export class BoardHandler {
|
|
|
4
4
|
boardState = { state: 'idle', cardId: null };
|
|
5
5
|
myColumnIds = [];
|
|
6
6
|
boardId = null;
|
|
7
|
+
workspaceId = null;
|
|
7
8
|
api;
|
|
8
9
|
constructor(api) {
|
|
9
10
|
this.api = api;
|
|
@@ -12,11 +13,13 @@ export class BoardHandler {
|
|
|
12
13
|
try {
|
|
13
14
|
const data = await this.api.get('/api/agent/board');
|
|
14
15
|
this.boardId = data.board.id;
|
|
16
|
+
this.workspaceId = data.board.workspaceId;
|
|
15
17
|
this.myColumnIds = data.board.myColumnIds;
|
|
16
|
-
console.log(`Board initialized: ${this.boardId}, watching ${this.myColumnIds.length} column(s)`);
|
|
18
|
+
console.log(`Board initialized: ${this.boardId} (workspace: ${this.workspaceId}), watching ${this.myColumnIds.length} column(s)`);
|
|
17
19
|
// Backfill: check for existing unassigned cards in my columns
|
|
18
20
|
await this.checkQueue(data);
|
|
19
|
-
|
|
21
|
+
// Return workspaceId for channel subscription (board:<workspaceId>)
|
|
22
|
+
return this.workspaceId;
|
|
20
23
|
}
|
|
21
24
|
catch (err) {
|
|
22
25
|
console.error('Board initialization failed:', err instanceof Error ? err.message : err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-handler.js","sourceRoot":"","sources":["../../src/handlers/board-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAI1C,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAM,OAAO,YAAY;IACf,UAAU,GAAe,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACzD,WAAW,GAAa,EAAE,CAAC;IAC3B,OAAO,GAAkB,IAAI,CAAC;IAC9B,GAAG,CAAW;IAEtB,YAAY,GAAa;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAc,CAAC;YACjE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"board-handler.js","sourceRoot":"","sources":["../../src/handlers/board-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentCommand } from '../types.js';
|
|
2
|
+
export declare function handleChatListSessions(command: AgentCommand, publish: (data: unknown) => Promise<void>): Promise<void>;
|
|
3
|
+
export declare function handleChatHistory(command: AgentCommand, publish: (data: unknown) => Promise<void>): Promise<void>;
|
|
4
|
+
export declare function handleChatSend(command: AgentCommand, publish: (data: unknown) => Promise<void>, agentId: string): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getChatProvider } from '../openclaw/index.js';
|
|
2
|
+
export async function handleChatListSessions(command, publish) {
|
|
3
|
+
const provider = getChatProvider();
|
|
4
|
+
if (!provider) {
|
|
5
|
+
await publish({ type: 'chat_sessions_response', correlationId: command.id, sessions: [], error: 'Chat provider not initialized' });
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
const sessions = await provider.listSessions();
|
|
10
|
+
await publish({ type: 'chat_sessions_response', correlationId: command.id, sessions });
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
await publish({ type: 'chat_sessions_response', correlationId: command.id, sessions: [], error: err instanceof Error ? err.message : String(err) });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function handleChatHistory(command, publish) {
|
|
17
|
+
const { sessionKey, limit } = command.payload;
|
|
18
|
+
const provider = getChatProvider();
|
|
19
|
+
if (!provider) {
|
|
20
|
+
await publish({ type: 'chat_history_response', correlationId: command.id, messages: [], error: 'Chat provider not initialized' });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const messages = await provider.getHistory(sessionKey, limit ?? 200);
|
|
25
|
+
await publish({ type: 'chat_history_response', correlationId: command.id, messages });
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
await publish({ type: 'chat_history_response', correlationId: command.id, messages: [], error: err instanceof Error ? err.message : String(err) });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function handleChatSend(command, publish, agentId) {
|
|
32
|
+
const { sessionKey, text, attachments } = command.payload;
|
|
33
|
+
const correlationId = command.id;
|
|
34
|
+
// Typing indicator
|
|
35
|
+
await publish({ type: 'chat_typing', agentId, state: true }).catch(() => { });
|
|
36
|
+
const provider = getChatProvider();
|
|
37
|
+
if (!provider) {
|
|
38
|
+
await publish({ type: 'chat_response', correlationId, sessionKey, text: '', error: 'Chat provider not initialized' });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
await provider.sendMessage({
|
|
43
|
+
sessionKey,
|
|
44
|
+
text,
|
|
45
|
+
idempotencyKey: correlationId,
|
|
46
|
+
attachments, // base64 inline — Centrifugo limit raised to 10MB
|
|
47
|
+
onDelta: async (accumulated) => {
|
|
48
|
+
await publish({ type: 'chat_delta', correlationId, sessionKey, text: accumulated }).catch(() => { });
|
|
49
|
+
},
|
|
50
|
+
onDone: async (finalText) => {
|
|
51
|
+
await publish({ type: 'chat_response', correlationId, sessionKey, text: finalText }).catch(() => { });
|
|
52
|
+
},
|
|
53
|
+
onError: async (error) => {
|
|
54
|
+
await publish({ type: 'chat_response', correlationId, sessionKey, text: '', error }).catch(() => { });
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
await publish({ type: 'chat_response', correlationId, sessionKey, text: '', error: err instanceof Error ? err.message : String(err) }).catch(() => { });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/handlers/chat.ts"],"names":[],"mappings":"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"}
|