patchwork-os 0.2.0-alpha.2 → 0.2.0-alpha.22

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 (281) hide show
  1. package/README.bridge.md +6 -0
  2. package/README.md +40 -15
  3. package/deploy/bootstrap-vps.sh +184 -0
  4. package/dist/approvalHttp.d.ts +11 -2
  5. package/dist/approvalHttp.js +98 -10
  6. package/dist/approvalHttp.js.map +1 -1
  7. package/dist/approvalQueue.d.ts +12 -1
  8. package/dist/approvalQueue.js +25 -3
  9. package/dist/approvalQueue.js.map +1 -1
  10. package/dist/automation.d.ts +20 -0
  11. package/dist/automation.js +35 -0
  12. package/dist/automation.js.map +1 -1
  13. package/dist/bridge.js +145 -23
  14. package/dist/bridge.js.map +1 -1
  15. package/dist/bridgeToken.js +57 -19
  16. package/dist/bridgeToken.js.map +1 -1
  17. package/dist/claudeDriver.d.ts +3 -1
  18. package/dist/claudeDriver.js +48 -0
  19. package/dist/claudeDriver.js.map +1 -1
  20. package/dist/claudeOrchestrator.d.ts +1 -1
  21. package/dist/claudeOrchestrator.js +14 -8
  22. package/dist/claudeOrchestrator.js.map +1 -1
  23. package/dist/commands/launchd.d.ts +2 -0
  24. package/dist/commands/launchd.js +94 -0
  25. package/dist/commands/launchd.js.map +1 -0
  26. package/dist/commands/recipe.d.ts +256 -0
  27. package/dist/commands/recipe.js +1313 -0
  28. package/dist/commands/recipe.js.map +1 -0
  29. package/dist/config.d.ts +15 -2
  30. package/dist/config.js +94 -8
  31. package/dist/config.js.map +1 -1
  32. package/dist/connectors/baseConnector.d.ts +117 -0
  33. package/dist/connectors/baseConnector.js +213 -0
  34. package/dist/connectors/baseConnector.js.map +1 -0
  35. package/dist/connectors/confluence.d.ts +111 -0
  36. package/dist/connectors/confluence.js +406 -0
  37. package/dist/connectors/confluence.js.map +1 -0
  38. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  39. package/dist/connectors/fixtureLibrary.js +70 -0
  40. package/dist/connectors/fixtureLibrary.js.map +1 -0
  41. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  42. package/dist/connectors/fixtureRecorder.js +35 -0
  43. package/dist/connectors/fixtureRecorder.js.map +1 -0
  44. package/dist/connectors/github.d.ts +58 -8
  45. package/dist/connectors/github.js +312 -84
  46. package/dist/connectors/github.js.map +1 -1
  47. package/dist/connectors/gmail.d.ts +4 -1
  48. package/dist/connectors/gmail.js +93 -16
  49. package/dist/connectors/gmail.js.map +1 -1
  50. package/dist/connectors/googleCalendar.d.ts +60 -0
  51. package/dist/connectors/googleCalendar.js +345 -0
  52. package/dist/connectors/googleCalendar.js.map +1 -0
  53. package/dist/connectors/jira.d.ts +98 -0
  54. package/dist/connectors/jira.js +379 -0
  55. package/dist/connectors/jira.js.map +1 -0
  56. package/dist/connectors/linear.d.ts +117 -0
  57. package/dist/connectors/linear.js +239 -0
  58. package/dist/connectors/linear.js.map +1 -0
  59. package/dist/connectors/mcpClient.d.ts +56 -0
  60. package/dist/connectors/mcpClient.js +189 -0
  61. package/dist/connectors/mcpClient.js.map +1 -0
  62. package/dist/connectors/mcpOAuth.d.ts +84 -0
  63. package/dist/connectors/mcpOAuth.js +389 -0
  64. package/dist/connectors/mcpOAuth.js.map +1 -0
  65. package/dist/connectors/mockConnector.d.ts +28 -0
  66. package/dist/connectors/mockConnector.js +81 -0
  67. package/dist/connectors/mockConnector.js.map +1 -0
  68. package/dist/connectors/notion.d.ts +143 -0
  69. package/dist/connectors/notion.js +424 -0
  70. package/dist/connectors/notion.js.map +1 -0
  71. package/dist/connectors/sentry.d.ts +43 -0
  72. package/dist/connectors/sentry.js +188 -0
  73. package/dist/connectors/sentry.js.map +1 -0
  74. package/dist/connectors/slack.d.ts +50 -0
  75. package/dist/connectors/slack.js +324 -0
  76. package/dist/connectors/slack.js.map +1 -0
  77. package/dist/connectors/tokenStorage.d.ts +35 -0
  78. package/dist/connectors/tokenStorage.js +394 -0
  79. package/dist/connectors/tokenStorage.js.map +1 -0
  80. package/dist/connectors/zendesk.d.ts +104 -0
  81. package/dist/connectors/zendesk.js +424 -0
  82. package/dist/connectors/zendesk.js.map +1 -0
  83. package/dist/drivers/claude/api.d.ts +11 -0
  84. package/dist/drivers/claude/api.js +54 -0
  85. package/dist/drivers/claude/api.js.map +1 -0
  86. package/dist/drivers/claude/envSanitizer.d.ts +7 -0
  87. package/dist/drivers/claude/envSanitizer.js +18 -0
  88. package/dist/drivers/claude/envSanitizer.js.map +1 -0
  89. package/dist/drivers/claude/streamParser.d.ts +38 -0
  90. package/dist/drivers/claude/streamParser.js +34 -0
  91. package/dist/drivers/claude/streamParser.js.map +1 -0
  92. package/dist/drivers/claude/subprocess.d.ts +19 -0
  93. package/dist/drivers/claude/subprocess.js +216 -0
  94. package/dist/drivers/claude/subprocess.js.map +1 -0
  95. package/dist/drivers/claude/subprocessSettings.d.ts +9 -0
  96. package/dist/drivers/claude/subprocessSettings.js +55 -0
  97. package/dist/drivers/claude/subprocessSettings.js.map +1 -0
  98. package/dist/drivers/gemini/index.d.ts +18 -0
  99. package/dist/drivers/gemini/index.js +210 -0
  100. package/dist/drivers/gemini/index.js.map +1 -0
  101. package/dist/drivers/grok/index.d.ts +11 -0
  102. package/dist/drivers/grok/index.js +22 -0
  103. package/dist/drivers/grok/index.js.map +1 -0
  104. package/dist/drivers/index.d.ts +23 -0
  105. package/dist/drivers/index.js +31 -0
  106. package/dist/drivers/index.js.map +1 -0
  107. package/dist/drivers/openai/index.d.ts +24 -0
  108. package/dist/drivers/openai/index.js +110 -0
  109. package/dist/drivers/openai/index.js.map +1 -0
  110. package/dist/drivers/types.d.ts +72 -0
  111. package/dist/drivers/types.js +30 -0
  112. package/dist/drivers/types.js.map +1 -0
  113. package/dist/featureFlags.d.ts +73 -0
  114. package/dist/featureFlags.js +203 -0
  115. package/dist/featureFlags.js.map +1 -0
  116. package/dist/fp/automationInterpreter.js +1 -0
  117. package/dist/fp/automationInterpreter.js.map +1 -1
  118. package/dist/fp/automationProgram.d.ts +1 -1
  119. package/dist/fp/automationProgram.js.map +1 -1
  120. package/dist/fp/policyParser.js +17 -0
  121. package/dist/fp/policyParser.js.map +1 -1
  122. package/dist/index.js +543 -37
  123. package/dist/index.js.map +1 -1
  124. package/dist/installGuard.d.ts +25 -0
  125. package/dist/installGuard.js +48 -0
  126. package/dist/installGuard.js.map +1 -0
  127. package/dist/oauth.d.ts +4 -1
  128. package/dist/oauth.js +50 -14
  129. package/dist/oauth.js.map +1 -1
  130. package/dist/patchworkConfig.d.ts +9 -0
  131. package/dist/patchworkConfig.js.map +1 -1
  132. package/dist/recipes/chainedRunner.d.ts +104 -0
  133. package/dist/recipes/chainedRunner.js +359 -0
  134. package/dist/recipes/chainedRunner.js.map +1 -0
  135. package/dist/recipes/dependencyGraph.d.ts +39 -0
  136. package/dist/recipes/dependencyGraph.js +199 -0
  137. package/dist/recipes/dependencyGraph.js.map +1 -0
  138. package/dist/recipes/legacyRecipeCompat.d.ts +1 -0
  139. package/dist/recipes/legacyRecipeCompat.js +97 -0
  140. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  141. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  142. package/dist/recipes/nestedRecipeStep.js +95 -0
  143. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  144. package/dist/recipes/outputRegistry.d.ts +28 -0
  145. package/dist/recipes/outputRegistry.js +52 -0
  146. package/dist/recipes/outputRegistry.js.map +1 -0
  147. package/dist/recipes/scheduler.d.ts +23 -7
  148. package/dist/recipes/scheduler.js +135 -41
  149. package/dist/recipes/scheduler.js.map +1 -1
  150. package/dist/recipes/schemaGenerator.d.ts +28 -0
  151. package/dist/recipes/schemaGenerator.js +484 -0
  152. package/dist/recipes/schemaGenerator.js.map +1 -0
  153. package/dist/recipes/templateEngine.d.ts +62 -0
  154. package/dist/recipes/templateEngine.js +182 -0
  155. package/dist/recipes/templateEngine.js.map +1 -0
  156. package/dist/recipes/toolRegistry.d.ts +181 -0
  157. package/dist/recipes/toolRegistry.js +300 -0
  158. package/dist/recipes/toolRegistry.js.map +1 -0
  159. package/dist/recipes/tools/calendar.d.ts +6 -0
  160. package/dist/recipes/tools/calendar.js +61 -0
  161. package/dist/recipes/tools/calendar.js.map +1 -0
  162. package/dist/recipes/tools/confluence.d.ts +6 -0
  163. package/dist/recipes/tools/confluence.js +254 -0
  164. package/dist/recipes/tools/confluence.js.map +1 -0
  165. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  166. package/dist/recipes/tools/diagnostics.js +36 -0
  167. package/dist/recipes/tools/diagnostics.js.map +1 -0
  168. package/dist/recipes/tools/file.d.ts +6 -0
  169. package/dist/recipes/tools/file.js +170 -0
  170. package/dist/recipes/tools/file.js.map +1 -0
  171. package/dist/recipes/tools/git.d.ts +6 -0
  172. package/dist/recipes/tools/git.js +63 -0
  173. package/dist/recipes/tools/git.js.map +1 -0
  174. package/dist/recipes/tools/github.d.ts +6 -0
  175. package/dist/recipes/tools/github.js +91 -0
  176. package/dist/recipes/tools/github.js.map +1 -0
  177. package/dist/recipes/tools/gmail.d.ts +6 -0
  178. package/dist/recipes/tools/gmail.js +210 -0
  179. package/dist/recipes/tools/gmail.js.map +1 -0
  180. package/dist/recipes/tools/index.d.ts +18 -0
  181. package/dist/recipes/tools/index.js +21 -0
  182. package/dist/recipes/tools/index.js.map +1 -0
  183. package/dist/recipes/tools/linear.d.ts +6 -0
  184. package/dist/recipes/tools/linear.js +83 -0
  185. package/dist/recipes/tools/linear.js.map +1 -0
  186. package/dist/recipes/tools/notion.d.ts +6 -0
  187. package/dist/recipes/tools/notion.js +278 -0
  188. package/dist/recipes/tools/notion.js.map +1 -0
  189. package/dist/recipes/tools/slack.d.ts +6 -0
  190. package/dist/recipes/tools/slack.js +72 -0
  191. package/dist/recipes/tools/slack.js.map +1 -0
  192. package/dist/recipes/tools/zendesk.d.ts +6 -0
  193. package/dist/recipes/tools/zendesk.js +245 -0
  194. package/dist/recipes/tools/zendesk.js.map +1 -0
  195. package/dist/recipes/yamlRunner.d.ts +79 -0
  196. package/dist/recipes/yamlRunner.js +612 -346
  197. package/dist/recipes/yamlRunner.js.map +1 -1
  198. package/dist/recipesHttp.d.ts +14 -1
  199. package/dist/recipesHttp.js +21 -4
  200. package/dist/recipesHttp.js.map +1 -1
  201. package/dist/riskTier.js +1 -0
  202. package/dist/riskTier.js.map +1 -1
  203. package/dist/runLog.d.ts +23 -0
  204. package/dist/runLog.js +56 -1
  205. package/dist/runLog.js.map +1 -1
  206. package/dist/server.d.ts +19 -1
  207. package/dist/server.js +682 -31
  208. package/dist/server.js.map +1 -1
  209. package/dist/streamableHttp.js +2 -0
  210. package/dist/streamableHttp.js.map +1 -1
  211. package/dist/tools/addLinearComment.d.ts +55 -0
  212. package/dist/tools/addLinearComment.js +72 -0
  213. package/dist/tools/addLinearComment.js.map +1 -0
  214. package/dist/tools/bridgeDoctor.js +2 -2
  215. package/dist/tools/bridgeDoctor.js.map +1 -1
  216. package/dist/tools/createLinearIssue.d.ts +84 -0
  217. package/dist/tools/createLinearIssue.js +146 -0
  218. package/dist/tools/createLinearIssue.js.map +1 -0
  219. package/dist/tools/ctxGetTaskContext.d.ts +4 -1
  220. package/dist/tools/ctxGetTaskContext.js +45 -2
  221. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  222. package/dist/tools/fetchCalendarEvents.d.ts +94 -0
  223. package/dist/tools/fetchCalendarEvents.js +97 -0
  224. package/dist/tools/fetchCalendarEvents.js.map +1 -0
  225. package/dist/tools/fetchGithubIssue.d.ts +80 -0
  226. package/dist/tools/fetchGithubIssue.js +84 -0
  227. package/dist/tools/fetchGithubIssue.js.map +1 -0
  228. package/dist/tools/fetchGithubPR.d.ts +89 -0
  229. package/dist/tools/fetchGithubPR.js +96 -0
  230. package/dist/tools/fetchGithubPR.js.map +1 -0
  231. package/dist/tools/fetchLinearIssue.d.ts +112 -0
  232. package/dist/tools/fetchLinearIssue.js +129 -0
  233. package/dist/tools/fetchLinearIssue.js.map +1 -0
  234. package/dist/tools/fetchSentryIssue.d.ts +143 -0
  235. package/dist/tools/fetchSentryIssue.js +150 -0
  236. package/dist/tools/fetchSentryIssue.js.map +1 -0
  237. package/dist/tools/fetchSlackProfile.d.ts +43 -0
  238. package/dist/tools/fetchSlackProfile.js +46 -0
  239. package/dist/tools/fetchSlackProfile.js.map +1 -0
  240. package/dist/tools/getConnectorStatus.d.ts +58 -0
  241. package/dist/tools/getConnectorStatus.js +56 -0
  242. package/dist/tools/getConnectorStatus.js.map +1 -0
  243. package/dist/tools/github/actions.js +4 -2
  244. package/dist/tools/github/actions.js.map +1 -1
  245. package/dist/tools/github/composite.d.ts +339 -0
  246. package/dist/tools/github/composite.js +343 -0
  247. package/dist/tools/github/composite.js.map +1 -0
  248. package/dist/tools/github/index.d.ts +2 -1
  249. package/dist/tools/github/index.js +2 -1
  250. package/dist/tools/github/index.js.map +1 -1
  251. package/dist/tools/github/issues.js +8 -4
  252. package/dist/tools/github/issues.js.map +1 -1
  253. package/dist/tools/github/pr.d.ts +122 -0
  254. package/dist/tools/github/pr.js +195 -5
  255. package/dist/tools/github/pr.js.map +1 -1
  256. package/dist/tools/index.js +36 -1
  257. package/dist/tools/index.js.map +1 -1
  258. package/dist/tools/searchTools.js +1 -1
  259. package/dist/tools/searchTools.js.map +1 -1
  260. package/dist/tools/slackListChannels.d.ts +65 -0
  261. package/dist/tools/slackListChannels.js +70 -0
  262. package/dist/tools/slackListChannels.js.map +1 -0
  263. package/dist/tools/slackPostMessage.d.ts +57 -0
  264. package/dist/tools/slackPostMessage.js +77 -0
  265. package/dist/tools/slackPostMessage.js.map +1 -0
  266. package/dist/tools/updateLinearIssue.d.ts +89 -0
  267. package/dist/tools/updateLinearIssue.js +117 -0
  268. package/dist/tools/updateLinearIssue.js.map +1 -0
  269. package/dist/transport.d.ts +7 -1
  270. package/dist/transport.js +85 -11
  271. package/dist/transport.js.map +1 -1
  272. package/package.json +4 -2
  273. package/scripts/start-all.sh +56 -19
  274. package/templates/automation-policies/recipe-authoring.json +25 -0
  275. package/templates/automation-policy.example.json +6 -0
  276. package/templates/co.patchwork-os.bridge.plist +34 -0
  277. package/templates/recipes/ctx-loop-test.yaml +75 -0
  278. package/templates/recipes/lint-on-save.yaml +1 -2
  279. package/templates/recipes/morning-brief-slack.yaml +57 -0
  280. package/templates/recipes/morning-brief.yaml +21 -5
  281. package/templates/recipes/sentry-to-linear.yaml +77 -0
