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.
Files changed (110) hide show
  1. package/README.md +361 -0
  2. package/container/Dockerfile +48 -0
  3. package/container/entrypoint.sh +8 -0
  4. package/dist/agent-runner/index.d.ts +9 -0
  5. package/dist/agent-runner/index.d.ts.map +1 -0
  6. package/dist/agent-runner/index.js +21 -0
  7. package/dist/agent-runner/index.js.map +1 -0
  8. package/dist/agent-runner/interface.d.ts +56 -0
  9. package/dist/agent-runner/interface.d.ts.map +1 -0
  10. package/dist/agent-runner/interface.js +5 -0
  11. package/dist/agent-runner/interface.js.map +1 -0
  12. package/dist/agent-runner/pi-runner.d.ts +41 -0
  13. package/dist/agent-runner/pi-runner.d.ts.map +1 -0
  14. package/dist/agent-runner/pi-runner.js +162 -0
  15. package/dist/agent-runner/pi-runner.js.map +1 -0
  16. package/dist/channels/interface.d.ts +63 -0
  17. package/dist/channels/interface.d.ts.map +1 -0
  18. package/dist/channels/interface.js +33 -0
  19. package/dist/channels/interface.js.map +1 -0
  20. package/dist/channels/registry.d.ts +30 -0
  21. package/dist/channels/registry.d.ts.map +1 -0
  22. package/dist/channels/registry.js +71 -0
  23. package/dist/channels/registry.js.map +1 -0
  24. package/dist/channels/signal.d.ts +51 -0
  25. package/dist/channels/signal.d.ts.map +1 -0
  26. package/dist/channels/signal.js +263 -0
  27. package/dist/channels/signal.js.map +1 -0
  28. package/dist/channels/web.d.ts +35 -0
  29. package/dist/channels/web.d.ts.map +1 -0
  30. package/dist/channels/web.js +65 -0
  31. package/dist/channels/web.js.map +1 -0
  32. package/dist/channels/whatsapp.d.ts +25 -0
  33. package/dist/channels/whatsapp.d.ts.map +1 -0
  34. package/dist/channels/whatsapp.js +150 -0
  35. package/dist/channels/whatsapp.js.map +1 -0
  36. package/dist/config.d.ts +366 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +140 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/context.d.ts +69 -0
  41. package/dist/context.d.ts.map +1 -0
  42. package/dist/context.js +166 -0
  43. package/dist/context.js.map +1 -0
  44. package/dist/credential-proxy.d.ts +25 -0
  45. package/dist/credential-proxy.d.ts.map +1 -0
  46. package/dist/credential-proxy.js +96 -0
  47. package/dist/credential-proxy.js.map +1 -0
  48. package/dist/daemon.d.ts +25 -0
  49. package/dist/daemon.d.ts.map +1 -0
  50. package/dist/daemon.js +138 -0
  51. package/dist/daemon.js.map +1 -0
  52. package/dist/db/index.d.ts +23 -0
  53. package/dist/db/index.d.ts.map +1 -0
  54. package/dist/db/index.js +113 -0
  55. package/dist/db/index.js.map +1 -0
  56. package/dist/db/schema.d.ts +408 -0
  57. package/dist/db/schema.d.ts.map +1 -0
  58. package/dist/db/schema.js +55 -0
  59. package/dist/db/schema.js.map +1 -0
  60. package/dist/doctor.d.ts +23 -0
  61. package/dist/doctor.d.ts.map +1 -0
  62. package/dist/doctor.js +217 -0
  63. package/dist/doctor.js.map +1 -0
  64. package/dist/extensions/loader.d.ts +19 -0
  65. package/dist/extensions/loader.d.ts.map +1 -0
  66. package/dist/extensions/loader.js +124 -0
  67. package/dist/extensions/loader.js.map +1 -0
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +561 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/orchestrator.d.ts +60 -0
  73. package/dist/orchestrator.d.ts.map +1 -0
  74. package/dist/orchestrator.js +313 -0
  75. package/dist/orchestrator.js.map +1 -0
  76. package/dist/packages.d.ts +21 -0
  77. package/dist/packages.d.ts.map +1 -0
  78. package/dist/packages.js +116 -0
  79. package/dist/packages.js.map +1 -0
  80. package/dist/scheduler-registry.d.ts +8 -0
  81. package/dist/scheduler-registry.d.ts.map +1 -0
  82. package/dist/scheduler-registry.js +14 -0
  83. package/dist/scheduler-registry.js.map +1 -0
  84. package/dist/scheduler.d.ts +60 -0
  85. package/dist/scheduler.d.ts.map +1 -0
  86. package/dist/scheduler.js +143 -0
  87. package/dist/scheduler.js.map +1 -0
  88. package/dist/server.d.ts +18 -0
  89. package/dist/server.d.ts.map +1 -0
  90. package/dist/server.js +489 -0
  91. package/dist/server.js.map +1 -0
  92. package/dist/setup-wizard.d.ts +12 -0
  93. package/dist/setup-wizard.d.ts.map +1 -0
  94. package/dist/setup-wizard.js +163 -0
  95. package/dist/setup-wizard.js.map +1 -0
  96. package/extensions/confirm-destructive.ts +59 -0
  97. package/extensions/custom-compaction.ts +114 -0
  98. package/extensions/protected-paths.ts +30 -0
  99. package/extensions/sandbox/index.ts +317 -0
  100. package/extensions/sandbox/package-lock.json +92 -0
  101. package/extensions/sandbox/package.json +19 -0
  102. package/extensions/scheduler-tool.ts +65 -0
  103. package/extensions/session-name.ts +27 -0
  104. package/extensions/token-meter.ts +55 -0
  105. package/package.json +68 -0
  106. package/skills/send-message/SKILL.md +27 -0
  107. package/skills/web-search/SKILL.md +32 -0
  108. package/templates/global-agents.md +23 -0
  109. package/templates/main-agents.md +28 -0
  110. package/webchat/index.html +421 -0
