edgecrab-cli 0.1.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 +104 -0
- package/bin/edgecrab.js +34 -0
- package/package.json +39 -0
- package/scripts/install.js +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# edgecrab-cli (npm)
|
|
2
|
+
|
|
3
|
+
> **EdgeCrab** — Super Powerful Personal Assistant inspired by **NousHermes** and **OpenClaw**.
|
|
4
|
+
> Blazing-fast TUI · ReAct tool loop · Multi-provider LLM · ACP protocol · Single 15 MB static binary.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/edgecrab-cli)
|
|
7
|
+
[](https://github.com/raphaelmansuy/edgecrab/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Global install (recommended) — adds `edgecrab` to your PATH
|
|
15
|
+
npm install -g edgecrab-cli
|
|
16
|
+
|
|
17
|
+
# Or use without a global install
|
|
18
|
+
npx edgecrab-cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The postinstall script automatically downloads the correct pre-built Rust binary for
|
|
22
|
+
your platform (macOS arm64/x64, Linux x64/arm64, Windows x64) from
|
|
23
|
+
[GitHub Releases](https://github.com/raphaelmansuy/edgecrab/releases).
|
|
24
|
+
|
|
25
|
+
No Rust, GCC, or build tools are required.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# First-run setup wizard — detects API keys, writes ~/.edgecrab/config.yaml
|
|
33
|
+
edgecrab setup
|
|
34
|
+
|
|
35
|
+
# Verify your environment
|
|
36
|
+
edgecrab doctor
|
|
37
|
+
|
|
38
|
+
# Start the interactive TUI
|
|
39
|
+
edgecrab
|
|
40
|
+
|
|
41
|
+
# One-shot query (pipe-friendly)
|
|
42
|
+
edgecrab "summarise the git log for today"
|
|
43
|
+
|
|
44
|
+
# Pick a specific LLM provider
|
|
45
|
+
edgecrab --model anthropic/claude-opus-4 "explain this codebase"
|
|
46
|
+
|
|
47
|
+
# Stream output
|
|
48
|
+
edgecrab --quiet "write a Rust hello-world"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Why EdgeCrab?
|
|
54
|
+
|
|
55
|
+
EdgeCrab is a **Rust-native** autonomous coding agent and personal assistant, inspired by
|
|
56
|
+
the reasoning depth of **NousHermes** and the tool-use power of **OpenClaw**.
|
|
57
|
+
|
|
58
|
+
| Feature | Detail |
|
|
59
|
+
|---------|--------|
|
|
60
|
+
| **Single binary** | 15 MB static binary, < 50 ms startup, ~15 MB resident memory |
|
|
61
|
+
| **Multi-provider LLM** | Copilot · OpenAI · Anthropic · Gemini · xAI · DeepSeek · Ollama |
|
|
62
|
+
| **ReAct tool loop** | File, terminal, web search, memory, process, skill tools |
|
|
63
|
+
| **ratatui TUI** | 60 fps capable terminal UI with streaming output |
|
|
64
|
+
| **ACP protocol** | Built-in JSON-RPC 2.0 stdio adapter for VS Code Copilot |
|
|
65
|
+
| **Built-in security** | Path safety, SSRF protection, command scanning, output redaction |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Alternative Installation Methods
|
|
70
|
+
|
|
71
|
+
| Method | Command |
|
|
72
|
+
|--------|---------|
|
|
73
|
+
| **npm** | `npm install -g edgecrab-cli` |
|
|
74
|
+
| **PyPI** | `pip install edgecrab-cli` |
|
|
75
|
+
| **Cargo** | `cargo install edgecrab-cli` |
|
|
76
|
+
| **Docker** | `docker pull ghcr.io/raphaelmansuy/edgecrab:latest` |
|
|
77
|
+
| **Pre-built binary** | [GitHub Releases](https://github.com/raphaelmansuy/edgecrab/releases) |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Supported Platforms
|
|
82
|
+
|
|
83
|
+
| Platform | Architecture |
|
|
84
|
+
|----------|-------------|
|
|
85
|
+
| macOS | Apple Silicon (arm64) · Intel (x64) |
|
|
86
|
+
| Linux | x86_64 · arm64 |
|
|
87
|
+
| Windows | x64 |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Documentation
|
|
92
|
+
|
|
93
|
+
Full docs: **[edgecrab.com](https://www.edgecrab.com)**
|
|
94
|
+
|
|
95
|
+
- [Quick Start](https://www.edgecrab.com/getting-started/quick-start/)
|
|
96
|
+
- [Installation Guide](https://www.edgecrab.com/getting-started/installation/)
|
|
97
|
+
- [CLI Commands Reference](https://www.edgecrab.com/reference/cli-commands/)
|
|
98
|
+
- [Provider Setup](https://www.edgecrab.com/providers/)
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT © [Raphael Mansuy](https://github.com/raphaelmansuy)
|
package/bin/edgecrab.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Thin launcher for the EdgeCrab native binary.
|
|
4
|
+
*
|
|
5
|
+
* This script is the `bin` entry point for `edgecrab-cli` on npm.
|
|
6
|
+
* It resolves the platform-specific binary installed by `postinstall`,
|
|
7
|
+
* then spawns it with all arguments forwarded.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const { spawnSync } = require('node:child_process');
|
|
13
|
+
const fs = require('node:fs');
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
const os = require('node:os');
|
|
16
|
+
|
|
17
|
+
const BINARY = process.platform === 'win32' ? 'edgecrab.exe' : 'edgecrab';
|
|
18
|
+
const BIN_DIR = path.join(__dirname, BINARY);
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(BIN_DIR)) {
|
|
21
|
+
console.error(
|
|
22
|
+
`[edgecrab-cli] Native binary not found at: ${BIN_DIR}\n` +
|
|
23
|
+
`[edgecrab-cli] Re-run: npm install edgecrab-cli\n` +
|
|
24
|
+
`[edgecrab-cli] Or install from source: cargo install edgecrab-cli`
|
|
25
|
+
);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result = spawnSync(BIN_DIR, process.argv.slice(2), {
|
|
30
|
+
stdio: 'inherit',
|
|
31
|
+
env: process.env,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
process.exit(result.status ?? 1);
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "edgecrab-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "EdgeCrab — Super Powerful Personal Assistant inspired by NousHermes and OpenClaw. Single 15 MB static binary. Blazing-fast TUI, ReAct tool loop, multi-provider LLM.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://www.edgecrab.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/raphaelmansuy/edgecrab.git",
|
|
10
|
+
"directory": "sdks/npm-cli"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"ai",
|
|
14
|
+
"agent",
|
|
15
|
+
"llm",
|
|
16
|
+
"edgecrab",
|
|
17
|
+
"coding-agent",
|
|
18
|
+
"personal-assistant",
|
|
19
|
+
"cli",
|
|
20
|
+
"rust",
|
|
21
|
+
"nous-hermes",
|
|
22
|
+
"openclaw"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"edgecrab": "./bin/edgecrab.js"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"postinstall": "node scripts/install.js"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"bin/",
|
|
35
|
+
"scripts/",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {}
|
|
39
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall: download the correct EdgeCrab native binary for the current
|
|
4
|
+
* platform and architecture from GitHub Releases.
|
|
5
|
+
*
|
|
6
|
+
* Supported platforms:
|
|
7
|
+
* darwin-arm64 → edgecrab-aarch64-apple-darwin.tar.gz
|
|
8
|
+
* darwin-x64 → edgecrab-x86_64-apple-darwin.tar.gz
|
|
9
|
+
* linux-x64 → edgecrab-x86_64-unknown-linux-gnu.tar.gz
|
|
10
|
+
* linux-arm64 → edgecrab-aarch64-unknown-linux-gnu.tar.gz
|
|
11
|
+
* win32-x64 → edgecrab-x86_64-pc-windows-msvc.zip
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const https = require('node:https');
|
|
17
|
+
const fs = require('node:fs');
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
const os = require('node:os');
|
|
20
|
+
const { execSync } = require('node:child_process');
|
|
21
|
+
const { createGunzip } = require('node:zlib');
|
|
22
|
+
|
|
23
|
+
// ─── Config ──────────────────────────────────────────────────────────────────
|
|
24
|
+
const VERSION = require('../package.json').version;
|
|
25
|
+
const REPO = 'raphaelmansuy/edgecrab';
|
|
26
|
+
const BINARY = process.platform === 'win32' ? 'edgecrab.exe' : 'edgecrab';
|
|
27
|
+
const BIN_DIR = path.join(__dirname, '..', 'bin');
|
|
28
|
+
const DEST = path.join(BIN_DIR, BINARY);
|
|
29
|
+
|
|
30
|
+
// ─── Platform map ─────────────────────────────────────────────────────────────
|
|
31
|
+
const PLATFORM_MAP = {
|
|
32
|
+
'darwin-arm64': `edgecrab-aarch64-apple-darwin.tar.gz`,
|
|
33
|
+
'darwin-x64': `edgecrab-x86_64-apple-darwin.tar.gz`,
|
|
34
|
+
'linux-x64': `edgecrab-x86_64-unknown-linux-gnu.tar.gz`,
|
|
35
|
+
'linux-arm64': `edgecrab-aarch64-unknown-linux-gnu.tar.gz`,
|
|
36
|
+
'win32-x64': `edgecrab-x86_64-pc-windows-msvc.zip`,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const key = `${process.platform}-${os.arch()}`;
|
|
40
|
+
const archive = PLATFORM_MAP[key];
|
|
41
|
+
|
|
42
|
+
if (!archive) {
|
|
43
|
+
console.error(`[edgecrab-cli] Unsupported platform: ${key}`);
|
|
44
|
+
console.error(`[edgecrab-cli] Please build from source: https://github.com/${REPO}`);
|
|
45
|
+
process.exit(0); // non-fatal — SDK still works
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${archive}`;
|
|
49
|
+
|
|
50
|
+
// Skip download in CI if binary already exists (cache hit)
|
|
51
|
+
if (fs.existsSync(DEST)) {
|
|
52
|
+
console.log(`[edgecrab-cli] Binary already present: ${DEST}`);
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Follow redirects and return the final response.
|
|
60
|
+
* @param {string} downloadUrl
|
|
61
|
+
* @returns {Promise<import('node:http').IncomingMessage>}
|
|
62
|
+
*/
|
|
63
|
+
function fetchFollowRedirects(downloadUrl) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const req = https.get(downloadUrl, { headers: { 'User-Agent': 'edgecrab-npm-installer' } }, (res) => {
|
|
66
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
67
|
+
resolve(fetchFollowRedirects(res.headers.location));
|
|
68
|
+
} else if (res.statusCode === 200) {
|
|
69
|
+
resolve(res);
|
|
70
|
+
} else {
|
|
71
|
+
reject(new Error(`HTTP ${res.statusCode} for ${downloadUrl}`));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
req.on('error', reject);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Extract the binary from a .tar.gz archive into BIN_DIR.
|
|
80
|
+
* @param {string} tarPath path to the downloaded .tar.gz
|
|
81
|
+
*/
|
|
82
|
+
function extractTarGz(tarPath) {
|
|
83
|
+
// Use system tar if available (macOS and Linux always have it)
|
|
84
|
+
execSync(`tar -xzf "${tarPath}" -C "${BIN_DIR}" --strip-components=0 "${BINARY}" 2>/dev/null || tar -xzf "${tarPath}" -C "${BIN_DIR}"`, { stdio: 'pipe' });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Extract the binary from a .zip archive into BIN_DIR.
|
|
89
|
+
* @param {string} zipPath
|
|
90
|
+
*/
|
|
91
|
+
function extractZip(zipPath) {
|
|
92
|
+
// PowerShell is available on all modern Windows
|
|
93
|
+
execSync(`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${BIN_DIR}' -Force"`, { stdio: 'pipe' });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
97
|
+
async function main() {
|
|
98
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
99
|
+
|
|
100
|
+
const tmpFile = path.join(os.tmpdir(), `edgecrab-install-${Date.now()}.${archive.endsWith('.zip') ? 'zip' : 'tar.gz'}`);
|
|
101
|
+
|
|
102
|
+
console.log(`[edgecrab-cli] Downloading ${archive} ...`);
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const res = await fetchFollowRedirects(url);
|
|
106
|
+
await new Promise((resolve, reject) => {
|
|
107
|
+
const out = fs.createWriteStream(tmpFile);
|
|
108
|
+
res.pipe(out);
|
|
109
|
+
out.on('finish', resolve);
|
|
110
|
+
out.on('error', reject);
|
|
111
|
+
});
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error(`[edgecrab-cli] Download failed: ${err.message}`);
|
|
114
|
+
console.error(`[edgecrab-cli] You can install manually: cargo install edgecrab-cli`);
|
|
115
|
+
process.exit(0); // non-fatal
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
if (archive.endsWith('.zip')) {
|
|
120
|
+
extractZip(tmpFile);
|
|
121
|
+
} else {
|
|
122
|
+
extractTarGz(tmpFile);
|
|
123
|
+
}
|
|
124
|
+
fs.chmodSync(DEST, 0o755);
|
|
125
|
+
console.log(`[edgecrab-cli] Installed: ${DEST}`);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.error(`[edgecrab-cli] Extraction failed: ${err.message}`);
|
|
128
|
+
console.error(`[edgecrab-cli] You can install manually: cargo install edgecrab-cli`);
|
|
129
|
+
} finally {
|
|
130
|
+
try { fs.unlinkSync(tmpFile); } catch (_) { /* ignore */ }
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
main().catch((err) => {
|
|
135
|
+
console.error(`[edgecrab-cli] Unexpected error: ${err.message}`);
|
|
136
|
+
process.exit(0); // always non-fatal to avoid blocking npm install
|
|
137
|
+
});
|