vibebox 0.0.0 → 0.0.2
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/Dockerfile +86 -0
- package/LICENSE.md +187 -0
- package/README.md +155 -2
- package/container-scripts/port-monitor.sh +37 -0
- package/container-scripts/startup.sh +109 -0
- package/container-scripts/watcher.sh +46 -0
- package/dist/agents/auth.js +77 -0
- package/dist/agents/claude/index.js +176 -0
- package/dist/agents/index.js +24 -0
- package/dist/agents/types.js +2 -0
- package/dist/auth.js +11 -0
- package/dist/index.js +883 -0
- package/dist/update.js +256 -0
- package/package.json +25 -24
- package/.dockerignore +0 -13
- package/LICENSE +0 -1
package/dist/update.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.hashString = hashString;
|
|
37
|
+
exports.getExpectedBuildHash = getExpectedBuildHash;
|
|
38
|
+
exports.getImageBuildHash = getImageBuildHash;
|
|
39
|
+
exports.checkForUpdates = checkForUpdates;
|
|
40
|
+
exports.checkVersions = checkVersions;
|
|
41
|
+
const node_child_process_1 = require("node:child_process");
|
|
42
|
+
const node_readline_1 = require("node:readline");
|
|
43
|
+
const node_fs_1 = require("node:fs");
|
|
44
|
+
const node_crypto_1 = require("node:crypto");
|
|
45
|
+
const node_path_1 = require("node:path");
|
|
46
|
+
function getVersion(cmd) {
|
|
47
|
+
const out = (0, node_child_process_1.execSync)(cmd, { encoding: "utf8" });
|
|
48
|
+
const match = out.match(/^(\d+\.\d+\.\d+(-[^\s]+)?)/);
|
|
49
|
+
return match ? match[1] : out.trim();
|
|
50
|
+
}
|
|
51
|
+
function parseSemVer(version) {
|
|
52
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(-([^\s]+))?$/);
|
|
53
|
+
if (!match)
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
major: parseInt(match[1], 10),
|
|
57
|
+
minor: parseInt(match[2], 10),
|
|
58
|
+
patch: parseInt(match[3], 10),
|
|
59
|
+
prerelease: match[5] || "",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function compareVersions(v1, v2) {
|
|
63
|
+
const a = parseSemVer(v1);
|
|
64
|
+
const b = parseSemVer(v2);
|
|
65
|
+
if (!a || !b)
|
|
66
|
+
return 0; // Can't compare, treat as equal
|
|
67
|
+
if (a.major !== b.major)
|
|
68
|
+
return a.major - b.major;
|
|
69
|
+
if (a.minor !== b.minor)
|
|
70
|
+
return a.minor - b.minor;
|
|
71
|
+
if (a.patch !== b.patch)
|
|
72
|
+
return a.patch - b.patch;
|
|
73
|
+
// Handle prerelease: no prerelease > prerelease, then lexicographic
|
|
74
|
+
if (!a.prerelease && b.prerelease)
|
|
75
|
+
return 1;
|
|
76
|
+
if (a.prerelease && !b.prerelease)
|
|
77
|
+
return -1;
|
|
78
|
+
if (a.prerelease && b.prerelease) {
|
|
79
|
+
return a.prerelease.localeCompare(b.prerelease);
|
|
80
|
+
}
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
function promptUser(question) {
|
|
84
|
+
const rl = (0, node_readline_1.createInterface)({ input: process.stdin, output: process.stdout });
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
rl.question(question, (answer) => {
|
|
87
|
+
rl.close();
|
|
88
|
+
resolve(answer);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function updateHost(agentCommand, version) {
|
|
93
|
+
console.log(`\nUpdating host ${agentCommand}${version ? ` to ${version}` : " to latest"}...`);
|
|
94
|
+
const args = version ? ["install", version] : ["install"];
|
|
95
|
+
const result = (0, node_child_process_1.spawnSync)(agentCommand, args, {
|
|
96
|
+
stdio: "inherit",
|
|
97
|
+
});
|
|
98
|
+
if (result.status !== 0) {
|
|
99
|
+
throw new Error(`Failed to update host ${agentCommand}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function updateSandbox(sandboxName, agentCommand, version) {
|
|
103
|
+
console.log(`\nUpdating sandbox ${agentCommand}${version ? ` to ${version}` : " to latest"}...`);
|
|
104
|
+
const args = ["exec", "-it", sandboxName, agentCommand, "install"];
|
|
105
|
+
if (version)
|
|
106
|
+
args.push(version);
|
|
107
|
+
const result = (0, node_child_process_1.spawnSync)("docker", args, { stdio: "inherit" });
|
|
108
|
+
if (result.status !== 0) {
|
|
109
|
+
throw new Error(`Failed to update sandbox ${agentCommand}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function verifyVersionsMatch({ sandboxName, versionCommand, successMsg }) {
|
|
113
|
+
const newHost = getVersion(versionCommand);
|
|
114
|
+
const newSandbox = getVersion(`docker exec ${sandboxName} ${versionCommand}`);
|
|
115
|
+
if (newHost === newSandbox) {
|
|
116
|
+
console.log(`\nSuccess! ${successMsg} ${newHost}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.error(`\nWarning: Versions still differ after update. Host: ${newHost}, Sandbox: ${newSandbox}`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// ============ Build Hash Functions ============
|
|
124
|
+
function hashString(content) {
|
|
125
|
+
return (0, node_crypto_1.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
126
|
+
}
|
|
127
|
+
function getExpectedBuildHash() {
|
|
128
|
+
try {
|
|
129
|
+
const pkgPath = (0, node_path_1.join)((0, node_path_1.dirname)(__dirname), "package.json");
|
|
130
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)(pkgPath, "utf8"));
|
|
131
|
+
return pkg.vibebox?.version?.build ?? null;
|
|
132
|
+
}
|
|
133
|
+
catch { }
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
function getImageBuildHash() {
|
|
137
|
+
try {
|
|
138
|
+
const out = (0, node_child_process_1.execFileSync)("docker", ["image", "inspect", "vibebox", "--format", '{{index .Config.Labels "vibebox.version.build"}}'], { encoding: "utf8" }).trim();
|
|
139
|
+
return out || null;
|
|
140
|
+
}
|
|
141
|
+
catch { }
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function getLatestNpmVersion() {
|
|
145
|
+
try {
|
|
146
|
+
return (0, node_child_process_1.execSync)("npm view vibebox version", { encoding: "utf8" }).trim();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function getCurrentVersion() {
|
|
153
|
+
const pkgPath = (0, node_path_1.join)((0, node_path_1.dirname)(__dirname), "package.json");
|
|
154
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)(pkgPath, "utf8"));
|
|
155
|
+
return pkg.version;
|
|
156
|
+
}
|
|
157
|
+
async function checkForUpdates() {
|
|
158
|
+
const currentVersion = getCurrentVersion();
|
|
159
|
+
const latestVersion = getLatestNpmVersion();
|
|
160
|
+
// Check npm version FIRST - if updated, new code will handle hash checks
|
|
161
|
+
if (latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
162
|
+
console.log(`\nvibebox update available: ${latestVersion} (current: ${currentVersion})`);
|
|
163
|
+
const answer = await promptUser(`\nUpdate now? [Y/n]: `);
|
|
164
|
+
if (answer.toLowerCase() !== "n") {
|
|
165
|
+
console.log("\nUpdating vibebox...");
|
|
166
|
+
const r = (0, node_child_process_1.spawnSync)("npm", ["install", "-g", "vibebox@latest"], { stdio: "inherit" });
|
|
167
|
+
if (r.status !== 0) {
|
|
168
|
+
console.error("Failed to update vibebox");
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
console.log("\nUpdate complete! Please run your command again.");
|
|
172
|
+
process.exit(0);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Check image build hash
|
|
176
|
+
const expectedHash = getExpectedBuildHash();
|
|
177
|
+
const imageHash = getImageBuildHash();
|
|
178
|
+
let needsRebuild = false;
|
|
179
|
+
if (expectedHash && imageHash && expectedHash !== imageHash) {
|
|
180
|
+
console.log("\nvibebox image is outdated (build files have changed)");
|
|
181
|
+
needsRebuild = true;
|
|
182
|
+
}
|
|
183
|
+
else if (expectedHash && !imageHash) {
|
|
184
|
+
// Image exists but has no/old hash label
|
|
185
|
+
try {
|
|
186
|
+
(0, node_child_process_1.execSync)("docker image inspect vibebox", { stdio: "pipe" });
|
|
187
|
+
console.log("\nvibebox image is outdated (missing build hash)");
|
|
188
|
+
needsRebuild = true;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// No image exists, will be built on first use
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (needsRebuild) {
|
|
195
|
+
const answer = await promptUser(`Rebuild image? [Y/n]: `);
|
|
196
|
+
if (answer.toLowerCase() !== "n") {
|
|
197
|
+
console.log("\nRebuilding vibebox image...");
|
|
198
|
+
try {
|
|
199
|
+
(0, node_child_process_1.execSync)("docker rmi vibebox", { stdio: "pipe" });
|
|
200
|
+
}
|
|
201
|
+
catch { }
|
|
202
|
+
const { buildImage } = await Promise.resolve().then(() => __importStar(require("./index")));
|
|
203
|
+
buildImage();
|
|
204
|
+
console.log("Image rebuilt!");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function checkVersions(sandboxName, agent) {
|
|
209
|
+
const versionCommand = agent?.versionCommand ?? "claude --version";
|
|
210
|
+
const agentName = agent?.name ?? "Claude Code";
|
|
211
|
+
const agentCommand = agent?.command ?? "claude";
|
|
212
|
+
try {
|
|
213
|
+
const host = getVersion(versionCommand);
|
|
214
|
+
const sandbox = getVersion(`docker exec ${sandboxName} ${versionCommand}`);
|
|
215
|
+
if (host !== sandbox) {
|
|
216
|
+
const comparison = compareVersions(host, sandbox);
|
|
217
|
+
const higher = comparison >= 0 ? host : sandbox;
|
|
218
|
+
console.error(`\n${agentName} version mismatch! Host: ${host}, Sandbox: ${sandbox}`);
|
|
219
|
+
const answer = await promptUser(`\nChoose update strategy:
|
|
220
|
+
[1] Sync to higher version (${higher})
|
|
221
|
+
[2] Update both to latest
|
|
222
|
+
[N] Cancel
|
|
223
|
+
|
|
224
|
+
Your choice: `);
|
|
225
|
+
if (answer === "1") {
|
|
226
|
+
// Sync to higher version
|
|
227
|
+
if (comparison >= 0) {
|
|
228
|
+
updateSandbox(sandboxName, agentCommand, host);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
updateHost(agentCommand, sandbox);
|
|
232
|
+
}
|
|
233
|
+
verifyVersionsMatch({ sandboxName, versionCommand, successMsg: "Both synced to" });
|
|
234
|
+
}
|
|
235
|
+
else if (answer === "2") {
|
|
236
|
+
// Update both to latest
|
|
237
|
+
updateHost(agentCommand);
|
|
238
|
+
updateSandbox(sandboxName, agentCommand);
|
|
239
|
+
verifyVersionsMatch({ sandboxName, versionCommand, successMsg: "Both updated to" });
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.error(`
|
|
243
|
+
Manual update options:
|
|
244
|
+
Update host: ${agentCommand} install
|
|
245
|
+
Update sandbox: vibebox exec ${agentCommand} install
|
|
246
|
+
Or recreate: vibebox rm && vibebox agent ${agentCommand}
|
|
247
|
+
|
|
248
|
+
Note: If using alias, run 'unalias ${agentCommand}' first or 'command ${agentCommand} install' (macOS and linux).`);
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
/* sandbox not running, skip */
|
|
255
|
+
}
|
|
256
|
+
}
|
package/package.json
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibebox",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"main": "dist/index.js",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
5
|
"bin": {
|
|
7
|
-
"vibebox": "./dist/
|
|
6
|
+
"vibebox": "./dist/index.js"
|
|
8
7
|
},
|
|
8
|
+
"files": [
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE.md",
|
|
11
|
+
"dist",
|
|
12
|
+
"Dockerfile",
|
|
13
|
+
"container-scripts"
|
|
14
|
+
],
|
|
9
15
|
"scripts": {
|
|
10
16
|
"build": "tsc",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
17
|
+
"postbuild": "chmod +x dist/index.js",
|
|
18
|
+
"build:image": "docker build -t vibebox .",
|
|
19
|
+
"rebuild": "tsc && node scripts/update-build-hashes.mjs && vibebox rm --all && vibebox rebuild",
|
|
20
|
+
"preversion": "npm run build && node scripts/update-build-hashes.mjs",
|
|
21
|
+
"prepublishOnly": "npm run build",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest"
|
|
13
24
|
},
|
|
14
|
-
"keywords": [
|
|
15
|
-
"cli",
|
|
16
|
-
"docker",
|
|
17
|
-
"claude",
|
|
18
|
-
"ai",
|
|
19
|
-
"sandbox"
|
|
20
|
-
],
|
|
21
|
-
"author": "",
|
|
22
|
-
"license": "",
|
|
23
25
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"commander": "^12.1.0",
|
|
26
|
-
"ora": "^5.4.1"
|
|
26
|
+
"commander": "^12.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"typescript": "^5.8.3"
|
|
29
|
+
"@types/node": "^22.0.0",
|
|
30
|
+
"typescript": "^5.0.0",
|
|
31
|
+
"vitest": "^3.0.0"
|
|
33
32
|
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
33
|
+
"vibebox": {
|
|
34
|
+
"version": {
|
|
35
|
+
"build": "bc83a65b541a24ce"
|
|
36
|
+
}
|
|
36
37
|
}
|
|
37
38
|
}
|
package/.dockerignore
DELETED
package/LICENSE
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2025-present (c) Giuseppe Gurgone
|