@openacp/cli 0.2.18 → 0.2.22
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 +49 -213
- package/dist/{chunk-3UGSZYSQ.js → chunk-XOVJLTEC.js} +27 -3
- package/dist/chunk-XOVJLTEC.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +1 -1
- package/dist/{main-4H43GCXO.js → main-GC6JY7DS.js} +4 -4
- package/dist/{setup-FB4DGR6R.js → setup-XQBEZZQB.js} +2 -2
- package/dist/{setup-FB4DGR6R.js.map → setup-XQBEZZQB.js.map} +1 -1
- package/dist/{tunnel-service-FPRPBPQ5.js → tunnel-service-I6NUMBT4.js} +263 -15
- package/dist/tunnel-service-I6NUMBT4.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3UGSZYSQ.js.map +0 -1
- package/dist/tunnel-service-FPRPBPQ5.js.map +0 -1
- /package/dist/{main-4H43GCXO.js.map → main-GC6JY7DS.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,82 +1,58 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# OpenACP
|
|
2
4
|
|
|
3
|
-
Self-hosted bridge
|
|
5
|
+
**Self-hosted bridge between messaging platforms and AI coding agents**
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
One message, any channel, any agent.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
[](https://agentclientprotocol.org/)
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
You (Telegram / Discord / ...)
|
|
11
|
-
│
|
|
12
|
-
▼
|
|
13
|
-
OpenACP (ChannelAdapter)
|
|
14
|
-
│
|
|
15
|
-
▼
|
|
16
|
-
ACP Protocol (JSON-RPC over stdio)
|
|
17
|
-
│
|
|
18
|
-
▼
|
|
19
|
-
AI Agent subprocess (Claude Code, Codex, ...)
|
|
20
|
-
```
|
|
13
|
+
[Getting Started](docs/guide/getting-started.md) | [Usage](docs/guide/usage.md) | [Configuration](docs/guide/configuration.md) | [Tunnel](docs/guide/tunnel.md) | [Plugins](docs/guide/plugins.md) | [Development](docs/guide/development.md)
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
</div>
|
|
23
16
|
|
|
24
|
-
|
|
17
|
+
---
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
- **Telegram integration** — Forum topics per session, real-time streaming, inline permission buttons
|
|
28
|
-
- **Session management** — Multiple parallel sessions, prompt queue, auto-naming
|
|
29
|
-
- **Assistant topic** — AI-powered help bot that guides you through creating sessions
|
|
30
|
-
- **Notification topic** — Aggregated notifications with deep links
|
|
31
|
-
- **Workspace management** — Named workspaces or custom paths
|
|
32
|
-
- **Self-hosted** — Your keys, your data, your machine
|
|
33
|
-
|
|
34
|
-
## Quick Start
|
|
19
|
+
Send a message in Telegram. An AI coding agent picks it up, writes code, runs commands, and streams everything back — in real time.
|
|
35
20
|
|
|
36
|
-
|
|
21
|
+
OpenACP connects messaging platforms (Telegram, Discord, ...) to AI coding agents (Claude Code, Codex, ...) via the [Agent Client Protocol (ACP)](https://agentclientprotocol.org/). You host it, you own the data.
|
|
37
22
|
|
|
38
|
-
|
|
39
|
-
- pnpm
|
|
40
|
-
- A Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
41
|
-
- A Telegram Supergroup with **Forum/Topics enabled**
|
|
42
|
-
- At least one ACP agent installed (e.g., `claude-agent-acp`)
|
|
23
|
+
## Architecture
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
25
|
+
```
|
|
26
|
+
You (Telegram / Discord / ...)
|
|
27
|
+
↓
|
|
28
|
+
OpenACP ─── ChannelAdapter ─── Session Manager ─── Session Store
|
|
29
|
+
↓ ↓
|
|
30
|
+
ACP Protocol (JSON-RPC / stdio) Tunnel Service
|
|
31
|
+
↓ ↓
|
|
32
|
+
AI Agent (Claude Code, Codex, ...) File/Diff Viewer (Monaco)
|
|
49
33
|
```
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
## Highlights
|
|
52
36
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
37
|
+
- [**Multi-agent**](docs/guide/configuration.md#agents) — Claude Code, Codex, or any ACP-compatible agent
|
|
38
|
+
- [**Telegram**](docs/guide/telegram-setup.md) — Forum topics, real-time streaming, permission buttons, skill commands
|
|
39
|
+
- [**Tunnel & Viewer**](docs/guide/tunnel.md) — Public file/diff viewer via Cloudflare, ngrok, bore, Tailscale
|
|
40
|
+
- [**Session persistence**](docs/guide/usage.md#session-persistence--resume) — Lazy resume across restarts
|
|
41
|
+
- [**Setup wizard**](docs/guide/getting-started.md) — Interactive first-run setup with bot validation and auto-detect
|
|
42
|
+
- [**Plugin system**](docs/guide/plugins.md) — Install channel adapters as npm packages
|
|
43
|
+
- [**Structured logging**](docs/guide/configuration.md#logging) — Pino with rotation, per-session log files
|
|
44
|
+
- **Self-hosted** — Your keys, your data, your machine
|
|
57
45
|
|
|
58
|
-
|
|
46
|
+
## Quick Start
|
|
59
47
|
|
|
60
48
|
```bash
|
|
49
|
+
npm install -g @openacp/cli
|
|
61
50
|
openacp
|
|
62
51
|
```
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
1. **Telegram** — bot token + chat ID (validated against Telegram API)
|
|
67
|
-
2. **Agents** — auto-detects installed agents, select which to enable
|
|
68
|
-
3. **Workspace** — base directory for project workspaces
|
|
69
|
-
4. **Security** — allowed users, session limits, timeout
|
|
70
|
-
|
|
71
|
-
Config is saved to `~/.openacp/config.json`. See [docs/setup-guide.md](docs/setup-guide.md) for details.
|
|
72
|
-
|
|
73
|
-
OpenACP will auto-create two topics in your group:
|
|
74
|
-
- Notifications — aggregated alerts with deep links
|
|
75
|
-
- Assistant — AI helper for managing sessions
|
|
53
|
+
First run launches an [interactive setup wizard](docs/guide/getting-started.md) that validates your bot token, auto-detects your Telegram group, and finds installed agents.
|
|
76
54
|
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
### Commands
|
|
55
|
+
## Commands
|
|
80
56
|
|
|
81
57
|
| Command | Description |
|
|
82
58
|
|---------|-------------|
|
|
@@ -85,169 +61,29 @@ OpenACP will auto-create two topics in your group:
|
|
|
85
61
|
| `/cancel` | Cancel current session |
|
|
86
62
|
| `/status` | Show session or system status |
|
|
87
63
|
| `/agents` | List available agents |
|
|
88
|
-
| `/help` | Show help |
|
|
89
|
-
|
|
90
|
-
### Examples
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
/new claude my-app → New session with Claude in ~/openacp-workspace/my-app/
|
|
94
|
-
/new codex api-server → New session with Codex in ~/openacp-workspace/api-server/
|
|
95
|
-
/new claude ~/code/project → New session with absolute path
|
|
96
|
-
/new → New session with default agent and workspace
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Session Flow
|
|
100
|
-
|
|
101
|
-
1. Type `/new claude my-project` — bot creates a new topic
|
|
102
|
-
2. Send your coding request in the topic
|
|
103
|
-
3. Agent responds with streaming text, tool calls, and code
|
|
104
|
-
4. When agent needs permission (run command, edit file) → inline buttons appear
|
|
105
|
-
5. Click Allow/Deny → agent continues
|
|
106
|
-
6. `/cancel` to stop, or start a new topic with `/new`
|
|
107
|
-
|
|
108
|
-
## Configuration
|
|
109
|
-
|
|
110
|
-
Config file: `~/.openacp/config.json`
|
|
111
|
-
|
|
112
|
-
```json
|
|
113
|
-
{
|
|
114
|
-
"channels": {
|
|
115
|
-
"telegram": {
|
|
116
|
-
"enabled": true,
|
|
117
|
-
"botToken": "...",
|
|
118
|
-
"chatId": -1001234567890,
|
|
119
|
-
"notificationTopicId": null,
|
|
120
|
-
"assistantTopicId": null
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
"agents": {
|
|
124
|
-
"claude": {
|
|
125
|
-
"command": "claude-agent-acp",
|
|
126
|
-
"args": [],
|
|
127
|
-
"env": {}
|
|
128
|
-
},
|
|
129
|
-
"codex": {
|
|
130
|
-
"command": "codex",
|
|
131
|
-
"args": ["--acp"],
|
|
132
|
-
"env": {}
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
"defaultAgent": "claude",
|
|
136
|
-
"workspace": {
|
|
137
|
-
"baseDir": "~/openacp-workspace"
|
|
138
|
-
},
|
|
139
|
-
"security": {
|
|
140
|
-
"allowedUserIds": [],
|
|
141
|
-
"maxConcurrentSessions": 5,
|
|
142
|
-
"sessionTimeoutMinutes": 60
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Environment Variables
|
|
148
|
-
|
|
149
|
-
| Variable | Overrides |
|
|
150
|
-
|----------|-----------|
|
|
151
|
-
| `OPENACP_CONFIG_PATH` | Config file location |
|
|
152
|
-
| `OPENACP_TELEGRAM_BOT_TOKEN` | `channels.telegram.botToken` |
|
|
153
|
-
| `OPENACP_TELEGRAM_CHAT_ID` | `channels.telegram.chatId` |
|
|
154
|
-
| `OPENACP_DEFAULT_AGENT` | `defaultAgent` |
|
|
155
|
-
| `OPENACP_DEBUG` | Enable debug logging (set to `1`) |
|
|
156
|
-
|
|
157
|
-
## Plugins
|
|
158
|
-
|
|
159
|
-
Install additional adapters:
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
openacp install @openacp/adapter-discord
|
|
163
|
-
openacp plugins # list installed
|
|
164
|
-
openacp uninstall @openacp/adapter-discord # remove
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Configure in `~/.openacp/config.json`:
|
|
168
|
-
|
|
169
|
-
```json
|
|
170
|
-
{
|
|
171
|
-
"channels": {
|
|
172
|
-
"discord": {
|
|
173
|
-
"enabled": true,
|
|
174
|
-
"adapter": "@openacp/adapter-discord",
|
|
175
|
-
"botToken": "..."
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Project Structure
|
|
182
|
-
|
|
183
|
-
```
|
|
184
|
-
src/
|
|
185
|
-
cli.ts → CLI entry point
|
|
186
|
-
main.ts → Server startup
|
|
187
|
-
index.ts → Public API exports
|
|
188
|
-
core/
|
|
189
|
-
core.ts → OpenACPCore orchestrator
|
|
190
|
-
config.ts → ConfigManager + Zod validation
|
|
191
|
-
setup.ts → Interactive setup wizard
|
|
192
|
-
session.ts → Session (prompt queue, auto-name)
|
|
193
|
-
agent-instance.ts → ACP SDK integration
|
|
194
|
-
channel.ts → ChannelAdapter abstract class
|
|
195
|
-
plugin-manager.ts → Plugin install/uninstall/load
|
|
196
|
-
types.ts → Shared types
|
|
197
|
-
adapters/
|
|
198
|
-
telegram/
|
|
199
|
-
adapter.ts → TelegramAdapter
|
|
200
|
-
streaming.ts → Real-time message streaming
|
|
201
|
-
commands.ts → Bot commands
|
|
202
|
-
permissions.ts → Permission inline buttons
|
|
203
|
-
assistant.ts → AI assistant topic
|
|
204
|
-
formatting.ts → Markdown → Telegram HTML
|
|
205
|
-
topics.ts → Forum topic management
|
|
206
|
-
```
|
|
207
64
|
|
|
208
65
|
## Roadmap
|
|
209
66
|
|
|
210
|
-
- **Phase 1**
|
|
211
|
-
- **Phase 2** —
|
|
212
|
-
- **Phase 3** — Agent skills as commands,
|
|
213
|
-
- **Phase 4** — Voice control, file sharing
|
|
67
|
+
- **Phase 1** — Core + Telegram + ACP agents
|
|
68
|
+
- **Phase 2** — Tunnel/file viewer, session persistence, logging, plugin system
|
|
69
|
+
- **Phase 3** — Agent skills as commands, Discord adapter, Web UI
|
|
70
|
+
- **Phase 4** — Voice control, file/image sharing
|
|
214
71
|
- **Phase 5** — WhatsApp, agent chaining, plugin marketplace
|
|
215
72
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
## Adding a Channel Adapter
|
|
219
|
-
|
|
220
|
-
Extend `ChannelAdapter` from `@openacp/cli`:
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
import { ChannelAdapter } from '@openacp/cli'
|
|
224
|
-
|
|
225
|
-
class MyAdapter extends ChannelAdapter {
|
|
226
|
-
async start() { /* connect to platform */ }
|
|
227
|
-
async stop() { /* disconnect */ }
|
|
228
|
-
async sendMessage(sessionId, content) { /* send to user */ }
|
|
229
|
-
async sendPermissionRequest(sessionId, request) { /* show buttons */ }
|
|
230
|
-
async sendNotification(notification) { /* notify user */ }
|
|
231
|
-
async createSessionThread(sessionId, name) { /* create thread */ }
|
|
232
|
-
async renameSessionThread(sessionId, name) { /* rename thread */ }
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
## Development
|
|
73
|
+
## Star History
|
|
237
74
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
75
|
+
<a href="https://star-history.com/#Open-ACP/OpenACP&Date">
|
|
76
|
+
<picture>
|
|
77
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Open-ACP/OpenACP&type=Date&theme=dark" />
|
|
78
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Open-ACP/OpenACP&type=Date" />
|
|
79
|
+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Open-ACP/OpenACP&type=Date" />
|
|
80
|
+
</picture>
|
|
81
|
+
</a>
|
|
244
82
|
|
|
245
|
-
|
|
83
|
+
## Contributing
|
|
246
84
|
|
|
247
|
-
|
|
248
|
-
pnpm start
|
|
249
|
-
```
|
|
85
|
+
See [development guide](docs/guide/development.md).
|
|
250
86
|
|
|
251
87
|
## License
|
|
252
88
|
|
|
253
|
-
AGPL-3.0
|
|
89
|
+
[AGPL-3.0](LICENSE)
|
|
@@ -34,7 +34,7 @@ var TunnelAuthSchema = z.object({
|
|
|
34
34
|
var TunnelSchema = z.object({
|
|
35
35
|
enabled: z.boolean().default(false),
|
|
36
36
|
port: z.number().default(3100),
|
|
37
|
-
provider: z.enum(["cloudflare", "ngrok", "bore"]).default("cloudflare"),
|
|
37
|
+
provider: z.enum(["cloudflare", "ngrok", "bore", "tailscale"]).default("cloudflare"),
|
|
38
38
|
options: z.record(z.string(), z.unknown()).default({}),
|
|
39
39
|
storeTtlMinutes: z.number().default(60),
|
|
40
40
|
auth: TunnelAuthSchema
|
|
@@ -84,7 +84,15 @@ var DEFAULT_CONFIG = {
|
|
|
84
84
|
maxConcurrentSessions: 5,
|
|
85
85
|
sessionTimeoutMinutes: 60
|
|
86
86
|
},
|
|
87
|
-
sessionStore: { ttlDays: 30 }
|
|
87
|
+
sessionStore: { ttlDays: 30 },
|
|
88
|
+
tunnel: {
|
|
89
|
+
enabled: true,
|
|
90
|
+
port: 3100,
|
|
91
|
+
provider: "cloudflare",
|
|
92
|
+
options: {},
|
|
93
|
+
storeTtlMinutes: 60,
|
|
94
|
+
auth: { enabled: false }
|
|
95
|
+
}
|
|
88
96
|
};
|
|
89
97
|
var ConfigManager = class {
|
|
90
98
|
config;
|
|
@@ -107,6 +115,22 @@ var ConfigManager = class {
|
|
|
107
115
|
process.exit(1);
|
|
108
116
|
}
|
|
109
117
|
const raw = JSON.parse(fs.readFileSync(this.configPath, "utf-8"));
|
|
118
|
+
let configUpdated = false;
|
|
119
|
+
if (!raw.tunnel) {
|
|
120
|
+
raw.tunnel = {
|
|
121
|
+
enabled: true,
|
|
122
|
+
port: 3100,
|
|
123
|
+
provider: "cloudflare",
|
|
124
|
+
options: {},
|
|
125
|
+
storeTtlMinutes: 60,
|
|
126
|
+
auth: { enabled: false }
|
|
127
|
+
};
|
|
128
|
+
configUpdated = true;
|
|
129
|
+
log.info("Added tunnel section to config (enabled by default with cloudflare)");
|
|
130
|
+
}
|
|
131
|
+
if (configUpdated) {
|
|
132
|
+
fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
|
|
133
|
+
}
|
|
110
134
|
this.applyEnvOverrides(raw);
|
|
111
135
|
const result = ConfigSchema.safeParse(raw);
|
|
112
136
|
if (!result.success) {
|
|
@@ -275,4 +299,4 @@ export {
|
|
|
275
299
|
listPlugins,
|
|
276
300
|
loadAdapterFactory
|
|
277
301
|
};
|
|
278
|
-
//# sourceMappingURL=chunk-
|
|
302
|
+
//# sourceMappingURL=chunk-XOVJLTEC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/config.ts","../../src/core/plugin-manager.ts"],"sourcesContent":["import { z } from \"zod\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { createChildLogger } from \"./log.js\";\nconst log = createChildLogger({ module: \"config\" });\n\nconst BaseChannelSchema = z\n .object({\n enabled: z.boolean().default(false),\n adapter: z.string().optional(), // package name for plugin adapters\n })\n .passthrough();\n\nexport const PLUGINS_DIR = path.join(os.homedir(), \".openacp\", \"plugins\");\n\nconst AgentSchema = z.object({\n command: z.string(),\n args: z.array(z.string()).default([]),\n workingDirectory: z.string().optional(),\n env: z.record(z.string(), z.string()).default({}),\n});\n\nconst LoggingSchema = z\n .object({\n level: z\n .enum([\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"])\n .default(\"info\"),\n logDir: z.string().default(\"~/.openacp/logs\"),\n maxFileSize: z.union([z.string(), z.number()]).default(\"10m\"),\n maxFiles: z.number().default(7),\n sessionLogRetentionDays: z.number().default(30),\n })\n .default({});\n\nexport type LoggingConfig = z.infer<typeof LoggingSchema>;\n\nconst TunnelAuthSchema = z\n .object({\n enabled: z.boolean().default(false),\n token: z.string().optional(),\n })\n .default({});\n\nconst TunnelSchema = z\n .object({\n enabled: z.boolean().default(false),\n port: z.number().default(3100),\n provider: z.enum([\"cloudflare\", \"ngrok\", \"bore\", \"tailscale\"]).default(\"cloudflare\"),\n options: z.record(z.string(), z.unknown()).default({}),\n storeTtlMinutes: z.number().default(60),\n auth: TunnelAuthSchema,\n })\n .default({});\n\nexport type TunnelConfig = z.infer<typeof TunnelSchema>;\n\nexport const ConfigSchema = z.object({\n channels: z.record(z.string(), BaseChannelSchema),\n agents: z.record(z.string(), AgentSchema),\n defaultAgent: z.string(),\n workspace: z\n .object({\n baseDir: z.string().default(\"~/openacp-workspace\"),\n })\n .default({}),\n security: z\n .object({\n allowedUserIds: z.array(z.string()).default([]),\n maxConcurrentSessions: z.number().default(5),\n sessionTimeoutMinutes: z.number().default(60),\n })\n .default({}),\n logging: LoggingSchema,\n sessionStore: z\n .object({\n ttlDays: z.number().default(30),\n })\n .default({}),\n tunnel: TunnelSchema,\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function expandHome(p: string): string {\n if (p.startsWith(\"~\")) {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n}\n\nconst DEFAULT_CONFIG = {\n channels: {\n telegram: {\n enabled: false,\n botToken: \"YOUR_BOT_TOKEN_HERE\",\n chatId: 0,\n notificationTopicId: null,\n assistantTopicId: null,\n },\n },\n agents: {\n claude: { command: \"claude-agent-acp\", args: [], env: {} },\n codex: { command: \"codex\", args: [\"--acp\"], env: {} },\n },\n defaultAgent: \"claude\",\n workspace: { baseDir: \"~/openacp-workspace\" },\n security: {\n allowedUserIds: [],\n maxConcurrentSessions: 5,\n sessionTimeoutMinutes: 60,\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n};\n\nexport class ConfigManager {\n private config!: Config;\n private configPath: string;\n\n constructor() {\n this.configPath =\n process.env.OPENACP_CONFIG_PATH || expandHome(\"~/.openacp/config.json\");\n }\n\n async load(): Promise<void> {\n // 1. Ensure directory exists\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n\n // 2. If config file doesn't exist, create default\n if (!fs.existsSync(this.configPath)) {\n fs.writeFileSync(\n this.configPath,\n JSON.stringify(DEFAULT_CONFIG, null, 2),\n );\n log.info({ configPath: this.configPath }, \"Config created\");\n log.info(\n \"Please edit it with your Telegram bot token and chat ID, then restart.\",\n );\n process.exit(1);\n }\n\n // 3. Read and parse\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n\n // 3.5. Auto-migrate: add missing sections with defaults\n let configUpdated = false;\n if (!raw.tunnel) {\n raw.tunnel = {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n };\n configUpdated = true;\n log.info(\"Added tunnel section to config (enabled by default with cloudflare)\");\n }\n if (configUpdated) {\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n }\n\n // 4. Apply env var overrides\n this.applyEnvOverrides(raw);\n\n // 5. Validate with Zod\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n log.error(\"Config validation failed\");\n for (const issue of result.error.issues) {\n log.error(\n { path: issue.path.join(\".\"), message: issue.message },\n \"Validation error\",\n );\n }\n process.exit(1);\n }\n this.config = result.data;\n }\n\n get(): Config {\n return this.config;\n }\n\n async save(updates: Record<string, unknown>): Promise<void> {\n // Read current file, merge updates, write back\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n this.deepMerge(raw, updates);\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n // Re-validate and update in-memory config\n const result = ConfigSchema.safeParse(raw);\n if (result.success) {\n this.config = result.data;\n }\n }\n\n resolveWorkspace(input?: string): string {\n if (!input) {\n const resolved = expandHome(this.config.workspace.baseDir);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n if (input.startsWith(\"/\") || input.startsWith(\"~\")) {\n const resolved = expandHome(input);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n // Named workspace → lowercase, under baseDir\n const name = input.toLowerCase();\n const resolved = path.join(expandHome(this.config.workspace.baseDir), name);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n\n async exists(): Promise<boolean> {\n return fs.existsSync(this.configPath);\n }\n\n getConfigPath(): string {\n return this.configPath;\n }\n\n async writeNew(config: Config): Promise<void> {\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2));\n }\n\n private applyEnvOverrides(raw: Record<string, unknown>): void {\n const overrides: [string, string[]][] = [\n [\"OPENACP_TELEGRAM_BOT_TOKEN\", [\"channels\", \"telegram\", \"botToken\"]],\n [\"OPENACP_TELEGRAM_CHAT_ID\", [\"channels\", \"telegram\", \"chatId\"]],\n [\"OPENACP_DEFAULT_AGENT\", [\"defaultAgent\"]],\n ];\n for (const [envVar, configPath] of overrides) {\n const value = process.env[envVar];\n if (value !== undefined) {\n let target = raw as Record<string, any>;\n for (let i = 0; i < configPath.length - 1; i++) {\n if (!target[configPath[i]]) target[configPath[i]] = {};\n target = target[configPath[i]];\n }\n const key = configPath[configPath.length - 1];\n // Convert chatId to number\n target[key] = key === \"chatId\" ? Number(value) : value;\n }\n }\n\n // Logging env var overrides\n if (process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level =\n process.env.OPENACP_LOG_LEVEL;\n }\n if (process.env.OPENACP_LOG_DIR) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).logDir =\n process.env.OPENACP_LOG_DIR;\n }\n if (process.env.OPENACP_DEBUG && !process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level = \"debug\";\n }\n\n // Tunnel env var overrides\n if (process.env.OPENACP_TUNNEL_ENABLED) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).enabled =\n process.env.OPENACP_TUNNEL_ENABLED === \"true\";\n }\n if (process.env.OPENACP_TUNNEL_PORT) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).port = Number(\n process.env.OPENACP_TUNNEL_PORT,\n );\n }\n if (process.env.OPENACP_TUNNEL_PROVIDER) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).provider =\n process.env.OPENACP_TUNNEL_PROVIDER;\n }\n }\n\n private deepMerge(\n target: Record<string, any>,\n source: Record<string, any>,\n ): void {\n for (const key of Object.keys(source)) {\n if (\n source[key] &&\n typeof source[key] === \"object\" &&\n !Array.isArray(source[key])\n ) {\n if (!target[key]) target[key] = {};\n this.deepMerge(target[key], source[key]);\n } else {\n target[key] = source[key];\n }\n }\n }\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { PLUGINS_DIR } from './config.js'\nimport { createChildLogger } from './log.js'\nconst log = createChildLogger({ module: 'plugin-manager' })\nimport type { ChannelAdapter } from './channel.js'\n\nexport interface AdapterFactory {\n name: string\n createAdapter(core: any, config: any): ChannelAdapter\n}\n\nfunction ensurePluginsDir(): void {\n fs.mkdirSync(PLUGINS_DIR, { recursive: true })\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n}\n\nexport function installPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info({ packageName }, 'Installing plugin')\n execSync(`npm install ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info({ packageName }, 'Plugin installed successfully')\n}\n\nexport function uninstallPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info({ packageName }, 'Uninstalling plugin')\n execSync(`npm uninstall ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info({ packageName }, 'Plugin uninstalled')\n}\n\nexport function listPlugins(): Record<string, string> {\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) return {}\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n return pkg.dependencies || {}\n}\n\nexport async function loadAdapterFactory(packageName: string): Promise<AdapterFactory | null> {\n try {\n const require = createRequire(path.join(PLUGINS_DIR, 'package.json'))\n const resolved = require.resolve(packageName)\n const mod = await import(resolved)\n\n // Plugin must export `adapterFactory` or default export conforming to AdapterFactory\n const factory: AdapterFactory | undefined = mod.adapterFactory || mod.default\n if (!factory || typeof factory.createAdapter !== 'function') {\n log.error({ packageName }, 'Plugin does not export a valid AdapterFactory (needs .createAdapter())')\n return null\n }\n return factory\n } catch (err) {\n log.error({ packageName, err }, 'Failed to load plugin')\n log.error({ packageName }, 'Run: npx openacp install <packageName>')\n return null\n }\n}\n"],"mappings":"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","names":["resolved","fs","path","log","require"]}
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
installPlugin,
|
|
4
4
|
listPlugins,
|
|
5
5
|
uninstallPlugin
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XOVJLTEC.js";
|
|
7
7
|
import "./chunk-ZATQZUJT.js";
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
@@ -84,7 +84,7 @@ async function main() {
|
|
|
84
84
|
printHelp();
|
|
85
85
|
process.exit(1);
|
|
86
86
|
}
|
|
87
|
-
const { startServer } = await import("./main-
|
|
87
|
+
const { startServer } = await import("./main-GC6JY7DS.js");
|
|
88
88
|
await startServer();
|
|
89
89
|
}
|
|
90
90
|
main().catch((err) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -130,7 +130,7 @@ type LoggingConfig = z.infer<typeof LoggingSchema>;
|
|
|
130
130
|
declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
131
131
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
132
132
|
port: z.ZodDefault<z.ZodNumber>;
|
|
133
|
-
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore"]>>;
|
|
133
|
+
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
|
|
134
134
|
options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
135
135
|
storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
136
136
|
auth: z.ZodDefault<z.ZodObject<{
|
|
@@ -147,7 +147,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
|
147
147
|
options: Record<string, unknown>;
|
|
148
148
|
enabled: boolean;
|
|
149
149
|
port: number;
|
|
150
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
150
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
151
151
|
storeTtlMinutes: number;
|
|
152
152
|
auth: {
|
|
153
153
|
enabled: boolean;
|
|
@@ -157,7 +157,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
|
|
|
157
157
|
options?: Record<string, unknown> | undefined;
|
|
158
158
|
enabled?: boolean | undefined;
|
|
159
159
|
port?: number | undefined;
|
|
160
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
160
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
161
161
|
storeTtlMinutes?: number | undefined;
|
|
162
162
|
auth?: {
|
|
163
163
|
enabled?: boolean | undefined;
|
|
@@ -242,7 +242,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
242
242
|
tunnel: z.ZodDefault<z.ZodObject<{
|
|
243
243
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
244
244
|
port: z.ZodDefault<z.ZodNumber>;
|
|
245
|
-
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore"]>>;
|
|
245
|
+
provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
|
|
246
246
|
options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
247
247
|
storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
248
248
|
auth: z.ZodDefault<z.ZodObject<{
|
|
@@ -259,7 +259,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
259
259
|
options: Record<string, unknown>;
|
|
260
260
|
enabled: boolean;
|
|
261
261
|
port: number;
|
|
262
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
262
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
263
263
|
storeTtlMinutes: number;
|
|
264
264
|
auth: {
|
|
265
265
|
enabled: boolean;
|
|
@@ -269,7 +269,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
269
269
|
options?: Record<string, unknown> | undefined;
|
|
270
270
|
enabled?: boolean | undefined;
|
|
271
271
|
port?: number | undefined;
|
|
272
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
272
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
273
273
|
storeTtlMinutes?: number | undefined;
|
|
274
274
|
auth?: {
|
|
275
275
|
enabled?: boolean | undefined;
|
|
@@ -310,7 +310,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
310
310
|
options: Record<string, unknown>;
|
|
311
311
|
enabled: boolean;
|
|
312
312
|
port: number;
|
|
313
|
-
provider: "cloudflare" | "ngrok" | "bore";
|
|
313
|
+
provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
|
|
314
314
|
storeTtlMinutes: number;
|
|
315
315
|
auth: {
|
|
316
316
|
enabled: boolean;
|
|
@@ -351,7 +351,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
351
351
|
options?: Record<string, unknown> | undefined;
|
|
352
352
|
enabled?: boolean | undefined;
|
|
353
353
|
port?: number | undefined;
|
|
354
|
-
provider?: "cloudflare" | "ngrok" | "bore" | undefined;
|
|
354
|
+
provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
|
|
355
355
|
storeTtlMinutes?: number | undefined;
|
|
356
356
|
auth?: {
|
|
357
357
|
enabled?: boolean | undefined;
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
ConfigManager,
|
|
8
8
|
loadAdapterFactory
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XOVJLTEC.js";
|
|
10
10
|
import {
|
|
11
11
|
cleanupOldSessionLogs,
|
|
12
12
|
initLogger,
|
|
@@ -20,7 +20,7 @@ async function startServer() {
|
|
|
20
20
|
const configManager = new ConfigManager();
|
|
21
21
|
const configExists = await configManager.exists();
|
|
22
22
|
if (!configExists) {
|
|
23
|
-
const { runSetup } = await import("./setup-
|
|
23
|
+
const { runSetup } = await import("./setup-XQBEZZQB.js");
|
|
24
24
|
const shouldStart = await runSetup(configManager);
|
|
25
25
|
if (!shouldStart) process.exit(0);
|
|
26
26
|
}
|
|
@@ -34,7 +34,7 @@ async function startServer() {
|
|
|
34
34
|
const core = new OpenACPCore(configManager);
|
|
35
35
|
let tunnelService;
|
|
36
36
|
if (config.tunnel.enabled) {
|
|
37
|
-
const { TunnelService } = await import("./tunnel-service-
|
|
37
|
+
const { TunnelService } = await import("./tunnel-service-I6NUMBT4.js");
|
|
38
38
|
tunnelService = new TunnelService(config.tunnel);
|
|
39
39
|
const publicUrl = await tunnelService.start();
|
|
40
40
|
core.tunnelService = tunnelService;
|
|
@@ -100,4 +100,4 @@ if (isDirectExecution) {
|
|
|
100
100
|
export {
|
|
101
101
|
startServer
|
|
102
102
|
};
|
|
103
|
-
//# sourceMappingURL=main-
|
|
103
|
+
//# sourceMappingURL=main-GC6JY7DS.js.map
|
|
@@ -309,7 +309,7 @@ async function runSetup(configManager) {
|
|
|
309
309
|
},
|
|
310
310
|
sessionStore: { ttlDays: 30 },
|
|
311
311
|
tunnel: {
|
|
312
|
-
enabled:
|
|
312
|
+
enabled: true,
|
|
313
313
|
port: 3100,
|
|
314
314
|
provider: "cloudflare",
|
|
315
315
|
options: {},
|
|
@@ -350,4 +350,4 @@ export {
|
|
|
350
350
|
validateBotToken,
|
|
351
351
|
validateChatId
|
|
352
352
|
};
|
|
353
|
-
//# sourceMappingURL=setup-
|
|
353
|
+
//# sourceMappingURL=setup-XQBEZZQB.js.map
|