patchwork-os 0.2.0-beta.12.canary.240 → 0.2.0-beta.12.canary.242
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/dist/fp/commandDescription.js +3 -0
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.js +2 -2
- package/package.json +6 -2
- package/deploy/README.md +0 -172
- package/deploy/bootstrap-new-vps.sh +0 -364
- package/deploy/bootstrap-vps.sh +0 -192
- package/deploy/claude-ide-bridge.service.template +0 -67
- package/deploy/claude-ide-bridge@.service +0 -31
- package/deploy/deploy-dashboard.sh +0 -198
- package/deploy/deploy-landing.sh +0 -136
- package/deploy/ecosystem.config.js.example +0 -36
- package/deploy/install-vps-service.sh +0 -240
- package/deploy/macos/README.md +0 -153
- package/deploy/macos/com.patchwork.bridge.plist.template +0 -54
- package/deploy/macos/com.patchwork.tunnel.plist.template +0 -76
- package/deploy/macos/install-mac-bridge.sh +0 -244
- package/deploy/macos/uninstall-mac-bridge.sh +0 -22
- package/deploy/nginx-claude-bridge.conf.template +0 -129
- package/deploy/qumo-liq-collector.mjs +0 -106
- package/deploy/qumo-liq-collector.service +0 -19
|
@@ -56,6 +56,9 @@ export const DANGEROUS_FLAGS_FOR_COMMAND = {
|
|
|
56
56
|
npm: new Set(["--node-options"]),
|
|
57
57
|
yarn: new Set(["--node-options"]),
|
|
58
58
|
pnpm: new Set(["--node-options"]),
|
|
59
|
+
// npx runs an arbitrary package binary, so --node-options is the same
|
|
60
|
+
// interpreter-bypass vector as npm/yarn/pnpm (H10 sibling — was missed).
|
|
61
|
+
npx: new Set(["--node-options"]),
|
|
59
62
|
};
|
|
60
63
|
export const PATH_FLAG_EXEMPTIONS = {
|
|
61
64
|
psql: new Set(["--config"]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandDescription.js","sourceRoot":"","sources":["../../src/fp/commandDescription.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,sEAAsE;AACtE,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IACjD,IAAI;IACJ,QAAQ;IACR,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,cAAc;IACd,UAAU;IACV,UAAU;IACV,uBAAuB;IACvB,IAAI;IACJ,WAAW;IACX,eAAe;IACf,gBAAgB;CACjB,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IAC1C,UAAU;IACV,iBAAiB;IACjB,UAAU;IACV,UAAU;IACV,WAAW;IACX,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,IAAI;IACJ,UAAU;IACV,IAAI;IACJ,eAAe;IACf,IAAI;IACJ,eAAe;IACf,IAAI;IACJ,eAAe;IACf,wBAAwB;IACxB,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAgC;IACtE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/B,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACpC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1B,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IACpB,6EAA6E;IAC7E,0EAA0E;IAC1E,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAChC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"commandDescription.js","sourceRoot":"","sources":["../../src/fp/commandDescription.ts"],"names":[],"mappings":"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"}
|
|
@@ -154,10 +154,10 @@ function bulletLines(lines) {
|
|
|
154
154
|
/**
|
|
155
155
|
* Extract display names / emails from a line of inline chips. Handles three
|
|
156
156
|
* formats Drive emits across export modes:
|
|
157
|
-
* 1. Markdown link form: `[
|
|
157
|
+
* 1. Markdown link form: `[Jane Doe](mailto:jane@example.com)`
|
|
158
158
|
* 2. Tab / 2+ space separated tokens (markdown export of bare chips)
|
|
159
159
|
* 3. Single-space separated tokens with emails as boundaries
|
|
160
|
-
* (`text/plain` export form): `
|
|
160
|
+
* (`text/plain` export form): `alice@example.com Jane Doe jane@example.com`
|
|
161
161
|
* where multi-word names are several capitalised tokens in a row.
|
|
162
162
|
*/
|
|
163
163
|
function extractChips(line) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "patchwork-os",
|
|
3
|
-
"version": "0.2.0-beta.12.canary.
|
|
3
|
+
"version": "0.2.0-beta.12.canary.242",
|
|
4
4
|
"description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -64,6 +64,11 @@
|
|
|
64
64
|
"dist",
|
|
65
65
|
"!dist/__tests__",
|
|
66
66
|
"!dist/**/__tests__",
|
|
67
|
+
"!dist/recipes/tools/altscan.*",
|
|
68
|
+
"!dist/recipes/tools/market.*",
|
|
69
|
+
"!dist/recipes/tools/ta.*",
|
|
70
|
+
"!dist/recipes/tools/taLedger.*",
|
|
71
|
+
"!dist/recipes/tools/watchlist.*",
|
|
67
72
|
"scripts/start-all.sh",
|
|
68
73
|
"scripts/start-all.mjs",
|
|
69
74
|
"scripts/start-all.ps1",
|
|
@@ -79,7 +84,6 @@
|
|
|
79
84
|
"scripts/gen-claude-desktop-config.sh",
|
|
80
85
|
"scripts/smoke/run-all.mjs",
|
|
81
86
|
"templates",
|
|
82
|
-
"deploy",
|
|
83
87
|
"LICENSE",
|
|
84
88
|
"README.md"
|
|
85
89
|
],
|
package/deploy/README.md
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# Deploy
|
|
2
|
-
|
|
3
|
-
Production VPS deployment files for claude-ide-bridge.
|
|
4
|
-
|
|
5
|
-
> **Deployment targets:** The **systemd + nginx** path (this directory) is the
|
|
6
|
-
> production-supported deployment for VPS/remote use. A `Dockerfile` and
|
|
7
|
-
> `docker-compose.yml` exist in the repo root as an alternative for
|
|
8
|
-
> containerised environments, but are not actively tested against the systemd
|
|
9
|
-
> config — if you use Docker, treat it as a community-supported path and keep
|
|
10
|
-
> it in sync with any service config changes.
|
|
11
|
-
|
|
12
|
-
## Files
|
|
13
|
-
|
|
14
|
-
| File | Purpose |
|
|
15
|
-
|------|---------|
|
|
16
|
-
| `bootstrap-new-vps.sh` | **Full fresh-server setup** — Node.js, clone, build, user, firewall, systemd, nginx, Certbot |
|
|
17
|
-
| `install-vps-service.sh` | **Idempotent updater** — re-installs service + nginx after `git pull` on an existing server |
|
|
18
|
-
| `nginx-claude-bridge.conf.template` | nginx config reference (domain + port injected by scripts) |
|
|
19
|
-
| `claude-ide-bridge.service.template` | systemd unit reference (paths + user injected by scripts) |
|
|
20
|
-
| `claude-ide-bridge@.service` | Template unit for multi-user demo instances (alternate pattern) |
|
|
21
|
-
| `ecosystem.config.js.example` | PM2 ecosystem config template (alternative to systemd) |
|
|
22
|
-
|
|
23
|
-
## First-time setup (new VPS)
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Option A: run remotely on fresh server
|
|
27
|
-
DOMAIN=bridge.example.com bash <(curl -fsSL https://raw.githubusercontent.com/Oolab-labs/claude-ide-bridge/main/deploy/bootstrap-new-vps.sh)
|
|
28
|
-
|
|
29
|
-
# Option B: after cloning the repo
|
|
30
|
-
DOMAIN=bridge.example.com bash deploy/bootstrap-new-vps.sh
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
The bootstrap script handles everything end-to-end:
|
|
34
|
-
1. Installs Node.js 22, nginx, certbot
|
|
35
|
-
2. Creates a dedicated `claude-bridge` system user (non-root)
|
|
36
|
-
3. Clones the repo to `/opt/claude-ide-bridge`
|
|
37
|
-
4. Runs `npm ci && npm run build`
|
|
38
|
-
5. Generates `.env.vps` with a random auth token
|
|
39
|
-
6. Opens ports 80/443 in ufw
|
|
40
|
-
7. Installs and enables the systemd service
|
|
41
|
-
8. Writes the nginx config with your domain injected
|
|
42
|
-
9. Runs Certbot for HTTPS
|
|
43
|
-
10. Starts the bridge and confirms it's healthy
|
|
44
|
-
|
|
45
|
-
**Required:** `DOMAIN` env var pointing to a subdomain that resolves to your VPS IP.
|
|
46
|
-
|
|
47
|
-
**Optional overrides:**
|
|
48
|
-
|
|
49
|
-
| Variable | Default | Description |
|
|
50
|
-
|----------|---------|-------------|
|
|
51
|
-
| `REPO_URL` | GitHub upstream | Git repo to clone |
|
|
52
|
-
| `INSTALL_DIR` | `/opt/claude-ide-bridge` | Where to install |
|
|
53
|
-
| `SERVICE_USER` | `claude-bridge` | System user to run as |
|
|
54
|
-
| `PORT` | `9000` | Bridge listen port |
|
|
55
|
-
| `BRANCH` | `main` | Git branch |
|
|
56
|
-
| `SKIP_CERTBOT` | `0` | Set to `1` to skip TLS (DNS not ready) |
|
|
57
|
-
|
|
58
|
-
## Updating an existing server
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
cd /opt/claude-ide-bridge # or wherever INSTALL_DIR is
|
|
62
|
-
git pull
|
|
63
|
-
npm ci
|
|
64
|
-
npm run build
|
|
65
|
-
bash deploy/install-vps-service.sh
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
`install-vps-service.sh` re-generates the systemd unit and nginx config from the current state of `.env.vps`, then restarts the service automatically. It auto-detects the domain and service user from the existing installation — no config needed.
|
|
69
|
-
|
|
70
|
-
## Day-to-day management
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# View live logs
|
|
74
|
-
journalctl -u claude-ide-bridge -f
|
|
75
|
-
|
|
76
|
-
# Check status
|
|
77
|
-
systemctl status claude-ide-bridge
|
|
78
|
-
|
|
79
|
-
# Restart after code change
|
|
80
|
-
npm run build && systemctl restart claude-ide-bridge
|
|
81
|
-
|
|
82
|
-
# Stop (won't restart until manually started)
|
|
83
|
-
systemctl stop claude-ide-bridge
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Using PM2 instead of systemd
|
|
87
|
-
|
|
88
|
-
PM2 is a simpler alternative when you're running as root, already have PM2 installed, or prefer not to configure systemd manually.
|
|
89
|
-
|
|
90
|
-
> **Important:** The bridge picks a **random port** by default. The port in your PM2 start command **must match** the port in your nginx `proxy_pass` directive, or every restart will cause a 502 Bad Gateway.
|
|
91
|
-
|
|
92
|
-
### Quick start with PM2
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# Replace 4748 and YOUR_TOKEN_HERE with your nginx proxy_pass port and auth token
|
|
96
|
-
pm2 delete claude-bridge 2>/dev/null || true
|
|
97
|
-
pm2 start /root/claude-ide-bridge/dist/index.js \
|
|
98
|
-
--name claude-bridge \
|
|
99
|
-
-- --port 4748 --bind 0.0.0.0 --vps --fixed-token YOUR_TOKEN_HERE
|
|
100
|
-
pm2 save
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Retrieve your token anytime:
|
|
104
|
-
```bash
|
|
105
|
-
cat ~/.claude/ide/*.lock | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8').trim(); console.log(JSON.parse(d).authToken)"
|
|
106
|
-
# or if you have a .env.vps:
|
|
107
|
-
grep FIXED_TOKEN /root/claude-ide-bridge/.env.vps
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Persist across reboots
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
# Generate and run the startup command PM2 prints
|
|
114
|
-
pm2 startup
|
|
115
|
-
# (run the command it outputs, then:)
|
|
116
|
-
pm2 save
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Using an ecosystem file
|
|
120
|
-
|
|
121
|
-
For repeatable deployments, use the included example:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
cp deploy/ecosystem.config.js.example ecosystem.config.js
|
|
125
|
-
# Edit ecosystem.config.js: set cwd, port, and fixed-token
|
|
126
|
-
pm2 start ecosystem.config.js
|
|
127
|
-
pm2 save
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Day-to-day management with PM2
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# View live logs
|
|
134
|
-
pm2 logs claude-bridge
|
|
135
|
-
|
|
136
|
-
# Check status
|
|
137
|
-
pm2 status
|
|
138
|
-
|
|
139
|
-
# Restart after code change
|
|
140
|
-
npm run build && pm2 restart claude-bridge
|
|
141
|
-
|
|
142
|
-
# Stop
|
|
143
|
-
pm2 stop claude-bridge
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## MCP endpoint
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
https://<your-domain>/mcp
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Use in `.mcp.json` for Claude Desktop, claude.ai Custom Connectors, or any remote MCP client:
|
|
153
|
-
|
|
154
|
-
```json
|
|
155
|
-
{
|
|
156
|
-
"mcpServers": {
|
|
157
|
-
"claude-ide-bridge": {
|
|
158
|
-
"type": "http",
|
|
159
|
-
"url": "https://your-domain/mcp",
|
|
160
|
-
"headers": {
|
|
161
|
-
"Authorization": "Bearer ${BRIDGE_TOKEN}"
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Set `BRIDGE_TOKEN` in your shell profile. Retrieve the token anytime:
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
grep FIXED_TOKEN /opt/claude-ide-bridge/.env.vps
|
|
172
|
-
```
|
|
@@ -1,364 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# deploy/bootstrap-new-vps.sh
|
|
3
|
-
# Full fresh-server setup for patchwork-os on a NEW VPS.
|
|
4
|
-
# Handles everything from Node.js install to running HTTPS service.
|
|
5
|
-
#
|
|
6
|
-
# Usage (run as root on a fresh Ubuntu 22.04/24.04 VPS):
|
|
7
|
-
# curl -fsSL https://raw.githubusercontent.com/Oolab-labs/patchwork-os/main/deploy/bootstrap-new-vps.sh | \
|
|
8
|
-
# DOMAIN=bridge.example.com bash
|
|
9
|
-
#
|
|
10
|
-
# Or after cloning:
|
|
11
|
-
# DOMAIN=bridge.example.com bash deploy/bootstrap-new-vps.sh
|
|
12
|
-
#
|
|
13
|
-
# Required environment variables:
|
|
14
|
-
# DOMAIN Subdomain for the bridge (e.g. bridge.example.com)
|
|
15
|
-
#
|
|
16
|
-
# Optional environment variables:
|
|
17
|
-
# REPO_URL Git repo URL (default: https://github.com/Oolab-labs/patchwork-os)
|
|
18
|
-
# INSTALL_DIR Where to clone the repo (default: /opt/patchwork-os)
|
|
19
|
-
# SERVICE_USER System user to run bridge (default: patchwork)
|
|
20
|
-
# PORT Bridge port (default: 9000)
|
|
21
|
-
# BRANCH Git branch to clone (default: main)
|
|
22
|
-
# SKIP_CERTBOT Set to 1 to skip TLS cert (useful if DNS not yet set)
|
|
23
|
-
|
|
24
|
-
set -euo pipefail
|
|
25
|
-
|
|
26
|
-
# ── Config ────────────────────────────────────────────────────────────────────
|
|
27
|
-
DOMAIN="${DOMAIN:-}"
|
|
28
|
-
REPO_URL="${REPO_URL:-https://github.com/Oolab-labs/patchwork-os}"
|
|
29
|
-
INSTALL_DIR="${INSTALL_DIR:-/opt/patchwork-os}"
|
|
30
|
-
SERVICE_USER="${SERVICE_USER:-patchwork}"
|
|
31
|
-
PORT="${PORT:-9000}"
|
|
32
|
-
BRANCH="${BRANCH:-main}"
|
|
33
|
-
SKIP_CERTBOT="${SKIP_CERTBOT:-0}"
|
|
34
|
-
SERVICE_NAME="patchwork-os"
|
|
35
|
-
|
|
36
|
-
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
|
37
|
-
info() { echo -e "${GREEN}✓${NC} $*"; }
|
|
38
|
-
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
|
|
39
|
-
err() { echo -e "${RED}✗${NC} $*" >&2; }
|
|
40
|
-
section() { echo ""; echo "── $* ──────────────────────────────────────────"; }
|
|
41
|
-
|
|
42
|
-
# ── Pre-flight ────────────────────────────────────────────────────────────────
|
|
43
|
-
section "Pre-flight"
|
|
44
|
-
|
|
45
|
-
[[ "$(id -u)" -eq 0 ]] || { err "Run as root: sudo bash deploy/bootstrap-new-vps.sh"; exit 1; }
|
|
46
|
-
|
|
47
|
-
if [[ -z "$DOMAIN" ]]; then
|
|
48
|
-
err "DOMAIN is required. Example:"
|
|
49
|
-
echo " DOMAIN=bridge.example.com bash deploy/bootstrap-new-vps.sh"
|
|
50
|
-
exit 1
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
info "Domain: $DOMAIN"
|
|
54
|
-
info "Install dir: $INSTALL_DIR"
|
|
55
|
-
info "Service user: $SERVICE_USER"
|
|
56
|
-
info "Port: $PORT"
|
|
57
|
-
info "Branch: $BRANCH"
|
|
58
|
-
|
|
59
|
-
# ── 1. System packages ────────────────────────────────────────────────────────
|
|
60
|
-
section "System packages"
|
|
61
|
-
|
|
62
|
-
apt-get update -qq
|
|
63
|
-
apt-get install -y -qq curl git nginx certbot python3-certbot-nginx ufw
|
|
64
|
-
info "System packages installed"
|
|
65
|
-
|
|
66
|
-
# ── 2. Node.js 20+ ────────────────────────────────────────────────────────────
|
|
67
|
-
section "Node.js"
|
|
68
|
-
|
|
69
|
-
NODE_OK=false
|
|
70
|
-
if command -v node &>/dev/null; then
|
|
71
|
-
NODE_VER=$(node -e 'console.log(parseInt(process.version.slice(1)))')
|
|
72
|
-
[[ "$NODE_VER" -ge 20 ]] && NODE_OK=true
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
if [[ "$NODE_OK" == false ]]; then
|
|
76
|
-
info "Installing Node.js 20..."
|
|
77
|
-
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|
78
|
-
apt-get install -y -qq nodejs
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
NODE_VERSION=$(node --version)
|
|
82
|
-
info "Node $NODE_VERSION / npm $(npm --version)"
|
|
83
|
-
|
|
84
|
-
# ── 3. Service user ───────────────────────────────────────────────────────────
|
|
85
|
-
section "Service user"
|
|
86
|
-
|
|
87
|
-
if ! id "$SERVICE_USER" &>/dev/null; then
|
|
88
|
-
useradd --system --create-home --shell /bin/bash "$SERVICE_USER"
|
|
89
|
-
info "Created user: $SERVICE_USER"
|
|
90
|
-
else
|
|
91
|
-
info "User already exists: $SERVICE_USER"
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
# ── 4. Clone or update repo ───────────────────────────────────────────────────
|
|
95
|
-
section "Repository"
|
|
96
|
-
|
|
97
|
-
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
|
98
|
-
info "Repo exists — pulling latest..."
|
|
99
|
-
git -C "$INSTALL_DIR" fetch origin
|
|
100
|
-
git -C "$INSTALL_DIR" checkout "$BRANCH"
|
|
101
|
-
git -C "$INSTALL_DIR" pull origin "$BRANCH"
|
|
102
|
-
else
|
|
103
|
-
info "Cloning $REPO_URL..."
|
|
104
|
-
git clone --branch "$BRANCH" --depth 1 "$REPO_URL" "$INSTALL_DIR"
|
|
105
|
-
fi
|
|
106
|
-
|
|
107
|
-
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
|
|
108
|
-
info "Repo ready at $INSTALL_DIR"
|
|
109
|
-
|
|
110
|
-
# ── 5. Build ──────────────────────────────────────────────────────────────────
|
|
111
|
-
section "Build"
|
|
112
|
-
|
|
113
|
-
# Run npm install + build as SERVICE_USER
|
|
114
|
-
sudo -u "$SERVICE_USER" bash -c "cd $INSTALL_DIR && npm ci --prefer-offline 2>&1"
|
|
115
|
-
sudo -u "$SERVICE_USER" bash -c "cd $INSTALL_DIR && npm run build 2>&1"
|
|
116
|
-
info "Build complete"
|
|
117
|
-
|
|
118
|
-
# ── 6. Generate .env.vps ──────────────────────────────────────────────────────
|
|
119
|
-
section ".env.vps"
|
|
120
|
-
|
|
121
|
-
ENV_FILE="$INSTALL_DIR/.env.vps"
|
|
122
|
-
if [[ -f "$ENV_FILE" ]]; then
|
|
123
|
-
warn ".env.vps already exists — leaving unchanged"
|
|
124
|
-
source "$ENV_FILE"
|
|
125
|
-
info " PORT=$PORT WORKSPACE=$WORKSPACE TOKEN=***"
|
|
126
|
-
else
|
|
127
|
-
FIXED_TOKEN=$(node -e "console.log(require('crypto').randomUUID())")
|
|
128
|
-
WORKSPACE="$INSTALL_DIR"
|
|
129
|
-
cat > "$ENV_FILE" <<EOF
|
|
130
|
-
# Claude IDE Bridge — VPS config
|
|
131
|
-
# Generated by bootstrap-new-vps.sh on $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
132
|
-
# Gitignored — never commit this file.
|
|
133
|
-
|
|
134
|
-
PORT=$PORT
|
|
135
|
-
WORKSPACE=$WORKSPACE
|
|
136
|
-
FIXED_TOKEN=$FIXED_TOKEN
|
|
137
|
-
BRIDGE_SESSION=bridge
|
|
138
|
-
NGROK_SESSION=ngrok
|
|
139
|
-
EOF
|
|
140
|
-
chmod 600 "$ENV_FILE"
|
|
141
|
-
chown "$SERVICE_USER:$SERVICE_USER" "$ENV_FILE"
|
|
142
|
-
info ".env.vps created"
|
|
143
|
-
info " PORT=$PORT"
|
|
144
|
-
info " WORKSPACE=$WORKSPACE"
|
|
145
|
-
info " TOKEN=$FIXED_TOKEN"
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
# Reload in case it already existed
|
|
149
|
-
source "$ENV_FILE"
|
|
150
|
-
|
|
151
|
-
# ── 7. Firewall ───────────────────────────────────────────────────────────────
|
|
152
|
-
section "Firewall (ufw)"
|
|
153
|
-
|
|
154
|
-
ufw --force enable >/dev/null 2>&1 || true
|
|
155
|
-
ufw allow ssh >/dev/null 2>&1
|
|
156
|
-
ufw allow 80 >/dev/null 2>&1
|
|
157
|
-
ufw allow 443 >/dev/null 2>&1
|
|
158
|
-
info "ufw: ssh, 80, 443 open"
|
|
159
|
-
|
|
160
|
-
# ── 8. Systemd service ────────────────────────────────────────────────────────
|
|
161
|
-
section "Systemd service"
|
|
162
|
-
|
|
163
|
-
# Generate service file from template (parameterised for this install)
|
|
164
|
-
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<SERVICE
|
|
165
|
-
[Unit]
|
|
166
|
-
Description=Patchwork OS bridge
|
|
167
|
-
Documentation=https://github.com/Oolab-labs/patchwork-os
|
|
168
|
-
After=network.target
|
|
169
|
-
StartLimitIntervalSec=120
|
|
170
|
-
StartLimitBurst=5
|
|
171
|
-
|
|
172
|
-
[Service]
|
|
173
|
-
Type=simple
|
|
174
|
-
User=$SERVICE_USER
|
|
175
|
-
WorkingDirectory=$INSTALL_DIR
|
|
176
|
-
|
|
177
|
-
# Load config — FIXED_TOKEN, PORT, WORKSPACE
|
|
178
|
-
EnvironmentFile=$ENV_FILE
|
|
179
|
-
|
|
180
|
-
# Bridge process
|
|
181
|
-
ExecStart=/usr/bin/node $INSTALL_DIR/dist/index.js \\
|
|
182
|
-
--port \${PORT} \\
|
|
183
|
-
--workspace \${WORKSPACE} \\
|
|
184
|
-
--fixed-token \${FIXED_TOKEN} \\
|
|
185
|
-
--grace-period 120000 \\
|
|
186
|
-
--vps
|
|
187
|
-
|
|
188
|
-
KillMode=mixed
|
|
189
|
-
KillSignal=SIGTERM
|
|
190
|
-
TimeoutStopSec=15
|
|
191
|
-
Restart=always
|
|
192
|
-
RestartSec=5
|
|
193
|
-
|
|
194
|
-
StandardOutput=journal
|
|
195
|
-
StandardError=journal
|
|
196
|
-
SyslogIdentifier=patchwork-os
|
|
197
|
-
|
|
198
|
-
NoNewPrivileges=true
|
|
199
|
-
PrivateTmp=true
|
|
200
|
-
|
|
201
|
-
[Install]
|
|
202
|
-
WantedBy=multi-user.target
|
|
203
|
-
SERVICE
|
|
204
|
-
|
|
205
|
-
systemctl daemon-reload
|
|
206
|
-
systemctl enable "$SERVICE_NAME"
|
|
207
|
-
info "Systemd service installed and enabled"
|
|
208
|
-
|
|
209
|
-
# ── 9. nginx ──────────────────────────────────────────────────────────────────
|
|
210
|
-
section "nginx"
|
|
211
|
-
|
|
212
|
-
# Add connection_upgrade map to nginx.conf if missing
|
|
213
|
-
if ! grep -q "connection_upgrade" /etc/nginx/nginx.conf 2>/dev/null; then
|
|
214
|
-
# Insert after the `http {` line
|
|
215
|
-
perl -i -0pe 's/(http \{)/$1\n map \$http_upgrade \$connection_upgrade {\n default upgrade;\n '"''"' close;\n }/' /etc/nginx/nginx.conf
|
|
216
|
-
info "Added connection_upgrade map to nginx.conf"
|
|
217
|
-
fi
|
|
218
|
-
|
|
219
|
-
# Write nginx site config (domain injected here, not hardcoded in repo)
|
|
220
|
-
cat > "/etc/nginx/sites-available/claude-bridge" <<NGINX
|
|
221
|
-
# Claude IDE Bridge — nginx reverse proxy
|
|
222
|
-
# Domain: $DOMAIN Port: ${PORT}
|
|
223
|
-
# Generated by bootstrap-new-vps.sh
|
|
224
|
-
|
|
225
|
-
server {
|
|
226
|
-
listen 80;
|
|
227
|
-
listen [::]:80;
|
|
228
|
-
server_name $DOMAIN;
|
|
229
|
-
|
|
230
|
-
location /.well-known/acme-challenge/ {
|
|
231
|
-
root /var/www/html;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
location / {
|
|
235
|
-
return 301 https://\$host\$request_uri;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
server {
|
|
240
|
-
listen 443 ssl http2;
|
|
241
|
-
listen [::]:443 ssl http2;
|
|
242
|
-
server_name $DOMAIN;
|
|
243
|
-
|
|
244
|
-
# TLS — populated by Certbot
|
|
245
|
-
# ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
|
246
|
-
# ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
|
247
|
-
# include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
248
|
-
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
249
|
-
|
|
250
|
-
add_header X-Content-Type-Options nosniff always;
|
|
251
|
-
add_header X-Frame-Options DENY always;
|
|
252
|
-
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
253
|
-
|
|
254
|
-
# /mcp — Streamable HTTP MCP endpoint (SSE-safe)
|
|
255
|
-
location /mcp {
|
|
256
|
-
proxy_pass http://127.0.0.1:${PORT};
|
|
257
|
-
proxy_http_version 1.1;
|
|
258
|
-
proxy_buffering off;
|
|
259
|
-
proxy_cache off;
|
|
260
|
-
proxy_read_timeout 3600s;
|
|
261
|
-
proxy_send_timeout 3600s;
|
|
262
|
-
proxy_connect_timeout 10s;
|
|
263
|
-
proxy_set_header Authorization \$http_authorization;
|
|
264
|
-
proxy_pass_header Authorization;
|
|
265
|
-
proxy_set_header Mcp-Session-Id \$http_mcp_session_id;
|
|
266
|
-
proxy_pass_header Mcp-Session-Id;
|
|
267
|
-
proxy_set_header Host \$host;
|
|
268
|
-
proxy_set_header X-Real-IP \$remote_addr;
|
|
269
|
-
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
270
|
-
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
271
|
-
proxy_set_header Upgrade \$http_upgrade;
|
|
272
|
-
proxy_set_header Connection \$connection_upgrade;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
location /health {
|
|
276
|
-
proxy_pass http://127.0.0.1:${PORT};
|
|
277
|
-
proxy_http_version 1.1;
|
|
278
|
-
proxy_connect_timeout 5s;
|
|
279
|
-
proxy_read_timeout 10s;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
location /.well-known/ {
|
|
283
|
-
proxy_pass http://127.0.0.1:${PORT};
|
|
284
|
-
proxy_http_version 1.1;
|
|
285
|
-
proxy_connect_timeout 5s;
|
|
286
|
-
proxy_read_timeout 10s;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
location / {
|
|
290
|
-
return 404;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
NGINX
|
|
294
|
-
|
|
295
|
-
# Enable site
|
|
296
|
-
[[ -L "/etc/nginx/sites-enabled/claude-bridge" ]] || \
|
|
297
|
-
ln -s /etc/nginx/sites-available/claude-bridge /etc/nginx/sites-enabled/claude-bridge
|
|
298
|
-
|
|
299
|
-
# Remove default site (conflicts on port 80)
|
|
300
|
-
[[ -L "/etc/nginx/sites-enabled/default" ]] && \
|
|
301
|
-
rm -f /etc/nginx/sites-enabled/default && info "Removed nginx default site"
|
|
302
|
-
|
|
303
|
-
nginx -t
|
|
304
|
-
systemctl reload nginx
|
|
305
|
-
info "nginx configured for $DOMAIN"
|
|
306
|
-
|
|
307
|
-
# ── 10. TLS certificate ───────────────────────────────────────────────────────
|
|
308
|
-
section "TLS certificate"
|
|
309
|
-
|
|
310
|
-
if [[ "$SKIP_CERTBOT" == "1" ]]; then
|
|
311
|
-
warn "SKIP_CERTBOT=1 — skipping cert. Run manually later:"
|
|
312
|
-
echo " certbot --nginx -d $DOMAIN"
|
|
313
|
-
else
|
|
314
|
-
if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos \
|
|
315
|
-
--register-unsafely-without-email --redirect 2>&1; then
|
|
316
|
-
info "TLS certificate obtained for $DOMAIN"
|
|
317
|
-
else
|
|
318
|
-
warn "Certbot failed. Common causes:"
|
|
319
|
-
echo " - DNS not yet pointing to this IP (check: dig $DOMAIN)"
|
|
320
|
-
echo " - Port 80 blocked"
|
|
321
|
-
echo " Re-run manually: certbot --nginx -d $DOMAIN"
|
|
322
|
-
fi
|
|
323
|
-
fi
|
|
324
|
-
|
|
325
|
-
# ── 11. Start service ─────────────────────────────────────────────────────────
|
|
326
|
-
section "Starting service"
|
|
327
|
-
|
|
328
|
-
systemctl restart "$SERVICE_NAME"
|
|
329
|
-
|
|
330
|
-
echo -n "Waiting for bridge..."
|
|
331
|
-
for i in $(seq 1 30); do
|
|
332
|
-
if curl -sf --max-time 3 "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then
|
|
333
|
-
echo " ready."
|
|
334
|
-
break
|
|
335
|
-
fi
|
|
336
|
-
sleep 1; echo -n "."
|
|
337
|
-
if [[ $i -eq 30 ]]; then
|
|
338
|
-
echo " timed out."
|
|
339
|
-
warn "Check logs: journalctl -u $SERVICE_NAME -n 50"
|
|
340
|
-
fi
|
|
341
|
-
done
|
|
342
|
-
|
|
343
|
-
# ── Summary ───────────────────────────────────────────────────────────────────
|
|
344
|
-
echo ""
|
|
345
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
346
|
-
echo " Claude IDE Bridge — bootstrap complete"
|
|
347
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
348
|
-
echo ""
|
|
349
|
-
echo " MCP endpoint: https://$DOMAIN/mcp"
|
|
350
|
-
echo " Health check: https://$DOMAIN/health"
|
|
351
|
-
echo " Local: http://127.0.0.1:${PORT}/mcp"
|
|
352
|
-
echo " Token: ${FIXED_TOKEN}"
|
|
353
|
-
echo " Install dir: $INSTALL_DIR"
|
|
354
|
-
echo " Service user: $SERVICE_USER"
|
|
355
|
-
echo ""
|
|
356
|
-
echo " Service management:"
|
|
357
|
-
echo " systemctl status $SERVICE_NAME"
|
|
358
|
-
echo " journalctl -u $SERVICE_NAME -f"
|
|
359
|
-
echo " systemctl restart $SERVICE_NAME"
|
|
360
|
-
echo ""
|
|
361
|
-
echo " To update:"
|
|
362
|
-
echo " cd $INSTALL_DIR && git pull && npm ci && npm run build"
|
|
363
|
-
echo " systemctl restart $SERVICE_NAME"
|
|
364
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|