@@ -0,0 +1,75 @@
1
+ name: ctx-loop-test
2
+ description: |
3
+ End-to-end test of the agent-read loop. An agent writes a decision trace with
4
+ ctxSaveTrace, then reads it back with ctxQueryTraces, and confirms the trace
5
+ appears in the result. Output lands in ~/.patchwork/inbox/ for manual inspection.
6
+ Run this after deploying a new bridge build to confirm the memory moat is live.
7
+
8
+ NOTE: requires --claude-driver subprocess and a running bridge with HTTP port
9
+ so the agent subprocess has MCP access. Running via `patchwork recipe run`
10
+ (local yamlRunner) will fail at Step 1 — the local claude -p subprocess has
11
+ no bridge MCP context. Trigger from the dashboard Recipes page instead.
12
+ trigger:
13
+ type: manual
14
+ steps:
15
+ - tool: git.log_since
16
+ since: 1h
17
+ into: recent_commits
18
+
19
+ - agent:
20
+ prompt: |
21
+ You are validating the Patchwork cross-session memory loop end-to-end.
22
+
23
+ RECENT COMMITS (context only):
24
+ {{recent_commits}}
25
+
26
+ Perform the following steps IN ORDER. Stop immediately if any step fails and
27
+ report the failure clearly in your output.
28
+
29
+ ## Step 1 — Write a trace
30
+ Call ctxSaveTrace with these exact values:
31
+ ref: "ctx-loop-test-{{date}}"
32
+ problem: "Validating that ctxSaveTrace persists traces readable by future sessions"
33
+ solution: "ctxSaveTrace writes to decision_traces.jsonl; ctxQueryTraces reads it back"
34
+ tags: ["loop-test", "dogfood"]
35
+
36
+ Record the returned `seq` number.
37
+
38
+ ## Step 2 — Read it back
39
+ Call ctxQueryTraces with:
40
+ traceType: "decision"
41
+ limit: 5
42
+
43
+ Check that the trace you just wrote (ref "ctx-loop-test-{{date}}") appears in
44
+ the results. If it does, the loop is confirmed closed.
45
+
46
+ ## Step 3 — Write your report
47
+ Output a markdown block in this exact format:
48
+
49
+ ```
50
+ # ctx-loop-test — {{date}} {{time}}
51
+
52
+ ## Result: PASS / FAIL
53
+
54
+ ### Step 1 — ctxSaveTrace
55
+ - seq: <returned seq>
56
+ - ref: ctx-loop-test-{{date}}
57
+ - Status: OK / ERROR: <message>
58
+
59
+ ### Step 2 — ctxQueryTraces
60
+ - Traces returned: <count>
61
+ - Test trace found: yes / no
62
+ - Status: OK / ERROR: <message>
63
+
64
+ ### Verdict
65
+ <one sentence summary>
66
+ ```
67
+
68
+ Output ONLY the markdown block. No preamble.
69
+ driver: claude-code
70
+ model: claude-haiku-4-5-20251001
71
+ into: report
72
+
73
+ - tool: file.write
74
+ path: ~/.patchwork/inbox/ctx-loop-test-{{date}}.md
75
+ content: "{{report}}\n"
@@ -9,5 +9,4 @@ steps:
9
9
  into: diags
