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.
- package/README.md +95 -25
- package/dist/activityLog.js +2 -1
- package/dist/activityLog.js.map +1 -1
- package/dist/approvalHttp.js +25 -8
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalQueue.d.ts +44 -1
- package/dist/approvalQueue.js +117 -0
- package/dist/approvalQueue.js.map +1 -1
- package/dist/automation.d.ts +3 -3
- package/dist/automation.js +12 -5
- package/dist/automation.js.map +1 -1
- package/dist/bridge.js +29 -1
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeLockDiscovery.js +2 -1
- package/dist/bridgeLockDiscovery.js.map +1 -1
- package/dist/claudeOrchestrator.js +27 -10
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/dashboard.js +8 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/install.js +3 -0
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/patchworkInit.js +4 -1
- package/dist/commands/patchworkInit.js.map +1 -1
- package/dist/commitIssueLinkLog.d.ts +16 -0
- package/dist/commitIssueLinkLog.js +87 -4
- package/dist/commitIssueLinkLog.js.map +1 -1
- package/dist/config.d.ts +20 -1
- package/dist/config.js +42 -4
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +1 -1
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/asana.js +4 -3
- package/dist/connectors/asana.js.map +1 -1
- package/dist/connectors/confluence.js +35 -0
- package/dist/connectors/confluence.js.map +1 -1
- package/dist/connectors/datadog.js +33 -4
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/discord.js +5 -4
- package/dist/connectors/discord.js.map +1 -1
- package/dist/connectors/gitlab.js +7 -1
- package/dist/connectors/gitlab.js.map +1 -1
- package/dist/connectors/mcpOAuth.js +71 -6
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/slack.d.ts +1 -1
- package/dist/connectors/slack.js +56 -4
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/tokenStorage.js +10 -4
- package/dist/connectors/tokenStorage.js.map +1 -1
- package/dist/decisionTraceLog.d.ts +28 -0
- package/dist/decisionTraceLog.js +115 -7
- package/dist/decisionTraceLog.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +22 -3
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/gemini/index.js +19 -3
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/extensionClient.d.ts +29 -4
- package/dist/extensionClient.js +26 -11
- package/dist/extensionClient.js.map +1 -1
- package/dist/featureFlags.js +18 -32
- package/dist/featureFlags.js.map +1 -1
- package/dist/fileLockSync.d.ts +67 -0
- package/dist/fileLockSync.js +126 -0
- package/dist/fileLockSync.js.map +1 -0
- package/dist/fp/automationInterpreter.d.ts +6 -0
- package/dist/fp/automationInterpreter.js +15 -2
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationState.d.ts +1 -1
- package/dist/fp/automationState.js +10 -0
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/commandDescription.js +7 -1
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/fsWatchWithFallback.d.ts +36 -0
- package/dist/fsWatchWithFallback.js +127 -0
- package/dist/fsWatchWithFallback.js.map +1 -0
- package/dist/index.js +34 -8
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -2
- package/dist/installGuard.js.map +1 -1
- package/dist/lockfile.js +27 -3
- package/dist/lockfile.js.map +1 -1
- package/dist/patchworkConfig.js +8 -3
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/pluginLoader.js +10 -1
- package/dist/pluginLoader.js.map +1 -1
- package/dist/pluginWatcher.js +6 -13
- package/dist/pluginWatcher.js.map +1 -1
- package/dist/preToolUseHook.js +3 -2
- package/dist/preToolUseHook.js.map +1 -1
- package/dist/processTree.d.ts +34 -0
- package/dist/processTree.js +105 -0
- package/dist/processTree.js.map +1 -0
- package/dist/prompts.js +3 -3
- package/dist/prompts.js.map +1 -1
- package/dist/recipeRoutes.d.ts +1 -0
- package/dist/recipeRoutes.js +5 -1
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/connectorPreflight.js +64 -0
- package/dist/recipes/connectorPreflight.js.map +1 -1
- package/dist/recipes/idempotencyKey.js +3 -4
- package/dist/recipes/idempotencyKey.js.map +1 -1
- package/dist/recipes/installer.js +48 -2
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/parser.js +82 -4
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/scheduler.d.ts +17 -0
- package/dist/recipes/scheduler.js +33 -1
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +4 -1
- package/dist/recipes/yamlRunner.js +18 -6
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/resources.js +21 -13
- package/dist/resources.js.map +1 -1
- package/dist/runLog.js +14 -3
- package/dist/runLog.js.map +1 -1
- package/dist/sanitizeParsedJson.d.ts +39 -0
- package/dist/sanitizeParsedJson.js +55 -0
- package/dist/sanitizeParsedJson.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.js +69 -15
- package/dist/server.js.map +1 -1
- package/dist/sessionCheckpoint.d.ts +8 -0
- package/dist/sessionCheckpoint.js +18 -2
- package/dist/sessionCheckpoint.js.map +1 -1
- package/dist/tools/detectUnusedCode.js +9 -7
- package/dist/tools/detectUnusedCode.js.map +1 -1
- package/dist/tools/editText.js +2 -1
- package/dist/tools/editText.js.map +1 -1
- package/dist/tools/fileOperations.js +2 -1
- package/dist/tools/fileOperations.js.map +1 -1
- package/dist/tools/fileWatcher.js +8 -2
- package/dist/tools/fileWatcher.js.map +1 -1
- package/dist/tools/fixAllLintErrors.js +10 -5
- package/dist/tools/fixAllLintErrors.js.map +1 -1
- package/dist/tools/formatDocument.js +10 -5
- package/dist/tools/formatDocument.js.map +1 -1
- package/dist/tools/handoffNote.js +2 -1
- package/dist/tools/handoffNote.js.map +1 -1
- package/dist/tools/headless/lspClient.js +3 -0
- package/dist/tools/headless/lspClient.js.map +1 -1
- package/dist/tools/index.js +0 -6
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lsp.js +17 -0
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/openDiff.js +4 -1
- package/dist/tools/openDiff.js.map +1 -1
- package/dist/tools/openFile.js +4 -1
- package/dist/tools/openFile.js.map +1 -1
- package/dist/tools/organizeImports.js +5 -3
- package/dist/tools/organizeImports.js.map +1 -1
- package/dist/tools/previewEdit.js +7 -2
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/refactorExtractFunction.js +4 -1
- package/dist/tools/refactorExtractFunction.js.map +1 -1
- package/dist/tools/refactorPreview.js +10 -2
- package/dist/tools/refactorPreview.js.map +1 -1
- package/dist/tools/replaceBlock.js +2 -1
- package/dist/tools/replaceBlock.js.map +1 -1
- package/dist/tools/searchAndReplace.js +2 -1
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/spawnWorkspace.js +15 -7
- package/dist/tools/spawnWorkspace.js.map +1 -1
- package/dist/tools/transaction.js +4 -1
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/utils.js +62 -5
- package/dist/tools/utils.js.map +1 -1
- package/dist/transport.d.ts +1 -1
- package/dist/transport.js +18 -4
- package/dist/transport.js.map +1 -1
- package/dist/winShim.d.ts +34 -0
- package/dist/winShim.js +94 -0
- package/dist/winShim.js.map +1 -0
- package/dist/writeFileAtomic.d.ts +23 -0
- package/dist/writeFileAtomic.js +94 -0
- package/dist/writeFileAtomic.js.map +1 -0
- package/package.json +1 -1
- package/scripts/postinstall.mjs +18 -5
- package/scripts/smoke/run-all.mjs +55 -4
- package/scripts/start-all.mjs +60 -1
- package/dist/tools/ccRoutines.d.ts +0 -221
- package/dist/tools/ccRoutines.js +0 -264
- package/dist/tools/ccRoutines.js.map +0 -1
package/scripts/start-all.mjs
CHANGED
|
@@ -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))
|
|
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
|
-
};
|
package/dist/tools/ccRoutines.js
DELETED
|
@@ -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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"}
|