# How to View Directory Contents Using Bash: The `ls` Command and pi‑web API Integration

> Learn the bash command ls -la to view directory contents, including hidden files in long format. Explore pi-web API integration for enhanced file management.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: how-to-guide
- Published: 2026-08-11

---

**The standard Bash command to view directory contents is `ls -la`, which lists all files including hidden ones in long format.**

The **pi‑web** repository provides a full‑stack filesystem browser that mirrors this experience through a secure REST API. While the classic `ls` command remains essential for server‑side debugging, the application's TypeScript architecture—enforced through [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) and [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts)—ensures that web‑based directory listings follow identical security constraints.

## Why `ls` Still Matters in Modern Web Applications

Even with sophisticated frontend explorers, developers need reliable Bash tools for local verification. The `ls` command provides immediate, unfiltered visibility into the filesystem state, which proves invaluable when troubleshooting path permissions or verifying that directories are correctly registered in the allow‑list.

## The Core `ls` Command Syntax

### Basic Directory Listing

```bash
ls /path/to/directory

```

This displays visible filenames only.

### Detailed Listing with Hidden Files

```bash
ls -la /path/to/your/project

```

| Flag | Purpose |
|------|---------|
| `-l` | Long format showing permissions, owner, size, and timestamp |
| `-a` | Include hidden files (dot‑files) |

**Note:** The pi‑web API filters hidden files by default unless explicitly allowed in the security configuration.

## How pi‑web Mirrors `ls` Through Its API

The application exposes directory contents via HTTP while enforcing the same filesystem boundaries. The request flow in `app/api/files/[...path]/route.ts` handles this translation:

1. Extract encoded path from URL segment
2. Decode to native OS path via [`lib/file-paths.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-paths.ts)
3. Validate against allow‑list in [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) using `isFilePathAllowed()` from [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts)
4. Call Node's `fs.readdir` and serialize entries
5. Return JSON array matching `ls -l` metadata

### Fetch Directory Contents via API

```bash
curl http://localhost:30141/api/files/path/to/your/project

```

**Sample response:**

```json
[
  {"name":"src","isDirectory":true,"size":0,"mtime":"2024-10-12T08:15:30.000Z"},
  {"name":"package.json","isDirectory":false,"size":1234,"mtime":"2024-10-10T14:02:11.000Z"}
]

```

## Key Source Files and Responsibilities

| File | Role |
|------|------|
| `app/api/files/[...path]/route.ts` | HTTP route handler for `GET /api/files/[…path]` |
| [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) | Maintains allow‑list of roots: session cwd, project root, `~/pi‑cwd‑*` |
| [`lib/file-paths.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-paths.ts) | URL encoding/decoding with Windows case‑folding support |
| [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts) | Path traversal prevention via `isFilePathAllowed()` |
| [`components/FileExplorer.tsx`](https://github.com/agegr/pi-web/blob/main/components/FileExplorer.tsx) | React UI that consumes the API and renders directory trees |

## Extending the Allow‑List Programatically

To expose a new directory through both `ls` and the API:

```ts
import { addFileRoot } from '@/lib/file-access';

await addFileRoot('/mnt/shared/data');

```

After execution, `ls /mnt/shared/data` and the API endpoint return consistent results.

## Frontend Integration

The `FileExplorer` component handles API consumption internally:

```tsx
import { FileExplorer } from '@/components/FileExplorer';

export default function Sidebar() {
  return <FileExplorer cwd="/path/to/your/project" />;
}

```

## Summary

- **Use `ls -la`** for immediate, complete directory inspection on the server
- The **pi‑web API** at `/api/files/[…path]` exposes the same data over HTTP with JSON formatting
- **Security enforcement** in [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts) guarantees that API and Bash views respect identical filesystem boundaries
- **File paths** are normalized through [`lib/file-paths.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-paths.ts) to handle cross‑platform differences
- **Adding roots** via `addFileRoot()` in [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) updates both interfaces simultaneously

## Frequently Asked Questions

### What is the difference between `ls` and the pi‑web API for viewing directory contents?

`ls` is a native Bash command that executes directly on the filesystem, showing all files including hidden ones and permission bits. The pi‑web API provides a JSON‑serialized view over HTTP, applying security filters from [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts) and excluding dot‑files by default. Both access the same underlying directories, but the API adds network accessibility and access control.

### How does pi‑web prevent directory traversal attacks when listing files?

The `isFilePathAllowed()` function in [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts) re‑normalizes both the requested path and the configured allow‑list before comparison. This occurs in [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) before any `fs.readdir` call executes, ensuring only explicitly permitted roots are exposed through the API.

### Can I use wildcards with `ls` for filtered directory views?

Yes. Bash globbing works with `ls`, such as `ls -la /path/*.json` for JSON files only. The pi‑web API does not support server‑side filtering by pattern; implement client‑side filtering on the returned JSON array instead.

### Why does the API hide hidden files when `ls -la` shows them?

The API filters dot‑files as a security default. To expose hidden files through the API, modify the allow‑list configuration in [`lib/file-access.ts`](https://github.com/agegr/pi-web/blob/main/lib/file-access.ts) or add explicit patterns to the security policy in [`lib/path-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/path-security.ts).