reeboot 1.0.0
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 +361 -0
- package/container/Dockerfile +48 -0
- package/container/entrypoint.sh +8 -0
- package/dist/agent-runner/index.d.ts +9 -0
- package/dist/agent-runner/index.d.ts.map +1 -0
- package/dist/agent-runner/index.js +21 -0
- package/dist/agent-runner/index.js.map +1 -0
- package/dist/agent-runner/interface.d.ts +56 -0
- package/dist/agent-runner/interface.d.ts.map +1 -0
- package/dist/agent-runner/interface.js +5 -0
- package/dist/agent-runner/interface.js.map +1 -0
- package/dist/agent-runner/pi-runner.d.ts +41 -0
- package/dist/agent-runner/pi-runner.d.ts.map +1 -0
- package/dist/agent-runner/pi-runner.js +162 -0
- package/dist/agent-runner/pi-runner.js.map +1 -0
- package/dist/channels/interface.d.ts +63 -0
- package/dist/channels/interface.d.ts.map +1 -0
- package/dist/channels/interface.js +33 -0
- package/dist/channels/interface.js.map +1 -0
- package/dist/channels/registry.d.ts +30 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +71 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/signal.d.ts +51 -0
- package/dist/channels/signal.d.ts.map +1 -0
- package/dist/channels/signal.js +263 -0
- package/dist/channels/signal.js.map +1 -0
- package/dist/channels/web.d.ts +35 -0
- package/dist/channels/web.d.ts.map +1 -0
- package/dist/channels/web.js +65 -0
- package/dist/channels/web.js.map +1 -0
- package/dist/channels/whatsapp.d.ts +25 -0
- package/dist/channels/whatsapp.d.ts.map +1 -0
- package/dist/channels/whatsapp.js +150 -0
- package/dist/channels/whatsapp.js.map +1 -0
- package/dist/config.d.ts +366 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +140 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +69 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +166 -0
- package/dist/context.js.map +1 -0
- package/dist/credential-proxy.d.ts +25 -0
- package/dist/credential-proxy.d.ts.map +1 -0
- package/dist/credential-proxy.js +96 -0
- package/dist/credential-proxy.js.map +1 -0
- package/dist/daemon.d.ts +25 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +138 -0
- package/dist/daemon.js.map +1 -0
- package/dist/db/index.d.ts +23 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +113 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +408 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +55 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/doctor.d.ts +23 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +217 -0
- package/dist/doctor.js.map +1 -0
- package/dist/extensions/loader.d.ts +19 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +124 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +561 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +60 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +313 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/packages.d.ts +21 -0
- package/dist/packages.d.ts.map +1 -0
- package/dist/packages.js +116 -0
- package/dist/packages.js.map +1 -0
- package/dist/scheduler-registry.d.ts +8 -0
- package/dist/scheduler-registry.d.ts.map +1 -0
- package/dist/scheduler-registry.js +14 -0
- package/dist/scheduler-registry.js.map +1 -0
- package/dist/scheduler.d.ts +60 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +143 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +489 -0
- package/dist/server.js.map +1 -0
- package/dist/setup-wizard.d.ts +12 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +163 -0
- package/dist/setup-wizard.js.map +1 -0
- package/extensions/confirm-destructive.ts +59 -0
- package/extensions/custom-compaction.ts +114 -0
- package/extensions/protected-paths.ts +30 -0
- package/extensions/sandbox/index.ts +317 -0
- package/extensions/sandbox/package-lock.json +92 -0
- package/extensions/sandbox/package.json +19 -0
- package/extensions/scheduler-tool.ts +65 -0
- package/extensions/session-name.ts +27 -0
- package/extensions/token-meter.ts +55 -0
- package/package.json +68 -0
- package/skills/send-message/SKILL.md +27 -0
- package/skills/web-search/SKILL.md +32 -0
- package/templates/global-agents.md +23 -0
- package/templates/main-agents.md +28 -0
- package/webchat/index.html +421 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name('reeboot')
|
|
9
|
+
.description('Personal AI agent running locally')
|
|
10
|
+
.version('0.0.1');
|
|
11
|
+
// ─── start ───────────────────────────────────────────────────────────────────
|
|
12
|
+
program
|
|
13
|
+
.command('start')
|
|
14
|
+
.description('Start the reeboot agent server')
|
|
15
|
+
.option('--no-interactive', 'Run in non-interactive mode (skip wizard prompts)')
|
|
16
|
+
.option('--daemon', 'Run as a background service (launchd on macOS, systemd on Linux)')
|
|
17
|
+
.option('--provider <provider>', 'LLM provider (non-interactive)')
|
|
18
|
+
.option('--api-key <key>', 'API key (non-interactive)')
|
|
19
|
+
.option('--model <model>', 'Model ID (non-interactive)')
|
|
20
|
+
.option('--channels <channels>', 'Channels comma-separated (non-interactive)')
|
|
21
|
+
.option('--name <name>', 'Agent name (non-interactive)')
|
|
22
|
+
.action(async (opts) => {
|
|
23
|
+
if (opts.daemon) {
|
|
24
|
+
const { startDaemon } = await import('./daemon.js');
|
|
25
|
+
console.log('Registering reeboot as a background service...');
|
|
26
|
+
try {
|
|
27
|
+
await startDaemon({
|
|
28
|
+
reebotBin: process.argv[1],
|
|
29
|
+
});
|
|
30
|
+
console.log('Done. Reeboot will start automatically on login.');
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(`Failed to register daemon: ${err.message}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const configPath = join(homedir(), '.reeboot', 'config.json');
|
|
39
|
+
if (!existsSync(configPath)) {
|
|
40
|
+
// No config — launch wizard
|
|
41
|
+
const { runWizard } = await import('./setup-wizard.js');
|
|
42
|
+
await runWizard({ interactive: opts.interactive ?? true, ...opts });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const { loadConfig } = await import('./config.js');
|
|
46
|
+
const { startServer } = await import('./server.js');
|
|
47
|
+
const config = loadConfig(configPath);
|
|
48
|
+
console.log(`Starting reeboot on port ${config.channels.web.port}...`);
|
|
49
|
+
await startServer({
|
|
50
|
+
port: config.channels.web.port,
|
|
51
|
+
// Allow overriding the bind host via env var so Docker containers can
|
|
52
|
+
// bind 0.0.0.0 without changing config.json.
|
|
53
|
+
host: process.env.REEBOOT_HOST ?? '127.0.0.1',
|
|
54
|
+
logLevel: config.logging.level,
|
|
55
|
+
token: config.server.token,
|
|
56
|
+
config,
|
|
57
|
+
});
|
|
58
|
+
console.log(`Server running at http://localhost:${config.channels.web.port}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// ─── stop ────────────────────────────────────────────────────────────────────
|
|
62
|
+
program
|
|
63
|
+
.command('stop')
|
|
64
|
+
.description('Stop the reeboot daemon service (does not unregister it)')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
const { stopDaemon } = await import('./daemon.js');
|
|
67
|
+
console.log('Stopping reeboot daemon...');
|
|
68
|
+
try {
|
|
69
|
+
await stopDaemon();
|
|
70
|
+
console.log('Done.');
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error(`Failed to stop daemon: ${err.message}`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// ─── setup ───────────────────────────────────────────────────────────────────
|
|
78
|
+
program
|
|
79
|
+
.command('setup')
|
|
80
|
+
.description('Run the interactive setup wizard')
|
|
81
|
+
.option('--no-interactive', 'Run in non-interactive mode')
|
|
82
|
+
.option('--provider <provider>', 'LLM provider')
|
|
83
|
+
.option('--api-key <key>', 'API key')
|
|
84
|
+
.option('--model <model>', 'Model ID')
|
|
85
|
+
.option('--channels <channels>', 'Channels comma-separated')
|
|
86
|
+
.option('--name <name>', 'Agent name')
|
|
87
|
+
.action(async (opts) => {
|
|
88
|
+
const { runWizard } = await import('./setup-wizard.js');
|
|
89
|
+
await runWizard({ interactive: opts.interactive ?? true, ...opts });
|
|
90
|
+
});
|
|
91
|
+
// ─── status ──────────────────────────────────────────────────────────────────
|
|
92
|
+
program
|
|
93
|
+
.command('status')
|
|
94
|
+
.description('Show agent status')
|
|
95
|
+
.action(async () => {
|
|
96
|
+
const { loadConfig } = await import('./config.js');
|
|
97
|
+
const config = loadConfig();
|
|
98
|
+
const port = config.channels.web.port;
|
|
99
|
+
try {
|
|
100
|
+
const res = await fetch(`http://localhost:${port}/api/status`);
|
|
101
|
+
if (!res.ok)
|
|
102
|
+
throw new Error(`HTTP ${res.status}`);
|
|
103
|
+
const body = await res.json();
|
|
104
|
+
console.log(JSON.stringify(body, null, 2));
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
console.error(`Could not reach server on port ${port}: ${err.message}`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// ─── doctor ──────────────────────────────────────────────────────────────────
|
|
112
|
+
program
|
|
113
|
+
.command('doctor')
|
|
114
|
+
.description('Run pre-flight diagnostics on your reeboot installation')
|
|
115
|
+
.option('--skip-network', 'Skip network-dependent checks (API key, Signal version)')
|
|
116
|
+
.action(async (opts) => {
|
|
117
|
+
const { runDoctor, formatResult, doctorExitCode } = await import('./doctor.js');
|
|
118
|
+
console.log('Running reeboot diagnostics...\n');
|
|
119
|
+
const results = await runDoctor({ skipNetwork: opts.skipNetwork ?? false });
|
|
120
|
+
for (const r of results) {
|
|
121
|
+
console.log(formatResult(r));
|
|
122
|
+
}
|
|
123
|
+
console.log('');
|
|
124
|
+
const code = doctorExitCode(results);
|
|
125
|
+
if (code === 0) {
|
|
126
|
+
console.log('All checks passed (or only warnings).');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log('Some checks failed. See above for fix instructions.');
|
|
130
|
+
}
|
|
131
|
+
process.exit(code);
|
|
132
|
+
});
|
|
133
|
+
// ─── reload ──────────────────────────────────────────────────────────────────
|
|
134
|
+
program
|
|
135
|
+
.command('reload')
|
|
136
|
+
.description('Hot-reload extensions and skills on the running agent')
|
|
137
|
+
.action(async () => {
|
|
138
|
+
const { loadConfig } = await import('./config.js');
|
|
139
|
+
const config = loadConfig();
|
|
140
|
+
const port = config.channels.web.port;
|
|
141
|
+
try {
|
|
142
|
+
const res = await fetch(`http://localhost:${port}/api/reload`, { method: 'POST' });
|
|
143
|
+
if (!res.ok)
|
|
144
|
+
throw new Error(`HTTP ${res.status}`);
|
|
145
|
+
console.log('Extensions and skills reloaded.');
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
console.error(`Reload failed: ${err.message}`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// ─── restart ─────────────────────────────────────────────────────────────────
|
|
153
|
+
program
|
|
154
|
+
.command('restart')
|
|
155
|
+
.description('Gracefully restart the agent')
|
|
156
|
+
.action(async () => {
|
|
157
|
+
const { loadConfig } = await import('./config.js');
|
|
158
|
+
const config = loadConfig();
|
|
159
|
+
const port = config.channels.web.port;
|
|
160
|
+
try {
|
|
161
|
+
const res = await fetch(`http://localhost:${port}/api/restart`, { method: 'POST' });
|
|
162
|
+
if (!res.ok)
|
|
163
|
+
throw new Error(`HTTP ${res.status}`);
|
|
164
|
+
console.log('Restart initiated.');
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
console.error(`Restart failed: ${err.message}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
// ─── install ─────────────────────────────────────────────────────────────────
|
|
172
|
+
program
|
|
173
|
+
.command('install <package>')
|
|
174
|
+
.description('Install a pi-compatible package (e.g., npm:reeboot-github-tools, git:github.com/user/pkg)')
|
|
175
|
+
.action(async (pkg) => {
|
|
176
|
+
const { installPackage } = await import('./packages.js');
|
|
177
|
+
console.log(`Installing ${pkg}...`);
|
|
178
|
+
try {
|
|
179
|
+
await installPackage(pkg);
|
|
180
|
+
console.log(`Installed ${pkg}. Run 'reeboot reload' to activate.`);
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
console.error(err.message);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
// ─── uninstall ───────────────────────────────────────────────────────────────
|
|
188
|
+
program
|
|
189
|
+
.command('uninstall <package>')
|
|
190
|
+
.description('Uninstall an installed package by name')
|
|
191
|
+
.action(async (pkg) => {
|
|
192
|
+
const { uninstallPackage } = await import('./packages.js');
|
|
193
|
+
try {
|
|
194
|
+
await uninstallPackage(pkg);
|
|
195
|
+
console.log(`Uninstalled ${pkg}.`);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
console.error(err.message);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// ─── packages ────────────────────────────────────────────────────────────────
|
|
203
|
+
const packages = program
|
|
204
|
+
.command('packages')
|
|
205
|
+
.description('Package management commands');
|
|
206
|
+
packages
|
|
207
|
+
.command('list')
|
|
208
|
+
.description('List installed packages')
|
|
209
|
+
.action(async () => {
|
|
210
|
+
const { listPackages } = await import('./packages.js');
|
|
211
|
+
const pkgs = await listPackages();
|
|
212
|
+
if (pkgs.length === 0) {
|
|
213
|
+
console.log('No packages installed.');
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
console.log('Installed packages:');
|
|
217
|
+
console.log('Name Spec');
|
|
218
|
+
console.log('────────────────────────────── ──────────────────────────────────');
|
|
219
|
+
for (const pkg of pkgs) {
|
|
220
|
+
console.log(`${pkg.name.padEnd(30)} ${pkg.spec}`);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
// ─── channels ────────────────────────────────────────────────────────────────
|
|
224
|
+
const channels = program
|
|
225
|
+
.command('channels')
|
|
226
|
+
.description('Channel management commands');
|
|
227
|
+
channels
|
|
228
|
+
.command('list')
|
|
229
|
+
.description('List configured channels and their statuses')
|
|
230
|
+
.action(async () => {
|
|
231
|
+
const { loadConfig } = await import('./config.js');
|
|
232
|
+
const config = loadConfig();
|
|
233
|
+
const port = config.channels.web.port;
|
|
234
|
+
try {
|
|
235
|
+
const res = await fetch(`http://localhost:${port}/api/channels`);
|
|
236
|
+
if (!res.ok)
|
|
237
|
+
throw new Error(`HTTP ${res.status}`);
|
|
238
|
+
const body = await res.json();
|
|
239
|
+
if (body.length === 0) {
|
|
240
|
+
console.log('No channels configured.');
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
console.log('Channel Status Connected At');
|
|
244
|
+
console.log('──────── ──────────── ────────────────────');
|
|
245
|
+
for (const ch of body) {
|
|
246
|
+
const connectedAt = ch.connectedAt ? new Date(ch.connectedAt).toLocaleString() : '—';
|
|
247
|
+
console.log(`${ch.type.padEnd(8)} ${ch.status.padEnd(12)} ${connectedAt}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
console.error(`Could not reach server on port ${port}: ${err.message}`);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
channels
|
|
256
|
+
.command('login <type>')
|
|
257
|
+
.description('Login to a channel (e.g., whatsapp, signal)')
|
|
258
|
+
.action(async (type) => {
|
|
259
|
+
if (type === 'whatsapp') {
|
|
260
|
+
console.log('Starting WhatsApp login — scan the QR code in the terminal...');
|
|
261
|
+
const { join } = await import('path');
|
|
262
|
+
const { homedir } = await import('os');
|
|
263
|
+
const { WhatsAppAdapter } = await import('./channels/whatsapp.js');
|
|
264
|
+
const { MessageBus } = await import('./channels/interface.js');
|
|
265
|
+
const authDir = join(homedir(), '.reeboot', 'channels', 'whatsapp', 'auth');
|
|
266
|
+
const adapter = new WhatsAppAdapter(authDir);
|
|
267
|
+
const bus = new MessageBus();
|
|
268
|
+
await adapter.init({ enabled: true }, bus);
|
|
269
|
+
await adapter.start();
|
|
270
|
+
// Wait for connection or error
|
|
271
|
+
await new Promise((resolve) => {
|
|
272
|
+
const check = setInterval(() => {
|
|
273
|
+
const s = adapter.status();
|
|
274
|
+
if (s === 'connected') {
|
|
275
|
+
clearInterval(check);
|
|
276
|
+
console.log('WhatsApp connected.');
|
|
277
|
+
resolve();
|
|
278
|
+
}
|
|
279
|
+
else if (s === 'error') {
|
|
280
|
+
clearInterval(check);
|
|
281
|
+
console.error('WhatsApp login failed.');
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|
|
284
|
+
}, 500);
|
|
285
|
+
});
|
|
286
|
+
await adapter.stop();
|
|
287
|
+
process.exit(0);
|
|
288
|
+
}
|
|
289
|
+
else if (type === 'signal') {
|
|
290
|
+
const { execSync, spawnSync, spawn } = await import('child_process');
|
|
291
|
+
const { createInterface } = await import('readline');
|
|
292
|
+
const { homedir } = await import('os');
|
|
293
|
+
const { join } = await import('path');
|
|
294
|
+
const { mkdirSync } = await import('fs');
|
|
295
|
+
const qrTerminal = await import('qrcode-terminal');
|
|
296
|
+
const SIGNAL_API_PORT = 8080;
|
|
297
|
+
const signalDir = join(homedir(), '.reeboot', 'channels', 'signal');
|
|
298
|
+
console.log('\n📡 Signal setup via signal-cli-rest-api\n');
|
|
299
|
+
// Step 1: Check Docker
|
|
300
|
+
console.log('Step 1: Checking Docker...');
|
|
301
|
+
try {
|
|
302
|
+
execSync('docker info', { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
303
|
+
console.log(' ✓ Docker is running');
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
console.error(' ✗ Docker is not running or not installed.');
|
|
307
|
+
console.error(' Fix: Install Docker from https://docs.docker.com/get-docker/');
|
|
308
|
+
console.error(' Then start Docker Desktop (or systemctl start docker).');
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
// Step 2: Check / start container in native mode (required for linking)
|
|
312
|
+
const isContainerRunning = () => {
|
|
313
|
+
try {
|
|
314
|
+
return execSync('docker ps --filter name=signal-cli-rest-api --format "{{.Names}}"', { stdio: ['pipe', 'pipe', 'pipe'] }).toString().trim().includes('signal-cli-rest-api');
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
const isContainerStopped = () => {
|
|
321
|
+
try {
|
|
322
|
+
return execSync('docker ps -a --filter name=signal-cli-rest-api --filter status=exited --format "{{.Names}}"', { stdio: ['pipe', 'pipe', 'pipe'] }).toString().trim().includes('signal-cli-rest-api');
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
if (isContainerRunning()) {
|
|
329
|
+
console.log('\n ℹ signal-cli-rest-api is already running.');
|
|
330
|
+
console.log(' Restarting in native mode for linking...');
|
|
331
|
+
spawnSync('docker', ['stop', 'signal-cli-rest-api'], { stdio: 'pipe' });
|
|
332
|
+
spawnSync('docker', ['rm', 'signal-cli-rest-api'], { stdio: 'pipe' });
|
|
333
|
+
}
|
|
334
|
+
else if (isContainerStopped()) {
|
|
335
|
+
spawnSync('docker', ['rm', 'signal-cli-rest-api'], { stdio: 'pipe' });
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
// Pull image
|
|
339
|
+
console.log('\nStep 2: Pulling bbernhard/signal-cli-rest-api...');
|
|
340
|
+
const pull = spawnSync('docker', ['pull', 'bbernhard/signal-cli-rest-api:latest'], {
|
|
341
|
+
stdio: 'inherit',
|
|
342
|
+
});
|
|
343
|
+
if (pull.status !== 0) {
|
|
344
|
+
console.error(' ✗ Failed to pull image. Check your internet connection.');
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
console.log(' ✓ Image pulled');
|
|
348
|
+
}
|
|
349
|
+
// Start container in native mode (required for QR linking handshake)
|
|
350
|
+
console.log('\nStep 3: Starting container in native mode for linking...');
|
|
351
|
+
mkdirSync(signalDir, { recursive: true });
|
|
352
|
+
const start = spawnSync('docker', [
|
|
353
|
+
'run', '-d',
|
|
354
|
+
'--name', 'signal-cli-rest-api',
|
|
355
|
+
'-p', `${SIGNAL_API_PORT}:8080`,
|
|
356
|
+
'-v', `${signalDir}:/home/.local/share/signal-cli`,
|
|
357
|
+
'-e', 'MODE=native',
|
|
358
|
+
'bbernhard/signal-cli-rest-api:latest',
|
|
359
|
+
], { stdio: 'pipe' });
|
|
360
|
+
if (start.status !== 0) {
|
|
361
|
+
console.error(' ✗ Failed to start container.');
|
|
362
|
+
console.error(start.stderr?.toString());
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
// Wait for native mode to be ready
|
|
366
|
+
process.stdout.write(' Waiting for signal-cli to initialize...');
|
|
367
|
+
for (let i = 0; i < 15; i++) {
|
|
368
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
369
|
+
process.stdout.write('.');
|
|
370
|
+
try {
|
|
371
|
+
const res = await fetch(`http://127.0.0.1:${SIGNAL_API_PORT}/v1/about`);
|
|
372
|
+
if (res.ok) {
|
|
373
|
+
console.log(' ✓');
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
catch { /* not ready yet */ }
|
|
378
|
+
if (i === 14) {
|
|
379
|
+
console.log('');
|
|
380
|
+
console.error(' ✗ Container did not become ready in time.');
|
|
381
|
+
process.exit(1);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// Step 4: Register or link
|
|
385
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
386
|
+
const ask = (q) => new Promise((r) => rl.question(q, r));
|
|
387
|
+
console.log('\nStep 4: Register or link your phone number');
|
|
388
|
+
console.log(' (a) Register a new number via SMS/voice');
|
|
389
|
+
console.log(' (b) Link an existing Signal account (scan QR in terminal)');
|
|
390
|
+
const choice = (await ask('\nEnter (a) or (b): ')).trim().toLowerCase();
|
|
391
|
+
if (choice === 'b') {
|
|
392
|
+
// Get the sgnl:// URI directly from signal-cli inside the container
|
|
393
|
+
// then render it as ASCII QR — no external tools needed
|
|
394
|
+
console.log('\n📱 Generating QR code...\n');
|
|
395
|
+
const linkProc = spawn('docker', [
|
|
396
|
+
'exec', 'signal-cli-rest-api',
|
|
397
|
+
'signal-cli', 'link', '--name', 'reeboot',
|
|
398
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
399
|
+
let linked = false;
|
|
400
|
+
await new Promise((resolve, reject) => {
|
|
401
|
+
let output = '';
|
|
402
|
+
linkProc.stdout.on('data', (chunk) => {
|
|
403
|
+
output += chunk.toString();
|
|
404
|
+
const match = output.match(/(sgnl:\/\/[^\s\n]+)/);
|
|
405
|
+
if (match && !linked) {
|
|
406
|
+
const uri = match[1];
|
|
407
|
+
qrTerminal.default.generate(uri, { small: true });
|
|
408
|
+
console.log('Scan this QR code with your Signal app:');
|
|
409
|
+
console.log(' Settings → Linked Devices → + button\n');
|
|
410
|
+
console.log('Waiting for you to scan...');
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
linkProc.on('close', (code) => {
|
|
414
|
+
if (code === 0) {
|
|
415
|
+
linked = true;
|
|
416
|
+
resolve();
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
reject(new Error(`signal-cli link exited with code ${code}`));
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
linkProc.on('error', reject);
|
|
423
|
+
}).catch((err) => {
|
|
424
|
+
console.error(`\n ✗ Linking failed: ${err.message}`);
|
|
425
|
+
rl.close();
|
|
426
|
+
process.exit(1);
|
|
427
|
+
});
|
|
428
|
+
console.log(' ✓ Device linked successfully!');
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
// Register a new number
|
|
432
|
+
const phone = (await ask('\nEnter your phone number (e.g., +1234567890): ')).trim();
|
|
433
|
+
console.log(`\nSending verification SMS to ${phone}...`);
|
|
434
|
+
const regRes = await fetch(`http://127.0.0.1:${SIGNAL_API_PORT}/v1/register/${encodeURIComponent(phone)}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' });
|
|
435
|
+
if (!regRes.ok) {
|
|
436
|
+
const body = await regRes.text();
|
|
437
|
+
console.error(` ✗ Registration failed: ${body}`);
|
|
438
|
+
rl.close();
|
|
439
|
+
process.exit(1);
|
|
440
|
+
}
|
|
441
|
+
console.log(' ✓ SMS sent');
|
|
442
|
+
const code = (await ask('Enter the verification code you received: ')).trim();
|
|
443
|
+
const verRes = await fetch(`http://127.0.0.1:${SIGNAL_API_PORT}/v1/register/${encodeURIComponent(phone)}/code/${code}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' });
|
|
444
|
+
if (!verRes.ok) {
|
|
445
|
+
const body = await verRes.text();
|
|
446
|
+
console.error(` ✗ Verification failed: ${body}`);
|
|
447
|
+
rl.close();
|
|
448
|
+
process.exit(1);
|
|
449
|
+
}
|
|
450
|
+
console.log(' ✓ Number verified');
|
|
451
|
+
}
|
|
452
|
+
rl.close();
|
|
453
|
+
// Step 5: Restart container in json-rpc mode for production use
|
|
454
|
+
console.log('\nStep 5: Restarting container in json-rpc mode for production...');
|
|
455
|
+
spawnSync('docker', ['stop', 'signal-cli-rest-api'], { stdio: 'pipe' });
|
|
456
|
+
spawnSync('docker', ['rm', 'signal-cli-rest-api'], { stdio: 'pipe' });
|
|
457
|
+
const restart = spawnSync('docker', [
|
|
458
|
+
'run', '-d',
|
|
459
|
+
'--name', 'signal-cli-rest-api',
|
|
460
|
+
'--restart', 'always',
|
|
461
|
+
'-p', `${SIGNAL_API_PORT}:8080`,
|
|
462
|
+
'-v', `${signalDir}:/home/.local/share/signal-cli`,
|
|
463
|
+
'-e', 'MODE=json-rpc',
|
|
464
|
+
'bbernhard/signal-cli-rest-api:latest',
|
|
465
|
+
], { stdio: 'pipe' });
|
|
466
|
+
if (restart.status !== 0) {
|
|
467
|
+
console.error(' ✗ Failed to restart container in json-rpc mode.');
|
|
468
|
+
console.error(restart.stderr?.toString());
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
console.log(' ✓ Container running in json-rpc mode');
|
|
472
|
+
// Detect phone number from accounts
|
|
473
|
+
process.stdout.write('\nDetecting registered phone number...');
|
|
474
|
+
let detectedPhone = '';
|
|
475
|
+
for (let i = 0; i < 15; i++) {
|
|
476
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
477
|
+
process.stdout.write('.');
|
|
478
|
+
try {
|
|
479
|
+
const res = await fetch(`http://127.0.0.1:${SIGNAL_API_PORT}/v1/accounts`);
|
|
480
|
+
if (res.ok) {
|
|
481
|
+
const accounts = await res.json();
|
|
482
|
+
if (accounts.length > 0) {
|
|
483
|
+
detectedPhone = accounts[0];
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
catch { /* not ready yet */ }
|
|
489
|
+
}
|
|
490
|
+
console.log(detectedPhone ? ` ✓ ${detectedPhone}` : ' (could not detect — check manually)');
|
|
491
|
+
console.log('\n✅ Signal setup complete!');
|
|
492
|
+
console.log('\nAdd this to your ~/.reeboot/config.json:');
|
|
493
|
+
console.log(JSON.stringify({
|
|
494
|
+
channels: {
|
|
495
|
+
signal: {
|
|
496
|
+
enabled: true,
|
|
497
|
+
phoneNumber: detectedPhone || '+YOURNUMBER',
|
|
498
|
+
apiPort: SIGNAL_API_PORT,
|
|
499
|
+
pollInterval: 1000,
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}, null, 2));
|
|
503
|
+
console.log('\nThen run: reeboot start\n');
|
|
504
|
+
process.exit(0);
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
console.log(`channels login ${type}: not yet implemented`);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
channels
|
|
511
|
+
.command('logout <type>')
|
|
512
|
+
.description('Logout from a channel')
|
|
513
|
+
.action(async (type) => {
|
|
514
|
+
const { loadConfig } = await import('./config.js');
|
|
515
|
+
const config = loadConfig();
|
|
516
|
+
const port = config.channels.web.port;
|
|
517
|
+
try {
|
|
518
|
+
const res = await fetch(`http://localhost:${port}/api/channels/${type}/logout`, { method: 'POST' });
|
|
519
|
+
if (!res.ok)
|
|
520
|
+
throw new Error(`HTTP ${res.status}`);
|
|
521
|
+
console.log(`${type} logged out.`);
|
|
522
|
+
}
|
|
523
|
+
catch (err) {
|
|
524
|
+
console.error(`Could not reach server on port ${port}: ${err.message}`);
|
|
525
|
+
process.exit(1);
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
// ─── contexts ────────────────────────────────────────────────────────────────
|
|
529
|
+
const contexts = program
|
|
530
|
+
.command('contexts')
|
|
531
|
+
.description('Context management commands');
|
|
532
|
+
contexts
|
|
533
|
+
.command('list')
|
|
534
|
+
.description('List contexts (stub)')
|
|
535
|
+
.action(() => {
|
|
536
|
+
console.log('contexts list: not yet implemented');
|
|
537
|
+
});
|
|
538
|
+
contexts
|
|
539
|
+
.command('create <name>')
|
|
540
|
+
.description('Create a context (stub)')
|
|
541
|
+
.action((name) => {
|
|
542
|
+
console.log(`contexts create ${name}: not yet implemented`);
|
|
543
|
+
});
|
|
544
|
+
// ─── sessions ────────────────────────────────────────────────────────────────
|
|
545
|
+
const sessions = program
|
|
546
|
+
.command('sessions')
|
|
547
|
+
.description('Session management commands');
|
|
548
|
+
sessions
|
|
549
|
+
.command('list')
|
|
550
|
+
.description('List sessions (stub)')
|
|
551
|
+
.action(() => {
|
|
552
|
+
console.log('sessions list: not yet implemented');
|
|
553
|
+
});
|
|
554
|
+
// ─── Error on unknown commands ───────────────────────────────────────────────
|
|
555
|
+
program.on('command:*', () => {
|
|
556
|
+
console.error(`Unknown command: ${program.args.join(' ')}`);
|
|
557
|
+
console.error('Run "reeboot --help" for available commands.');
|
|
558
|
+
process.exit(1);
|
|
559
|
+
});
|
|
560
|
+
program.parse(process.argv);
|
|
561
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to the MessageBus, applies routing rules, dispatches incoming
|
|
5
|
+
* messages to the correct context's AgentRunner, handles in-chat commands,
|
|
6
|
+
* manages per-context inactivity timers, and queues messages when a context
|
|
7
|
+
* is busy.
|
|
8
|
+
*
|
|
9
|
+
* Routing priority: peer match > channel match > default
|
|
10
|
+
* Queue depth: max 5 messages per context; overflow gets "queue full" reply.
|
|
11
|
+
*/
|
|
12
|
+
import type { MessageBus, IncomingMessage, ChannelAdapter } from './channels/interface.js';
|
|
13
|
+
import type { AgentRunner } from './agent-runner/index.js';
|
|
14
|
+
export interface RoutingRule {
|
|
15
|
+
peer?: string;
|
|
16
|
+
channel?: string;
|
|
17
|
+
context: string;
|
|
18
|
+
}
|
|
19
|
+
export interface OrchestratorConfig {
|
|
20
|
+
routing: {
|
|
21
|
+
default: string;
|
|
22
|
+
rules: RoutingRule[];
|
|
23
|
+
};
|
|
24
|
+
session?: {
|
|
25
|
+
inactivityTimeout?: number;
|
|
26
|
+
};
|
|
27
|
+
agent?: {
|
|
28
|
+
turnTimeout?: number;
|
|
29
|
+
rateLimitRetries?: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export declare class Orchestrator {
|
|
33
|
+
private _config;
|
|
34
|
+
private _bus;
|
|
35
|
+
private _adapters;
|
|
36
|
+
private _runners;
|
|
37
|
+
private _contextState;
|
|
38
|
+
private _unsubscribe;
|
|
39
|
+
constructor(config: OrchestratorConfig, bus: MessageBus, adapters: Map<string, ChannelAdapter>, runners: Map<string, AgentRunner>);
|
|
40
|
+
start(): void;
|
|
41
|
+
stop(): void;
|
|
42
|
+
private _resolveContext;
|
|
43
|
+
private _handleMessage;
|
|
44
|
+
private _dispatch;
|
|
45
|
+
private _runTurn;
|
|
46
|
+
private _handleCommand;
|
|
47
|
+
handleNew(contextId: string, msg: IncomingMessage): Promise<void>;
|
|
48
|
+
handleContext(contextId: string, msg: IncomingMessage, targetContext: string): Promise<void>;
|
|
49
|
+
handleContexts(_contextId: string, msg: IncomingMessage): Promise<void>;
|
|
50
|
+
handleStatus(contextId: string, msg: IncomingMessage): Promise<void>;
|
|
51
|
+
handleCompact(contextId: string, msg: IncomingMessage): Promise<void>;
|
|
52
|
+
private _resetInactivityTimer;
|
|
53
|
+
private _getOrCreateContextState;
|
|
54
|
+
private _reply;
|
|
55
|
+
/** Expose runners for reload/restart */
|
|
56
|
+
get runners(): Map<string, AgentRunner>;
|
|
57
|
+
/** Expose adapters for restart */
|
|
58
|
+
get adapters(): Map<string, ChannelAdapter>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAI3D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,WAAW,EAAE,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AA6CD,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAA6B;gBAG/C,MAAM,EAAE,kBAAkB,EAC1B,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAQnC,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,SAAS;YAeH,QAAQ;YAyGR,cAAc;IAkCtB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjE,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5F,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3E,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,MAAM;IAQd,wCAAwC;IACxC,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAEtC;IAED,kCAAkC;IAClC,IAAI,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAE1C;CACF"}
|