patchwork-os 0.2.0-beta.3 → 0.2.0-beta.4

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 (181) hide show
  1. package/README.md +95 -25
  2. package/dist/activityLog.js +2 -1
  3. package/dist/activityLog.js.map +1 -1
  4. package/dist/approvalHttp.js +25 -8
  5. package/dist/approvalHttp.js.map +1 -1
  6. package/dist/approvalQueue.d.ts +44 -1
  7. package/dist/approvalQueue.js +117 -0
  8. package/dist/approvalQueue.js.map +1 -1
  9. package/dist/automation.d.ts +3 -3
  10. package/dist/automation.js +12 -5
  11. package/dist/automation.js.map +1 -1
  12. package/dist/bridge.js +29 -1
  13. package/dist/bridge.js.map +1 -1
  14. package/dist/bridgeLockDiscovery.js +2 -1
  15. package/dist/bridgeLockDiscovery.js.map +1 -1
  16. package/dist/claudeOrchestrator.js +27 -10
  17. package/dist/claudeOrchestrator.js.map +1 -1
  18. package/dist/commands/dashboard.js +8 -1
  19. package/dist/commands/dashboard.js.map +1 -1
  20. package/dist/commands/install.js +3 -0
  21. package/dist/commands/install.js.map +1 -1
  22. package/dist/commands/patchworkInit.js +4 -1
  23. package/dist/commands/patchworkInit.js.map +1 -1
  24. package/dist/commitIssueLinkLog.d.ts +16 -0
  25. package/dist/commitIssueLinkLog.js +87 -4
  26. package/dist/commitIssueLinkLog.js.map +1 -1
  27. package/dist/config.d.ts +20 -1
  28. package/dist/config.js +42 -4
  29. package/dist/config.js.map +1 -1
  30. package/dist/connectorRoutes.js +1 -1
  31. package/dist/connectorRoutes.js.map +1 -1
  32. package/dist/connectors/asana.js +4 -3
  33. package/dist/connectors/asana.js.map +1 -1
  34. package/dist/connectors/confluence.js +35 -0
  35. package/dist/connectors/confluence.js.map +1 -1
  36. package/dist/connectors/datadog.js +33 -4
  37. package/dist/connectors/datadog.js.map +1 -1
  38. package/dist/connectors/discord.js +5 -4
  39. package/dist/connectors/discord.js.map +1 -1
  40. package/dist/connectors/gitlab.js +7 -1
  41. package/dist/connectors/gitlab.js.map +1 -1
  42. package/dist/connectors/mcpOAuth.js +71 -6
  43. package/dist/connectors/mcpOAuth.js.map +1 -1
  44. package/dist/connectors/slack.d.ts +1 -1
  45. package/dist/connectors/slack.js +56 -4
  46. package/dist/connectors/slack.js.map +1 -1
  47. package/dist/connectors/tokenStorage.js +10 -4
  48. package/dist/connectors/tokenStorage.js.map +1 -1
  49. package/dist/decisionTraceLog.d.ts +28 -0
  50. package/dist/decisionTraceLog.js +115 -7
  51. package/dist/decisionTraceLog.js.map +1 -1
  52. package/dist/drivers/claude/subprocess.js +22 -3
  53. package/dist/drivers/claude/subprocess.js.map +1 -1
  54. package/dist/drivers/gemini/index.js +19 -3
  55. package/dist/drivers/gemini/index.js.map +1 -1
  56. package/dist/extensionClient.d.ts +29 -4
  57. package/dist/extensionClient.js +26 -11
  58. package/dist/extensionClient.js.map +1 -1
  59. package/dist/featureFlags.js +18 -32
  60. package/dist/featureFlags.js.map +1 -1
  61. package/dist/fileLockSync.d.ts +67 -0
  62. package/dist/fileLockSync.js +126 -0
  63. package/dist/fileLockSync.js.map +1 -0
  64. package/dist/fp/automationInterpreter.d.ts +6 -0
  65. package/dist/fp/automationInterpreter.js +15 -2
  66. package/dist/fp/automationInterpreter.js.map +1 -1
  67. package/dist/fp/automationState.d.ts +1 -1
  68. package/dist/fp/automationState.js +10 -0
  69. package/dist/fp/automationState.js.map +1 -1
  70. package/dist/fp/commandDescription.js +7 -1
  71. package/dist/fp/commandDescription.js.map +1 -1
  72. package/dist/fsWatchWithFallback.d.ts +36 -0
  73. package/dist/fsWatchWithFallback.js +127 -0
  74. package/dist/fsWatchWithFallback.js.map +1 -0
  75. package/dist/index.js +34 -8
  76. package/dist/index.js.map +1 -1
  77. package/dist/installGuard.js +6 -2
  78. package/dist/installGuard.js.map +1 -1
  79. package/dist/lockfile.js +27 -3
  80. package/dist/lockfile.js.map +1 -1
  81. package/dist/patchworkConfig.js +8 -3
  82. package/dist/patchworkConfig.js.map +1 -1
  83. package/dist/pluginLoader.js +10 -1
  84. package/dist/pluginLoader.js.map +1 -1
  85. package/dist/pluginWatcher.js +6 -13
  86. package/dist/pluginWatcher.js.map +1 -1
  87. package/dist/preToolUseHook.js +3 -2
  88. package/dist/preToolUseHook.js.map +1 -1
  89. package/dist/processTree.d.ts +34 -0
  90. package/dist/processTree.js +105 -0
  91. package/dist/processTree.js.map +1 -0
  92. package/dist/prompts.js +3 -3
  93. package/dist/prompts.js.map +1 -1
  94. package/dist/recipeRoutes.d.ts +1 -0
  95. package/dist/recipeRoutes.js +5 -1
  96. package/dist/recipeRoutes.js.map +1 -1
  97. package/dist/recipes/connectorPreflight.js +64 -0
  98. package/dist/recipes/connectorPreflight.js.map +1 -1
  99. package/dist/recipes/idempotencyKey.js +3 -4
  100. package/dist/recipes/idempotencyKey.js.map +1 -1
  101. package/dist/recipes/installer.js +48 -2
  102. package/dist/recipes/installer.js.map +1 -1
  103. package/dist/recipes/parser.js +82 -4
  104. package/dist/recipes/parser.js.map +1 -1
  105. package/dist/recipes/scheduler.d.ts +17 -0
  106. package/dist/recipes/scheduler.js +33 -1
  107. package/dist/recipes/scheduler.js.map +1 -1
  108. package/dist/recipes/yamlRunner.d.ts +4 -1
  109. package/dist/recipes/yamlRunner.js +18 -6
  110. package/dist/recipes/yamlRunner.js.map +1 -1
  111. package/dist/resources.js +21 -13
  112. package/dist/resources.js.map +1 -1
  113. package/dist/runLog.js +14 -3
  114. package/dist/runLog.js.map +1 -1
  115. package/dist/sanitizeParsedJson.d.ts +39 -0
  116. package/dist/sanitizeParsedJson.js +55 -0
  117. package/dist/sanitizeParsedJson.js.map +1 -0
  118. package/dist/server.d.ts +14 -0
  119. package/dist/server.js +69 -15
  120. package/dist/server.js.map +1 -1
  121. package/dist/sessionCheckpoint.d.ts +8 -0
  122. package/dist/sessionCheckpoint.js +18 -2
  123. package/dist/sessionCheckpoint.js.map +1 -1
  124. package/dist/tools/detectUnusedCode.js +9 -7
  125. package/dist/tools/detectUnusedCode.js.map +1 -1
  126. package/dist/tools/editText.js +2 -1
  127. package/dist/tools/editText.js.map +1 -1
  128. package/dist/tools/fileOperations.js +2 -1
  129. package/dist/tools/fileOperations.js.map +1 -1
  130. package/dist/tools/fileWatcher.js +8 -2
  131. package/dist/tools/fileWatcher.js.map +1 -1
  132. package/dist/tools/fixAllLintErrors.js +10 -5
  133. package/dist/tools/fixAllLintErrors.js.map +1 -1
  134. package/dist/tools/formatDocument.js +10 -5
  135. package/dist/tools/formatDocument.js.map +1 -1
  136. package/dist/tools/handoffNote.js +2 -1
  137. package/dist/tools/handoffNote.js.map +1 -1
  138. package/dist/tools/headless/lspClient.js +3 -0
  139. package/dist/tools/headless/lspClient.js.map +1 -1
  140. package/dist/tools/index.js +0 -6
  141. package/dist/tools/index.js.map +1 -1
  142. package/dist/tools/lsp.js +17 -0
  143. package/dist/tools/lsp.js.map +1 -1
  144. package/dist/tools/openDiff.js +4 -1
  145. package/dist/tools/openDiff.js.map +1 -1
  146. package/dist/tools/openFile.js +4 -1
  147. package/dist/tools/openFile.js.map +1 -1
  148. package/dist/tools/organizeImports.js +5 -3
  149. package/dist/tools/organizeImports.js.map +1 -1
  150. package/dist/tools/previewEdit.js +7 -2
  151. package/dist/tools/previewEdit.js.map +1 -1
  152. package/dist/tools/refactorExtractFunction.js +4 -1
  153. package/dist/tools/refactorExtractFunction.js.map +1 -1
  154. package/dist/tools/refactorPreview.js +10 -2
  155. package/dist/tools/refactorPreview.js.map +1 -1
  156. package/dist/tools/replaceBlock.js +2 -1
  157. package/dist/tools/replaceBlock.js.map +1 -1
  158. package/dist/tools/searchAndReplace.js +2 -1
  159. package/dist/tools/searchAndReplace.js.map +1 -1
  160. package/dist/tools/spawnWorkspace.js +15 -7
  161. package/dist/tools/spawnWorkspace.js.map +1 -1
  162. package/dist/tools/transaction.js +4 -1
  163. package/dist/tools/transaction.js.map +1 -1
  164. package/dist/tools/utils.js +62 -5
  165. package/dist/tools/utils.js.map +1 -1
  166. package/dist/transport.d.ts +1 -1
  167. package/dist/transport.js +18 -4
  168. package/dist/transport.js.map +1 -1
  169. package/dist/winShim.d.ts +34 -0
  170. package/dist/winShim.js +94 -0
  171. package/dist/winShim.js.map +1 -0
  172. package/dist/writeFileAtomic.d.ts +23 -0
  173. package/dist/writeFileAtomic.js +94 -0
  174. package/dist/writeFileAtomic.js.map +1 -0
  175. package/package.json +1 -1
  176. package/scripts/postinstall.mjs +18 -5
  177. package/scripts/smoke/run-all.mjs +55 -4
  178. package/scripts/start-all.mjs +60 -1
  179. package/dist/tools/ccRoutines.d.ts +0 -221
  180. package/dist/tools/ccRoutines.js +0 -264
  181. package/dist/tools/ccRoutines.js.map +0 -1
