---
name: workspace-filesystem
description: The virtual filesystem layout of this workspace.
---
# Virtual Filesystem
| Path | Description |
| --- | --- |
| `/<path>` | `linear`, read |
## VFS Layout
### `/<path>`
```text
/<path>
teams/
<team-key>__<team-name>__<team-id>/
team.json
members/
<display-name>__<user-id>.json
issues/
<issue-key>__<issue-id>/
issue.json
comments.jsonl
projects/
<name>__<project-id>.json
cycles/
<name>__<cycle-id>.json
documents/
<title>__<document-id>.json
```
- `ls` directories first to discover exact names.
- Every entity-named segment is `<sanitized-human-readable>__<id>`. The
human-readable part is sanitized, so don't construct it; `ls` the
parent directory instead.
- The id is the last `__`-separated segment:
```text
/<path>/teams/STR__Strukto-ai__<team-id>/ -> <team-id>
/<path>/teams/.../issues/STR-42__<issue-id>/ -> <issue-id>
/<path>/teams/.../members/Alice__<user-id>.json -> <user-id>
```
All `cat` output is normalized by Mirage (snake_case keys), not the raw
Linear GraphQL response. The shapes:
`team.json`:
```jsonc
{
"team_id": "...", "team_key": "STR", "team_name": "Strukto",
"name": "...", "description": "...", "timezone": "...",
"updated_at": "...",
"states": [
{ "state_id": "...", "state_name": "Todo", "type": "unstarted" },
... // one element per workflow state
]
}
```
`issue.json`:
```jsonc
{
"issue_id": "...", "issue_key": "STR-42",
"title": "...", "description": "...",
"team_id": "...", "team_key": "...", "team_name": "...",
"project_id": "...", "project_name": "...",
"cycle_id": "...", "cycle_name": "...", "cycle_number": 7,
"state_id": "...", "state_name": "In Progress",
"assignee_id": "...", "assignee_email": "...", "assignee_name": "...",
"creator_id": "...", "creator_email": "...", "creator_name": "...",
"priority": 2, // 0=none 1=urgent 2=high 3=medium 4=low
"label_ids": ["..."],
"label_names": ["bug", "frontend"],
"created_at": "...", "updated_at": "...", "url": "..."
}
```
`comments.jsonl`, one normalized comment per line:
```jsonc
{ "comment_id": "...", "issue_id": "...", "issue_key": "STR-42",
"user_id": "...", "user_email": "...", "user_name": "...",
"body": "...", "created_at": "...", "updated_at": "...",
"url": "..." }
```
A project (`projects/<name>__<project-id>.json`):
```jsonc
{
"project_id": "...", "team_id": "...",
"name": "...", "description": "...", "state": "started",
"lead_id": "...", "updated_at": "...", "url": "...",
"issue_count": 12,
"issues": [
{ "issue_id": "...", "issue_key": "STR-42", "title": "...",
"state_id": "...", "state_name": "In Progress", "url": "..." }
]
}
```
A cycle (`cycles/<name>__<cycle-id>.json`):
```jsonc
{
"cycle_id": "...", "team_id": "...",
"name": "...", "number": 7,
"starts_at": "...", "ends_at": "...",
"updated_at": "...", "url": "..."
}
```
A member (`members/<display-name>__<user-id>.json`):
```jsonc
{
"user_id": "...", "name": "...", "display_name": "...",
"email": "...", "is_active": true, "is_admin": false,
"updated_at": "...", "url": "..."
}
```
A document (`documents/<title>__<document-id>.json`):
```jsonc
{
"document_id": "...", "title": "...", "content": "...",
"project_id": "...", "project_name": "...",
"creator_id": "...", "creator_name": "...", "creator_email": "...",
"created_at": "...", "updated_at": "...", "url": "..."
}
```
Useful `jq` paths:
```jq
.issue_key # issue.json
.state_name # issue.json
.assignee_email # issue.json
.label_names[] # issue.json
.issues[] | select(.state_name == "In Progress") # a project
.states[].state_name # team.json
[inputs] | length # comments.jsonl: count
[inputs | select(.user_email == "x")] | length # comments.jsonl
```
To act on issues (list, get, create, update, assign, transition,
comments, projects, cycles, labels, users, documents, search), use the
`linear` CLI if installed (`linear --help`).
## Supported Unix Commands for VFS
Unix commands work on each path as on a local filesystem, as far as the path supports them:
| Path | Supported |
| --- | --- |
| `/<path>` | Commands that read files (`ls`, `cat`, `grep`, `find`, `jq` and the rest). `grep -r` and `rg` ask `linear` which files may match. |
## Limitations of Unix Commands for VFS
Where a path differs from a local filesystem:
| Path | Limitations |
| --- | --- |
| `/<path>` | Read only: no command changes files. `linear` answers only for `teams/*/issues/*/issue.json`, `teams/*/members/*`, `teams/*/projects/*`, `teams/*/cycles/*` and `teams/*/documents/*`; `grep -r` and `rg` read every other file. `grep -r`, `find` and `du` stop after 1000 files; a glob matching more, `tar -c`, `cp -r` and `rm -r` are refused. |
Run `man <cmd>` or `<cmd> --help` for one command's usage.