@perstack/base 0.0.61 → 0.0.62
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/dist/bin/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { F as version, N as description, P as name, r as createBaseServer } from "../server-
|
|
2
|
+
import { F as version, N as description, P as name, r as createBaseServer } from "../server-ByOYnUvF.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import { z } from "zod
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { z as z$1 } from "zod/v4";
|
|
3
4
|
import fs, { constants, lstat, mkdir, open, stat } from "node:fs/promises";
|
|
4
5
|
import { existsSync, realpathSync } from "node:fs";
|
|
5
6
|
import os from "node:os";
|
|
@@ -10,7 +11,7 @@ import { getFilteredEnv } from "@perstack/core";
|
|
|
10
11
|
|
|
11
12
|
//#region package.json
|
|
12
13
|
var name = "@perstack/base";
|
|
13
|
-
var version = "0.0.
|
|
14
|
+
var version = "0.0.62";
|
|
14
15
|
var description = "Perstack base skills for agents.";
|
|
15
16
|
|
|
16
17
|
//#endregion
|
|
@@ -70,8 +71,8 @@ function registerTodo(server) {
|
|
|
70
71
|
title: "todo",
|
|
71
72
|
description: "Manage a todo list: add tasks and mark them completed.",
|
|
72
73
|
inputSchema: {
|
|
73
|
-
newTodos: z.array(z.string()).describe("New todos to add").optional(),
|
|
74
|
-
completedTodos: z.array(z.number()).describe("Todo ids that are completed").optional()
|
|
74
|
+
newTodos: z$1.array(z$1.string()).describe("New todos to add").optional(),
|
|
75
|
+
completedTodos: z$1.array(z$1.number()).describe("Todo ids that are completed").optional()
|
|
75
76
|
}
|
|
76
77
|
}, async (input) => {
|
|
77
78
|
try {
|
|
@@ -107,8 +108,8 @@ async function attemptCompletion() {
|
|
|
107
108
|
function registerAttemptCompletion(server) {
|
|
108
109
|
server.registerTool("attemptCompletion", {
|
|
109
110
|
title: "Attempt completion",
|
|
110
|
-
description: "Signal task completion. Validates all todos are complete before ending.",
|
|
111
|
-
inputSchema: {}
|
|
111
|
+
description: "Signal task completion. Provide a result parameter with your final response text. Validates all todos are complete before ending.",
|
|
112
|
+
inputSchema: z.object({ result: z.string().optional() }).strict()
|
|
112
113
|
}, async () => {
|
|
113
114
|
try {
|
|
114
115
|
return successToolResult(await attemptCompletion());
|
|
@@ -208,9 +209,9 @@ function registerEditTextFile(server) {
|
|
|
208
209
|
title: "Edit text file",
|
|
209
210
|
description: "Replace exact text in an existing file. Normalizes line endings (CRLF → LF).",
|
|
210
211
|
inputSchema: {
|
|
211
|
-
path: z.string().describe("Target file path to edit."),
|
|
212
|
-
newText: z.string().describe("Text to replace with."),
|
|
213
|
-
oldText: z.string().describe("Exact text to find and replace.")
|
|
212
|
+
path: z$1.string().describe("Target file path to edit."),
|
|
213
|
+
newText: z$1.string().describe("Text to replace with."),
|
|
214
|
+
oldText: z$1.string().describe("Exact text to find and replace.")
|
|
214
215
|
}
|
|
215
216
|
}, async (input) => {
|
|
216
217
|
try {
|
|
@@ -247,13 +248,13 @@ function registerExec(server) {
|
|
|
247
248
|
title: "Execute Command",
|
|
248
249
|
description: "Execute a system command. Returns stdout/stderr.",
|
|
249
250
|
inputSchema: {
|
|
250
|
-
command: z.string().describe("The command to execute"),
|
|
251
|
-
args: z.array(z.string()).describe("The arguments to pass to the command"),
|
|
252
|
-
env: z.record(z.string(), z.string()).describe("The environment variables to set"),
|
|
253
|
-
cwd: z.string().describe("The working directory to execute the command in"),
|
|
254
|
-
stdout: z.boolean().describe("Whether to capture the standard output"),
|
|
255
|
-
stderr: z.boolean().describe("Whether to capture the standard error"),
|
|
256
|
-
timeout: z.number().optional().default(6e4).describe("Timeout in milliseconds (default: 60000)")
|
|
251
|
+
command: z$1.string().describe("The command to execute"),
|
|
252
|
+
args: z$1.array(z$1.string()).describe("The arguments to pass to the command"),
|
|
253
|
+
env: z$1.record(z$1.string(), z$1.string()).describe("The environment variables to set"),
|
|
254
|
+
cwd: z$1.string().describe("The working directory to execute the command in"),
|
|
255
|
+
stdout: z$1.boolean().describe("Whether to capture the standard output"),
|
|
256
|
+
stderr: z$1.boolean().describe("Whether to capture the standard error"),
|
|
257
|
+
timeout: z$1.number().optional().default(6e4).describe("Timeout in milliseconds (default: 60000)")
|
|
257
258
|
}
|
|
258
259
|
}, async (input) => {
|
|
259
260
|
try {
|
|
@@ -322,7 +323,7 @@ function registerReadImageFile(server) {
|
|
|
322
323
|
server.registerTool("readImageFile", {
|
|
323
324
|
title: "Read image file",
|
|
324
325
|
description: "Read an image file as base64. Supports PNG, JPEG, GIF, WebP. Max 15MB.",
|
|
325
|
-
inputSchema: { path: z.string() }
|
|
326
|
+
inputSchema: { path: z$1.string() }
|
|
326
327
|
}, async (input) => {
|
|
327
328
|
try {
|
|
328
329
|
return successToolResult(await readImageFile(input));
|
|
@@ -355,7 +356,7 @@ function registerReadPdfFile(server) {
|
|
|
355
356
|
server.registerTool("readPdfFile", {
|
|
356
357
|
title: "Read PDF file",
|
|
357
358
|
description: "Read a PDF file as base64. Max 30MB.",
|
|
358
|
-
inputSchema: { path: z.string() }
|
|
359
|
+
inputSchema: { path: z$1.string() }
|
|
359
360
|
}, async (input) => {
|
|
360
361
|
try {
|
|
361
362
|
return successToolResult(await readPdfFile(input));
|
|
@@ -387,9 +388,9 @@ function registerReadTextFile(server) {
|
|
|
387
388
|
title: "Read text file",
|
|
388
389
|
description: "Read a UTF-8 text file. Supports partial reading via line ranges.",
|
|
389
390
|
inputSchema: {
|
|
390
|
-
path: z.string(),
|
|
391
|
-
from: z.number().optional().describe("The line number to start reading from."),
|
|
392
|
-
to: z.number().optional().describe("The line number to stop reading at.")
|
|
391
|
+
path: z$1.string(),
|
|
392
|
+
from: z$1.number().optional().describe("The line number to start reading from."),
|
|
393
|
+
to: z$1.number().optional().describe("The line number to stop reading at.")
|
|
393
394
|
}
|
|
394
395
|
}, async (input) => {
|
|
395
396
|
try {
|
|
@@ -408,17 +409,17 @@ function registerAddSkill(server, callbacks) {
|
|
|
408
409
|
title: "Add skill",
|
|
409
410
|
description: "Dynamically add an MCP skill. Returns the list of tool names provided by the new skill.",
|
|
410
411
|
inputSchema: {
|
|
411
|
-
name: z.string().describe("Unique skill name"),
|
|
412
|
-
type: z.enum(["mcpStdioSkill", "mcpSseSkill"]).describe("Skill transport type"),
|
|
413
|
-
command: z.string().optional().describe("Command to execute (for stdio skills)"),
|
|
414
|
-
packageName: z.string().optional().describe("Package name for npx/uvx (for stdio skills)"),
|
|
415
|
-
args: z.array(z.string()).optional().describe("Additional command arguments"),
|
|
416
|
-
requiredEnv: z.array(z.string()).optional().describe("Required environment variable names"),
|
|
417
|
-
endpoint: z.string().optional().describe("SSE endpoint URL (for SSE skills)"),
|
|
418
|
-
description: z.string().optional().describe("Human-readable description"),
|
|
419
|
-
rule: z.string().optional().describe("Usage rules for the LLM"),
|
|
420
|
-
pick: z.array(z.string()).optional().describe("Tool names to include (whitelist)"),
|
|
421
|
-
omit: z.array(z.string()).optional().describe("Tool names to exclude (blacklist)")
|
|
412
|
+
name: z$1.string().describe("Unique skill name"),
|
|
413
|
+
type: z$1.enum(["mcpStdioSkill", "mcpSseSkill"]).describe("Skill transport type"),
|
|
414
|
+
command: z$1.string().optional().describe("Command to execute (for stdio skills)"),
|
|
415
|
+
packageName: z$1.string().optional().describe("Package name for npx/uvx (for stdio skills)"),
|
|
416
|
+
args: z$1.array(z$1.string()).optional().describe("Additional command arguments"),
|
|
417
|
+
requiredEnv: z$1.array(z$1.string()).optional().describe("Required environment variable names"),
|
|
418
|
+
endpoint: z$1.string().optional().describe("SSE endpoint URL (for SSE skills)"),
|
|
419
|
+
description: z$1.string().optional().describe("Human-readable description"),
|
|
420
|
+
rule: z$1.string().optional().describe("Usage rules for the LLM"),
|
|
421
|
+
pick: z$1.array(z$1.string()).optional().describe("Tool names to include (whitelist)"),
|
|
422
|
+
omit: z$1.array(z$1.string()).optional().describe("Tool names to exclude (blacklist)")
|
|
422
423
|
}
|
|
423
424
|
}, async (input) => {
|
|
424
425
|
try {
|
|
@@ -433,7 +434,7 @@ function registerRemoveSkill(server, callbacks) {
|
|
|
433
434
|
server.registerTool("removeSkill", {
|
|
434
435
|
title: "Remove skill",
|
|
435
436
|
description: "Dynamically remove an MCP skill by name. Disconnects and removes the skill.",
|
|
436
|
-
inputSchema: { skillName: z.string().describe("Name of the skill to remove") }
|
|
437
|
+
inputSchema: { skillName: z$1.string().describe("Name of the skill to remove") }
|
|
437
438
|
}, async (input) => {
|
|
438
439
|
try {
|
|
439
440
|
await callbacks.removeSkill(input.skillName);
|
|
@@ -448,7 +449,7 @@ function registerAddDelegate(server, callbacks) {
|
|
|
448
449
|
server.registerTool("addDelegate", {
|
|
449
450
|
title: "Add delegate",
|
|
450
451
|
description: "Dynamically add a delegate expert. Returns the delegate tool name so you know what to call.",
|
|
451
|
-
inputSchema: { expertKey: z.string().describe("Key of the expert to add as a delegate") }
|
|
452
|
+
inputSchema: { expertKey: z$1.string().describe("Key of the expert to add as a delegate") }
|
|
452
453
|
}, async (input) => {
|
|
453
454
|
try {
|
|
454
455
|
return successToolResult(await callbacks.addDelegate(input.expertKey));
|
|
@@ -462,7 +463,7 @@ function registerRemoveDelegate(server, callbacks) {
|
|
|
462
463
|
server.registerTool("removeDelegate", {
|
|
463
464
|
title: "Remove delegate",
|
|
464
465
|
description: "Dynamically remove a delegate expert by name.",
|
|
465
|
-
inputSchema: { expertName: z.string().describe("Name of the delegate expert to remove") }
|
|
466
|
+
inputSchema: { expertName: z$1.string().describe("Name of the delegate expert to remove") }
|
|
466
467
|
}, async (input) => {
|
|
467
468
|
try {
|
|
468
469
|
await callbacks.removeDelegate(input.expertName);
|
|
@@ -478,26 +479,26 @@ function registerCreateExpert(server, callbacks) {
|
|
|
478
479
|
title: "Create expert",
|
|
479
480
|
description: "Dynamically create an expert definition in memory. Returns the expert key so you can add it as a delegate.",
|
|
480
481
|
inputSchema: {
|
|
481
|
-
key: z.string().describe("Unique expert key (kebab-case)"),
|
|
482
|
-
instruction: z.string().describe("System instruction for the expert"),
|
|
483
|
-
description: z.string().optional().describe("Human-readable description"),
|
|
484
|
-
version: z.string().optional().describe("Semantic version (defaults to 1.0.0)"),
|
|
485
|
-
skills: z.record(z.string(), z.object({
|
|
486
|
-
type: z.enum(["mcpStdioSkill", "mcpSseSkill"]).describe("Skill transport type"),
|
|
487
|
-
command: z.string().optional().describe("Command to execute (for stdio skills)"),
|
|
488
|
-
packageName: z.string().optional().describe("Package name for npx/uvx (for stdio skills)"),
|
|
489
|
-
args: z.array(z.string()).optional().describe("Additional command arguments"),
|
|
490
|
-
requiredEnv: z.array(z.string()).optional().describe("Required environment variable names"),
|
|
491
|
-
endpoint: z.string().optional().describe("SSE endpoint URL (for SSE skills)"),
|
|
492
|
-
description: z.string().optional().describe("Human-readable description"),
|
|
493
|
-
rule: z.string().optional().describe("Usage rules for the LLM"),
|
|
494
|
-
pick: z.array(z.string()).optional().describe("Tool names to include (whitelist)"),
|
|
495
|
-
omit: z.array(z.string()).optional().describe("Tool names to exclude (blacklist)"),
|
|
496
|
-
lazyInit: z.boolean().optional().describe("Lazy initialization")
|
|
482
|
+
key: z$1.string().describe("Unique expert key (kebab-case)"),
|
|
483
|
+
instruction: z$1.string().describe("System instruction for the expert"),
|
|
484
|
+
description: z$1.string().optional().describe("Human-readable description"),
|
|
485
|
+
version: z$1.string().optional().describe("Semantic version (defaults to 1.0.0)"),
|
|
486
|
+
skills: z$1.record(z$1.string(), z$1.object({
|
|
487
|
+
type: z$1.enum(["mcpStdioSkill", "mcpSseSkill"]).describe("Skill transport type"),
|
|
488
|
+
command: z$1.string().optional().describe("Command to execute (for stdio skills)"),
|
|
489
|
+
packageName: z$1.string().optional().describe("Package name for npx/uvx (for stdio skills)"),
|
|
490
|
+
args: z$1.array(z$1.string()).optional().describe("Additional command arguments"),
|
|
491
|
+
requiredEnv: z$1.array(z$1.string()).optional().describe("Required environment variable names"),
|
|
492
|
+
endpoint: z$1.string().optional().describe("SSE endpoint URL (for SSE skills)"),
|
|
493
|
+
description: z$1.string().optional().describe("Human-readable description"),
|
|
494
|
+
rule: z$1.string().optional().describe("Usage rules for the LLM"),
|
|
495
|
+
pick: z$1.array(z$1.string()).optional().describe("Tool names to include (whitelist)"),
|
|
496
|
+
omit: z$1.array(z$1.string()).optional().describe("Tool names to exclude (blacklist)"),
|
|
497
|
+
lazyInit: z$1.boolean().optional().describe("Lazy initialization")
|
|
497
498
|
})).optional().describe("Skills map (defaults to @perstack/base)"),
|
|
498
|
-
delegates: z.array(z.string()).optional().describe("Expert keys to delegate to"),
|
|
499
|
-
tags: z.array(z.string()).optional().describe("Tags for categorization"),
|
|
500
|
-
providerTools: z.array(z.string()).optional().describe("Provider-specific tool names")
|
|
499
|
+
delegates: z$1.array(z$1.string()).optional().describe("Expert keys to delegate to"),
|
|
500
|
+
tags: z$1.array(z$1.string()).optional().describe("Tags for categorization"),
|
|
501
|
+
providerTools: z$1.array(z$1.string()).optional().describe("Provider-specific tool names")
|
|
501
502
|
}
|
|
502
503
|
}, async (input) => {
|
|
503
504
|
try {
|
|
@@ -535,8 +536,8 @@ function registerWriteTextFile(server) {
|
|
|
535
536
|
title: "writeTextFile",
|
|
536
537
|
description: "Create or overwrite a UTF-8 text file. Creates parent directories as needed.",
|
|
537
538
|
inputSchema: {
|
|
538
|
-
path: z.string().describe("Target file path (relative or absolute)."),
|
|
539
|
-
text: z.string().describe("Text to write to the file.")
|
|
539
|
+
path: z$1.string().describe("Target file path (relative or absolute)."),
|
|
540
|
+
text: z$1.string().describe("Text to write to the file.")
|
|
540
541
|
}
|
|
541
542
|
}, async (input) => {
|
|
542
543
|
try {
|
|
@@ -585,4 +586,4 @@ function createBaseServer(options) {
|
|
|
585
586
|
|
|
586
587
|
//#endregion
|
|
587
588
|
export { todo as A, validatePath as C, getRemainingTodos as D, clearTodo as E, version as F, successToolResult as M, description as N, registerClearTodo as O, name as P, registerEditTextFile as S, registerAttemptCompletion as T, readImageFile as _, registerWriteTextFile as a, registerExec as b, registerAddSkill as c, registerRemoveSkill as d, registerSkillManagementTools as f, registerReadPdfFile as g, readPdfFile as h, registerAllTools as i, errorToolResult as j, registerTodo as k, registerCreateExpert as l, registerReadTextFile as m, BASE_SKILL_VERSION as n, writeTextFile as o, readTextFile as p, createBaseServer as r, registerAddDelegate as s, BASE_SKILL_NAME as t, registerRemoveDelegate as u, registerReadImageFile as v, attemptCompletion as w, editTextFile as x, exec as y };
|
|
588
|
-
//# sourceMappingURL=server-
|
|
589
|
+
//# sourceMappingURL=server-ByOYnUvF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-ByOYnUvF.js","names":["z","z","z","z","z","z","z","z","packageJson.name","packageJson.version"],"sources":["../package.json","../src/lib/tool-result.ts","../src/tools/todo.ts","../src/tools/attempt-completion.ts","../src/lib/path.ts","../src/lib/safe-file.ts","../src/tools/edit-text-file.ts","../src/tools/exec.ts","../src/lib/mime.ts","../src/tools/read-image-file.ts","../src/tools/read-pdf-file.ts","../src/tools/read-text-file.ts","../src/tools/skill-management.ts","../src/tools/write-text-file.ts","../src/server.ts"],"sourcesContent":["","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\"\n\nexport function successToolResult(result: unknown): CallToolResult {\n return { content: [{ type: \"text\", text: JSON.stringify(result) }] }\n}\n\nexport function errorToolResult(e: Error): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify({ error: e.name, message: e.message }) }],\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nclass Todo {\n currentTodoId = 0\n todos: { id: number; title: string; completed: boolean }[] = []\n public processTodo(input: { newTodos?: string[]; completedTodos?: number[] }) {\n const { newTodos, completedTodos } = input\n if (newTodos) {\n this.todos.push(\n ...newTodos.map((title) => ({ id: this.currentTodoId++, title, completed: false })),\n )\n }\n if (completedTodos) {\n this.todos = this.todos.map((todo) => ({\n ...todo,\n completed: todo.completed || completedTodos.includes(todo.id),\n }))\n }\n return {\n todos: this.todos,\n }\n }\n public clearTodo() {\n this.todos = []\n this.currentTodoId = 0\n return {\n todos: this.todos,\n }\n }\n}\nconst todoSingleton = new Todo()\nexport async function todo(input: { newTodos?: string[]; completedTodos?: number[] }) {\n return todoSingleton.processTodo(input)\n}\nexport async function clearTodo() {\n return todoSingleton.clearTodo()\n}\nexport function getRemainingTodos() {\n return todoSingleton.todos.filter((t) => !t.completed)\n}\n\nexport function registerTodo(server: McpServer) {\n server.registerTool(\n \"todo\",\n {\n title: \"todo\",\n description: \"Manage a todo list: add tasks and mark them completed.\",\n inputSchema: {\n newTodos: z.array(z.string()).describe(\"New todos to add\").optional(),\n completedTodos: z.array(z.number()).describe(\"Todo ids that are completed\").optional(),\n },\n },\n async (input: { newTodos?: string[]; completedTodos?: number[] }) => {\n try {\n return successToolResult(await todo(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerClearTodo(server: McpServer) {\n server.registerTool(\n \"clearTodo\",\n {\n title: \"clearTodo\",\n description: \"Clear all todos.\",\n inputSchema: {},\n },\n async () => {\n try {\n return successToolResult(await clearTodo())\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\nimport { getRemainingTodos } from \"./todo.js\"\n\nexport type AttemptCompletionResult =\n | { remainingTodos: { id: number; title: string; completed: boolean }[] }\n | Record<string, never>\n\nexport async function attemptCompletion(): Promise<AttemptCompletionResult> {\n const remainingTodos = getRemainingTodos()\n if (remainingTodos.length > 0) {\n return { remainingTodos }\n }\n return {}\n}\n\nexport function registerAttemptCompletion(server: McpServer) {\n server.registerTool(\n \"attemptCompletion\",\n {\n title: \"Attempt completion\",\n description:\n \"Signal task completion. Provide a result parameter with your final response text. Validates all todos are complete before ending.\",\n inputSchema: z.object({ result: z.string().optional() }).strict(),\n },\n async () => {\n try {\n return successToolResult(await attemptCompletion())\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { realpathSync } from \"node:fs\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nexport const workspacePath = realpathSync(expandHome(process.cwd()))\n\nfunction expandHome(filepath: string): string {\n if (filepath.startsWith(\"~/\") || filepath === \"~\") {\n return path.join(os.homedir(), filepath.slice(1))\n }\n return filepath\n}\n\nexport async function validatePath(requestedPath: string): Promise<string> {\n const expandedPath = expandHome(requestedPath)\n const absolute = path.isAbsolute(expandedPath)\n ? path.resolve(expandedPath)\n : path.resolve(process.cwd(), expandedPath)\n const perstackDir = `${workspacePath}/perstack`.toLowerCase()\n if (\n absolute.toLowerCase() === perstackDir ||\n absolute.toLowerCase().startsWith(`${perstackDir}/`)\n ) {\n throw new Error(\"Access denied - perstack directory is not allowed\")\n }\n try {\n const realAbsolute = await fs.realpath(absolute)\n if (!isWithinWorkspace(realAbsolute)) {\n throw new Error(\"Access denied - symlink target outside allowed directories\")\n }\n return realAbsolute\n } catch (_error) {\n const parentDir = path.dirname(absolute)\n try {\n const realParentPath = await fs.realpath(parentDir)\n if (!isWithinWorkspace(realParentPath)) {\n throw new Error(\"Access denied - parent directory outside allowed directories\")\n }\n return absolute\n } catch {\n if (!isWithinWorkspace(absolute)) {\n throw new Error(\n `Access denied - path outside allowed directories: ${absolute} not in ${workspacePath}`,\n )\n }\n throw new Error(`Parent directory does not exist: ${parentDir}`)\n }\n }\n}\n\nfunction isWithinWorkspace(absolutePath: string): boolean {\n return absolutePath === workspacePath || absolutePath.startsWith(`${workspacePath}/`)\n}\n","import type { FileHandle } from \"node:fs/promises\"\nimport { constants, lstat, open } from \"node:fs/promises\"\n\nconst O_NOFOLLOW = constants.O_NOFOLLOW ?? 0\nconst O_NOFOLLOW_SUPPORTED = typeof constants.O_NOFOLLOW === \"number\"\n\nasync function checkNotSymlink(path: string): Promise<void> {\n const stats = await lstat(path).catch(() => null)\n if (stats?.isSymbolicLink()) {\n throw new Error(\"Operation denied: target is a symbolic link\")\n }\n}\n\nexport function isSymlinkProtectionFullySupported(): boolean {\n return O_NOFOLLOW_SUPPORTED\n}\n\nexport async function safeWriteFile(path: string, data: string): Promise<void> {\n let handle: FileHandle | undefined\n try {\n await checkNotSymlink(path)\n const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | O_NOFOLLOW\n handle = await open(path, flags, 0o644)\n await handle.writeFile(data, \"utf-8\")\n } finally {\n await handle?.close()\n }\n}\n\nexport async function safeReadFile(path: string): Promise<string> {\n let handle: FileHandle | undefined\n try {\n await checkNotSymlink(path)\n const flags = constants.O_RDONLY | O_NOFOLLOW\n handle = await open(path, flags)\n const buffer = await handle.readFile(\"utf-8\")\n return buffer\n } finally {\n await handle?.close()\n }\n}\n","import { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeReadFile, safeWriteFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function editTextFile(input: { path: string; newText: string; oldText: string }) {\n const { path, newText, oldText } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (!stats) {\n throw new Error(`File ${path} does not exist.`)\n }\n if (!(stats.mode & 0o200)) {\n throw new Error(`File ${path} is not writable`)\n }\n await applyFileEdit(validatedPath, newText, oldText)\n return {\n path: validatedPath,\n newText,\n oldText,\n }\n}\n\nfunction normalizeLineEndings(text: string): string {\n return text.replace(/\\r\\n/g, \"\\n\")\n}\n\nasync function applyFileEdit(filePath: string, newText: string, oldText: string) {\n const content = normalizeLineEndings(await safeReadFile(filePath))\n const normalizedOld = normalizeLineEndings(oldText)\n const normalizedNew = normalizeLineEndings(newText)\n if (!content.includes(normalizedOld)) {\n throw new Error(`Could not find exact match for oldText in file ${filePath}`)\n }\n const modifiedContent = content.replace(normalizedOld, normalizedNew)\n await safeWriteFile(filePath, modifiedContent)\n}\n\nexport function registerEditTextFile(server: McpServer) {\n server.registerTool(\n \"editTextFile\",\n {\n title: \"Edit text file\",\n description: \"Replace exact text in an existing file. Normalizes line endings (CRLF → LF).\",\n inputSchema: {\n path: z.string().describe(\"Target file path to edit.\"),\n newText: z.string().describe(\"Text to replace with.\"),\n oldText: z.string().describe(\"Exact text to find and replace.\"),\n },\n },\n async (input: { path: string; newText: string; oldText: string }) => {\n try {\n return successToolResult(await editTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { type ExecException, execFile } from \"node:child_process\"\nimport { promisify } from \"node:util\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { getFilteredEnv } from \"@perstack/core\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { successToolResult } from \"../lib/tool-result.js\"\n\nconst execFileAsync = promisify(execFile)\ntype ExecError = ExecException & { stdout?: string; stderr?: string }\nfunction isExecError(error: unknown): error is ExecError {\n return error instanceof Error && \"code\" in error\n}\ntype ExecInput = {\n command: string\n args: string[]\n env: Record<string, string>\n cwd: string\n stdout: boolean\n stderr: boolean\n timeout?: number\n}\nexport async function exec(input: ExecInput) {\n const validatedCwd = await validatePath(input.cwd)\n const { stdout, stderr } = await execFileAsync(input.command, input.args, {\n cwd: validatedCwd,\n env: getFilteredEnv(input.env),\n timeout: input.timeout,\n maxBuffer: 10 * 1024 * 1024,\n })\n let output = \"\"\n if (input.stdout) {\n output += stdout\n }\n if (input.stderr) {\n output += stderr\n }\n if (!output.trim()) {\n output = \"Command executed successfully, but produced no output.\"\n }\n return { output }\n}\n\nexport function registerExec(server: McpServer) {\n server.registerTool(\n \"exec\",\n {\n title: \"Execute Command\",\n description: \"Execute a system command. Returns stdout/stderr.\",\n inputSchema: {\n command: z.string().describe(\"The command to execute\"),\n args: z.array(z.string()).describe(\"The arguments to pass to the command\"),\n env: z.record(z.string(), z.string()).describe(\"The environment variables to set\"),\n cwd: z.string().describe(\"The working directory to execute the command in\"),\n stdout: z.boolean().describe(\"Whether to capture the standard output\"),\n stderr: z.boolean().describe(\"Whether to capture the standard error\"),\n timeout: z\n .number()\n .optional()\n .default(60000)\n .describe(\"Timeout in milliseconds (default: 60000)\"),\n },\n },\n async (input: ExecInput) => {\n try {\n return successToolResult(await exec(input))\n } catch (error: unknown) {\n let message: string\n let stdout: string | undefined\n let stderr: string | undefined\n if (isExecError(error)) {\n if ((error.killed || error.signal === \"SIGTERM\") && typeof input.timeout === \"number\") {\n message = `Command timed out after ${input.timeout}ms.`\n } else if (error.message.includes(\"timeout\")) {\n message = `Command timed out after ${input.timeout}ms.`\n } else {\n message = error.message\n }\n stdout = error.stdout\n stderr = error.stderr\n } else if (error instanceof Error) {\n message = error.message\n } else {\n message = \"An unknown error occurred.\"\n }\n const result: { error: string; stdout?: string; stderr?: string } = { error: message }\n if (stdout && input.stdout) {\n result.stdout = stdout\n }\n if (stderr && input.stderr) {\n result.stderr = stderr\n }\n return { content: [{ type: \"text\", text: JSON.stringify(result) }] }\n }\n },\n )\n}\n","import { extname } from \"node:path\"\n\nconst MIME_TYPES: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".pdf\": \"application/pdf\",\n}\n\nexport function lookupMimeType(filePath: string): string | undefined {\n return MIME_TYPES[extname(filePath).toLowerCase()]\n}\n","import { existsSync } from \"node:fs\"\nimport { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { lookupMimeType } from \"../lib/mime.js\"\nimport { validatePath } from \"../lib/path.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nconst MAX_IMAGE_SIZE = 15 * 1024 * 1024\nexport async function readImageFile(input: { path: string }) {\n const { path } = input\n const validatedPath = await validatePath(path)\n const isFile = existsSync(validatedPath)\n if (!isFile) {\n throw new Error(`File ${path} does not exist.`)\n }\n const mimeType = lookupMimeType(validatedPath)\n if (!mimeType || ![\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"].includes(mimeType)) {\n throw new Error(`File ${path} is not supported.`)\n }\n const fileStats = await stat(validatedPath)\n const fileSizeMB = fileStats.size / (1024 * 1024)\n if (fileStats.size > MAX_IMAGE_SIZE) {\n throw new Error(\n `Image file too large (${fileSizeMB.toFixed(1)}MB). Maximum supported size is ${MAX_IMAGE_SIZE / (1024 * 1024)}MB. Please use a smaller image file.`,\n )\n }\n return {\n path: validatedPath,\n mimeType,\n size: fileStats.size,\n }\n}\n\nexport function registerReadImageFile(server: McpServer) {\n server.registerTool(\n \"readImageFile\",\n {\n title: \"Read image file\",\n description: \"Read an image file as base64. Supports PNG, JPEG, GIF, WebP. Max 15MB.\",\n inputSchema: {\n path: z.string(),\n },\n },\n async (input: { path: string }) => {\n try {\n return successToolResult(await readImageFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { existsSync } from \"node:fs\"\nimport { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { lookupMimeType } from \"../lib/mime.js\"\nimport { validatePath } from \"../lib/path.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nconst MAX_PDF_SIZE = 30 * 1024 * 1024\nexport async function readPdfFile(input: { path: string }) {\n const { path } = input\n const validatedPath = await validatePath(path)\n const isFile = existsSync(validatedPath)\n if (!isFile) {\n throw new Error(`File ${path} does not exist.`)\n }\n const mimeType = lookupMimeType(validatedPath)\n if (mimeType !== \"application/pdf\") {\n throw new Error(`File ${path} is not a PDF file.`)\n }\n const fileStats = await stat(validatedPath)\n const fileSizeMB = fileStats.size / (1024 * 1024)\n if (fileStats.size > MAX_PDF_SIZE) {\n throw new Error(\n `PDF file too large (${fileSizeMB.toFixed(1)}MB). Maximum supported size is ${MAX_PDF_SIZE / (1024 * 1024)}MB. Please use a smaller PDF file.`,\n )\n }\n return {\n path: validatedPath,\n mimeType,\n size: fileStats.size,\n }\n}\n\nexport function registerReadPdfFile(server: McpServer) {\n server.registerTool(\n \"readPdfFile\",\n {\n title: \"Read PDF file\",\n description: \"Read a PDF file as base64. Max 30MB.\",\n inputSchema: {\n path: z.string(),\n },\n },\n async (input: { path: string }) => {\n try {\n return successToolResult(await readPdfFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeReadFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function readTextFile(input: { path: string; from?: number; to?: number }) {\n const { path, from, to } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (!stats) {\n throw new Error(`File ${path} does not exist.`)\n }\n const fileContent = await safeReadFile(validatedPath)\n const lines = fileContent.split(\"\\n\")\n const fromLine = from ?? 0\n const toLine = to ?? lines.length\n const selectedLines = lines.slice(fromLine, toLine)\n const content = selectedLines.join(\"\\n\")\n return {\n path,\n content,\n from: fromLine,\n to: toLine,\n }\n}\n\nexport function registerReadTextFile(server: McpServer) {\n server.registerTool(\n \"readTextFile\",\n {\n title: \"Read text file\",\n description: \"Read a UTF-8 text file. Supports partial reading via line ranges.\",\n inputSchema: {\n path: z.string(),\n from: z.number().optional().describe(\"The line number to start reading from.\"),\n to: z.number().optional().describe(\"The line number to stop reading at.\"),\n },\n },\n async (input: { path: string; from?: number; to?: number }) => {\n try {\n return successToolResult(await readTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport interface SkillManagementCallbacks {\n addSkill(input: {\n name: string\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n }): Promise<{ tools: string[] }>\n removeSkill(skillName: string): Promise<void>\n addDelegate(expertKey: string): Promise<{ delegateToolName: string }>\n removeDelegate(expertName: string): Promise<void>\n createExpert(input: {\n key: string\n instruction: string\n description?: string\n version?: string\n skills?: Record<\n string,\n {\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n lazyInit?: boolean\n }\n >\n delegates?: string[]\n tags?: string[]\n providerTools?: string[]\n }): Promise<{ expertKey: string }>\n}\n\nexport function registerAddSkill(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"addSkill\",\n {\n title: \"Add skill\",\n description:\n \"Dynamically add an MCP skill. Returns the list of tool names provided by the new skill.\",\n inputSchema: {\n name: z.string().describe(\"Unique skill name\"),\n type: z.enum([\"mcpStdioSkill\", \"mcpSseSkill\"]).describe(\"Skill transport type\"),\n command: z.string().optional().describe(\"Command to execute (for stdio skills)\"),\n packageName: z.string().optional().describe(\"Package name for npx/uvx (for stdio skills)\"),\n args: z.array(z.string()).optional().describe(\"Additional command arguments\"),\n requiredEnv: z.array(z.string()).optional().describe(\"Required environment variable names\"),\n endpoint: z.string().optional().describe(\"SSE endpoint URL (for SSE skills)\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n rule: z.string().optional().describe(\"Usage rules for the LLM\"),\n pick: z.array(z.string()).optional().describe(\"Tool names to include (whitelist)\"),\n omit: z.array(z.string()).optional().describe(\"Tool names to exclude (blacklist)\"),\n },\n },\n async (input: {\n name: string\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n }) => {\n try {\n return successToolResult(await callbacks.addSkill(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerRemoveSkill(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"removeSkill\",\n {\n title: \"Remove skill\",\n description: \"Dynamically remove an MCP skill by name. Disconnects and removes the skill.\",\n inputSchema: {\n skillName: z.string().describe(\"Name of the skill to remove\"),\n },\n },\n async (input: { skillName: string }) => {\n try {\n await callbacks.removeSkill(input.skillName)\n return successToolResult({ removed: input.skillName })\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerAddDelegate(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"addDelegate\",\n {\n title: \"Add delegate\",\n description:\n \"Dynamically add a delegate expert. Returns the delegate tool name so you know what to call.\",\n inputSchema: {\n expertKey: z.string().describe(\"Key of the expert to add as a delegate\"),\n },\n },\n async (input: { expertKey: string }) => {\n try {\n return successToolResult(await callbacks.addDelegate(input.expertKey))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerRemoveDelegate(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"removeDelegate\",\n {\n title: \"Remove delegate\",\n description: \"Dynamically remove a delegate expert by name.\",\n inputSchema: {\n expertName: z.string().describe(\"Name of the delegate expert to remove\"),\n },\n },\n async (input: { expertName: string }) => {\n try {\n await callbacks.removeDelegate(input.expertName)\n return successToolResult({ removed: input.expertName })\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerCreateExpert(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"createExpert\",\n {\n title: \"Create expert\",\n description:\n \"Dynamically create an expert definition in memory. Returns the expert key so you can add it as a delegate.\",\n inputSchema: {\n key: z.string().describe(\"Unique expert key (kebab-case)\"),\n instruction: z.string().describe(\"System instruction for the expert\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n version: z.string().optional().describe(\"Semantic version (defaults to 1.0.0)\"),\n skills: z\n .record(\n z.string(),\n z.object({\n type: z.enum([\"mcpStdioSkill\", \"mcpSseSkill\"]).describe(\"Skill transport type\"),\n command: z.string().optional().describe(\"Command to execute (for stdio skills)\"),\n packageName: z\n .string()\n .optional()\n .describe(\"Package name for npx/uvx (for stdio skills)\"),\n args: z.array(z.string()).optional().describe(\"Additional command arguments\"),\n requiredEnv: z\n .array(z.string())\n .optional()\n .describe(\"Required environment variable names\"),\n endpoint: z.string().optional().describe(\"SSE endpoint URL (for SSE skills)\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n rule: z.string().optional().describe(\"Usage rules for the LLM\"),\n pick: z.array(z.string()).optional().describe(\"Tool names to include (whitelist)\"),\n omit: z.array(z.string()).optional().describe(\"Tool names to exclude (blacklist)\"),\n lazyInit: z.boolean().optional().describe(\"Lazy initialization\"),\n }),\n )\n .optional()\n .describe(\"Skills map (defaults to @perstack/base)\"),\n delegates: z.array(z.string()).optional().describe(\"Expert keys to delegate to\"),\n tags: z.array(z.string()).optional().describe(\"Tags for categorization\"),\n providerTools: z.array(z.string()).optional().describe(\"Provider-specific tool names\"),\n },\n },\n async (input: {\n key: string\n instruction: string\n description?: string\n version?: string\n skills?: Record<\n string,\n {\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n lazyInit?: boolean\n }\n >\n delegates?: string[]\n tags?: string[]\n providerTools?: string[]\n }) => {\n try {\n return successToolResult(await callbacks.createExpert(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerSkillManagementTools(\n server: McpServer,\n callbacks: SkillManagementCallbacks,\n): void {\n registerAddSkill(server, callbacks)\n registerRemoveSkill(server, callbacks)\n registerAddDelegate(server, callbacks)\n registerRemoveDelegate(server, callbacks)\n registerCreateExpert(server, callbacks)\n}\n","import { mkdir, stat } from \"node:fs/promises\"\nimport { dirname } from \"node:path\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeWriteFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function writeTextFile(input: { path: string; text: string }) {\n const { path, text } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (stats && !(stats.mode & 0o200)) {\n throw new Error(`File ${path} is not writable`)\n }\n const dir = dirname(validatedPath)\n await mkdir(dir, { recursive: true })\n await safeWriteFile(validatedPath, text)\n return {\n path: validatedPath,\n text,\n }\n}\n\nexport function registerWriteTextFile(server: McpServer) {\n server.registerTool(\n \"writeTextFile\",\n {\n title: \"writeTextFile\",\n description: \"Create or overwrite a UTF-8 text file. Creates parent directories as needed.\",\n inputSchema: {\n path: z.string().describe(\"Target file path (relative or absolute).\"),\n text: z.string().describe(\"Text to write to the file.\"),\n },\n },\n async (input: { path: string; text: string }) => {\n try {\n return successToolResult(await writeTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport packageJson from \"../package.json\" with { type: \"json\" }\nimport { registerAttemptCompletion } from \"./tools/attempt-completion.js\"\nimport { registerEditTextFile } from \"./tools/edit-text-file.js\"\nimport { registerExec } from \"./tools/exec.js\"\nimport { registerReadImageFile } from \"./tools/read-image-file.js\"\nimport { registerReadPdfFile } from \"./tools/read-pdf-file.js\"\nimport { registerReadTextFile } from \"./tools/read-text-file.js\"\nimport type { SkillManagementCallbacks } from \"./tools/skill-management.js\"\nimport { registerSkillManagementTools } from \"./tools/skill-management.js\"\nimport { registerClearTodo, registerTodo } from \"./tools/todo.js\"\nimport { registerWriteTextFile } from \"./tools/write-text-file.js\"\n\n/** Base skill name */\nexport const BASE_SKILL_NAME = packageJson.name\n\n/** Base skill version */\nexport const BASE_SKILL_VERSION = packageJson.version\n\n/**\n * Register all base skill tools on an MCP server.\n * This is useful for both standalone and in-process server creation.\n */\nexport function registerAllTools(server: McpServer): void {\n registerAttemptCompletion(server)\n registerTodo(server)\n registerClearTodo(server)\n registerExec(server)\n registerReadTextFile(server)\n registerReadImageFile(server)\n registerReadPdfFile(server)\n registerWriteTextFile(server)\n registerEditTextFile(server)\n}\n\nexport interface CreateBaseServerOptions {\n skillManagement?: SkillManagementCallbacks\n}\n\n/**\n * Create a base skill MCP server with all tools registered.\n * Used by the runtime for in-process execution via InMemoryTransport.\n */\nexport function createBaseServer(options?: CreateBaseServerOptions): McpServer {\n const server = new McpServer(\n {\n name: BASE_SKILL_NAME,\n version: BASE_SKILL_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n },\n )\n registerAllTools(server)\n if (options?.skillManagement) {\n registerSkillManagementTools(server, options.skillManagement)\n }\n return server\n}\n"],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as todo, C as validatePath, D as getRemainingTodos, E as clearTodo, M as successToolResult, O as registerClearTodo, S as registerEditTextFile, T as registerAttemptCompletion, _ as readImageFile, a as registerWriteTextFile, b as registerExec, c as registerAddSkill, d as registerRemoveSkill, f as registerSkillManagementTools, g as registerReadPdfFile, h as readPdfFile, i as registerAllTools, j as errorToolResult, k as registerTodo, l as registerCreateExpert, m as registerReadTextFile, n as BASE_SKILL_VERSION, o as writeTextFile, p as readTextFile, r as createBaseServer, s as registerAddDelegate, t as BASE_SKILL_NAME, u as registerRemoveDelegate, v as registerReadImageFile, w as attemptCompletion, x as editTextFile, y as exec } from "../server-
|
|
1
|
+
import { A as todo, C as validatePath, D as getRemainingTodos, E as clearTodo, M as successToolResult, O as registerClearTodo, S as registerEditTextFile, T as registerAttemptCompletion, _ as readImageFile, a as registerWriteTextFile, b as registerExec, c as registerAddSkill, d as registerRemoveSkill, f as registerSkillManagementTools, g as registerReadPdfFile, h as readPdfFile, i as registerAllTools, j as errorToolResult, k as registerTodo, l as registerCreateExpert, m as registerReadTextFile, n as BASE_SKILL_VERSION, o as writeTextFile, p as readTextFile, r as createBaseServer, s as registerAddDelegate, t as BASE_SKILL_NAME, u as registerRemoveDelegate, v as registerReadImageFile, w as attemptCompletion, x as editTextFile, y as exec } from "../server-ByOYnUvF.js";
|
|
2
2
|
|
|
3
3
|
export { BASE_SKILL_NAME, BASE_SKILL_VERSION, attemptCompletion, clearTodo, createBaseServer, editTextFile, errorToolResult, exec, getRemainingTodos, readImageFile, readPdfFile, readTextFile, registerAddDelegate, registerAddSkill, registerAllTools, registerAttemptCompletion, registerClearTodo, registerCreateExpert, registerEditTextFile, registerExec, registerReadImageFile, registerReadPdfFile, registerReadTextFile, registerRemoveDelegate, registerRemoveSkill, registerSkillManagementTools, registerTodo, registerWriteTextFile, successToolResult, todo, validatePath, writeTextFile };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@perstack/base",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.62",
|
|
4
4
|
"description": "Perstack base skills for agents.",
|
|
5
5
|
"author": "Wintermute Technologies, Inc.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
19
19
|
"commander": "^14.0.3",
|
|
20
20
|
"zod": "^4.3.6",
|
|
21
|
-
"@perstack/core": "0.0.
|
|
21
|
+
"@perstack/core": "0.0.51"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@tsconfig/node22": "^22.0.5",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-BM7K7dr8.js","names":["packageJson.name","packageJson.version"],"sources":["../package.json","../src/lib/tool-result.ts","../src/tools/todo.ts","../src/tools/attempt-completion.ts","../src/lib/path.ts","../src/lib/safe-file.ts","../src/tools/edit-text-file.ts","../src/tools/exec.ts","../src/lib/mime.ts","../src/tools/read-image-file.ts","../src/tools/read-pdf-file.ts","../src/tools/read-text-file.ts","../src/tools/skill-management.ts","../src/tools/write-text-file.ts","../src/server.ts"],"sourcesContent":["","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\"\n\nexport function successToolResult(result: unknown): CallToolResult {\n return { content: [{ type: \"text\", text: JSON.stringify(result) }] }\n}\n\nexport function errorToolResult(e: Error): CallToolResult {\n return {\n content: [{ type: \"text\", text: JSON.stringify({ error: e.name, message: e.message }) }],\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nclass Todo {\n currentTodoId = 0\n todos: { id: number; title: string; completed: boolean }[] = []\n public processTodo(input: { newTodos?: string[]; completedTodos?: number[] }) {\n const { newTodos, completedTodos } = input\n if (newTodos) {\n this.todos.push(\n ...newTodos.map((title) => ({ id: this.currentTodoId++, title, completed: false })),\n )\n }\n if (completedTodos) {\n this.todos = this.todos.map((todo) => ({\n ...todo,\n completed: todo.completed || completedTodos.includes(todo.id),\n }))\n }\n return {\n todos: this.todos,\n }\n }\n public clearTodo() {\n this.todos = []\n this.currentTodoId = 0\n return {\n todos: this.todos,\n }\n }\n}\nconst todoSingleton = new Todo()\nexport async function todo(input: { newTodos?: string[]; completedTodos?: number[] }) {\n return todoSingleton.processTodo(input)\n}\nexport async function clearTodo() {\n return todoSingleton.clearTodo()\n}\nexport function getRemainingTodos() {\n return todoSingleton.todos.filter((t) => !t.completed)\n}\n\nexport function registerTodo(server: McpServer) {\n server.registerTool(\n \"todo\",\n {\n title: \"todo\",\n description: \"Manage a todo list: add tasks and mark them completed.\",\n inputSchema: {\n newTodos: z.array(z.string()).describe(\"New todos to add\").optional(),\n completedTodos: z.array(z.number()).describe(\"Todo ids that are completed\").optional(),\n },\n },\n async (input: { newTodos?: string[]; completedTodos?: number[] }) => {\n try {\n return successToolResult(await todo(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerClearTodo(server: McpServer) {\n server.registerTool(\n \"clearTodo\",\n {\n title: \"clearTodo\",\n description: \"Clear all todos.\",\n inputSchema: {},\n },\n async () => {\n try {\n return successToolResult(await clearTodo())\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\nimport { getRemainingTodos } from \"./todo.js\"\n\nexport type AttemptCompletionResult =\n | { remainingTodos: { id: number; title: string; completed: boolean }[] }\n | Record<string, never>\n\nexport async function attemptCompletion(): Promise<AttemptCompletionResult> {\n const remainingTodos = getRemainingTodos()\n if (remainingTodos.length > 0) {\n return { remainingTodos }\n }\n return {}\n}\n\nexport function registerAttemptCompletion(server: McpServer) {\n server.registerTool(\n \"attemptCompletion\",\n {\n title: \"Attempt completion\",\n description: \"Signal task completion. Validates all todos are complete before ending.\",\n inputSchema: {},\n },\n async () => {\n try {\n return successToolResult(await attemptCompletion())\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { realpathSync } from \"node:fs\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nexport const workspacePath = realpathSync(expandHome(process.cwd()))\n\nfunction expandHome(filepath: string): string {\n if (filepath.startsWith(\"~/\") || filepath === \"~\") {\n return path.join(os.homedir(), filepath.slice(1))\n }\n return filepath\n}\n\nexport async function validatePath(requestedPath: string): Promise<string> {\n const expandedPath = expandHome(requestedPath)\n const absolute = path.isAbsolute(expandedPath)\n ? path.resolve(expandedPath)\n : path.resolve(process.cwd(), expandedPath)\n const perstackDir = `${workspacePath}/perstack`.toLowerCase()\n if (\n absolute.toLowerCase() === perstackDir ||\n absolute.toLowerCase().startsWith(`${perstackDir}/`)\n ) {\n throw new Error(\"Access denied - perstack directory is not allowed\")\n }\n try {\n const realAbsolute = await fs.realpath(absolute)\n if (!isWithinWorkspace(realAbsolute)) {\n throw new Error(\"Access denied - symlink target outside allowed directories\")\n }\n return realAbsolute\n } catch (_error) {\n const parentDir = path.dirname(absolute)\n try {\n const realParentPath = await fs.realpath(parentDir)\n if (!isWithinWorkspace(realParentPath)) {\n throw new Error(\"Access denied - parent directory outside allowed directories\")\n }\n return absolute\n } catch {\n if (!isWithinWorkspace(absolute)) {\n throw new Error(\n `Access denied - path outside allowed directories: ${absolute} not in ${workspacePath}`,\n )\n }\n throw new Error(`Parent directory does not exist: ${parentDir}`)\n }\n }\n}\n\nfunction isWithinWorkspace(absolutePath: string): boolean {\n return absolutePath === workspacePath || absolutePath.startsWith(`${workspacePath}/`)\n}\n","import type { FileHandle } from \"node:fs/promises\"\nimport { constants, lstat, open } from \"node:fs/promises\"\n\nconst O_NOFOLLOW = constants.O_NOFOLLOW ?? 0\nconst O_NOFOLLOW_SUPPORTED = typeof constants.O_NOFOLLOW === \"number\"\n\nasync function checkNotSymlink(path: string): Promise<void> {\n const stats = await lstat(path).catch(() => null)\n if (stats?.isSymbolicLink()) {\n throw new Error(\"Operation denied: target is a symbolic link\")\n }\n}\n\nexport function isSymlinkProtectionFullySupported(): boolean {\n return O_NOFOLLOW_SUPPORTED\n}\n\nexport async function safeWriteFile(path: string, data: string): Promise<void> {\n let handle: FileHandle | undefined\n try {\n await checkNotSymlink(path)\n const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | O_NOFOLLOW\n handle = await open(path, flags, 0o644)\n await handle.writeFile(data, \"utf-8\")\n } finally {\n await handle?.close()\n }\n}\n\nexport async function safeReadFile(path: string): Promise<string> {\n let handle: FileHandle | undefined\n try {\n await checkNotSymlink(path)\n const flags = constants.O_RDONLY | O_NOFOLLOW\n handle = await open(path, flags)\n const buffer = await handle.readFile(\"utf-8\")\n return buffer\n } finally {\n await handle?.close()\n }\n}\n","import { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeReadFile, safeWriteFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function editTextFile(input: { path: string; newText: string; oldText: string }) {\n const { path, newText, oldText } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (!stats) {\n throw new Error(`File ${path} does not exist.`)\n }\n if (!(stats.mode & 0o200)) {\n throw new Error(`File ${path} is not writable`)\n }\n await applyFileEdit(validatedPath, newText, oldText)\n return {\n path: validatedPath,\n newText,\n oldText,\n }\n}\n\nfunction normalizeLineEndings(text: string): string {\n return text.replace(/\\r\\n/g, \"\\n\")\n}\n\nasync function applyFileEdit(filePath: string, newText: string, oldText: string) {\n const content = normalizeLineEndings(await safeReadFile(filePath))\n const normalizedOld = normalizeLineEndings(oldText)\n const normalizedNew = normalizeLineEndings(newText)\n if (!content.includes(normalizedOld)) {\n throw new Error(`Could not find exact match for oldText in file ${filePath}`)\n }\n const modifiedContent = content.replace(normalizedOld, normalizedNew)\n await safeWriteFile(filePath, modifiedContent)\n}\n\nexport function registerEditTextFile(server: McpServer) {\n server.registerTool(\n \"editTextFile\",\n {\n title: \"Edit text file\",\n description: \"Replace exact text in an existing file. Normalizes line endings (CRLF → LF).\",\n inputSchema: {\n path: z.string().describe(\"Target file path to edit.\"),\n newText: z.string().describe(\"Text to replace with.\"),\n oldText: z.string().describe(\"Exact text to find and replace.\"),\n },\n },\n async (input: { path: string; newText: string; oldText: string }) => {\n try {\n return successToolResult(await editTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { type ExecException, execFile } from \"node:child_process\"\nimport { promisify } from \"node:util\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { getFilteredEnv } from \"@perstack/core\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { successToolResult } from \"../lib/tool-result.js\"\n\nconst execFileAsync = promisify(execFile)\ntype ExecError = ExecException & { stdout?: string; stderr?: string }\nfunction isExecError(error: unknown): error is ExecError {\n return error instanceof Error && \"code\" in error\n}\ntype ExecInput = {\n command: string\n args: string[]\n env: Record<string, string>\n cwd: string\n stdout: boolean\n stderr: boolean\n timeout?: number\n}\nexport async function exec(input: ExecInput) {\n const validatedCwd = await validatePath(input.cwd)\n const { stdout, stderr } = await execFileAsync(input.command, input.args, {\n cwd: validatedCwd,\n env: getFilteredEnv(input.env),\n timeout: input.timeout,\n maxBuffer: 10 * 1024 * 1024,\n })\n let output = \"\"\n if (input.stdout) {\n output += stdout\n }\n if (input.stderr) {\n output += stderr\n }\n if (!output.trim()) {\n output = \"Command executed successfully, but produced no output.\"\n }\n return { output }\n}\n\nexport function registerExec(server: McpServer) {\n server.registerTool(\n \"exec\",\n {\n title: \"Execute Command\",\n description: \"Execute a system command. Returns stdout/stderr.\",\n inputSchema: {\n command: z.string().describe(\"The command to execute\"),\n args: z.array(z.string()).describe(\"The arguments to pass to the command\"),\n env: z.record(z.string(), z.string()).describe(\"The environment variables to set\"),\n cwd: z.string().describe(\"The working directory to execute the command in\"),\n stdout: z.boolean().describe(\"Whether to capture the standard output\"),\n stderr: z.boolean().describe(\"Whether to capture the standard error\"),\n timeout: z\n .number()\n .optional()\n .default(60000)\n .describe(\"Timeout in milliseconds (default: 60000)\"),\n },\n },\n async (input: ExecInput) => {\n try {\n return successToolResult(await exec(input))\n } catch (error: unknown) {\n let message: string\n let stdout: string | undefined\n let stderr: string | undefined\n if (isExecError(error)) {\n if ((error.killed || error.signal === \"SIGTERM\") && typeof input.timeout === \"number\") {\n message = `Command timed out after ${input.timeout}ms.`\n } else if (error.message.includes(\"timeout\")) {\n message = `Command timed out after ${input.timeout}ms.`\n } else {\n message = error.message\n }\n stdout = error.stdout\n stderr = error.stderr\n } else if (error instanceof Error) {\n message = error.message\n } else {\n message = \"An unknown error occurred.\"\n }\n const result: { error: string; stdout?: string; stderr?: string } = { error: message }\n if (stdout && input.stdout) {\n result.stdout = stdout\n }\n if (stderr && input.stderr) {\n result.stderr = stderr\n }\n return { content: [{ type: \"text\", text: JSON.stringify(result) }] }\n }\n },\n )\n}\n","import { extname } from \"node:path\"\n\nconst MIME_TYPES: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".pdf\": \"application/pdf\",\n}\n\nexport function lookupMimeType(filePath: string): string | undefined {\n return MIME_TYPES[extname(filePath).toLowerCase()]\n}\n","import { existsSync } from \"node:fs\"\nimport { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { lookupMimeType } from \"../lib/mime.js\"\nimport { validatePath } from \"../lib/path.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nconst MAX_IMAGE_SIZE = 15 * 1024 * 1024\nexport async function readImageFile(input: { path: string }) {\n const { path } = input\n const validatedPath = await validatePath(path)\n const isFile = existsSync(validatedPath)\n if (!isFile) {\n throw new Error(`File ${path} does not exist.`)\n }\n const mimeType = lookupMimeType(validatedPath)\n if (!mimeType || ![\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"].includes(mimeType)) {\n throw new Error(`File ${path} is not supported.`)\n }\n const fileStats = await stat(validatedPath)\n const fileSizeMB = fileStats.size / (1024 * 1024)\n if (fileStats.size > MAX_IMAGE_SIZE) {\n throw new Error(\n `Image file too large (${fileSizeMB.toFixed(1)}MB). Maximum supported size is ${MAX_IMAGE_SIZE / (1024 * 1024)}MB. Please use a smaller image file.`,\n )\n }\n return {\n path: validatedPath,\n mimeType,\n size: fileStats.size,\n }\n}\n\nexport function registerReadImageFile(server: McpServer) {\n server.registerTool(\n \"readImageFile\",\n {\n title: \"Read image file\",\n description: \"Read an image file as base64. Supports PNG, JPEG, GIF, WebP. Max 15MB.\",\n inputSchema: {\n path: z.string(),\n },\n },\n async (input: { path: string }) => {\n try {\n return successToolResult(await readImageFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { existsSync } from \"node:fs\"\nimport { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { lookupMimeType } from \"../lib/mime.js\"\nimport { validatePath } from \"../lib/path.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nconst MAX_PDF_SIZE = 30 * 1024 * 1024\nexport async function readPdfFile(input: { path: string }) {\n const { path } = input\n const validatedPath = await validatePath(path)\n const isFile = existsSync(validatedPath)\n if (!isFile) {\n throw new Error(`File ${path} does not exist.`)\n }\n const mimeType = lookupMimeType(validatedPath)\n if (mimeType !== \"application/pdf\") {\n throw new Error(`File ${path} is not a PDF file.`)\n }\n const fileStats = await stat(validatedPath)\n const fileSizeMB = fileStats.size / (1024 * 1024)\n if (fileStats.size > MAX_PDF_SIZE) {\n throw new Error(\n `PDF file too large (${fileSizeMB.toFixed(1)}MB). Maximum supported size is ${MAX_PDF_SIZE / (1024 * 1024)}MB. Please use a smaller PDF file.`,\n )\n }\n return {\n path: validatedPath,\n mimeType,\n size: fileStats.size,\n }\n}\n\nexport function registerReadPdfFile(server: McpServer) {\n server.registerTool(\n \"readPdfFile\",\n {\n title: \"Read PDF file\",\n description: \"Read a PDF file as base64. Max 30MB.\",\n inputSchema: {\n path: z.string(),\n },\n },\n async (input: { path: string }) => {\n try {\n return successToolResult(await readPdfFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { stat } from \"node:fs/promises\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeReadFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function readTextFile(input: { path: string; from?: number; to?: number }) {\n const { path, from, to } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (!stats) {\n throw new Error(`File ${path} does not exist.`)\n }\n const fileContent = await safeReadFile(validatedPath)\n const lines = fileContent.split(\"\\n\")\n const fromLine = from ?? 0\n const toLine = to ?? lines.length\n const selectedLines = lines.slice(fromLine, toLine)\n const content = selectedLines.join(\"\\n\")\n return {\n path,\n content,\n from: fromLine,\n to: toLine,\n }\n}\n\nexport function registerReadTextFile(server: McpServer) {\n server.registerTool(\n \"readTextFile\",\n {\n title: \"Read text file\",\n description: \"Read a UTF-8 text file. Supports partial reading via line ranges.\",\n inputSchema: {\n path: z.string(),\n from: z.number().optional().describe(\"The line number to start reading from.\"),\n to: z.number().optional().describe(\"The line number to stop reading at.\"),\n },\n },\n async (input: { path: string; from?: number; to?: number }) => {\n try {\n return successToolResult(await readTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport interface SkillManagementCallbacks {\n addSkill(input: {\n name: string\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n }): Promise<{ tools: string[] }>\n removeSkill(skillName: string): Promise<void>\n addDelegate(expertKey: string): Promise<{ delegateToolName: string }>\n removeDelegate(expertName: string): Promise<void>\n createExpert(input: {\n key: string\n instruction: string\n description?: string\n version?: string\n skills?: Record<\n string,\n {\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n lazyInit?: boolean\n }\n >\n delegates?: string[]\n tags?: string[]\n providerTools?: string[]\n }): Promise<{ expertKey: string }>\n}\n\nexport function registerAddSkill(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"addSkill\",\n {\n title: \"Add skill\",\n description:\n \"Dynamically add an MCP skill. Returns the list of tool names provided by the new skill.\",\n inputSchema: {\n name: z.string().describe(\"Unique skill name\"),\n type: z.enum([\"mcpStdioSkill\", \"mcpSseSkill\"]).describe(\"Skill transport type\"),\n command: z.string().optional().describe(\"Command to execute (for stdio skills)\"),\n packageName: z.string().optional().describe(\"Package name for npx/uvx (for stdio skills)\"),\n args: z.array(z.string()).optional().describe(\"Additional command arguments\"),\n requiredEnv: z.array(z.string()).optional().describe(\"Required environment variable names\"),\n endpoint: z.string().optional().describe(\"SSE endpoint URL (for SSE skills)\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n rule: z.string().optional().describe(\"Usage rules for the LLM\"),\n pick: z.array(z.string()).optional().describe(\"Tool names to include (whitelist)\"),\n omit: z.array(z.string()).optional().describe(\"Tool names to exclude (blacklist)\"),\n },\n },\n async (input: {\n name: string\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n }) => {\n try {\n return successToolResult(await callbacks.addSkill(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerRemoveSkill(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"removeSkill\",\n {\n title: \"Remove skill\",\n description: \"Dynamically remove an MCP skill by name. Disconnects and removes the skill.\",\n inputSchema: {\n skillName: z.string().describe(\"Name of the skill to remove\"),\n },\n },\n async (input: { skillName: string }) => {\n try {\n await callbacks.removeSkill(input.skillName)\n return successToolResult({ removed: input.skillName })\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerAddDelegate(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"addDelegate\",\n {\n title: \"Add delegate\",\n description:\n \"Dynamically add a delegate expert. Returns the delegate tool name so you know what to call.\",\n inputSchema: {\n expertKey: z.string().describe(\"Key of the expert to add as a delegate\"),\n },\n },\n async (input: { expertKey: string }) => {\n try {\n return successToolResult(await callbacks.addDelegate(input.expertKey))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerRemoveDelegate(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"removeDelegate\",\n {\n title: \"Remove delegate\",\n description: \"Dynamically remove a delegate expert by name.\",\n inputSchema: {\n expertName: z.string().describe(\"Name of the delegate expert to remove\"),\n },\n },\n async (input: { expertName: string }) => {\n try {\n await callbacks.removeDelegate(input.expertName)\n return successToolResult({ removed: input.expertName })\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerCreateExpert(server: McpServer, callbacks: SkillManagementCallbacks) {\n server.registerTool(\n \"createExpert\",\n {\n title: \"Create expert\",\n description:\n \"Dynamically create an expert definition in memory. Returns the expert key so you can add it as a delegate.\",\n inputSchema: {\n key: z.string().describe(\"Unique expert key (kebab-case)\"),\n instruction: z.string().describe(\"System instruction for the expert\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n version: z.string().optional().describe(\"Semantic version (defaults to 1.0.0)\"),\n skills: z\n .record(\n z.string(),\n z.object({\n type: z.enum([\"mcpStdioSkill\", \"mcpSseSkill\"]).describe(\"Skill transport type\"),\n command: z.string().optional().describe(\"Command to execute (for stdio skills)\"),\n packageName: z\n .string()\n .optional()\n .describe(\"Package name for npx/uvx (for stdio skills)\"),\n args: z.array(z.string()).optional().describe(\"Additional command arguments\"),\n requiredEnv: z\n .array(z.string())\n .optional()\n .describe(\"Required environment variable names\"),\n endpoint: z.string().optional().describe(\"SSE endpoint URL (for SSE skills)\"),\n description: z.string().optional().describe(\"Human-readable description\"),\n rule: z.string().optional().describe(\"Usage rules for the LLM\"),\n pick: z.array(z.string()).optional().describe(\"Tool names to include (whitelist)\"),\n omit: z.array(z.string()).optional().describe(\"Tool names to exclude (blacklist)\"),\n lazyInit: z.boolean().optional().describe(\"Lazy initialization\"),\n }),\n )\n .optional()\n .describe(\"Skills map (defaults to @perstack/base)\"),\n delegates: z.array(z.string()).optional().describe(\"Expert keys to delegate to\"),\n tags: z.array(z.string()).optional().describe(\"Tags for categorization\"),\n providerTools: z.array(z.string()).optional().describe(\"Provider-specific tool names\"),\n },\n },\n async (input: {\n key: string\n instruction: string\n description?: string\n version?: string\n skills?: Record<\n string,\n {\n type: \"mcpStdioSkill\" | \"mcpSseSkill\"\n command?: string\n packageName?: string\n args?: string[]\n requiredEnv?: string[]\n endpoint?: string\n description?: string\n rule?: string\n pick?: string[]\n omit?: string[]\n lazyInit?: boolean\n }\n >\n delegates?: string[]\n tags?: string[]\n providerTools?: string[]\n }) => {\n try {\n return successToolResult(await callbacks.createExpert(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n\nexport function registerSkillManagementTools(\n server: McpServer,\n callbacks: SkillManagementCallbacks,\n): void {\n registerAddSkill(server, callbacks)\n registerRemoveSkill(server, callbacks)\n registerAddDelegate(server, callbacks)\n registerRemoveDelegate(server, callbacks)\n registerCreateExpert(server, callbacks)\n}\n","import { mkdir, stat } from \"node:fs/promises\"\nimport { dirname } from \"node:path\"\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { z } from \"zod/v4\"\nimport { validatePath } from \"../lib/path.js\"\nimport { safeWriteFile } from \"../lib/safe-file.js\"\nimport { errorToolResult, successToolResult } from \"../lib/tool-result.js\"\n\nexport async function writeTextFile(input: { path: string; text: string }) {\n const { path, text } = input\n const validatedPath = await validatePath(path)\n const stats = await stat(validatedPath).catch(() => null)\n if (stats && !(stats.mode & 0o200)) {\n throw new Error(`File ${path} is not writable`)\n }\n const dir = dirname(validatedPath)\n await mkdir(dir, { recursive: true })\n await safeWriteFile(validatedPath, text)\n return {\n path: validatedPath,\n text,\n }\n}\n\nexport function registerWriteTextFile(server: McpServer) {\n server.registerTool(\n \"writeTextFile\",\n {\n title: \"writeTextFile\",\n description: \"Create or overwrite a UTF-8 text file. Creates parent directories as needed.\",\n inputSchema: {\n path: z.string().describe(\"Target file path (relative or absolute).\"),\n text: z.string().describe(\"Text to write to the file.\"),\n },\n },\n async (input: { path: string; text: string }) => {\n try {\n return successToolResult(await writeTextFile(input))\n } catch (e) {\n if (e instanceof Error) return errorToolResult(e)\n throw e\n }\n },\n )\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport packageJson from \"../package.json\" with { type: \"json\" }\nimport { registerAttemptCompletion } from \"./tools/attempt-completion.js\"\nimport { registerEditTextFile } from \"./tools/edit-text-file.js\"\nimport { registerExec } from \"./tools/exec.js\"\nimport { registerReadImageFile } from \"./tools/read-image-file.js\"\nimport { registerReadPdfFile } from \"./tools/read-pdf-file.js\"\nimport { registerReadTextFile } from \"./tools/read-text-file.js\"\nimport type { SkillManagementCallbacks } from \"./tools/skill-management.js\"\nimport { registerSkillManagementTools } from \"./tools/skill-management.js\"\nimport { registerClearTodo, registerTodo } from \"./tools/todo.js\"\nimport { registerWriteTextFile } from \"./tools/write-text-file.js\"\n\n/** Base skill name */\nexport const BASE_SKILL_NAME = packageJson.name\n\n/** Base skill version */\nexport const BASE_SKILL_VERSION = packageJson.version\n\n/**\n * Register all base skill tools on an MCP server.\n * This is useful for both standalone and in-process server creation.\n */\nexport function registerAllTools(server: McpServer): void {\n registerAttemptCompletion(server)\n registerTodo(server)\n registerClearTodo(server)\n registerExec(server)\n registerReadTextFile(server)\n registerReadImageFile(server)\n registerReadPdfFile(server)\n registerWriteTextFile(server)\n registerEditTextFile(server)\n}\n\nexport interface CreateBaseServerOptions {\n skillManagement?: SkillManagementCallbacks\n}\n\n/**\n * Create a base skill MCP server with all tools registered.\n * Used by the runtime for in-process execution via InMemoryTransport.\n */\nexport function createBaseServer(options?: CreateBaseServerOptions): McpServer {\n const server = new McpServer(\n {\n name: BASE_SKILL_NAME,\n version: BASE_SKILL_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n },\n )\n registerAllTools(server)\n if (options?.skillManagement) {\n registerSkillManagementTools(server, options.skillManagement)\n }\n return server\n}\n"],"mappings":"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"}
|