patchwork-os 0.2.0-alpha.34 → 0.2.0-alpha.35
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 +142 -88
- package/deploy/bootstrap-new-vps.sh +12 -12
- package/deploy/bootstrap-vps.sh +6 -3
- package/deploy/deploy-landing.sh +59 -2
- package/dist/bridge.js +32 -1
- package/dist/bridge.js.map +1 -1
- package/dist/commands/recipe.js +18 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +79 -1
- package/dist/commands/recipeInstall.js +241 -13
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/connectors/asana.d.ts +198 -0
- package/dist/connectors/asana.js +680 -0
- package/dist/connectors/asana.js.map +1 -0
- package/dist/connectors/baseConnector.d.ts +16 -0
- package/dist/connectors/baseConnector.js +106 -24
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/discord.d.ts +150 -0
- package/dist/connectors/discord.js +544 -0
- package/dist/connectors/discord.js.map +1 -0
- package/dist/connectors/github.js +11 -4
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.d.ts +180 -0
- package/dist/connectors/gitlab.js +582 -0
- package/dist/connectors/gitlab.js.map +1 -0
- package/dist/connectors/gmail.js +11 -0
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleDrive.d.ts +34 -0
- package/dist/connectors/googleDrive.js +305 -0
- package/dist/connectors/googleDrive.js.map +1 -0
- package/dist/connectors/linear.js +23 -4
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/pagerduty.d.ts +160 -0
- package/dist/connectors/pagerduty.js +464 -0
- package/dist/connectors/pagerduty.js.map +1 -0
- package/dist/connectors/slack.d.ts +1 -1
- package/dist/connectors/slack.js +3 -1
- package/dist/connectors/slack.js.map +1 -1
- package/dist/featureFlags.d.ts +17 -11
- package/dist/featureFlags.js +52 -47
- package/dist/featureFlags.js.map +1 -1
- package/dist/index.js +255 -127
- package/dist/index.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +7 -0
- package/dist/recipeOrchestration.js +149 -28
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipes/captureForRunlog.d.ts +27 -0
- package/dist/recipes/captureForRunlog.js +128 -0
- package/dist/recipes/captureForRunlog.js.map +1 -0
- package/dist/recipes/chainedRunner.d.ts +39 -3
- package/dist/recipes/chainedRunner.js +183 -28
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/detectSilentFail.d.ts +34 -0
- package/dist/recipes/detectSilentFail.js +105 -0
- package/dist/recipes/detectSilentFail.js.map +1 -0
- package/dist/recipes/manifest.js +21 -6
- package/dist/recipes/manifest.js.map +1 -1
- package/dist/recipes/replayRun.d.ts +62 -0
- package/dist/recipes/replayRun.js +97 -0
- package/dist/recipes/replayRun.js.map +1 -0
- package/dist/recipes/scheduler.js +102 -11
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schemaGenerator.js +3 -3
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/toolRegistry.d.ts +5 -0
- package/dist/recipes/toolRegistry.js +9 -0
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/asana.d.ts +16 -0
- package/dist/recipes/tools/asana.js +524 -0
- package/dist/recipes/tools/asana.js.map +1 -0
- package/dist/recipes/tools/discord.d.ts +18 -0
- package/dist/recipes/tools/discord.js +254 -0
- package/dist/recipes/tools/discord.js.map +1 -0
- package/dist/recipes/tools/github.js +29 -4
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gitlab.d.ts +11 -0
- package/dist/recipes/tools/gitlab.js +285 -0
- package/dist/recipes/tools/gitlab.js.map +1 -0
- package/dist/recipes/tools/gmail.d.ts +1 -1
- package/dist/recipes/tools/gmail.js +230 -6
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/googleDrive.d.ts +1 -0
- package/dist/recipes/tools/googleDrive.js +55 -0
- package/dist/recipes/tools/googleDrive.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +6 -0
- package/dist/recipes/tools/index.js +6 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/linear.d.ts +2 -1
- package/dist/recipes/tools/linear.js +222 -1
- package/dist/recipes/tools/linear.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.d.ts +21 -0
- package/dist/recipes/tools/meetingNotes.js +701 -0
- package/dist/recipes/tools/meetingNotes.js.map +1 -0
- package/dist/recipes/tools/pagerduty.d.ts +15 -0
- package/dist/recipes/tools/pagerduty.js +451 -0
- package/dist/recipes/tools/pagerduty.js.map +1 -0
- package/dist/recipes/tools/slack.js +8 -2
- package/dist/recipes/tools/slack.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +23 -2
- package/dist/recipes/yamlRunner.js +263 -58
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +32 -0
- package/dist/recipesHttp.js +310 -1
- package/dist/recipesHttp.js.map +1 -1
- package/dist/runLog.d.ts +64 -2
- package/dist/runLog.js +116 -2
- package/dist/runLog.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.js +331 -9
- package/dist/server.js.map +1 -1
- package/dist/streamableHttp.d.ts +31 -1
- package/dist/streamableHttp.js +20 -2
- package/dist/streamableHttp.js.map +1 -1
- package/dist/tools/slackPostMessage.js +1 -1
- package/dist/tools/slackPostMessage.js.map +1 -1
- package/package.json +19 -4
- package/templates/recipes/project-health-check.yaml +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,77 @@
|
|
|
1
|
-
# Patchwork OS
|
|
1
|
+
# Claude IDE Bridge & Patchwork OS
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**One npm package. Two products.** Pick the layer you need.
|
|
4
|
+
|
|
5
|
+
| | What you get | Install | Best for |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| **🔌 Claude IDE Bridge** | MCP bridge connecting Claude Code to your IDE. 170+ tools — diagnostics, LSP, debugger, terminal, git, GitHub, file ops. | `npm i -g patchwork-os` then run `claude-ide-bridge` | Anyone who wants Claude Code to see and act on their editor state |
|
|
8
|
+
| **🤖 Patchwork OS** | Everything in the bridge **plus** YAML recipes, approval queue, oversight dashboard, mobile push approvals, multi-model providers, JetBrains companion. | Same package, run `patchwork patchwork-init` | Power users running automation, agent workflows, or background tasks |
|
|
9
|
+
|
|
10
|
+
Same codebase. Bridge is the foundation; Patchwork OS is the optional layer on top. **No vendor lock-in. Runs on your machine.**
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🔌 Claude IDE Bridge — Quick Start
|
|
4
15
|
|
|
5
16
|
```bash
|
|
6
|
-
|
|
17
|
+
# 1. Install the npm package
|
|
18
|
+
npm install -g patchwork-os
|
|
19
|
+
|
|
20
|
+
# 2. Install the VS Code / Cursor / Windsurf extension
|
|
21
|
+
# Search "Claude IDE Bridge" on OpenVSX, or:
|
|
22
|
+
claude-ide-bridge install-extension
|
|
23
|
+
|
|
24
|
+
# 3. Start the bridge for your workspace
|
|
25
|
+
claude-ide-bridge --workspace .
|
|
26
|
+
|
|
27
|
+
# 4. Connect Claude Code (in another terminal)
|
|
28
|
+
CLAUDE_CODE_IDE_SKIP_VALID_CHECK=true claude --ide
|
|
7
29
|
```
|
|
8
30
|
|
|
9
|
-
|
|
31
|
+
Type `/ide` in Claude Code to confirm the connection. That's it — Claude now sees your diagnostics, open files, and editor state, and can call 170+ tools to act on them.
|
|
32
|
+
|
|
33
|
+
**What the bridge gives Claude:**
|
|
34
|
+
|
|
35
|
+
- Diagnostics, LSP navigation (goto / references / call hierarchy), refactoring with risk analysis
|
|
36
|
+
- Terminal — run commands, read output, wait for async work
|
|
37
|
+
- Git — status, diff, commit, push, blame, checkout, branch list
|
|
38
|
+
- GitHub — open PRs, list issues, post reviews, fetch run logs
|
|
39
|
+
- Debugger — set breakpoints, evaluate expressions, inspect runtime state
|
|
40
|
+
- Files — read, edit by line range, search and replace, capture screenshots
|
|
41
|
+
- Code quality — `auditDependencies`, `detectUnusedCode`, `getCodeCoverage`, `getGitHotspots`
|
|
42
|
+
|
|
43
|
+
The bridge runs without any flags. No recipes, no automation, no dashboard — just the IDE-Claude connection.
|
|
44
|
+
|
|
45
|
+
**Compatible IDEs:** VS Code, Cursor, Windsurf, Google Antigravity. JetBrains IDEs via [companion plugin](#jetbrains-plugin).
|
|
46
|
+
|
|
47
|
+
**Transport layers:**
|
|
48
|
+
|
|
49
|
+
| Client | Protocol |
|
|
50
|
+
|---|---|
|
|
51
|
+
| Claude Code CLI | WebSocket `ws://127.0.0.1:<port>` |
|
|
52
|
+
| Claude Desktop | stdio shim → WebSocket |
|
|
53
|
+
| Remote (claude.ai, Codex CLI) | Streamable HTTP + Bearer token |
|
|
54
|
+
|
|
55
|
+
**Tool modes:**
|
|
56
|
+
|
|
57
|
+
| Mode | Tools | When to use |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| Full _(default)_ | ~170 | All git, GitHub, terminal, file ops, orchestration |
|
|
60
|
+
| Slim (`--slim`) | ~60 | LSP + debugger + editor state only |
|
|
61
|
+
|
|
62
|
+
Bridge-only docs: [documents/platform-docs.md](documents/platform-docs.md)
|
|
10
63
|
|
|
11
64
|
---
|
|
12
65
|
|
|
13
|
-
##
|
|
66
|
+
## 🤖 Patchwork OS — Quick Start
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx patchwork-os@alpha patchwork-init
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Sets up 5 local recipes, detects Ollama, and opens a terminal dashboard — under 90 seconds.
|
|
73
|
+
|
|
74
|
+
### What it adds on top of the bridge
|
|
14
75
|
|
|
15
76
|
Patchwork OS is a local automation platform that watches your workspace for events, runs AI-powered recipes in response, and routes anything risky through an approval queue before it goes anywhere.
|
|
16
77
|
|
|
@@ -20,44 +81,30 @@ Think of it as a background agent that acts on your behalf — but asks before s
|
|
|
20
81
|
- Customer email arrives → draft reply in your voice, pending your approval
|
|
21
82
|
- Field-trip permission form flagged → reply drafted to the teacher, waiting for your nod
|
|
22
83
|
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## How it works
|
|
26
|
-
|
|
27
84
|
**Recipes** are plain YAML files. They declare a trigger (cron, file save, git commit, test run, webhook) and an action (run a prompt, write to inbox, call a connector). No code required. Share them like dotfiles.
|
|
28
85
|
|
|
29
86
|
**Models** are yours. Claude, GPT, Gemini, Grok, or local Ollama. Swap at any time. Nothing phones home.
|
|
30
87
|
|
|
31
88
|
**Oversight** is non-negotiable. Every write or external action lands in `~/.patchwork/inbox/` for approval. The web UI at `http://localhost:3100` shows pending approvals, live sessions, recipe run history, and analytics.
|
|
32
89
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## Quickstart
|
|
90
|
+
### Patchwork commands
|
|
36
91
|
|
|
37
92
|
```bash
|
|
38
|
-
# Install globally
|
|
39
|
-
npm install -g patchwork-os
|
|
40
|
-
|
|
41
93
|
# One-command setup: extension + CLAUDE.md + starter recipes
|
|
42
|
-
patchwork
|
|
94
|
+
patchwork patchwork-init
|
|
43
95
|
|
|
44
96
|
# Explore
|
|
45
|
-
patchwork
|
|
46
|
-
patchwork
|
|
47
|
-
patchwork
|
|
48
|
-
patchwork
|
|
49
|
-
patchwork
|
|
97
|
+
patchwork recipe list # installed recipes
|
|
98
|
+
patchwork recipe run daily-status # run one now
|
|
99
|
+
patchwork recipe run morning-brief --local # run with local Ollama
|
|
100
|
+
patchwork tools list # browse 170+ tools
|
|
101
|
+
patchwork # open terminal dashboard
|
|
102
|
+
|
|
103
|
+
# Web UI — bridge + extension watcher in tmux
|
|
104
|
+
patchwork start-all # then http://localhost:3100
|
|
50
105
|
```
|
|
51
106
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
patchwork-os start-all # bridge + extension watcher in tmux
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Starter recipes
|
|
107
|
+
### Starter recipes
|
|
61
108
|
|
|
62
109
|
No external API keys needed for these:
|
|
63
110
|
|
|
@@ -70,44 +117,65 @@ No external API keys needed for these:
|
|
|
70
117
|
| `stale-branches` | cron weekly | Lists branches older than 30 days |
|
|
71
118
|
| `morning-brief` | cron 08:00 | Commits + Linear issues + Calendar events |
|
|
72
119
|
| `sentry-to-linear` | manual | Sentry issue → Linear ticket (one-shot) |
|
|
120
|
+
| `google-meet-debrief` | manual | Meeting notes → Linear + Slack |
|
|
73
121
|
|
|
74
|
-
Connectors (Linear, Sentry, Slack, Google Calendar) require API keys and approval-gated writes.
|
|
122
|
+
Connectors (Linear, Sentry, Slack, Google Calendar, Intercom, HubSpot, Datadog, Stripe) require API keys and approval-gated writes.
|
|
123
|
+
|
|
124
|
+
### Automation hooks
|
|
125
|
+
|
|
126
|
+
Event-driven hooks trigger Claude tasks automatically. Activate with `--automation --automation-policy <path.json> --claude-driver subprocess`.
|
|
127
|
+
|
|
128
|
+
Key hooks:
|
|
129
|
+
|
|
130
|
+
| Hook | Fires when |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `onFileSave` | Matching files saved |
|
|
133
|
+
| `onDiagnosticsStateChange` | Errors appear or clear |
|
|
134
|
+
| `onRecipeSave` | Any `.yaml`/`.yml` saved — runs preflight |
|
|
135
|
+
| `onGitCommit` / `onGitPush` / `onGitPull` | Git tools succeed |
|
|
136
|
+
| `onTestRun` | Test run completes (filter: any/failure/pass-after-fail) |
|
|
137
|
+
| `onBranchCheckout` | After branch switch |
|
|
138
|
+
| `onPullRequest` | After `githubCreatePR` succeeds |
|
|
139
|
+
| `onCompaction` | Before/after Claude context compaction |
|
|
140
|
+
| `onTaskCreated` / `onTaskSuccess` | Orchestrator task lifecycle |
|
|
141
|
+
|
|
142
|
+
All hooks support inline prompts, named prompt references, and a minimum 5s cooldown. Full reference: [documents/platform-docs.md → Automation Hooks](documents/platform-docs.md)
|
|
75
143
|
|
|
76
144
|
---
|
|
77
145
|
|
|
78
146
|
## Architecture
|
|
79
147
|
|
|
80
148
|
```
|
|
81
|
-
patchwork-os
|
|
82
|
-
|
|
83
|
-
├──
|
|
84
|
-
│ ├──
|
|
85
|
-
│ ├──
|
|
86
|
-
│ ├──
|
|
87
|
-
│ ├──
|
|
88
|
-
│ └──
|
|
89
|
-
|
|
90
|
-
└──
|
|
149
|
+
patchwork-os (npm package)
|
|
150
|
+
│
|
|
151
|
+
├── claude-ide-bridge ← run alone for bridge-only mode
|
|
152
|
+
│ ├── MCP server 170+ tools over WebSocket / HTTP / stdio
|
|
153
|
+
│ ├── VS Code extension LSP, debugger, editor state, live diagnostics
|
|
154
|
+
│ ├── Git / GitHub gitCommit, gitPush, githubCreatePR, …
|
|
155
|
+
│ ├── Terminal runInTerminal, getTerminalOutput, …
|
|
156
|
+
│ └── Code quality auditDependencies, detectUnusedCode, getCodeCoverage
|
|
157
|
+
│
|
|
158
|
+
└── patchwork ← run for full Patchwork OS layer
|
|
159
|
+
├── Recipe runner YAML triggers → LLM prompt → action
|
|
160
|
+
├── Connectors Linear, Sentry, Slack, Google Calendar, +
|
|
161
|
+
├── Orchestrator Claude subprocess tasks, automation hooks
|
|
162
|
+
├── Oversight inbox ~/.patchwork/inbox/ — approval queue
|
|
163
|
+
└── Web dashboard http://localhost:3100 — approvals, sessions, analytics
|
|
91
164
|
```
|
|
92
165
|
|
|
93
|
-
**
|
|
166
|
+
The npm package ships **three CLI binaries** that share the same code:
|
|
94
167
|
|
|
95
|
-
|
|
|
168
|
+
| Binary | Default behavior |
|
|
96
169
|
|---|---|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
101
|
-
**Tool modes:**
|
|
170
|
+
| `claude-ide-bridge` | Bridge only — no automation, no recipe runner, no dashboard |
|
|
171
|
+
| `patchwork` | Full Patchwork OS — automation + recipes + dashboard |
|
|
172
|
+
| `patchwork-os` | Alias for `patchwork` |
|
|
102
173
|
|
|
103
|
-
|
|
104
|
-
|---|---|---|
|
|
105
|
-
| Full _(default)_ | ~170 | All git, GitHub, terminal, file ops, orchestration |
|
|
106
|
-
| Slim (`--slim`) | ~60 | LSP + debugger + editor state only |
|
|
174
|
+
Use whichever fits your mental model.
|
|
107
175
|
|
|
108
176
|
---
|
|
109
177
|
|
|
110
|
-
## Tool surface (v0.2.0-alpha.
|
|
178
|
+
## Tool surface (v0.2.0-alpha.35)
|
|
111
179
|
|
|
112
180
|
170+ MCP tools across 15 categories. Highlights:
|
|
113
181
|
|
|
@@ -126,38 +194,16 @@ Full reference: [documents/platform-docs.md](documents/platform-docs.md)
|
|
|
126
194
|
|
|
127
195
|
---
|
|
128
196
|
|
|
129
|
-
## Automation hooks
|
|
130
|
-
|
|
131
|
-
Event-driven hooks trigger Claude tasks automatically. Activate with `--automation --automation-policy <path.json> --claude-driver subprocess`.
|
|
132
|
-
|
|
133
|
-
Key hooks:
|
|
134
|
-
|
|
135
|
-
| Hook | Fires when |
|
|
136
|
-
|---|---|
|
|
137
|
-
| `onFileSave` | Matching files saved |
|
|
138
|
-
| `onDiagnosticsStateChange` | Errors appear or clear |
|
|
139
|
-
| `onRecipeSave` | Any `.yaml`/`.yml` saved — runs preflight |
|
|
140
|
-
| `onGitCommit` | After successful commit |
|
|
141
|
-
| `onTestRun` | After test run completes |
|
|
142
|
-
| `onBranchCheckout` | After branch switch |
|
|
143
|
-
| `onCompaction` | Before/after Claude context compaction |
|
|
144
|
-
|
|
145
|
-
All hooks support inline prompts, named prompt references, and a minimum 5s cooldown.
|
|
146
|
-
|
|
147
|
-
Full reference: [documents/platform-docs.md → Automation Hooks](documents/platform-docs.md)
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
197
|
## Plugin system
|
|
152
198
|
|
|
153
199
|
Extend the tool surface without forking the bridge.
|
|
154
200
|
|
|
155
201
|
```bash
|
|
156
202
|
# Scaffold a new plugin
|
|
157
|
-
patchwork
|
|
203
|
+
patchwork gen-plugin-stub ./my-plugin --name "org/name" --prefix "myPrefix"
|
|
158
204
|
|
|
159
205
|
# Load at runtime
|
|
160
|
-
|
|
206
|
+
claude-ide-bridge --plugin ./my-plugin
|
|
161
207
|
```
|
|
162
208
|
|
|
163
209
|
Plugins register MCP tools in-process. Publish to npm with keyword `claude-ide-bridge-plugin`.
|
|
@@ -166,12 +212,22 @@ Full reference: [documents/plugin-authoring.md](documents/plugin-authoring.md)
|
|
|
166
212
|
|
|
167
213
|
---
|
|
168
214
|
|
|
215
|
+
## JetBrains plugin
|
|
216
|
+
|
|
217
|
+
Companion IntelliJ plugin (v1.0.0) on the JetBrains Marketplace. Covers 49 handlers: core tools, PSI-based LSP (goto, references, hover, rename, symbols, format), XDebugger integration, and code style tools.
|
|
218
|
+
|
|
219
|
+
Use the same bridge from VS Code and JetBrains IDEs simultaneously — IntelliJ IDEA, PyCharm, GoLand, WebStorm, and other IntelliJ-platform editors.
|
|
220
|
+
|
|
221
|
+
Source: [intellij-plugin/](intellij-plugin/)
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
169
225
|
## Remote deployment
|
|
170
226
|
|
|
171
|
-
|
|
227
|
+
Run headless on a VPS with full tool support via VS Code Remote-SSH.
|
|
172
228
|
|
|
173
229
|
```bash
|
|
174
|
-
|
|
230
|
+
claude-ide-bridge --bind 0.0.0.0 \
|
|
175
231
|
--issuer-url https://your-domain.com \
|
|
176
232
|
--fixed-token <uuid> \
|
|
177
233
|
--vps
|
|
@@ -185,20 +241,18 @@ Systemd service and deploy scripts in [`deploy/`](deploy/). Full guide: [docs/re
|
|
|
185
241
|
|
|
186
242
|
| Feature | Status |
|
|
187
243
|
|---|---|
|
|
244
|
+
| 170+ MCP tools (LSP, git, tests, debugger, diagnostics) | **shipped** |
|
|
245
|
+
| VS Code / Cursor / Windsurf / Antigravity extension | **shipped** |
|
|
246
|
+
| JetBrains plugin (49 handlers) | **shipped** |
|
|
188
247
|
| `patchwork-init` — one-command setup | **shipped** |
|
|
189
248
|
| Terminal dashboard | **shipped** |
|
|
190
249
|
| Web oversight UI (approvals, sessions, recipes) | **shipped** |
|
|
191
250
|
| Recipe runner (YAML, cron, manual, webhook) | **shipped** |
|
|
192
251
|
| Multi-provider LLM (Claude, Gemini, OpenAI, Grok, Ollama) | **shipped** |
|
|
193
|
-
|
|
|
194
|
-
| Linear connector (read + approval-gated write) | **shipped** |
|
|
195
|
-
| Sentry connector | **shipped** |
|
|
196
|
-
| Google Calendar connector (read-only) | **shipped** |
|
|
197
|
-
| Slack connector | **shipped** |
|
|
252
|
+
| Connectors: Linear, Sentry, Slack, Google Calendar, Intercom, HubSpot, Datadog, Stripe | **shipped** |
|
|
198
253
|
| Cross-session memory (traces, handoff notes) | **shipped** |
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
| Community recipe marketplace | Q3 |
|
|
254
|
+
| Mobile oversight PWA (push approvals) | **shipped (alpha)** |
|
|
255
|
+
| Community recipe marketplace | Q3 2026 |
|
|
202
256
|
|
|
203
257
|
---
|
|
204
258
|
|
|
@@ -213,7 +267,7 @@ npm install && npm run build
|
|
|
213
267
|
# Symlink installs break the macOS LaunchAgent (EPERM at startup)
|
|
214
268
|
npm pack
|
|
215
269
|
npm install -g patchwork-os-*.tgz
|
|
216
|
-
patchwork
|
|
270
|
+
patchwork patchwork-init
|
|
217
271
|
```
|
|
218
272
|
|
|
219
273
|
---
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# deploy/bootstrap-new-vps.sh
|
|
3
|
-
# Full fresh-server setup for
|
|
3
|
+
# Full fresh-server setup for patchwork-os on a NEW VPS.
|
|
4
4
|
# Handles everything from Node.js install to running HTTPS service.
|
|
5
5
|
#
|
|
6
6
|
# Usage (run as root on a fresh Ubuntu 22.04/24.04 VPS):
|
|
7
|
-
# curl -fsSL https://raw.githubusercontent.com/Oolab-labs/
|
|
7
|
+
# curl -fsSL https://raw.githubusercontent.com/Oolab-labs/patchwork-os/main/deploy/bootstrap-new-vps.sh | \
|
|
8
8
|
# DOMAIN=bridge.example.com bash
|
|
9
9
|
#
|
|
10
10
|
# Or after cloning:
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
# DOMAIN Subdomain for the bridge (e.g. bridge.example.com)
|
|
15
15
|
#
|
|
16
16
|
# Optional environment variables:
|
|
17
|
-
# REPO_URL Git repo URL (default: https://github.com/Oolab-labs/
|
|
18
|
-
# INSTALL_DIR Where to clone the repo (default: /opt/
|
|
19
|
-
# SERVICE_USER System user to run bridge (default:
|
|
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
20
|
# PORT Bridge port (default: 9000)
|
|
21
21
|
# BRANCH Git branch to clone (default: main)
|
|
22
22
|
# SKIP_CERTBOT Set to 1 to skip TLS cert (useful if DNS not yet set)
|
|
@@ -25,13 +25,13 @@ set -euo pipefail
|
|
|
25
25
|
|
|
26
26
|
# ── Config ────────────────────────────────────────────────────────────────────
|
|
27
27
|
DOMAIN="${DOMAIN:-}"
|
|
28
|
-
REPO_URL="${REPO_URL:-https://github.com/Oolab-labs/
|
|
29
|
-
INSTALL_DIR="${INSTALL_DIR:-/opt/
|
|
30
|
-
SERVICE_USER="${SERVICE_USER:-
|
|
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
31
|
PORT="${PORT:-9000}"
|
|
32
32
|
BRANCH="${BRANCH:-main}"
|
|
33
33
|
SKIP_CERTBOT="${SKIP_CERTBOT:-0}"
|
|
34
|
-
SERVICE_NAME="
|
|
34
|
+
SERVICE_NAME="patchwork-os"
|
|
35
35
|
|
|
36
36
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
|
37
37
|
info() { echo -e "${GREEN}✓${NC} $*"; }
|
|
@@ -163,8 +163,8 @@ section "Systemd service"
|
|
|
163
163
|
# Generate service file from template (parameterised for this install)
|
|
164
164
|
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<SERVICE
|
|
165
165
|
[Unit]
|
|
166
|
-
Description=
|
|
167
|
-
Documentation=https://github.com/Oolab-labs/
|
|
166
|
+
Description=Patchwork OS bridge
|
|
167
|
+
Documentation=https://github.com/Oolab-labs/patchwork-os
|
|
168
168
|
After=network.target
|
|
169
169
|
StartLimitIntervalSec=120
|
|
170
170
|
StartLimitBurst=5
|
|
@@ -193,7 +193,7 @@ RestartSec=5
|
|
|
193
193
|
|
|
194
194
|
StandardOutput=journal
|
|
195
195
|
StandardError=journal
|
|
196
|
-
SyslogIdentifier=
|
|
196
|
+
SyslogIdentifier=patchwork-os
|
|
197
197
|
|
|
198
198
|
NoNewPrivileges=true
|
|
199
199
|
PrivateTmp=true
|
package/deploy/bootstrap-vps.sh
CHANGED
|
@@ -40,9 +40,12 @@ mkdir -p "${BRIDGE_HOME}"
|
|
|
40
40
|
chown "${BRIDGE_USER}:${BRIDGE_USER}" "${BRIDGE_HOME}"
|
|
41
41
|
|
|
42
42
|
# ── 4. Install bridge globally ────────────────────────────────────────────────
|
|
43
|
-
info "Installing
|
|
44
|
-
npm install -g
|
|
45
|
-
|
|
43
|
+
info "Installing patchwork-os from npm..."
|
|
44
|
+
npm install -g patchwork-os@alpha 2>&1 | tail -5
|
|
45
|
+
# `patchwork-os` ships three bin aliases: `patchwork` (preferred),
|
|
46
|
+
# `patchwork-os`, and the legacy `claude-ide-bridge`. Use the canonical
|
|
47
|
+
# `patchwork` name for the systemd unit + nginx config below.
|
|
48
|
+
BRIDGE_BIN="$(which patchwork)"
|
|
46
49
|
info "Bridge binary: ${BRIDGE_BIN}"
|
|
47
50
|
|
|
48
51
|
# ── 5. Generate fixed token ───────────────────────────────────────────────────
|
package/deploy/deploy-landing.sh
CHANGED
|
@@ -9,9 +9,16 @@ NGINX_CONF="/etc/nginx/sites-available/patchworkos"
|
|
|
9
9
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
10
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
11
11
|
|
|
12
|
-
echo "==> Copying landing page to VPS..."
|
|
12
|
+
echo "==> Copying landing page + assets to VPS..."
|
|
13
13
|
ssh "$VPS" "mkdir -p $LANDING_DIR"
|
|
14
|
-
|
|
14
|
+
# index.html plus the favicon + manifest browsers probe at apex. Without
|
|
15
|
+
# these the browser console fills with /favicon.svg and /manifest.json
|
|
16
|
+
# 401s on every page load (nginx falls through to the dashboard middleware
|
|
17
|
+
# for paths that don't have an explicit `location`).
|
|
18
|
+
scp "$REPO_ROOT/landing/index.html" "$VPS:$LANDING_DIR/index.html"
|
|
19
|
+
scp "$REPO_ROOT/landing/favicon.ico" "$VPS:$LANDING_DIR/favicon.ico"
|
|
20
|
+
scp "$REPO_ROOT/landing/favicon.svg" "$VPS:$LANDING_DIR/favicon.svg"
|
|
21
|
+
scp "$REPO_ROOT/landing/manifest.json" "$VPS:$LANDING_DIR/manifest.json"
|
|
15
22
|
|
|
16
23
|
echo "==> Updating nginx to serve landing page at root..."
|
|
17
24
|
ssh "$VPS" bash <<'REMOTE'
|
|
@@ -70,6 +77,56 @@ else
|
|
|
70
77
|
echo "nginx: landing location already present, skipping"
|
|
71
78
|
fi
|
|
72
79
|
|
|
80
|
+
# Independent idempotency block for the apex asset locations — these were
|
|
81
|
+
# added after the original landing block, so existing installs miss them.
|
|
82
|
+
if ! grep -q "location = /favicon.ico" "$NGINX_CONF"; then
|
|
83
|
+
python3 - "$NGINX_CONF" <<'PYEOF'
|
|
84
|
+
import sys
|
|
85
|
+
|
|
86
|
+
path = sys.argv[1]
|
|
87
|
+
with open(path) as f:
|
|
88
|
+
content = f.read()
|
|
89
|
+
|
|
90
|
+
asset_blocks = """
|
|
91
|
+
# Apex assets — favicon + PWA manifest browsers probe at root
|
|
92
|
+
location = /favicon.ico {
|
|
93
|
+
root /var/www/patchwork-landing;
|
|
94
|
+
try_files /favicon.ico =404;
|
|
95
|
+
access_log off;
|
|
96
|
+
}
|
|
97
|
+
location = /favicon.svg {
|
|
98
|
+
root /var/www/patchwork-landing;
|
|
99
|
+
try_files /favicon.svg =404;
|
|
100
|
+
access_log off;
|
|
101
|
+
}
|
|
102
|
+
location = /manifest.json {
|
|
103
|
+
root /var/www/patchwork-landing;
|
|
104
|
+
try_files /manifest.json =404;
|
|
105
|
+
access_log off;
|
|
106
|
+
}
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
# Insert immediately after the existing `location = /` block
|
|
110
|
+
marker = ' location = / {'
|
|
111
|
+
idx = content.find(marker)
|
|
112
|
+
if idx == -1:
|
|
113
|
+
print("WARN: could not find `location = /` to anchor; appending to end", flush=True)
|
|
114
|
+
idx = content.rfind('\n}')
|
|
115
|
+
new_content = content[:idx] + asset_blocks + content[idx:]
|
|
116
|
+
else:
|
|
117
|
+
# find end of the location = / block
|
|
118
|
+
end = content.find(' }', idx)
|
|
119
|
+
end = content.find('\n', end) + 1 if end != -1 else idx
|
|
120
|
+
new_content = content[:end] + asset_blocks + content[end:]
|
|
121
|
+
|
|
122
|
+
with open(path, 'w') as f:
|
|
123
|
+
f.write(new_content)
|
|
124
|
+
print("nginx: apex asset location blocks inserted")
|
|
125
|
+
PYEOF
|
|
126
|
+
else
|
|
127
|
+
echo "nginx: apex asset locations already present, skipping"
|
|
128
|
+
fi
|
|
129
|
+
|
|
73
130
|
nginx -t && systemctl reload nginx
|
|
74
131
|
echo "nginx reloaded"
|
|
75
132
|
REMOTE
|
package/dist/bridge.js
CHANGED
|
@@ -16,6 +16,7 @@ import { CommitIssueLinkLog } from "./commitIssueLinkLog.js";
|
|
|
16
16
|
import { DecisionTraceLog } from "./decisionTraceLog.js";
|
|
17
17
|
import { createDriver } from "./drivers/index.js";
|
|
18
18
|
import { ExtensionClient } from "./extensionClient.js";
|
|
19
|
+
import { lockKillSwitchEnv } from "./featureFlags.js";
|
|
19
20
|
import { FileLock } from "./fileLock.js";
|
|
20
21
|
import { buildEnforcementReminder } from "./instructionsUtils.js";
|
|
21
22
|
import { LockFileManager } from "./lockfile.js";
|
|
@@ -683,7 +684,11 @@ export class Bridge {
|
|
|
683
684
|
async start() {
|
|
684
685
|
// 0. Initialize OpenTelemetry (no-op when OTEL_EXPORTER_OTLP_ENDPOINT is unset)
|
|
685
686
|
initTelemetry();
|
|
686
|
-
// 0a.
|
|
687
|
+
// 0a. Snapshot env-derived kill-switch flags. After this, plugins or
|
|
688
|
+
// recipe steps mutating `process.env.PATCHWORK_FLAG_*` cannot disable an
|
|
689
|
+
// active emergency stop. Closes MED-2 from the 2026-04-28 audit.
|
|
690
|
+
lockKillSwitchEnv();
|
|
691
|
+
// 0b. Auto-repair .claude/rules/bridge-tools.md if stale (present but missing the
|
|
687
692
|
// current version sentinel). Older package versions write stale files that may
|
|
688
693
|
// lack new tool substitution rules. Repair is silent on success; falls back to
|
|
689
694
|
// warn-only if the template is missing or the write fails.
|
|
@@ -792,6 +797,7 @@ export class Bridge {
|
|
|
792
797
|
getOrchestrator: () => this.orchestrator,
|
|
793
798
|
recipeOrchestrator: this.recipeOrchestrator,
|
|
794
799
|
recipeRunLog: this.recipeRunLog,
|
|
800
|
+
activityLog: this.activityLog,
|
|
795
801
|
workdir: this.config.workspace,
|
|
796
802
|
logger: this.logger,
|
|
797
803
|
});
|
|
@@ -1167,6 +1173,31 @@ export class Bridge {
|
|
|
1167
1173
|
: null, async () => {
|
|
1168
1174
|
await this.refreshRecentTracesDigest();
|
|
1169
1175
|
return this.buildInstructions();
|
|
1176
|
+
},
|
|
1177
|
+
// Tail-end deps so `registerAllTools` registers the same tool set
|
|
1178
|
+
// on Streamable-HTTP sessions as on WebSocket. Without this object,
|
|
1179
|
+
// `ctxSaveTrace`, `ctxQueryTraces`, and any tool gated on the
|
|
1180
|
+
// remaining deps silently failed to register over Streamable HTTP
|
|
1181
|
+
// (caught dogfooding `ctx-loop-test` from a remote MCP client).
|
|
1182
|
+
{
|
|
1183
|
+
automationHooks: this.automationHooks,
|
|
1184
|
+
getDisconnectInfo: () => ({
|
|
1185
|
+
at: this.lastDisconnectAt,
|
|
1186
|
+
code: this.lastDisconnectCode,
|
|
1187
|
+
reason: this.lastDisconnectReason,
|
|
1188
|
+
}),
|
|
1189
|
+
onContextCacheUpdated: (generatedAt) => {
|
|
1190
|
+
this._lastContextCachedAt = generatedAt;
|
|
1191
|
+
this._emitLiveState();
|
|
1192
|
+
},
|
|
1193
|
+
getExtensionDisconnectCount: () => this.extensionDisconnectCount,
|
|
1194
|
+
...(this.commitIssueLinkLog && {
|
|
1195
|
+
commitIssueLinkLog: this.commitIssueLinkLog,
|
|
1196
|
+
}),
|
|
1197
|
+
...(this.recipeRunLog && { recipeRunLog: this.recipeRunLog }),
|
|
1198
|
+
...(this.decisionTraceLog && {
|
|
1199
|
+
decisionTraceLog: this.decisionTraceLog,
|
|
1200
|
+
}),
|
|
1170
1201
|
});
|
|
1171
1202
|
this.server.httpMcpHandler = (req, res) => this.httpMcpHandler?.handle(req, res) ?? Promise.resolve();
|
|
1172
1203
|
// 3. Check for stale lock files
|