Skip to main content
curl "http://localhost:8887/api/filesystem/list?path=/home/user/projects&showHidden=false"
{
  "success": true,
  "data": {
    "path": "/home/user/projects",
    "entries": [
      {
        "name": "my-app",
        "path": "/home/user/projects/my-app",
        "type": "directory",
        "isGitRepo": true,
        "size": 4096,
        "modifiedAt": "2024-01-15T10:00:00Z",
        "permissions": "rwxr-xr-x"
      },
      {
        "name": "package.json",
        "path": "/home/user/projects/my-app/package.json",
        "type": "file",
        "size": 1024,
        "modifiedAt": "2024-01-15T09:30:00Z",
        "permissions": "rw-r--r--"
      },
      {
        "name": "src",
        "path": "/home/user/projects/my-app/src",
        "type": "directory",
        "size": 4096,
        "modifiedAt": "2024-01-15T10:15:00Z",
        "permissions": "rwxr-xr-x"
      },
      {
        "name": ".git",
        "path": "/home/user/projects/my-app/.git",
        "type": "directory",
        "isGitRepo": true,
        "hidden": true,
        "size": 4096,
        "modifiedAt": "2024-01-15T11:00:00Z",
        "permissions": "rwxr-xr-x"
      }
    ],
    "totalEntries": 4,
    "directories": 3,
    "files": 1,
    "gitRepos": 1
  }
}

Overview

The Filesystem API provides endpoints for browsing repository files and discovering git repositories on the local filesystem. Base URL: http://localhost:8887/api/filesystem

List Directory

List files and subdirectories in a given path.
GET /api/filesystem/list

Query Parameters

ParameterTypeRequiredDescription
pathstringDirectory path to list
showHiddenboolean⚠️Include hidden files (default: false)
recursiveboolean⚠️Recursively list subdirectories (default: false)
maxDepthinteger⚠️Max recursion depth (default: 1)
curl "http://localhost:8887/api/filesystem/list?path=/home/user/projects&showHidden=false"
{
  "success": true,
  "data": {
    "path": "/home/user/projects",
    "entries": [
      {
        "name": "my-app",
        "path": "/home/user/projects/my-app",
        "type": "directory",
        "isGitRepo": true,
        "size": 4096,
        "modifiedAt": "2024-01-15T10:00:00Z",
        "permissions": "rwxr-xr-x"
      },
      {
        "name": "package.json",
        "path": "/home/user/projects/my-app/package.json",
        "type": "file",
        "size": 1024,
        "modifiedAt": "2024-01-15T09:30:00Z",
        "permissions": "rw-r--r--"
      },
      {
        "name": "src",
        "path": "/home/user/projects/my-app/src",
        "type": "directory",
        "size": 4096,
        "modifiedAt": "2024-01-15T10:15:00Z",
        "permissions": "rwxr-xr-x"
      },
      {
        "name": ".git",
        "path": "/home/user/projects/my-app/.git",
        "type": "directory",
        "isGitRepo": true,
        "hidden": true,
        "size": 4096,
        "modifiedAt": "2024-01-15T11:00:00Z",
        "permissions": "rwxr-xr-x"
      }
    ],
    "totalEntries": 4,
    "directories": 3,
    "files": 1,
    "gitRepos": 1
  }
}

Response Fields

FieldTypeDescription
pathstringDirectory path that was listed
entriesarrayList of files and directories
entries[].namestringFile or directory name
entries[].pathstringAbsolute path
entries[].typeenumfile or directory
entries[].isGitRepobooleanIs a git repository (directories only)
entries[].hiddenbooleanHidden file/directory
entries[].sizeintegerSize in bytes
entries[].modifiedAtstringLast modified timestamp
entries[].permissionsstringUnix-style permissions
totalEntriesintegerTotal number of entries
directoriesintegerNumber of directories
filesintegerNumber of files
gitReposintegerNumber of git repositories found

List Git Repositories

Discover all git repositories under a given path.
GET /api/filesystem/git-repos

Query Parameters

ParameterTypeRequiredDescription
pathstringRoot path to search
maxDepthinteger⚠️Max directory depth (default: 3)
includeSubmodulesboolean⚠️Include git submodules (default: true)
curl "http://localhost:8887/api/filesystem/git-repos?path=/home/user/projects&maxDepth=2"
{
  "success": true,
  "data": {
    "searchPath": "/home/user/projects",
    "repositories": [
      {
        "name": "my-app",
        "path": "/home/user/projects/my-app",
        "gitPath": "/home/user/projects/my-app/.git",
        "isSubmodule": false,
        "branch": "main",
        "hasUncommittedChanges": false,
        "hasUnpushedCommits": true,
        "remotes": [
          {
            "name": "origin",
            "url": "https://github.com/user/my-app.git",
            "type": "https"
          }
        ],
        "lastCommit": {
          "hash": "abc123def456",
          "message": "Add authentication",
          "author": "John Doe",
          "date": "2024-01-15T10:00:00Z"
        }
      },
      {
        "name": "another-project",
        "path": "/home/user/projects/another-project",
        "gitPath": "/home/user/projects/another-project/.git",
        "isSubmodule": false,
        "branch": "develop",
        "hasUncommittedChanges": true,
        "hasUnpushedCommits": false,
        "remotes": [
          {
            "name": "origin",
            "url": "git@github.com:user/another-project.git",
            "type": "ssh"
          }
        ],
        "lastCommit": {
          "hash": "def456ghi789",
          "message": "Work in progress",
          "author": "Jane Smith",
          "date": "2024-01-14T15:30:00Z"
        }
      }
    ],
    "totalFound": 2,
    "searchDepth": 2,
    "searchDuration": 145
  }
}

