@vclawhub/vclaw 0.2.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 ADDED
@@ -0,0 +1,310 @@
1
+ # VClaw Agent — Local Agentic Mesh Wrapper
2
+
3
+ > **One command to set up pi.dev + pi-web.dev + NATS leaf node on any machine.**
4
+
5
+ This project is the orchestration layer that wraps three open-source components into a single, self-contained developer playground. Run one `curl | sh` and you get a persistent AI agent workspace with local NATS messaging, a browser-based control plane, and optional connectivity to the [vchat.email](https://vchat.email) agent network.
6
+
7
+ ---
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ # Install everything: NATS server, pi.dev CLI, pi-web.dev, vchat-agent
13
+ curl -fsSL https://vclawhub.com/install | sh
14
+
15
+ # Launch the local mesh (NATS + pi-web.dev)
16
+ vclaw-up
17
+
18
+ # Optional: join the vchat.email agent network
19
+ vclaw-up --onboard you@email.com
20
+ ```
21
+
22
+ That's it. Open a browser to `https://pi-web.dev/?connect=127.0.0.1:4222` and start chatting with your AI agent from any device.
23
+
24
+ ---
25
+
26
+ ## What You Get
27
+
28
+ After install, your machine has:
29
+
30
+ | Component | Binary | Purpose |
31
+ |-----------|--------|---------|
32
+ | **NATS Server** | `nats-server` | Local message broker on `127.0.0.1:4222` with JetStream for offline caching |
33
+ | **pi.dev CLI** | `pi` | Terminal AI agent with skill system, multi-provider LLM support |
34
+ | **PI WEB** | `pi-web` / `pi-web-sessiond` | Browser-based agent workspace, project management, session persistence |
35
+ | **vchat-agent** | `vchat-agent` (via `npx`) | Identity & onboarding CLI for the vchat.email agent network |
36
+ | **vclaw-up** | `~/.local/bin/vclaw-up` | Unified orchestrator — starts everything with one command |
37
+
38
+ Installed to `~/.local/bin/` with data in `~/.local/share/vclaw/`.
39
+
40
+ ---
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ ┌──────────────────────────────────────────────┐
46
+ │ Browser (any device) │
47
+ │ laptop · desktop · tablet · phone │
48
+ └──────────────────────┬───────────────────────┘
49
+ │ HTTPS + WebSocket
50
+
51
+ ┌──────────────────────────────────────────────┐
52
+ │ PI WEB (pi-web.dev) │
53
+ │ Fastify HTTP server · Real-time WebSocket │
54
+ │ Session daemon · Project management │
55
+ └──────────┬───────────────────┬────────────────┘
56
+ │ Unix socket/TCP │ WebSocket
57
+ ▼ ▼
58
+ ┌──────────────────┐ ┌────────────────────────┐
59
+ │ Pi Agent (pi) │ │ NATS Leaf Node │
60
+ │ LLM + skills │ │ 127.0.0.1:4222 │
61
+ │ Tavily, TTS, │ │ JetStream (offline) │
62
+ │ PDF, Kolors... │ │ Optional: upstream to │
63
+ └──────────────────┘ │ nats.vchat.email:443 │
64
+ └──────────┬─────────────┘
65
+ │ (if enabled)
66
+ ┌──────────▼─────────────┐
67
+ │ vchat.email Mesh │
68
+ │ agents.vchat.email │
69
+ │ A2A · fleet mgmt │
70
+ └────────────────────────┘
71
+ ```
72
+
73
+ The stack uses a **local-first architecture**:
74
+ - **NATS** runs locally with JetStream — no internet required for core operation.
75
+ - **PI WEB** connects to NATS via WebSocket for real-time agent communication.
76
+ - **Pi Agent** runs LLM interactions with loaded skills.
77
+ - **vchat.email** is optional — only if you want agent-to-agent networking across devices.
78
+
79
+ ---
80
+
81
+ ## Daily Use
82
+
83
+ ### Launch the stack
84
+
85
+ ```bash
86
+ vclaw-up
87
+ ```
88
+
89
+ Opens `https://pi-web.dev/?connect=127.0.0.1:4222` in your browser. NATS and the agent loop run in the background.
90
+
91
+ ### Watch agent messages in real time
92
+
93
+ Open another terminal:
94
+
95
+ ```bash
96
+ nats sub ">"
97
+ ```
98
+
99
+ You'll see JSON packets fly by as your agent searches the web, generates images, or processes documents.
100
+
101
+ ### Stop everything
102
+
103
+ ```bash
104
+ vclaw-up --stop
105
+ ```
106
+
107
+ ### Check status
108
+
109
+ ```bash
110
+ vclaw-up --status
111
+ ```
112
+
113
+ ### Chat with your agent
114
+
115
+ ```bash
116
+ pi "What's the latest AI news?"
117
+ pi "Search for Raspberry Pi 5 benchmarks"
118
+ pi "/help"
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Joining the vchat.email Network
124
+
125
+ For agent-to-agent collaboration, fleet management, and cross-device persistence, join the vchat.email mesh:
126
+
127
+ ```bash
128
+ # Interactive onboarding
129
+ vclaw-up --onboard you@email.com
130
+
131
+ # Or standalone
132
+ vchat-onboard.sh you@email.com
133
+ ```
134
+
135
+ **The flow:**
136
+ 1. Generates an ED25519 Nkey identity for your agent.
137
+ 2. Introduces it to vgate (`api.vchat.email`) as a pending agent.
138
+ 3. Opens your browser to `https://login.vchat.email/a/<hash>`.
139
+ 4. You log in and approve the agent at `agents.vchat.email`.
140
+ 5. Credentials saved to `~/.vchat/credentials.json`.
141
+ 6. Your agent now appears on the mesh — discoverable, addressable, delegatable.
142
+
143
+ Once onboarded, agents communicate on NATS subjects like `agents.hb.pi.<email>.<session>`, `agents.prompt.pi.<email>.<session>`, and `agents.a2a.<target_email>`.
144
+
145
+ ---
146
+
147
+ ## Installation Options
148
+
149
+ ### Option A: One-liner (recommended)
150
+
151
+ ```bash
152
+ curl -fsSL https://vclawhub.com/install | sh
153
+ ```
154
+
155
+ Detects your OS/arch, downloads NATS server, pi.dev CLI, vclaw binary, and the `vclaw-up` orchestrator. Also installs `@vchatemail/agent` for optional network onboarding.
156
+
157
+ ### Option B: From source
158
+
159
+ ```bash
160
+ git clone https://github.com/VillageCity/vclaw-agent.git
161
+ cd vclaw-agent
162
+ ./install.sh
163
+ ```
164
+
165
+ ### Option C: Manual component install
166
+
167
+ ```bash
168
+ # NATS Server
169
+ npm install -g nats-server
170
+
171
+ # Pi Agent
172
+ npm install -g @earendil-works/pi-coding-agent
173
+
174
+ # PI WEB
175
+ npm install -g @jmfederico/pi-web
176
+ pi-web install
177
+
178
+ # vchat-agent (optional)
179
+ npm install -g @vchatemail/agent
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Agent Skills
185
+
186
+ Skills live in `~/.pi/agent/skills/`. This project ships with 9 curated skills:
187
+
188
+ | Skill | What It Does | API Key |
189
+ |-------|-------------|---------|
190
+ | **Tavily Search** | Real-time web search with relevance filtering | `TAVILY_API_KEY` |
191
+ | **Brave Search** | Alternative web search | `BRAVE_API_KEY` |
192
+ | **PDF Reader** | Text + scanned PDF extraction via vision models | (uses LLM provider) |
193
+ | **Edge TTS** | Text-to-speech via Microsoft Edge engine (no API key) | None |
194
+ | **Kolors Image** | Local text-to-image generation (Kuaishou) | None (GPU +12GB VRAM) |
195
+ | **Hyperframes** | HTML/CSS → deterministic MP4 video | None |
196
+ | **Skywork Search** | Chinese/English web search | `SKYWORK_API_KEY` |
197
+ | **Bun Registry** | Publish CLI tools to npm/Bun registry | None (npm login) |
198
+ | **vchat Network** | Join the vchat.email agent mesh | None (email + browser) |
199
+
200
+ Skills are documented as `SKILL.md` files in each directory — Pi Agent reads them automatically.
201
+
202
+ ---
203
+
204
+ ## Project Structure
205
+
206
+ ```
207
+ vclaw-agent/
208
+ ├── install.sh # One-liner installer
209
+ ├── vclaw-up # Stack orchestrator
210
+ ├── src/ # Bun CLI source
211
+ ├── dist/ # Bun build output (gitignored)
212
+ ├── package.json # @vclawhub/vclaw (publishable to npm)
213
+ ├── .env.d/ # Local secrets (gitignored)
214
+ │ ├── vclawhub.env # npm publish token (VCLAW_NPM_TOKEN)
215
+ │ └── _template.env # Template for new env vars
216
+ ├── config/
217
+ │ └── nats-leaf.conf # Canonical NATS leaf-node config
218
+ ├── scripts/
219
+ │ └── vchat-onboard.sh # vchat.email network join
220
+ ├── .github/workflows/
221
+ │ └── publish.yml # CI/CD — Bun build + publish
222
+ ├── .pi/agent/skills/ # 9 agent skill packages
223
+ └── docs/
224
+ ├── NODES_members.md # Node inventory & deployment profiles
225
+ ├── archive/ # Archived reference docs
226
+ │ ├── ALPHA.md, BRIEFING.md, VCHAT_idp.md, RELEASES.md
227
+ │ └── onboard.sh # Legacy onboard script
228
+ ├── help/ # Archived HTML pages & proxy scripts
229
+ ├── things/ # IoT / device reference
230
+ └── firmwares/ # NanoPi R5C firmware
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Publishing to npm
236
+
237
+ Publish `@vclawhub/vclaw` to npmjs.com with a single command:
238
+
239
+ ```bash
240
+ source .env.d/vclawhub.env
241
+ export NPM_TOKEN="${VCLAW_NPM_TOKEN}"
242
+ bun run build
243
+ bun publish --access public
244
+ ```
245
+
246
+ Then anyone can use it:
247
+
248
+ ```bash
249
+ bunx @vclawhub/vclaw install
250
+ bunx @vclawhub/vclaw up
251
+ bunx @vclawhub/vclaw up --onboard you@email.com
252
+ ```
253
+
254
+ ### CI/CD — GitHub Actions
255
+
256
+ The workflow at `.github/workflows/publish.yml` runs automatically when a `v*` tag is pushed:
257
+
258
+ ```mermaid
259
+ graph LR
260
+ A[git tag v0.1.0] --> B[Workflow triggers]
261
+ B --> C[Bun build src/cli.ts]
262
+ C --> D[publish @vclawhub/vclaw]
263
+ D --> E[GitHub Release with changelog]
264
+ ```
265
+
266
+ #### Step-by-step: Add the secret to GitHub
267
+
268
+ 1. Go to **repo Settings → Secrets and variables → Actions**.
269
+ 2. Click **New repository secret**.
270
+ 3. **Name:** `VCLAW_NPM_TOKEN`
271
+ 4. **Value:** the automation token from `.env.d/vclawhub.env`
272
+ 5. Click **Add secret**.
273
+
274
+ #### To trigger a publish
275
+
276
+ ```bash
277
+ git tag v0.1.0
278
+ git push origin v0.1.0
279
+ ```
280
+
281
+ The workflow then:
282
+ 1. Bun-bundles `src/cli.ts` → `dist/cli.js`, publishes `@vclawhub/vclaw`
283
+ 2. Creates a GitHub Release with auto-generated notes
284
+
285
+ #### Manual trigger
286
+
287
+ Run the workflow manually from the GitHub Actions UI, entering a version tag.
288
+
289
+ ### Skill: bun-registry-publish
290
+
291
+ Pi Agent has a built-in skill (`~/.pi/agent/skills/bun-registry-publish/SKILL.md`) that walks through the full publish flow step by step — from `bun init` to `bunx` consumption.
292
+
293
+ ---
294
+
295
+ ## References
296
+
297
+ | Resource | URL |
298
+ |----------|-----|
299
+ | Pi.dev | [https://pi.dev](https://pi.dev) |
300
+ | PI WEB | [https://pi-web.dev](https://pi-web.dev) |
301
+ | NATS Server | [https://nats.io](https://nats.io) |
302
+ | vchat.email | [https://vchat.email](https://vchat.email) |
303
+ | @vchatemail/agent (npm) | [https://www.npmjs.com/package/@vchatemail/agent](https://www.npmjs.com/package/@vchatemail/agent) |
304
+ | @vclawhub/vclaw (npm) | [https://www.npmjs.com/package/@vclawhub/vclaw](https://www.npmjs.com/package/@vclawhub/vclaw) |
305
+ | VClaw Hub Install | `https://vclawhub.com/install` (serves `install.sh`) |
306
+
307
+ ---
308
+
309
+ > **VClaw Agent** — MIT Licensed.
310
+ > Build your own Local Agentic Mesh: pi.dev + pi-web.dev + NATS leaf node, one command away.
@@ -0,0 +1,31 @@
1
+ # VClaw Local NATS Leaf Node Configuration
2
+ # =========================================
3
+ # This config runs a local NATS server on 127.0.0.1:4222 with JetStream
4
+ # for offline caching, WebSocket for browser connectivity, and optionally
5
+ # dials upstream to the vchat.email hub.
6
+
7
+ listen: 127.0.0.1:4222
8
+
9
+ # Enable Local JetStream Storage
10
+ jetstream {
11
+ store_dir: "${HOME}/.local/share/vclaw/nats-data"
12
+ }
13
+
14
+ # WebSocket for browser-based PI WEB connectivity
15
+ websocket {
16
+ port: 9222
17
+ listen: "127.0.0.1:9222"
18
+ }
19
+
20
+ # Connect Upstream to vchat.email Hub (optional — uncomment after onboarding)
21
+ # leafnodes {
22
+ # remotes [
23
+ # {
24
+ # url: "nats-leaf://connect.vchat.email:7422"
25
+ # # Credentials from ~/.vchat/credentials.json (after npx @vchatemail/agent ensoul)
26
+ # }
27
+ # ]
28
+ # }
29
+
30
+ # Debug / monitoring
31
+ http_port: 8222
package/dist/cli.js ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+
4
+ // src/cli.ts
5
+ var {$ } = globalThis.Bun;
6
+ var PROJECT_ROOT = import.meta.dirname + "/..";
7
+ var HELP = `
8
+ VClaw Agent \u2014 Local Agentic Mesh Wrapper
9
+
10
+ Usage:
11
+ bunx @vclawhub/vclaw install Install the full stack
12
+ bunx @vclawhub/vclaw up Launch NATS + pi-web.dev
13
+ bunx @vclawhub/vclaw up --onboard <email> Launch + join vchat.email
14
+ bunx @vclawhub/vclaw up --uninstall Remove everything
15
+ bunx @vclawhub/vclaw onboard <email> Join the vchat.email network
16
+ bunx @vclawhub/vclaw help Show this message
17
+
18
+ Examples:
19
+ bunx @vclawhub/vclaw install
20
+ bunx @vclawhub/vclaw up
21
+ bunx @vclawhub/vclaw up --onboard alice@example.com
22
+ `;
23
+ var cmd = process.argv[2]?.toLowerCase();
24
+ switch (cmd) {
25
+ case "install": {
26
+ const localScript = `${PROJECT_ROOT}/install.sh`;
27
+ const { exitCode } = await $`test -f ${localScript}`.quiet();
28
+ if (exitCode === 0) {
29
+ console.log("\uD83D\uDCE6 Running local install.sh...");
30
+ await $`bash ${localScript}`;
31
+ } else {
32
+ console.log("\uD83D\uDCE6 Fetching installer from vclawhub.com...");
33
+ await $`curl -fsSL https://vclawhub.com/install | sh`;
34
+ }
35
+ break;
36
+ }
37
+ case "up": {
38
+ const onboardFlag = process.argv.indexOf("--onboard");
39
+ let email = "";
40
+ if (onboardFlag !== -1 && process.argv[onboardFlag + 1]) {
41
+ email = process.argv[onboardFlag + 1];
42
+ }
43
+ const localScript = `${PROJECT_ROOT}/vclaw-up`;
44
+ const uninstallFlag = process.argv.indexOf("--uninstall");
45
+ const { exitCode } = await $`test -f ${localScript}`.quiet();
46
+ if (exitCode === 0 && uninstallFlag !== -1) {
47
+ console.log("\uD83E\uDDF9 Uninstalling VClaw Hub...");
48
+ await $`bash ${localScript} --uninstall`;
49
+ process.exit(0);
50
+ } else if (exitCode === 0 && email) {
51
+ console.log("\uD83D\uDE80 Launching stack and joining vchat.email network...");
52
+ await $`bash ${localScript} --onboard ${email}`;
53
+ } else if (exitCode === 0) {
54
+ console.log("\uD83D\uDE80 Launching local agentic mesh...");
55
+ await $`bash ${localScript}`;
56
+ } else if (email) {
57
+ console.log("\uD83D\uDE80 Starting NATS server...");
58
+ const natsServer = Bun.which("nats-server");
59
+ if (!natsServer) {
60
+ console.error("\u274C nats-server not found. Run 'vclaw-agent install' first.");
61
+ process.exit(1);
62
+ }
63
+ const dataDir = `${process.env.HOME}/.local/share/vclaw`;
64
+ await $`mkdir -p ${dataDir}/nats-data`;
65
+ await $`nats-server --port 4222 --jetstream --store_dir ${dataDir}/nats-data > ${dataDir}/nats-server.log 2>&1 &`.quiet();
66
+ console.log(" \u2714 NATS server started on 127.0.0.1:4222");
67
+ const piUrl = "https://pi-web.dev/?connect=127.0.0.1:4222";
68
+ await $`bunx open ${piUrl}`.quiet().catch(() => {});
69
+ console.log(` \u2714 Browser opened to ${piUrl}`);
70
+ console.log(`
71
+ \uD83D\uDCE1 Onboarding to vchat.email...`);
72
+ await $`bunx @vchatemail/agent ensoul --email ${email}`;
73
+ } else {
74
+ console.error("\u274C vclaw-up not found. Run 'vclaw-agent install' first.");
75
+ process.exit(1);
76
+ }
77
+ break;
78
+ }
79
+ case "onboard": {
80
+ const email = process.argv[3];
81
+ if (!email) {
82
+ console.error("\u274C Usage: bunx @vclawhub/vclaw onboard <email>");
83
+ process.exit(1);
84
+ }
85
+ console.log(`\uD83D\uDCE1 Joining vchat.email network as ${email}...`);
86
+ await $`bunx @vchatemail/agent ensoul --email ${email}`;
87
+ break;
88
+ }
89
+ case "help":
90
+ case "--help":
91
+ case "-h":
92
+ default:
93
+ console.log(HELP);
94
+ break;
95
+ }
package/install.sh ADDED
@@ -0,0 +1,453 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================
3
+ # vclaw hub: complete multi-agent playground installer
4
+ # Target URL: https://vclawhub.com/install
5
+ #
6
+ # Installs: NATS server, pi.dev CLI, vclaw agent, pi-web.dev
7
+ # Generates: vclaw-up orchestrator, NATS leaf-node config
8
+ # ============================================================
9
+ set -e
10
+
11
+ # Color helpers
12
+ RED='\033[0;31m'
13
+ GREEN='\033[0;32m'
14
+ BLUE='\033[0;34m'
15
+ MAGENTA='\033[0;35m'
16
+ CYAN='\033[0;36m'
17
+ YELLOW='\033[0;33m'
18
+ NC='\033[0m'
19
+
20
+ # ASCII banner
21
+ echo -e "${MAGENTA}"
22
+ echo "██╗ ██╗ ██████╗██╗ █████╗ ██╗ ██╗"
23
+ echo "██║ ██║██╔════╝██║ ██╔══██╗██║ ██║"
24
+ echo "██║ ██║██║ ██║ ███████║██║ █╗ ██║"
25
+ echo "╚██╗ ██╔╝██║ ██║ ██╔══██║██║███╗██║"
26
+ echo " ╚████╔╝ ╚██████╗███████╗██║ ██║╚███╔███╔╝"
27
+ echo " ╚═══╝ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ "
28
+ echo -e "${NC}"
29
+ echo -e "${BLUE}=== VClaw Hub — Local Agentic Mesh Installer ===${NC}"
30
+ echo ""
31
+
32
+ # -------------------------------------------------------------
33
+ # Step 1: Detect OS & Architecture
34
+ # -------------------------------------------------------------
35
+ OS_TYPE="$(uname -s)"
36
+ ARCH_TYPE="$(uname -m)"
37
+
38
+ case "${OS_TYPE}" in
39
+ Darwin*)
40
+ SYS_OS="macos"
41
+ NATS_OS="darwin"
42
+ ;;
43
+ Linux*)
44
+ SYS_OS="linux"
45
+ NATS_OS="linux"
46
+ ;;
47
+ *)
48
+ echo -e "${RED}Error: Unsupported OS: ${OS_TYPE}${NC}"
49
+ exit 1
50
+ ;;
51
+ esac
52
+
53
+ case "${ARCH_TYPE}" in
54
+ x86_64*)
55
+ SYS_ARCH="x64"
56
+ NATS_ARCH="amd64"
57
+ ;;
58
+ arm64*|aarch64*)
59
+ SYS_ARCH="arm64"
60
+ NATS_ARCH="arm64"
61
+ ;;
62
+ *)
63
+ echo -e "${RED}Error: Unsupported CPU Arch: ${ARCH_TYPE}${NC}"
64
+ exit 1
65
+ ;;
66
+ esac
67
+
68
+ echo -e "Platform: ${CYAN}${SYS_OS}-${SYS_ARCH}${NC}"
69
+
70
+ # Map OS names to binary release names
71
+ case "${SYS_OS}" in
72
+ macos) VCLAW_OS="darwin" ;;
73
+ *) VCLAW_OS="${SYS_OS}" ;;
74
+ esac
75
+
76
+ # -------------------------------------------------------------
77
+ # Step 2: Establish Sandboxed Folder Structure
78
+ # -------------------------------------------------------------
79
+ INSTALL_DIR="${HOME}/.local/bin"
80
+ DATA_DIR="${HOME}/.local/share/vclaw"
81
+ NATS_DB_DIR="${DATA_DIR}/nats-data"
82
+
83
+ mkdir -p "${INSTALL_DIR}"
84
+ mkdir -p "${DATA_DIR}"
85
+ mkdir -p "${NATS_DB_DIR}"
86
+
87
+ echo -e "Directories: ${CYAN}${DATA_DIR}${NC}"
88
+
89
+ # -------------------------------------------------------------
90
+ # Step 3: Install & Configure NATS Server (Leaf Node)
91
+ # -------------------------------------------------------------
92
+ echo -e "\n${YELLOW}[1/4] Installing Local NATS Messaging...${NC}"
93
+
94
+ NATS_VERSION="2.10.16"
95
+ NATS_URL="https://github.com/nats-io/nats-server/releases/download/v${NATS_VERSION}/nats-server-v${NATS_VERSION}-${NATS_OS}-${NATS_ARCH}.tar.gz"
96
+
97
+ if ! command -v nats-server &>/dev/null; then
98
+ echo " Fetching NATS Server v${NATS_VERSION}..."
99
+ TEMP_TAR=$(mktemp)
100
+ curl -fsSL "${NATS_URL}" -o "${TEMP_TAR}"
101
+ TEMP_EXTRACT=$(mktemp -d)
102
+ tar -xzf "${TEMP_TAR}" -C "${TEMP_EXTRACT}" --strip-components=1
103
+ mv "${TEMP_EXTRACT}/nats-server" "${INSTALL_DIR}/nats-server"
104
+ chmod +x "${INSTALL_DIR}/nats-server"
105
+ rm -f "${TEMP_TAR}"
106
+ rm -rf "${TEMP_EXTRACT}"
107
+ echo -e "${GREEN} ✔ NATS Server installed${NC}"
108
+ else
109
+ echo -e "${GREEN} ✔ NATS Server already present${NC}"
110
+ fi
111
+
112
+ # Generate NATS leaf-node config
113
+ cat << NATSCONF > "${DATA_DIR}/nats-leaf.conf"
114
+ # VClaw Local NATS Leaf Node
115
+ listen: 127.0.0.1:4222
116
+
117
+ jetstream {
118
+ store_dir: "${NATS_DB_DIR}"
119
+ }
120
+
121
+ websocket {
122
+ port: 9222
123
+ }
124
+ NATSCONF
125
+ echo -e "${GREEN} ✔ Config: ${DATA_DIR}/nats-leaf.conf${NC}"
126
+
127
+ # -------------------------------------------------------------
128
+ # Step 4: Install pi.dev CLI
129
+ # -------------------------------------------------------------
130
+ echo -e "\n${YELLOW}[2/4] Installing pi.dev CLI Agent...${NC}"
131
+
132
+ if command -v pi &>/dev/null; then
133
+ echo -e "${GREEN} ✔ pi.dev CLI already present${NC}"
134
+ else
135
+ echo " Installing @earendil-works/pi-coding-agent..."
136
+ if command -v bun &>/dev/null; then
137
+ bun install -g @earendil-works/pi-coding-agent && echo -e "${GREEN} ✔ pi.dev CLI installed${NC}" || {
138
+ echo -e "${RED} ⚠ Could not install pi.dev. Run: npm install -g @earendil-works/pi-coding-agent${NC}"
139
+ }
140
+ elif command -v npm &>/dev/null; then
141
+ npm install -g @earendil-works/pi-coding-agent && echo -e "${GREEN} ✔ pi.dev CLI installed${NC}" || {
142
+ echo -e "${RED} ⚠ Could not install pi.dev. Run: npm install -g @earendil-works/pi-coding-agent${NC}"
143
+ }
144
+ else
145
+ echo -e "${RED} ⚠ Need Node.js/npm to install pi.dev. Install Node.js first.${NC}"
146
+ fi
147
+ fi
148
+
149
+ # -------------------------------------------------------------
150
+ # Step 5: Install vclaw binary (optional)
151
+ # -------------------------------------------------------------
152
+ echo -e "\n${YELLOW}[3/4] Installing vclaw Logic Controller...${NC}"
153
+
154
+ VCLAW_BINARY_URL="https://github.com/VillageCity/vclaw-agent/releases/latest/download/vclaw-${VCLAW_OS}-${SYS_ARCH}"
155
+
156
+ TEMP_VCLAW=$(mktemp)
157
+ if curl -fsSL "${VCLAW_BINARY_URL}" -o "${TEMP_VCLAW}"; then
158
+ mv "${TEMP_VCLAW}" "${INSTALL_DIR}/vclaw"
159
+ chmod +x "${INSTALL_DIR}/vclaw"
160
+ echo -e "${GREEN} ✔ vclaw installed${NC}"
161
+ else
162
+ rm -f "${TEMP_VCLAW}"
163
+ echo -e "${YELLOW} ⚠ vclaw binary not yet available (coming soon). vclaw-up will skip the agent loop.${NC}"
164
+ fi
165
+
166
+ # -------------------------------------------------------------
167
+ # Step 6: Install Orchestration Script (vclaw-up)
168
+ # -------------------------------------------------------------
169
+ echo -e "\n${YELLOW}[4/4] Installing vclaw-up orchestrator...${NC}"
170
+
171
+ cat << 'UPEOF' > "${INSTALL_DIR}/vclaw-up"
172
+ #!/usr/bin/env bash
173
+ # vclaw-up — Unified stack launcher for the Local Agentic Mesh
174
+ #
175
+ # Starts NATS leaf node + vclaw agent + opens pi-web.dev.
176
+ # Optional: --onboard <email> to join the vchat.email network.
177
+ #
178
+ # Usage:
179
+ # vclaw-up - Launch the local stack
180
+ # vclaw-up --onboard <email> - Launch + onboard to vchat.email
181
+ # vclaw-up --stop - Stop all services
182
+ # vclaw-up --status - Show service status
183
+ # vclaw-up --help - Show this help
184
+ # vclaw-up --uninstall - Remove all binaries, config, and data
185
+ set -euo pipefail
186
+
187
+ DATA_DIR="${HOME}/.local/share/vclaw"
188
+ NATS_LOG="${DATA_DIR}/nats-server.log"
189
+ AGENT_LOG="${DATA_DIR}/vclaw-agent.log"
190
+ PID_FILE="${DATA_DIR}/.vclaw-up.pids"
191
+
192
+ mkdir -p "${DATA_DIR}"
193
+
194
+ # -- Help
195
+ if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
196
+ echo "vclaw-up -- Local Agentic Mesh Launcher"
197
+ echo ""
198
+ echo "Usage:"
199
+ echo " vclaw-up Start NATS + vclaw + pi-web.dev"
200
+ echo " vclaw-up --onboard <email> Also onboard this agent to vchat.email"
201
+ echo " vclaw-up --stop Stop all running services"
202
+ echo " vclaw-up --status Show service status"
203
+ echo " vclaw-up --uninstall Remove all binaries, config, and data"
204
+ echo " vclaw-up --help This message"
205
+ echo ""
206
+ echo "After starting, open another terminal and run:"
207
+ echo " nats sub \">\" -- Watch real-time agent messages"
208
+ exit 0
209
+ fi
210
+
211
+ # -- Stop
212
+ if [ "${1:-}" = "--stop" ]; then
213
+ echo "Stopping pi-web..."
214
+ pi-web stop 2>/dev/null || true
215
+ if [ -f "$PID_FILE" ]; then
216
+ read -r NATS_PID VCLAW_PID < "$PID_FILE" 2>/dev/null || true
217
+ echo "Stopping NATS (PID ${NATS_PID:-?})..."
218
+ kill "${NATS_PID:-}" 2>/dev/null || true
219
+ echo "Stopping vclaw agent (PID ${VCLAW_PID:-?})..."
220
+ kill "${VCLAW_PID:-}" 2>/dev/null || true
221
+ rm -f "$PID_FILE"
222
+ fi
223
+ echo "✔ All services stopped."
224
+ exit 0
225
+ fi
226
+
227
+ # -- Status
228
+ if [ "${1:-}" = "--status" ]; then
229
+ echo "vclaw-up -- Service Status"
230
+ echo ""
231
+ PI_WEB_STATUS="$(pi-web status 2>/dev/null || echo 'not running')"
232
+ echo " pi-web: ${PI_WEB_STATUS}"
233
+ if [ -f "$PID_FILE" ]; then
234
+ read -r NATS_PID VCLAW_PID < "$PID_FILE" 2>/dev/null || true
235
+ if kill -0 "${NATS_PID:-}" 2>/dev/null; then
236
+ echo " NATS server: running (PID $NATS_PID)"
237
+ else
238
+ echo " NATS server: not running"
239
+ fi
240
+ if kill -0 "${VCLAW_PID:-}" 2>/dev/null; then
241
+ echo " vclaw agent: running (PID $VCLAW_PID)"
242
+ else
243
+ echo " vclaw agent: not running"
244
+ fi
245
+ else
246
+ echo " NATS server: not running"
247
+ echo " vclaw agent: not running"
248
+ fi
249
+ echo ""
250
+ echo "Logs:"
251
+ echo " NATS: $NATS_LOG"
252
+ echo " Agent: $AGENT_LOG"
253
+ echo " pi-web: ${DATA_DIR}/pi-web.log"
254
+ exit 0
255
+ fi
256
+
257
+ # -- Uninstall
258
+ if [ "${1:-}" = "--uninstall" ]; then
259
+ echo "Stopping services..."
260
+ pi-web stop 2>/dev/null || true
261
+ if [ -f "$PID_FILE" ]; then
262
+ read -r NATS_PID VCLAW_PID < "$PID_FILE"
263
+ kill "$NATS_PID" 2>/dev/null || true
264
+ kill "$VCLAW_PID" 2>/dev/null || true
265
+ rm -f "$PID_FILE"
266
+ fi
267
+ echo "Removing binaries..."
268
+ rm -f "${HOME}/.local/bin/nats-server"
269
+ rm -f "${HOME}/.local/bin/pi"
270
+ rm -f "${HOME}/.local/bin/vclaw"
271
+ rm -f "${HOME}/.local/bin/vclaw-up"
272
+ echo "Removing config and data..."
273
+ rm -rf "${DATA_DIR}"
274
+ echo ""
275
+ echo "✔ VClaw Hub uninstalled."
276
+ echo " To remove packages installed globally via npm/Bun:"
277
+ echo " npm uninstall -g @jmfederico/pi-web @vchatemail/agent @earendil-works/pi-coding-agent"
278
+ echo " bun uninstall -g @jmfederico/pi-web @vchatemail/agent @earendil-works/pi-coding-agent"
279
+ exit 0
280
+ fi
281
+
282
+ # -- Handle --onboard
283
+ ONBOARD_EMAIL=""
284
+ if [ "${1:-}" = "--onboard" ]; then
285
+ ONBOARD_EMAIL="${2:-}"
286
+ if [ -z "$ONBOARD_EMAIL" ]; then
287
+ echo "Usage: vclaw-up --onboard <email>"
288
+ exit 1
289
+ fi
290
+ fi
291
+
292
+ echo "=== Initializing Local Agentic Mesh ==="
293
+ echo ""
294
+
295
+ # -- 1. Start NATS Leaf Node
296
+ NATS_CONF="${DATA_DIR}/nats-leaf.conf"
297
+ if [ ! -f "$NATS_CONF" ]; then
298
+ echo "Generating default NATS config..."
299
+ cat > "$NATS_CONF" << NATSEOF
300
+ listen: 127.0.0.1:4222
301
+ jetstream {
302
+ store_dir: "${DATA_DIR}/nats-data"
303
+ }
304
+ websocket {
305
+ port: 9222
306
+ }
307
+ NATSEOF
308
+ fi
309
+
310
+ echo "Starting local NATS Leaf Node server..."
311
+ nats-server -c "$NATS_CONF" > "$NATS_LOG" 2>&1 &
312
+ NATS_PID=$!
313
+ echo " PID: $NATS_PID"
314
+ sleep 1.5
315
+
316
+ # -- 2. Start vclaw agent
317
+ if command -v vclaw &>/dev/null; then
318
+ echo "Booting vclaw scheduler agent..."
319
+ vclaw run --daemon > "$AGENT_LOG" 2>&1 &
320
+ VCLAW_PID=$!
321
+ echo " PID: $VCLAW_PID"
322
+ else
323
+ echo " vclaw binary not found -- skipping agent loop."
324
+ VCLAW_PID=""
325
+ fi
326
+
327
+ # -- 3. Start pi-web
328
+ PI_WEB_PID=""
329
+ if command -v pi-web &>/dev/null; then
330
+ echo "Starting pi-web workspace..."
331
+ pi-web start > "${DATA_DIR}/pi-web.log" 2>&1 &
332
+ PI_WEB_PID=$!
333
+ echo " PID: $PI_WEB_PID"
334
+ else
335
+ echo " pi-web not found -- browser workspace unavailable."
336
+ echo " Install: npm install -g @jmfederico/pi-web && pi-web install"
337
+ fi
338
+
339
+ # -- Save PIDs
340
+ echo "$NATS_PID $VCLAW_PID" > "$PID_FILE"
341
+
342
+ # -- 4. Open browser
343
+ echo ""
344
+ echo "Opening pi-web.dev workspace..."
345
+ if [ -n "$PI_WEB_PID" ]; then
346
+ PI_WEB_URL="http://localhost:4321"
347
+ else
348
+ PI_WEB_URL="https://pi-web.dev/?connect=ws://127.0.0.1:9222"
349
+ fi
350
+ if [[ "$OSTYPE" == "darwin"* ]]; then
351
+ open "$PI_WEB_URL" 2>/dev/null || true
352
+ else
353
+ xdg-open "$PI_WEB_URL" &>/dev/null & true
354
+ fi
355
+ echo " URL: $PI_WEB_URL"
356
+
357
+ # -- 5. Optional onboard
358
+ if [ -n "$ONBOARD_EMAIL" ]; then
359
+ echo ""
360
+ echo "=== Joining vchat.email Network ==="
361
+ echo " Email: $ONBOARD_EMAIL"
362
+ if ! npx --yes @vchatemail/agent --version &>/dev/null 2>&1; then
363
+ echo "Installing @vchatemail/agent..."
364
+ npm install -g @vchatemail/agent 2>/dev/null || true
365
+ fi
366
+ npx @vchatemail/agent ensoul --email "$ONBOARD_EMAIL" || {
367
+ echo " Onboarding skipped. Retry: vchat-onboard.sh $ONBOARD_EMAIL"
368
+ }
369
+ fi
370
+
371
+ # -- Summary
372
+ echo ""
373
+ echo "--------------------------------------------------------"
374
+ echo "✔ Playground Active!"
375
+ echo " NATS Leaf Engine: PID $NATS_PID"
376
+ echo " vclaw Agent Loop: PID ${VCLAW_PID:-(not running)}"
377
+ echo " pi-web Workspace: PID ${PI_WEB_PID:-(not running)}"
378
+ echo ""
379
+ echo " Browse: ${PI_WEB_URL}"
380
+ echo ""
381
+ echo " Watch messages: nats sub \">\""
382
+ echo " View logs: tail -f ${NATS_LOG}"
383
+ echo " Stop everything: vclaw-up --stop"
384
+ echo "--------------------------------------------------------"
385
+
386
+ if [ -n "$VCLAW_PID" ]; then
387
+ wait $NATS_PID $VCLAW_PID 2>/dev/null || true
388
+ else
389
+ wait $NATS_PID 2>/dev/null || true
390
+ fi
391
+ UPEOF
392
+
393
+ chmod +x "${INSTALL_DIR}/vclaw-up"
394
+ echo -e "${GREEN} ✔ Orchestrator: vclaw-up${NC}"
395
+
396
+ # -------------------------------------------------------------
397
+ # Step 7: Install pi-web (local PI WEB workspace)
398
+ # -------------------------------------------------------------
399
+ echo -e "\n${YELLOW}[extras] Installing pi-web.dev workspace...${NC}"
400
+ if command -v pi-web &>/dev/null && pi-web version &>/dev/null; then
401
+ echo -e "${GREEN} ✔ pi-web already installed${NC}"
402
+ else
403
+ if command -v bun &>/dev/null; then
404
+ bun install -g @jmfederico/pi-web && echo -e "${GREEN} ✔ pi-web installed${NC}" || {
405
+ echo -e "${YELLOW} ⚠ Could not install pi-web via Bun. Trying npm...${NC}"
406
+ npm install -g @jmfederico/pi-web && echo -e "${GREEN} ✔ pi-web installed${NC}" || {
407
+ echo -e "${RED} ⚠ Could not install pi-web. Run: npm install -g @jmfederico/pi-web${NC}"
408
+ }
409
+ }
410
+ elif command -v npm &>/dev/null; then
411
+ npm install -g @jmfederico/pi-web && echo -e "${GREEN} ✔ pi-web installed${NC}" || {
412
+ echo -e "${RED} ⚠ Could not install pi-web. Run: npm install -g @jmfederico/pi-web${NC}"
413
+ }
414
+ else
415
+ echo -e "${RED} ⚠ Need npm to install pi-web. Install Node.js first.${NC}"
416
+ fi
417
+ fi
418
+
419
+ # Install pi-web user service (launchd for macOS, systemd for Linux)
420
+ if command -v pi-web &>/dev/null; then
421
+ pi-web install 2>/dev/null && echo -e "${GREEN} ✔ pi-web service registered${NC}" || \
422
+ echo -e "${YELLOW} ⚠ pi-web service registration skipped (user services may require manual setup)${NC}"
423
+ fi
424
+
425
+ # -------------------------------------------------------------
426
+ # Step 8: Install vchat-agent network CLI
427
+ # -------------------------------------------------------------
428
+ # Step 8: Finalize PATH
429
+ # -------------------------------------------------------------
430
+ echo -e "\n${BLUE}=== Post-Installation ===${NC}"
431
+
432
+ if [[ ":$PATH:" != *":${INSTALL_DIR}:"* ]]; then
433
+ if [ -n "$ZSH_VERSION" ]; then
434
+ PROFILE="${HOME}/.zshrc"
435
+ elif [ -n "$BASH_VERSION" ]; then
436
+ PROFILE="${HOME}/.bashrc"
437
+ else
438
+ PROFILE="${HOME}/.profile"
439
+ fi
440
+ echo "export PATH=\"\$PATH:${INSTALL_DIR}\"" >> "${PROFILE}"
441
+ echo -e " Added ${INSTALL_DIR} to PATH in ${PROFILE}"
442
+ fi
443
+
444
+ echo ""
445
+ echo -e "${GREEN}★ Setup complete! ★${NC}"
446
+ echo ""
447
+ echo " Quick start:"
448
+ echo " ${CYAN}vclaw-up${NC} Launch local mesh"
449
+ echo " ${CYAN}vclaw-up --onboard you@email.com${NC} Launch + join vchat.email network"
450
+ echo " ${CYAN}pi \"hello world\"${NC} Chat with Pi Agent"
451
+ echo ""
452
+ echo " Open a new terminal or: source ${PROFILE:-~/.profile}"
453
+ echo ""
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@vclawhub/vclaw",
3
+ "version": "0.2.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "VClaw Hub — one-command setup for pi.dev + pi-web.dev + NATS leaf node + vchat.email network",
7
+ "keywords": [
8
+ "pi-agent",
9
+ "pi-web",
10
+ "coding-agent",
11
+ "ai-agent",
12
+ "vclaw",
13
+ "vchat",
14
+ "nats",
15
+ "bun"
16
+ ],
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/VillageCity/vclaw-agent.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/VillageCity/vclaw-agent/issues"
24
+ },
25
+ "homepage": "https://vclawhub.com",
26
+ "bin": {
27
+ "vclaw": "./dist/cli.js"
28
+ },
29
+ "files": [
30
+ "dist/cli.js",
31
+ "install.sh",
32
+ "vclaw-up",
33
+ "config/nats-leaf.conf",
34
+ "scripts/"
35
+ ],
36
+ "scripts": {
37
+ "build": "bun build ./src/cli.ts --target=bun --outdir=dist",
38
+ "compile:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 ./src/cli.ts --outfile=dist/vclaw-darwin-arm64",
39
+ "compile:darwin-x64": "bun build --compile --target=bun-darwin-x64 ./src/cli.ts --outfile=dist/vclaw-darwin-x64",
40
+ "compile:linux-x64": "bun build --compile --target=bun-linux-x64 ./src/cli.ts --outfile=dist/vclaw-linux-x64",
41
+ "compile:linux-arm64": "bun build --compile --target=bun-linux-arm64 ./src/cli.ts --outfile=dist/vclaw-linux-arm64",
42
+ "compile:all": "bun run compile:darwin-arm64 && bun run compile:darwin-x64 && bun run compile:linux-x64 && bun run compile:linux-arm64",
43
+ "dev": "bun --watch ./src/cli.ts",
44
+ "prepublishOnly": "bun run build",
45
+ "start": "bun run ./src/cli.ts"
46
+ },
47
+ "engines": {
48
+ "bun": ">=1.2"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ }
53
+ }
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================
3
+ # vchat-onboard.sh — Join the vchat.email agent network
4
+ #
5
+ # Wraps @vchatemail/agent CLI for human+agent signup/login.
6
+ # Run this after vclaw-up to connect your agent to the mesh.
7
+ # ============================================================
8
+ set -euo pipefail
9
+
10
+ RED='\033[0;31m'
11
+ GREEN='\033[0;32m'
12
+ BLUE='\033[0;34m'
13
+ CYAN='\033[0;36m'
14
+ YELLOW='\033[0;33m'
15
+ NC='\033[0m'
16
+
17
+ echo -e "${BLUE}=== vchat.email Agent Network Onboarding ===${NC}"
18
+ echo ""
19
+ echo -e "This will register your local vclaw agent on the ${CYAN}vchat.email${NC} mesh."
20
+ echo -e "You'll need an email address and access to a browser to approve the agent."
21
+ echo ""
22
+
23
+ # ── Check for @vchatemail/agent ──────────────────────────────
24
+ if ! npx --yes @vchatemail/agent --version &>/dev/null 2>&1; then
25
+ echo -e "${YELLOW}Installing @vchatemail/agent...${NC}"
26
+ bun install -g @vchatemail/agent 2>/dev/null || npm install -g @vchatemail/agent
27
+ fi
28
+
29
+ # ── Collect email ─────────────────────────────────────────────
30
+ EMAIL="${1:-}"
31
+ if [ -z "$EMAIL" ]; then
32
+ read -r -p "Enter your email (steward account): " EMAIL
33
+ fi
34
+
35
+ if [ -z "$EMAIL" ]; then
36
+ echo -e "${RED}Error: Email is required.${NC}"
37
+ echo "Usage: vchat-onboard.sh <email>"
38
+ exit 1
39
+ fi
40
+
41
+ # ── Check existing credentials ────────────────────────────────
42
+ if npx @vchatemail/agent status 2>/dev/null | grep -q "Agent Identity"; then
43
+ echo -e "${YELLOW}⚠️ An agent is already onboarded on this machine.${NC}"
44
+ read -r -p "Overwrite existing credentials? (y/N): " CONFIRM
45
+ if [ "$CONFIRM" != "y" ] && [ "$CONFIRM" != "Y" ]; then
46
+ echo "Aborted."
47
+ exit 0
48
+ fi
49
+ FORCE="--force"
50
+ else
51
+ FORCE=""
52
+ fi
53
+
54
+ # ── Generate agent name ──────────────────────────────────────
55
+ HOSTNAME=$(hostname -s 2>/dev/null || echo "vclaw")
56
+ AGENT_NAME="vclaw-${HOSTNAME}"
57
+
58
+ echo ""
59
+ echo -e "Agent name: ${CYAN}${AGENT_NAME}${NC}"
60
+ echo -e "Steward: ${CYAN}${EMAIL}${NC}"
61
+ echo ""
62
+
63
+ # ── Run ensoul (introduce → claim → token) ───────────────────
64
+ echo -e "${BLUE}Starting onboarding flow...${NC}"
65
+ echo ""
66
+ echo -e "1. Generate Nkey identity"
67
+ echo -e "2. Introduce agent to vgate (${CYAN}https://api.vchat.email${NC})"
68
+ echo -e "3. Open browser for approval"
69
+ echo -e "4. Wait for claim (up to 5 min)"
70
+ echo -e "5. Store credentials to ${CYAN}~/.vchat/credentials.json${NC}"
71
+ echo ""
72
+
73
+ npx @vchatemail/agent ensoul \
74
+ --email "$EMAIL" \
75
+ --name "$AGENT_NAME" \
76
+ $FORCE
77
+
78
+ # ── Done ──────────────────────────────────────────────────────
79
+ echo ""
80
+ echo -e "${GREEN}★ Agent onboarded to vchat.email!${NC}"
81
+ echo ""
82
+ echo -e " Your agent is now visible at: ${CYAN}https://agents.vchat.email${NC}"
83
+ echo -e " Credentials: ${CYAN}~/.vchat/credentials.json${NC}"
84
+ echo ""
85
+ echo -e "Next: run ${CYAN}vclaw-up${NC} to start the local stack."
86
+ echo " Your agent will connect to the mesh via the local NATS leaf node."
87
+ echo ""
package/vclaw-up ADDED
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================
3
+ # vclaw-up — Unified stack launcher for the Local Agentic Mesh
4
+ #
5
+ # Starts NATS leaf node + vclaw agent + pi-web workspace.
6
+ # Optional: --onboard <email> to join the vchat.email network.
7
+ #
8
+ # Usage:
9
+ # vclaw-up — Launch the local stack
10
+ # vclaw-up --onboard <email> — Launch + onboard to vchat.email
11
+ # vclaw-up --stop — Stop all services
12
+ # vclaw-up --status — Show service status
13
+ # vclaw-up --help — Show this help
14
+ # vclaw-up --uninstall — Remove all binaries, config, data
15
+ # ============================================================
16
+ set -euo pipefail
17
+
18
+ DATA_DIR="${HOME}/.local/share/vclaw"
19
+ NATS_LOG="${DATA_DIR}/nats-server.log"
20
+ AGENT_LOG="${DATA_DIR}/vclaw-agent.log"
21
+ PID_FILE="${DATA_DIR}/.vclaw-up.pids"
22
+
23
+ mkdir -p "${DATA_DIR}"
24
+
25
+ # ── Help ──────────────────────────────────────────────────────
26
+ if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
27
+ echo "vclaw-up — Local Agentic Mesh Launcher"
28
+ echo ""
29
+ echo "Usage:"
30
+ echo " vclaw-up Start NATS + pi-web + vclaw"
31
+ echo " vclaw-up --onboard <email> Also onboard agent to vchat.email"
32
+ echo " vclaw-up --stop Stop all running services"
33
+ echo " vclaw-up --status Show service status"
34
+ echo " vclaw-up --uninstall Remove binaries, config, data"
35
+ echo " vclaw-up --help This message"
36
+ echo ""
37
+ echo "After starting, open another terminal and run:"
38
+ echo " nats sub \">\" — Watch real-time agent messages"
39
+ exit 0
40
+ fi
41
+
42
+ # ── Stop ──────────────────────────────────────────────────────
43
+ if [ "${1:-}" = "--stop" ]; then
44
+ echo "Stopping pi-web..."
45
+ pi-web stop 2>/dev/null || true
46
+ if [ -f "$PID_FILE" ]; then
47
+ read -r NATS_PID VCLAW_PID < "$PID_FILE" 2>/dev/null || true
48
+ echo "Stopping NATS (PID ${NATS_PID:-?})..."
49
+ kill "${NATS_PID:-}" 2>/dev/null || true
50
+ echo "Stopping vclaw agent (PID ${VCLAW_PID:-?})..."
51
+ kill "${VCLAW_PID:-}" 2>/dev/null || true
52
+ rm -f "$PID_FILE"
53
+ fi
54
+ echo "✔ All services stopped."
55
+ exit 0
56
+ fi
57
+
58
+ # ── Status ────────────────────────────────────────────────────
59
+ if [ "${1:-}" = "--status" ]; then
60
+ echo "vclaw-up — Service Status"
61
+ echo ""
62
+ PI_WEB_STATUS="$(pi-web status 2>/dev/null || echo 'not running')"
63
+ echo " pi-web: ${PI_WEB_STATUS}"
64
+ if [ -f "$PID_FILE" ]; then
65
+ read -r NATS_PID VCLAW_PID < "$PID_FILE" 2>/dev/null || true
66
+ if kill -0 "${NATS_PID:-}" 2>/dev/null; then
67
+ echo " NATS server: ✅ running (PID $NATS_PID)"
68
+ else
69
+ echo " NATS server: ❌ not running"
70
+ fi
71
+ if kill -0 "${VCLAW_PID:-}" 2>/dev/null; then
72
+ echo " vclaw agent: ✅ running (PID $VCLAW_PID)"
73
+ else
74
+ echo " vclaw agent: ❌ not running"
75
+ fi
76
+ else
77
+ echo " NATS server: ❌ not running"
78
+ echo " vclaw agent: ❌ not running"
79
+ fi
80
+ echo ""
81
+ echo "Logs:"
82
+ echo " NATS: $NATS_LOG"
83
+ echo " Agent: $AGENT_LOG"
84
+ echo " pi-web: ${DATA_DIR}/pi-web.log"
85
+ exit 0
86
+ fi
87
+
88
+ # ── Uninstall ─────────────────────────────────────────────────
89
+ if [ "${1:-}" = "--uninstall" ]; then
90
+ echo "Stopping services..."
91
+ pi-web stop 2>/dev/null || true
92
+ if [ -f "$PID_FILE" ]; then
93
+ read -r NATS_PID VCLAW_PID < "$PID_FILE"
94
+ kill "$NATS_PID" 2>/dev/null || true
95
+ kill "$VCLAW_PID" 2>/dev/null || true
96
+ rm -f "$PID_FILE"
97
+ fi
98
+ echo "Removing binaries..."
99
+ rm -f "${HOME}/.local/bin/nats-server"
100
+ rm -f "${HOME}/.local/bin/pi"
101
+ rm -f "${HOME}/.local/bin/vclaw"
102
+ rm -f "${HOME}/.local/bin/vclaw-up"
103
+ echo "Removing config and data..."
104
+ rm -rf "${DATA_DIR}"
105
+ echo ""
106
+ echo "✔ VClaw Hub uninstalled."
107
+ echo " To remove globally installed npm/Bun packages:"
108
+ echo " npm uninstall -g @jmfederico/pi-web @vchatemail/agent @earendil-works/pi-coding-agent"
109
+ echo " bun uninstall -g @jmfederico/pi-web @vchatemail/agent @earendil-works/pi-coding-agent"
110
+ exit 0
111
+ fi
112
+
113
+ # ── Handle --onboard ──────────────────────────────────────────
114
+ ONBOARD_EMAIL=""
115
+ if [ "${1:-}" = "--onboard" ]; then
116
+ ONBOARD_EMAIL="${2:-}"
117
+ if [ -z "$ONBOARD_EMAIL" ]; then
118
+ echo "❌ Usage: vclaw-up --onboard <email>"
119
+ exit 1
120
+ fi
121
+ fi
122
+
123
+ echo "██╗ ██╗ ██████╗██╗ █████╗ ██╗ ██╗"
124
+ echo "██║ ██║██╔════╝██║ ██╔══██╗██║ ██║"
125
+ echo "██║ ██║██║ ██║ ███████║██║ █╗ ██║"
126
+ echo "╚██╗ ██╔╝██║ ██║ ██╔══██║██║███╗██║"
127
+ echo " ╚████╔╝ ╚██████╗███████╗██║ ██║╚███╔███╔╝"
128
+ echo " ╚═══╝ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ "
129
+ echo ""
130
+ echo "=== Initializing Local Agentic Mesh ==="
131
+ echo ""
132
+
133
+ # ── 1. Start NATS Leaf Node ───────────────────────────────────
134
+ NATS_CONF="${DATA_DIR}/nats-leaf.conf"
135
+ if [ ! -f "$NATS_CONF" ]; then
136
+ echo "Generating default NATS config..."
137
+ cat > "$NATS_CONF" << NATSEOF
138
+ listen: 127.0.0.1:4222
139
+ jetstream {
140
+ store_dir: "${DATA_DIR}/nats-data"
141
+ }
142
+ websocket {
143
+ port: 9222
144
+ }
145
+ NATSEOF
146
+ fi
147
+
148
+ echo "Starting local NATS Leaf Node server..."
149
+ nats-server -c "$NATS_CONF" > "$NATS_LOG" 2>&1 &
150
+ NATS_PID=$!
151
+ echo " PID: $NATS_PID"
152
+ sleep 1.5
153
+
154
+ # ── 2. Start vclaw agent ──────────────────────────────────────
155
+ if command -v vclaw &>/dev/null; then
156
+ echo "Booting vclaw scheduler agent..."
157
+ vclaw run --daemon > "$AGENT_LOG" 2>&1 &
158
+ VCLAW_PID=$!
159
+ echo " PID: $VCLAW_PID"
160
+ else
161
+ echo " vclaw binary not found — skipping agent loop."
162
+ VCLAW_PID=""
163
+ fi
164
+
165
+ # ── 3. Start pi-web ────────────────────────────────────────────
166
+ PI_WEB_PID=""
167
+ if command -v pi-web &>/dev/null; then
168
+ echo "Starting pi-web workspace..."
169
+ pi-web start > "${DATA_DIR}/pi-web.log" 2>&1 &
170
+ PI_WEB_PID=$!
171
+ echo " PID: $PI_WEB_PID"
172
+ else
173
+ echo " pi-web not found — browser workspace unavailable."
174
+ echo " Install: npm install -g @jmfederico/pi-web && pi-web install"
175
+ fi
176
+
177
+ # ── Save PIDs ──────────────────────────────────────────────────
178
+ echo "$NATS_PID $VCLAW_PID" > "$PID_FILE"
179
+
180
+ # ── 4. Open browser workspace ─────────────────────────────────
181
+ echo ""
182
+ echo "Opening pi-web workspace..."
183
+ if [ -n "$PI_WEB_PID" ]; then
184
+ PI_WEB_URL="http://localhost:4321"
185
+ else
186
+ PI_WEB_URL="https://pi-web.dev/?connect=ws://127.0.0.1:9222"
187
+ fi
188
+ if [[ "$OSTYPE" == "darwin"* ]]; then
189
+ open "$PI_WEB_URL" 2>/dev/null || true
190
+ else
191
+ xdg-open "$PI_WEB_URL" &>/dev/null & true
192
+ fi
193
+ echo " URL: $PI_WEB_URL"
194
+
195
+ # ── 5. Optional: Onboard to vchat.email ────────────────────────
196
+ if [ -n "$ONBOARD_EMAIL" ]; then
197
+ echo ""
198
+ echo "=== Joining vchat.email Network ==="
199
+ echo " Email: $ONBOARD_EMAIL"
200
+ echo ""
201
+
202
+ if ! npx --yes @vchatemail/agent --version &>/dev/null 2>&1; then
203
+ echo "Installing @vchatemail/agent..."
204
+ npm install -g @vchatemail/agent 2>/dev/null || true
205
+ fi
206
+
207
+ npx @vchatemail/agent ensoul --email "$ONBOARD_EMAIL" || {
208
+ echo "⚠️ Onboarding skipped or failed. You can retry with:"
209
+ echo " vchat-onboard.sh $ONBOARD_EMAIL"
210
+ }
211
+ fi
212
+
213
+ # ── Summary ────────────────────────────────────────────────────
214
+ echo ""
215
+ echo "--------------------------------------------------------"
216
+ echo "✔ Playground Active!"
217
+ echo " NATS Leaf Engine: PID $NATS_PID"
218
+ echo " vclaw Agent Loop: PID ${VCLAW_PID:-(not running)}"
219
+ echo " pi-web Workspace: PID ${PI_WEB_PID:-(not running)}"
220
+ echo ""
221
+ echo " Browse: ${PI_WEB_URL}"
222
+ if [ -n "$ONBOARD_EMAIL" ]; then
223
+ echo " vchat.email: ✅ Onboarded as ${ONBOARD_EMAIL}"
224
+ fi
225
+ echo ""
226
+ echo " Watch messages: nats sub \">\""
227
+ echo " View logs: tail -f ${NATS_LOG}"
228
+ echo " Stop everything: vclaw-up --stop"
229
+ echo "--------------------------------------------------------"
230
+
231
+ # Keep alive if run in foreground
232
+ if [ -n "$VCLAW_PID" ]; then
233
+ wait $NATS_PID $VCLAW_PID 2>/dev/null || true
234
+ else
235
+ wait $NATS_PID 2>/dev/null || true
236
+ fi