deepagents 1.10.2 → 1.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/agent-2caqZpg2.d.cts +4023 -0
- package/dist/agent-DURA4_mf.d.ts +4024 -0
- package/dist/browser.cjs +43 -0
- package/dist/browser.d.cts +3 -0
- package/dist/browser.d.ts +3 -0
- package/dist/browser.js +2 -0
- package/dist/index.cjs +52 -8849
- package/dist/index.d.cts +2 -3959
- package/dist/index.d.ts +2 -3961
- package/dist/index.js +3 -8763
- package/dist/langsmith-ZfNZ_Pyb.cjs +7639 -0
- package/dist/langsmith-ZfNZ_Pyb.cjs.map +1 -0
- package/dist/langsmith-wdF8zG42.js +7321 -0
- package/dist/langsmith-wdF8zG42.js.map +1 -0
- package/dist/node.cjs +53 -0
- package/dist/node.d.cts +2 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +3 -0
- package/dist/src-DybKvM4T.js +1402 -0
- package/dist/src-DybKvM4T.js.map +1 -0
- package/dist/src-plSII1Kf.cjs +1451 -0
- package/dist/src-plSII1Kf.cjs.map +1 -0
- package/package.json +31 -10
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-plSII1Kf.cjs","names":["path","fs","os","z","fs","fs","path","fsSync","path","fs","getMimeType","isTextMimeType","checkEmptyContent","performStringReplacement","#timeout","#maxOutputBytes","#sandboxId","#env","#initialized","SandboxError","fs","path","cp"],"sources":["../src/config.ts","../src/middleware/agent-memory.ts","../src/skills/loader.ts","../src/backends/filesystem.ts","../src/backends/local-shell.ts"],"sourcesContent":["/**\n * Configuration and settings for deepagents.\n *\n * Provides project detection, path management, and environment configuration\n * for skills and agent memory middleware.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\n/**\n * Options for creating a Settings instance.\n */\nexport interface SettingsOptions {\n /** Starting directory for project detection (defaults to cwd) */\n startPath?: string;\n}\n\n/**\n * Settings interface for project detection and path management.\n *\n * Provides access to:\n * - Project root detection (via .git directory)\n * - User-level deepagents directory (~/.deepagents)\n * - Agent-specific directories and files\n * - Skills directories (user and project level)\n */\nexport interface Settings {\n /** Detected project root directory, or null if not in a git project */\n readonly projectRoot: string | null;\n\n /** Base user-level .deepagents directory (~/.deepagents) */\n readonly userDeepagentsDir: string;\n\n /** Check if currently in a git project */\n readonly hasProject: boolean;\n\n /**\n * Get the agent directory path.\n * @param agentName - Name of the agent\n * @returns Path to ~/.deepagents/{agentName}\n * @throws Error if agent name is invalid\n */\n getAgentDir(agentName: string): string;\n\n /**\n * Ensure agent directory exists and return path.\n * @param agentName - Name of the agent\n * @returns Path to ~/.deepagents/{agentName}\n * @throws Error if agent name is invalid\n */\n ensureAgentDir(agentName: string): string;\n\n /**\n * Get user-level agent.md path for a specific agent.\n * @param agentName - Name of the agent\n * @returns Path to ~/.deepagents/{agentName}/agent.md\n */\n getUserAgentMdPath(agentName: string): string;\n\n /**\n * Get project-level agent.md path.\n * @returns Path to {projectRoot}/.deepagents/agent.md, or null if not in a project\n */\n getProjectAgentMdPath(): string | null;\n\n /**\n * Get user-level skills directory path for a specific agent.\n * @param agentName - Name of the agent\n * @returns Path to ~/.deepagents/{agentName}/skills/\n */\n getUserSkillsDir(agentName: string): string;\n\n /**\n * Ensure user-level skills directory exists and return path.\n * @param agentName - Name of the agent\n * @returns Path to ~/.deepagents/{agentName}/skills/\n */\n ensureUserSkillsDir(agentName: string): string;\n\n /**\n * Get project-level skills directory path.\n * @returns Path to {projectRoot}/.deepagents/skills/, or null if not in a project\n */\n getProjectSkillsDir(): string | null;\n\n /**\n * Ensure project-level skills directory exists and return path.\n * @returns Path to {projectRoot}/.deepagents/skills/, or null if not in a project\n */\n ensureProjectSkillsDir(): string | null;\n\n /**\n * Ensure project .deepagents directory exists.\n * @returns Path to {projectRoot}/.deepagents/, or null if not in a project\n */\n ensureProjectDeepagentsDir(): string | null;\n}\n\n/**\n * Find the project root by looking for .git directory.\n *\n * Walks up the directory tree from startPath (or cwd) looking for a .git\n * directory, which indicates the project root.\n *\n * @param startPath - Directory to start searching from. Defaults to current working directory.\n * @returns Path to the project root if found, null otherwise.\n */\nexport function findProjectRoot(startPath?: string): string | null {\n let current = path.resolve(startPath || process.cwd());\n\n // Walk up the directory tree\n while (current !== path.dirname(current)) {\n const gitDir = path.join(current, \".git\");\n if (fs.existsSync(gitDir)) {\n return current;\n }\n current = path.dirname(current);\n }\n\n // Check root directory as well\n const rootGitDir = path.join(current, \".git\");\n if (fs.existsSync(rootGitDir)) {\n return current;\n }\n\n return null;\n}\n\n/**\n * Validate agent name to prevent invalid filesystem paths and security issues.\n *\n * @param agentName - The agent name to validate\n * @returns True if valid, false otherwise\n */\nfunction isValidAgentName(agentName: string): boolean {\n if (!agentName || !agentName.trim()) {\n return false;\n }\n // Allow only alphanumeric, hyphens, underscores, and whitespace\n return /^[a-zA-Z0-9_\\-\\s]+$/.test(agentName);\n}\n\n/**\n * Create a Settings instance with detected environment.\n *\n * @param options - Configuration options\n * @returns Settings instance with project detection and path management\n */\nexport function createSettings(options: SettingsOptions = {}): Settings {\n const projectRoot = findProjectRoot(options.startPath);\n const userDeepagentsDir = path.join(os.homedir(), \".deepagents\");\n\n return {\n projectRoot,\n userDeepagentsDir,\n hasProject: projectRoot !== null,\n\n getAgentDir(agentName: string): string {\n if (!isValidAgentName(agentName)) {\n throw new Error(\n `Invalid agent name: ${JSON.stringify(agentName)}. ` +\n \"Agent names can only contain letters, numbers, hyphens, underscores, and spaces.\",\n );\n }\n return path.join(userDeepagentsDir, agentName);\n },\n\n ensureAgentDir(agentName: string): string {\n const agentDir = this.getAgentDir(agentName);\n fs.mkdirSync(agentDir, { recursive: true });\n return agentDir;\n },\n\n getUserAgentMdPath(agentName: string): string {\n return path.join(this.getAgentDir(agentName), \"agent.md\");\n },\n\n getProjectAgentMdPath(): string | null {\n if (!projectRoot) {\n return null;\n }\n return path.join(projectRoot, \".deepagents\", \"agent.md\");\n },\n\n getUserSkillsDir(agentName: string): string {\n return path.join(this.getAgentDir(agentName), \"skills\");\n },\n\n ensureUserSkillsDir(agentName: string): string {\n const skillsDir = this.getUserSkillsDir(agentName);\n fs.mkdirSync(skillsDir, { recursive: true });\n return skillsDir;\n },\n\n getProjectSkillsDir(): string | null {\n if (!projectRoot) {\n return null;\n }\n return path.join(projectRoot, \".deepagents\", \"skills\");\n },\n\n ensureProjectSkillsDir(): string | null {\n const skillsDir = this.getProjectSkillsDir();\n if (!skillsDir) {\n return null;\n }\n fs.mkdirSync(skillsDir, { recursive: true });\n return skillsDir;\n },\n\n ensureProjectDeepagentsDir(): string | null {\n if (!projectRoot) {\n return null;\n }\n const deepagentsDir = path.join(projectRoot, \".deepagents\");\n fs.mkdirSync(deepagentsDir, { recursive: true });\n return deepagentsDir;\n },\n };\n}\n","/**\n * Middleware for loading agent-specific long-term memory into the system prompt.\n *\n * This middleware loads the agent's long-term memory from agent.md files\n * and injects it into the system prompt. Memory is loaded from:\n * - User memory: ~/.deepagents/{agent_name}/agent.md\n * - Project memory: {project_root}/.deepagents/agent.md\n *\n * @deprecated Use `createMemoryMiddleware` from `./memory.js` instead.\n * This middleware uses direct filesystem access (Node.js fs module) which is not\n * portable across backends. The `createMemoryMiddleware` function uses the\n * `BackendProtocol` abstraction and follows the AGENTS.md specification.\n *\n * Migration example:\n * ```typescript\n * // Before (deprecated):\n * import { createAgentMemoryMiddleware } from \"./agent-memory.js\";\n * const middleware = createAgentMemoryMiddleware({ settings, assistantId });\n *\n * // After (recommended):\n * import { createMemoryMiddleware } from \"./memory.js\";\n * import { FilesystemBackend } from \"../backends/filesystem.js\";\n *\n * const middleware = createMemoryMiddleware({\n * backend: new FilesystemBackend({ rootDir: \"/\" }),\n * sources: [\n * `~/.deepagents/${assistantId}/AGENTS.md`,\n * `${projectRoot}/.deepagents/AGENTS.md`,\n * ],\n * });\n * ```\n */\n\nimport fs from \"node:fs\";\nimport { z } from \"zod\";\nimport {\n createMiddleware,\n /**\n * required for type inference\n */\n type AgentMiddleware as _AgentMiddleware,\n} from \"langchain\";\n\nimport type { Settings } from \"../config.js\";\n\n/**\n * Options for the agent memory middleware.\n */\nexport interface AgentMemoryMiddlewareOptions {\n /** Settings instance with project detection and paths */\n settings: Settings;\n\n /** The agent identifier */\n assistantId: string;\n\n /** Optional custom template for injecting agent memory into system prompt */\n systemPromptTemplate?: string;\n}\n\n/**\n * State schema for agent memory middleware.\n */\nconst AgentMemoryStateSchema = z.object({\n /** Personal preferences from ~/.deepagents/{agent}/ (applies everywhere) */\n userMemory: z.string().optional(),\n\n /** Project-specific context (loaded from project root) */\n projectMemory: z.string().optional(),\n});\n\n/**\n * Default template for memory injection.\n */\nconst DEFAULT_MEMORY_TEMPLATE = `<user_memory>\n{user_memory}\n</user_memory>\n\n<project_memory>\n{project_memory}\n</project_memory>`;\n\n/**\n * Long-term Memory Documentation system prompt.\n */\nconst LONGTERM_MEMORY_SYSTEM_PROMPT = `\n\n## Long-term Memory\n\nYour long-term memory is stored in files on the filesystem and persists across sessions.\n\n**User Memory Location**: \\`{agent_dir_absolute}\\` (displays as \\`{agent_dir_display}\\`)\n**Project Memory Location**: {project_memory_info}\n\nYour system prompt is loaded from TWO sources at startup:\n1. **User agent.md**: \\`{agent_dir_absolute}/agent.md\\` - Your personal preferences across all projects\n2. **Project agent.md**: Loaded from project root if available - Project-specific instructions\n\nProject-specific agent.md is loaded from these locations (both combined if both exist):\n- \\`[project-root]/.deepagents/agent.md\\` (preferred)\n- \\`[project-root]/agent.md\\` (fallback, but also included if both exist)\n\n**When to CHECK/READ memories (CRITICAL - do this FIRST):**\n- **At the start of ANY new session**: Check both user and project memories\n - User: \\`ls {agent_dir_absolute}\\`\n - Project: \\`ls {project_deepagents_dir}\\` (if in a project)\n- **BEFORE answering questions**: If asked \"what do you know about X?\" or \"how do I do Y?\", check project memories FIRST, then user\n- **When user asks you to do something**: Check if you have project-specific guides or examples\n- **When user references past work**: Search project memory files for related context\n\n**Memory-first response pattern:**\n1. User asks a question → Check project directory first: \\`ls {project_deepagents_dir}\\`\n2. If relevant files exist → Read them with \\`read_file '{project_deepagents_dir}/[filename]'\\`\n3. Check user memory if needed → \\`ls {agent_dir_absolute}\\`\n4. Base your answer on saved knowledge supplemented by general knowledge\n\n**When to update memories:**\n- **IMMEDIATELY when the user describes your role or how you should behave**\n- **IMMEDIATELY when the user gives feedback on your work** - Update memories to capture what was wrong and how to do it better\n- When the user explicitly asks you to remember something\n- When patterns or preferences emerge (coding styles, conventions, workflows)\n- After significant work where context would help in future sessions\n\n**Learning from feedback:**\n- When user says something is better/worse, capture WHY and encode it as a pattern\n- Each correction is a chance to improve permanently - don't just fix the immediate issue, update your instructions\n- When user says \"you should remember X\" or \"be careful about Y\", treat this as HIGH PRIORITY - update memories IMMEDIATELY\n- Look for the underlying principle behind corrections, not just the specific mistake\n\n## Deciding Where to Store Memory\n\nWhen writing or updating agent memory, decide whether each fact, configuration, or behavior belongs in:\n\n### User Agent File: \\`{agent_dir_absolute}/agent.md\\`\n→ Describes the agent's **personality, style, and universal behavior** across all projects.\n\n**Store here:**\n- Your general tone and communication style\n- Universal coding preferences (formatting, comment style, etc.)\n- General workflows and methodologies you follow\n- Tool usage patterns that apply everywhere\n- Personal preferences that don't change per-project\n\n**Examples:**\n- \"Be concise and direct in responses\"\n- \"Always use type hints in Python\"\n- \"Prefer functional programming patterns\"\n\n### Project Agent File: \\`{project_deepagents_dir}/agent.md\\`\n→ Describes **how this specific project works** and **how the agent should behave here only.**\n\n**Store here:**\n- Project-specific architecture and design patterns\n- Coding conventions specific to this codebase\n- Project structure and organization\n- Testing strategies for this project\n- Deployment processes and workflows\n- Team conventions and guidelines\n\n**Examples:**\n- \"This project uses FastAPI with SQLAlchemy\"\n- \"Tests go in tests/ directory mirroring src/ structure\"\n- \"All API changes require updating OpenAPI spec\"\n\n### Project Memory Files: \\`{project_deepagents_dir}/*.md\\`\n→ Use for **project-specific reference information** and structured notes.\n\n**Store here:**\n- API design documentation\n- Architecture decisions and rationale\n- Deployment procedures\n- Common debugging patterns\n- Onboarding information\n\n**Examples:**\n- \\`{project_deepagents_dir}/api-design.md\\` - REST API patterns used\n- \\`{project_deepagents_dir}/architecture.md\\` - System architecture overview\n- \\`{project_deepagents_dir}/deployment.md\\` - How to deploy this project\n\n### File Operations:\n\n**User memory:**\n\\`\\`\\`\nls {agent_dir_absolute} # List user memory files\nread_file '{agent_dir_absolute}/agent.md' # Read user preferences\nedit_file '{agent_dir_absolute}/agent.md' ... # Update user preferences\n\\`\\`\\`\n\n**Project memory (preferred for project-specific information):**\n\\`\\`\\`\nls {project_deepagents_dir} # List project memory files\nread_file '{project_deepagents_dir}/agent.md' # Read project instructions\nedit_file '{project_deepagents_dir}/agent.md' ... # Update project instructions\nwrite_file '{project_deepagents_dir}/agent.md' ... # Create project memory file\n\\`\\`\\`\n\n**Important**:\n- Project memory files are stored in \\`.deepagents/\\` inside the project root\n- Always use absolute paths for file operations\n- Check project memories BEFORE user when answering project-specific questions`;\n\n/**\n * Create middleware for loading agent-specific long-term memory.\n *\n * This middleware loads the agent's long-term memory from a file (agent.md)\n * and injects it into the system prompt. The memory is loaded once at the\n * start of the conversation and stored in state.\n *\n * @param options - Configuration options\n * @returns AgentMiddleware for memory loading and injection\n *\n * @deprecated Use `createMemoryMiddleware` from `./memory.js` instead.\n * This function uses direct filesystem access which limits portability.\n */\nexport function createAgentMemoryMiddleware(\n options: AgentMemoryMiddlewareOptions,\n) {\n const { settings, assistantId, systemPromptTemplate } = options;\n\n // Compute paths\n const agentDir = settings.getAgentDir(assistantId);\n const agentDirDisplay = `~/.deepagents/${assistantId}`;\n const agentDirAbsolute = agentDir;\n const projectRoot = settings.projectRoot;\n\n // Build project memory info for documentation\n const projectMemoryInfo = projectRoot\n ? `\\`${projectRoot}\\` (detected)`\n : \"None (not in a git project)\";\n\n // Build project deepagents directory path\n const projectDeepagentsDir = projectRoot\n ? `${projectRoot}/.deepagents`\n : \"[project-root]/.deepagents (not in a project)\";\n\n const template = systemPromptTemplate || DEFAULT_MEMORY_TEMPLATE;\n\n return createMiddleware({\n name: \"AgentMemoryMiddleware\",\n stateSchema: AgentMemoryStateSchema as any,\n\n beforeAgent(state: any) {\n const result: Record<string, string> = {};\n\n // Load user memory if not already in state\n if (!(\"userMemory\" in state)) {\n const userPath = settings.getUserAgentMdPath(assistantId);\n if (fs.existsSync(userPath)) {\n try {\n result.userMemory = fs.readFileSync(userPath, \"utf-8\");\n } catch {\n // Ignore read errors\n }\n }\n }\n\n // Load project memory if not already in state\n if (!(\"projectMemory\" in state)) {\n const projectPath = settings.getProjectAgentMdPath();\n if (projectPath && fs.existsSync(projectPath)) {\n try {\n result.projectMemory = fs.readFileSync(projectPath, \"utf-8\");\n } catch {\n // Ignore read errors\n }\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n },\n\n wrapModelCall(request: any, handler: any) {\n // Extract memory from state\n const userMemory = request.state?.userMemory;\n const projectMemory = request.state?.projectMemory;\n const baseSystemPrompt = request.systemPrompt || \"\";\n\n // Format memory section with both memories\n const memorySection = template\n .replace(\"{user_memory}\", userMemory || \"(No user agent.md)\")\n .replace(\"{project_memory}\", projectMemory || \"(No project agent.md)\");\n\n // Format long-term memory documentation\n const memoryDocs = LONGTERM_MEMORY_SYSTEM_PROMPT.replaceAll(\n \"{agent_dir_absolute}\",\n agentDirAbsolute,\n )\n .replaceAll(\"{agent_dir_display}\", agentDirDisplay)\n .replaceAll(\"{project_memory_info}\", projectMemoryInfo)\n .replaceAll(\"{project_deepagents_dir}\", projectDeepagentsDir);\n\n // Memory content at start, base prompt in middle, documentation at end\n let systemPrompt = memorySection;\n if (baseSystemPrompt) {\n systemPrompt += \"\\n\\n\" + baseSystemPrompt;\n }\n systemPrompt += \"\\n\\n\" + memoryDocs;\n\n return handler({ ...request, systemPrompt });\n },\n });\n}\n","/**\n * Skill loader for parsing and loading agent skills from SKILL.md files.\n *\n * This module implements Anthropic's agent skills pattern with YAML frontmatter parsing.\n * Each skill is a directory containing a SKILL.md file with:\n * - YAML frontmatter (name, description required)\n * - Markdown instructions for the agent\n * - Optional supporting files (scripts, configs, etc.)\n *\n * @example\n * ```markdown\n * ---\n * name: web-research\n * description: Structured approach to conducting thorough web research\n * ---\n *\n * # Web Research Skill\n *\n * ## When to Use\n * - User asks you to research a topic\n * ...\n * ```\n *\n * @see https://agentskills.io/specification\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\n\n/** Maximum size for SKILL.md files (10MB) */\nexport const MAX_SKILL_FILE_SIZE = 10 * 1024 * 1024;\n\n/** Agent Skills spec constraints */\nexport const MAX_SKILL_NAME_LENGTH = 64;\nexport const MAX_SKILL_DESCRIPTION_LENGTH = 1024;\n\n/** Pattern for validating skill names per Agent Skills spec */\nconst SKILL_NAME_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n\n/** Pattern for extracting YAML frontmatter */\nconst FRONTMATTER_PATTERN = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/;\n\n/**\n * Metadata for a skill per Agent Skills spec.\n * @see https://agentskills.io/specification\n */\nexport interface SkillMetadata {\n /** Name of the skill (max 64 chars, lowercase alphanumeric and hyphens) */\n name: string;\n\n /** Description of what the skill does (max 1024 chars) */\n description: string;\n\n /** Absolute path to the SKILL.md file */\n path: string;\n\n /** Source of the skill ('user' or 'project') */\n source: \"user\" | \"project\";\n\n /** Optional: License name or reference to bundled license file */\n license?: string;\n\n /** Optional: Environment requirements (max 500 chars) */\n compatibility?: string;\n\n /** Optional: Arbitrary key-value mapping for additional metadata */\n metadata?: Record<string, string>;\n\n /** Optional: Space-delimited list of pre-approved tools */\n allowedTools?: string;\n}\n\n/**\n * Options for listing skills.\n */\nexport interface ListSkillsOptions {\n /** Path to user-level skills directory */\n userSkillsDir?: string | null;\n\n /** Path to project-level skills directory */\n projectSkillsDir?: string | null;\n}\n\n/**\n * Result of skill name validation.\n */\ninterface ValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Check if a path is safely contained within base_dir.\n *\n * This prevents directory traversal attacks via symlinks or path manipulation.\n * The function resolves both paths to their canonical form (following symlinks)\n * and verifies that the target path is within the base directory.\n *\n * @param targetPath - The path to validate\n * @param baseDir - The base directory that should contain the path\n * @returns True if the path is safely within baseDir, false otherwise\n */\nfunction isSafePath(targetPath: string, baseDir: string): boolean {\n try {\n // Resolve both paths to their canonical form (follows symlinks)\n const resolvedPath = fs.realpathSync(targetPath);\n const resolvedBase = fs.realpathSync(baseDir);\n\n // Check if the resolved path is within the base directory\n return (\n resolvedPath.startsWith(resolvedBase + path.sep) ||\n resolvedPath === resolvedBase\n );\n } catch {\n // Error resolving paths (e.g., circular symlinks, too many levels)\n return false;\n }\n}\n\n/**\n * Validate skill name per Agent Skills spec.\n *\n * Requirements:\n * - Max 64 characters\n * - Lowercase alphanumeric and hyphens only (a-z, 0-9, -)\n * - Cannot start or end with hyphen\n * - No consecutive hyphens\n * - Must match parent directory name\n *\n * @param name - The skill name from YAML frontmatter\n * @param directoryName - The parent directory name\n * @returns Validation result with error message if invalid\n */\nfunction validateSkillName(\n name: string,\n directoryName: string,\n): ValidationResult {\n if (!name) {\n return { valid: false, error: \"name is required\" };\n }\n if (name.length > MAX_SKILL_NAME_LENGTH) {\n return { valid: false, error: \"name exceeds 64 characters\" };\n }\n // Pattern: lowercase alphanumeric, single hyphens between segments, no start/end hyphen\n if (!SKILL_NAME_PATTERN.test(name)) {\n return {\n valid: false,\n error: \"name must be lowercase alphanumeric with single hyphens only\",\n };\n }\n if (name !== directoryName) {\n return {\n valid: false,\n error: `name '${name}' must match directory name '${directoryName}'`,\n };\n }\n return { valid: true };\n}\n\n/**\n * Parse YAML frontmatter from content.\n *\n * @param content - The file content\n * @returns Parsed frontmatter object, or null if parsing fails\n */\nfunction parseFrontmatter(content: string): Record<string, unknown> | null {\n const match = content.match(FRONTMATTER_PATTERN);\n if (!match) {\n return null;\n }\n\n try {\n const parsed = yaml.parse(match[1]);\n return typeof parsed === \"object\" && parsed !== null ? parsed : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse YAML frontmatter from a SKILL.md file per Agent Skills spec.\n *\n * @param skillMdPath - Path to the SKILL.md file\n * @param source - Source of the skill ('user' or 'project')\n * @returns SkillMetadata with all fields, or null if parsing fails\n */\nexport function parseSkillMetadata(\n skillMdPath: string,\n source: \"user\" | \"project\",\n): SkillMetadata | null {\n try {\n // Security: Check file size to prevent DoS attacks\n const stats = fs.statSync(skillMdPath);\n if (stats.size > MAX_SKILL_FILE_SIZE) {\n // oxlint-disable-next-line no-console\n console.warn(\n `Skipping ${skillMdPath}: file too large (${stats.size} bytes)`,\n );\n return null;\n }\n\n const content = fs.readFileSync(skillMdPath, \"utf-8\");\n const frontmatter = parseFrontmatter(content);\n\n if (!frontmatter) {\n // oxlint-disable-next-line no-console\n console.warn(`Skipping ${skillMdPath}: no valid YAML frontmatter found`);\n return null;\n }\n\n // Validate required fields\n const name = frontmatter.name;\n const description = frontmatter.description;\n\n if (!name || !description) {\n // oxlint-disable-next-line no-console\n console.warn(\n `Skipping ${skillMdPath}: missing required 'name' or 'description'`,\n );\n return null;\n }\n\n // Validate name format per spec (warn but still load for backwards compatibility)\n const directoryName = path.basename(path.dirname(skillMdPath));\n const validation = validateSkillName(String(name), directoryName);\n if (!validation.valid) {\n // oxlint-disable-next-line no-console\n console.warn(\n `Skill '${name}' in ${skillMdPath} does not follow Agent Skills spec: ${validation.error}. ` +\n \"Consider renaming to be spec-compliant.\",\n );\n }\n\n // Truncate description if too long (spec: max 1024 chars)\n let descriptionStr = String(description);\n if (descriptionStr.length > MAX_SKILL_DESCRIPTION_LENGTH) {\n // oxlint-disable-next-line no-console\n console.warn(\n `Description exceeds ${MAX_SKILL_DESCRIPTION_LENGTH} chars in ${skillMdPath}, truncating`,\n );\n descriptionStr = descriptionStr.slice(0, MAX_SKILL_DESCRIPTION_LENGTH);\n }\n\n return {\n name: String(name),\n description: descriptionStr,\n path: skillMdPath,\n source,\n license: frontmatter.license ? String(frontmatter.license) : undefined,\n compatibility: frontmatter.compatibility\n ? String(frontmatter.compatibility)\n : undefined,\n metadata:\n frontmatter.metadata && typeof frontmatter.metadata === \"object\"\n ? (frontmatter.metadata as Record<string, string>)\n : undefined,\n allowedTools: frontmatter[\"allowed-tools\"]\n ? String(frontmatter[\"allowed-tools\"])\n : undefined,\n };\n } catch (error) {\n // oxlint-disable-next-line no-console\n console.warn(`Error reading ${skillMdPath}: ${error}`);\n return null;\n }\n}\n\n/**\n * List all skills from a single skills directory (internal helper).\n *\n * Scans the skills directory for subdirectories containing SKILL.md files,\n * parses YAML frontmatter, and returns skill metadata.\n *\n * Skills are organized as:\n * ```\n * skills/\n * ├── skill-name/\n * │ ├── SKILL.md # Required: instructions with YAML frontmatter\n * │ ├── script.py # Optional: supporting files\n * │ └── config.json # Optional: supporting files\n * ```\n *\n * @param skillsDir - Path to the skills directory\n * @param source - Source of the skills ('user' or 'project')\n * @returns List of skill metadata\n */\nfunction listSkillsFromDir(\n skillsDir: string,\n source: \"user\" | \"project\",\n): SkillMetadata[] {\n // Check if skills directory exists\n const expandedDir = skillsDir.startsWith(\"~\")\n ? path.join(\n process.env.HOME || process.env.USERPROFILE || \"\",\n skillsDir.slice(1),\n )\n : skillsDir;\n\n if (!fs.existsSync(expandedDir)) {\n return [];\n }\n\n // Resolve base directory to canonical path for security checks\n let resolvedBase: string;\n try {\n resolvedBase = fs.realpathSync(expandedDir);\n } catch {\n // Can't resolve base directory, fail safe\n return [];\n }\n\n const skills: SkillMetadata[] = [];\n\n // Iterate through subdirectories\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(resolvedBase, { withFileTypes: true });\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n const skillDir = path.join(resolvedBase, entry.name);\n\n // Security: Catch symlinks pointing outside the skills directory\n if (!isSafePath(skillDir, resolvedBase)) {\n continue;\n }\n\n if (!entry.isDirectory()) {\n continue;\n }\n\n // Look for SKILL.md file\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n if (!fs.existsSync(skillMdPath)) {\n continue;\n }\n\n // Security: Validate SKILL.md path is safe before reading\n if (!isSafePath(skillMdPath, resolvedBase)) {\n continue;\n }\n\n // Parse metadata\n const metadata = parseSkillMetadata(skillMdPath, source);\n if (metadata) {\n skills.push(metadata);\n }\n }\n\n return skills;\n}\n\n/**\n * List skills from user and/or project directories.\n *\n * When both directories are provided, project skills with the same name as\n * user skills will override them.\n *\n * @param options - Options specifying which directories to search\n * @returns Merged list of skill metadata from both sources, with project skills\n * taking precedence over user skills when names conflict\n */\nexport function listSkills(options: ListSkillsOptions): SkillMetadata[] {\n const allSkills: Map<string, SkillMetadata> = new Map();\n\n // Load user skills first (foundation)\n if (options.userSkillsDir) {\n const userSkills = listSkillsFromDir(options.userSkillsDir, \"user\");\n for (const skill of userSkills) {\n allSkills.set(skill.name, skill);\n }\n }\n\n // Load project skills second (override/augment)\n if (options.projectSkillsDir) {\n const projectSkills = listSkillsFromDir(\n options.projectSkillsDir,\n \"project\",\n );\n for (const skill of projectSkills) {\n // Project skills override user skills with the same name\n allSkills.set(skill.name, skill);\n }\n }\n\n return Array.from(allSkills.values());\n}\n","/**\n * FilesystemBackend: Read and write files directly from the filesystem.\n *\n * Security and search upgrades:\n * - Secure path resolution with root containment when in virtual_mode (sandboxed to cwd)\n * - Prevent symlink-following on file I/O using O_NOFOLLOW when available\n * - Ripgrep-powered grep with literal (fixed-string) search, plus substring fallback\n * and optional glob include filtering, while preserving virtual path behavior\n */\n\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\n\nimport fg from \"fast-glob\";\nimport micromatch from \"micromatch\";\nimport type {\n BackendProtocolV2,\n EditResult,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GlobResult,\n GrepMatch,\n GrepResult,\n LsResult,\n ReadRawResult,\n ReadResult,\n WriteResult,\n} from \"./protocol.js\";\nimport {\n checkEmptyContent,\n getMimeType,\n isTextMimeType,\n performStringReplacement,\n} from \"./utils.js\";\n\nconst SUPPORTS_NOFOLLOW = fsSync.constants.O_NOFOLLOW !== undefined;\n\n/**\n * Backend that reads and writes files directly from the filesystem.\n *\n * Files are accessed using their actual filesystem paths. Relative paths are\n * resolved relative to the current working directory. Content is read/written\n * as plain text, and metadata (timestamps) are derived from filesystem stats.\n */\nexport class FilesystemBackend implements BackendProtocolV2 {\n protected cwd: string;\n protected virtualMode: boolean;\n private maxFileSizeBytes: number;\n\n constructor(\n options: {\n rootDir?: string;\n virtualMode?: boolean;\n maxFileSizeMb?: number;\n } = {},\n ) {\n const { rootDir, virtualMode = false, maxFileSizeMb = 10 } = options;\n this.cwd = rootDir ? path.resolve(rootDir) : process.cwd();\n this.virtualMode = virtualMode;\n this.maxFileSizeBytes = maxFileSizeMb * 1024 * 1024;\n }\n\n /**\n * Resolve a file path with security checks.\n *\n * When virtualMode=true, treat incoming paths as virtual absolute paths under\n * this.cwd, disallow traversal (.., ~) and ensure resolved path stays within root.\n * When virtualMode=false, preserve legacy behavior: absolute paths are allowed\n * as-is; relative paths resolve under cwd.\n *\n * @param key - File path (absolute, relative, or virtual when virtualMode=true)\n * @returns Resolved absolute path string\n * @throws Error if path traversal detected or path outside root\n */\n private resolvePath(key: string): string {\n if (this.virtualMode) {\n const vpath = key.startsWith(\"/\") ? key : \"/\" + key;\n if (vpath.includes(\"..\") || vpath.startsWith(\"~\")) {\n throw new Error(\"Path traversal not allowed\");\n }\n const full = path.resolve(this.cwd, vpath.substring(1));\n const relative = path.relative(this.cwd, full);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path: ${full} outside root directory: ${this.cwd}`);\n }\n return full;\n }\n\n if (path.isAbsolute(key)) {\n return key;\n }\n return path.resolve(this.cwd, key);\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param dirPath - Absolute directory path to list files from\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n async ls(dirPath: string): Promise<LsResult> {\n try {\n const resolvedPath = this.resolvePath(dirPath);\n const stat = await fs.stat(resolvedPath);\n\n if (!stat.isDirectory()) {\n return { files: [] };\n }\n\n const entries = await fs.readdir(resolvedPath, { withFileTypes: true });\n const results: FileInfo[] = [];\n\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n\n for (const entry of entries) {\n const fullPath = path.join(resolvedPath, entry.name);\n\n try {\n const entryStat = await fs.stat(fullPath);\n const isFile = entryStat.isFile();\n const isDir = entryStat.isDirectory();\n\n if (!this.virtualMode) {\n // Non-virtual mode: use absolute paths\n if (isFile) {\n results.push({\n path: fullPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: fullPath + path.sep,\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n } else {\n let relativePath: string;\n if (fullPath.startsWith(cwdStr)) {\n relativePath = fullPath.substring(cwdStr.length);\n } else if (fullPath.startsWith(this.cwd)) {\n relativePath = fullPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = fullPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virtPath = \"/\" + relativePath;\n\n if (isFile) {\n results.push({\n path: virtPath,\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n });\n } else if (isDir) {\n results.push({\n path: virtPath + \"/\",\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n });\n }\n }\n } catch {\n // Skip entries we can't stat\n continue;\n }\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return { files: results };\n } catch {\n return { files: [] };\n }\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute or relative file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n async read(\n filePath: string,\n offset: number = 0,\n limit: number = 500,\n ): Promise<ReadResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n const mimeType = getMimeType(filePath);\n const isBinary = !isTextMimeType(mimeType);\n\n let content: string;\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return { error: `File '${filePath}' not found` };\n }\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW,\n );\n try {\n if (isBinary) {\n const buffer = await fd.readFile();\n return { content: new Uint8Array(buffer), mimeType };\n }\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return { error: `Symlinks are not allowed: ${filePath}` };\n }\n if (!stat.isFile()) {\n return { error: `File '${filePath}' not found` };\n }\n if (isBinary) {\n const buffer = await fs.readFile(resolvedPath);\n return { content: new Uint8Array(buffer), mimeType };\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const emptyMsg = checkEmptyContent(content);\n if (emptyMsg) {\n return { content: emptyMsg, mimeType };\n }\n\n const lines = content.split(\"\\n\");\n const startIdx = offset;\n const endIdx = Math.min(startIdx + limit, lines.length);\n\n if (startIdx >= lines.length) {\n return {\n error: `Line offset ${offset} exceeds file length (${lines.length} lines)`,\n };\n }\n\n const selectedLines = lines.slice(startIdx, endIdx);\n return { content: selectedLines.join(\"\\n\"), mimeType };\n } catch (e: any) {\n return { error: `Error reading file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns ReadRawResult with raw file data on success or error on failure\n */\n async readRaw(filePath: string): Promise<ReadRawResult> {\n const resolvedPath = this.resolvePath(filePath);\n\n const mimeType = getMimeType(filePath);\n const isBinary = !isTextMimeType(mimeType);\n\n let content: string;\n let stat: fsSync.Stats;\n\n if (SUPPORTS_NOFOLLOW) {\n stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return { error: `File '${filePath}' not found` };\n }\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW,\n );\n try {\n if (isBinary) {\n const buffer = await fd.readFile();\n return {\n data: {\n content: new Uint8Array(buffer),\n mimeType,\n created_at: stat.ctime.toISOString(),\n modified_at: stat.mtime.toISOString(),\n },\n };\n }\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return { error: `Symlinks are not allowed: ${filePath}` };\n }\n if (!stat.isFile()) {\n return { error: `File '${filePath}' not found` };\n }\n if (isBinary) {\n const buffer = await fs.readFile(resolvedPath);\n return {\n data: {\n content: new Uint8Array(buffer),\n mimeType,\n created_at: stat.ctime.toISOString(),\n modified_at: stat.mtime.toISOString(),\n },\n };\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n return {\n data: {\n content,\n mimeType,\n created_at: stat.ctime.toISOString(),\n modified_at: stat.mtime.toISOString(),\n },\n };\n }\n\n /**\n * Create a new file with content.\n * Returns WriteResult. External storage sets filesUpdate=null.\n */\n async write(filePath: string, content: string): Promise<WriteResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n const mimeType = getMimeType(filePath);\n const isBinary = !isTextMimeType(mimeType);\n\n try {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return {\n error: `Cannot write to ${filePath} because it is a symlink. Symlinks are not allowed.`,\n };\n }\n return {\n error: `Cannot write to ${filePath} because it already exists. Read and then make an edit, or write to a new path.`,\n };\n } catch {\n // File doesn't exist, good to proceed\n }\n\n await fs.mkdir(path.dirname(resolvedPath), { recursive: true });\n\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_CREAT |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags, 0o644);\n try {\n if (isBinary) {\n const buffer = Buffer.from(content, \"base64\");\n await fd.writeFile(buffer);\n } else {\n await fd.writeFile(content, \"utf-8\");\n }\n } finally {\n await fd.close();\n }\n } else {\n if (isBinary) {\n const buffer = Buffer.from(content, \"base64\");\n await fs.writeFile(resolvedPath, buffer);\n } else {\n await fs.writeFile(resolvedPath, content, \"utf-8\");\n }\n }\n\n return { path: filePath, filesUpdate: null };\n } catch (e: any) {\n return { error: `Error writing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Edit a file by replacing string occurrences.\n * Returns EditResult. External storage sets filesUpdate=null.\n */\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n ): Promise<EditResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n let content: string;\n\n if (SUPPORTS_NOFOLLOW) {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n\n const fd = await fs.open(\n resolvedPath,\n fsSync.constants.O_RDONLY | fsSync.constants.O_NOFOLLOW,\n );\n try {\n content = await fd.readFile({ encoding: \"utf-8\" });\n } finally {\n await fd.close();\n }\n } else {\n const stat = await fs.lstat(resolvedPath);\n if (stat.isSymbolicLink()) {\n return { error: `Error: Symlinks are not allowed: ${filePath}` };\n }\n if (!stat.isFile()) {\n return { error: `Error: File '${filePath}' not found` };\n }\n content = await fs.readFile(resolvedPath, \"utf-8\");\n }\n\n const result = performStringReplacement(\n content,\n oldString,\n newString,\n replaceAll,\n );\n\n if (typeof result === \"string\") {\n return { error: result };\n }\n\n const [newContent, occurrences] = result;\n\n // Write securely\n if (SUPPORTS_NOFOLLOW) {\n const flags =\n fsSync.constants.O_WRONLY |\n fsSync.constants.O_TRUNC |\n fsSync.constants.O_NOFOLLOW;\n\n const fd = await fs.open(resolvedPath, flags);\n try {\n await fd.writeFile(newContent, \"utf-8\");\n } finally {\n await fd.close();\n }\n } else {\n await fs.writeFile(resolvedPath, newContent, \"utf-8\");\n }\n\n return { path: filePath, filesUpdate: null, occurrences: occurrences };\n } catch (e: any) {\n return { error: `Error editing file '${filePath}': ${e.message}` };\n }\n }\n\n /**\n * Search for a literal text pattern in files.\n *\n * Uses ripgrep if available, falling back to substring search.\n *\n * @param pattern - Literal string to search for (NOT regex).\n * @param dirPath - Directory or file path to search in. Defaults to current directory.\n * @param glob - Optional glob pattern to filter which files to search.\n * @returns List of GrepMatch dicts containing path, line number, and matched text.\n */\n async grep(\n pattern: string,\n dirPath: string = \"/\",\n glob: string | null = null,\n ): Promise<GrepResult> {\n // Resolve base path\n let baseFull: string;\n try {\n baseFull = this.resolvePath(dirPath || \".\");\n } catch {\n return { matches: [] };\n }\n\n try {\n await fs.stat(baseFull);\n } catch {\n return { matches: [] };\n }\n\n // Try ripgrep first (with -F flag for literal search), fallback to substring search\n let results = await this.ripgrepSearch(pattern, baseFull, glob);\n if (results === null) {\n results = await this.literalSearch(pattern, baseFull, glob);\n }\n\n const matches: GrepMatch[] = [];\n for (const [fpath, items] of Object.entries(results)) {\n for (const [lineNum, lineText] of items) {\n matches.push({ path: fpath, line: lineNum, text: lineText });\n }\n }\n return { matches };\n }\n\n /**\n * Search using ripgrep with fixed-string (literal) mode.\n *\n * @param pattern - Literal string to search for (unescaped).\n * @param baseFull - Resolved base path to search in.\n * @param includeGlob - Optional glob pattern to filter files.\n * @returns Dict mapping file paths to list of (line_number, line_text) tuples.\n * Returns null if ripgrep is unavailable or times out.\n */\n private async ripgrepSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null,\n ): Promise<Record<string, Array<[number, string]>> | null> {\n return new Promise((resolve) => {\n // -F enables fixed-string (literal) mode\n const args = [\"--json\", \"-F\"];\n if (includeGlob) {\n args.push(\"--glob\", includeGlob);\n }\n args.push(\"--\", pattern, baseFull);\n\n const proc = spawn(\"rg\", args, { timeout: 30000 });\n const results: Record<string, Array<[number, string]>> = {};\n let output = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n output += data.toString();\n });\n\n proc.on(\"close\", (code) => {\n if (code !== 0 && code !== 1) {\n // Error (code 1 means no matches, which is ok)\n resolve(null);\n return;\n }\n\n for (const line of output.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const data = JSON.parse(line);\n if (data.type !== \"match\") continue;\n\n const pdata = data.data || {};\n const ftext = pdata.path?.text;\n if (!ftext) continue;\n\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const resolved = path.resolve(ftext);\n const relative = path.relative(this.cwd, resolved);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = ftext;\n }\n\n const ln = pdata.line_number;\n const lt = pdata.lines?.text?.replace(/\\n$/, \"\") || \"\";\n if (ln === undefined) continue;\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([ln, lt]);\n } catch {\n // Skip invalid JSON\n continue;\n }\n }\n\n resolve(results);\n });\n\n proc.on(\"error\", () => {\n resolve(null);\n });\n });\n }\n\n /**\n * Fallback search using literal substring matching when ripgrep is unavailable.\n *\n * Recursively searches files, respecting maxFileSizeBytes limit.\n *\n * @param pattern - Literal string to search for.\n * @param baseFull - Resolved base path to search in.\n * @param includeGlob - Optional glob pattern to filter files by name.\n * @returns Dict mapping file paths to list of (line_number, line_text) tuples.\n */\n private async literalSearch(\n pattern: string,\n baseFull: string,\n includeGlob: string | null,\n ): Promise<Record<string, Array<[number, string]>>> {\n const results: Record<string, Array<[number, string]>> = {};\n const stat = await fs.stat(baseFull);\n const root = stat.isDirectory() ? baseFull : path.dirname(baseFull);\n\n // Use fast-glob to recursively find all files\n const files = await fg(\"**/*\", {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const fp of files) {\n try {\n // Skip binary files\n const mimeType = getMimeType(fp);\n if (!isTextMimeType(mimeType)) {\n continue;\n }\n\n // Filter by glob if provided\n if (\n includeGlob &&\n !micromatch.isMatch(path.basename(fp), includeGlob)\n ) {\n continue;\n }\n\n // Check file size\n const stat = await fs.stat(fp);\n if (stat.size > this.maxFileSizeBytes) {\n continue;\n }\n\n // Read and search using literal substring matching\n const content = await fs.readFile(fp, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Simple substring search for literal matching\n if (line.includes(pattern)) {\n let virtPath: string;\n if (this.virtualMode) {\n try {\n const relative = path.relative(this.cwd, fp);\n if (relative.startsWith(\"..\")) continue;\n const normalizedRelative = relative.split(path.sep).join(\"/\");\n virtPath = \"/\" + normalizedRelative;\n } catch {\n continue;\n }\n } else {\n virtPath = fp;\n }\n\n if (!results[virtPath]) {\n results[virtPath] = [];\n }\n results[virtPath].push([i + 1, line]);\n }\n }\n } catch {\n // Skip files we can't read\n continue;\n }\n }\n\n return results;\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n */\n async glob(pattern: string, searchPath: string = \"/\"): Promise<GlobResult> {\n if (pattern.startsWith(\"/\")) {\n pattern = pattern.substring(1);\n }\n\n const resolvedSearchPath =\n searchPath === \"/\" ? this.cwd : this.resolvePath(searchPath);\n\n try {\n const stat = await fs.stat(resolvedSearchPath);\n if (!stat.isDirectory()) {\n return { files: [] };\n }\n } catch {\n return { files: [] };\n }\n\n const results: FileInfo[] = [];\n\n try {\n // Use fast-glob for pattern matching\n const matches = await fg(pattern, {\n cwd: resolvedSearchPath,\n absolute: true,\n onlyFiles: true,\n dot: true,\n });\n\n for (const matchedPath of matches) {\n try {\n const stat = await fs.stat(matchedPath);\n if (!stat.isFile()) continue;\n\n // Normalize fast-glob paths to platform separators\n // fast-glob returns forward slashes on all platforms, but we need\n // platform-native separators for path comparisons on Windows\n const normalizedPath = matchedPath.split(\"/\").join(path.sep);\n\n if (!this.virtualMode) {\n results.push({\n path: normalizedPath,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n } else {\n const cwdStr = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n let relativePath: string;\n\n if (normalizedPath.startsWith(cwdStr)) {\n relativePath = normalizedPath.substring(cwdStr.length);\n } else if (normalizedPath.startsWith(this.cwd)) {\n relativePath = normalizedPath\n .substring(this.cwd.length)\n .replace(/^[/\\\\]/, \"\");\n } else {\n relativePath = normalizedPath;\n }\n\n relativePath = relativePath.split(path.sep).join(\"/\");\n const virt = \"/\" + relativePath;\n results.push({\n path: virt,\n is_dir: false,\n size: stat.size,\n modified_at: stat.mtime.toISOString(),\n });\n }\n } catch {\n // Skip files we can't stat\n continue;\n }\n }\n } catch {\n // Ignore glob errors\n }\n\n results.sort((a, b) => a.path.localeCompare(b.path));\n return { files: results };\n }\n\n /**\n * Upload multiple files to the filesystem.\n *\n * @param files - List of [path, content] tuples to upload\n * @returns List of FileUploadResponse objects, one per input file\n */\n async uploadFiles(\n files: Array<[string, Uint8Array]>,\n ): Promise<FileUploadResponse[]> {\n const responses: FileUploadResponse[] = [];\n\n for (const [filePath, content] of files) {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(resolvedPath), { recursive: true });\n\n // Write file\n await fs.writeFile(resolvedPath, content);\n responses.push({ path: filePath, error: null });\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n responses.push({ path: filePath, error: \"file_not_found\" });\n } else if (e.code === \"EACCES\") {\n responses.push({ path: filePath, error: \"permission_denied\" });\n } else if (e.code === \"EISDIR\") {\n responses.push({ path: filePath, error: \"is_directory\" });\n } else {\n responses.push({ path: filePath, error: \"invalid_path\" });\n }\n }\n }\n\n return responses;\n }\n\n /**\n * Download multiple files from the filesystem.\n *\n * @param paths - List of file paths to download\n * @returns List of FileDownloadResponse objects, one per input path\n */\n async downloadFiles(paths: string[]): Promise<FileDownloadResponse[]> {\n const responses: FileDownloadResponse[] = [];\n\n for (const filePath of paths) {\n try {\n const resolvedPath = this.resolvePath(filePath);\n const content = await fs.readFile(resolvedPath);\n responses.push({ path: filePath, content, error: null });\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n responses.push({\n path: filePath,\n content: null,\n error: \"file_not_found\",\n });\n } else if (e.code === \"EACCES\") {\n responses.push({\n path: filePath,\n content: null,\n error: \"permission_denied\",\n });\n } else if (e.code === \"EISDIR\") {\n responses.push({\n path: filePath,\n content: null,\n error: \"is_directory\",\n });\n } else {\n responses.push({\n path: filePath,\n content: null,\n error: \"invalid_path\",\n });\n }\n }\n }\n\n return responses;\n }\n}\n","/**\n * LocalShellBackend: Node.js implementation of the filesystem backend with unrestricted local shell execution.\n *\n * This backend extends FilesystemBackend to add shell command execution on the local\n * host system. It provides NO sandboxing or isolation - all operations run directly\n * on the host machine with full system access.\n *\n * @module\n */\n\nimport cp from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport fg from \"fast-glob\";\n\nimport { FilesystemBackend } from \"./filesystem.js\";\nimport type {\n EditResult,\n ExecuteResponse,\n FileInfo,\n GlobResult,\n LsResult,\n ReadResult,\n SandboxBackendProtocolV2,\n} from \"./protocol.js\";\nimport { SandboxError } from \"./protocol.js\";\n\n/**\n * Options for creating a LocalShellBackend instance.\n */\nexport interface LocalShellBackendOptions {\n /**\n * Working directory for both filesystem operations and shell commands.\n * When set with `virtualMode: false` (default), absolute paths and `..` can\n * bypass rootDir for filesystem operations.\n * @defaultValue `process.cwd()`\n */\n rootDir?: string;\n\n /**\n * Enable virtual path mode for filesystem operations.\n * When true, treats rootDir as a virtual root filesystem.\n * When false (default), preserves legacy path behavior.\n * Does NOT restrict shell commands.\n * @defaultValue `false`\n */\n virtualMode?: boolean;\n\n /**\n * Maximum time in seconds to wait for shell command execution.\n * Commands exceeding this timeout will be terminated.\n * @defaultValue `120`\n */\n timeout?: number;\n\n /**\n * Maximum number of bytes to capture from command output.\n * Output exceeding this limit will be truncated.\n * @defaultValue `100_000`\n */\n maxOutputBytes?: number;\n\n /**\n * Environment variables for shell commands. If undefined, starts with an empty\n * environment (unless inheritEnv is true).\n * @defaultValue `undefined`\n */\n env?: Record<string, string>;\n\n /**\n * Whether to inherit the parent process's environment variables.\n * When false, only variables in env dict are available.\n * When true, inherits all process.env variables and applies env overrides.\n * @defaultValue `false`\n */\n inheritEnv?: boolean;\n\n /**\n * Files to create on disk during `create()`.\n * Keys are file paths (resolved via the backend's path handling),\n * values are string content.\n * @defaultValue `undefined`\n */\n initialFiles?: Record<string, string>;\n}\n\n/**\n * Filesystem backend with unrestricted local shell command execution.\n *\n * This backend extends FilesystemBackend to add shell command execution\n * capabilities. Commands are executed directly on the host system without any\n * sandboxing, process isolation, or security restrictions.\n *\n * **Security Warning:**\n * This backend grants agents BOTH direct filesystem access AND unrestricted\n * shell execution on your local machine. Use with extreme caution and only in\n * appropriate environments.\n *\n * **Appropriate use cases:**\n * - Local development CLIs (coding assistants, development tools)\n * - Personal development environments where you trust the agent's code\n * - CI/CD pipelines with proper secret management\n *\n * **Inappropriate use cases:**\n * - Production environments (e.g., web servers, APIs, multi-tenant systems)\n * - Processing untrusted user input or executing untrusted code\n *\n * Use StateBackend, StoreBackend, or extend BaseSandbox for production.\n *\n * @example\n * ```typescript\n * import { LocalShellBackend } from \"@langchain/deepagents\";\n *\n * // Create backend with explicit environment\n * const backend = new LocalShellBackend({\n * rootDir: \"/home/user/project\",\n * virtualMode: true,\n * env: { PATH: \"/usr/bin:/bin\" },\n * });\n *\n * // Execute shell commands (runs directly on host)\n * const result = await backend.execute(\"ls -la\");\n * console.log(result.output);\n * console.log(result.exitCode);\n *\n * // Use filesystem operations (inherited from FilesystemBackend)\n * const content = await backend.read(\"/README.md\");\n * await backend.write(\"/output.txt\", \"Hello world\");\n *\n * // Inherit all environment variables\n * const backend2 = new LocalShellBackend({\n * rootDir: \"/home/user/project\",\n * virtualMode: true,\n * inheritEnv: true,\n * });\n * ```\n */\nexport class LocalShellBackend\n extends FilesystemBackend\n implements SandboxBackendProtocolV2\n{\n #timeout: number;\n #maxOutputBytes: number;\n #env: Record<string, string>;\n #sandboxId: string;\n #initialized = false;\n\n constructor(options: LocalShellBackendOptions = {}) {\n const {\n rootDir,\n virtualMode = false,\n timeout = 120,\n maxOutputBytes = 100_000,\n env,\n inheritEnv = false,\n } = options;\n\n super({ rootDir, virtualMode, maxFileSizeMb: 10 });\n\n this.#timeout = timeout;\n this.#maxOutputBytes = maxOutputBytes;\n const bytes = new Uint8Array(4);\n crypto.getRandomValues(bytes);\n this.#sandboxId = `local-${[...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`;\n\n if (inheritEnv) {\n this.#env = { ...process.env } as Record<string, string>;\n if (env) {\n Object.assign(this.#env, env);\n }\n } else {\n this.#env = env ?? {};\n }\n }\n\n /** Unique identifier for this backend instance (format: \"local-{random_hex}\"). */\n get id(): string {\n return this.#sandboxId;\n }\n\n /** Whether the backend has been initialized and is ready to use. */\n get isInitialized(): boolean {\n return this.#initialized;\n }\n\n /** Alias for `isInitialized`, matching the standard sandbox interface. */\n get isRunning(): boolean {\n return this.#initialized;\n }\n\n /**\n * Initialize the backend by ensuring the rootDir exists.\n *\n * Creates the rootDir (and any parent directories) if it does not already\n * exist. Safe to call on an existing directory. Must be called before\n * `execute()`, or use the static `LocalShellBackend.create()` factory.\n *\n * @throws {SandboxError} If already initialized (`ALREADY_INITIALIZED`)\n */\n async initialize(): Promise<void> {\n if (this.#initialized) {\n throw new SandboxError(\n \"Backend is already initialized. Each LocalShellBackend instance can only be initialized once.\",\n \"ALREADY_INITIALIZED\",\n );\n }\n await fs.mkdir(this.cwd, { recursive: true });\n this.#initialized = true;\n }\n\n /**\n * Mark the backend as no longer running.\n *\n * For local shell backends there is no remote resource to tear down,\n * so this simply flips the `isRunning` / `isInitialized` flag.\n */\n async close(): Promise<void> {\n this.#initialized = false;\n }\n\n /**\n * Read a file, adapting error messages to the standard sandbox format.\n */\n override async read(\n filePath: string,\n offset: number = 0,\n limit: number = 500,\n ): Promise<ReadResult> {\n const result = await super.read(filePath, offset, limit);\n if (result.error?.includes(\"ENOENT\")) {\n return { error: `File '${filePath}' not found` };\n }\n return result;\n }\n\n /**\n * Edit a file, adapting error messages to the standard sandbox format.\n */\n override async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n ): Promise<EditResult> {\n const result = await super.edit(filePath, oldString, newString, replaceAll);\n if (result.error?.includes(\"ENOENT\")) {\n return { ...result, error: `Error: File '${filePath}' not found` };\n }\n return result;\n }\n\n /**\n * List directory contents, returning paths relative to rootDir.\n */\n override async ls(dirPath: string): Promise<LsResult> {\n const result = await super.ls(dirPath);\n if (result.error) {\n return result;\n }\n\n if (this.virtualMode) {\n return result;\n }\n\n const cwdPrefix = this.cwd.endsWith(path.sep)\n ? this.cwd\n : this.cwd + path.sep;\n const files = (result.files || []).map((info) => ({\n ...info,\n path: info.path.startsWith(cwdPrefix)\n ? info.path.slice(cwdPrefix.length)\n : info.path,\n }));\n return { files };\n }\n\n /**\n * Glob matching that returns relative paths and includes directories.\n */\n override async glob(\n pattern: string,\n searchPath: string = \"/\",\n ): Promise<GlobResult> {\n if (pattern.startsWith(\"/\")) {\n pattern = pattern.substring(1);\n }\n\n const resolvedSearchPath =\n searchPath === \"/\" || searchPath === \"\"\n ? this.cwd\n : this.virtualMode\n ? path.resolve(this.cwd, searchPath.replace(/^\\//, \"\"))\n : path.resolve(this.cwd, searchPath);\n\n try {\n const stat = await fs.stat(resolvedSearchPath);\n if (!stat.isDirectory()) return { files: [] };\n } catch {\n return { files: [] };\n }\n\n const formatPath = (rel: string) => (this.virtualMode ? `/${rel}` : rel);\n\n const globOpts = { cwd: resolvedSearchPath, absolute: false, dot: true };\n const [fileMatches, dirMatches] = await Promise.all([\n fg(pattern, { ...globOpts, onlyFiles: true }),\n fg(pattern, { ...globOpts, onlyDirectories: true }),\n ]);\n\n const statFile = async (match: string): Promise<FileInfo | null> => {\n try {\n const entryStat = await fs.stat(path.join(resolvedSearchPath, match));\n if (entryStat.isFile()) {\n return {\n path: formatPath(match),\n is_dir: false,\n size: entryStat.size,\n modified_at: entryStat.mtime.toISOString(),\n };\n }\n } catch {\n /* skip unstatable entries */\n }\n return null;\n };\n\n const statDir = async (match: string): Promise<FileInfo | null> => {\n try {\n const entryStat = await fs.stat(path.join(resolvedSearchPath, match));\n if (entryStat.isDirectory()) {\n return {\n path: formatPath(match),\n is_dir: true,\n size: 0,\n modified_at: entryStat.mtime.toISOString(),\n };\n }\n } catch {\n /* skip unstatable entries */\n }\n return null;\n };\n\n const [fileInfos, dirInfos] = await Promise.all([\n Promise.all(fileMatches.map(statFile)),\n Promise.all(dirMatches.map(statDir)),\n ]);\n\n const results = [...fileInfos, ...dirInfos].filter(\n (info): info is FileInfo => info !== null,\n );\n results.sort((a, b) => a.path.localeCompare(b.path));\n return { files: results };\n }\n\n /**\n * Execute a shell command directly on the host system.\n *\n * Commands are executed directly on your host system using `spawn()`\n * with `shell: true`. There is NO sandboxing, isolation, or security\n * restrictions. The command runs with your user's full permissions.\n *\n * The command is executed using the system shell with the working directory\n * set to the backend's rootDir. Stdout and stderr are combined into a single\n * output stream, with stderr lines prefixed with `[stderr]`.\n *\n * @param command - Shell command string to execute\n * @returns ExecuteResponse containing output, exit code, and truncation flag\n */\n async execute(command: string): Promise<ExecuteResponse> {\n if (!command || typeof command !== \"string\") {\n return {\n output: \"Error: Command must be a non-empty string.\",\n exitCode: 1,\n truncated: false,\n };\n }\n\n return new Promise<ExecuteResponse>((resolve) => {\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n\n const child = cp.spawn(command, {\n shell: true,\n env: this.#env,\n cwd: this.cwd,\n });\n\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n }, this.#timeout * 1000);\n\n child.stdout.on(\"data\", (data: Buffer) => {\n stdout += data.toString();\n });\n\n child.stderr.on(\"data\", (data: Buffer) => {\n stderr += data.toString();\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timer);\n resolve({\n output: `Error executing command: ${err.message}`,\n exitCode: 1,\n truncated: false,\n });\n });\n\n child.on(\"close\", (code, signal) => {\n clearTimeout(timer);\n\n if (timedOut || signal === \"SIGTERM\") {\n resolve({\n output: `Error: Command timed out after ${this.#timeout.toFixed(1)} seconds.`,\n exitCode: 124,\n truncated: false,\n });\n return;\n }\n\n const outputParts: string[] = [];\n if (stdout) {\n outputParts.push(stdout);\n }\n if (stderr) {\n const stderrLines = stderr.trim().split(\"\\n\");\n outputParts.push(\n ...stderrLines.map((line: string) => `[stderr] ${line}`),\n );\n }\n\n let output =\n outputParts.length > 0 ? outputParts.join(\"\\n\") : \"<no output>\";\n\n let truncated = false;\n if (output.length > this.#maxOutputBytes) {\n output = output.slice(0, this.#maxOutputBytes);\n output += `\\n\\n... Output truncated at ${this.#maxOutputBytes} bytes.`;\n truncated = true;\n }\n\n const exitCode = code ?? 1;\n\n if (exitCode !== 0) {\n output = `${output.trimEnd()}\\n\\nExit code: ${exitCode}`;\n }\n\n resolve({\n output,\n exitCode,\n truncated,\n });\n });\n });\n }\n\n /**\n * Create and initialize a new LocalShellBackend in one step.\n *\n * This is the recommended way to create a backend when the rootDir may\n * not exist yet. It combines construction and initialization (ensuring\n * rootDir exists) into a single async operation.\n *\n * @param options - Configuration options for the backend\n * @returns An initialized and ready-to-use backend\n */\n static async create(\n options: LocalShellBackendOptions = {},\n ): Promise<LocalShellBackend> {\n const { initialFiles, ...backendOptions } = options;\n const backend = new LocalShellBackend(backendOptions);\n await backend.initialize();\n\n if (initialFiles) {\n const encoder = new TextEncoder();\n const files: Array<[string, Uint8Array]> = Object.entries(\n initialFiles,\n ).map(([filePath, content]) => [filePath, encoder.encode(content)]);\n await backend.uploadFiles(files);\n }\n\n return backend;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepagents",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.5",
|
|
4
4
|
"description": "Deep Agents - a library for building controllable AI agents with LangGraph",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/langchain-ai/deepagentsjs#readme",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@langchain/core": "^1.
|
|
29
|
-
"@langchain/langgraph": "^1.
|
|
30
|
-
"@langchain/langgraph-sdk": "^1.9.
|
|
28
|
+
"@langchain/core": "^1.2.0",
|
|
29
|
+
"@langchain/langgraph": "^1.4.4",
|
|
30
|
+
"@langchain/langgraph-sdk": "^1.9.23",
|
|
31
31
|
"fast-glob": "^3.3.3",
|
|
32
|
-
"langchain": "^1.
|
|
32
|
+
"langchain": "^1.5.0",
|
|
33
33
|
"micromatch": "^4.0.8",
|
|
34
34
|
"yaml": "^2.8.2",
|
|
35
35
|
"zod": "^4.3.6"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@langchain/anthropic": "^1.
|
|
39
|
-
"@langchain/langgraph-checkpoint": "^1.
|
|
40
|
-
"@langchain/openai": "^1.
|
|
38
|
+
"@langchain/anthropic": "^1.5.0",
|
|
39
|
+
"@langchain/langgraph-checkpoint": "^1.1.2",
|
|
40
|
+
"@langchain/openai": "^1.5.1",
|
|
41
41
|
"@langchain/tavily": "^1.2.0",
|
|
42
42
|
"@tsconfig/recommended": "^1.0.13",
|
|
43
43
|
"@types/micromatch": "^4.0.10",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@vitest/coverage-v8": "^4.0.18",
|
|
46
46
|
"@vitest/ui": "^4.0.18",
|
|
47
47
|
"dotenv": "^17.2.4",
|
|
48
|
-
"tsdown": "^0.
|
|
48
|
+
"tsdown": "^0.22.1",
|
|
49
49
|
"tsx": "^4.21.0",
|
|
50
50
|
"typescript": "^6.0.2",
|
|
51
51
|
"vitest": "^4.0.18",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"exports": {
|
|
55
55
|
".": {
|
|
56
|
+
"browser": "./dist/browser.js",
|
|
56
57
|
"import": {
|
|
57
58
|
"types": "./dist/index.d.ts",
|
|
58
59
|
"default": "./dist/index.js"
|
|
@@ -62,10 +63,30 @@
|
|
|
62
63
|
"default": "./dist/index.cjs"
|
|
63
64
|
}
|
|
64
65
|
},
|
|
66
|
+
"./browser": {
|
|
67
|
+
"import": {
|
|
68
|
+
"types": "./dist/browser.d.ts",
|
|
69
|
+
"default": "./dist/browser.js"
|
|
70
|
+
},
|
|
71
|
+
"require": {
|
|
72
|
+
"types": "./dist/browser.d.cts",
|
|
73
|
+
"default": "./dist/browser.cjs"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"./node": {
|
|
77
|
+
"import": {
|
|
78
|
+
"types": "./dist/node.d.ts",
|
|
79
|
+
"default": "./dist/node.js"
|
|
80
|
+
},
|
|
81
|
+
"require": {
|
|
82
|
+
"types": "./dist/node.d.cts",
|
|
83
|
+
"default": "./dist/node.cjs"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
65
86
|
"./package.json": "./package.json"
|
|
66
87
|
},
|
|
67
88
|
"peerDependencies": {
|
|
68
|
-
"langsmith": "
|
|
89
|
+
"langsmith": "^0.7.1"
|
|
69
90
|
},
|
|
70
91
|
"files": [
|
|
71
92
|
"dist/**/*"
|