patchwork-os 0.2.0-alpha.3 → 0.2.0-alpha.31

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 (301) 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/deploy/deploy-dashboard.sh +174 -0
  5. package/deploy/deploy-landing.sh +79 -0
  6. package/dist/activationMetrics.d.ts +67 -0
  7. package/dist/activationMetrics.js +255 -0
  8. package/dist/activationMetrics.js.map +1 -0
  9. package/dist/approvalHttp.d.ts +24 -2
  10. package/dist/approvalHttp.js +150 -10
  11. package/dist/approvalHttp.js.map +1 -1
  12. package/dist/approvalQueue.d.ts +16 -1
  13. package/dist/approvalQueue.js +44 -3
  14. package/dist/approvalQueue.js.map +1 -1
  15. package/dist/automation.d.ts +20 -0
  16. package/dist/automation.js +54 -1
  17. package/dist/automation.js.map +1 -1
  18. package/dist/bridge.d.ts +2 -0
  19. package/dist/bridge.js +55 -130
  20. package/dist/bridge.js.map +1 -1
  21. package/dist/bridgeToken.js +57 -19
  22. package/dist/bridgeToken.js.map +1 -1
  23. package/dist/ccPermissions.js +6 -4
  24. package/dist/ccPermissions.js.map +1 -1
  25. package/dist/claudeOrchestrator.d.ts +1 -1
  26. package/dist/claudeOrchestrator.js +14 -8
  27. package/dist/claudeOrchestrator.js.map +1 -1
  28. package/dist/commands/launchd.d.ts +2 -0
  29. package/dist/commands/launchd.js +94 -0
  30. package/dist/commands/launchd.js.map +1 -0
  31. package/dist/commands/recipe.d.ts +258 -0
  32. package/dist/commands/recipe.js +1130 -0
  33. package/dist/commands/recipe.js.map +1 -0
  34. package/dist/commands/recipeInstall.d.ts +72 -0
  35. package/dist/commands/recipeInstall.js +339 -0
  36. package/dist/commands/recipeInstall.js.map +1 -0
  37. package/dist/config.d.ts +14 -1
  38. package/dist/config.js +99 -8
  39. package/dist/config.js.map +1 -1
  40. package/dist/connectors/baseConnector.d.ts +117 -0
  41. package/dist/connectors/baseConnector.js +213 -0
  42. package/dist/connectors/baseConnector.js.map +1 -0
  43. package/dist/connectors/confluence.d.ts +111 -0
  44. package/dist/connectors/confluence.js +406 -0
  45. package/dist/connectors/confluence.js.map +1 -0
  46. package/dist/connectors/datadog.d.ts +116 -0
  47. package/dist/connectors/datadog.js +385 -0
  48. package/dist/connectors/datadog.js.map +1 -0
  49. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  50. package/dist/connectors/fixtureLibrary.js +70 -0
  51. package/dist/connectors/fixtureLibrary.js.map +1 -0
  52. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  53. package/dist/connectors/fixtureRecorder.js +35 -0
  54. package/dist/connectors/fixtureRecorder.js.map +1 -0
  55. package/dist/connectors/github.d.ts +58 -8
  56. package/dist/connectors/github.js +312 -84
  57. package/dist/connectors/github.js.map +1 -1
  58. package/dist/connectors/gmail.d.ts +4 -1
  59. package/dist/connectors/gmail.js +79 -16
  60. package/dist/connectors/gmail.js.map +1 -1
  61. package/dist/connectors/googleCalendar.d.ts +60 -0
  62. package/dist/connectors/googleCalendar.js +345 -0
  63. package/dist/connectors/googleCalendar.js.map +1 -0
  64. package/dist/connectors/hubspot.d.ts +112 -0
  65. package/dist/connectors/hubspot.js +408 -0
  66. package/dist/connectors/hubspot.js.map +1 -0
  67. package/dist/connectors/intercom.d.ts +102 -0
  68. package/dist/connectors/intercom.js +402 -0
  69. package/dist/connectors/intercom.js.map +1 -0
  70. package/dist/connectors/jira.d.ts +98 -0
  71. package/dist/connectors/jira.js +379 -0
  72. package/dist/connectors/jira.js.map +1 -0
  73. package/dist/connectors/linear.d.ts +69 -19
  74. package/dist/connectors/linear.js +170 -129
  75. package/dist/connectors/linear.js.map +1 -1
  76. package/dist/connectors/mcpClient.d.ts +56 -0
  77. package/dist/connectors/mcpClient.js +189 -0
  78. package/dist/connectors/mcpClient.js.map +1 -0
  79. package/dist/connectors/mcpOAuth.d.ts +84 -0
  80. package/dist/connectors/mcpOAuth.js +389 -0
  81. package/dist/connectors/mcpOAuth.js.map +1 -0
  82. package/dist/connectors/mockConnector.d.ts +28 -0
  83. package/dist/connectors/mockConnector.js +81 -0
  84. package/dist/connectors/mockConnector.js.map +1 -0
  85. package/dist/connectors/notion.d.ts +143 -0
  86. package/dist/connectors/notion.js +424 -0
  87. package/dist/connectors/notion.js.map +1 -0
  88. package/dist/connectors/sentry.d.ts +17 -21
  89. package/dist/connectors/sentry.js +115 -131
  90. package/dist/connectors/sentry.js.map +1 -1
  91. package/dist/connectors/slack.d.ts +50 -0
  92. package/dist/connectors/slack.js +324 -0
  93. package/dist/connectors/slack.js.map +1 -0
  94. package/dist/connectors/stripe.d.ts +116 -0
  95. package/dist/connectors/stripe.js +379 -0
  96. package/dist/connectors/stripe.js.map +1 -0
  97. package/dist/connectors/tokenStorage.d.ts +35 -0
  98. package/dist/connectors/tokenStorage.js +459 -0
  99. package/dist/connectors/tokenStorage.js.map +1 -0
  100. package/dist/connectors/zendesk.d.ts +104 -0
  101. package/dist/connectors/zendesk.js +424 -0
  102. package/dist/connectors/zendesk.js.map +1 -0
  103. package/dist/drivers/gemini/index.d.ts +5 -1
  104. package/dist/drivers/gemini/index.js +39 -5
  105. package/dist/drivers/gemini/index.js.map +1 -1
  106. package/dist/drivers/index.d.ts +5 -0
  107. package/dist/drivers/index.js +1 -1
  108. package/dist/drivers/index.js.map +1 -1
  109. package/dist/featureFlags.d.ts +73 -0
  110. package/dist/featureFlags.js +203 -0
  111. package/dist/featureFlags.js.map +1 -0
  112. package/dist/fp/automationInterpreter.js +1 -0
  113. package/dist/fp/automationInterpreter.js.map +1 -1
  114. package/dist/fp/automationProgram.d.ts +1 -1
  115. package/dist/fp/automationProgram.js.map +1 -1
  116. package/dist/fp/policyParser.js +17 -0
  117. package/dist/fp/policyParser.js.map +1 -1
  118. package/dist/index.js +621 -61
  119. package/dist/index.js.map +1 -1
  120. package/dist/installGuard.d.ts +25 -0
  121. package/dist/installGuard.js +48 -0
  122. package/dist/installGuard.js.map +1 -0
  123. package/dist/oauth.d.ts +4 -1
  124. package/dist/oauth.js +50 -14
  125. package/dist/oauth.js.map +1 -1
  126. package/dist/patchworkConfig.d.ts +9 -0
  127. package/dist/patchworkConfig.js.map +1 -1
  128. package/dist/recipeOrchestration.d.ts +53 -0
  129. package/dist/recipeOrchestration.js +272 -0
  130. package/dist/recipeOrchestration.js.map +1 -0
  131. package/dist/recipes/RecipeOrchestrator.d.ts +40 -0
  132. package/dist/recipes/RecipeOrchestrator.js +51 -0
  133. package/dist/recipes/RecipeOrchestrator.js.map +1 -0
  134. package/dist/recipes/agentExecutor.d.ts +28 -0
  135. package/dist/recipes/agentExecutor.js +42 -0
  136. package/dist/recipes/agentExecutor.js.map +1 -0
  137. package/dist/recipes/chainedRunner.d.ts +140 -0
  138. package/dist/recipes/chainedRunner.js +539 -0
  139. package/dist/recipes/chainedRunner.js.map +1 -0
  140. package/dist/recipes/dependencyGraph.d.ts +39 -0
  141. package/dist/recipes/dependencyGraph.js +199 -0
  142. package/dist/recipes/dependencyGraph.js.map +1 -0
  143. package/dist/recipes/legacyRecipeCompat.d.ts +2 -0
  144. package/dist/recipes/legacyRecipeCompat.js +112 -0
  145. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  146. package/dist/recipes/manifest.d.ts +47 -0
  147. package/dist/recipes/manifest.js +141 -0
  148. package/dist/recipes/manifest.js.map +1 -0
  149. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  150. package/dist/recipes/nestedRecipeStep.js +95 -0
  151. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  152. package/dist/recipes/outputRegistry.d.ts +28 -0
  153. package/dist/recipes/outputRegistry.js +52 -0
  154. package/dist/recipes/outputRegistry.js.map +1 -0
  155. package/dist/recipes/scheduler.d.ts +23 -7
  156. package/dist/recipes/scheduler.js +131 -41
  157. package/dist/recipes/scheduler.js.map +1 -1
  158. package/dist/recipes/schema.d.ts +17 -2
  159. package/dist/recipes/schemaGenerator.d.ts +28 -0
  160. package/dist/recipes/schemaGenerator.js +565 -0
  161. package/dist/recipes/schemaGenerator.js.map +1 -0
  162. package/dist/recipes/templateEngine.d.ts +62 -0
  163. package/dist/recipes/templateEngine.js +182 -0
  164. package/dist/recipes/templateEngine.js.map +1 -0
  165. package/dist/recipes/toolRegistry.d.ts +181 -0
  166. package/dist/recipes/toolRegistry.js +300 -0
  167. package/dist/recipes/toolRegistry.js.map +1 -0
  168. package/dist/recipes/tools/calendar.d.ts +6 -0
  169. package/dist/recipes/tools/calendar.js +61 -0
  170. package/dist/recipes/tools/calendar.js.map +1 -0
  171. package/dist/recipes/tools/confluence.d.ts +6 -0
  172. package/dist/recipes/tools/confluence.js +254 -0
  173. package/dist/recipes/tools/confluence.js.map +1 -0
  174. package/dist/recipes/tools/datadog.d.ts +6 -0
  175. package/dist/recipes/tools/datadog.js +239 -0
  176. package/dist/recipes/tools/datadog.js.map +1 -0
  177. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  178. package/dist/recipes/tools/diagnostics.js +36 -0
  179. package/dist/recipes/tools/diagnostics.js.map +1 -0
  180. package/dist/recipes/tools/file.d.ts +6 -0
  181. package/dist/recipes/tools/file.js +170 -0
  182. package/dist/recipes/tools/file.js.map +1 -0
  183. package/dist/recipes/tools/git.d.ts +6 -0
  184. package/dist/recipes/tools/git.js +63 -0
  185. package/dist/recipes/tools/git.js.map +1 -0
  186. package/dist/recipes/tools/github.d.ts +6 -0
  187. package/dist/recipes/tools/github.js +91 -0
  188. package/dist/recipes/tools/github.js.map +1 -0
  189. package/dist/recipes/tools/gmail.d.ts +6 -0
  190. package/dist/recipes/tools/gmail.js +210 -0
  191. package/dist/recipes/tools/gmail.js.map +1 -0
  192. package/dist/recipes/tools/hubspot.d.ts +6 -0
  193. package/dist/recipes/tools/hubspot.js +232 -0
  194. package/dist/recipes/tools/hubspot.js.map +1 -0
  195. package/dist/recipes/tools/index.d.ts +22 -0
  196. package/dist/recipes/tools/index.js +25 -0
  197. package/dist/recipes/tools/index.js.map +1 -0
  198. package/dist/recipes/tools/intercom.d.ts +6 -0
  199. package/dist/recipes/tools/intercom.js +226 -0
  200. package/dist/recipes/tools/intercom.js.map +1 -0
  201. package/dist/recipes/tools/linear.d.ts +6 -0
  202. package/dist/recipes/tools/linear.js +83 -0
  203. package/dist/recipes/tools/linear.js.map +1 -0
  204. package/dist/recipes/tools/notion.d.ts +6 -0
  205. package/dist/recipes/tools/notion.js +278 -0
  206. package/dist/recipes/tools/notion.js.map +1 -0
  207. package/dist/recipes/tools/slack.d.ts +6 -0
  208. package/dist/recipes/tools/slack.js +72 -0
  209. package/dist/recipes/tools/slack.js.map +1 -0
  210. package/dist/recipes/tools/stripe.d.ts +6 -0
  211. package/dist/recipes/tools/stripe.js +265 -0
  212. package/dist/recipes/tools/stripe.js.map +1 -0
  213. package/dist/recipes/tools/zendesk.d.ts +6 -0
  214. package/dist/recipes/tools/zendesk.js +245 -0
  215. package/dist/recipes/tools/zendesk.js.map +1 -0
  216. package/dist/recipes/validation.d.ts +13 -0
  217. package/dist/recipes/validation.js +433 -0
  218. package/dist/recipes/validation.js.map +1 -0
  219. package/dist/recipes/yamlRunner.d.ts +87 -0
  220. package/dist/recipes/yamlRunner.js +693 -409
  221. package/dist/recipes/yamlRunner.js.map +1 -1
  222. package/dist/recipesHttp.d.ts +34 -6
  223. package/dist/recipesHttp.js +285 -15
  224. package/dist/recipesHttp.js.map +1 -1
  225. package/dist/riskTier.js +1 -0
  226. package/dist/riskTier.js.map +1 -1
  227. package/dist/runLog.d.ts +23 -0
  228. package/dist/runLog.js +56 -1
  229. package/dist/runLog.js.map +1 -1
  230. package/dist/schemas/dry-run-plan.v1.json +139 -0
  231. package/dist/schemas/recipe.v1.json +684 -0
  232. package/dist/server.d.ts +32 -1
  233. package/dist/server.js +980 -97
  234. package/dist/server.js.map +1 -1
  235. package/dist/streamableHttp.js +2 -0
  236. package/dist/streamableHttp.js.map +1 -1
  237. package/dist/tools/addLinearComment.d.ts +55 -0
  238. package/dist/tools/addLinearComment.js +72 -0
  239. package/dist/tools/addLinearComment.js.map +1 -0
  240. package/dist/tools/bridgeDoctor.js +2 -2
  241. package/dist/tools/bridgeDoctor.js.map +1 -1
  242. package/dist/tools/createLinearIssue.d.ts +84 -0
  243. package/dist/tools/createLinearIssue.js +146 -0
  244. package/dist/tools/createLinearIssue.js.map +1 -0
  245. package/dist/tools/fetchCalendarEvents.d.ts +94 -0
  246. package/dist/tools/fetchCalendarEvents.js +97 -0
  247. package/dist/tools/fetchCalendarEvents.js.map +1 -0
  248. package/dist/tools/fetchGithubIssue.d.ts +80 -0
  249. package/dist/tools/fetchGithubIssue.js +84 -0
  250. package/dist/tools/fetchGithubIssue.js.map +1 -0
  251. package/dist/tools/fetchGithubPR.d.ts +89 -0
  252. package/dist/tools/fetchGithubPR.js +96 -0
  253. package/dist/tools/fetchGithubPR.js.map +1 -0
  254. package/dist/tools/fetchSlackProfile.d.ts +43 -0
  255. package/dist/tools/fetchSlackProfile.js +46 -0
  256. package/dist/tools/fetchSlackProfile.js.map +1 -0
  257. package/dist/tools/getConnectorStatus.d.ts +58 -0
  258. package/dist/tools/getConnectorStatus.js +56 -0
  259. package/dist/tools/getConnectorStatus.js.map +1 -0
  260. package/dist/tools/github/actions.js +4 -2
  261. package/dist/tools/github/actions.js.map +1 -1
  262. package/dist/tools/github/composite.d.ts +339 -0
  263. package/dist/tools/github/composite.js +343 -0
  264. package/dist/tools/github/composite.js.map +1 -0
  265. package/dist/tools/github/index.d.ts +2 -1
  266. package/dist/tools/github/index.js +2 -1
  267. package/dist/tools/github/index.js.map +1 -1
  268. package/dist/tools/github/issues.js +8 -4
  269. package/dist/tools/github/issues.js.map +1 -1
  270. package/dist/tools/github/pr.d.ts +122 -0
  271. package/dist/tools/github/pr.js +195 -5
  272. package/dist/tools/github/pr.js.map +1 -1
  273. package/dist/tools/index.js +32 -1
  274. package/dist/tools/index.js.map +1 -1
  275. package/dist/tools/searchTools.js +1 -1
  276. package/dist/tools/searchTools.js.map +1 -1
  277. package/dist/tools/slackListChannels.d.ts +65 -0
  278. package/dist/tools/slackListChannels.js +70 -0
  279. package/dist/tools/slackListChannels.js.map +1 -0
  280. package/dist/tools/slackPostMessage.d.ts +57 -0
  281. package/dist/tools/slackPostMessage.js +77 -0
  282. package/dist/tools/slackPostMessage.js.map +1 -0
  283. package/dist/tools/testTraceToSource.js +2 -2
  284. package/dist/tools/testTraceToSource.js.map +1 -1
  285. package/dist/tools/updateLinearIssue.d.ts +89 -0
  286. package/dist/tools/updateLinearIssue.js +117 -0
  287. package/dist/tools/updateLinearIssue.js.map +1 -0
  288. package/dist/transport.d.ts +7 -1
  289. package/dist/transport.js +85 -11
  290. package/dist/transport.js.map +1 -1
  291. package/package.json +5 -2
  292. package/scripts/start-all.sh +56 -19
  293. package/templates/automation-policies/recipe-authoring.json +25 -0
  294. package/templates/automation-policy.example.json +6 -0
  295. package/templates/co.patchwork-os.bridge.plist +34 -0
  296. package/templates/recipes/ctx-loop-test.yaml +75 -0
  297. package/templates/recipes/lint-on-save.yaml +1 -2
  298. package/templates/recipes/morning-brief-slack.yaml +57 -0
  299. package/templates/recipes/morning-brief.yaml +14 -6
  300. package/templates/recipes/project-health-check.yaml +50 -0
  301. package/templates/recipes/sentry-to-linear.yaml +77 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * NestedRecipeStep — handler for calling recipes from within recipes.
