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
|
@@ -0,0 +1,313 @@
|
|
|
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 { statfsSync } from 'fs';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
import { join } from 'path';
|
|
15
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
16
|
+
const MAX_QUEUE_DEPTH = 5;
|
|
17
|
+
const DEFAULT_INACTIVITY_MS = 14_400_000; // 4 hours
|
|
18
|
+
const DEFAULT_TURN_TIMEOUT_MS = 300_000; // 5 min
|
|
19
|
+
const DEFAULT_RATE_LIMIT_RETRIES = 3;
|
|
20
|
+
const DISK_SPACE_MIN_BYTES = 100 * 1024 * 1024; // 100MB
|
|
21
|
+
const BUSY_REPLY = "I'm still working on your last request. Please wait.";
|
|
22
|
+
const QUEUE_FULL_REPLY = "Queue full. Please wait for the current messages to be processed.";
|
|
23
|
+
// ─── Disk space check ─────────────────────────────────────────────────────────
|
|
24
|
+
function checkDiskSpace() {
|
|
25
|
+
try {
|
|
26
|
+
const reebotDir = join(homedir(), '.reeboot');
|
|
27
|
+
const stats = statfsSync(reebotDir);
|
|
28
|
+
const freeBytes = stats.bfree * stats.bsize;
|
|
29
|
+
if (freeBytes < DISK_SPACE_MIN_BYTES) {
|
|
30
|
+
const freeMB = Math.floor(freeBytes / (1024 * 1024));
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
message: `Disk space critically low (${freeMB}MB free). Cannot start new agent turn. Free up space in ~/.reeboot/`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return { ok: true };
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Can't check — allow turn to proceed
|
|
40
|
+
return { ok: true };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ─── Orchestrator ─────────────────────────────────────────────────────────────
|
|
44
|
+
export class Orchestrator {
|
|
45
|
+
_config;
|
|
46
|
+
_bus;
|
|
47
|
+
_adapters;
|
|
48
|
+
_runners;
|
|
49
|
+
_contextState = new Map();
|
|
50
|
+
_unsubscribe = null;
|
|
51
|
+
constructor(config, bus, adapters, runners) {
|
|
52
|
+
this._config = config;
|
|
53
|
+
this._bus = bus;
|
|
54
|
+
this._adapters = adapters;
|
|
55
|
+
this._runners = runners;
|
|
56
|
+
}
|
|
57
|
+
start() {
|
|
58
|
+
this._unsubscribe = this._bus.onMessage((msg) => this._handleMessage(msg));
|
|
59
|
+
}
|
|
60
|
+
stop() {
|
|
61
|
+
if (this._unsubscribe) {
|
|
62
|
+
this._unsubscribe();
|
|
63
|
+
this._unsubscribe = null;
|
|
64
|
+
}
|
|
65
|
+
for (const state of this._contextState.values()) {
|
|
66
|
+
if (state.inactivityTimer)
|
|
67
|
+
clearTimeout(state.inactivityTimer);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// ── Routing ───────────────────────────────────────────────────────────────
|
|
71
|
+
_resolveContext(msg) {
|
|
72
|
+
const rules = this._config.routing.rules ?? [];
|
|
73
|
+
// Check per-peer runtime override first
|
|
74
|
+
for (const state of this._contextState.values()) {
|
|
75
|
+
const override = state.peerContextOverride.get(msg.peerId);
|
|
76
|
+
if (override)
|
|
77
|
+
return override;
|
|
78
|
+
}
|
|
79
|
+
// Peer match
|
|
80
|
+
for (const rule of rules) {
|
|
81
|
+
if (rule.peer && rule.peer === msg.peerId)
|
|
82
|
+
return rule.context;
|
|
83
|
+
}
|
|
84
|
+
// Channel match
|
|
85
|
+
for (const rule of rules) {
|
|
86
|
+
if (rule.channel && rule.channel === msg.channelType)
|
|
87
|
+
return rule.context;
|
|
88
|
+
}
|
|
89
|
+
return this._config.routing.default ?? 'main';
|
|
90
|
+
}
|
|
91
|
+
// ── Message handling ──────────────────────────────────────────────────────
|
|
92
|
+
_handleMessage(msg) {
|
|
93
|
+
const contextId = this._resolveContext(msg);
|
|
94
|
+
const state = this._getOrCreateContextState(contextId);
|
|
95
|
+
// Reset inactivity timer
|
|
96
|
+
this._resetInactivityTimer(contextId, state);
|
|
97
|
+
if (state.busy) {
|
|
98
|
+
// Queue or drop
|
|
99
|
+
if (state.queue.length >= MAX_QUEUE_DEPTH) {
|
|
100
|
+
this._reply(msg, QUEUE_FULL_REPLY);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
state.queue.push(msg);
|
|
104
|
+
this._reply(msg, BUSY_REPLY);
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this._dispatch(contextId, msg);
|
|
109
|
+
}
|
|
110
|
+
_dispatch(contextId, msg) {
|
|
111
|
+
const state = this._getOrCreateContextState(contextId);
|
|
112
|
+
state.busy = true;
|
|
113
|
+
// Run async without blocking
|
|
114
|
+
this._runTurn(contextId, msg).finally(() => {
|
|
115
|
+
state.busy = false;
|
|
116
|
+
// Process next queued message if any
|
|
117
|
+
if (state.queue.length > 0) {
|
|
118
|
+
const next = state.queue.shift();
|
|
119
|
+
this._dispatch(contextId, next);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async _runTurn(contextId, msg) {
|
|
124
|
+
// Check for in-chat command
|
|
125
|
+
if (msg.content.startsWith('/')) {
|
|
126
|
+
const handled = await this._handleCommand(contextId, msg);
|
|
127
|
+
if (handled)
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Disk space pre-check
|
|
131
|
+
const disk = checkDiskSpace();
|
|
132
|
+
if (!disk.ok) {
|
|
133
|
+
this._reply(msg, disk.message);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const runner = this._runners.get(contextId);
|
|
137
|
+
if (!runner) {
|
|
138
|
+
this._reply(msg, `No runner found for context "${contextId}".`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const turnTimeoutMs = this._config.agent?.turnTimeout ?? DEFAULT_TURN_TIMEOUT_MS;
|
|
142
|
+
const maxRetries = this._config.agent?.rateLimitRetries ?? DEFAULT_RATE_LIMIT_RETRIES;
|
|
143
|
+
let responseText = '';
|
|
144
|
+
let retries = 0;
|
|
145
|
+
while (true) {
|
|
146
|
+
responseText = '';
|
|
147
|
+
// Build a promise that races the turn vs. timeout
|
|
148
|
+
let aborted = false;
|
|
149
|
+
const turnPromise = runner.prompt(msg.content, (event) => {
|
|
150
|
+
if (event.type === 'text_delta') {
|
|
151
|
+
responseText += event.delta;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
let timeoutHandle = null;
|
|
155
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
156
|
+
timeoutHandle = setTimeout(() => resolve('timeout'), turnTimeoutMs);
|
|
157
|
+
});
|
|
158
|
+
let result = 'done';
|
|
159
|
+
let turnError = null;
|
|
160
|
+
try {
|
|
161
|
+
const winner = await Promise.race([
|
|
162
|
+
turnPromise.then(() => 'done'),
|
|
163
|
+
timeoutPromise,
|
|
164
|
+
]);
|
|
165
|
+
if (winner === 'timeout') {
|
|
166
|
+
aborted = true;
|
|
167
|
+
result = 'timeout';
|
|
168
|
+
try {
|
|
169
|
+
runner.abort();
|
|
170
|
+
}
|
|
171
|
+
catch { /* ignore */ }
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
result = 'error';
|
|
176
|
+
turnError = err;
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
if (timeoutHandle)
|
|
180
|
+
clearTimeout(timeoutHandle);
|
|
181
|
+
}
|
|
182
|
+
if (result === 'timeout') {
|
|
183
|
+
this._reply(msg, 'Your request timed out. The agent took too long to respond.');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (result === 'error') {
|
|
187
|
+
const err = turnError;
|
|
188
|
+
if (err?.name === 'AbortError')
|
|
189
|
+
return;
|
|
190
|
+
// Check for rate limit (HTTP 429)
|
|
191
|
+
const isRateLimit = err?.status === 429 ||
|
|
192
|
+
(err?.message ?? '').toLowerCase().includes('rate limit');
|
|
193
|
+
if (isRateLimit && retries < maxRetries) {
|
|
194
|
+
retries++;
|
|
195
|
+
// Exponential backoff: base is configurable (default 5s), tests can inject 10ms
|
|
196
|
+
const backoffBase = this._config.agent?._testBackoffMs ?? 5000;
|
|
197
|
+
const delayMs = Math.pow(2, retries) * backoffBase; // 10s, 20s, 40s (or 20ms, 40ms in tests)
|
|
198
|
+
this._reply(msg, `Rate limited — retrying in ${Math.round(delayMs / 1000)}s (attempt ${retries}/${maxRetries})...`);
|
|
199
|
+
await new Promise(r => setTimeout(r, delayMs));
|
|
200
|
+
continue; // retry
|
|
201
|
+
}
|
|
202
|
+
// Non-retryable error
|
|
203
|
+
this._reply(msg, `Error: ${err?.message ?? String(err)}`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
// Success
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (responseText) {
|
|
210
|
+
this._reply(msg, responseText);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ── In-chat commands ──────────────────────────────────────────────────────
|
|
214
|
+
async _handleCommand(contextId, msg) {
|
|
215
|
+
const content = msg.content.trim();
|
|
216
|
+
const parts = content.split(/\s+/);
|
|
217
|
+
const cmd = parts[0].toLowerCase();
|
|
218
|
+
if (cmd === '/new') {
|
|
219
|
+
await this.handleNew(contextId, msg);
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
if (cmd === '/context' && parts[1]) {
|
|
223
|
+
await this.handleContext(contextId, msg, parts[1]);
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
if (cmd === '/contexts') {
|
|
227
|
+
await this.handleContexts(contextId, msg);
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
if (cmd === '/status') {
|
|
231
|
+
await this.handleStatus(contextId, msg);
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
if (cmd === '/compact') {
|
|
235
|
+
await this.handleCompact(contextId, msg);
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
// Unknown slash command — forward to agent
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
async handleNew(contextId, msg) {
|
|
242
|
+
const runner = this._runners.get(contextId);
|
|
243
|
+
if (runner) {
|
|
244
|
+
await runner.dispose();
|
|
245
|
+
}
|
|
246
|
+
this._reply(msg, 'New session started.');
|
|
247
|
+
}
|
|
248
|
+
async handleContext(contextId, msg, targetContext) {
|
|
249
|
+
const state = this._getOrCreateContextState(contextId);
|
|
250
|
+
state.peerContextOverride.set(msg.peerId, targetContext);
|
|
251
|
+
this._reply(msg, `Switched to context: ${targetContext}`);
|
|
252
|
+
}
|
|
253
|
+
async handleContexts(_contextId, msg) {
|
|
254
|
+
const names = Array.from(this._runners.keys());
|
|
255
|
+
const contextId = this._resolveContext(msg);
|
|
256
|
+
const lines = names.map(n => (n === contextId ? `* ${n}` : ` ${n}`));
|
|
257
|
+
this._reply(msg, lines.join('\n'));
|
|
258
|
+
}
|
|
259
|
+
async handleStatus(contextId, msg) {
|
|
260
|
+
this._reply(msg, `Context: ${contextId}`);
|
|
261
|
+
}
|
|
262
|
+
async handleCompact(contextId, msg) {
|
|
263
|
+
// Trigger pi session compaction via runner if supported
|
|
264
|
+
const runner = this._runners.get(contextId);
|
|
265
|
+
if (runner?.compact) {
|
|
266
|
+
await runner.compact();
|
|
267
|
+
}
|
|
268
|
+
this._reply(msg, 'Session compacted.');
|
|
269
|
+
}
|
|
270
|
+
// ── Inactivity timer ──────────────────────────────────────────────────────
|
|
271
|
+
_resetInactivityTimer(contextId, state) {
|
|
272
|
+
if (state.inactivityTimer) {
|
|
273
|
+
clearTimeout(state.inactivityTimer);
|
|
274
|
+
}
|
|
275
|
+
const timeoutMs = this._config.session?.inactivityTimeout ?? DEFAULT_INACTIVITY_MS;
|
|
276
|
+
state.inactivityTimer = setTimeout(async () => {
|
|
277
|
+
const runner = this._runners.get(contextId);
|
|
278
|
+
if (runner) {
|
|
279
|
+
await runner.dispose();
|
|
280
|
+
}
|
|
281
|
+
this._contextState.delete(contextId);
|
|
282
|
+
}, timeoutMs);
|
|
283
|
+
}
|
|
284
|
+
// ── Helpers ───────────────────────────────────────────────────────────────
|
|
285
|
+
_getOrCreateContextState(contextId) {
|
|
286
|
+
if (!this._contextState.has(contextId)) {
|
|
287
|
+
this._contextState.set(contextId, {
|
|
288
|
+
busy: false,
|
|
289
|
+
queue: [],
|
|
290
|
+
inactivityTimer: null,
|
|
291
|
+
peerContextOverride: new Map(),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
return this._contextState.get(contextId);
|
|
295
|
+
}
|
|
296
|
+
_reply(msg, text) {
|
|
297
|
+
const adapter = this._adapters.get(msg.channelType);
|
|
298
|
+
if (!adapter)
|
|
299
|
+
return;
|
|
300
|
+
adapter.send(msg.peerId, { type: 'text', text }).catch((err) => {
|
|
301
|
+
console.error(`[Orchestrator] Failed to send reply: ${err}`);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/** Expose runners for reload/restart */
|
|
305
|
+
get runners() {
|
|
306
|
+
return this._runners;
|
|
307
|
+
}
|
|
308
|
+
/** Expose adapters for restart */
|
|
309
|
+
get adapters() {
|
|
310
|
+
return this._adapters;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package system
|
|
3
|
+
*
|
|
4
|
+
* installPackage, uninstallPackage, listPackages.
|
|
5
|
+
* Packages are installed to ~/.reeboot/packages/ via npm.
|
|
6
|
+
* Identifiers are stored in config.extensions.packages[].
|
|
7
|
+
*/
|
|
8
|
+
export interface PackageOptions {
|
|
9
|
+
/** Path to config.json (default: ~/.reeboot/config.json) */
|
|
10
|
+
configPath?: string;
|
|
11
|
+
/** Reeboot home dir (default: ~/.reeboot) */
|
|
12
|
+
reebotDir?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface InstalledPackage {
|
|
15
|
+
spec: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function installPackage(spec: string, opts?: PackageOptions): Promise<void>;
|
|
19
|
+
export declare function uninstallPackage(name: string, opts?: PackageOptions): Promise<void>;
|
|
20
|
+
export declare function listPackages(opts?: PackageOptions): Promise<InstalledPackage[]>;
|
|
21
|
+
//# sourceMappingURL=packages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packages.d.ts","sourceRoot":"","sources":["../src/packages.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAqDD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAID,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAID,wBAAsB,YAAY,CAChC,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAW7B"}
|
package/dist/packages.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package system
|
|
3
|
+
*
|
|
4
|
+
* installPackage, uninstallPackage, listPackages.
|
|
5
|
+
* Packages are installed to ~/.reeboot/packages/ via npm.
|
|
6
|
+
* Identifiers are stored in config.extensions.packages[].
|
|
7
|
+
*/
|
|
8
|
+
import { spawnSync } from 'child_process';
|
|
9
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
13
|
+
function getDefaultReebotDir() {
|
|
14
|
+
return join(homedir(), '.reeboot');
|
|
15
|
+
}
|
|
16
|
+
function getDefaultConfigPath(reebotDir) {
|
|
17
|
+
return join(reebotDir, 'config.json');
|
|
18
|
+
}
|
|
19
|
+
function readConfig(configPath) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveConfig(configPath, config) {
|
|
28
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert a spec string (npm:name, git:..., /local/path) to the package name
|
|
32
|
+
* and the npm install argument.
|
|
33
|
+
*/
|
|
34
|
+
function parseSpec(spec) {
|
|
35
|
+
if (spec.startsWith('npm:')) {
|
|
36
|
+
const pkgWithVersion = spec.slice(4);
|
|
37
|
+
const name = pkgWithVersion.split('@')[0];
|
|
38
|
+
return { name, npmArg: pkgWithVersion };
|
|
39
|
+
}
|
|
40
|
+
if (spec.startsWith('git:')) {
|
|
41
|
+
// git:github.com/user/repo → github:user/repo
|
|
42
|
+
const path = spec.slice(4);
|
|
43
|
+
const parts = path.split('/');
|
|
44
|
+
if (parts[0].includes('github.com')) {
|
|
45
|
+
const npmArg = `github:${parts.slice(1).join('/')}`;
|
|
46
|
+
const name = parts[parts.length - 1].replace('.git', '');
|
|
47
|
+
return { name, npmArg };
|
|
48
|
+
}
|
|
49
|
+
// Generic git URL
|
|
50
|
+
return { name: spec, npmArg: spec.slice(4) };
|
|
51
|
+
}
|
|
52
|
+
// Local path
|
|
53
|
+
const name = spec.split('/').pop() ?? spec;
|
|
54
|
+
return { name, npmArg: spec };
|
|
55
|
+
}
|
|
56
|
+
// ─── installPackage ───────────────────────────────────────────────────────────
|
|
57
|
+
export async function installPackage(spec, opts = {}) {
|
|
58
|
+
const reebotDir = opts.reebotDir ?? getDefaultReebotDir();
|
|
59
|
+
const configPath = opts.configPath ?? getDefaultConfigPath(reebotDir);
|
|
60
|
+
const packagesDir = join(reebotDir, 'packages');
|
|
61
|
+
mkdirSync(packagesDir, { recursive: true });
|
|
62
|
+
const { name, npmArg } = parseSpec(spec);
|
|
63
|
+
// Run npm install
|
|
64
|
+
const result = spawnSync('npm', ['install', '--prefix', packagesDir, npmArg], { stdio: 'inherit' });
|
|
65
|
+
if (result.status !== 0) {
|
|
66
|
+
throw new Error(`npm install failed for ${spec} (exit code ${result.status})`);
|
|
67
|
+
}
|
|
68
|
+
// Update config
|
|
69
|
+
const config = readConfig(configPath);
|
|
70
|
+
if (!config.extensions)
|
|
71
|
+
config.extensions = {};
|
|
72
|
+
if (!Array.isArray(config.extensions.packages))
|
|
73
|
+
config.extensions.packages = [];
|
|
74
|
+
// Avoid duplicates
|
|
75
|
+
if (!config.extensions.packages.includes(spec)) {
|
|
76
|
+
config.extensions.packages.push(spec);
|
|
77
|
+
}
|
|
78
|
+
saveConfig(configPath, config);
|
|
79
|
+
}
|
|
80
|
+
// ─── uninstallPackage ─────────────────────────────────────────────────────────
|
|
81
|
+
export async function uninstallPackage(name, opts = {}) {
|
|
82
|
+
const reebotDir = opts.reebotDir ?? getDefaultReebotDir();
|
|
83
|
+
const configPath = opts.configPath ?? getDefaultConfigPath(reebotDir);
|
|
84
|
+
const packagesDir = join(reebotDir, 'packages');
|
|
85
|
+
// Find the spec in config
|
|
86
|
+
const config = readConfig(configPath);
|
|
87
|
+
const packages = config.extensions?.packages ?? [];
|
|
88
|
+
// Find matching spec (could be npm:name, git:..., or just name)
|
|
89
|
+
const matchingSpec = packages.find((spec) => {
|
|
90
|
+
const { name: specName } = parseSpec(spec);
|
|
91
|
+
return specName === name || spec === name;
|
|
92
|
+
});
|
|
93
|
+
if (!matchingSpec) {
|
|
94
|
+
throw new Error(`Package not installed: ${name}`);
|
|
95
|
+
}
|
|
96
|
+
// Run npm uninstall
|
|
97
|
+
const result = spawnSync('npm', ['uninstall', '--prefix', packagesDir, name], { stdio: 'inherit' });
|
|
98
|
+
if (result.status !== 0) {
|
|
99
|
+
throw new Error(`npm uninstall failed for ${name} (exit code ${result.status})`);
|
|
100
|
+
}
|
|
101
|
+
// Update config
|
|
102
|
+
config.extensions.packages = packages.filter((spec) => spec !== matchingSpec);
|
|
103
|
+
saveConfig(configPath, config);
|
|
104
|
+
}
|
|
105
|
+
// ─── listPackages ─────────────────────────────────────────────────────────────
|
|
106
|
+
export async function listPackages(opts = {}) {
|
|
107
|
+
const reebotDir = opts.reebotDir ?? getDefaultReebotDir();
|
|
108
|
+
const configPath = opts.configPath ?? getDefaultConfigPath(reebotDir);
|
|
109
|
+
const config = readConfig(configPath);
|
|
110
|
+
const packages = config.extensions?.packages ?? [];
|
|
111
|
+
return packages.map((spec) => {
|
|
112
|
+
const { name } = parseSpec(spec);
|
|
113
|
+
return { spec, name };
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=packages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packages.js","sourceRoot":"","sources":["../src/packages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Scheduler registry singleton.
|
|
3
|
+
* Set by server.ts after the Scheduler is initialised.
|
|
4
|
+
*/
|
|
5
|
+
import type { SchedulerToolsTarget } from './scheduler.js';
|
|
6
|
+
export declare let globalScheduler: SchedulerToolsTarget;
|
|
7
|
+
export declare function setGlobalScheduler(scheduler: SchedulerToolsTarget): void;
|
|
8
|
+
//# sourceMappingURL=scheduler-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler-registry.d.ts","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAQ3D,eAAO,IAAI,eAAe,EAAE,oBAAoC,CAAC;AAEjE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAExE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Scheduler registry singleton.
|
|
3
|
+
* Set by server.ts after the Scheduler is initialised.
|
|
4
|
+
*/
|
|
5
|
+
// Stub scheduler that no-ops until a real one is registered
|
|
6
|
+
const noopScheduler = {
|
|
7
|
+
registerJob: () => { },
|
|
8
|
+
cancelJob: () => { },
|
|
9
|
+
};
|
|
10
|
+
export let globalScheduler = noopScheduler;
|
|
11
|
+
export function setGlobalScheduler(scheduler) {
|
|
12
|
+
globalScheduler = scheduler;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=scheduler-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler-registry.js","sourceRoot":"","sources":["../src/scheduler-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,4DAA4D;AAC5D,MAAM,aAAa,GAAyB;IAC1C,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;IACrB,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC;CACpB,CAAC;AAEF,MAAM,CAAC,IAAI,eAAe,GAAyB,aAAa,CAAC;AAEjE,MAAM,UAAU,kBAAkB,CAAC,SAA+B;IAChE,eAAe,GAAG,SAAS,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler
|
|
3
|
+
*
|
|
4
|
+
* Loads enabled tasks from the SQLite `tasks` table on startup,
|
|
5
|
+
* registers node-cron jobs, and dispatches prompts to the orchestrator
|
|
6
|
+
* when jobs fire. Updates `last_run` after each execution.
|
|
7
|
+
*/
|
|
8
|
+
import type Database from 'better-sqlite3';
|
|
9
|
+
export interface ScheduledTaskRef {
|
|
10
|
+
taskId: string;
|
|
11
|
+
contextId: string;
|
|
12
|
+
prompt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SchedulerOrchestrator {
|
|
15
|
+
handleScheduledTask(task: ScheduledTaskRef): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare class Scheduler {
|
|
18
|
+
private _db;
|
|
19
|
+
private _orchestrator;
|
|
20
|
+
private _jobs;
|
|
21
|
+
constructor(db: Database.Database, orchestrator: SchedulerOrchestrator);
|
|
22
|
+
start(): Promise<void>;
|
|
23
|
+
registerJob(task: {
|
|
24
|
+
id: string;
|
|
25
|
+
contextId: string;
|
|
26
|
+
schedule: string;
|
|
27
|
+
prompt: string;
|
|
28
|
+
}): void;
|
|
29
|
+
cancelJob(taskId: string): void;
|
|
30
|
+
stop(): void;
|
|
31
|
+
}
|
|
32
|
+
export interface SchedulerToolsTarget {
|
|
33
|
+
registerJob(task: {
|
|
34
|
+
id: string;
|
|
35
|
+
contextId: string;
|
|
36
|
+
schedule: string;
|
|
37
|
+
prompt: string;
|
|
38
|
+
}): void;
|
|
39
|
+
cancelJob(taskId: string): void;
|
|
40
|
+
}
|
|
41
|
+
export interface ToolResult {
|
|
42
|
+
content: Array<{
|
|
43
|
+
type: 'text';
|
|
44
|
+
text: string;
|
|
45
|
+
}>;
|
|
46
|
+
details: Record<string, unknown>;
|
|
47
|
+
isError?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare function createSchedulerTools(db: Database.Database, scheduler: SchedulerToolsTarget): {
|
|
50
|
+
schedule_task(params: {
|
|
51
|
+
schedule: string;
|
|
52
|
+
prompt: string;
|
|
53
|
+
contextId?: string;
|
|
54
|
+
}): Promise<ToolResult>;
|
|
55
|
+
list_tasks(_params: Record<string, never>): Promise<ToolResult>;
|
|
56
|
+
cancel_task(params: {
|
|
57
|
+
task_id: string;
|
|
58
|
+
}): Promise<ToolResult>;
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAaD,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAoB;IAC/B,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,KAAK,CAAuD;gBAExD,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,qBAAqB;IAKhE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B,WAAW,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IA2B5F,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,IAAI,IAAI,IAAI;CAMb;AAID,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,oBAAoB;0BAE3D;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,UAAU,CAAC;wBAsCG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;wBAsB3C;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;EAsBtE"}
|