MCPcopy
hub / github.com/coder/mux / createAgentSkillWriteTool

Function createAgentSkillWriteTool

src/node/services/tools/agent_skill_write.ts:82–323  ·  view source on GitHub ↗
(config: ToolConfiguration)

Source from the content-addressed store, hash-verified

80 * Tool that creates/updates files in the contextual skills directory.
81 */
82export const createAgentSkillWriteTool: ToolFactory = (config: ToolConfiguration) => {
83 return tool({
84 description: TOOL_DEFINITIONS.agent_skill_write.description,
85 inputSchema: TOOL_DEFINITIONS.agent_skill_write.schema,
86 execute: async ({
87 name,
88 filePath,
89 content,
90 }: AgentSkillWriteToolArgs): Promise<AgentSkillWriteToolResult> => {
91 const parsedName = SkillNameSchema.safeParse(name);
92 if (!parsedName.success) {
93 return {
94 success: false,
95 error: parsedName.error.message,
96 };
97 }
98
99 try {
100 const relativeFilePath = filePath ?? SKILL_FILENAME;
101 const skillCtx = resolveSkillStorageContext({
102 runtime: config.runtime,
103 workspacePath: config.cwd,
104 muxScope: config.muxScope ?? null,
105 });
106
107 if (skillCtx.kind === "project-runtime") {
108 const skillsRoot = config.runtime.normalizePath(".mux/skills", skillCtx.workspacePath);
109 const skillDir = config.runtime.normalizePath(parsedName.data, skillsRoot);
110
111 let resolvedTarget: ReturnType<typeof resolveSkillFilePathForRuntime>;
112 try {
113 resolvedTarget = resolveSkillFilePathForRuntime(
114 config.runtime,
115 skillDir,
116 relativeFilePath
117 );
118 } catch (error) {
119 return {
120 success: false,
121 error: getErrorMessage(error),
122 };
123 }
124
125 // Canonicalize any casing variant of SKILL.md to the canonical path.
126 // Validate the exact path we will write so casing aliases cannot bypass leaf-symlink checks.
127 if (isSkillMarkdownRootFile(resolvedTarget.normalizedRelativePath)) {
128 resolvedTarget = {
129 ...resolvedTarget,
130 resolvedPath: config.runtime.normalizePath(SKILL_FILENAME, skillDir),
131 normalizedRelativePath: SKILL_FILENAME,
132 };
133 }
134
135 const targetContainment = await inspectContainmentOnRuntime(
136 config.runtime,
137 skillDir,
138 resolvedTarget.resolvedPath
139 );

Callers 3

getToolsForModelFunction · 0.90
createWriteToolFunction · 0.90

Calls 15

getErrorMessageFunction · 0.90
isSkillMarkdownRootFileFunction · 0.90
parseSkillMarkdownFunction · 0.90
readFileStringFunction · 0.90
writeFileStringFunction · 0.90
generateDiffFunction · 0.90

Tested by 1

createWriteToolFunction · 0.72