@cyanheads/workflows-mcp-server 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +376 -0
- package/Dockerfile +99 -0
- package/LICENSE +201 -0
- package/README.md +306 -0
- package/changelog/0.1.x/0.1.0.md +19 -0
- package/changelog/0.1.x/0.1.1.md +25 -0
- package/changelog/template.md +127 -0
- package/dist/config/server-config.d.ts +13 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +30 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +132 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +14 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-create-temp.tool.d.ts +34 -0
- package/dist/mcp-server/tools/definitions/workflow-create-temp.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-create-temp.tool.js +132 -0
- package/dist/mcp-server/tools/definitions/workflow-create-temp.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-create.tool.d.ts +40 -0
- package/dist/mcp-server/tools/definitions/workflow-create.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-create.tool.js +153 -0
- package/dist/mcp-server/tools/definitions/workflow-create.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-get.tool.d.ts +52 -0
- package/dist/mcp-server/tools/definitions/workflow-get.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-get.tool.js +163 -0
- package/dist/mcp-server/tools/definitions/workflow-get.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-list.tool.d.ts +28 -0
- package/dist/mcp-server/tools/definitions/workflow-list.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/workflow-list.tool.js +148 -0
- package/dist/mcp-server/tools/definitions/workflow-list.tool.js.map +1 -0
- package/dist/services/workflow-index/types.d.ts +49 -0
- package/dist/services/workflow-index/types.d.ts.map +1 -0
- package/dist/services/workflow-index/types.js +6 -0
- package/dist/services/workflow-index/types.js.map +1 -0
- package/dist/services/workflow-index/workflow-index-service.d.ts +47 -0
- package/dist/services/workflow-index/workflow-index-service.d.ts.map +1 -0
- package/dist/services/workflow-index/workflow-index-service.js +395 -0
- package/dist/services/workflow-index/workflow-index-service.js.map +1 -0
- package/package.json +103 -0
- package/server.json +129 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-specific environment configuration for workflows-mcp-server.
|
|
3
|
+
* @module config/server-config
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
declare const ServerConfigSchema: z.ZodObject<{
|
|
7
|
+
workflowsDir: z.ZodDefault<z.ZodString>;
|
|
8
|
+
globalInstructionsPath: z.ZodDefault<z.ZodString>;
|
|
9
|
+
watcherDebounceMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare function getServerConfig(): z.infer<typeof ServerConfigSchema>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=server-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB;;;;iBAetB,CAAC;AAIH,wBAAgB,eAAe,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAOpE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-specific environment configuration for workflows-mcp-server.
|
|
3
|
+
* @module config/server-config
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
const ServerConfigSchema = z.object({
|
|
8
|
+
workflowsDir: z
|
|
9
|
+
.string()
|
|
10
|
+
.default('./workflows-yaml')
|
|
11
|
+
.describe('Absolute or relative path to the workflows root directory'),
|
|
12
|
+
globalInstructionsPath: z
|
|
13
|
+
.string()
|
|
14
|
+
.default('')
|
|
15
|
+
.describe('Path to the global instructions markdown file. Empty string means derive from WORKFLOWS_DIR.'),
|
|
16
|
+
watcherDebounceMs: z.coerce
|
|
17
|
+
.number()
|
|
18
|
+
.default(500)
|
|
19
|
+
.describe('Milliseconds to debounce filesystem change events before rebuilding the index'),
|
|
20
|
+
});
|
|
21
|
+
let _config;
|
|
22
|
+
export function getServerConfig() {
|
|
23
|
+
_config ??= parseEnvConfig(ServerConfigSchema, {
|
|
24
|
+
workflowsDir: 'WORKFLOWS_DIR',
|
|
25
|
+
globalInstructionsPath: 'GLOBAL_INSTRUCTIONS_PATH',
|
|
26
|
+
watcherDebounceMs: 'WATCHER_DEBOUNCE_MS',
|
|
27
|
+
});
|
|
28
|
+
return _config;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=server-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,OAAO,CAAC,kBAAkB,CAAC;SAC3B,QAAQ,CAAC,2DAA2D,CAAC;IACxE,sBAAsB,EAAE,CAAC;SACtB,MAAM,EAAE;SACR,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CACP,8FAA8F,CAC/F;IACH,iBAAiB,EAAE,CAAC,CAAC,MAAM;SACxB,MAAM,EAAE;SACR,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,+EAA+E,CAAC;CAC7F,CAAC,CAAC;AAEH,IAAI,OAAuD,CAAC;AAE5D,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,cAAc,CAAC,kBAAkB,EAAE;QAC7C,YAAY,EAAE,eAAe;QAC7B,sBAAsB,EAAE,0BAA0B;QAClD,iBAAiB,EAAE,qBAAqB;KACzC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview workflows-mcp-server MCP server entry point.
|
|
4
|
+
* @module index
|
|
5
|
+
*/
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import { createApp } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { getServerConfig } from './config/server-config.js';
|
|
9
|
+
import { allToolDefinitions } from './mcp-server/tools/definitions/index.js';
|
|
10
|
+
import { initWorkflowIndexService } from './services/workflow-index/workflow-index-service.js';
|
|
11
|
+
await createApp({
|
|
12
|
+
tools: allToolDefinitions,
|
|
13
|
+
resources: [],
|
|
14
|
+
prompts: [],
|
|
15
|
+
instructions: 'A declarative workflow library. Use workflow_list to discover available workflows, ' +
|
|
16
|
+
'workflow_get to retrieve a full workflow definition with global instructions, ' +
|
|
17
|
+
'workflow_create to persist a new workflow, and workflow_create_temp to store a temporary one-shot plan.',
|
|
18
|
+
setup(core) {
|
|
19
|
+
const cfg = getServerConfig();
|
|
20
|
+
// Resolve the workflows directory relative to CWD
|
|
21
|
+
const workflowsDir = path.resolve(process.cwd(), cfg.workflowsDir);
|
|
22
|
+
// Derive globalInstructionsPath: use explicit override, or default to
|
|
23
|
+
// <workflowsDir>/global_instructions.md
|
|
24
|
+
const globalInstructionsPath = cfg.globalInstructionsPath.trim()
|
|
25
|
+
? path.resolve(process.cwd(), cfg.globalInstructionsPath)
|
|
26
|
+
: path.join(workflowsDir, 'global_instructions.md');
|
|
27
|
+
initWorkflowIndexService(core.config, core.storage, workflowsDir, globalInstructionsPath, cfg.watcherDebounceMs);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAE/F,MAAM,SAAS,CAAC;IACd,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,YAAY,EACV,qFAAqF;QACrF,gFAAgF;QAChF,yGAAyG;IAE3G,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;QAE9B,kDAAkD;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;QAEnE,sEAAsE;QACtE,wCAAwC;QACxC,MAAM,sBAAsB,GAAG,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE;YAC9D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,sBAAsB,CAAC;YACzD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;QAEtD,wBAAwB,CACtB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,OAAO,EACZ,YAAY,EACZ,sBAAsB,EACtB,GAAG,CAAC,iBAAiB,CACtB,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions/index
|
|
4
|
+
*/
|
|
5
|
+
export { workflowCreate } from './workflow-create.tool.js';
|
|
6
|
+
export { workflowCreateTemp } from './workflow-create-temp.tool.js';
|
|
7
|
+
export { workflowGet } from './workflow-get.tool.js';
|
|
8
|
+
export { workflowList } from './workflow-list.tool.js';
|
|
9
|
+
export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
10
|
+
name: import("zod").ZodString;
|
|
11
|
+
version: import("zod").ZodString;
|
|
12
|
+
description: import("zod").ZodString;
|
|
13
|
+
author: import("zod").ZodString;
|
|
14
|
+
category: import("zod").ZodString;
|
|
15
|
+
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
16
|
+
steps: import("zod").ZodArray<import("zod").ZodObject<{
|
|
17
|
+
server: import("zod").ZodString;
|
|
18
|
+
tool: import("zod").ZodString;
|
|
19
|
+
action: import("zod").ZodOptional<import("zod").ZodString>;
|
|
20
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
21
|
+
name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
22
|
+
params: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>;
|
|
23
|
+
forEach: import("zod").ZodOptional<import("zod").ZodString>;
|
|
24
|
+
}, import("zod/v4/core").$strip>>;
|
|
25
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
26
|
+
status: import("zod").ZodLiteral<"created">;
|
|
27
|
+
filePath: import("zod").ZodString;
|
|
28
|
+
key: import("zod").ZodString;
|
|
29
|
+
created_date: import("zod").ZodString;
|
|
30
|
+
last_updated_date: import("zod").ZodString;
|
|
31
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
32
|
+
readonly reason: "already_exists";
|
|
33
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
34
|
+
readonly when: "A permanent workflow with this name@version already exists in the index.";
|
|
35
|
+
readonly recovery: "Change the version field or use a different name to avoid the conflict.";
|
|
36
|
+
}, {
|
|
37
|
+
readonly reason: "write_failed";
|
|
38
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InternalError;
|
|
39
|
+
readonly when: "Filesystem write error (permissions, disk full, or name too long).";
|
|
40
|
+
readonly recovery: "Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.";
|
|
41
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
42
|
+
name: import("zod").ZodString;
|
|
43
|
+
version: import("zod").ZodString;
|
|
44
|
+
description: import("zod").ZodString;
|
|
45
|
+
author: import("zod").ZodString;
|
|
46
|
+
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
47
|
+
steps: import("zod").ZodArray<import("zod").ZodObject<{
|
|
48
|
+
server: import("zod").ZodString;
|
|
49
|
+
tool: import("zod").ZodString;
|
|
50
|
+
action: import("zod").ZodOptional<import("zod").ZodString>;
|
|
51
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
52
|
+
name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
53
|
+
params: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>;
|
|
54
|
+
forEach: import("zod").ZodOptional<import("zod").ZodString>;
|
|
55
|
+
}, import("zod/v4/core").$strip>>;
|
|
56
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
57
|
+
status: import("zod").ZodLiteral<"created">;
|
|
58
|
+
filePath: import("zod").ZodString;
|
|
59
|
+
key: import("zod").ZodString;
|
|
60
|
+
created_date: import("zod").ZodString;
|
|
61
|
+
last_updated_date: import("zod").ZodString;
|
|
62
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
63
|
+
readonly reason: "write_failed";
|
|
64
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InternalError;
|
|
65
|
+
readonly when: "Filesystem write error (permissions, disk full, or name too long).";
|
|
66
|
+
readonly recovery: "Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.";
|
|
67
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
68
|
+
name: import("zod").ZodString;
|
|
69
|
+
version: import("zod").ZodOptional<import("zod").ZodString>;
|
|
70
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
71
|
+
workflow: import("zod").ZodObject<{
|
|
72
|
+
name: import("zod").ZodString;
|
|
73
|
+
version: import("zod").ZodString;
|
|
74
|
+
description: import("zod").ZodString;
|
|
75
|
+
author: import("zod").ZodString;
|
|
76
|
+
category: import("zod").ZodOptional<import("zod").ZodString>;
|
|
77
|
+
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
78
|
+
created_date: import("zod").ZodOptional<import("zod").ZodString>;
|
|
79
|
+
last_updated_date: import("zod").ZodOptional<import("zod").ZodString>;
|
|
80
|
+
temporary: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
81
|
+
steps: import("zod").ZodArray<import("zod").ZodObject<{
|
|
82
|
+
server: import("zod").ZodString;
|
|
83
|
+
tool: import("zod").ZodString;
|
|
84
|
+
action: import("zod").ZodOptional<import("zod").ZodString>;
|
|
85
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
86
|
+
name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
87
|
+
params: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>;
|
|
88
|
+
forEach: import("zod").ZodOptional<import("zod").ZodString>;
|
|
89
|
+
}, import("zod/v4/core").$strip>>;
|
|
90
|
+
}, import("zod/v4/core").$strip>;
|
|
91
|
+
globalInstructions: import("zod").ZodNullable<import("zod").ZodString>;
|
|
92
|
+
source: import("zod").ZodEnum<{
|
|
93
|
+
temp: "temp";
|
|
94
|
+
permanent: "permanent";
|
|
95
|
+
}>;
|
|
96
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
97
|
+
readonly reason: "not_found";
|
|
98
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
99
|
+
readonly when: "No workflow matches the given name.";
|
|
100
|
+
readonly recovery: "Use workflow_list to discover available workflow names and verify spelling.";
|
|
101
|
+
}, {
|
|
102
|
+
readonly reason: "version_not_found";
|
|
103
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
104
|
+
readonly when: "Name exists but the specific version does not.";
|
|
105
|
+
readonly recovery: "Omit version to get the latest, or use workflow_list to see available versions.";
|
|
106
|
+
}, {
|
|
107
|
+
readonly reason: "index_unavailable";
|
|
108
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ServiceUnavailable;
|
|
109
|
+
readonly when: "The workflow index has not finished building yet.";
|
|
110
|
+
readonly recovery: "Retry after the server has finished initializing its workflow index.";
|
|
111
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
112
|
+
category: import("zod").ZodOptional<import("zod").ZodString>;
|
|
113
|
+
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
114
|
+
includeTools: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
115
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
116
|
+
workflows: import("zod").ZodArray<import("zod").ZodObject<{
|
|
117
|
+
name: import("zod").ZodString;
|
|
118
|
+
version: import("zod").ZodString;
|
|
119
|
+
description: import("zod").ZodString;
|
|
120
|
+
author: import("zod").ZodString;
|
|
121
|
+
category: import("zod").ZodOptional<import("zod").ZodString>;
|
|
122
|
+
tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
123
|
+
tools: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
124
|
+
}, import("zod/v4/core").$strip>>;
|
|
125
|
+
totalCount: import("zod").ZodNumber;
|
|
126
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
127
|
+
readonly reason: "index_unavailable";
|
|
128
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ServiceUnavailable;
|
|
129
|
+
readonly when: "The workflow index has not finished building yet.";
|
|
130
|
+
readonly recovery: "Retry after the server has finished initializing its workflow index.";
|
|
131
|
+
}]>)[];
|
|
132
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAOvD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAAkE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions/index
|
|
4
|
+
*/
|
|
5
|
+
export { workflowCreate } from './workflow-create.tool.js';
|
|
6
|
+
export { workflowCreateTemp } from './workflow-create-temp.tool.js';
|
|
7
|
+
export { workflowGet } from './workflow-get.tool.js';
|
|
8
|
+
export { workflowList } from './workflow-list.tool.js';
|
|
9
|
+
import { workflowCreate } from './workflow-create.tool.js';
|
|
10
|
+
import { workflowCreateTemp } from './workflow-create-temp.tool.js';
|
|
11
|
+
import { workflowGet } from './workflow-get.tool.js';
|
|
12
|
+
import { workflowList } from './workflow-list.tool.js';
|
|
13
|
+
export const allToolDefinitions = [workflowList, workflowGet, workflowCreate, workflowCreateTemp];
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for creating a temporary workflow.
|
|
3
|
+
* @module mcp-server/tools/definitions/workflow-create-temp
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const workflowCreateTemp: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
version: z.ZodString;
|
|
10
|
+
description: z.ZodString;
|
|
11
|
+
author: z.ZodString;
|
|
12
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
14
|
+
server: z.ZodString;
|
|
15
|
+
tool: z.ZodString;
|
|
16
|
+
action: z.ZodOptional<z.ZodString>;
|
|
17
|
+
description: z.ZodOptional<z.ZodString>;
|
|
18
|
+
name: z.ZodOptional<z.ZodString>;
|
|
19
|
+
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
20
|
+
forEach: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>>;
|
|
22
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
23
|
+
status: z.ZodLiteral<"created">;
|
|
24
|
+
filePath: z.ZodString;
|
|
25
|
+
key: z.ZodString;
|
|
26
|
+
created_date: z.ZodString;
|
|
27
|
+
last_updated_date: z.ZodString;
|
|
28
|
+
}, z.core.$strip>, readonly [{
|
|
29
|
+
readonly reason: "write_failed";
|
|
30
|
+
readonly code: JsonRpcErrorCode.InternalError;
|
|
31
|
+
readonly when: "Filesystem write error (permissions, disk full, or name too long).";
|
|
32
|
+
readonly recovery: "Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.";
|
|
33
|
+
}]>;
|
|
34
|
+
//# sourceMappingURL=workflow-create-temp.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-create-temp.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/workflow-create-temp.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAwBjE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;GAwH7B,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for creating a temporary workflow.
|
|
3
|
+
* @module mcp-server/tools/definitions/workflow-create-temp
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getWorkflowIndexService } from '../../../services/workflow-index/workflow-index-service.js';
|
|
8
|
+
const StepInputSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
server: z.string().min(1).describe('Target MCP server name.'),
|
|
11
|
+
tool: z.string().min(1).describe('Target tool on the server.'),
|
|
12
|
+
action: z.string().optional().describe('Sub-action or variant label.'),
|
|
13
|
+
description: z.string().optional().describe('Why this step exists.'),
|
|
14
|
+
name: z.string().optional().describe('Optional step name.'),
|
|
15
|
+
params: z
|
|
16
|
+
.record(z.string(), z.unknown())
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Key-value parameter map. May include {{input.foo}} placeholders for the consuming agent to resolve.'),
|
|
19
|
+
forEach: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Iteration expression (opaque, not executed server-side).'),
|
|
23
|
+
})
|
|
24
|
+
.describe('A single workflow step with server, tool, and optional params/metadata.');
|
|
25
|
+
export const workflowCreateTemp = tool('workflow_create_temp', {
|
|
26
|
+
title: 'Create Temporary Workflow',
|
|
27
|
+
description: 'Write a temporary workflow to the temp/ directory. ' +
|
|
28
|
+
'Temporary workflows are indexed and retrievable via workflow_get but excluded from workflow_list results. ' +
|
|
29
|
+
'No conflict check — temp is throwaway. Useful for one-shot plans, short-lived scaffolding, or workflows not intended for the permanent library. ' +
|
|
30
|
+
'The server stamps created_date and last_updated_date automatically.',
|
|
31
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
|
|
32
|
+
input: z.object({
|
|
33
|
+
name: z.string().min(1).describe('Workflow name (human-readable).'),
|
|
34
|
+
version: z
|
|
35
|
+
.string()
|
|
36
|
+
.regex(/^\d+\.\d+\.\d+/)
|
|
37
|
+
.describe('Semver version string (e.g. "1.0.0").'),
|
|
38
|
+
description: z.string().min(1).describe('One-line description of what the workflow does.'),
|
|
39
|
+
author: z.string().min(1).describe('Author name or team.'),
|
|
40
|
+
tags: z.array(z.string()).optional().describe('Free-form tags.'),
|
|
41
|
+
steps: z
|
|
42
|
+
.array(StepInputSchema)
|
|
43
|
+
.min(1)
|
|
44
|
+
.describe('Ordered sequence of steps. Each step must have server and tool fields.'),
|
|
45
|
+
}),
|
|
46
|
+
output: z.object({
|
|
47
|
+
status: z
|
|
48
|
+
.literal('created')
|
|
49
|
+
.describe('Confirms the temporary workflow was written to disk and indexed.'),
|
|
50
|
+
filePath: z.string().describe('Absolute path where the workflow was written.'),
|
|
51
|
+
key: z.string().describe('Index key for this workflow: name@version.'),
|
|
52
|
+
created_date: z.string().describe('Date the workflow was created (YYYY-MM-DD).'),
|
|
53
|
+
last_updated_date: z.string().describe('Date the workflow was last updated (YYYY-MM-DD).'),
|
|
54
|
+
}),
|
|
55
|
+
errors: [
|
|
56
|
+
{
|
|
57
|
+
reason: 'write_failed',
|
|
58
|
+
code: JsonRpcErrorCode.InternalError,
|
|
59
|
+
when: 'Filesystem write error (permissions, disk full, or name too long).',
|
|
60
|
+
recovery: 'Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
async handler(input, ctx) {
|
|
64
|
+
const svc = getWorkflowIndexService();
|
|
65
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
66
|
+
const workflow = {
|
|
67
|
+
name: input.name.trim(),
|
|
68
|
+
version: input.version.trim(),
|
|
69
|
+
description: input.description,
|
|
70
|
+
author: input.author,
|
|
71
|
+
...(input.tags !== undefined && { tags: input.tags }),
|
|
72
|
+
created_date: today,
|
|
73
|
+
last_updated_date: today,
|
|
74
|
+
temporary: true,
|
|
75
|
+
steps: input.steps.map((s) => ({
|
|
76
|
+
server: s.server,
|
|
77
|
+
tool: s.tool,
|
|
78
|
+
...(s.action !== undefined && { action: s.action }),
|
|
79
|
+
...(s.description !== undefined && { description: s.description }),
|
|
80
|
+
...(s.name !== undefined && { name: s.name }),
|
|
81
|
+
...(s.params !== undefined && { params: s.params }),
|
|
82
|
+
...(s.forEach !== undefined && { forEach: s.forEach }),
|
|
83
|
+
})),
|
|
84
|
+
};
|
|
85
|
+
let filePath;
|
|
86
|
+
try {
|
|
87
|
+
filePath = await svc.writeTemp(workflow);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const reason = err._reason;
|
|
91
|
+
if (err instanceof Error && (reason === 'name_too_long' || reason === 'invalid_name')) {
|
|
92
|
+
throw ctx.fail('write_failed', err.message, { ...ctx.recoveryFor('write_failed') });
|
|
93
|
+
}
|
|
94
|
+
ctx.log.error('Failed to write temp workflow', err instanceof Error ? err : new Error(String(err)));
|
|
95
|
+
const safeMsg = err instanceof Error
|
|
96
|
+
? err.message.replace(/\s*open '.*?'/g, '').trim()
|
|
97
|
+
: 'Unknown write error';
|
|
98
|
+
throw ctx.fail('write_failed', `Failed to write temp workflow: ${safeMsg}`, {
|
|
99
|
+
...ctx.recoveryFor('write_failed'),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
ctx.log.info('workflow_create_temp completed', {
|
|
103
|
+
name: workflow.name,
|
|
104
|
+
version: workflow.version,
|
|
105
|
+
filePath,
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
status: 'created',
|
|
109
|
+
filePath,
|
|
110
|
+
key: `${workflow.name}@${workflow.version}`,
|
|
111
|
+
created_date: today,
|
|
112
|
+
last_updated_date: today,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
format(result) {
|
|
116
|
+
return [
|
|
117
|
+
{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: [
|
|
120
|
+
`## Temporary Workflow Created`,
|
|
121
|
+
`**Status:** ${result.status}`,
|
|
122
|
+
`**Key:** ${result.key}`,
|
|
123
|
+
`**File:** ${result.filePath}`,
|
|
124
|
+
`**Created:** ${result.created_date}`,
|
|
125
|
+
`**Updated:** ${result.last_updated_date}`,
|
|
126
|
+
`> This workflow is temporary — excluded from workflow_list but accessible via workflow_get.`,
|
|
127
|
+
].join('\n'),
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=workflow-create-temp.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-create-temp.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/workflow-create-temp.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for creating a permanent workflow.
|
|
3
|
+
* @module mcp-server/tools/definitions/workflow-create
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
export declare const workflowCreate: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
version: z.ZodString;
|
|
10
|
+
description: z.ZodString;
|
|
11
|
+
author: z.ZodString;
|
|
12
|
+
category: z.ZodString;
|
|
13
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
14
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
15
|
+
server: z.ZodString;
|
|
16
|
+
tool: z.ZodString;
|
|
17
|
+
action: z.ZodOptional<z.ZodString>;
|
|
18
|
+
description: z.ZodOptional<z.ZodString>;
|
|
19
|
+
name: z.ZodOptional<z.ZodString>;
|
|
20
|
+
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
forEach: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
24
|
+
status: z.ZodLiteral<"created">;
|
|
25
|
+
filePath: z.ZodString;
|
|
26
|
+
key: z.ZodString;
|
|
27
|
+
created_date: z.ZodString;
|
|
28
|
+
last_updated_date: z.ZodString;
|
|
29
|
+
}, z.core.$strip>, readonly [{
|
|
30
|
+
readonly reason: "already_exists";
|
|
31
|
+
readonly code: JsonRpcErrorCode.Conflict;
|
|
32
|
+
readonly when: "A permanent workflow with this name@version already exists in the index.";
|
|
33
|
+
readonly recovery: "Change the version field or use a different name to avoid the conflict.";
|
|
34
|
+
}, {
|
|
35
|
+
readonly reason: "write_failed";
|
|
36
|
+
readonly code: JsonRpcErrorCode.InternalError;
|
|
37
|
+
readonly when: "Filesystem write error (permissions, disk full, or name too long).";
|
|
38
|
+
readonly recovery: "Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.";
|
|
39
|
+
}]>;
|
|
40
|
+
//# sourceMappingURL=workflow-create.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-create.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/workflow-create.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAwBjE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoJzB,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for creating a permanent workflow.
|
|
3
|
+
* @module mcp-server/tools/definitions/workflow-create
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getWorkflowIndexService } from '../../../services/workflow-index/workflow-index-service.js';
|
|
8
|
+
const StepInputSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
server: z.string().min(1).describe('Target MCP server name.'),
|
|
11
|
+
tool: z.string().min(1).describe('Target tool on the server.'),
|
|
12
|
+
action: z.string().optional().describe('Sub-action or variant label.'),
|
|
13
|
+
description: z.string().optional().describe('Why this step exists.'),
|
|
14
|
+
name: z.string().optional().describe('Optional step name.'),
|
|
15
|
+
params: z
|
|
16
|
+
.record(z.string(), z.unknown())
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Key-value parameter map. May include {{input.foo}} placeholders for the consuming agent to resolve.'),
|
|
19
|
+
forEach: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Iteration expression (opaque, not executed server-side).'),
|
|
23
|
+
})
|
|
24
|
+
.describe('A single workflow step with server, tool, and optional params/metadata.');
|
|
25
|
+
export const workflowCreate = tool('workflow_create', {
|
|
26
|
+
title: 'Create Workflow',
|
|
27
|
+
description: 'Write a new permanent workflow YAML to the categories/<slugified-category>/ directory. ' +
|
|
28
|
+
'Rejects if name@version already exists in the index — use a different version to update. ' +
|
|
29
|
+
'The server stamps created_date and last_updated_date automatically. ' +
|
|
30
|
+
'Rebuilds the index after writing. Template placeholders in params ({{input.foo}}) are stored verbatim.',
|
|
31
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },
|
|
32
|
+
input: z.object({
|
|
33
|
+
name: z
|
|
34
|
+
.string()
|
|
35
|
+
.min(1)
|
|
36
|
+
.describe('Workflow name (human-readable, e.g. "Standard Git Wrap-up").'),
|
|
37
|
+
version: z
|
|
38
|
+
.string()
|
|
39
|
+
.regex(/^\d+\.\d+\.\d+/)
|
|
40
|
+
.describe('Semver version string (e.g. "1.0.0").'),
|
|
41
|
+
description: z.string().min(1).describe('One-line description of what the workflow does.'),
|
|
42
|
+
author: z.string().min(1).describe('Author name or team.'),
|
|
43
|
+
category: z
|
|
44
|
+
.string()
|
|
45
|
+
.min(1)
|
|
46
|
+
.describe('Category name (e.g. "Git Operations"). Used to determine the storage directory. Must not be blank or whitespace-only.'),
|
|
47
|
+
tags: z.array(z.string()).optional().describe('Free-form tags for filtering.'),
|
|
48
|
+
steps: z
|
|
49
|
+
.array(StepInputSchema)
|
|
50
|
+
.min(1)
|
|
51
|
+
.describe('Ordered sequence of steps. Each step must have server and tool fields.'),
|
|
52
|
+
}),
|
|
53
|
+
output: z.object({
|
|
54
|
+
status: z.literal('created').describe('Confirms the workflow was written to disk and indexed.'),
|
|
55
|
+
filePath: z.string().describe('Absolute path where the workflow was written.'),
|
|
56
|
+
key: z.string().describe('Index key for this workflow: name@version.'),
|
|
57
|
+
created_date: z.string().describe('Date the workflow was created (YYYY-MM-DD).'),
|
|
58
|
+
last_updated_date: z.string().describe('Date the workflow was last updated (YYYY-MM-DD).'),
|
|
59
|
+
}),
|
|
60
|
+
errors: [
|
|
61
|
+
{
|
|
62
|
+
reason: 'already_exists',
|
|
63
|
+
code: JsonRpcErrorCode.Conflict,
|
|
64
|
+
when: 'A permanent workflow with this name@version already exists in the index.',
|
|
65
|
+
recovery: 'Change the version field or use a different name to avoid the conflict.',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
reason: 'write_failed',
|
|
69
|
+
code: JsonRpcErrorCode.InternalError,
|
|
70
|
+
when: 'Filesystem write error (permissions, disk full, or name too long).',
|
|
71
|
+
recovery: 'Check that the workflows directory is writable, has sufficient disk space, and that the workflow name is not excessively long.',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
async handler(input, ctx) {
|
|
75
|
+
const svc = getWorkflowIndexService();
|
|
76
|
+
// Reject whitespace-only category at the tool boundary (Zod min(1) passes " ").
|
|
77
|
+
if (input.category.trim().length === 0) {
|
|
78
|
+
throw ctx.fail('write_failed', 'Category must not be blank or whitespace-only.', {
|
|
79
|
+
...ctx.recoveryFor('write_failed'),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
83
|
+
const workflow = {
|
|
84
|
+
name: input.name.trim(),
|
|
85
|
+
version: input.version.trim(),
|
|
86
|
+
description: input.description,
|
|
87
|
+
author: input.author,
|
|
88
|
+
category: input.category.trim(),
|
|
89
|
+
...(input.tags !== undefined && { tags: input.tags }),
|
|
90
|
+
created_date: today,
|
|
91
|
+
last_updated_date: today,
|
|
92
|
+
steps: input.steps.map((s) => ({
|
|
93
|
+
server: s.server,
|
|
94
|
+
tool: s.tool,
|
|
95
|
+
...(s.action !== undefined && { action: s.action }),
|
|
96
|
+
...(s.description !== undefined && { description: s.description }),
|
|
97
|
+
...(s.name !== undefined && { name: s.name }),
|
|
98
|
+
...(s.params !== undefined && { params: s.params }),
|
|
99
|
+
...(s.forEach !== undefined && { forEach: s.forEach }),
|
|
100
|
+
})),
|
|
101
|
+
};
|
|
102
|
+
let filePath;
|
|
103
|
+
try {
|
|
104
|
+
filePath = await svc.writePermanent(workflow);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const reason = err._reason;
|
|
108
|
+
if (err instanceof Error && reason === 'already_exists') {
|
|
109
|
+
throw ctx.fail('already_exists', `Workflow "${workflow.name}@${workflow.version}" already exists`, { ...ctx.recoveryFor('already_exists') });
|
|
110
|
+
}
|
|
111
|
+
if (err instanceof Error && (reason === 'name_too_long' || reason === 'invalid_name')) {
|
|
112
|
+
// Surface name validation issues as write_failed with the service's message (no path leak).
|
|
113
|
+
throw ctx.fail('write_failed', err.message, { ...ctx.recoveryFor('write_failed') });
|
|
114
|
+
}
|
|
115
|
+
ctx.log.error('Failed to write workflow', err instanceof Error ? err : new Error(String(err)));
|
|
116
|
+
// Strip filesystem paths from the user-visible message.
|
|
117
|
+
const safeMsg = err instanceof Error
|
|
118
|
+
? err.message.replace(/\s*open '.*?'/g, '').trim()
|
|
119
|
+
: 'Unknown write error';
|
|
120
|
+
throw ctx.fail('write_failed', `Failed to write workflow: ${safeMsg}`, {
|
|
121
|
+
...ctx.recoveryFor('write_failed'),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
ctx.log.info('workflow_create completed', {
|
|
125
|
+
name: workflow.name,
|
|
126
|
+
version: workflow.version,
|
|
127
|
+
filePath,
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
status: 'created',
|
|
131
|
+
filePath,
|
|
132
|
+
key: `${workflow.name}@${workflow.version}`,
|
|
133
|
+
created_date: today,
|
|
134
|
+
last_updated_date: today,
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
format(result) {
|
|
138
|
+
return [
|
|
139
|
+
{
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: [
|
|
142
|
+
`## Workflow Created`,
|
|
143
|
+
`**Status:** ${result.status}`,
|
|
144
|
+
`**Key:** ${result.key}`,
|
|
145
|
+
`**File:** ${result.filePath}`,
|
|
146
|
+
`**Created:** ${result.created_date}`,
|
|
147
|
+
`**Updated:** ${result.last_updated_date}`,
|
|
148
|
+
].join('\n'),
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=workflow-create.tool.js.map
|