10
10
  - tool: file.append
11
11
  path: ~/.patchwork/inbox/lint.md
12
- content: "- {{time}} {{file}} — {{diags.errors}} errors, {{diags.warnings}} warnings\n"
13
- when: "{{diags.errors}} > 0 || {{diags.warnings}} > 0"
12
+ content: "- {{time}} {{file}} — {{diags}}\n"
@@ -0,0 +1,57 @@
1
+ name: morning-brief-slack
2
+ description: Daily morning brief combining calendar, GitHub PRs, and Linear issues — posted to Slack.
3
+ trigger:
4
+ type: cron
5
+ at: "0 8 * * 1-5"
6
+ steps:
7
+ - tool: github.list_prs
8
+ author: "@me"
9
+ max: 10
10
+ into: prs
11
+ - tool: linear.list_issues
12
+ assignee: "@me"
13
+ state: "started,unstarted"
14
+ max: 15
15
+ into: linear_issues
16
+ - tool: calendar.list_events
17
+ days_ahead: 1
18
+ max: 10
19
+ into: calendar
20
+ - agent:
21
+ prompt: |
22
+ You are a personal assistant writing a concise morning brief. Use ONLY the data provided below — do not call any tools or fetch additional information.
23
+
24
+ OPEN PULL REQUESTS (authored by me):
25
+ {{prs}}
26
+
27
+ LINEAR ISSUES (assigned to me, in progress or unstarted):
28
+ {{linear_issues}}
29
+
30
+ TODAY'S CALENDAR EVENTS:
31
+ {{calendar}}
32
+
33
+ Write a short morning brief for Slack. Rules:
34
+ - Plain text only. No markdown headers (no # or ## lines). No code blocks.
35
+ - Use emoji to start each section.
36
+ - Do NOT include a title or greeting line like "Morning Brief" or "Good morning" — start directly with the first section.
37
+
38
+ 📅 *Calendar* — list today's meetings with time; write "No meetings today" if empty or error
39
+ 🔀 *Pull Requests* — list open PRs needing attention; omit section entirely if empty
40
+ 📋 *Linear* — list in-progress and unstarted issues by priority; omit section entirely if empty or error
41
+
42
+ Keep it under 15 lines. Be direct. Output only the brief, nothing else.
43
+ driver: claude-code
44
+ model: claude-haiku-4-5-20251001
45
+ into: brief
46
+ - tool: file.write
47
+ path: ~/.patchwork/inbox/morning-brief-{{date}}.md
48
+ content: |
49
+ # Morning brief — {{date}}
50
+
51
+ {{brief}}
52
+ - tool: slack.post_message
53
+ channel: all-massappealdesigns
54
+ text: |
55
+ *Morning Brief — {{date}}*
56
+
57
+ {{brief}}
@@ -1,5 +1,5 @@
1
1
  name: morning-brief
2
- description: Daily morning brief combining unread emails, recent git activity, and open GitHub issues.
2
+ description: Daily morning brief combining unread emails, calendar, recent git activity, and open GitHub issues.
3
3
  trigger:
4
4
  type: cron
5
5
  at: "0 8 * * 1-5"
@@ -19,6 +19,15 @@ steps:
19
19
  author: "@me"
20
20
  max: 10
21
21
  into: prs
22
+ - tool: linear.list_issues
23
+ assignee: "@me"
24
+ state: "started,unstarted"
25
+ max: 15
26
+ into: linear_issues
27
+ - tool: calendar.list_events
28
+ days_ahead: 1
29
+ max: 10
30
+ into: calendar
22
31
  - agent:
23
32
  prompt: |
24
33
  You are a personal assistant writing a concise morning brief. Use ONLY the data provided below — do not call any tools or fetch additional information.
@@ -37,15 +46,22 @@ steps:
37
46
  OPEN PULL REQUESTS (authored by me):
38
47
  {{prs}}
39
48
 
49
+ LINEAR ISSUES (assigned to me, in progress or unstarted):
50
+ {{linear_issues}}
51
+
52
+ TODAY'S CALENDAR EVENTS:
53
+ {{calendar}}
54
+
40
55
  Write a morning brief with these sections:
41
56
  1. **Email triage** — list emails needing action today (sender, subject, one-line summary)
42
57
  2. **FYI emails** — informational only, no action needed
43
- 3. **Code activity** — summarize the RECENT GIT COMMITS above; if the list is empty write "No commits in the last 24 hours"
44
- 4. **GitHub** — list open issues and PRs needing attention; omit this section entirely if both lists are empty
58
+ 3. **Calendar** — list today's meetings with time and attendees; omit if calendar returned an error or no events
59
+ 4. **Code activity** — summarize the RECENT GIT COMMITS above; if the list is empty write "No commits in the last 24 hours"
60
+ 5. **GitHub** — list open issues and PRs needing attention; omit this section entirely if both lists are empty
61
+ 6. **Linear** — list in-progress and unstarted issues by priority; omit this section entirely if the list is empty or returned an error
45
62
 
46
63
  Be concise. Skip newsletters and automated notifications.
47
- driver: claude-code
48
- model: claude-haiku-4-5-20251001
64
+ driver: gemini
49
65
  into: brief
50
66
  - tool: file.write
51
67
  path: ~/.patchwork/inbox/morning-brief-{{date}}.md
@@ -0,0 +1,77 @@
1
+ name: sentry-to-linear
2
+ description: |
3
+ Fetch a Sentry issue, enrich it with git blame, and create a triage-ready
4
+ Linear ticket. Requires both Sentry and Linear connectors connected.
5
+ Run ad-hoc or trigger via webhook / automation policy.
6
+
7
+ # Example manual trigger:
8
+ # patchwork-os run-recipe sentry-to-linear --var SENTRY_ISSUE_ID=12345678
9
+ #
10
+ # Example automation trigger (add to ~/.patchwork/automation-policy.json):
11
+ # "onFileSave": { ... } — or fire from a Sentry webhook handler
12
+
13
+ trigger:
14
+ type: manual
15
+ vars:
16
+ - name: SENTRY_ISSUE_ID
17
+ description: "Sentry issue ID or URL (e.g. '12345678' or 'https://sentry.io/...')"
18
+ required: true
19
+ - name: LINEAR_TEAM_KEY
20
+ description: "Linear team key to create the issue in (e.g. 'ENG'). Defaults to first team."
21
+ required: false
22
+ - name: LINEAR_PRIORITY
23
+ description: "Linear priority: 1=urgent, 2=high, 3=medium, 4=low (default: 2)"
24
+ required: false
25
+ default: "2"
26
+
27
+ steps:
28
+ - agent:
29
+ prompt: |
30
+ You are a triage assistant. Your job is to:
31
+ 1. Fetch the Sentry issue using fetchSentryIssue with issueId "{{SENTRY_ISSUE_ID}}"
32
+ 2. Create a Linear issue using createLinearIssue with the data you received
33
+
34
+ For the Linear issue:
35
+ - title: Use the Sentry issue title verbatim
36
+ - description: Write a structured Markdown body with these sections:
37
+ ## Error
38
+ (one-line error type + message from the Sentry title)
39
+
40
+ ## Stack trace
41
+ (the top 5 frames from the stackTrace field, formatted as a code block)
42
+
43
+ ## Suspect commit
44
+ (if topSuspect is present: sha, author, date, subject — otherwise write "No suspect commit identified")
45
+
46
+ ## Confidence
47
+ (the confidence field value + a one-sentence explanation of what it means)
48
+
49
+ ## Sentry link
50
+ (a link back to the Sentry issue — construct from the issueId: https://sentry.io/issues/{{SENTRY_ISSUE_ID}}/)
51
+
52
+ - teamKey: "{{LINEAR_TEAM_KEY}}" (pass as-is; if blank the tool picks the first team)
53
+ - priority: {{LINEAR_PRIORITY}} (as an integer)
54
+ - labelNames: ["bug"]
55
+
56
+ After creating the ticket, respond with ONLY a JSON object:
57
+ {
58
+ "sentryIssueId": "<the issueId from fetchSentryIssue>",
59
+ "sentryTitle": "<the title>",
60
+ "linearIdentifier": "<e.g. ENG-101>",
61
+ "linearUrl": "<the url from createLinearIssue>",
62
+ "confidence": "<high|medium|low>",
63
+ "suspectCommit": "<sha or null>"
64
+ }
65
+
66
+ If either tool returns an error (sentryConnected: false or linearConnected: false),
67
+ respond with the same JSON shape but set linearUrl to "" and add an "error" key
68
+ explaining which connector is not connected.
69
+ driver: claude-code
70
+ model: claude-haiku-4-5-20251001
71
+ into: result
72
+ - tool: file.write
73
+ path: ~/.patchwork/inbox/sentry-to-linear-{{date}}.md
74
+ content: |
75
+ # Sentry → Linear triage ({{date}})
76
+
77
+ {{result}}