@vibecontrols/agent 2026.601.30

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 (108) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +558 -0
  3. package/dist/agent-config-85pskv43.js +2 -0
  4. package/dist/agent-ready-tracker-zp6p8e6f.js +2 -0
  5. package/dist/app-yvjadjmh.js +2 -0
  6. package/dist/bootstrap-workspace-zpm20zez.js +2 -0
  7. package/dist/bootstrap.service-pjmnpxha.js +2 -0
  8. package/dist/bridge-client-341r9rry.js +2 -0
  9. package/dist/cli.js +5 -0
  10. package/dist/daemon-profile-vas1vf2t.js +2 -0
  11. package/dist/esm-9fpye77x.js +2 -0
  12. package/dist/finalize-retry-handle-registry-vv241fsq.js +2 -0
  13. package/dist/finalize-retry-worker-xp1nhv3c.js +2 -0
  14. package/dist/gateway-client-43gzvj5s.js +2 -0
  15. package/dist/getMachineId-bsd-a56s0v8c.js +2 -0
  16. package/dist/getMachineId-darwin-w9k0yw9r.js +3 -0
  17. package/dist/getMachineId-linux-anh31jbf.js +2 -0
  18. package/dist/getMachineId-unsupported-5hv3pwca.js +2 -0
  19. package/dist/getMachineId-win-njb8tery.js +2 -0
  20. package/dist/highlights-8d9mgr01.js +2 -0
  21. package/dist/highlights-eq9cgrbb.scm +604 -0
  22. package/dist/highlights-ghv9g403.scm +205 -0
  23. package/dist/highlights-hk7bwhj4.scm +284 -0
  24. package/dist/highlights-jwvdxm9x.js +2 -0
  25. package/dist/highlights-qbx2vnme.js +2 -0
  26. package/dist/highlights-r3m83kn9.js +2 -0
  27. package/dist/highlights-r812a2qc.scm +150 -0
  28. package/dist/highlights-s7mqapt6.js +2 -0
  29. package/dist/highlights-x6tmsnaa.scm +115 -0
  30. package/dist/index-01qzsnwd.js +16 -0
  31. package/dist/index-0248afsn.js +3 -0
  32. package/dist/index-04n4qgvd.js +407 -0
  33. package/dist/index-0ckffygp.js +5 -0
  34. package/dist/index-0cn9bv8z.js +4 -0
  35. package/dist/index-1hnw0rhc.js +178 -0
  36. package/dist/index-1zw3kea7.js +10 -0
  37. package/dist/index-2gsarrbn.js +4 -0
  38. package/dist/index-2xs9cvjn.js +28 -0
  39. package/dist/index-3ys16efc.js +231 -0
  40. package/dist/index-4wgjx8bf.js +3 -0
  41. package/dist/index-52cp759f.js +3 -0
  42. package/dist/index-5mw3eshk.js +4 -0
  43. package/dist/index-678rwfc0.js +5 -0
  44. package/dist/index-6jq17k9s.js +7 -0
  45. package/dist/index-6jzsthh9.js +3 -0
  46. package/dist/index-6mprnf7p.js +9 -0
  47. package/dist/index-8kvc8ttn.js +15 -0
  48. package/dist/index-8sm0nkh8.js +3 -0
  49. package/dist/index-9bqd8veb.js +21 -0
  50. package/dist/index-b5dhmybd.js +4 -0
  51. package/dist/index-c58g96mb.js +26 -0
  52. package/dist/index-cs78wq6y.js +3 -0
  53. package/dist/index-d5ysy1yn.js +3 -0
  54. package/dist/index-dm6yjmgq.js +3 -0
  55. package/dist/index-e1bw1bwr.js +4 -0
  56. package/dist/index-ef95xr4z.js +9 -0
  57. package/dist/index-g2raeeh4.js +11 -0
  58. package/dist/index-g3ap3xpr.js +5 -0
  59. package/dist/index-g8zv1gta.js +17 -0
  60. package/dist/index-h8a8s8sn.js +3 -0
  61. package/dist/index-hrdamx5j.js +2 -0
  62. package/dist/index-jw1k4vbk.js +3 -0
  63. package/dist/index-mtm8cfyt.js +158 -0
  64. package/dist/index-mxc61yr1.js +3 -0
  65. package/dist/index-n7qyrdr1.js +3 -0
  66. package/dist/index-qfz9fy56.js +3 -0
  67. package/dist/index-rc79x8fw.js +3 -0
  68. package/dist/index-rdp5xq4r.js +15 -0
  69. package/dist/index-scsjyj4m.js +171 -0
  70. package/dist/index-ssjmzqcz.js +13 -0
  71. package/dist/index-tmrbs96r.js +11 -0
  72. package/dist/index-tp4y9jde.js +83 -0
  73. package/dist/index-v9fx5wab.js +83 -0
  74. package/dist/index-vdahdt49.js +2 -0
  75. package/dist/index-x1h8r7pr.js +3 -0
  76. package/dist/index-xjzmb1pn.js +3 -0
  77. package/dist/index-yrgm89r8.js +3 -0
  78. package/dist/index-yy1mm8zs.js +3 -0
  79. package/dist/index-z5a4yxzz.js +8 -0
  80. package/dist/index.js +5 -0
  81. package/dist/injections-73j83es3.scm +27 -0
  82. package/dist/injections-srewsjcz.js +2 -0
  83. package/dist/interactive-22ta89hc.js +2 -0
  84. package/dist/key.cmd-wgcq6kt8.js +2 -0
  85. package/dist/log-shipper-k24m8yw5.js +2 -0
  86. package/dist/path-utils-35re7qf9.js +2 -0
  87. package/dist/plugin-system-c916v9an.js +2 -0
  88. package/dist/postinstall-shim-fix.cjs +382 -0
  89. package/dist/prereqs-runner-ca4kt803.js +2 -0
  90. package/dist/preuninstall.cjs +254 -0
  91. package/dist/profile-mount-npcknw6v.js +2 -0
  92. package/dist/prune-stale-shims-nkx9vq5m.js +2 -0
  93. package/dist/register-core-qrawzyym.js +2 -0
  94. package/dist/secondary-profile-attach-db5cr3e1.js +2 -0
  95. package/dist/subprocess-g9sk1ep9.js +2 -0
  96. package/dist/telemetry-tnq47dcs.js +2 -0
  97. package/dist/tree-sitter-javascript-3h25c6bs.js +2 -0
  98. package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  99. package/dist/tree-sitter-markdown-3nemcjhe.js +2 -0
  100. package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
  101. package/dist/tree-sitter-markdown_inline-16ftwa53.js +2 -0
  102. package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  103. package/dist/tree-sitter-typescript-f6mq6ze6.js +2 -0
  104. package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  105. package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
  106. package/dist/tree-sitter-zig-s2trkm2d.js +2 -0
  107. package/dist/tunnel-bootstrap-2kg79ng8.js +2 -0
  108. package/package.json +122 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2025-2026 Burdenoff Consultancy Services Pvt. Ltd. All rights reserved.
