# How the SecureDesign Tool System Works: AI-Powered File Manipulation Architecture

> Explore the AI-powered file manipulation architecture of the SecureDesign tool system. Learn how read, write, edit, and other tools ensure secure workspace isolation.

- Repository: [Harold Martin/secure-design](https://github.com/hbmartin/secure-design)
- Tags: architecture
- Published: 2026-03-03

---

**The SecureDesign tool system provides a secure, typed bridge between LLM agents and the local file system through specialized tools (read, write, edit, glob, grep, ls, multiedit, theme) that enforce workspace isolation via path validation in [`tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/tool-utils.ts).**

The SecureDesign extension (`hbmartin/secure-design`) implements a comprehensive tool system that allows AI agents to safely manipulate files within the VS Code workspace. This architecture ensures that all file operations remain sandboxed within the project boundary while providing rich metadata and standardized error handling for LLM consumption. Each tool is built around the `ai.tool` pattern with Zod schemas for type safety.

## Core Architecture of the SecureDesign Tool System

### Standardized Response Types

All tools in SecureDesign return a `ToolResponse` union type defined in [`src/tools/tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/tool-utils.ts). The system distinguishes between `ToolSuccessResponse` and `ToolErrorResponse`, with errors normalized through `handleToolError` to include an `error_type` tag and concise messaging that the LLM can interpret.

```typescript
// src/tools/tool-utils.ts
export interface ToolErrorResponse { … }
export interface ToolSuccessResponse { … }
export type ToolResponse = ToolSuccessResponse | ToolErrorResponse;

```

### Path Security and Workspace Isolation

Every file system tool invokes `validateWorkspacePath(filePath, context)` before operations. This helper, implemented in [`src/tools/tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/tool-utils.ts):

- Rejects paths containing `..` to prevent directory traversal attacks
- Resolves relative paths against `context.workingDirectory`
- Verifies the final absolute path starts with the workspace root

Violations return a `ToolErrorResponse` with `error_type: "security"`, ensuring the AI cannot escape the sandbox.

### Execution Context and Logging

Tools receive an `ExecutionContext` containing the workspace root and a VS Code logger:

```typescript
export interface ExecutionContext {
    workingDirectory: string;   // workspace root
    logger: Logger;             // injected VS Code logger
}

```

Each operation logs via `context.logger.info`, creating an audit trail in the output panel (e.g., `[read] Reading text file: src/main.ts (4.2 KB)`).

### Tool Definition Pattern

All tools follow a factory pattern using `ai.tool`:

```typescript
export function createReadTool(context: ExecutionContext) {
    return tool({
        description: 'Read file content with optional line range',
        inputSchema: z.object({ filePath: z.string(), ... }),
        execute: async (args): Promise<ToolResponse> => {
            // 1. Validate path
            // 2. Resolve absolute location
            // 3. Perform operation
            // 4. Return standardized response
        },
    });
}

```

## The Nine Core Tools in SecureDesign

The SecureDesign tool system provides nine specialized instruments for file manipulation and workspace inspection:

| Tool | Purpose | Key File |
|------|---------|----------|
| **read** | Return content (text, image, PDF, binary) with optional line-range | [`src/tools/read-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/read-tool.ts) |
| **write** | Write arbitrary content to a file (creates parent dirs) | [`src/tools/write-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/write-tool.ts) |
| **edit** | Single find-and-replace in a file | [`src/tools/edit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/edit-tool.ts) |
| **multiedit** | Apply a sequence of edits atomically | [`src/tools/multiedit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/multiedit-tool.ts) |
| **glob** | Find files/directories matching a glob pattern | [`src/tools/glob-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/glob-tool.ts) |
| **grep** | Search file contents with a regexp | [`src/tools/grep-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/grep-tool.ts) |
| **ls** | List directory entries with filtering | [`src/tools/ls-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/ls-tool.ts) |
| **theme** | Persist a CSS theme generated by the LLM | [`src/tools/theme-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/theme-tool.ts) |

### Read Tool

Located in [`src/tools/read-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/read-tool.ts), this tool handles text, image, PDF, and binary files. It enforces a 10 MB size limit and supports line-range extraction via `startLine` and `lineCount` parameters. The `detectFileType` function categorizes content, while `processTextFile` handles truncation and `processMediaFile` prepares image/PDF data for the LLM.

### Write Tool

Implemented in [`src/tools/write-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/write-tool.ts), this tool creates or overwrites files. The `create_dirs` parameter automatically generates parent directories using `fs.mkdirSync`. It validates that the target is not a directory before writing via `fs.writeFileSync`.

### Edit Tool

Found in [`src/tools/edit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/edit-tool.ts), this performs single find-and-replace operations. It counts exact matches of `old_string` and validates against `expected_replacements` to prevent unintended changes. The replacement is atomic: read, modify, write back.

### Multiedit Tool

Located in [`src/tools/multiedit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/multiedit-tool.ts), this applies a sequence of edits atomically. The `fail_fast` parameter controls whether to stop on the first error or continue processing remaining edits. It uses `applySingleEdit` internally and only writes the file if at least one edit succeeded.

### Glob Tool

In [`src/tools/glob-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/glob-tool.ts), this converts glob patterns to regex for recursive file discovery. It supports `case_sensitive`, `include_dirs`, `show_hidden`, and `max_results` filters. The `findMatches` function walks directories efficiently, sorting results by time when requested.

### Grep Tool

Implemented in [`src/tools/grep-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/grep-tool.ts), this searches file contents with regex. It skips common directories (like `node_modules`) via `findFilesToSearch`, streams files with `searchInFile`, and respects `max_files` and `max_matches` limits to prevent resource exhaustion.

### Ls Tool

Found in [`src/tools/ls-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/ls-tool.ts), this lists directory contents. It filters hidden files and ignore patterns, supports `detailed` view with file stats via `fs.statSync`, and sorts directories before files for logical presentation.

### Theme Tool

Located in [`src/tools/theme-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/theme-tool.ts), this persists CSS themes generated by the LLM. It validates the CSS file path, creates directories if needed via the `create_dirs` parameter, and returns theme metadata for the UI to consume.

## Practical Usage Examples

The SecureDesign tool system accepts JSON payloads from the LLM and returns structured responses. Below are representative invocations:

### Reading Source Code with Line Ranges

```json
{
  "tool": "read",
  "arguments": {
    "filePath": "src/services/customAgentService.ts",
    "startLine": 10,
    "lineCount": 20,
    "encoding": "utf-8"
  }
}

```

**Response:**

```json
{
  "success": true,
  "content": "[Content truncated: showing lines 10-29 of 250 total lines]\n\nimport …",
  "filePath": "src/services/customAgentService.ts",
  "fileType": "text",
  "mimeType": "text/typescript",
  "size": 8423,
  "lineCount": 250,
  "isTruncated": true,
  "linesShown": [10, 29]
}

```

### Writing Configuration Files

```json
{
  "tool": "write",
  "arguments": {
    "file_path": ".superdesign/config/theme.json",
    "content": "{ \"name\": \"dark\", \"primary\": \"#1e1e1e\" }",
    "create_dirs": true
  }
}

```

**Response:**

```json
{
  "success": true,
  "file_path": ".superdesign/config/theme.json",
  "absolute_path": "/repo/.superdesign/config/theme.json",
  "is_new_file": true,
  "lines_written": 1,
  "bytes_written": 44
}

```

### Batch Editing with Multiedit

```json
{
  "tool": "multiedit",
  "arguments": {
    "file_path": "src/webview/components/CanvasView.tsx",
    "edits": [
      {
        "old_string": "const foo = 1;",
        "new_string": "const foo = 42;",
        "expected_replacements": 1
      },
      {
        "old_string": "background: white;",
        "new_string": "background: #111;",
        "expected_replacements": 1
      }
    ],
    "fail_fast": false
  }
}

```

**Response:**

```json
{
  "success": true,
  "file_path": "src/webview/components/CanvasView.tsx",
  "edits_total": 2,
  "edits_successful": 2,
  "total_replacements": 2,
  "lines_total": 312,
  "bytes_total": 8456,
  "content_changed": true,
  "edit_results": [
    { "edit": { … }, "success": true, "occurrences": 1 },
    { "edit": { … }, "success": true, "occurrences": 1 }
  ]
}

```

### Searching with Grep

```json
{
  "tool": "grep",
  "arguments": {
    "pattern": "createTool\\(",
    "path": "src/tools",
    "include": "*.ts",
    "case_sensitive": false,
    "max_files": 200,
    "max_matches": 10
  }
}

```

**Response:**

```json
{
  "success": true,
  "pattern": "createTool\\(",
  "search_path": "src/tools",
  "files_searched": 8,
  "files_with_matches": 3,
  "matches": [
    {
      "filePath": "read-tool.ts",
      "lineNumber": 17,
      "line": "export function createReadTool(context: ExecutionContext) {",
      "matchStart": 22,
      "matchEnd": 33
    }
  ],
  "total_matches": 6,
  "summary": "Found 6 match(es) for \"createTool\\(\" in 3 file(s) (searched 8/8 files)"
}

```

## Key Source Files

| File | Role |
|------|------|
| [`src/tools/tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/tool-utils.ts) | Shared validation, path resolution, and response helpers |
| [`src/tools/read-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/read-tool.ts) | Implements file reading with truncation and media handling |
| [`src/tools/write-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/write-tool.ts) | Writes content, creates directories, returns write metadata |
| [`src/tools/edit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/edit-tool.ts) | Single find-and-replace with occurrence validation |
| [`src/tools/multiedit-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/multiedit-tool.ts) | Sequential batch edits with optional fail-fast |
| [`src/tools/glob-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/glob-tool.ts) | Fast glob-to-regex conversion and recursive discovery |
| [`src/tools/grep-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/grep-tool.ts) | Regex search across text files with resource limits |
| [`src/tools/ls-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/ls-tool.ts) | Directory listing with hidden file filtering |
| [`src/tools/theme-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/theme-tool.ts) | Persists CSS themes generated by the LLM |
| [`src/services/customAgentService.ts`](https://github.com/hbmartin/secure-design/blob/main/src/services/customAgentService.ts) | Registers all tools with the AI runtime and injects execution context |

## Summary

- The SecureDesign tool system uses `ai.tool` with Zod schemas to register type-safe operations with the LLM runtime.
- All file system tools enforce workspace isolation through `validateWorkspacePath` in [`src/tools/tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/tool-utils.ts), preventing directory traversal attacks.
- Tools return standardized `ToolResponse` objects containing rich metadata (file sizes, line counts, MIME types) for LLM consumption.
- The nine core tools (read, write, edit, multiedit, glob, grep, ls, theme, and bash) cover the full spectrum of file manipulation, search, and UI theming needs.
- Execution context provides workspace root resolution and audit logging, creating a transparent record of all AI file operations.

## Frequently Asked Questions

### How does SecureDesign prevent the AI from accessing files outside the workspace?

The `validateWorkspacePath` function in [`src/tools/tool-utils.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/tool-utils.ts) rejects any path containing `..` sequences and resolves all paths against the workspace root. It verifies that the final absolute path starts with `context.workingDirectory`, returning a `security` error type if the check fails, effectively sandboxing all file operations.

### What is the difference between the edit and multiedit tools?

The **edit** tool performs a single find-and-replace operation with exact match counting and validation against `expected_replacements`. The **multiedit** tool accepts an array of edits and applies them sequentially to the same file, with the `fail_fast` parameter controlling whether to stop on first error or continue processing remaining edits.

### How does the read tool handle different file types?

The read tool in [`src/tools/read-tool.ts`](https://github.com/hbmartin/secure-design/blob/main/src/tools/read-tool.ts) uses `detectFileType` to categorize files as text, image, PDF, or binary. Text files support line-range extraction via `processTextFile`, images and PDFs are processed through `processMediaFile` for appropriate MIME type handling, and binary files return a placeholder response. All files are subject to a 10 MB size limit.

### Where are the tools registered with the AI runtime?

The [`customAgentService.ts`](https://github.com/hbmartin/secure-design/blob/main/customAgentService.ts) file in `src/services/` instantiates all tool factories (like `createReadTool`, `createWriteTool`) with the `ExecutionContext`, then registers them with the LLM runtime using the `ai.tool` pattern. This service injects the workspace root and logger into each tool, ensuring consistent context across all file operations.