@@ -58,6 +58,56 @@ const DASH_DIR = path.join(BRIDGE_DIR, "dashboard");
58
58
  const DIST_INDEX = path.join(BRIDGE_DIR, "dist", "index.js");
59
59
  const IS_WIN = process.platform === "win32";
60
60
 
61
+ // ── Security helpers ──────────────────────────────────────────────────────────
62
+ // On Windows `\` is the path separator (e.g. `C:\Program Files\nodejs\node.exe`),
63
+ // not a shell-injection vector. cmd.exe's actual metacharacters are
64
+ // `^ & < > | ( )` — `\` does not need escaping. Including it in the regex
65
+ // would reject every legitimate Windows path that spawnProc validates
66
+ // (process.execPath, npm.cmd, npx.cmd, etc.) and fail-stop the whole script.
67
+ // Same fix that PR #525 applied to vscode-extension/src/bridgeProcess.ts.
68
+ const SHELL_METACHARACTERS = IS_WIN
69
+ ? /[;&|`$(){}[\]<>"'\n\r]/
70
+ : /[;&|`$(){}[\]<>"'\\\n\r]/;
71
+
72
+ /**
73
+ * Validate that a command path is safe to execute.
74
+ * Prevents command injection by checking for shell metacharacters.
75
+ * @param {string} cmdPath - Path to validate
76
+ * @param {string} label - Label for error messages
77
+ * @throws {Error} If path contains shell metacharacters or is empty
78
+ */
79
+ function validateCommandPath(cmdPath, label) {
80
+ if (!cmdPath || typeof cmdPath !== "string") {
81
+ throw new Error(`${label}: command path is empty or invalid`);
82
+ }
83
+ if (SHELL_METACHARACTERS.test(cmdPath)) {
84
+ throw new Error(
85
+ `${label}: command path contains shell metacharacters: ${cmdPath}`,
86
+ );
87
+ }
88
+ // Additional check: on Windows, .cmd files are allowed but must not have spaces without proper quoting
89
+ if (IS_WIN && cmdPath.endsWith(".cmd") && cmdPath.includes(" ")) {
90
+ // This is handled by using cmd.exe explicitly, not shell:true
91
+ // We validate the path doesn't have injection chars above
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Validate command arguments don't contain injection vectors.
97
+ * @param {string[]} args - Arguments to validate
98
+ * @param {string} label - Label for error messages
99
+ */
100
+ function validateCommandArgs(args, label) {
101
+ if (!Array.isArray(args)) {
102
+ throw new Error(`${label}: arguments must be an array`);
103
+ }
104
+ for (const arg of args) {
105
+ if (typeof arg !== "string") {
106
+ throw new Error(`${label}: all arguments must be strings`);
107
+ }
108
+ }
109
+ }
110
+
61
111
  // ── Colour helpers ────────────────────────────────────────────────────────────
62
112
  const C = {
63
113
  cyan: (s) => `\x1b[36m${s}\x1b[0m`,
@@ -98,6 +148,10 @@ function notify(msg, priority = "default") {
98
148
  const procs = new Map(); // name → ChildProcess
99
149
 
100
150
  function spawnProc(name, cmd, cmdArgs, opts = {}) {
151
+ // Validate command and arguments to prevent injection attacks
152
+ validateCommandPath(cmd, `spawnProc[${name}]`);
153
+ validateCommandArgs(cmdArgs, `spawnProc[${name}]`);
154
+
101
155
  // shell:false everywhere — on Windows we always invoke cmd.exe explicitly
102
156
  // for .cmd shim resolution, so shell:true would only widen the attack
103
157
  // surface by interpolating env-derived paths into a shell string.
@@ -238,7 +292,12 @@ function readLock(lockPath) {
238
292
  function bridgeBin() {
239
293
  if (fs.existsSync(DIST_INDEX)) return [process.execPath, [DIST_INDEX]];
240
294
  const srcIndex = path.join(BRIDGE_DIR, "src", "index.ts");
241
- if (fs.existsSync(srcIndex)) return ["npx", ["tsx", srcIndex]];
295
+ if (fs.existsSync(srcIndex)) {
296
+ // On Windows the spawnProc helper uses shell:false, so we must point at
297
+ // the .cmd shim directly — bare "npx" would ENOENT.
298
+ const npx = IS_WIN ? "npx.cmd" : "npx";
299
+ return [npx, ["tsx", srcIndex]];
300
+ }
242
301
  console.error("Error: dist/index.js not found. Run 'npm run build' first.");
243
302
  process.exit(1);
244
303
  }
@@ -1,221 +0,0 @@
1
- /**
2
- * CC Routines Phase 3 — thin MCP tools for Claude Code Routines API.
3
- *
4
- * The `claude routines` subcommand is part of a research preview
5
- * (API identifier: experimental-cc-routine-2026-04-01) gated on
6
- * claude.ai accounts. These tools are registered unconditionally so
7
- * they appear in the MCP handshake and fail gracefully when the API
8
- * is not yet available on the host account.
9
- *
10
- * TODO: ungate when API exits research preview
11
- */
12
- export type RoutinesExecutor = (binary: string, args: string[]) => Promise<{
13
- stdout: string;
14
- }>;
15
- /** Default executor using node:child_process execFile. */
16
- export declare const defaultExecutor: RoutinesExecutor;
17
- export declare function createListRoutinesTool(claudeBinary?: string, executor?: RoutinesExecutor): {
18
- schema: {
19
- name: string;
20
- description: string;
21
- annotations: {
22
- title: string;
23
- readOnlyHint: boolean;
24
- destructiveHint: boolean;
25
- openWorldHint: boolean;
26
- };
27
- inputSchema: {
28
- type: "object";
29
- properties: {};
30
- additionalProperties: false;
31
- };
32
- outputSchema: {
33
- type: string;
34
- properties: {
35
- routines: {
36
- type: string;
37
- items: {
38
- type: string;
39
- properties: {
40
- id: {
41
- type: string;
42
- };
43
- name: {
44
- type: string;
45
- };
46
- schedule: {
47
- type: string;
48
- };
49
- lastRun: {
50
- type: string;
51
- };
52
- status: {
53
- type: string;
54
- };
55
- };
56
- required: string[];
57
- };
58
- };
59
- error: {
60
- type: string;
61
- };
62
- message: {
63
- type: string;
64
- };
65
- };
66
- };
67
- };
68
- handler: (_args: Record<string, unknown>) => Promise<{
69
- content: Array<{
70
- type: string;
71
- text: string;
72
- }>;
73
- structuredContent: unknown;
74
- isError?: undefined;
75
- } | {
76
- content: Array<{
77
- type: string;
78
- text: string;
79
- }>;
80
- isError: true;
81
- } | {
82
- content: {
83
- type: "text";
84
- text: string;
85
- }[];
86
- isError: boolean;
87
- }>;
88
- };
89
- export declare function createRunRoutineTool(claudeBinary?: string, executor?: RoutinesExecutor): {
90
- schema: {
91
- name: string;
92
- description: string;
93
- annotations: {
94
- title: string;
95
- readOnlyHint: boolean;
96
- destructiveHint: boolean;
97
- openWorldHint: boolean;
98
- };
99
- inputSchema: {
100
- type: "object";
101
- properties: {
102
- id: {
103
- type: string;
104
- description: string;
105
- };
106
- input: {
107
- type: string;
108
- description: string;
109
- };
110
- };
111
- required: readonly ["id"];
112
- additionalProperties: false;
113
- };
114
- outputSchema: {
115
- type: string;
116
- properties: {
117
- taskId: {
118
- type: string;
119
- };
120
- status: {
121
- type: string;
122
- };
123
- error: {
124
- type: string;
125
- };
126
- message: {
127
- type: string;
128
- };
129
- };
130
- };
131
- };
132
- handler: (args: Record<string, unknown>) => Promise<{
133
- content: Array<{
134
- type: string;
135
- text: string;
136
- }>;
137
- structuredContent: unknown;
138
- isError?: undefined;
139
- } | {
140
- content: Array<{
141
- type: string;
142
- text: string;
143
- }>;
144
- isError: true;
145
- } | {
146
- content: {
147
- type: "text";
148
- text: string;
149
- }[];
150
- isError: boolean;
151
- }>;
152
- };
153
- export declare function createGetRoutineStatusTool(claudeBinary?: string, executor?: RoutinesExecutor): {
154
- schema: {
155
- name: string;
156
- description: string;
157
- annotations: {
158
- title: string;
159
- readOnlyHint: boolean;
160
- destructiveHint: boolean;
161
- openWorldHint: boolean;
162
- };
163
- inputSchema: {
164
- type: "object";
165
- properties: {
166
- id: {
167
- type: string;
168
- description: string;
169
- };
170
- };
171
- required: readonly ["id"];
172
- additionalProperties: false;
173
- };
174
- outputSchema: {
175
- type: string;
176
- properties: {
177
- id: {
178
- type: string;
179
- };
180
- status: {
181
- type: string;
182
- };
183
- lastRun: {
184
- type: string;
185
- };
186
- nextRun: {
187
- type: string;
188
- };
189
- output: {
190
- type: string;
191
- };
192
- error: {
193
- type: string;
194
- };
195
- message: {
196
- type: string;
197
- };
198
- };
199
- };
200
- };
201
- handler: (args: Record<string, unknown>) => Promise<{
202
- content: Array<{
203
- type: string;
204
- text: string;
205
- }>;
206
- structuredContent: unknown;
207
- isError?: undefined;
208
- } | {
209
- content: Array<{
210
- type: string;
211
- text: string;
212
- }>;
213
- isError: true;
214
- } | {
215
- content: {
216
- type: "text";
217
- text: string;
218
- }[];
219
- isError: boolean;
220
- }>;
221
- };
@@ -1,264 +0,0 @@
1
- /**
2
- * CC Routines Phase 3 — thin MCP tools for Claude Code Routines API.
3
- *
4
- * The `claude routines` subcommand is part of a research preview
5
- * (API identifier: experimental-cc-routine-2026-04-01) gated on
6
- * claude.ai accounts. These tools are registered unconditionally so
7
- * they appear in the MCP handshake and fail gracefully when the API
8
- * is not yet available on the host account.
9
- *
10
- * TODO: ungate when API exits research preview
11
- */
12
- import { execFile } from "node:child_process";
13
- import { ToolErrorCodes } from "../errors.js";
14
- import { error, successStructured } from "./utils.js";
15
- const UNAVAILABLE_ERROR = {
16
- error: "cc_routines_unavailable",
17
- message: "Claude Code Routines API not yet available on this account. See https://claude.ai/code/routines",
18
- };
19
- /** Default executor using node:child_process execFile. */
20
- export const defaultExecutor = (binary, args) => new Promise((resolve, reject) => {
21
- execFile(binary, args, { timeout: 30_000, env: process.env }, (err, stdout) => {
22
- if (err)
23
- reject(err);
24
- else
25
- resolve({ stdout });
26
- });
27
- });
28
- /** Run `claude routines <args>` and return stdout, or null if unavailable. */
29
- async function runRoutinesCli(args, claudeBinary, executor) {
30
- try {
31
- const { stdout } = await executor(claudeBinary, ["routines", ...args]);
32
- return { stdout };
33
- }
34
- catch (e) {
35
- const msg = e instanceof Error ? e.message : String(e);
36
- // Detect "unknown command" / "not found" variants that indicate the
37
- // routines subcommand is not available on this build/account.
38
- if (msg.includes("unknown command") ||
39
- msg.includes("is not a claude command") ||
40
- msg.includes("not found") ||
41
- msg.includes("Unknown argument: routines")) {
42
- return { unavailable: true };
43
- }
44
- return { execError: msg };
45
- }
46
- }
47
- // ---------------------------------------------------------------------------
48
- // listRoutines
49
- // ---------------------------------------------------------------------------
50
- export function createListRoutinesTool(claudeBinary = "claude", executor = defaultExecutor) {
51
- return {
52
- schema: {
53
- name: "listRoutines",
54
- description: "List all Claude Code Routines configured on this account. Returns an array of routine summaries including id, name, schedule, lastRun, and status. Requires the CC Routines research-preview feature.",
55
- annotations: {
56
- title: "List CC Routines",
57
- readOnlyHint: true,
58
- destructiveHint: false,
59
- openWorldHint: true,
60
- },
61
- inputSchema: {
62
- type: "object",
63
- properties: {},
64
- additionalProperties: false,
65
- },
66
- outputSchema: {
67
- type: "object",
68
- properties: {
69
- routines: {
70
- type: "array",
71
- items: {
72
- type: "object",
73
- properties: {
74
- id: { type: "string" },
75
- name: { type: "string" },
76
- schedule: { type: "string" },
77
- lastRun: { type: "string" },
78
- status: { type: "string" },
79
- },
80
- required: ["id", "name"],
81
- },
82
- },
83
- error: { type: "string" },
84
- message: { type: "string" },
85
- },
86
- },
87
- },
88
- handler: async (_args) => {
89
- const result = await runRoutinesCli(["list", "--json"], claudeBinary, executor);
90
- if ("unavailable" in result) {
91
- return {
92
- content: [
93
- { type: "text", text: JSON.stringify(UNAVAILABLE_ERROR) },
94
- ],
95
- isError: true,
96
- };
97
- }
98
- if ("execError" in result) {
99
- return error(`Failed to list routines: ${result.execError}`, ToolErrorCodes.EXTERNAL_COMMAND_FAILED);
100
- }
101
- try {
102
- const parsed = JSON.parse(result.stdout.trim() || "[]");
103
- const routines = Array.isArray(parsed)
104
- ? parsed
105
- : (parsed.routines ?? []);
106
- return successStructured({ routines });
107
- }
108
- catch {
109
- // Non-JSON output — surface as raw text in a best-effort parse
110
- const lines = result.stdout.trim().split("\n").filter(Boolean);
111
- const routines = lines.map((line, i) => ({
112
- id: String(i),
113
- name: line,
114
- }));
115
- return successStructured({ routines });
116
- }
117
- },
118
- };
119
- }
120
- // ---------------------------------------------------------------------------
121
- // runRoutine
122
- // ---------------------------------------------------------------------------
123
- export function createRunRoutineTool(claudeBinary = "claude", executor = defaultExecutor) {
124
- return {
125
- schema: {
126
- name: "runRoutine",
127
- description: "Trigger a Claude Code Routine by ID. Optionally pass an input JSON string. Returns a taskId and initial status. Requires the CC Routines research-preview feature.",
128
- annotations: {
129
- title: "Run CC Routine",
130
- readOnlyHint: false,
131
- destructiveHint: false,
132
- openWorldHint: true,
133
- },
134
- inputSchema: {
135
- type: "object",
136
- properties: {
137
- id: {
138
- type: "string",
139
- description: "Routine ID to run.",
140
- },
141
- input: {
142
- type: "string",
143
- description: "Optional JSON string passed as --input to the routine.",
144
- },
145
- },
146
- required: ["id"],
147
- additionalProperties: false,
148
- },
149
- outputSchema: {
150
- type: "object",
151
- properties: {
152
- taskId: { type: "string" },
153
- status: { type: "string" },
154
- error: { type: "string" },
155
- message: { type: "string" },
156
- },
157
- },
158
- },
159
- handler: async (args) => {
160
- const id = args.id;
161
- if (typeof id !== "string" || id.trim() === "") {
162
- return error("id must be a non-empty string", ToolErrorCodes.INVALID_ARGS);
163
- }
164
- const cliArgs = ["run", id.trim(), "--json"];
165
- if (typeof args.input === "string" && args.input.trim() !== "") {
166
- cliArgs.push("--input", args.input.trim());
167
- }
168
- const result = await runRoutinesCli(cliArgs, claudeBinary, executor);
169
- if ("unavailable" in result) {
170
- return {
171
- content: [
172
- { type: "text", text: JSON.stringify(UNAVAILABLE_ERROR) },
173
- ],
174
- isError: true,
175
- };
176
- }
177
- if ("execError" in result) {
178
- return error(`Failed to run routine: ${result.execError}`, ToolErrorCodes.EXTERNAL_COMMAND_FAILED);
179
- }
180
- try {
181
- const parsed = JSON.parse(result.stdout.trim() || "{}");
182
- return successStructured({
183
- taskId: parsed.taskId ?? parsed.id ?? id,
184
- status: parsed.status ?? "running",
185
- });
186
- }
187
- catch {
188
- return successStructured({ taskId: id, status: "running" });
189
- }
190
- },
191
- };
192
- }
193
- // ---------------------------------------------------------------------------
194
- // getRoutineStatus
195
- // ---------------------------------------------------------------------------
196
- export function createGetRoutineStatusTool(claudeBinary = "claude", executor = defaultExecutor) {
197
- return {
198
- schema: {
199
- name: "getRoutineStatus",
200
- description: "Get the current status, last run time, next scheduled run, and most recent output for a Claude Code Routine. Requires the CC Routines research-preview feature.",
201
- annotations: {
202
- title: "Get CC Routine Status",
203
- readOnlyHint: true,
204
- destructiveHint: false,
205
- openWorldHint: true,
206
- },
207
- inputSchema: {
208
- type: "object",
209
- properties: {
210
- id: {
211
- type: "string",
212
- description: "Routine ID to query.",
213
- },
214
- },
215
- required: ["id"],
216
- additionalProperties: false,
217
- },
218
- outputSchema: {
219
- type: "object",
220
- properties: {
221
- id: { type: "string" },
222
- status: { type: "string" },
223
- lastRun: { type: "string" },
224
- nextRun: { type: "string" },
225
- output: { type: "string" },
226
- error: { type: "string" },
227
- message: { type: "string" },
228
- },
229
- },
230
- },
231
- handler: async (args) => {
232
- const id = args.id;
233
- if (typeof id !== "string" || id.trim() === "") {
234
- return error("id must be a non-empty string", ToolErrorCodes.INVALID_ARGS);
235
- }
236
- const result = await runRoutinesCli(["status", id.trim(), "--json"], claudeBinary, executor);
237
- if ("unavailable" in result) {
238
- return {
239
- content: [
240
- { type: "text", text: JSON.stringify(UNAVAILABLE_ERROR) },
241
- ],
242
- isError: true,
243
- };
244
- }
245
- if ("execError" in result) {
246
- return error(`Failed to get routine status: ${result.execError}`, ToolErrorCodes.EXTERNAL_COMMAND_FAILED);
247
- }
248
- try {
249
- const parsed = JSON.parse(result.stdout.trim() || "{}");
250
- return successStructured({
251
- id: parsed.id ?? id.trim(),
252
- status: parsed.status ?? "unknown",
253
- lastRun: parsed.lastRun ?? parsed.last_run ?? undefined,
254
- nextRun: parsed.nextRun ?? parsed.next_run ?? undefined,
255
- output: parsed.output ?? undefined,
256
- });
257
- }
258
- catch {
259
- return successStructured({ id: id.trim(), status: "unknown" });
260
- }
261
- },
262
- };
263
- }
264
- //# sourceMappingURL=ccRoutines.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ccRoutines.js","sourceRoot":"","sources":["../../src/tools/ccRoutines.ts"],"names":[],"mappings":"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"}