claw-zero 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 +96 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/container.d.ts +15 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +41 -0
- package/dist/container.js.map +1 -0
- package/dist/docker.d.ts +7 -0
- package/dist/docker.d.ts.map +1 -0
- package/dist/docker.js +42 -0
- package/dist/docker.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +1 -0
- package/dist/profiles.d.ts +3 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +47 -0
- package/dist/profiles.js.map +1 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace.d.ts +4 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +9 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# One-Click Claw
|
|
2
|
+
|
|
3
|
+
A Node.js CLI that installs and sandboxes the [OpenClaw](https://github.com/openclaw/openclaw) AI agent on your local Mac with zero manual configuration.
|
|
4
|
+
|
|
5
|
+
**What it does in one command:**
|
|
6
|
+
- Checks for Docker (installs via Homebrew if missing)
|
|
7
|
+
- Creates `~/Desktop/OpenClaw_Workspace`
|
|
8
|
+
- Generates a `clawdbot.json` security config based on your chosen profile
|
|
9
|
+
- Pulls `ghcr.io/openclaw/openclaw:latest` and boots it on `localhost:3845`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
| Requirement | Notes |
|
|
16
|
+
|---|---|
|
|
17
|
+
| macOS | Homebrew auto-install is Mac-only for MVP |
|
|
18
|
+
| Node.js ≥ 18 | ESModules + native `fetch` |
|
|
19
|
+
| Docker Desktop | Auto-installed via Homebrew if absent |
|
|
20
|
+
| Anthropic or OpenAI API key | Entered during setup; never stored in plaintext |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quickstart
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone <repo-url> claw_zero
|
|
28
|
+
cd claw_zero
|
|
29
|
+
npm install
|
|
30
|
+
npm start
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Follow the interactive prompts — the entire setup takes under 2 minutes.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Security Profiles
|
|
38
|
+
|
|
39
|
+
Choose a profile during setup. The selection writes a `clawdbot.json` to your workspace.
|
|
40
|
+
|
|
41
|
+
| Profile | Sandbox | Workspace | Human Approval Required | Skill Trust | Budget |
|
|
42
|
+
|---|---|---|---|---|---|
|
|
43
|
+
| **Fort Knox** | `all` | Read-only | All commands | None | 100k tokens |
|
|
44
|
+
| **Pragmatic PM** *(default)* | `non-main` | Scoped | `rm`, `sudo`, `curl`, `wget`, `git push`, `npm publish` | Verified only | 500k tokens |
|
|
45
|
+
| **Cowboy Coder** | `off` | Scoped | `sudo`, `rm -rf` | All | 2M tokens |
|
|
46
|
+
| **YOLO Mode** | `off` | Read-write | None | All | Unlimited |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Container Details
|
|
51
|
+
|
|
52
|
+
| Parameter | Value |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Image | `ghcr.io/openclaw/openclaw:latest` |
|
|
55
|
+
| Container name | `openclaw_sandbox` |
|
|
56
|
+
| Port | `3845` → `localhost:3845` |
|
|
57
|
+
| Volume mount | `~/Desktop/OpenClaw_Workspace:/workspace` |
|
|
58
|
+
| API key env var | `ANTHROPIC_API_KEY` |
|
|
59
|
+
|
|
60
|
+
The container runs with `--detach --rm` — it stops automatically when Docker restarts.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Key Environment Variables
|
|
65
|
+
|
|
66
|
+
None required at the host level. The API key is collected interactively and passed directly to the container via `--env`.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Project Structure
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
claw_zero/
|
|
74
|
+
├── src/
|
|
75
|
+
│ ├── index.ts # Entry point — UI flow
|
|
76
|
+
│ ├── types.ts # TypeScript types
|
|
77
|
+
│ ├── profiles.ts # Security profile config map
|
|
78
|
+
│ ├── config.ts # clawdbot.json generation
|
|
79
|
+
│ ├── docker.ts # Docker detection, install, daemon start
|
|
80
|
+
│ ├── workspace.ts # Workspace directory creation
|
|
81
|
+
│ └── container.ts # Image pull + container launch
|
|
82
|
+
├── PRD.md
|
|
83
|
+
├── tasks.md
|
|
84
|
+
└── architecture.md
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Scripts
|
|
90
|
+
|
|
91
|
+
| Command | Action |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `npm start` | Run the CLI via `tsx` |
|
|
94
|
+
| `npm run build` | Compile TypeScript to `dist/` |
|
|
95
|
+
| `npm run dev` | Same as `start` (alias) |
|
|
96
|
+
| `npx tsc --noEmit` | Type-check without emitting |
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SecurityProfileKey } from './types.js';
|
|
2
|
+
export declare const WORKSPACE_PATH: string;
|
|
3
|
+
export declare const CONFIG_FILENAME = "clawdbot.json";
|
|
4
|
+
/** Generates clawdbot.json and writes it to the workspace directory. */
|
|
5
|
+
export declare function generateConfig(profileKey: SecurityProfileKey, apiKey: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,eAAO,MAAM,cAAc,QAAmD,CAAC;AAC/E,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAE/C,wEAAwE;AACxE,wBAAsB,cAAc,CAClC,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAef"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { PROFILES } from './profiles.js';
|
|
5
|
+
export const WORKSPACE_PATH = join(homedir(), 'Desktop', 'OpenClaw_Workspace');
|
|
6
|
+
export const CONFIG_FILENAME = 'clawdbot.json';
|
|
7
|
+
/** Generates clawdbot.json and writes it to the workspace directory. */
|
|
8
|
+
export async function generateConfig(profileKey, apiKey) {
|
|
9
|
+
const profile = PROFILES[profileKey];
|
|
10
|
+
if (!profile)
|
|
11
|
+
throw new Error(`Unknown profile: ${profileKey}`);
|
|
12
|
+
const configData = {
|
|
13
|
+
...profile.config,
|
|
14
|
+
api_key: apiKey,
|
|
15
|
+
};
|
|
16
|
+
await mkdir(WORKSPACE_PATH, { recursive: true });
|
|
17
|
+
await writeFile(join(WORKSPACE_PATH, CONFIG_FILENAME), JSON.stringify(configData, null, 2), 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAE/C,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAA8B,EAC9B,MAAc;IAEd,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC;IAEhE,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO,CAAC,MAAM;QACjB,OAAO,EAAE,MAAM;KAChB,CAAC;IAEF,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,SAAS,CACb,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,EACrC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EACnC,OAAO,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SecurityProfileKey } from './types.js';
|
|
2
|
+
/** Pulls the OpenClaw container image; returns the pulled image size. */
|
|
3
|
+
export declare function pullContainerImage(): Promise<{
|
|
4
|
+
size: string;
|
|
5
|
+
}>;
|
|
6
|
+
/**
|
|
7
|
+
* Runs the OpenClaw container:
|
|
8
|
+
* - Mounts ONLY ~/Desktop/OpenClaw_Workspace (never the full home dir)
|
|
9
|
+
* - Exposes port 3845
|
|
10
|
+
* - Passes the API key as ANTHROPIC_API_KEY env var
|
|
11
|
+
*/
|
|
12
|
+
export declare function launchContainer(apiKey: string, _profileKey: SecurityProfileKey): Promise<{
|
|
13
|
+
port: number;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMrD,yEAAyE;AACzE,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAepE;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,GAC9B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB3B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const WORKSPACE_PATH = join(homedir(), 'Desktop', 'OpenClaw_Workspace');
|
|
5
|
+
const IMAGE = 'ghcr.io/openclaw/openclaw:latest';
|
|
6
|
+
const PORT = 3845;
|
|
7
|
+
/** Pulls the OpenClaw container image; returns the pulled image size. */
|
|
8
|
+
export async function pullContainerImage() {
|
|
9
|
+
await execa('docker', ['pull', IMAGE], { stdio: 'inherit' });
|
|
10
|
+
// Get image size after pull
|
|
11
|
+
const { stdout } = await execa('docker', [
|
|
12
|
+
'image',
|
|
13
|
+
'inspect',
|
|
14
|
+
IMAGE,
|
|
15
|
+
'--format',
|
|
16
|
+
'{{.Size}}',
|
|
17
|
+
]);
|
|
18
|
+
const bytes = parseInt(stdout.trim(), 10);
|
|
19
|
+
const size = isNaN(bytes) ? 'unknown' : `${(bytes / 1_073_741_824).toFixed(1)} GB`;
|
|
20
|
+
return { size };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Runs the OpenClaw container:
|
|
24
|
+
* - Mounts ONLY ~/Desktop/OpenClaw_Workspace (never the full home dir)
|
|
25
|
+
* - Exposes port 3845
|
|
26
|
+
* - Passes the API key as ANTHROPIC_API_KEY env var
|
|
27
|
+
*/
|
|
28
|
+
export async function launchContainer(apiKey, _profileKey) {
|
|
29
|
+
await execa('docker', [
|
|
30
|
+
'run',
|
|
31
|
+
'--detach',
|
|
32
|
+
'--rm',
|
|
33
|
+
'--name', 'openclaw_sandbox',
|
|
34
|
+
'--publish', `${PORT}:${PORT}`,
|
|
35
|
+
'--volume', `${WORKSPACE_PATH}:/workspace`,
|
|
36
|
+
'--env', `ANTHROPIC_API_KEY=${apiKey}`,
|
|
37
|
+
IMAGE,
|
|
38
|
+
], { stdio: 'ignore' });
|
|
39
|
+
return { port: PORT };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AACxE,MAAM,KAAK,GAAG,kCAAkC,CAAC;AACjD,MAAM,IAAI,GAAG,IAAI,CAAC;AAElB,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE7D,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACvC,OAAO;QACP,SAAS;QACT,KAAK;QACL,UAAU;QACV,WAAW;KACZ,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAEnF,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,WAA+B;IAE/B,MAAM,KAAK,CACT,QAAQ,EACR;QACE,KAAK;QACL,UAAU;QACV,MAAM;QACN,QAAQ,EAAE,kBAAkB;QAC5B,WAAW,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE;QAC9B,UAAU,EAAE,GAAG,cAAc,aAAa;QAC1C,OAAO,EAAE,qBAAqB,MAAM,EAAE;QACtC,KAAK;KACN,EACD,EAAE,KAAK,EAAE,QAAQ,EAAE,CACpB,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
|
package/dist/docker.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Silent check — returns true if docker CLI is available. */
|
|
2
|
+
export declare function checkDocker(): Promise<boolean>;
|
|
3
|
+
/** Install Docker Desktop via Homebrew Cask. */
|
|
4
|
+
export declare function installDocker(): Promise<void>;
|
|
5
|
+
/** Open Docker.app and poll `docker info` until daemon is ready (max 60s). */
|
|
6
|
+
export declare function startDockerDaemon(): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"AAEA,8DAA8D;AAC9D,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,gDAAgD;AAChD,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED,8EAA8E;AAC9E,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CA0BvD"}
|
package/dist/docker.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
/** Silent check — returns true if docker CLI is available. */
|
|
3
|
+
export async function checkDocker() {
|
|
4
|
+
try {
|
|
5
|
+
await execa('docker', ['--version']);
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Install Docker Desktop via Homebrew Cask. */
|
|
13
|
+
export async function installDocker() {
|
|
14
|
+
await execa('brew', ['install', '--cask', 'docker'], { stdio: 'inherit' });
|
|
15
|
+
}
|
|
16
|
+
/** Open Docker.app and poll `docker info` until daemon is ready (max 60s). */
|
|
17
|
+
export async function startDockerDaemon() {
|
|
18
|
+
// Check if daemon is already running
|
|
19
|
+
try {
|
|
20
|
+
await execa('docker', ['info'], { stdio: 'ignore' });
|
|
21
|
+
return; // Already running
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Not running — launch it
|
|
25
|
+
}
|
|
26
|
+
await execa('open', ['-a', 'Docker']);
|
|
27
|
+
const POLL_INTERVAL_MS = 2000;
|
|
28
|
+
const MAX_WAIT_MS = 60_000;
|
|
29
|
+
const start = Date.now();
|
|
30
|
+
while (Date.now() - start < MAX_WAIT_MS) {
|
|
31
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
32
|
+
try {
|
|
33
|
+
await execa('docker', ['info'], { stdio: 'ignore' });
|
|
34
|
+
return; // Daemon ready
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Still starting — keep polling
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw new Error('Docker daemon did not start within 60 seconds.');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,qCAAqC;IACrC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,kBAAkB;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IAED,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtC,MAAM,gBAAgB,GAAG,IAAI,CAAC;IAC9B,MAAM,WAAW,GAAG,MAAM,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,WAAW,EAAE,CAAC;QACxC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,eAAe;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;AACpE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import pc from 'picocolors';
|
|
4
|
+
import { Listr } from 'listr2';
|
|
5
|
+
import { PROFILES } from './profiles.js';
|
|
6
|
+
import { generateConfig, WORKSPACE_PATH } from './config.js';
|
|
7
|
+
import { execa } from 'execa';
|
|
8
|
+
import { checkDocker, installDocker, startDockerDaemon } from './docker.js';
|
|
9
|
+
import { createWorkspace } from './workspace.js';
|
|
10
|
+
import { pullContainerImage, launchContainer } from './container.js';
|
|
11
|
+
/** Formats API key for inline confirmation: first 7 + last 4 chars. */
|
|
12
|
+
function maskApiKey(key) {
|
|
13
|
+
if (key.length <= 11)
|
|
14
|
+
return key.slice(0, 3) + '••••' + key.slice(-2);
|
|
15
|
+
return key.slice(0, 7) + '••••' + key.slice(-4);
|
|
16
|
+
}
|
|
17
|
+
/** Syntax-highlights a JSON object: cyan keys, green strings, purple numbers. */
|
|
18
|
+
function highlightJson(obj) {
|
|
19
|
+
return JSON.stringify(obj, null, 2)
|
|
20
|
+
.split('\n')
|
|
21
|
+
.map((line) => {
|
|
22
|
+
return line
|
|
23
|
+
.replace(/"([^"]+)":/g, (_, k) => pc.cyan('"' + k + '"') + ':')
|
|
24
|
+
.replace(/: "([^"]*)"/g, (_, v) => ': ' + pc.green('"' + v + '"'))
|
|
25
|
+
.replace(/: (\d+)/g, (_, n) => ': ' + pc.magenta(n))
|
|
26
|
+
.replace(/: \[/g, ': [')
|
|
27
|
+
.replace(/"(\*|rm|sudo|curl|wget|git push|npm publish|rm -rf)"/g, (_, v) => pc.green('"' + v + '"'));
|
|
28
|
+
})
|
|
29
|
+
.join('\n');
|
|
30
|
+
}
|
|
31
|
+
async function main() {
|
|
32
|
+
// ── 3.2 Welcome intro ───────────────────────────────────────────────────────
|
|
33
|
+
console.clear();
|
|
34
|
+
console.log(pc.dim('──────────────────────────────────────────────'));
|
|
35
|
+
p.intro(`${pc.bgCyan(pc.black(' 🦞 ONE-CLICK CLAW '))} ${pc.dim('Secure Local Sandbox')}`);
|
|
36
|
+
console.log(pc.dim('──────────────────────────────────────────────'));
|
|
37
|
+
// ── 3.3 API key masked input ────────────────────────────────────────────────
|
|
38
|
+
const apiKey = await p.password({
|
|
39
|
+
message: 'Paste your Anthropic or OpenAI API Key',
|
|
40
|
+
mask: '•',
|
|
41
|
+
validate: (value) => {
|
|
42
|
+
if (!value)
|
|
43
|
+
return 'API Key is required to power the brain.';
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (p.isCancel(apiKey)) {
|
|
47
|
+
p.cancel('Setup cancelled.');
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
// Inline confirmation
|
|
51
|
+
console.log(`${pc.green('◆')} API Key ${pc.dim('✓')} ${pc.dim(maskApiKey(apiKey))}`);
|
|
52
|
+
// ── 3.4 Security profile selection ─────────────────────────────────────────
|
|
53
|
+
const profileKey = await p.select({
|
|
54
|
+
message: 'Select your security profile',
|
|
55
|
+
initialValue: 'pragmatic',
|
|
56
|
+
options: [
|
|
57
|
+
{ value: 'fort_knox', label: 'Fort Knox', hint: 'Super strict. Read-only.' },
|
|
58
|
+
{ value: 'pragmatic', label: 'The Pragmatic PM', hint: 'Recommended. Scoped access.' },
|
|
59
|
+
{ value: 'cowboy', label: 'Cowboy Coder', hint: 'Lenient. Proceed with caution.' },
|
|
60
|
+
{ value: 'yolo', label: 'YOLO Mode', hint: 'Unrestricted. Good luck.' },
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
if (p.isCancel(profileKey)) {
|
|
64
|
+
p.cancel('Setup cancelled.');
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
const selectedProfile = PROFILES[profileKey];
|
|
68
|
+
// Inline confirmation
|
|
69
|
+
console.log(`${pc.green('◆')} Profile ${pc.yellow(selectedProfile.label)}`);
|
|
70
|
+
// ── 3.5 Config preview ──────────────────────────────────────────────────────
|
|
71
|
+
console.log(`\n${pc.dim('◇')} ${pc.dim('Generating clawdbot.json')}`);
|
|
72
|
+
console.log(highlightJson(selectedProfile.config));
|
|
73
|
+
console.log();
|
|
74
|
+
// ── 3.6 Sequential install checklist (listr2) ───────────────────────────────
|
|
75
|
+
let dockerVersion = 'Docker';
|
|
76
|
+
let imageSize = '1.2 GB';
|
|
77
|
+
let containerPort = 3845;
|
|
78
|
+
const tasks = new Listr([
|
|
79
|
+
{
|
|
80
|
+
title: 'Checking Docker daemon...',
|
|
81
|
+
task: async (_, task) => {
|
|
82
|
+
const installed = await checkDocker();
|
|
83
|
+
if (!installed) {
|
|
84
|
+
task.title = 'Installing Docker via Homebrew...';
|
|
85
|
+
await installDocker();
|
|
86
|
+
}
|
|
87
|
+
await startDockerDaemon();
|
|
88
|
+
try {
|
|
89
|
+
const { stdout } = await execa('docker', ['--version']);
|
|
90
|
+
dockerVersion = stdout.trim();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// version string is cosmetic — don't block
|
|
94
|
+
}
|
|
95
|
+
task.title = pc.dim(`✔ ${dockerVersion} is running`);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: 'Creating workspace directory...',
|
|
100
|
+
task: async (_, task) => {
|
|
101
|
+
await createWorkspace();
|
|
102
|
+
task.title = pc.dim(`✔ Workspace ready at ${WORKSPACE_PATH}`);
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
title: 'Writing clawdbot.json...',
|
|
107
|
+
task: async (_, task) => {
|
|
108
|
+
await generateConfig(profileKey, apiKey);
|
|
109
|
+
task.title = pc.dim('✔ clawdbot.json written');
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
title: 'Pulling OpenClaw container image...',
|
|
114
|
+
task: async (_, task) => {
|
|
115
|
+
const result = await pullContainerImage();
|
|
116
|
+
imageSize = result.size;
|
|
117
|
+
task.title = pc.dim(`✔ Image pulled (${imageSize})`);
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
title: 'Booting container...',
|
|
122
|
+
task: async (_, task) => {
|
|
123
|
+
const result = await launchContainer(apiKey, profileKey);
|
|
124
|
+
containerPort = result.port;
|
|
125
|
+
task.title = pc.dim(`✔ Container live on port ${containerPort}`);
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
], {
|
|
129
|
+
rendererOptions: { collapseErrors: false },
|
|
130
|
+
});
|
|
131
|
+
try {
|
|
132
|
+
await tasks.run();
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
p.cancel(`Setup failed: ${err.message}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
// ── 3.7 Outro ───────────────────────────────────────────────────────────────
|
|
139
|
+
const box = [
|
|
140
|
+
` ${pc.dim('│')} ☕ Pouring some coffee for your new AI intern...`,
|
|
141
|
+
` ${pc.dim('│')}`,
|
|
142
|
+
` ${pc.dim('│')} Workspace → ${pc.cyan(WORKSPACE_PATH)}`,
|
|
143
|
+
` ${pc.dim('│')} Access → ${pc.cyan(`localhost:${containerPort}`)}`,
|
|
144
|
+
` ${pc.dim('│')} Profile → ${pc.yellow(selectedProfile.label)}`,
|
|
145
|
+
` ${pc.dim('│')}`,
|
|
146
|
+
` ${pc.dim('│')} Drop files into the workspace folder to begin.`,
|
|
147
|
+
].join('\n');
|
|
148
|
+
p.outro(`${pc.green('✔')} Sandbox successfully booted!\n\n${box}`);
|
|
149
|
+
}
|
|
150
|
+
main().catch((err) => {
|
|
151
|
+
p.cancel(`Unexpected error: ${err.message}`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CA6CpD,CAAC"}
|
package/dist/profiles.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const PROFILES = {
|
|
2
|
+
fort_knox: {
|
|
3
|
+
key: 'fort_knox',
|
|
4
|
+
label: 'Fort Knox',
|
|
5
|
+
config: {
|
|
6
|
+
sandbox: { mode: 'all' },
|
|
7
|
+
workspaceAccess: 'ro',
|
|
8
|
+
require_human_approval: ['*'],
|
|
9
|
+
skill_registry_trust: 'none',
|
|
10
|
+
max_budget: 100000,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
pragmatic: {
|
|
14
|
+
key: 'pragmatic',
|
|
15
|
+
label: 'The Pragmatic PM',
|
|
16
|
+
config: {
|
|
17
|
+
sandbox: { mode: 'non-main' },
|
|
18
|
+
workspaceAccess: 'scoped',
|
|
19
|
+
require_human_approval: ['rm', 'sudo', 'curl', 'wget', 'git push', 'npm publish'],
|
|
20
|
+
skill_registry_trust: 'verified_only',
|
|
21
|
+
max_budget: 500000,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
cowboy: {
|
|
25
|
+
key: 'cowboy',
|
|
26
|
+
label: 'Cowboy Coder',
|
|
27
|
+
config: {
|
|
28
|
+
sandbox: { mode: 'off' },
|
|
29
|
+
workspaceAccess: 'scoped',
|
|
30
|
+
require_human_approval: ['sudo', 'rm -rf'],
|
|
31
|
+
skill_registry_trust: 'all',
|
|
32
|
+
max_budget: 2000000,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
yolo: {
|
|
36
|
+
key: 'yolo',
|
|
37
|
+
label: 'YOLO Mode',
|
|
38
|
+
config: {
|
|
39
|
+
sandbox: { mode: 'off' },
|
|
40
|
+
workspaceAccess: 'rw',
|
|
41
|
+
require_human_approval: [],
|
|
42
|
+
skill_registry_trust: 'all',
|
|
43
|
+
max_budget: 0, // 0 = unlimited
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAoC;IACvD,SAAS,EAAE;QACT,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE;YACN,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;YACxB,eAAe,EAAE,IAAI;YACrB,sBAAsB,EAAE,CAAC,GAAG,CAAC;YAC7B,oBAAoB,EAAE,MAAM;YAC5B,UAAU,EAAE,MAAM;SACnB;KACF;IACD,SAAS,EAAE;QACT,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,kBAAkB;QACzB,MAAM,EAAE;YACN,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAC7B,eAAe,EAAE,QAAQ;YACzB,sBAAsB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC;YACjF,oBAAoB,EAAE,eAAe;YACrC,UAAU,EAAE,MAAM;SACnB;KACF;IACD,MAAM,EAAE;QACN,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,cAAc;QACrB,MAAM,EAAE;YACN,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;YACxB,eAAe,EAAE,QAAQ;YACzB,sBAAsB,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;YAC1C,oBAAoB,EAAE,KAAK;YAC3B,UAAU,EAAE,OAAO;SACpB;KACF;IACD,IAAI,EAAE;QACJ,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE;YACN,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;YACxB,eAAe,EAAE,IAAI;YACrB,sBAAsB,EAAE,EAAE;YAC1B,oBAAoB,EAAE,KAAK;YAC3B,UAAU,EAAE,CAAC,EAAE,gBAAgB;SAChC;KACF;CACF,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type SecurityProfileKey = 'fort_knox' | 'pragmatic' | 'cowboy' | 'yolo';
|
|
2
|
+
export type SandboxMode = 'all' | 'non-main' | 'off';
|
|
3
|
+
export type WorkspaceAccess = 'ro' | 'scoped' | 'rw';
|
|
4
|
+
export type SkillRegistryTrust = 'none' | 'verified_only' | 'all';
|
|
5
|
+
export interface ClawdbotConfig {
|
|
6
|
+
sandbox: {
|
|
7
|
+
mode: SandboxMode;
|
|
8
|
+
};
|
|
9
|
+
workspaceAccess: WorkspaceAccess;
|
|
10
|
+
require_human_approval: string[];
|
|
11
|
+
skill_registry_trust: SkillRegistryTrust;
|
|
12
|
+
max_budget: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SecurityProfile {
|
|
15
|
+
key: SecurityProfileKey;
|
|
16
|
+
label: string;
|
|
17
|
+
config: ClawdbotConfig;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC;AAErD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC;AAErD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,eAAe,GAAG,KAAK,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QACP,IAAI,EAAE,WAAW,CAAC;KACnB,CAAC;IACF,eAAe,EAAE,eAAe,CAAC;IACjC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,oBAAoB,EAAE,kBAAkB,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,kBAAkB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,QAAmD,CAAC;AAE/E,+EAA+E;AAC/E,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export const WORKSPACE_PATH = join(homedir(), 'Desktop', 'OpenClaw_Workspace');
|
|
5
|
+
/** Idempotent — creates workspace directory; no error if it already exists. */
|
|
6
|
+
export async function createWorkspace() {
|
|
7
|
+
await execa('mkdir', ['-p', WORKSPACE_PATH]);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAE/E,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claw-zero",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "One-Click CLI to securely install and sandbox the OpenClaw AI agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"claw-zero": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "tsx src/index.ts",
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsx watch src/index.ts",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@clack/prompts": "^0.9.0",
|
|
22
|
+
"execa": "^9.5.2",
|
|
23
|
+
"listr2": "^8.2.5",
|
|
24
|
+
"picocolors": "^1.1.1"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^22.0.0",
|
|
28
|
+
"tsx": "^4.19.2",
|
|
29
|
+
"typescript": "^5.7.2"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|