Response Fields

FieldTypeDescription
searchPathstringRoot path that was searched
repositoriesarrayList of discovered git repositories
repositories[].namestringRepository name (directory name)
repositories[].pathstringAbsolute path to repository
repositories[].gitPathstringPath to .git directory
repositories[].isSubmodulebooleanIs a git submodule
repositories[].branchstringCurrent branch
repositories[].hasUncommittedChangesbooleanHas uncommitted changes
repositories[].hasUnpushedCommitsbooleanHas unpushed commits
repositories[].remotesarrayConfigured git remotes
repositories[].lastCommitobjectMost recent commit info
totalFoundintegerTotal repositories found
searchDepthintegerDepth of search performed
searchDurationintegerSearch duration in milliseconds

Use Cases

Project Selection

Use filesystem browsing to help users select a git repository when creating a new Forge project:
// 1. List user's common project directories
const dirs = await forge.filesystem.list({
  path: '/home/user/projects'
});

// 2. Find git repositories
const repos = await forge.filesystem.gitRepos({
  path: '/home/user/projects',
  maxDepth: 2
});

// 3. Present repos to user for selection
repos.repositories.forEach(repo => {
  console.log(`${repo.name} - ${repo.branch} (${repo.lastCommit.message})`);
});

Repository Discovery

Automatically discover all git repositories on the system:
// Search common locations
const searchPaths = [
  '/home/user/projects',
  '/home/user/Documents/code',
  '/workspace'
];

const allRepos = [];
for (const path of searchPaths) {
  const result = await forge.filesystem.gitRepos({ path });
  allRepos.push(...result.repositories);
}

console.log(`Found ${allRepos.length} repositories`);

File Browser

Build a file browser interface for selecting files to include in task context:
async function browseDirectory(path, depth = 0) {
  const result = await forge.filesystem.list({
    path,
    showHidden: false
  });

  result.entries.forEach(entry => {
    const indent = '  '.repeat(depth);
    const icon = entry.type === 'directory' ? '📁' : '📄';
    const gitBadge = entry.isGitRepo ? ' [GIT]' : '';

    console.log(`${indent}${icon} ${entry.name}${gitBadge}`);
  });
}

SDK Examples

JavaScript/TypeScript

import { ForgeClient } from '@automagik/forge-sdk';

const forge = new ForgeClient();

// List directory contents
const contents = await forge.filesystem.list({
  path: '/home/user/projects',
  showHidden: false,
  recursive: false
});

console.log(`Found ${contents.directories} directories and ${contents.files} files`);

// Find all git repositories
const repos = await forge.filesystem.gitRepos({
  path: '/home/user',
  maxDepth: 3,
  includeSubmodules: true
});

repos.repositories.forEach(repo => {
  console.log(`${repo.name}: ${repo.branch}`);
  if (repo.hasUncommittedChanges) {
    console.log('  ⚠️  Uncommitted changes');
  }
  if (repo.hasUnpushedCommits) {
    console.log('  📤 Unpushed commits');
  }
});

// Recursive directory listing
const tree = await forge.filesystem.list({
  path: '/home/user/my-project',
  recursive: true,
  maxDepth: 3
});

Python

from automagik_forge import ForgeClient

forge = ForgeClient()

# List directory
contents = forge.filesystem.list(
    path='/home/user/projects',
    show_hidden=False
)

print(f"Found {contents['directories']} directories")

# Find git repositories
repos = forge.filesystem.git_repos(
    path='/home/user',
    max_depth=3
)

for repo in repos['repositories']:
    print(f"{repo['name']}: {repo['branch']}")
    if repo['hasUncommittedChanges']:
        print("  ⚠️  Uncommitted changes")

Security Considerations

Path Traversal Protection: The Filesystem API includes built-in protection against path traversal attacks. Requests attempting to access paths outside allowed directories will be rejected.

Allowed Directories

By default, filesystem access is restricted to:
  • User’s home directory
  • Common project directories (~/projects, ~/Documents, ~/workspace)
  • Directories explicitly added to Forge projects

Blocked Paths

The following paths are always blocked:
  • /etc - System configuration
  • /var - System variables
  • /sys - System files
  • /proc - Process information
  • Root filesystem access (requires explicit configuration)

Configuration

Customize allowed paths in Forge configuration:
{
  "filesystem": {
    "allowedPaths": [
      "/home/user/projects",
      "/workspace",
      "/custom/path"
    ],
    "blockedPaths": [
      "/home/user/secrets",
      "/home/user/.ssh"
    ]
  }
}

Error Responses

Path Not Found

{
  "success": false,
  "error": {
    "code": "PATH_NOT_FOUND",
    "message": "Path '/nonexistent/path' does not exist"
  }
}

Access Denied

{
  "success": false,
  "error": {
    "code": "ACCESS_DENIED",
    "message": "Access to path '/etc/passwd' is not allowed"
  }
}

Not a Directory

{
  "success": false,
  "error": {
    "code": "NOT_A_DIRECTORY",
    "message": "Path '/home/user/file.txt' is not a directory"
  }
}

Next Steps