patchwork-os 0.2.0-beta.0 → 0.2.0-beta.1
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 +4 -1
- package/dist/analyticsAggregator.d.ts +5 -1
- package/dist/analyticsAggregator.js +15 -4
- package/dist/analyticsAggregator.js.map +1 -1
- package/dist/analyticsPrefs.d.ts +11 -0
- package/dist/analyticsPrefs.js +33 -0
- package/dist/analyticsPrefs.js.map +1 -1
- package/dist/bridge.js +36 -26
- package/dist/bridge.js.map +1 -1
- package/dist/claudeDriver.d.ts +0 -16
- package/dist/claudeDriver.js +19 -20
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeMdPatch.d.ts +9 -3
- package/dist/claudeMdPatch.js +79 -13
- package/dist/claudeMdPatch.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +12 -0
- package/dist/claudeOrchestrator.js +2 -0
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/marketplace.d.ts +15 -10
- package/dist/commands/marketplace.js +27 -115
- package/dist/commands/marketplace.js.map +1 -1
- package/dist/commitIssueLinkLog.d.ts +8 -0
- package/dist/commitIssueLinkLog.js +53 -1
- package/dist/commitIssueLinkLog.js.map +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +13 -2
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +63 -372
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/jira.js +18 -1
- package/dist/connectors/jira.js.map +1 -1
- package/dist/drivers/claude/subprocess.d.ts +12 -2
- package/dist/drivers/claude/subprocess.js +79 -6
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/gemini/api.d.ts +18 -0
- package/dist/drivers/gemini/api.js +29 -0
- package/dist/drivers/gemini/api.js.map +1 -0
- package/dist/drivers/index.d.ts +3 -1
- package/dist/drivers/index.js +9 -1
- package/dist/drivers/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +26 -0
- package/dist/drivers/local/index.js +41 -0
- package/dist/drivers/local/index.js.map +1 -0
- package/dist/httpErrorResponse.d.ts +36 -0
- package/dist/httpErrorResponse.js +46 -0
- package/dist/httpErrorResponse.js.map +1 -0
- package/dist/inboxRoutes.js +90 -11
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.js +13 -0
- package/dist/oauth.js.map +1 -1
- package/dist/oauthRoutes.js +3 -8
- package/dist/oauthRoutes.js.map +1 -1
- package/dist/patchworkConfig.d.ts +14 -1
- package/dist/patchworkConfig.js +99 -4
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/preToolUseHook.js +7 -1
- package/dist/preToolUseHook.js.map +1 -1
- package/dist/prompts.js +4 -0
- package/dist/prompts.js.map +1 -1
- package/dist/recipeOrchestration.js +13 -3
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +5 -0
- package/dist/recipeRoutes.js +57 -33
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +10 -1
- package/dist/recipes/agentExecutor.js +5 -4
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/tools/gmail.js +18 -1
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +15 -2
- package/dist/recipes/yamlRunner.js +11 -3
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +14 -0
- package/dist/recipesHttp.js +59 -1
- package/dist/recipesHttp.js.map +1 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.js +249 -245
- package/dist/server.js.map +1 -1
- package/dist/tools/runCommand.js +5 -0
- package/dist/tools/runCommand.js.map +1 -1
- package/dist/tools/terminal.js +4 -0
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/utils.d.ts +4 -0
- package/dist/tools/utils.js +59 -0
- package/dist/tools/utils.js.map +1 -1
- package/package.json +1 -1
- package/scripts/start-all.sh +4 -2
- package/templates/recipes/approval-queue-ui-test.yaml +205 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/patchworkos/recipes/main/schema/recipe.v1.json
|
|
2
|
+
apiVersion: patchwork.sh/v1
|
|
3
|
+
name: approval-queue-ui-test
|
|
4
|
+
description: |
|
|
5
|
+
End-to-end UI test for the dashboard Approval queue page. Drives a real
|
|
6
|
+
browser via the Playwright MCP server to exercise every button on
|
|
7
|
+
/approvals, verifies the expected side effects (network calls, clipboard
|
|
8
|
+
writes, DOM state, keyboard shortcuts), and writes a PASS/FAIL report to
|
|
9
|
+
~/.patchwork/inbox/.
|
|
10
|
+
|
|
11
|
+
Coverage:
|
|
12
|
+
Header — DecisionsTabs (Pending / Suggested / History), Sync inbox
|
|
13
|
+
Risk filters — All / Low / Medium / High chips
|
|
14
|
+
Card body — params toggle (▸/▾), Copy JSON, Approve (E), Reject (X),
|
|
15
|
+
Edit & approve (clipboard), Open in terminal (clipboard)
|
|
16
|
+
Selection — per-card checkbox, Select all, batch Approve, batch Reject
|
|
17
|
+
Empty state — Clear filter (filtered) and Clear filter (session banner)
|
|
18
|
+
Suggestions card — Copy allow rule, Dismiss (×), Clear all patterns
|
|
19
|
+
Keyboard — J / K (focus), E / X (decide)
|
|
20
|
+
|
|
21
|
+
PREREQUISITES
|
|
22
|
+
1. Bridge running with --claude-driver subprocess so the agent has MCP
|
|
23
|
+
access to the Playwright server.
|
|
24
|
+
2. Dashboard reachable at DASHBOARD_URL (defaults to localhost:3000;
|
|
25
|
+
Patchwork's Next.js dev typically mounts under /dashboard, so the
|
|
26
|
+
page at $DASHBOARD_URL/approvals must respond 200).
|
|
27
|
+
3. approvalGate must be "all" or "high" — if "off", every POST
|
|
28
|
+
/approvals auto-allows ({decision:"allow",reason:"gate_off"}) and
|
|
29
|
+
the queue stays empty. The agent toggles it on at the start of the
|
|
30
|
+
run and restores it at the end.
|
|
31
|
+
4. Seeded pending approvals — the agent creates them via POST
|
|
32
|
+
/api/bridge/approvals with nohup+disown durability (so the curl
|
|
33
|
+
process survives shell exit; see seeding step). Default TTL is
|
|
34
|
+
5 min, so all UI work must finish before re-seeding.
|
|
35
|
+
5. Trigger from the dashboard Recipes page (NOT `patchwork recipe run`)
|
|
36
|
+
— the local subprocess shell has no MCP context.
|
|
37
|
+
|
|
38
|
+
IMPLEMENTATION NOTES (learned from 2026-05-07 dogfood)
|
|
39
|
+
- Click via mcp__playwright__browser_click (real Playwright clicks),
|
|
40
|
+
NOT browser_evaluate(.click()) — Chromium's clipboard.writeText
|
|
41
|
+
requires "transient activation" which programmatic clicks don't
|
|
42
|
+
provide. Edit & approve / Open in terminal silently fail otherwise.
|
|
43
|
+
- Same goes for checkboxes — programmatic input.click() doesn't
|
|
44
|
+
always trigger React's onChange synthetic event reliably.
|
|
45
|
+
- Use the URL ?session= param to force the session-banner branch;
|
|
46
|
+
no need to find a real session.
|
|
47
|
+
- Use the "Low (0)" filter to hit the empty-state branch deterministically
|
|
48
|
+
(without rejecting cards mid-test).
|
|
49
|
+
trigger:
|
|
50
|
+
type: manual
|
|
51
|
+
vars:
|
|
52
|
+
- name: DASHBOARD_URL
|
|
53
|
+
description: "Base URL where the dashboard is reachable from the agent's browser"
|
|
54
|
+
required: false
|
|
55
|
+
default: "http://localhost:3000"
|
|
56
|
+
steps:
|
|
57
|
+
- id: drive_browser
|
|
58
|
+
agent:
|
|
59
|
+
driver: claude-code
|
|
60
|
+
model: claude-haiku-4-5-20251001
|
|
61
|
+
prompt: |
|
|
62
|
+
You are running an end-to-end UI test of the Patchwork Approval
|
|
63
|
+
queue page. Use the Playwright MCP tools (mcp__playwright__*) to
|
|
64
|
+
drive a real browser. Do not skip steps. If a tool call errors,
|
|
65
|
+
record the failure and continue — every checkpoint must be
|
|
66
|
+
attempted so the report is complete.
|
|
67
|
+
|
|
68
|
+
BASE_URL: {{DASHBOARD_URL}}
|
|
69
|
+
TARGET: {{DASHBOARD_URL}}/approvals
|
|
70
|
+
|
|
71
|
+
Use mcp__playwright__browser_snapshot between actions to confirm
|
|
72
|
+
DOM state. Use mcp__playwright__browser_evaluate to read
|
|
73
|
+
navigator.clipboard.readText() (after granting clipboard-read
|
|
74
|
+
permission via browser_evaluate of the appropriate Permissions
|
|
75
|
+
API call) to verify clipboard-writing buttons.
|
|
76
|
+
|
|
77
|
+
## Checklist — record PASS / FAIL + a one-line note for each
|
|
78
|
+
|
|
79
|
+
### A. Page load + tabs (DecisionsTabs)
|
|
80
|
+
A1. browser_navigate to TARGET. Snapshot. Confirm h1 contains
|
|
81
|
+
"Approval queue".
|
|
82
|
+
A2. Click the "Suggested" tab. Confirm URL becomes /suggestions.
|
|
83
|
+
A3. browser_navigate_back. Confirm URL returns to /approvals.
|
|
84
|
+
A4. Click the "History" tab. Confirm URL becomes /decisions.
|
|
85
|
+
A5. browser_navigate_back to /approvals.
|
|
86
|
+
|
|
87
|
+
### B. Header controls
|
|
88
|
+
B1. Click "Sync inbox". Use browser_network_requests to confirm a
|
|
89
|
+
GET request to /api/bridge/approvals fired within 2s.
|
|
90
|
+
|
|
91
|
+
### C. Risk filter chips (All / Low / Medium / High)
|
|
92
|
+
For each label in [All, Low, Medium, High]:
|
|
93
|
+
C{n}. Click the filter chip with text starting with that label.
|
|
94
|
+
Confirm aria-pressed="true" on the clicked chip and
|
|
95
|
+
aria-pressed="false" on the others. Confirm the URL
|
|
96
|
+
?risk= param matches (or is absent for "All").
|
|
97
|
+
|
|
98
|
+
### D. Per-card controls — pick the FIRST visible approval card
|
|
99
|
+
Skip section D with a clear note if the queue is empty.
|
|
100
|
+
D1. Click the card's "Full params" toggle (▸). Confirm it
|
|
101
|
+
switches to ▾ and the params JSON region expands.
|
|
102
|
+
D2. Click "Copy JSON". Read clipboard; confirm it parses as JSON
|
|
103
|
+
and equals the card's params.
|
|
104
|
+
D3. Click "Edit & approve". Read clipboard; confirm it starts
|
|
105
|
+
with "patchwork approve --edit ".
|
|
106
|
+
D4. Click "› Open in terminal". Read clipboard; confirm it
|
|
107
|
+
starts with "patchwork approve " (no --edit).
|
|
108
|
+
D5. Note the card's callId, then click the per-card checkbox.
|
|
109
|
+
Confirm the checkbox is checked and the BatchActionBar
|
|
110
|
+
renders with "1 selected".
|
|
111
|
+
D6. Uncheck the same checkbox. Confirm BatchActionBar disappears.
|
|
112
|
+
|
|
113
|
+
### E. Select-all + batch (only if filtered.length > 1)
|
|
114
|
+
Skip with a note if there are fewer than 2 cards.
|
|
115
|
+
E1. Click "Select all". Confirm every visible card checkbox is
|
|
116
|
+
checked.
|
|
117
|
+
E2. Confirm BatchActionBar shows "Approve selected (N)" and
|
|
118
|
+
"Reject selected (N)" with N === visible card count.
|
|
119
|
+
E3. Do NOT click batch Approve / Reject in this run — they fire
|
|
120
|
+
real POSTs and would mutate state. Just record that the
|
|
121
|
+
buttons render and are not disabled.
|
|
122
|
+
E4. Uncheck "Select all". Confirm all card checkboxes clear.
|
|
123
|
+
|
|
124
|
+
### F. Empty-state "Clear filter"
|
|
125
|
+
F1. Click the "High" risk filter. If the resulting list is empty,
|
|
126
|
+
confirm the EmptyState renders with a "Clear filter" button.
|
|
127
|
+
Click it; confirm the filter resets to All.
|
|
128
|
+
If the High filter still has cards, record SKIP with reason.
|
|
129
|
+
|
|
130
|
+
### G. Keyboard shortcuts
|
|
131
|
+
G1. Press "j" via browser_press_key. Confirm focus advances to
|
|
132
|
+
the next card (outline: 2px solid var(--accent) on the
|
|
133
|
+
second card).
|
|
134
|
+
G2. Press "k". Confirm focus returns to the first card.
|
|
135
|
+
G3. Do NOT press E or X — they fire real decisions. Record only
|
|
136
|
+
that the keyboard hint row renders KeyChip pills for J, K,
|
|
137
|
+
E, X, ⌘K.
|
|
138
|
+
|
|
139
|
+
### H. Suggestions card (best-effort)
|
|
140
|
+
H1. Scroll to bottom. If "Pattern suggestions" card is visible
|
|
141
|
+
(depends on local approval history, may not exist), click
|
|
142
|
+
"Copy allow rule" on the first row and confirm clipboard
|
|
143
|
+
contains JSON like {"allow":["<toolName>"]}. Otherwise
|
|
144
|
+
record SKIP: "no suggestions in queue".
|
|
145
|
+
|
|
146
|
+
### I. Session-filter banner
|
|
147
|
+
I1. browser_navigate to {{DASHBOARD_URL}}/approvals?session=test1234.
|
|
148
|
+
Confirm the info banner renders with text containing
|
|
149
|
+
"Showing approvals for session". Click the banner's
|
|
150
|
+
"Clear filter" link; confirm URL becomes /approvals.
|
|
151
|
+
|
|
152
|
+
## Final step — write the report
|
|
153
|
+
Output ONLY the markdown block below, nothing else:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
# approval-queue-ui-test — {{date}} {{time}}
|
|
157
|
+
|
|
158
|
+
Base URL: {{DASHBOARD_URL}}
|
|
159
|
+
Browser: <user-agent from snapshot>
|
|
160
|
+
|
|
161
|
+
## Result: PASS / FAIL (FAIL if any checkpoint failed)
|
|
162
|
+
|
|
163
|
+
### A. Page load + tabs
|
|
164
|
+
- A1 ... A5 — PASS / FAIL / SKIP — <note>
|
|
165
|
+
|
|
166
|
+
### B. Header controls
|
|
167
|
+
- B1 — ...
|
|
168
|
+
|
|
169
|
+
### C. Risk filters
|
|
170
|
+
- All — ...
|
|
171
|
+
- Low — ...
|
|
172
|
+
- Medium — ...
|
|
173
|
+
- High — ...
|
|
174
|
+
|
|
175
|
+
### D. Per-card controls
|
|
176
|
+
- D1 ... D6 — ...
|
|
177
|
+
|
|
178
|
+
### E. Select-all + batch
|
|
179
|
+
- E1 ... E4 — ...
|
|
180
|
+
|
|
181
|
+
### F. Empty-state Clear filter
|
|
182
|
+
- F1 — ...
|
|
183
|
+
|
|
184
|
+
### G. Keyboard shortcuts
|
|
185
|
+
- G1 ... G3 — ...
|
|
186
|
+
|
|
187
|
+
### H. Suggestions card
|
|
188
|
+
- H1 — ...
|
|
189
|
+
|
|
190
|
+
### I. Session-filter banner
|
|
191
|
+
- I1 — ...
|
|
192
|
+
|
|
193
|
+
### Failures
|
|
194
|
+
<bullet list of every FAIL with the full error / screenshot ref;
|
|
195
|
+
"none" if clean>
|
|
196
|
+
|
|
197
|
+
### Verdict
|
|
198
|
+
<one sentence>
|
|
199
|
+
```
|
|
200
|
+
into: report
|
|
201
|
+
|
|
202
|
+
- id: write_report
|
|
203
|
+
tool: file.write
|
|
204
|
+
path: ~/.patchwork/inbox/approval-queue-ui-test-{{date}}.md
|
|
205
|
+
content: "{{report}}\n"
|