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.
Files changed (92) hide show
  1. package/README.md +4 -1
  2. package/dist/analyticsAggregator.d.ts +5 -1
  3. package/dist/analyticsAggregator.js +15 -4
  4. package/dist/analyticsAggregator.js.map +1 -1
  5. package/dist/analyticsPrefs.d.ts +11 -0
  6. package/dist/analyticsPrefs.js +33 -0
  7. package/dist/analyticsPrefs.js.map +1 -1
  8. package/dist/bridge.js +36 -26
  9. package/dist/bridge.js.map +1 -1
  10. package/dist/claudeDriver.d.ts +0 -16
  11. package/dist/claudeDriver.js +19 -20
  12. package/dist/claudeDriver.js.map +1 -1
  13. package/dist/claudeMdPatch.d.ts +9 -3
  14. package/dist/claudeMdPatch.js +79 -13
  15. package/dist/claudeMdPatch.js.map +1 -1
  16. package/dist/claudeOrchestrator.d.ts +12 -0
  17. package/dist/claudeOrchestrator.js +2 -0
  18. package/dist/claudeOrchestrator.js.map +1 -1
  19. package/dist/commands/marketplace.d.ts +15 -10
  20. package/dist/commands/marketplace.js +27 -115
  21. package/dist/commands/marketplace.js.map +1 -1
  22. package/dist/commitIssueLinkLog.d.ts +8 -0
  23. package/dist/commitIssueLinkLog.js +53 -1
  24. package/dist/commitIssueLinkLog.js.map +1 -1
  25. package/dist/config.d.ts +3 -3
  26. package/dist/config.js +13 -2
  27. package/dist/config.js.map +1 -1
  28. package/dist/connectorRoutes.js +63 -372
  29. package/dist/connectorRoutes.js.map +1 -1
  30. package/dist/connectors/jira.js +18 -1
  31. package/dist/connectors/jira.js.map +1 -1
  32. package/dist/drivers/claude/subprocess.d.ts +12 -2
  33. package/dist/drivers/claude/subprocess.js +79 -6
  34. package/dist/drivers/claude/subprocess.js.map +1 -1
  35. package/dist/drivers/gemini/api.d.ts +18 -0
  36. package/dist/drivers/gemini/api.js +29 -0
  37. package/dist/drivers/gemini/api.js.map +1 -0
  38. package/dist/drivers/index.d.ts +3 -1
  39. package/dist/drivers/index.js +9 -1
  40. package/dist/drivers/index.js.map +1 -1
  41. package/dist/drivers/local/index.d.ts +26 -0
  42. package/dist/drivers/local/index.js +41 -0
  43. package/dist/drivers/local/index.js.map +1 -0
  44. package/dist/httpErrorResponse.d.ts +36 -0
  45. package/dist/httpErrorResponse.js +46 -0
  46. package/dist/httpErrorResponse.js.map +1 -0
  47. package/dist/inboxRoutes.js +90 -11
  48. package/dist/inboxRoutes.js.map +1 -1
  49. package/dist/index.d.ts +1 -1
  50. package/dist/index.js +3 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/oauth.d.ts +13 -0
  53. package/dist/oauth.js +13 -0
  54. package/dist/oauth.js.map +1 -1
  55. package/dist/oauthRoutes.js +3 -8
  56. package/dist/oauthRoutes.js.map +1 -1
  57. package/dist/patchworkConfig.d.ts +14 -1
  58. package/dist/patchworkConfig.js +99 -4
  59. package/dist/patchworkConfig.js.map +1 -1
  60. package/dist/preToolUseHook.js +7 -1
  61. package/dist/preToolUseHook.js.map +1 -1
  62. package/dist/prompts.js +4 -0
  63. package/dist/prompts.js.map +1 -1
  64. package/dist/recipeOrchestration.js +13 -3
  65. package/dist/recipeOrchestration.js.map +1 -1
  66. package/dist/recipeRoutes.d.ts +5 -0
  67. package/dist/recipeRoutes.js +57 -33
  68. package/dist/recipeRoutes.js.map +1 -1
  69. package/dist/recipes/agentExecutor.d.ts +10 -1
  70. package/dist/recipes/agentExecutor.js +5 -4
  71. package/dist/recipes/agentExecutor.js.map +1 -1
  72. package/dist/recipes/tools/gmail.js +18 -1
  73. package/dist/recipes/tools/gmail.js.map +1 -1
  74. package/dist/recipes/yamlRunner.d.ts +15 -2
  75. package/dist/recipes/yamlRunner.js +11 -3
  76. package/dist/recipes/yamlRunner.js.map +1 -1
  77. package/dist/recipesHttp.d.ts +14 -0
  78. package/dist/recipesHttp.js +59 -1
  79. package/dist/recipesHttp.js.map +1 -1
  80. package/dist/server.d.ts +6 -0
  81. package/dist/server.js +249 -245
  82. package/dist/server.js.map +1 -1
  83. package/dist/tools/runCommand.js +5 -0
  84. package/dist/tools/runCommand.js.map +1 -1
  85. package/dist/tools/terminal.js +4 -0
  86. package/dist/tools/terminal.js.map +1 -1
  87. package/dist/tools/utils.d.ts +4 -0
  88. package/dist/tools/utils.js +59 -0
  89. package/dist/tools/utils.js.map +1 -1
  90. package/package.json +1 -1
  91. package/scripts/start-all.sh +4 -2
  92. 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"