3
+ *
4
+ * Supports:
5
+ * - Variable passing via template resolution
6
+ * - Isolated OutputRegistry for child
7
+ * - Risk escalation (child risk > parent risk uses child's)
8
+ * - Depth limiting (prevent infinite recursion)
9
+ */
10
+ import { compileTemplate } from "./templateEngine.js";
11
+ /** Resolve template variables against parent context */
12
+ export function resolveNestedVars(vars, context) {
13
+ const resolved = {};
14
+ const errors = [];
15
+ for (const [key, templateStr] of Object.entries(vars)) {
16
+ const compiled = compileTemplate(templateStr);
17
+ const result = compiled.evaluate(context);
18
+ if ("error" in result) {
19
+ errors.push(result.error);
20
+ resolved[key] = "";
21
+ }
22
+ else {
23
+ resolved[key] = result.value;
24
+ }
25
+ }
26
+ return { resolved, errors };
27
+ }
28
+ /** Validate nested recipe call before execution */
29
+ export function validateNestedRecipe(config, context) {
30
+ if (context.currentDepth > context.recipeMaxDepth) {
31
+ return {
32
+ valid: false,
33
+ error: `Recipe nesting depth limit (${context.recipeMaxDepth}) exceeded. ` +
34
+ `Step "${config.id}" attempted to call "${config.recipe}" at depth ${context.currentDepth + 1}.`,
35
+ };
36
+ }
37
+ if (!config.recipe || typeof config.recipe !== "string") {
38
+ return {
39
+ valid: false,
40
+ error: `Invalid recipe reference in step "${config.id}": recipe name is required`,
41
+ };
42
+ }
43
+ return { valid: true };
44
+ }
45
+ /** Calculate effective risk tier */
46
+ export function calculateNestedRisk(parentRisk, childRisk) {
47
+ const tiers = { low: 1, medium: 2, high: 3 };
48
+ const parentTier = tiers[parentRisk ?? "low"];
49
+ const childTier = tiers[childRisk ?? "low"];
50
+ const effective = Math.max(parentTier, childTier);
51
+ return effective === 1 ? "low" : effective === 2 ? "medium" : "high";
52
+ }
53
+ /** Format nested recipe result for parent registry */
54
+ export function formatNestedOutput(result, config) {
55
+ return {
56
+ stepId: config.output ?? config.id,
57
+ output: {
58
+ status: result.success ? "success" : "error",
59
+ data: result.success
60
+ ? {
61
+ recipe: config.recipe,
62
+ result: result.data,
63
+ childOutputs: result.childOutputs,
64
+ }
65
+ : { error: result.error },
66
+ },
67
+ };
68
+ }
69
+ /** Mock nested recipe execution for dry-run mode */
70
+ export async function mockNestedRecipe(config, context) {
71
+ const validation = validateNestedRecipe(config, context);
72
+ if (!validation.valid) {
73
+ return { success: false, error: validation.error };
74
+ }
75
+ // Resolve templates to show what would be passed
76
+ const parentContext = context.parentRegistry.toTemplateContext(context.parentEnv);
77
+ const { resolved, errors } = resolveNestedVars(config.vars, parentContext);
78
+ if (errors.length > 0) {
79
+ return {
80
+ success: false,
81
+ error: `Template errors: ${errors.map((e) => e.message).join(", ")}`,
82
+ };
83
+ }
84
+ return {
85
+ success: true,
86
+ data: {
87
+ dryRun: true,
88
+ recipe: config.recipe,
89
+ resolvedVars: resolved,
90
+ effectiveRisk: calculateNestedRisk(undefined, config.risk),
91
+ wouldExecuteAtDepth: context.currentDepth + 1,
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=nestedRecipeStep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestedRecipeStep.js","sourceRoot":"","sources":["../../src/recipes/nestedRecipeStep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * OutputRegistry — per-recipe-run state container for step outputs.
3
+ *
4
+ * Isolated from other runs, no persistence. Used by template engine
5
+ * to resolve {{steps.X.data.field}} references.
6
+ */
7
+ import type { StepOutput, TemplateContext } from "./templateEngine.js";
8
+ export interface OutputRegistry {
9
+ /** Store output from a completed step */
10
+ set(stepId: string, output: StepOutput): void;
11
+ /** Get output for a step, or undefined if not yet run */
12
+ get(stepId: string): StepOutput | undefined;
13
+ /** Check if a step has completed */
14
+ has(stepId: string): boolean;
15
+ /** Get all step IDs that have outputs */
16
+ keys(): string[];
17
+ /** Convert to TemplateContext for template resolution */
18
+ toTemplateContext(env: Record<string, string | undefined>): TemplateContext;
19
+ /** Summary for logging/debugging */
20
+ summary(): {
21
+ total: number;
22
+ succeeded: number;
23
+ failed: number;
24
+ skipped: number;
25
+ };
26
+ }
27
+ /** Create a new isolated OutputRegistry for a recipe run */
28
+ export declare function createOutputRegistry(): OutputRegistry;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * OutputRegistry — per-recipe-run state container for step outputs.
3
+ *
4
+ * Isolated from other runs, no persistence. Used by template engine
5
+ * to resolve {{steps.X.data.field}} references.
6
+ */
7
+ class OutputRegistryImpl {
8
+ outputs = new Map();
9
+ set(stepId, output) {
10
+ this.outputs.set(stepId, output);
11
+ }
12
+ get(stepId) {
13
+ return this.outputs.get(stepId);
14
+ }
15
+ has(stepId) {
16
+ return this.outputs.has(stepId);
17
+ }
18
+ keys() {
19
+ return Array.from(this.outputs.keys());
20
+ }
21
+ toTemplateContext(env) {
22
+ const steps = {};
23
+ for (const [key, value] of this.outputs) {
24
+ steps[key] = value;
25
+ }
26
+ return { steps, env };
27
+ }
28
+ summary() {
29
+ let succeeded = 0;
30
+ let failed = 0;
31
+ let skipped = 0;
32
+ for (const output of this.outputs.values()) {
33
+ if (output.status === "success")
34
+ succeeded++;
35
+ else if (output.status === "error")
36
+ failed++;
37
+ else if (output.status === "skipped")
38
+ skipped++;
39
+ }
40
+ return {
41
+ total: this.outputs.size,
42
+ succeeded,
43
+ failed,
44
+ skipped,
45
+ };
46
+ }
47
+ }
48
+ /** Create a new isolated OutputRegistry for a recipe run */
49
+ export function createOutputRegistry() {
50
+ return new OutputRegistryImpl();
51
+ }
52
+ //# sourceMappingURL=outputRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputRegistry.js","sourceRoot":"","sources":["../../src/recipes/outputRegistry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6BH,MAAM,kBAAkB;IACd,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEhD,GAAG,CAAC,MAAc,EAAE,MAAkB;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,IAAI;QACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,iBAAiB,CAAC,GAAuC;QACvD,MAAM,KAAK,GAA+B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,OAAO;QAML,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,SAAS,EAAE,CAAC;iBACxC,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;gBAAE,MAAM,EAAE,CAAC;iBACxC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;QAClD,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACxB,SAAS;YACT,MAAM;YACN,OAAO;SACR,CAAC;IACJ,CAAC;CACF;AAED,4DAA4D;AAC5D,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,kBAAkB,EAAE,CAAC;AAClC,CAAC"}
@@ -1,10 +1,12 @@
1
+ import cron from "node-cron";
1
2
  import type { Logger } from "../logger.js";
2
3
  /**
3
- * RecipeScheduler — runs cron-triggered recipes on a simple interval.
4
+ * RecipeScheduler — runs cron-triggered recipes on a simple interval or
5
+ * standard 5-field cron expression.
4
6
  *
5
- * Phase-0 scope supports the `@every Ns|Nm|Nh` schedule form, which is
6
- * enough to demonstrate "works while you're away" without pulling in a full
7
- * cron dependency. Standard 5-field expressions can be added later.
7
+ * Supported schedule forms:
8
+ * @every Ns|Nm|Nh — simple interval (setInterval-based)
9
+ * <5-field cron> — standard cron expression (node-cron-based)
8
10
  *
9
11
  * Scheduler is a pure consumer of the recipes-on-disk contract and an
10
12
  * injected enqueue fn, so it's trivial to unit test without the orchestrator.
@@ -13,15 +15,20 @@ export type SchedulerEnqueue = (opts: {
13
15
  prompt: string;
14
16
  triggerSource: string;
15
17
  }) => string;
18
+ export type SchedulerRunYaml = (name: string) => Promise<void>;
16
19
  export interface ScheduledRecipe {
17
20
  name: string;
18
21
  schedule: string;
19
22
  intervalMs: number;
20
23
  timer: ReturnType<typeof setInterval>;
24
+ /** Present only for cron5-kind recipes. */
25
+ cronJob?: cron.ScheduledTask;
21
26
  }
22
27
  export interface SchedulerOptions {
23
28
  recipesDir: string;
24
29
  enqueue: SchedulerEnqueue;
30
+ /** Called for YAML recipes instead of enqueue. */
31
+ runYaml?: SchedulerRunYaml;
25
32
  logger?: Logger;
26
33
  /** Override for tests — defaults to setInterval. */
27
34
  setInterval?: typeof setInterval;
@@ -36,10 +43,19 @@ export declare class RecipeScheduler {
36
43
  constructor(opts: SchedulerOptions);
37
44
  start(): ScheduledRecipe[];
38
45
  stop(): void;
39
- list(): ReadonlyArray<Omit<ScheduledRecipe, "timer">>;
46
+ restart(): void;
47
+ list(): ReadonlyArray<Omit<ScheduledRecipe, "timer" | "cronJob">>;
40
48
  /** Test hook: dispatch a recipe immediately without waiting for the interval. */
41
49
  fireForTest(name: string): void;
42
50
  private fire;
43
51
  }
44
- /** Parse @every forms into milliseconds. Returns null for unsupported schedules. */
45
- export declare function parseSchedule(schedule: string): number | null;
52
+ type ParsedSchedule = {
53
+ kind: "interval";
54
+ intervalMs: number;
55
+ } | {
56
+ kind: "cron5";
57
+ expression: string;
58
+ };
59
+ /** Parse @every forms into milliseconds, or detect a 5-field cron expression. Returns null for unsupported schedules. */
60
+ export declare function parseSchedule(schedule: string): ParsedSchedule | null;
61
+ export {};
@@ -1,6 +1,9 @@
1
1
  import { readdirSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
- import { loadRecipePrompt } from "../recipesHttp.js";
3
+ import cron from "node-cron";
4
+ import { parse as parseYaml } from "yaml";
5
+ import { loadConfig } from "../patchworkConfig.js";
6
+ import { findYamlRecipePath, loadRecipePrompt } from "../recipesHttp.js";
4
7
  export class RecipeScheduler {
5
8
  opts;
6
9
  scheduled = [];
@@ -13,6 +16,17 @@ export class RecipeScheduler {
13
16
  }
14
17
  start() {
15
18
  this.stop();
19
+ // Load disabled list from config
20
+ let disabled = new Set();
21
+ try {
22
+ const cfg = loadConfig();
23
+ if (cfg.recipes?.disabled) {
24
+ disabled = new Set(cfg.recipes.disabled);
25
+ }
26
+ }
27
+ catch {
28
+ // non-fatal — proceed with empty disabled set
29
+ }
16
30
  let entries;
17
31
  try {
18
32
  entries = readdirSync(this.opts.recipesDir);
@@ -21,35 +35,80 @@ export class RecipeScheduler {
21
35
  return [];
22
36
  }
23
37
  for (const f of entries) {
24
- if (!f.endsWith(".json") || f.endsWith(".permissions.json"))
38
+ const isJson = f.endsWith(".json") && !f.endsWith(".permissions.json");
39
+ const isYaml = f.endsWith(".yaml") || f.endsWith(".yml");
40
+ if (!isJson && !isYaml)
25
41
  continue;
26
42
  const fullPath = path.join(this.opts.recipesDir, f);
27
43
  try {
28
- const raw = readFileSync(fullPath, "utf-8");
29
- const parsed = JSON.parse(raw);
30
- if (parsed.trigger?.type !== "cron")
31
- continue;
32
- if (!parsed.trigger.schedule ||
33
- typeof parsed.trigger.schedule !== "string")
44
+ let name;
45
+ let schedule;
46
+ if (isJson) {
47
+ const raw = readFileSync(fullPath, "utf-8");
48
+ const parsed = JSON.parse(raw);
49
+ if (parsed.trigger?.type !== "cron")
50
+ continue;
51
+ if (!parsed.trigger.schedule ||
52
+ typeof parsed.trigger.schedule !== "string")
53
+ continue;
54
+ schedule = parsed.trigger.schedule;
55
+ name = parsed.name ?? path.basename(f, ".json");
56
+ }
57
+ else {
58
+ // YAML
59
+ const raw = readFileSync(fullPath, "utf-8");
60
+ const parsed = parseYaml(raw);
61
+ if (parsed.trigger?.type !== "cron")
62
+ continue;
63
+ schedule = parsed.trigger.at ?? parsed.trigger.schedule;
64
+ if (!schedule || typeof schedule !== "string")
65
+ continue;
66
+ name =
67
+ parsed.name ?? path.basename(f, isYaml ? path.extname(f) : ".yaml");
68
+ }
69
+ // Apply disabled filter
70
+ if (disabled.has(name)) {
71
+ this.opts.logger?.info?.(`[scheduler] skipping disabled recipe "${name}"`);
34
72
  continue;
35
- const intervalMs = parseSchedule(parsed.trigger.schedule);
36
- if (intervalMs === null) {
37
- this.opts.logger?.warn?.(`[scheduler] ignoring recipe "${parsed.name ?? f}" — unsupported schedule "${parsed.trigger.schedule}" (use @every Ns|Nm|Nh)`);
73
+ }
74
+ const parsed2 = parseSchedule(schedule);
75
+ if (parsed2 === null) {
76
+ this.opts.logger?.warn?.(`[scheduler] ignoring recipe "${name}" — unsupported schedule "${schedule}" (use @every Ns|Nm|Nh or a 5-field cron expression)`);
38
77
  continue;
39
78
  }
40
- const name = parsed.name ?? path.basename(f, ".json");
41
- const timer = this.setIntervalFn(() => {
42
- this.fire(name);
43
- }, intervalMs);
44
- if (typeof timer === "object" && "unref" in timer)
45
- timer.unref();
46
- this.scheduled.push({
47
- name,
48
- schedule: parsed.trigger.schedule,
49
- intervalMs,
50
- timer,
51
- });
52
- this.opts.logger?.info?.(`[scheduler] "${name}" scheduled every ${intervalMs}ms (${parsed.trigger.schedule})`);
79
+ if (parsed2.kind === "interval") {
80
+ const intervalMs = parsed2.intervalMs;
81
+ const timer = this.setIntervalFn(() => {
82
+ this.fire(name);
83
+ }, intervalMs);
84
+ if (typeof timer === "object" && "unref" in timer)
85
+ timer.unref();
86
+ this.scheduled.push({
87
+ name,
88
+ schedule,
89
+ intervalMs,
90
+ timer,
91
+ });
92
+ this.opts.logger?.info?.(`[scheduler] "${name}" scheduled every ${intervalMs}ms (${schedule})`);
93
+ }
94
+ else {
95
+ // cron5
96
+ const cronJob = cron.schedule(parsed2.expression, () => {
97
+ this.fire(name);
98
+ });
99
+ // Store a sentinel timer so the ScheduledRecipe shape stays stable
100
+ const dummyTimer = this.setIntervalFn(() => { }, 2_147_483_647);
101
+ if (typeof dummyTimer === "object" && "unref" in dummyTimer)
102
+ dummyTimer.unref();
103
+ this.scheduled.push({
104
+ name,
105
+ schedule,
106
+ intervalMs: 0,
107
+ timer: dummyTimer,
108
+ cronJob,
109
+ });
110
+ this.opts.logger?.info?.(`[scheduler] "${name}" scheduled with cron expression "${schedule}"`);
111
+ }
53
112
  }
54
113
  catch {
55
114
  // skip malformed recipe
@@ -59,18 +118,41 @@ export class RecipeScheduler {
59
118
  }
60
119
  stop() {
61
120
  for (const entry of this.scheduled) {
62
- this.clearIntervalFn(entry.timer);
121
+ if (entry.cronJob) {
122
+ entry.cronJob.stop();
123
+ }
124
+ else {
125
+ this.clearIntervalFn(entry.timer);
126
+ }
63
127
  }
64
128
  this.scheduled = [];
65
129
  }
130
+ restart() {
131
+ this.stop();
132
+ this.start();
133
+ }
66
134
  list() {
67
- return this.scheduled.map(({ timer: _t, ...rest }) => rest);
135
+ return this.scheduled.map(({ timer: _t, cronJob: _c, ...rest }) => rest);
68
136
  }
69
137
  /** Test hook: dispatch a recipe immediately without waiting for the interval. */
70
138
  fireForTest(name) {
71
139
  this.fire(name);
72
140
  }
73
141
  fire(name) {
142
+ // YAML recipe — delegate to runYaml if provided
143
+ const yamlPath = findYamlRecipePath(this.opts.recipesDir, name);
144
+ if (yamlPath) {
145
+ if (!this.opts.runYaml) {
146
+ this.opts.logger?.warn?.(`[scheduler] skipped "${name}" — YAML recipe requires runYaml callback (start bridge with --claude-driver)`);
147
+ return;
148
+ }
149
+ this.opts.runYaml(name).catch((err) => {
150
+ this.opts.logger?.warn?.(`[scheduler] YAML recipe "${name}" failed: ${err instanceof Error ? err.message : String(err)}`);
151
+ });
152
+ this.opts.logger?.info?.(`[scheduler] fired YAML recipe "${name}"`);
153
+ return;
154
+ }
155
+ // JSON recipe — legacy path
74
156
  const loaded = loadRecipePrompt(this.opts.recipesDir, name);
75
157
  if (!loaded) {
76
158
  this.opts.logger?.warn?.(`[scheduler] skipped "${name}" — recipe file disappeared`);
@@ -88,23 +170,31 @@ export class RecipeScheduler {
88
170
  }
89
171
  }
90
172
  }
91
- /** Parse @every forms into milliseconds. Returns null for unsupported schedules. */
173
+ /** Parse @every forms into milliseconds, or detect a 5-field cron expression. Returns null for unsupported schedules. */
92
174
  export function parseSchedule(schedule) {
93
175
  const trimmed = schedule.trim();
176
+ // @every Ns|Nm|Nh
94
177
  const m = /^@every\s+(\d+)\s*(ms|s|m|h)$/i.exec(trimmed);
95
- if (!m)
96
- return null;
97
- const n = Number.parseInt(m[1], 10);
98
- const unit = m[2].toLowerCase();
99
- if (!Number.isFinite(n) || n <= 0)
100
- return null;
101
- const multiplier = unit === "ms"
102
- ? 1
103
- : unit === "s"
104
- ? 1000
105
- : unit === "m"
106
- ? 60_000
107
- : 60 * 60_000;
108
- return n * multiplier;
178
+ if (m) {
179
+ const n = Number.parseInt(m[1], 10);
180
+ const unit = m[2]?.toLowerCase();
181
+ if (!Number.isFinite(n) || n <= 0)
182
+ return null;
183
+ const multiplier = unit === "ms"
184
+ ? 1
185
+ : unit === "s"
186
+ ? 1000
187
+ : unit === "m"
188
+ ? 60_000
189
+ : 60 * 60_000;
190
+ return { kind: "interval", intervalMs: n * multiplier };
191
+ }
192
+ // 5-field cron expression (e.g. "0 8 * * 1-5")
193
+ if (/^\S+\s+\S+\s+\S+\s+\S+\s+\S+$/.test(trimmed)) {
194
+ if (cron.validate(trimmed)) {
195
+ return { kind: "cron5", expression: trimmed };
196
+ }
197
+ }
198
+ return null;
109
199
  }
110
200
  //# sourceMappingURL=scheduler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/recipes/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/recipes/scheduler.ts"],"names":[],"mappings":"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"}
@@ -55,10 +55,25 @@ export interface ToolStep {
55
55
  output?: string;
56
56
  }
57
57
  export type Step = AgentStep | ToolStep;
58
+ /**
59
+ * Recipe-level error policy. Single source of truth shared across
60
+ * chainedRunner, yamlRunner, and generated JSON schema.
61
+ *
62
+ * Currently-honored fields at runtime:
63
+ * - retry — integer; overridden per-step via step.retry
64
+ * - retryDelay — ms between retries (default 1000); overridden per-step
65
+ * - fallback — "log_only" and "deliver_original" both treat step
66
+ * failure as non-fatal (like optional: true) — fail-open.
67
+ * "abort" is the default (propagate).
68
+ * - notify — reserved; yamlRunner currently posts Slack notifications
69
+ * on any step failure when slack is connected. Gating on
70
+ * this flag is not yet wired.
71
+ */
58
72
  export interface ErrorPolicy {
59
- notify?: boolean;
60
73
  retry?: number;
61
- fallback?: "log_only" | "abort" | string;
74
+ retryDelay?: number;
75
+ fallback?: "log_only" | "abort" | "deliver_original";
76
+ notify?: boolean;
62
77
  }
63
78
  export interface Recipe {
64
79
  name: string;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Schema Generator — produces JSON Schema from tool registry.
3
+ *
4
+ * Generates composable schemas for editor autocomplete:
5
+ * - schemas/recipe.v1.json — top-level recipe schema
6
+ * - schemas/tools/<namespace>.json — per-namespace tool param schemas
7
+ */
8
+ export interface SchemaSet {
9
+ /** Top-level recipe schema */
10
+ recipe: unknown;
11
+ /** Per-namespace tool schemas */
12
+ namespaces: Record<string, unknown>;
13
+ /** Dry-run plan JSON schema (machine-readable contract for `recipe run --dry-run` output) */
14
+ dryRunPlan: unknown;
15
+ }
16
+ /**
17
+ * Generate complete schema set from current registry state.
18
+ */
19
+ export declare function generateSchemaSet(): SchemaSet;
20
+ /**
21
+ * JSON Schema for RecipeDryRunPlan. Consumers (dashboard run timeline, external CI)
22
+ * should pin on `schemaVersion` and validate against this.
23
+ */
24
+ export declare function generateDryRunPlanSchema(): unknown;
25
+ /**
26
+ * Write schema files to disk.
27
+ */
28
+ export declare function writeSchemas(outputDir: string, schemas: SchemaSet, writeFile: (path: string, content: string) => Promise<void> | void): Promise<void>;