package/README.md ADDED
@@ -0,0 +1,361 @@
1
+ # reeboot
2
+
3
+ > Your personal AI agent. One command to install. Runs locally. Talk to it from anywhere.
4
+
5
+ ---
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Install and launch the setup wizard
11
+ npx reeboot
12
+
13
+ # Or install globally
14
+ npm install -g reeboot
15
+ reeboot setup
16
+ reeboot start
17
+ ```
18
+
19
+ The wizard will ask for your LLM provider, API key, model, and which channels to enable. After that, `reeboot start` runs the agent — open the WebChat URL it prints, or scan the WhatsApp QR code.
20
+
21
+ ---
22
+
23
+ ## What It Can Do
24
+
25
+ | Capability | Description |
26
+ |---|---|
27
+ | **WebChat** | Browser-based chat UI, available instantly at `http://localhost:3000` |
28
+ | **WhatsApp** | Scan a QR code — your agent lives in your WhatsApp DMs |
29
+ | **Signal** | Connect via a Signal Docker container (json-rpc or polling mode) |
30
+ | **Multi-context** | Separate conversation threads (work, personal, projects) |
31
+ | **Scheduled tasks** | Ask your agent to remind you or run jobs on a cron schedule |
32
+ | **Extensions** | Pi-compatible extension system — tools, compaction, custom prompts |
33
+ | **Skills** | Drop Markdown skill files into `~/.reeboot/skills/` for instant capabilities |
34
+ | **Packages** | Install community tool packages: `reeboot install npm:reeboot-github-tools` |
35
+ | **Daemon mode** | Run as a background service (launchd on macOS, systemd on Linux) |
36
+ | **Doctor** | `reeboot doctor` diagnoses your setup before you even start |
37
+
38
+ ---
39
+
40
+ ## Architecture Overview
41
+
42
+ Reeboot is a single Node.js process. All channels (WhatsApp, Signal, WebChat) connect to the same orchestrator, which routes messages to the AI agent and returns responses.
43
+
44
+ ```
45
+ ┌──────────────────────────────────┐
46
+ │ reeboot process │
47
+ │ │
48
+ WhatsApp ────────►│ ChannelRegistry │
49
+ Signal ────────►│ │ │
50
+ WebChat ────────►│ MessageBus ──► Orchestrator │
51
+ HTTP API ────────►│ │ │
52
+ │ AgentRunner (pi) │
53
+ │ │ │
54
+ │ LLM Provider │
55
+ │ (Anthropic / OpenAI …) │
56
+ └──────────────────────────────────┘
57
+ ```
58
+
59
+ Configuration lives in `~/.reeboot/config.json`. Sessions and conversation history are stored in `~/.reeboot/db/reeboot.db` (SQLite). Extensions are loaded from `~/.reeboot/extensions/` and `~/.reeboot/packages/`.
60
+
61
+ ---
62
+
63
+ ## Configuration Reference
64
+
65
+ Config file: `~/.reeboot/config.json`
66
+
67
+ ```json
68
+ {
69
+ "agent": {
70
+ "provider": "anthropic",
71
+ "apiKey": "sk-ant-...",
72
+ "model": "claude-opus-4-5",
73
+ "name": "Reeboot",
74
+ "turnTimeout": 300000,
75
+ "rateLimitRetries": 3
76
+ },
77
+ "channels": {
78
+ "web": {
79
+ "enabled": true,
80
+ "port": 3000
81
+ },
82
+ "whatsapp": {
83
+ "enabled": false
84
+ },
85
+ "signal": {
86
+ "enabled": false,
87
+ "phoneNumber": "+15551234567",
88
+ "apiUrl": "http://localhost:8080",
89
+ "pollInterval": 1000
90
+ }
91
+ },
92
+ "extensions": {
93
+ "packages": []
94
+ },
95
+ "credentialProxy": {
96
+ "enabled": false
97
+ }
98
+ }
99
+ ```
100
+
101
+ **Environment variables** (override config values):
102
+ - `REEBOOT_API_KEY` — LLM provider API key
103
+ - `REEBOOT_PROVIDER` — provider name
104
+ - `REEBOOT_MODEL` — model ID
105
+ - `REEBOOT_PORT` — HTTP port (default: 3000)
106
+
107
+ ---
108
+
109
+ ## Extension System
110
+
111
+ Reeboot uses a three-level extension ladder. Pick the right level for what you want to do:
112
+
113
+ ### Level 1 — Skills (Markdown, easiest)
114
+
115
+ Drop a `SKILL.md` file into `~/.reeboot/skills/<skill-name>/SKILL.md`. The agent reads it as a system-level instruction when the skill is invoked. Great for domain-specific personas, checklists, or prompt templates.
116
+
117
+ ```
118
+ ~/.reeboot/skills/
119
+ morning-standup/
120
+ SKILL.md ← "When asked for standup, ask 3 questions then summarise..."
121
+ code-review/
122
+ SKILL.md
123
+ ```
124
+
125
+ ### Level 2 — Pi Extensions (TypeScript, full tool access)
126
+
127
+ Drop a `.ts` file into `~/.reeboot/extensions/`. Extensions are pi-compatible — they can register tools, hook into system prompt generation, and intercept messages.
128
+
129
+ ```typescript
130
+ // ~/.reeboot/extensions/my-tool.ts
131
+ export default {
132
+ tools: [
133
+ {
134
+ name: 'get_weather',
135
+ description: 'Get current weather for a city',
136
+ inputSchema: { ... },
137
+ handler: async ({ city }) => { ... }
138
+ }
139
+ ]
140
+ };
141
+ ```
142
+
143
+ Reload without restart: `reeboot reload`
144
+
145
+ ### Level 3 — Channel Adapters (TypeScript, custom channels)
146
+
147
+ Implement the `ChannelAdapter` interface from `reeboot/channels` to add new messaging channels (Telegram, SMS, Slack, etc.):
148
+
149
+ ```typescript
150
+ import type { ChannelAdapter } from 'reeboot/channels';
151
+
152
+ export class TelegramAdapter implements ChannelAdapter {
153
+ // ...
154
+ }
155
+ ```
156
+
157
+ ### Community Packages
158
+
159
+ Install published packages that bundle tools, extensions, or channel adapters:
160
+
161
+ ```bash
162
+ reeboot install npm:reeboot-github-tools
163
+ reeboot install npm:reeboot-obsidian-tools
164
+ reeboot install git:github.com/you/my-reeboot-pack
165
+ reeboot install ./path/to/local-package
166
+ ```
167
+
168
+ List installed packages:
169
+
170
+ ```bash
171
+ reeboot packages list
172
+ ```
173
+
174
+ Uninstall:
175
+
176
+ ```bash
177
+ reeboot uninstall reeboot-github-tools
178
+ ```
179
+
180
+ **Publishing a community package** — add a `pi` manifest to your `package.json`:
181
+
182
+ ```json
183
+ {
184
+ "name": "reeboot-github-tools",
185
+ "pi": {
186
+ "extensions": ["./dist/github-extension.js"],
187
+ "skills": ["./skills/"]
188
+ }
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## WhatsApp Setup
195
+
196
+ 1. Enable WhatsApp in your config (`"whatsapp": { "enabled": true }`)
197
+ 2. Start the agent: `reeboot start`
198
+ 3. Run the channel login: `reeboot channel login whatsapp`
199
+ 4. A QR code appears in your terminal — scan it with WhatsApp (Settings → Linked Devices → Link a Device)
200
+ 5. The agent is now available in your WhatsApp DMs
201
+
202
+ ```
203
+ ┌─────────────────────────────────────┐
204
+ │ ██████░░██░░░░████░░███░░░██████ │
205
+ │ ██░░░░░░██░░░░██░░░░██░██░░██ │ ← Scan with WhatsApp
206
+ │ ██░░░░░░████░░████░░█████░░██ │
207
+ │ ██░░░░░░██░░░░██░░░░██░██░░██ │
208
+ │ ██████░░██░░░░████░░███░░░██████ │
209
+ └─────────────────────────────────────┘
210
+ ```
211
+
212
+ The session persists across restarts (credentials saved in `~/.reeboot/credentials/`).
213
+
214
+ ---
215
+
216
+ ## Signal Setup
217
+
218
+ Signal requires the [`bbernhard/signal-cli-rest-api`](https://github.com/bbernhard/signal-cli-rest-api) Docker container.
219
+
220
+ **Step 1 — Link your Signal account**
221
+
222
+ ```bash
223
+ docker run -p 8080:8080 \
224
+ -v ~/.reeboot/signal-data:/home/user/.local/share/signal-cli \
225
+ -e MODE=native \
226
+ bbernhard/signal-cli-rest-api:latest
227
+ ```
228
+
229
+ Then open `http://localhost:8080/v1/qrcodelink?device_name=reeboot` in your browser and scan the QR with Signal (Settings → Linked Devices → Link new device).
230
+
231
+ **Step 2 — Run in json-rpc mode (recommended)**
232
+
233
+ ```bash
234
+ docker run -p 8080:8080 \
235
+ -v ~/.reeboot/signal-data:/home/user/.local/share/signal-cli \
236
+ -e MODE=json-rpc \
237
+ bbernhard/signal-cli-rest-api:latest
238
+ ```
239
+
240
+ **Step 3 — Enable in reeboot config**
241
+
242
+ ```json
243
+ "signal": {
244
+ "enabled": true,
245
+ "phoneNumber": "+15551234567",
246
+ "apiUrl": "http://localhost:8080"
247
+ }
248
+ ```
249
+
250
+ Then: `reeboot start`
251
+
252
+ ---
253
+
254
+ ## CLI Reference
255
+
256
+ ```
257
+ reeboot [command] [options]
258
+
259
+ Commands:
260
+ start Start the agent server
261
+ stop Stop the running daemon
262
+ setup Interactive setup wizard
263
+ status Show agent and channel status
264
+ doctor Run pre-flight diagnostics
265
+ reload Hot-reload extensions and skills
266
+ restart Gracefully restart the agent
267
+
268
+ install <pkg> Install a pi-compatible package
269
+ uninstall <name> Uninstall a package
270
+
271
+ packages list List installed packages
272
+
273
+ channel list List channels and their status
274
+ channel login <ch> Authenticate a channel (whatsapp, signal)
275
+ channel logout <ch> Disconnect a channel
276
+
277
+ Options:
278
+ start:
279
+ --daemon Run as background service (launchd/systemd)
280
+ --no-interactive Skip prompts (use with --provider etc.)
281
+ --provider <name> LLM provider
282
+ --api-key <key> API key
283
+ --model <id> Model ID
284
+ --channels <list> Comma-separated channel list
285
+ --name <name> Agent name
286
+
287
+ setup:
288
+ --no-interactive Non-interactive (use with flags below)
289
+ --provider, --api-key, --model, --channels, --name
290
+
291
+ doctor:
292
+ --skip-network Skip network checks (API key validation, Signal version)
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Docker
298
+
299
+ Run reeboot as a container, mounting your config from the host:
300
+
301
+ ```bash
302
+ docker run -d \
303
+ -v ~/.reeboot:/home/reeboot/.reeboot \
304
+ -p 3000:3000 \
305
+ --name reeboot \
306
+ reeboot/reeboot:latest
307
+ ```
308
+
309
+ Health check:
310
+
311
+ ```bash
312
+ curl http://localhost:3000/api/health
313
+ # {"status":"ok","uptime":42,"version":"1.0.0"}
314
+ ```
315
+
316
+ WebChat is available at `http://localhost:3000`.
317
+
318
+ **Docker Compose example:**
319
+
320
+ ```yaml
321
+ services:
322
+ reeboot:
323
+ image: reeboot/reeboot:latest
324
+ ports:
325
+ - "3000:3000"
326
+ volumes:
327
+ - ~/.reeboot:/home/reeboot/.reeboot
328
+ restart: unless-stopped
329
+ ```
330
+
331
+ ---
332
+
333
+ ## CI/CD Secrets
334
+
335
+ To use the GitHub Actions publish pipeline, add these repository secrets:
336
+
337
+ | Secret | Description |
338
+ |---|---|
339
+ | `NPM_TOKEN` | npm automation token (`npm token create --type=automation`) |
340
+ | `DOCKERHUB_TOKEN` | Docker Hub access token (Hub → Account Settings → Security) |
341
+
342
+ The workflow automatically publishes to npm and pushes Docker images when you push a `v*` tag:
343
+
344
+ ```bash
345
+ git tag v1.0.0
346
+ git push origin v1.0.0
347
+ ```
348
+
349
+ ---
350
+
351
+ ## License
352
+
353
+ MIT
354
+
355
+ ---
356
+
357
+ ## Links
358
+
359
+ - [npm package](https://www.npmjs.com/package/reeboot)
360
+ - [Docker Hub](https://hub.docker.com/r/reeboot/reeboot)
361
+ - [Architecture decisions](../architecture-decisions.md)
@@ -0,0 +1,48 @@
1
+ # ── Stage 1: builder ─────────────────────────────────────────────────────────
2
+ FROM node:22-slim AS builder
3
+
4
+ WORKDIR /app
5
+
6
+ # Install dependencies first (better layer caching)
7
+ COPY package*.json ./
8
+ RUN npm ci
9
+
10
+ # Copy source and build
11
+ COPY . .
12
+ RUN npm run build
13
+
14
+ # ── Stage 2: runtime ─────────────────────────────────────────────────────────
15
+ FROM node:22-slim
16
+
17
+ # Create non-root user (uid 1000) — rename existing node user if uid 1000 is taken
18
+ RUN if id -u 1000 >/dev/null 2>&1; then \
19
+ usermod -l reeboot -d /home/reeboot -m $(getent passwd 1000 | cut -d: -f1); \
20
+ else \
21
+ useradd -m -u 1000 -s /bin/bash reeboot; \
22
+ fi
23
+
24
+ USER reeboot
25
+ WORKDIR /home/reeboot
26
+
27
+ # Copy built output and runtime assets from builder
28
+ COPY --from=builder --chown=reeboot:reeboot /app/dist ./dist
29
+ COPY --from=builder --chown=reeboot:reeboot /app/extensions ./extensions
30
+ COPY --from=builder --chown=reeboot:reeboot /app/skills ./skills
31
+ COPY --from=builder --chown=reeboot:reeboot /app/templates ./templates
32
+ COPY --from=builder --chown=reeboot:reeboot /app/container ./container
33
+ COPY --from=builder --chown=reeboot:reeboot /app/webchat ./webchat
34
+ COPY --from=builder --chown=reeboot:reeboot /app/package.json ./package.json
35
+ COPY --from=builder --chown=reeboot:reeboot /app/package-lock.json ./package-lock.json
36
+
37
+ # Install production dependencies only
38
+ RUN npm ci --omit=dev
39
+
40
+ # Make entrypoint executable
41
+ RUN chmod +x ./container/entrypoint.sh
42
+
43
+ # Config and data directory (mount from host: -v ~/.reeboot:/home/reeboot/.reeboot)
44
+ VOLUME ["/home/reeboot/.reeboot"]
45
+
46
+ EXPOSE 3000
47
+
48
+ ENTRYPOINT ["./container/entrypoint.sh"]
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+ # reeboot container entrypoint
3
+ # Starts the agent in non-interactive mode (no TTY in container).
4
+ # Binds to 0.0.0.0 so the port is reachable from outside the container.
5
+ set -e
6
+
7
+ export REEBOOT_HOST="${REEBOOT_HOST:-0.0.0.0}"
8
+ exec node dist/index.js start --no-interactive "$@"
@@ -0,0 +1,9 @@
1
+ import type { Config } from '../config.js';
2
+ import type { AgentRunner, ContextConfig } from './interface.js';
3
+ export type { AgentRunner, AgentRunnerFactory, ContextConfig, RunnerEvent } from './interface.js';
4
+ /**
5
+ * Factory function: reads config.agent.runner and returns the appropriate AgentRunner.
6
+ * Phase 1 only supports "pi". Unknown values throw a descriptive error.
7
+ */
8
+ export declare function createRunner(context: ContextConfig, config: Config): AgentRunner;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMjE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElG;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAahF"}
@@ -0,0 +1,21 @@
1
+ import { PiAgentRunner } from './pi-runner.js';
2
+ import { DefaultResourceLoader } from '@mariozechner/pi-coding-agent';
3
+ import { homedir } from 'os';
4
+ import { join } from 'path';
5
+ /**
6
+ * Factory function: reads config.agent.runner and returns the appropriate AgentRunner.
7
+ * Phase 1 only supports "pi". Unknown values throw a descriptive error.
8
+ */
9
+ export function createRunner(context, config) {
10
+ const runnerType = config.agent.runner ?? 'pi';
11
+ if (runnerType === 'pi') {
12
+ const agentDir = join(homedir(), '.reeboot');
13
+ const loader = new DefaultResourceLoader({
14
+ cwd: context.workspacePath,
15
+ agentDir,
16
+ });
17
+ return new PiAgentRunner(context, loader);
18
+ }
19
+ throw new Error(`Unknown agent runner: ${runnerType}`);
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-runner/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB,EAAE,MAAc;IACjE,MAAM,UAAU,GAAI,MAAM,CAAC,KAAa,CAAC,MAAM,IAAI,IAAI,CAAC;IAExD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,qBAAqB,CAAC;YACvC,GAAG,EAAE,OAAO,CAAC,aAAa;YAC1B,QAAQ;SACT,CAAC,CAAC;QACH,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,56 @@
1
+ export type RunnerEvent = {
2
+ type: 'text_delta';
3
+ delta: string;
4
+ } | {
5
+ type: 'tool_call_start';
6
+ toolCallId: string;
7
+ toolName: string;
8
+ args: unknown;
9
+ } | {
10
+ type: 'tool_call_end';
11
+ toolCallId: string;
12
+ toolName: string;
13
+ result: unknown;
14
+ isError: boolean;
15
+ } | {
16
+ type: 'message_end';
17
+ runId: string;
18
+ usage: {
19
+ input: number;
20
+ output: number;
21
+ };
22
+ } | {
23
+ type: 'error';
24
+ message: string;
25
+ };
26
+ export interface AgentRunner {
27
+ /**
28
+ * Send a user message to the agent. Calls onEvent for each RunnerEvent as
29
+ * they arrive. Resolves when the turn completes (message_end received).
30
+ */
31
+ prompt(content: string, onEvent: (event: RunnerEvent) => void): Promise<void>;
32
+ /**
33
+ * Abort any in-flight prompt. No-op if no prompt is active.
34
+ */
35
+ abort(): void;
36
+ /**
37
+ * Dispose the runner and release underlying resources.
38
+ * Idempotent — safe to call multiple times.
39
+ */
40
+ dispose(): Promise<void>;
41
+ /**
42
+ * Hot-reload extensions/skills without restarting the process.
43
+ * Calls loader.reload() on the underlying DefaultResourceLoader.
44
+ */
45
+ reload(): Promise<void>;
46
+ }
47
+ export interface ContextConfig {
48
+ /** Unique context identifier (e.g., "main") */
49
+ id: string;
50
+ /** Workspace directory for this context (cwd for pi session) */
51
+ workspacePath: string;
52
+ }
53
+ export interface AgentRunnerFactory {
54
+ create(context: ContextConfig, config: import('../config.js').Config): AgentRunner;
55
+ }
56
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/agent-runner/interface.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAClG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAIvC,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;OAGG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAID,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,GAAG,WAAW,CAAC;CACpF"}
@@ -0,0 +1,5 @@
1
+ // ─── RunnerEvent ─────────────────────────────────────────────────────────────
2
+ // Discriminated union of events forwarded from the pi AgentSession to callers.
3
+ // These intentionally use simple field names independent of pi SDK internals.
4
+ export {};
5
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/agent-runner/interface.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * PiAgentRunner — wraps the pi SDK AgentSession.
3
+ *
4
+ * Pi SDK event mapping (verified against @mariozechner/pi-agent-core types.d.ts):
5
+ *
6
+ * pi event → RunnerEvent
7
+ * ─────────────────────────────────────────────────────────────────────
8
+ * message_update → text_delta
9
+ * .assistantMessageEvent.type === "text_delta"
10
+ * .assistantMessageEvent.delta (the text string)
11
+ *
12
+ * tool_execution_start → tool_call_start
13
+ * .toolCallId, .toolName, .args
14
+ *
15
+ * tool_execution_end → tool_call_end
16
+ * .toolCallId, .toolName, .result, .isError
17
+ *
18
+ * agent_end → message_end
19
+ * (usage is retrieved from session stats — pi does not put it on agent_end directly)
20
+ *
21
+ * All other pi events are silently ignored.
22
+ *
23
+ * agentDir: ~/.reeboot/ (global extensions/skills)
24
+ * cwd: context.workspacePath (project-local discovery)
25
+ */
26
+ import type { AgentRunner, ContextConfig, RunnerEvent } from './interface.js';
27
+ import type { ResourceLoader } from '@mariozechner/pi-coding-agent';
28
+ export declare class PiAgentRunner implements AgentRunner {
29
+ private readonly context;
30
+ private readonly loader;
31
+ private abortController;
32
+ private disposed;
33
+ private _session;
34
+ constructor(context: ContextConfig, loader: ResourceLoader);
35
+ prompt(content: string, onEvent: (event: RunnerEvent) => void): Promise<void>;
36
+ abort(): void;
37
+ dispose(): Promise<void>;
38
+ reload(): Promise<void>;
39
+ private _getOrCreateSession;
40
+ }
41
+ //# sourceMappingURL=pi-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-runner.d.ts","sourceRoot":"","sources":["../../src/agent-runner/pi-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,qBAAa,aAAc,YAAW,WAAW;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,QAAQ,CAAqE;gBAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc;IAOpD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAmFnF,KAAK,IAAI,IAAI;IAiBP,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YAMf,mBAAmB;CAclC"}