vibora 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -12
- package/bin/vibora.js +0 -46
- package/dist/assets/{index-r4Upl2GW.js → index-B_0ZMwER.js} +93 -93
- package/dist/assets/index-D643AGV4.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/index.js +599 -1010
- package/dist/assets/index-C9swvEK_.css +0 -1
package/README.md
CHANGED
|
@@ -144,17 +144,18 @@ For Claude Desktop, add to your `claude_desktop_config.json`:
|
|
|
144
144
|
|
|
145
145
|
Run the backend on a remote server and connect from anywhere. Launch tasks, close your laptop, and your agents keep working. As AI becomes more capable of autonomous work, this becomes essential.
|
|
146
146
|
|
|
147
|
-
1. **
|
|
147
|
+
1. **Set up a secure tunnel** — Use Tailscale (recommended) or Cloudflare Tunnels to securely expose your server
|
|
148
|
+
- **Tailscale** — Works with both web and desktop app. No CORS configuration needed.
|
|
149
|
+
- **Cloudflare Tunnels** — Alternative for web-only usage. Note: Desktop app has CORS limitations with Cloudflare Tunnels.
|
|
150
|
+
|
|
151
|
+
2. **On the remote server:**
|
|
148
152
|
```bash
|
|
149
153
|
npx vibora@latest up
|
|
150
|
-
vibora config set remoteHost your-server.example.com
|
|
151
|
-
vibora config set basicAuthUsername admin
|
|
152
|
-
vibora config set basicAuthPassword your-secure-password
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
3. **Connect from desktop app** — Click "Connect to Remote" and enter the server URL (e.g., `http://your-server.tailnet.ts.net:7777`)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
4. **Or access via browser** — Open the tunnel URL in your browser
|
|
158
159
|
|
|
159
160
|
<details>
|
|
160
161
|
<summary><strong>Configuration</strong></summary>
|
|
@@ -171,8 +172,6 @@ Settings are stored in `.vibora/settings.json`. The vibora directory is resolved
|
|
|
171
172
|
| defaultGitReposDir | `VIBORA_GIT_REPOS_DIR` | ~ |
|
|
172
173
|
| remoteHost | `VIBORA_REMOTE_HOST` | (empty) |
|
|
173
174
|
| sshPort | `VIBORA_SSH_PORT` | 22 |
|
|
174
|
-
| basicAuthUsername | `VIBORA_BASIC_AUTH_USERNAME` | null |
|
|
175
|
-
| basicAuthPassword | `VIBORA_BASIC_AUTH_PASSWORD` | null |
|
|
176
175
|
| linearApiKey | `LINEAR_API_KEY` | null |
|
|
177
176
|
| githubPat | `GITHUB_PAT` | null |
|
|
178
177
|
| language | — | null (auto-detect) |
|
|
@@ -185,10 +184,6 @@ Precedence: environment variable → settings.json → default
|
|
|
185
184
|
|
|
186
185
|
Vibora can sync task status with Linear tickets. Configure `linearApiKey` in settings or set `LINEAR_API_KEY`. When a task is linked to a Linear ticket, status changes in Vibora automatically update Linear.
|
|
187
186
|
|
|
188
|
-
### Basic Auth
|
|
189
|
-
|
|
190
|
-
Set `basicAuthUsername` and `basicAuthPassword` to require authentication when exposing Vibora over a network.
|
|
191
|
-
|
|
192
187
|
</details>
|
|
193
188
|
|
|
194
189
|
<details>
|
package/bin/vibora.js
CHANGED
|
@@ -43,23 +43,6 @@ function getPortFromSettings(settings) {
|
|
|
43
43
|
}
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
|
-
function getAuthFromSettings(settings) {
|
|
47
|
-
if (!settings)
|
|
48
|
-
return null;
|
|
49
|
-
if (settings.authentication?.username && settings.authentication?.password) {
|
|
50
|
-
return {
|
|
51
|
-
username: settings.authentication.username,
|
|
52
|
-
password: settings.authentication.password
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
if (settings.basicAuthUsername && settings.basicAuthPassword) {
|
|
56
|
-
return {
|
|
57
|
-
username: settings.basicAuthUsername,
|
|
58
|
-
password: settings.basicAuthPassword
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
46
|
function expandPath(p) {
|
|
64
47
|
if (p.startsWith("~/")) {
|
|
65
48
|
return join(homedir(), p.slice(2));
|
|
@@ -117,21 +100,6 @@ function getViboraDir() {
|
|
|
117
100
|
}
|
|
118
101
|
return join(homedir(), ".vibora");
|
|
119
102
|
}
|
|
120
|
-
function getAuthCredentials() {
|
|
121
|
-
const settingsPaths = [
|
|
122
|
-
process.env.VIBORA_DIR && join(expandPath(process.env.VIBORA_DIR), "settings.json"),
|
|
123
|
-
join(process.cwd(), ".vibora", "settings.json"),
|
|
124
|
-
join(homedir(), ".vibora", "settings.json")
|
|
125
|
-
].filter(Boolean);
|
|
126
|
-
for (const path of settingsPaths) {
|
|
127
|
-
const settings = readSettingsFile(path);
|
|
128
|
-
const auth = getAuthFromSettings(settings);
|
|
129
|
-
if (auth) {
|
|
130
|
-
return auth;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
103
|
var DEFAULT_PORT = 7777;
|
|
136
104
|
var init_server = () => {};
|
|
137
105
|
|
|
@@ -171,16 +139,8 @@ var init_errors = __esm(() => {
|
|
|
171
139
|
// cli/src/client.ts
|
|
172
140
|
class ViboraClient {
|
|
173
141
|
baseUrl;
|
|
174
|
-
authHeader;
|
|
175
142
|
constructor(urlOverride, portOverride) {
|
|
176
143
|
this.baseUrl = discoverServerUrl(urlOverride, portOverride);
|
|
177
|
-
const credentials = getAuthCredentials();
|
|
178
|
-
if (credentials) {
|
|
179
|
-
const encoded = btoa(`${credentials.username}:${credentials.password}`);
|
|
180
|
-
this.authHeader = `Basic ${encoded}`;
|
|
181
|
-
} else {
|
|
182
|
-
this.authHeader = null;
|
|
183
|
-
}
|
|
184
144
|
}
|
|
185
145
|
async fetch(path, options) {
|
|
186
146
|
const url = `${this.baseUrl}${path}`;
|
|
@@ -188,17 +148,11 @@ class ViboraClient {
|
|
|
188
148
|
"Content-Type": "application/json",
|
|
189
149
|
...options?.headers
|
|
190
150
|
};
|
|
191
|
-
if (this.authHeader) {
|
|
192
|
-
headers["Authorization"] = this.authHeader;
|
|
193
|
-
}
|
|
194
151
|
try {
|
|
195
152
|
const res = await fetch(url, {
|
|
196
153
|
...options,
|
|
197
154
|
headers
|
|
198
155
|
});
|
|
199
|
-
if (res.status === 401) {
|
|
200
|
-
throw new ApiError(401, "Authentication required. Configure basicAuthUsername and basicAuthPassword in settings.json");
|
|
201
|
-
}
|
|
202
156
|
if (!res.ok) {
|
|
203
157
|
const body = await res.json().catch(() => ({}));
|
|
204
158
|
throw new ApiError(res.status, body.error || body.message || `Request failed: ${res.status}`);
|