dejima 0.5.1
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 +58 -0
- package/bin/dejima.js +26 -0
- package/install.js +155 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# dejima (CLI)
|
|
2
|
+
|
|
3
|
+
The `dejima` command-line client, installable from npm. Drives a [Dejima](https://dejima.tech/)
|
|
4
|
+
host — create islands, connect to agents, run one-shot commands — from macOS, Linux, or Windows.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npm install -g dejima
|
|
8
|
+
dejima --version
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
On install, this package downloads the prebuilt `dejima` binary matching its
|
|
12
|
+
version from the [GitHub Release](https://github.com/aoos/dejima/releases),
|
|
13
|
+
checksum-verifies it, and puts a `dejima` command on your PATH. No Go toolchain
|
|
14
|
+
required.
|
|
15
|
+
|
|
16
|
+
## What this installs (and what it doesn't)
|
|
17
|
+
|
|
18
|
+
This package ships the **CLI client only** — the cross-platform binary you use to
|
|
19
|
+
drive a host. That's all most people on a laptop need:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
export DEJIMA_HOST=your-host.tailnet.ts.net:7273
|
|
23
|
+
dejima ls
|
|
24
|
+
dejima connect <island>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It does **not** install the daemon (`dejimad`) or the island Docker image. Those
|
|
28
|
+
run only on a Unix **host** (your Mac mini / Linux box) and need Docker. Set a
|
|
29
|
+
host up with:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
curl -fsSL https://dejima.tech/install.sh | bash # full host: binaries + image + service
|
|
33
|
+
# or
|
|
34
|
+
brew install aoos/dejima/dejima # binaries via Homebrew
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
See <https://dejima.tech/> for the full picture.
|
|
38
|
+
|
|
39
|
+
## Other install channels
|
|
40
|
+
|
|
41
|
+
| Command | Gets you |
|
|
42
|
+
|---------|----------|
|
|
43
|
+
| `npm install -g dejima` | the CLI client (this package) |
|
|
44
|
+
| `brew install aoos/dejima/dejima` | CLI + daemon binaries |
|
|
45
|
+
| `curl -fsSL https://dejima.tech/install.sh \| bash` | full host (binaries + image + service) |
|
|
46
|
+
|
|
47
|
+
## Environment knobs
|
|
48
|
+
|
|
49
|
+
- `DEJIMA_SKIP_DOWNLOAD=1` — skip the postinstall download (offline / sandboxed
|
|
50
|
+
CI). Provide your own binary at runtime with `DEJIMA_BINARY=/path/to/dejima`.
|
|
51
|
+
- `DEJIMA_BINARY=/path/to/dejima` — run a specific binary instead of the
|
|
52
|
+
downloaded one.
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
|
|
56
|
+
- Requires Node 16+ and a `tar` on PATH (bundled on macOS, Linux, and Windows 10+).
|
|
57
|
+
- macOS binaries are currently unsigned; the installer strips the Gatekeeper
|
|
58
|
+
quarantine attribute on download. Notarization is on the roadmap.
|
package/bin/dejima.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin shim: exec the dejima binary that install.js placed in ../binary/,
|
|
3
|
+
// forwarding argv, stdio, and the exit code. Lets `npm install -g dejima`
|
|
4
|
+
// expose a real `dejima` command on PATH.
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { spawnSync } = require('child_process');
|
|
10
|
+
|
|
11
|
+
const exe = process.platform === 'win32' ? 'dejima.exe' : 'dejima';
|
|
12
|
+
const binary = process.env.DEJIMA_BINARY || path.join(__dirname, '..', 'binary', exe);
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(binary)) {
|
|
15
|
+
console.error(`dejima: binary not found at ${binary}`);
|
|
16
|
+
console.error('The postinstall download may have failed. Reinstall the package, or');
|
|
17
|
+
console.error('set DEJIMA_BINARY to the path of a dejima binary you provide yourself.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
|
|
22
|
+
if (result.error) {
|
|
23
|
+
console.error(`dejima: ${result.error.message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Postinstall hook for the `dejima` npm package.
|
|
3
|
+
//
|
|
4
|
+
// Downloads the dejima CLI binary that matches this package's version from the
|
|
5
|
+
// GitHub Release, verifies its SHA256 against the release's SHA256SUMS, and
|
|
6
|
+
// unpacks it into ./binary/. The bin shim (bin/dejima.js) execs it.
|
|
7
|
+
//
|
|
8
|
+
// This package ships only the CLI *client* — the cross-platform binary you
|
|
9
|
+
// drive a Dejima host with. The daemon (dejimad) and the island image are
|
|
10
|
+
// Unix-host-only; install those with `curl -fsSL https://dejima.tech/install.sh
|
|
11
|
+
// | bash` or Homebrew. See README.md.
|
|
12
|
+
//
|
|
13
|
+
// Knobs:
|
|
14
|
+
// DEJIMA_SKIP_DOWNLOAD=1 skip the download (e.g. offline CI); provide your
|
|
15
|
+
// own binary via DEJIMA_BINARY at runtime instead.
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
const https = require('https');
|
|
21
|
+
const crypto = require('crypto');
|
|
22
|
+
const { execFileSync } = require('child_process');
|
|
23
|
+
|
|
24
|
+
const REPO = 'aoos/dejima';
|
|
25
|
+
const pkg = require('./package.json');
|
|
26
|
+
const version = String(pkg.version).replace(/^v/, '');
|
|
27
|
+
const tag = `v${version}`;
|
|
28
|
+
|
|
29
|
+
if (process.env.DEJIMA_SKIP_DOWNLOAD === '1') {
|
|
30
|
+
console.log('dejima: DEJIMA_SKIP_DOWNLOAD=1 set — skipping binary download.');
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function mapPlatform() {
|
|
35
|
+
switch (process.platform) {
|
|
36
|
+
case 'darwin': return 'darwin';
|
|
37
|
+
case 'linux': return 'linux';
|
|
38
|
+
case 'win32': return 'windows';
|
|
39
|
+
default: throw new Error(`unsupported platform: ${process.platform}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function mapArch() {
|
|
43
|
+
switch (process.arch) {
|
|
44
|
+
case 'x64': return 'amd64';
|
|
45
|
+
case 'arm64': return 'arm64';
|
|
46
|
+
default: throw new Error(`unsupported arch: ${process.arch}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const plat = mapPlatform();
|
|
51
|
+
const arch = mapArch();
|
|
52
|
+
const ext = plat === 'windows' ? 'zip' : 'tar.gz';
|
|
53
|
+
const asset = `dejima_${tag}_${plat}_${arch}.${ext}`;
|
|
54
|
+
const base = `https://github.com/${REPO}/releases/download/${tag}`;
|
|
55
|
+
|
|
56
|
+
// GET that follows redirects (GitHub release assets 302 to a CDN) and buffers
|
|
57
|
+
// the body. Caps redirects so a misconfigured mirror can't loop forever.
|
|
58
|
+
function get(url, redirects = 0) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
if (redirects > 10) return reject(new Error('too many redirects'));
|
|
61
|
+
https
|
|
62
|
+
.get(url, { headers: { 'User-Agent': 'dejima-npm-installer' } }, (res) => {
|
|
63
|
+
const { statusCode, headers } = res;
|
|
64
|
+
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
65
|
+
res.resume();
|
|
66
|
+
resolve(get(headers.location, redirects + 1));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (statusCode !== 200) {
|
|
70
|
+
res.resume();
|
|
71
|
+
reject(new Error(`GET ${url} -> HTTP ${statusCode}`));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const chunks = [];
|
|
75
|
+
res.on('data', (c) => chunks.push(c));
|
|
76
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
77
|
+
})
|
|
78
|
+
.on('error', reject);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function verifyChecksum(tarball) {
|
|
83
|
+
let sums;
|
|
84
|
+
try {
|
|
85
|
+
sums = (await get(`${base}/SHA256SUMS`)).toString('utf8');
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.warn(`dejima: could not fetch SHA256SUMS (${e.message}) — skipping checksum.`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const row = sums
|
|
91
|
+
.split('\n')
|
|
92
|
+
.map((l) => l.trim().split(/\s+/))
|
|
93
|
+
.find((p) => p[1] === asset);
|
|
94
|
+
if (!row) {
|
|
95
|
+
console.warn(`dejima: ${asset} not listed in SHA256SUMS — skipping checksum.`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const got = crypto.createHash('sha256').update(tarball).digest('hex');
|
|
99
|
+
if (got !== row[0]) {
|
|
100
|
+
throw new Error(`checksum mismatch for ${asset}\n want ${row[0]}\n got ${got}`);
|
|
101
|
+
}
|
|
102
|
+
console.log('dejima: checksum OK');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function main() {
|
|
106
|
+
const binDir = path.join(__dirname, 'binary');
|
|
107
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
108
|
+
|
|
109
|
+
console.log(`dejima: downloading ${asset} …`);
|
|
110
|
+
const tarball = await get(`${base}/${asset}`);
|
|
111
|
+
await verifyChecksum(tarball);
|
|
112
|
+
|
|
113
|
+
// Unpack with the system tar. bsdtar (Windows 10+ `tar.exe`) reads .zip too;
|
|
114
|
+
// gnutar/bsdtar read .tar.gz on Unix. Archives carry dejima (+ dejimad on
|
|
115
|
+
// Unix, which we leave unused) and LICENSE/README.
|
|
116
|
+
const archivePath = path.join(binDir, asset);
|
|
117
|
+
fs.writeFileSync(archivePath, tarball);
|
|
118
|
+
const flags = ext === 'tar.gz' ? ['-xzf'] : ['-xf'];
|
|
119
|
+
execFileSync('tar', [...flags, archivePath, '-C', binDir], { stdio: 'inherit' });
|
|
120
|
+
fs.unlinkSync(archivePath);
|
|
121
|
+
|
|
122
|
+
const exe = plat === 'windows' ? 'dejima.exe' : 'dejima';
|
|
123
|
+
const exePath = path.join(binDir, exe);
|
|
124
|
+
if (!fs.existsSync(exePath)) {
|
|
125
|
+
throw new Error(`expected ${exe} in ${asset}, but it was not found after extraction`);
|
|
126
|
+
}
|
|
127
|
+
if (plat !== 'windows') fs.chmodSync(exePath, 0o755);
|
|
128
|
+
|
|
129
|
+
// Drop the extras the archive carries (dejimad, LICENSE, README) — this
|
|
130
|
+
// package is the CLI client only, so keep just the one binary.
|
|
131
|
+
for (const f of fs.readdirSync(binDir)) {
|
|
132
|
+
if (f !== exe) fs.rmSync(path.join(binDir, f), { force: true });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Strip the macOS quarantine xattr — binaries are unsigned until notarization
|
|
136
|
+
// lands, so Gatekeeper would otherwise block the downloaded executable.
|
|
137
|
+
if (plat === 'darwin') {
|
|
138
|
+
try {
|
|
139
|
+
execFileSync('xattr', ['-d', 'com.apple.quarantine', exePath], { stdio: 'ignore' });
|
|
140
|
+
} catch (_) {
|
|
141
|
+
/* attribute may be absent; ignore */
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(`dejima ${version} installed → ${exePath}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
main().catch((err) => {
|
|
149
|
+
console.error(`\ndejima: install failed: ${err.message}\n`);
|
|
150
|
+
console.error('Alternatives:');
|
|
151
|
+
console.error(' • curl -fsSL https://dejima.tech/install-client.sh | bash');
|
|
152
|
+
console.error(' • brew install aoos/dejima/dejima');
|
|
153
|
+
console.error(' • set DEJIMA_SKIP_DOWNLOAD=1 and point DEJIMA_BINARY at a dejima binary.');
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dejima",
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "CLI for Dejima — run a fleet of isolated AI coding agents on hardware you own.",
|
|
5
|
+
"license": "Pre-public-release",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dejima": "bin/dejima.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node ./install.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/dejima.js",
|
|
14
|
+
"install.js",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16"
|
|
19
|
+
},
|
|
20
|
+
"os": [
|
|
21
|
+
"darwin",
|
|
22
|
+
"linux",
|
|
23
|
+
"win32"
|
|
24
|
+
],
|
|
25
|
+
"cpu": [
|
|
26
|
+
"x64",
|
|
27
|
+
"arm64"
|
|
28
|
+
],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"dejima",
|
|
31
|
+
"ai-agents",
|
|
32
|
+
"claude-code",
|
|
33
|
+
"codex",
|
|
34
|
+
"cli",
|
|
35
|
+
"self-hosted",
|
|
36
|
+
"sandbox"
|
|
37
|
+
],
|
|
38
|
+
"homepage": "https://dejima.tech/",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/aoos/dejima.git",
|
|
42
|
+
"directory": "npm"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/aoos/dejima/issues"
|
|
46
|
+
}
|
|
47
|
+
}
|