@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 +310 -0
- package/config/nats-leaf.conf +31 -0
- package/dist/cli.js +95 -0
- package/install.sh +453 -0
- package/package.json +53 -0
- package/scripts/vchat-onboard.sh +87 -0
- package/vclaw-up +236 -0
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
|