@perstack/base 0.0.61 → 0.0.63

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.
@@ -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-BM7K7dr8.js";
2
+ import { F as version, N as description, P as name, r as createBaseServer } from "../server-Ccrq3MP0.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/v4";
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.61";
14
+ var version = "0.0.63";
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-BM7K7dr8.js.map
589
+ //# sourceMappingURL=server-Ccrq3MP0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-Ccrq3MP0.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-BM7K7dr8.js";
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-Ccrq3MP0.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.61",
3
+ "version": "0.0.63",
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.50"
21
+ "@perstack/core": "0.0.52"
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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"}