4
+
5
+ This software and associated documentation files (the "Software") are the proprietary
6
+ property of Burdenoff Consultancy Services Pvt. Ltd. and its affiliates.
7
+
8
+ UNAUTHORIZED COPYING, MODIFICATION, DISTRIBUTION, OR USE OF THIS SOFTWARE, VIA ANY
9
+ MEDIUM, IS STRICTLY PROHIBITED.
10
+
11
+ The Software is provided under a proprietary license. You may use the Software only in
12
+ accordance with the terms of your license agreement with Burdenoff Consultancy Services
13
+ Pvt. Ltd.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
19
+ OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
+ OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ For licensing inquiries, contact: contact@vibecontrols.com
package/README.md ADDED
@@ -0,0 +1,558 @@
1
+ # @vibecontrols/agent
2
+
3
+ Remote development environment management CLI with terminal multiplexing, SSH tunneling, port forwarding, cloudflared integration, and a plugin system.
4
+
5
+ **VibeControls Agent** runs as a lightweight local service on your development machine, providing a unified REST API and CLI for managing tmux sessions, SSH connections, cloudflared tunnels, port forwards, background tasks, and more.
6
+
7
+ ## Installation
8
+
9
+ Requires **Bun >= 1.3**.
10
+
11
+ ### Supported operating systems
12
+
13
+ | OS | Status | Notes |
14
+ | ------------------- | -------------- | ------------------------------------------------------------------------- |
15
+ | Linux (glibc/musl) | ✅ first-class | systemd `vibe autostart install` ships out of the box |
16
+ | macOS (Apple/Intel) | ✅ first-class | launchd `vibe autostart install` ships out of the box |
17
+ | Windows 10/11 | ✅ supported | Task Scheduler autostart (`vibe autostart install` → schtasks); see notes |
18
+ | WSL2 | ✅ supported | Treated as Linux. systemd-on-WSL needed for autostart |
19
+
20
+ OS-specific abstraction lives behind `src/core/os-adapter.ts` (`OsAdapter` interface with one implementation per platform). Cross-platform pieces:
21
+
22
+ - **Process liveness / kill** uses `process.kill(pid, 0)` on POSIX and the same on Windows; signal escalation translates to `taskkill /T /F` on Windows.
23
+ - **Locating binaries** uses `which` on POSIX and `where.exe` on Windows.
24
+ - **Listing child PIDs** uses `pgrep -P` on POSIX and `wmic process where (ParentProcessId=...)` on Windows.
25
+ - **Shell quoting / shell invocation** ships POSIX (`/bin/sh -c`) and PowerShell (`powershell -Command`) implementations.
26
+ - **npm / bun spawns** use `npm.cmd`/`bun.exe` on Windows and `npm`/`bun` on POSIX.
27
+
28
+ #### Windows-specific notes
29
+
30
+ - Run from PowerShell or Windows Terminal. `cmd.exe` works for basic commands but PowerShell is the tested shell.
31
+ - Bun on Windows requires Windows 10 (1809+) or Windows 11.
32
+ - `vibe autostart install` writes a Task Scheduler entry under your user account (no admin rights needed). Trigger: logon. Restart on failure: 3 attempts, 1 min apart.
33
+ - `vibe tunnel kill --orphans` translates SIGTERM/SIGKILL into `taskkill /T /F` (Windows has no POSIX signals).
34
+ - `vibe deploy <ssh-target>` works from any OS as long as `ssh` is on PATH (built into Windows 10 1809+).
35
+
36
+ #### macOS-specific notes
37
+
38
+ - First-time launch may need to grant Terminal "Full Disk Access" if you store agent state in protected locations like `~/Library`.
39
+ - `vibe autostart install` writes a launchd plist to `~/Library/LaunchAgents/`. Enabled with `launchctl bootstrap gui/<uid>`.
40
+ - Apple Silicon: cloudflared must be the arm64 build. The plugin's `prereqs/install` handles this automatically.
41
+
42
+ #### Linux-specific notes
43
+
44
+ - systemd user services need `loginctl enable-linger <user>` for the agent to keep running after logout. `vibe autostart install` does this for you.
45
+ - On non-systemd distros (Alpine, Void, etc.) `vibe autostart` is not yet supported — run `vibe start` from your service supervisor of choice.
46
+
47
+ #### WSL-specific notes
48
+
49
+ - WSL2 reports `linux` as platform. The agent treats it like a Linux install.
50
+ - `vibe autostart install` requires systemd in WSL (Windows 11 22H2+ or `wsl --update` + `systemd=true` in `/etc/wsl.conf`).
51
+ - Tunnels work, but the URL is reachable from the Windows host out of the box.
52
+
53
+ ### Global install (default)
54
+
55
+ ```bash
56
+ npm install -g @vibecontrols/agent
57
+ # or
58
+ bun install -g @vibecontrols/agent
59
+ ```
60
+
61
+ The `vibe` binary is on your PATH and plugins install into your global `node_modules`.
62
+
63
+ ### Local install (per-folder)
64
+
65
+ You can also install the agent into a single folder and keep all plugins scoped to that folder — useful for project-pinned setups, CI runners, multi-tenant machines, or trying things in isolation without touching the global `node_modules`.
66
+
67
+ ```bash
68
+ mkdir my-vibe && cd my-vibe
69
+ npm install @vibecontrols/agent
70
+ # or: bun add @vibecontrols/agent
71
+
72
+ # Tell the agent to install plugins into this folder, not globally
73
+ export VIBECONTROLS_PLUGIN_INSTALL_MODE=local
74
+
75
+ ./node_modules/.bin/vibe start
76
+ ```
77
+
78
+ In `local` mode, plugins go to `<cwd>/.boff/vibecontrols/agents/<agentId>/agent-plugins/node_modules/`.
79
+
80
+ The plugin loader searches **both** local and global locations on every start, in this priority order:
81
+
82
+ 1. `<agentDir>/agent-plugins/node_modules/` (per-agent local)
83
+ 2. `VIBECONTROLS_PLUGIN_ROOTS` (colon-separated extra paths)
84
+ 3. CWD walk-up `node_modules/`
85
+ 4. The agent's own location
86
+ 5. Bun global (`bun pm -g bin`)
87
+ 6. npm global (`npm root -g`)
88
+
89
+ So you can mix-and-match: a globally installed agent will still pick up plugins dropped into a local folder, and vice versa. `VIBECONTROLS_PLUGIN_INSTALL_MODE` only controls **where new installs land** (default: `global`).
90
+
91
+ ### From source (local development)
92
+
93
+ ```bash
94
+ cd ~/products/vibecontrols/vibecontrols-agent
95
+ bun install
96
+
97
+ # Standard dev (restarts on file change, new tunnel URL each time)
98
+ bun run dev
99
+
100
+ # Hot-reload dev (tunnel URL and API key survive restarts)
101
+ bun run dev:reload
102
+
103
+ # Or with a pinned API key
104
+ AGENT_API_KEY=vcak_your_key_here bun run dev:reload
105
+ ```
106
+
107
+ ## Quick Start
108
+
109
+ ```bash
110
+ # Start the agent as a background daemon (default)
111
+ vibe start
112
+
113
+ # Or start in foreground for debugging
114
+ vibe start --foreground
115
+
116
+ # Verify it's running
117
+ vibe health
118
+ vibe status
119
+ ```
120
+
121
+ On **first run**, the agent automatically:
122
+
123
+ 1. Detects missing system dependencies (tmux, ttyd, cloudflared)
124
+ 2. Installs them via `vibe setup`
125
+ 3. Detects port conflicts and auto-selects the next available port
126
+
127
+ ## Profiles
128
+
129
+ A **profile** is a single JSON file holding the gateway URLs, OAuth credentials, API key, and plugin config for one VibeControls environment. Profiles let one agent binary target local / alpha / prod gateways without rebuilds.
130
+
131
+ Layout:
132
+
133
+ ```
134
+ ~/.boff/vibecontrols/
135
+ profiles/
136
+ local.json # localhost dev URLs
137
+ alpha.json # alpha CF tunnel URLs
138
+ prod.json # production URLs (default)
139
+ <custom>.json # any operator-defined env
140
+ active # plain text -- name of the active profile
141
+ ```
142
+
143
+ The `active` pointer defaults to `prod`. On first run the agent idempotently:
144
+
145
+ 1. Migrates a legacy `~/.boff/vibecontrols/config.json` to `profiles/default.json` (only if `profiles/` does not yet exist).
146
+ 2. Creates `local`, `alpha`, `prod` profiles when absent (existing user profiles are never overwritten).
147
+ 3. Writes `active=prod` (or `default` if a legacy config was migrated) when no `active` pointer exists.
148
+
149
+ You can re-run that pass at any time with `vibe profile seed`.
150
+
151
+ ### Profile commands
152
+
153
+ ```bash
154
+ vibe profile list # all profiles, active flagged
155
+ vibe profile current # name of the active profile
156
+ vibe profile show [<name>] # profile JSON (apiKey + secrets redacted)
157
+ vibe profile create <name> [--from <existing>] [--use]
158
+ # blank, or copy of another profile;
159
+ # if <name> is local|alpha|prod the
160
+ # built-in URLs are used as the seed
161
+ vibe profile use <name> # set the active pointer
162
+ vibe profile delete <name> --confirm # refuses if <name> is the active profile
163
+ vibe profile seed # idempotent migrate + seed pass
164
+ ```
165
+
166
+ ### Profile resolution
167
+
168
+ `getAgentConfig()` reads the `active` pointer, loads `profiles/<active>.json`, then layers on per-agent `config.json` overrides and finally environment variables (env wins). No code paths require a rebuild to swap environments -- flip `active` (or run `vibe profile use <name>`) and restart.
169
+
170
+ ### Concurrent profiles
171
+
172
+ Each profile runs as its own daemon with its own port and tunnel:
173
+
174
+ ```bash
175
+ vibe --profile alpha start
176
+ vibe --profile dev start
177
+ vibe list # both running
178
+ ```
179
+
180
+ ### REST API for profile management
181
+
182
+ Frontends can manage profiles directly via the agent's tunnel:
183
+
184
+ ```
185
+ GET /api/profiles # list
186
+ POST /api/profiles # create body: { name, gatewayUrl?, workspaceGatewayUrl?, clientId?, clientSecret?, copyFrom?, start? }
187
+ GET /api/profiles/:name # single profile + status
188
+ PUT /api/profiles/:name # patch config (excludes static-api-key, apiKeys, agentRecordId)
189
+ DELETE /api/profiles/:name # body: { confirm: true, keepConfig? }
190
+ POST /api/profiles/:name/start # spawn daemon
191
+ POST /api/profiles/:name/stop # graceful stop
192
+ POST /api/profiles/:name/switch # set as default
193
+ ```
194
+
195
+ All data API routes are addressed via the profile prefix:
196
+
197
+ ```
198
+ /api/profiles/<name>/agent/identity
199
+ /api/profiles/<name>/sessions/...
200
+ /api/profiles/<name>/tasks/...
201
+ /api/profiles/<name>/plugins/install
202
+ /api/profiles/<name>/agent/gateway-auth
203
+ ... etc.
204
+ ```
205
+
206
+ When `<name>` matches the running daemon's profile, the request is served. Mismatches return `404 { "error": "profile-mismatch", "running": "<X>", "requested": "<Y>" }` so clients can pick the right tunnel.
207
+
208
+ **Bare `/api/<rest>` paths (no profile prefix) return `410 Gone`** — there's no longer a "default" data route for ambiguity reasons. Frontend / backend integrations must always carry the profile name in the URL. Discover the running profile via `GET /api/profiles` first.
209
+
210
+ Exempt from the rule (no profile prefix needed):
211
+
212
+ - `/health` — process liveness
213
+ - `/api/profiles[/:name][/...]` — profile management
214
+ - `/ui/`, `/ws/`, `/terminal/`, `/code-server/` — websocket/UI bridges
215
+
216
+ ## Configuration
217
+
218
+ Create a `.env` file in your working directory or set environment variables:
219
+
220
+ | Variable | Description | Default |
221
+ | ---------------------------------- | -------------------------------------------------------------- | -------------------------------------------- |
222
+ | `PORT` | Agent server port | `3005` |
223
+ | `NODE_ENV` | Environment | `development` |
224
+ | `CORS_ORIGIN` | Allowed CORS origin | `http://localhost:3000` |
225
+ | `AGENT_API_KEY` | Static API key (optional) | (auto-generated) |
226
+ | `DB_PATH` | SQLite database path | `.boff/vibecontrols/agents/default/agent.db` |
227
+ | `AGENT_TUNNEL` | Auto-start cloudflared tunnel | `true` |
228
+ | `VIBECONTROLS_HOME` | Override product state dir | `.boff/vibecontrols/` |
229
+ | `VIBECONTROLS_PROFILE` | Profile name for isolated config | `default` |
230
+ | `VIBECONTROLS_REGISTRY` | Override plugin registry | `https://registry.npmjs.org/` |
231
+ | `VIBECONTROLS_PLUGIN_INSTALL_MODE` | Where new plugins are installed: `global` or `local` | `global` |
232
+ | `VIBECONTROLS_PLUGIN_ROOTS` | Extra colon-separated `node_modules` roots to scan for plugins | (unset) |
233
+
234
+ ### Static API Key
235
+
236
+ By default, the agent generates a new API key on each restart. To persist one:
237
+
238
+ ```bash
239
+ # Auto-generate and save a persistent key
240
+ vibe config --set static-api-key=true
241
+
242
+ # Or set an explicit key
243
+ vibe config --set static-api-key=my-secret-key-here
244
+ ```
245
+
246
+ The key is stored in `.boff/vibecontrols/agents/{agentId}/config.json` (relative to the directory where `vibe start` was run).
247
+
248
+ An `.env.example` file is included in the package for reference.
249
+
250
+ ## Command Reference
251
+
252
+ ### Core Commands
253
+
254
+ ```bash
255
+ vibe start # Start as daemon (default)
256
+ vibe start --foreground # Start in foreground
257
+ vibe start -p 4000 # Start on custom port
258
+ vibe start -n myagent # Start with instance name
259
+ vibe start --db-path ~/my.db # Custom database path
260
+
261
+ vibe stop # Stop default instance
262
+ vibe stop -n myagent # Stop named instance
263
+ vibe stop --all # Stop all instances
264
+
265
+ vibe restart # Restart default instance
266
+ vibe restart -n myagent # Restart named instance
267
+
268
+ vibe status # Show all instance statuses
269
+ vibe status -n myagent # Show specific instance status
270
+
271
+ vibe list # List all instances
272
+ vibe kill # Force kill default instance
273
+ vibe kill --all # Force kill all
274
+
275
+ vibe logs # Show logs (default instance)
276
+ vibe logs -f # Follow logs (tail -f)
277
+ vibe logs --tail 50 # Last 50 lines
278
+
279
+ vibe health # Health check via HTTP
280
+ vibe info # Detailed version/system info
281
+ vibe key # Display the agent API key
282
+ vibe system # System info from running agent
283
+
284
+ vibe update # Update to latest version
285
+ vibe update --check # Check for updates without installing
286
+ ```
287
+
288
+ ### Setup & Configuration
289
+
290
+ ```bash
291
+ vibe setup # Install dependencies (tmux, ttyd, cloudflared)
292
+ vibe setup --check # Check without installing
293
+
294
+ vibe config --list # List all config values
295
+ vibe config --get <key> # Get a specific config value
296
+ vibe config --set key=value # Set a config value
297
+ ```
298
+
299
+ ### Plugin Management
300
+
301
+ Extend the agent with plugins that add CLI commands, routes, or both.
302
+
303
+ ```bash
304
+ vibe plugin list # List installed plugins
305
+ vibe plugin install @vibecontrols/vibe-plugin-ssh # Install a plugin
306
+ vibe plugin install @vibecontrols/vibe-plugin-ai # Install AI tools plugin
307
+ vibe plugin remove @vibecontrols/vibe-plugin-ssh # Remove a plugin
308
+ vibe plugin create my-plugin # Scaffold a new plugin
309
+ vibe plugin create my-plugin --with-ui # Scaffold with React UI
310
+ vibe plugin create my-plugin --tag provider # Set plugin tag
311
+ ```
312
+
313
+ **Available Plugins:**
314
+
315
+ | Plugin | Description |
316
+ | --------------------------------------------- | ----------------------------------------------------- |
317
+ | `@vibecontrols/vibe-plugin-ssh` | SSH connections & port forwarding |
318
+ | `@vibecontrols/vibe-plugin-ai` | AI tool detection & prompt management (SQLite + REST) |
319
+ | `@vibecontrols/vibe-plugin-session-tmux` | tmux-based session provider |
320
+ | `@vibecontrols/vibe-plugin-tunnel-cloudflare` | Cloudflare tunnel provider |
321
+ | `@vibecontrols/vibe-plugin-ui-ssh` | Web UI for SSH management |
322
+ | `@vibecontrols/vibe-plugin-ui-ai` | Web UI for AI tools & prompt templates |
323
+
324
+ ### Tunnel Management
325
+
326
+ Manage cloudflared tunnels that expose local ports via public URLs.
327
+
328
+ ```bash
329
+ # Per-port tunnels
330
+ vibe tunnel list # List all tunnels
331
+ vibe tunnel status # Overview (total, active, inactive, errored)
332
+ vibe tunnel start -p 8080 # Expose local port 8080
333
+ vibe tunnel start -p 3000 -s myapp # With preferred subdomain
334
+ vibe tunnel stop -i <id> # Stop a tunnel
335
+ vibe tunnel delete -i <id> # Delete a tunnel
336
+
337
+ # Agent tunnel (main agent cloudflared tunnel)
338
+ vibe tunnel agent # Show agent tunnel status
339
+ vibe tunnel agent --start # Start agent tunnel
340
+ vibe tunnel agent --stop # Stop agent tunnel
341
+
342
+ # Orphan handling — see "Tunnel survives the agent" below
343
+ vibe tunnel kill --orphans # Kill any tunnel process whose agent is gone
344
+ ```
345
+
346
+ #### Tunnel survives the agent
347
+
348
+ The agent tunnel (cloudflared / frpc) is spawned as an independent OS process so a hard `kill -9` of the agent does **not** drop the public URL — that's intentional. The trade-off: when the agent is gone, you have nothing to talk to over REST, so the standard `vibe tunnel agent` command can't tell you what's still running.
349
+
350
+ To work around that, every tunnel start writes `<agentDir>/tunnel.state.json` with the PID, URL, provider, and start time. The CLI uses that file as a fallback:
351
+
352
+ ```bash
353
+ # Works even after `kill -9 <agent-pid>` — reads tunnel.state.json
354
+ vibe tunnel agent
355
+
356
+ # Output when the agent is dead but cloudflared is still running:
357
+ # Status: orphan
358
+ # Public URL: https://random-words-123.trycloudflare.com
359
+ # PID: 48211
360
+ # Provider: bootstrap-cloudflared
361
+
362
+ # Reap the orphan:
363
+ vibe tunnel kill --orphans # SIGTERM, then SIGKILL after 3s
364
+ vibe tunnel kill --orphans --force # SIGKILL immediately
365
+ ```
366
+
367
+ If you prefer the unix-y route:
368
+
369
+ ```bash
370
+ # Find it manually
371
+ cat ./.boff/vibecontrols/agents/default/tunnel.state.json
372
+ ps -p $(jq -r .pid ./.boff/vibecontrols/agents/default/tunnel.state.json)
373
+
374
+ # Kill it manually
375
+ pkill -f "cloudflared tunnel --url"
376
+ ```
377
+
378
+ Stale state files (where the recorded PID is no longer alive) are cleared automatically on the next `vibe tunnel agent` call.
379
+
380
+ ### Terminal Sessions (tmux)
381
+
382
+ ```bash
383
+ vibe session list # List managed sessions
384
+ vibe session list --system # Include unmanaged tmux sessions
385
+
386
+ vibe session create --name dev # Create session named "dev"
387
+ vibe session create --name dev --cwd ~/project --command "npm run dev"
388
+
389
+ vibe session kill -i <id> # Kill a session
390
+ vibe session exec -i <id> -c "ls -la" # Run command in session
391
+ vibe session capture -i <id> # Capture session output
392
+ ```
393
+
394
+ ### SSH Connections
395
+
396
+ ```bash
397
+ vibe ssh list # List saved connections
398
+
399
+ vibe ssh add --name prod \
400
+ --host 10.0.1.50 \
401
+ --user deploy \
402
+ --port 22 \
403
+ --key ~/.ssh/id_rsa # Add a connection
404
+
405
+ vibe ssh remove -i <id> # Remove a connection
406
+ vibe ssh test -i <id> # Test connectivity
407
+ vibe ssh exec -i <id> -c "uptime" # Execute remote command
408
+ ```
409
+
410
+ ### Port Forwarding
411
+
412
+ ```bash
413
+ vibe forward list # List all forwards
414
+
415
+ vibe forward create \
416
+ --local 5432 \
417
+ --remote-host db.internal \
418
+ --remote-port 5432 \
419
+ --server prod # Create a forward rule
420
+
421
+ vibe forward start -i <id> # Start forwarding
422
+ vibe forward stop -i <id> # Stop forwarding
423
+ vibe forward delete -i <id> # Delete forward rule
424
+ ```
425
+
426
+ ### Background Tasks
427
+
428
+ ```bash
429
+ vibe task list # List all tasks
430
+ vibe task list --status running # Filter by status
431
+ vibe task run -c "npm test" # Run command as background task
432
+ vibe task run -c "make build" --cwd ~/project
433
+ ```
434
+
435
+ ### Notifications
436
+
437
+ ```bash
438
+ vibe notify list # List all notifications
439
+ vibe notify list --unread # Show only unread
440
+ vibe notify read-all # Mark all as read
441
+ ```
442
+
443
+ ## Global Options
444
+
445
+ Every subcommand that communicates with a running agent accepts:
446
+
447
+ ```bash
448
+ --agent-url <url> # Default: http://localhost:3005
449
+ ```
450
+
451
+ This lets you manage remote agents or agents on non-default ports:
452
+
453
+ ```bash
454
+ vibe health --agent-url http://192.168.1.10:3005
455
+ vibe tunnel list --agent-url http://localhost:4000
456
+ ```
457
+
458
+ ## Architecture
459
+
460
+ The agent runs as a Bun + Elysia HTTP server with:
461
+
462
+ - **bun:sqlite** database for local state (sessions, connections, tunnels, tasks, config)
463
+ - **tmux** integration for terminal multiplexing
464
+ - **cloudflared** for secure tunnel management
465
+ - **Plugin system** for extensibility (SSH, AI tools, UI plugins, and custom plugins)
466
+ - **WebSocket** proxy for real-time terminal streaming
467
+ - **API key** authentication on all endpoints
468
+ - **Daemon mode** by default with proper process management
469
+
470
+ ### System Dependencies
471
+
472
+ | Tool | Purpose | Required |
473
+ | ----------- | --------------------- | ----------- |
474
+ | Bun >= 1.3 | Runtime | Yes |
475
+ | tmux | Terminal multiplexing | Yes |
476
+ | ttyd | Web-based terminal | Recommended |
477
+ | cloudflared | Tunnel management | For tunnels |
478
+
479
+ Run `vibe setup --check` to verify all dependencies.
480
+
481
+ ## REST API
482
+
483
+ When the agent is running, it exposes a REST API at `http://localhost:3005/api/` with 112 endpoints across these route groups:
484
+
485
+ - `/api/tmux/*` - Terminal session management
486
+ - `/api/ssh/*` - SSH connection management
487
+ - `/api/tunnel/*` - Per-port tunnel CRUD
488
+ - `/api/agent-tunnel/*` - Agent tunnel management
489
+ - `/api/port-forward/*` - Port forwarding
490
+ - `/api/tasks/*` - Background task management
491
+ - `/api/config/*` - Configuration & system info
492
+ - `/api/notifications/*` - Notification management
493
+ - `/api/files/*` - File operations
494
+ - `/api/git/*` - Git repository scanning
495
+ - `/api/bookmarks/*` - Command bookmarks
496
+ - `/api/projects/*` - Project scanning
497
+ - `/api/ai/tools` - AI tool detection
498
+ - `/api/ai/prompts/*` - Prompt template CRUD (via AI plugin)
499
+
500
+ Authentication: Include `x-agent-api-key` header with your API key.
501
+
502
+ ## Examples
503
+
504
+ ### Development Workflow
505
+
506
+ ```bash
507
+ # Start agent (daemon mode is the default)
508
+ vibe start
509
+
510
+ # Set up a dev session
511
+ vibe session create --name frontend --cwd ~/app --command "npm run dev"
512
+ vibe session create --name backend --cwd ~/api --command "npm start"
513
+
514
+ # Expose your dev server publicly
515
+ vibe tunnel start -p 3000
516
+
517
+ # Check everything is running
518
+ vibe session list
519
+ vibe tunnel list
520
+ vibe health
521
+
522
+ # Later, clean up
523
+ vibe stop
524
+ ```
525
+
526
+ ### Remote Server Management
527
+
528
+ ```bash
529
+ # Save SSH connections
530
+ vibe ssh add --name staging --host staging.example.com --user deploy --key ~/.ssh/deploy
531
+ vibe ssh add --name production --host prod.example.com --user deploy --key ~/.ssh/deploy
532
+
533
+ # Test connections
534
+ vibe ssh test -i <staging-id>
535
+
536
+ # Run remote commands
537
+ vibe ssh exec -i <staging-id> -c "docker ps"
538
+ vibe ssh exec -i <production-id> -c "systemctl status nginx"
539
+
540
+ # Set up port forwarding to access remote databases
541
+ vibe forward create --local 5432 --remote-host localhost --remote-port 5432 --server staging
542
+ vibe forward start -i <forward-id>
543
+ ```
544
+
545
+ ## Part of the VibeControls Ecosystem
546
+
547
+ This agent is the local component of the [VibeControls](https://vibecontrols.com) development environment platform. It can operate standalone or connect to the VibeControls backend for centralized management across multiple machines.
548
+
549
+ ## Author
550
+
551
+ **Vignesh T.V.** ([@tvvignesh](https://github.com/tvvignesh))
552
+ [vignesh@burdenoff.com](mailto:vignesh@burdenoff.com)
553
+
554
+ ## License
555
+
556
+ Proprietary - Copyright 2025-2026 Burdenoff Consultancy Services Pvt. Ltd. All rights reserved.
557
+
558
+ See [LICENSE](./LICENSE) for details.
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{$c as g,Vc as a,Wc as b,Xc as c,Yc as d,Zc as e,_c as f,ad as h,bd as i,cd as j,dd as k,ed as l,fd as m,gd as n,hd as o,id as p,jd as q,kd as r,ld as s,md as t,nd as u,od as v,pd as w,qd as x,rd as y,sd as z,td as A,ud as B}from"./index-g2raeeh4.js";import"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";export{m as writeProfile,x as writeAgentConfigAwaitSecrets,w as writeAgentConfig,j as writeActiveProfileName,l as readProfile,y as readAgentConfigWithSecrets,u as readAgentConfig,i as readActiveProfileName,z as readActiveProfile,k as listProfileNames,f as getProfilesDir,h as getProfilePath,q as getProductionGatewayUrls,v as getOrCreateAgentInstanceId,t as getAgentConfigSeed,r as getAgentConfigPath,s as getAgentConfigDefaults,g as getActiveProfilePointerPath,p as ensureProfilesInitialized,n as deleteProfile,o as buildProfileSeed,e as assertValidProfileName,B as applyAgentSecretsToEnv,A as applyAgentConfigToEnv,c as NAMED_ENV_PRESETS,d as DEFAULT_PROFILE_NAME,a as CURRENT_CONFIG_SCHEMA_VERSION,b as BUILTIN_PROFILE_SEEDS};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{nc as G,uc as f,vc as y,wc as V}from"./index-z5a4yxzz.js";import"./index-yy1mm8zs.js";var N={pending:()=>G.gray("\u25CF"),active:()=>G.cyan("\u25B6"),ok:()=>G.green("\u2713"),warn:()=>G.yellow("\u26A0"),fail:()=>G.red("\u2717")};function L(E,A){if(A)console.log(" "+E)}async function O(E,A=2000){let W=new AbortController,j=setTimeout(()=>W.abort(),A);try{let q=await fetch(`${E}/health/ready`,{signal:W.signal});if(q.status!==200&&q.status!==503)return null;return await q.json()}catch{return null}finally{clearTimeout(j)}}function P(E){if(!E?.message)return null;let A=E.message.match(/provider:\s*(\S+)/);return A?A[1]:null}async function M(E,A={}){let W=A.timeoutMs??60000,j=A.pollIntervalMs??500,q=A.verbose!==!1;if(q)f("Waiting for agent to become ready");let C={daemon:!1,awaiting:!1,initializing:!1,db:!1,session:!1,tunnel:!1},z=Date.now(),X="",H=0,D=null;while(Date.now()-z<W){let Q=await O(E);if(!Q){await T(j);continue}if(!C.daemon)L(`${N.ok()} Daemon listening on ${E}`,q),C.daemon=!0;let F=Q.bootState??"unknown",Y=Q.components??{};if(F!==X){if(X=F,F==="awaiting-config"&&!C.awaiting)L(`${N.warn()} Workspace config: ${G.yellow("awaiting OAuth credentials \u2014 register this agent in the VibeControls UI")}`,q),C.awaiting=!0;else if(F==="initializing"&&!C.initializing)L(`${N.active()} Finalizing: fetching encryption key, opening storage, loading plugins\u2026`,q),C.initializing=!0}if(F==="awaiting-config"){if(H++,H>=2)return{outcome:"awaiting-config",bootState:F,degradedReasons:[],summary:"Agent is awaiting workspace registration. Open the VibeControls UI \u2192 Agents \u2192 Add Agent, paste the API Key and Tunnel URL printed above."}}else H=0;if(Y.db?.ok&&!C.db)L(`${N.ok()} Storage encryption key loaded, DB opened`,q),C.db=!0;if(Y.session?.ok&&!C.session){let x=Y.session.message??"";L(`${N.ok()} Plugins started \u2014 ${x}`,q),C.session=!0}let Z=P(Y.tunnel);if(Z&&Z!=="bootstrap"&&Z!==D){if(D=Z,!C.tunnel)L(`${N.ok()} Tunnel ready (provider: ${Z})`,q),C.tunnel=!0}let I=Q.status==="degraded";if(F==="ready"&&!I){if(q)V(),y("Status",G.green("ready"));return{outcome:"ready",bootState:F,degradedReasons:[],summary:"Agent ready."}}if(F==="degraded"||F==="ready"&&I){let x=Q.degradedReasons??[],_=x;if(x.length===0){let J=[];for(let[$,K]of Object.entries(Y)){if($==="boot"||$==="lifecycle")continue;if(K&&!K.ok&&K.message)J.push({plugin:$,message:K.message})}for(let[$,K]of Object.entries(Q.plugins??{}))if(K&&!K.ok&&K.message)J.push({plugin:`plugin:${$}`,message:K.message});_=J}if(q){V(),L(`${N.fail()} Agent boot ${G.red("degraded")} \u2014 investigate before retrying`,q);for(let J of _)L(` ${G.gray("\xB7")} [${J.plugin}] ${J.message}`,q);V()}return{outcome:"degraded",bootState:F,degradedReasons:_,summary:_.length?`Agent degraded: ${_.map((J)=>`[${J.plugin}] ${J.message}`).join("; ")}`:"Agent degraded with no reported reason \u2014 check vibe logs."}}await T(j)}if(q)V(),L(`${N.warn()} Timed out after ${Math.round(W/1000)}s; last bootState=${X||"unknown"}. Check ${G.bold("vibe logs")} for details.`,q),V();return{outcome:"timeout",bootState:X||"unknown",degradedReasons:[],summary:`Timed out waiting for ready. Last bootState=${X||"unknown"}.`}}function T(E){return new Promise((A)=>setTimeout(A,E))}export{M as trackAgentReady};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{n as a}from"./index-c58g96mb.js";import"./index-n7qyrdr1.js";import"./index-1hnw0rhc.js";import"./index-6jzsthh9.js";import"./index-g8zv1gta.js";import"./index-qfz9fy56.js";import"./index-ssjmzqcz.js";import"./index-tp4y9jde.js";import"./index-4wgjx8bf.js";import"./index-g3ap3xpr.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import"./index-yrgm89r8.js";import"./index-52cp759f.js";import"./index-v9fx5wab.js";import"./index-01qzsnwd.js";import"./index-d5ysy1yn.js";import"./index-04n4qgvd.js";import"./index-xjzmb1pn.js";import"./index-g2raeeh4.js";import"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";export{a as createApp};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{t as a}from"./index-6jq17k9s.js";import"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";export{a as bootstrapWorkspace};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{O as a,P as b}from"./index-e1bw1bwr.js";import"./index-yy1mm8zs.js";export{b as installDependencies,a as checkDependencies};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{Hd as K,Nd as D}from"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";var b="bridge-client",U=2000,G=30000,N=30000,O=6,z={ws:null,pingTimer:null,reconnectTimer:null,reconnectAttempt:0,connected:!1,stopped:!1,agentId:null,profile:"default",pendingEvents:[]};function Z(J,Q,$){D().logger[J](b,Q,$)}function C(J){try{let Q=new URL(J);Q.protocol=Q.protocol==="https:"?"wss:":"ws:",Q.pathname="/agent-bridge",Q.search="",Q.hash="";let $=process.env.VIBE_BRIDGE_URL;if($)return $;return Q.toString()}catch{return process.env.VIBE_BRIDGE_URL??""}}async function x(){if(z.stopped||z.ws)return;if(!K.isConfigured()){Z("debug","Gateway client not configured yet; deferring bridge connect");return}if(!z.agentId){Z("debug","No agentId set yet; deferring bridge connect");return}let J,Q,$;try{let Y=await K.getAccessToken();J=Y.token,Q=Y.workspaceGatewayUrl,$=Y.workspaceId}catch(Y){Z("warn","Failed to fetch access token for bridge",{error:Y instanceof Error?Y.message:String(Y)}),W();return}if(!J||!Q){W();return}let q=C(Q);if(!q){Z("warn","Cannot resolve bridge URL from workspaceGatewayUrl",{workspaceGatewayUrl:Q}),W();return}Z("info","Connecting to agent-bridge",{url:q,agentId:z.agentId});let H;try{H=new WebSocket(q,{headers:{Authorization:`Bearer ${J}`,...$?{"x-workspace-id":$}:{}}})}catch(Y){Z("warn","Bridge connect threw",{error:Y instanceof Error?Y.message:String(Y)}),W();return}z.ws=H,H.addEventListener("open",()=>{z.reconnectAttempt=0,Z("info","Bridge socket open \u2014 sending hello"),X({type:"hello",agentId:z.agentId,profile:z.profile,version:process.env.npm_package_version??"unknown"})}),H.addEventListener("message",(Y)=>{let B=typeof Y.data==="string"?Y.data:Y.data instanceof Blob?"":new TextDecoder().decode(Y.data);if(!B)return;let V;try{V=JSON.parse(B)}catch{return}if(V.type==="welcome")z.connected=!0,Z("info","Bridge welcome received \u2014 connection ready",{workspaceId:typeof V.workspaceId==="string"?V.workspaceId:void 0}),L(),P();else if(V.type==="error")Z("warn","Bridge error frame",{error:V})}),H.addEventListener("close",(Y)=>{if(Z("info","Bridge socket closed",{code:Y.code,reason:Y.reason}),M(),!z.stopped)W()}),H.addEventListener("error",(Y)=>{Z("warn","Bridge socket error",{message:Y.message})})}function X(J){if(!z.ws||z.ws.readyState!==1)return!1;try{return z.ws.send(JSON.stringify(J)),!0}catch(Q){return Z("debug","safeSend failed",{error:Q instanceof Error?Q.message:String(Q)}),!1}}function L(){F(),z.pingTimer=setInterval(()=>{X({type:"ping"})},N),z.pingTimer.unref?.()}function F(){if(z.pingTimer)clearInterval(z.pingTimer),z.pingTimer=null}function M(){z.connected=!1,F(),z.ws=null}function W(){if(z.stopped||z.reconnectTimer)return;let J=z.reconnectAttempt+1,Q=Math.min(U*2**Math.min(J-1,5),G);if(z.reconnectAttempt=J,J===O)Z("warn",`Bridge unavailable after ${J} attempts \u2014 falling back to existing HTTP polling for heartbeat/tunnel sync. Will keep retrying in the background.`);z.reconnectTimer=setTimeout(()=>{z.reconnectTimer=null,x()},Q),z.reconnectTimer.unref?.()}function P(){if(!z.connected)return;while(z.pendingEvents.length>0){let J=z.pendingEvents.shift();if(!X({type:J.type,...J.payload})){z.pendingEvents.unshift(J);return}}}var R=500;function j(J){if(z.connected&&X({type:J.type,...J.payload}))return;if(z.pendingEvents.length>=R)z.pendingEvents.shift();z.pendingEvents.push(J)}var I={start(J,Q){if(z.stopped=!1,z.agentId===J&&z.connected)return;z.agentId=J,z.profile=Q||"default",x()},stop(){if(z.stopped=!0,z.reconnectTimer)clearTimeout(z.reconnectTimer),z.reconnectTimer=null;let J=z.ws;try{J?.close(1000,"agent shutdown")}catch{}M()},publishEvent(J){j({type:"event",payload:{topic:J.topic,payload:J.payload}})},publishLog(J){j({type:"log",payload:{payload:J}})},isConnected(){return z.connected},isFallbackEngaged(){return z.reconnectAttempt>=O&&!z.connected}};export{I as bridgeClient};
package/dist/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ import{H as O}from"./index-mxc61yr1.js";import{I as Q,J as w}from"./index-3ys16efc.js";import"./index-2gsarrbn.js";import"./index-b5dhmybd.js";import"./index-e1bw1bwr.js";import"./index-g8zv1gta.js";import"./index-qfz9fy56.js";import"./index-ssjmzqcz.js";import{wa as Z,za as I}from"./index-tp4y9jde.js";import{Aa as G,Ba as H}from"./index-4wgjx8bf.js";import{Wa as J}from"./index-g3ap3xpr.js";import{Xa as U}from"./index-0ckffygp.js";import"./index-rc79x8fw.js";import{bb as K}from"./index-yrgm89r8.js";import"./index-52cp759f.js";import"./index-01qzsnwd.js";import"./index-d5ysy1yn.js";import"./index-04n4qgvd.js";import{cc as $}from"./index-2xs9cvjn.js";import"./index-5mw3eshk.js";import{mc as E}from"./index-z5a4yxzz.js";import"./index-ef95xr4z.js";import"./index-xjzmb1pn.js";import"./index-g2raeeh4.js";import{Nd as Y}from"./index-9bqd8veb.js";import{_d as W,ce as X}from"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";import{join as B}from"path";if(typeof Bun>"u")console.error(`\x1B[31mError:\x1B[0m VibeControls Agent requires the Bun runtime.
4
+ Install Bun: https://bun.sh
5
+ Then run: bun run vibe ...`),process.exit(1);var T=process.argv.slice(2),_=T.includes("--plain")||T.includes("--json")||process.env.NO_COLOR==="1"||!process.stdout.isTTY;E(!_);try{O()}catch{}var N="1.0.0";try{let q=B(import.meta.dir,"..","package.json");N=(await Bun.file(q).json()).version}catch{}var x=new $;x.name("vibe").description("VibeControls Agent CLI \u2014 Remote development environment management").version(N,"-v, --version").option("--provider <name>","Override the default provider for tunnel/session operations").option("-p, --profile <name>","Target a specific profile (one-off; doesn't change the persisted default). See `vibe profile`.").option("--json","Emit machine-readable JSON instead of human output.").option("--plain","Force plain-text output (no interactive UI).").hook("preAction",(q,z)=>{let F=q.opts().profile;if(F)process.env.VIBECONTROLS_PROFILE=F;try{K.init(),K.emit("command.executed",{command_name:z.name()})}catch{}});w(x);async function M(){let q=new J;try{await q.loadCorePlugins()}catch{}try{await q.loadAll()}catch{}let z=new Z,F={storage:{async get(){return null},async set(){},async delete(){return!1},async list(){return[]},async deleteAll(){return 0}},logger:Y().logger,serviceRegistry:z,getProvider:(L)=>z.getProvider(L),getAgentBaseUrl:()=>process.env.AGENT_URL||"http://localhost:3005",getAgentVersion:()=>N,broadcast:()=>{},workspaceQuery:async()=>({data:void 0,errors:[{message:"workspaceQuery is not available in CLI mode"}]}),isGatewayConfigured:()=>!1,getAgentRecordId:async()=>null,getWorkspaceId:async()=>null,getConfig:async()=>{return},getPluginRegistry:()=>X(),getDataDir:()=>W(),cliContributors:new G,telemetry:{emit:(L,D)=>{try{K.emit(L,D??{})}catch{}}},os:U(),iframeBridge:I()};H(F.cliContributors);try{await q.dispatchCliSetup(x,F)}catch{}x.configureHelp({formatHelp:()=>Q(x,!0)}),await x.parseAsync()}M().then(()=>{process.exit(process.exitCode??0)}).catch((q)=>{console.error(`\x1B[31mFatal:\x1B[0m ${q instanceof Error?q.message:q}`),process.exit(1)});
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{Ld as a,Md as b,Nd as c,Od as d,Pd as e}from"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";export{a as profileRegistry,d as getOrCreateProfile,c as getDaemonProfile,b as ensureDaemonProfile,e as __resetDaemonProfileForTests};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{$b as e,Xb as a,Yb as b,Zb as c,_b as d,ac as f,bc as g,cc as h,dc as i,ec as j,fc as k}from"./index-2xs9cvjn.js";import"./index-yy1mm8zs.js";export{a as program,d as createOption,b as createCommand,c as createArgument,j as Option,g as InvalidOptionArgumentError,f as InvalidArgumentError,k as Help,e as CommanderError,h as Command,i as Argument};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index-yy1mm8zs.js";var e=null;function n(t){e=t}function r(){return e}export{n as setFinalizeRetryHandle,r as getFinalizeRetryHandle};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{Nd as Y}from"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";var Z=[300000,600000,900000,1800000];function j(R){let W=R.backoffsMs??Z,w=0,z=!1,G=null,J=null,I=null,q=Y();if(q.getBootState()==="ready")return{cancel(){},async forceRetryNow(){return{ok:!0}},getState(){return{attempt:0,cancelled:!0,nextAttemptAt:null}}};function Q(){if(G!==null)clearTimeout(G),G=null,J=null}function X(){if(z)return Promise.resolve({ok:!1,error:"retry worker cancelled"});if(q.getBootState()==="ready")return z=!0,Q(),Promise.resolve({ok:!0});if(I)return I;return w+=1,R.onAttempt?.(w),q.logger.info("finalize-retry",`Background finalize retry attempt ${w}`),I=(async()=>{try{let v=await R.trigger();if(v.ok)q.logger.info("finalize-retry",`Background finalize succeeded on attempt ${w} \u2014 agent recovered`),z=!0,Q();else q.recordFinalizeError(v.error,w),q.logger.warn("finalize-retry",`Background finalize attempt ${w} failed`,{error:v.error});return v}catch(v){let H=v instanceof Error?v.message:String(v);return q.recordFinalizeError(H,w),q.logger.error("finalize-retry",`Background finalize attempt ${w} threw`,{error:H}),{ok:!1,error:H}}finally{I=null}})(),I}function V(){if(z)return;if(q.getBootState()==="ready"){z=!0;return}if(G!==null)return;let v=Math.min(w,W.length-1),H=W[v];J=Date.now()+H,G=setTimeout(async()=>{if(G=null,await X(),!z&&q.getBootState()!=="ready")V()},H)}return V(),{cancel(){z=!0,Q()},async forceRetryNow(){if(q.getBootState()==="ready")return{ok:!0};if(z)return{ok:!1,error:"retry worker cancelled"};Q();let v=await X();if(!z&&q.getBootState()!=="ready")V();return v},getState(){return{attempt:w,cancelled:z,nextAttemptAt:J?new Date(J).toISOString():null}}}}export{j as startFinalizeRetryWorker};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{Fd as a,Gd as b,Hd as c,Id as d}from"./index-9bqd8veb.js";import"./index-0cn9bv8z.js";import"./index-jw1k4vbk.js";import"./index-yy1mm8zs.js";export{a as normalizeGatewayUrl,c as gatewayClient,d as default,b as GatewayClient};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{f as D}from"./index-8sm0nkh8.js";import{g as C}from"./index-x1h8r7pr.js";import{fe as z,he as B}from"./index-yy1mm8zs.js";var H=z((v)=>{Object.defineProperty(v,"__esModule",{value:!0});v.getMachineId=void 0;var E=B("fs"),F=D(),q=C();async function G(){try{return(await E.promises.readFile("/etc/hostid",{encoding:"utf8"})).trim()}catch(k){q.diag.debug(`error reading machine id: ${k}`)}try{return(await(0,F.execAsync)("kenv -q smbios.system.uuid")).stdout.trim()}catch(k){q.diag.debug(`error reading machine id: ${k}`)}return}v.getMachineId=G});export default H();