bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
393 lines
12 KiB
Plaintext
393 lines
12 KiB
Plaintext
---
|
|
title: Linear
|
|
description: Mount Linear workspaces, teams, projects, issues, and comments as a Mirage filesystem for Python agents.
|
|
icon: chart-gantt
|
|
---
|
|
The Linear resource exposes Linear workspace data as a virtual filesystem
|
|
mounted at some prefix such as `/linear/`.
|
|
|
|
For API key setup, see [Linear Setup](/python/setup/linear).
|
|
|
|
## Config
|
|
|
|
```python
|
|
import os
|
|
|
|
from mirage import MountMode, Workspace
|
|
from mirage.resource.linear import LinearConfig, LinearResource
|
|
|
|
config = LinearConfig(api_key=os.environ["LINEAR_API_KEY"])
|
|
resource = LinearResource(config=config)
|
|
ws = Workspace({"/linear": resource}, mode=MountMode.READ)
|
|
```
|
|
|
|
## Filesystem Layout
|
|
|
|
```text
|
|
/linear/
|
|
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
|
|
...
|
|
```
|
|
|
|
Example:
|
|
|
|
```text
|
|
/linear/
|
|
teams/
|
|
ENG__Engineering__abc123def/
|
|
team.json
|
|
members/
|
|
alice__usr_001.json
|
|
bob__usr_002.json
|
|
issues/
|
|
ENG-123__iss_001/
|
|
issue.json
|
|
comments.jsonl
|
|
ENG-124__iss_002/
|
|
issue.json
|
|
comments.jsonl
|
|
projects/
|
|
Mirage__proj_001.json
|
|
cycles/
|
|
Sprint-12__cyc_001.json
|
|
```
|
|
|
|
Directory and file names embed the Linear ID after `__` so that
|
|
resource-specific commands can reference the correct resource without
|
|
extra lookups.
|
|
|
|
### Teams
|
|
|
|
Each team directory is named:
|
|
|
|
```text
|
|
<team-key>__<team-name>__<team-id>
|
|
```
|
|
|
|
Inside the team directory:
|
|
|
|
- `team.json` is the normalized team metadata
|
|
- `members/` contains one JSON file per member
|
|
- `issues/` contains one directory per issue
|
|
- `projects/` contains one JSON file per project, including lightweight
|
|
related issue references
|
|
- `cycles/` contains one JSON file per cycle
|
|
|
|
### Issues
|
|
|
|
Each issue directory is named:
|
|
|
|
```text
|
|
<issue-key>__<issue-id>
|
|
```
|
|
|
|
Each issue directory contains:
|
|
|
|
- `issue.json` -- normalized issue metadata with command-aligned fields such as
|
|
`issue_id`, `issue_key`, `team_id`, `state_id`, and `assignee_id`
|
|
- `comments.jsonl` -- normalized comment stream ordered by `created_at`
|
|
|
|
`comments.jsonl` is a Mirage representation chosen for shell-friendly
|
|
workflows. It is not a native Linear file format.
|
|
|
|
### Members
|
|
|
|
Each member file is named:
|
|
|
|
```text
|
|
<display-name>__<user-id>.json
|
|
```
|
|
|
|
Member JSON includes command-aligned identifiers such as `user_id` and `email`
|
|
so the value can be reused directly in commands like `linear-issue-assign`.
|
|
|
|
### Projects and Cycles
|
|
|
|
Project and cycle files are named:
|
|
|
|
```text
|
|
<name>__<id>.json
|
|
```
|
|
|
|
Project JSON includes lightweight related issue references. Cycle JSON
|
|
includes cycle metadata such as start and end dates.
|
|
|
|
## Cache
|
|
|
|
The Linear resource uses `IndexCacheStore` (same as Discord and other
|
|
resources). There is no separate content cache -- file content caching
|
|
is handled by the workspace `IOResult` mechanism.
|
|
|
|
## Example
|
|
|
|
See `examples/linear/linear.py` for the full working example.
|
|
|
|
```bash
|
|
# List teams
|
|
ls /linear/teams/
|
|
|
|
# Read team metadata
|
|
cat /linear/teams/ENG__Engineering__abc123/team.json
|
|
|
|
# List issues
|
|
ls /linear/teams/ENG__Engineering__abc123/issues/
|
|
|
|
# Read an issue
|
|
cat /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/issue.json
|
|
|
|
# Read issue comments
|
|
cat /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/comments.jsonl
|
|
|
|
# Extract issue ID with jq
|
|
cat /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/issue.json \
|
|
| jq '.issue_id'
|
|
|
|
# Read last 5 comments
|
|
tail -n 5 /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/comments.jsonl
|
|
|
|
# List members
|
|
ls /linear/teams/ENG__Engineering__abc123/members/
|
|
|
|
# Read a project with its issues
|
|
cat /linear/teams/ENG__Engineering__abc123/projects/Mirage__proj_001.json \
|
|
| jq '.issues'
|
|
|
|
# Tree view
|
|
tree -L 2 /linear/teams/
|
|
```
|
|
|
|
## Finding IDs
|
|
|
|
IDs are embedded in directory and file names after `__`:
|
|
|
|
```bash
|
|
# Team ID -- embedded in directory name
|
|
ls /linear/teams/
|
|
# -> ENG__Engineering__abc123 <- team_id = abc123
|
|
|
|
# Issue ID -- embedded in issue directory name
|
|
ls /linear/teams/ENG__Engineering__abc123/issues/
|
|
# -> ENG-123__iss_001 <- issue_id = iss_001
|
|
|
|
# Member ID -- embedded in member file name
|
|
ls /linear/teams/ENG__Engineering__abc123/members/
|
|
# -> alice__usr_001.json <- user_id = usr_001
|
|
|
|
# Use stat for structured metadata
|
|
stat /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/issue.json
|
|
|
|
# Extract fields with jq
|
|
cat /linear/teams/ENG__Engineering__abc123/issues/ENG-123__iss_001/issue.json \
|
|
| jq '{issue_id, issue_key, team_id, state_id, assignee_id}'
|
|
```
|
|
|
|
## Shell Commands
|
|
|
|
Standard commands available on the mounted Linear tree:
|
|
|
|
| Command | Notes |
|
|
| --------------- | ------------------------------------------ |
|
|
| `ls` | List teams, issues, members, projects |
|
|
| `cat` | Read .json metadata or .jsonl comments |
|
|
| `head` / `tail` | First/last N lines |
|
|
| `grep` / `rg` | Pattern search (file or directory level) |
|
|
| `jq` | Query JSON fields |
|
|
| `wc` | Line/word/byte counts |
|
|
| `stat` | File metadata (name, size, type) |
|
|
| `find` | Recursive search with `-name`, `-maxdepth` |
|
|
| `tree` | Directory tree view |
|
|
| `basename` | Extract file name from path |
|
|
| `dirname` | Extract directory from path |
|
|
| `realpath` | Resolve path to absolute form |
|
|
|
|
## Resource-Specific Commands
|
|
|
|
### `linear-issue-create`
|
|
|
|
Create a new issue. Description can be passed via `--description`, `--description_file`, or stdin.
|
|
|
|
```bash
|
|
linear-issue-create --team_key ENG --title "New bug"
|
|
linear-issue-create --team_id abc123 --title "New bug" --description "Details here"
|
|
cat brief.md | linear-issue-create --team_key ENG --title "Agent bug"
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| -------------------- | -------- | ----------------------------------- |
|
|
| `--team_id` | \* | Linear team ID |
|
|
| `--team_key` | \* | Linear team key (e.g. ENG) |
|
|
| `--title` | yes | Issue title |
|
|
| `--description` | no | Inline description text |
|
|
| `--description_file` | no | Path to file containing description |
|
|
|
|
\* One of `--team_id` or `--team_key` is required.
|
|
|
|
### `linear-issue-update`
|
|
|
|
Update an existing issue. Description can be passed via `--description`, `--description_file`, or stdin.
|
|
|
|
```bash
|
|
linear-issue-update --issue_key ENG-123 --title "Updated title"
|
|
linear-issue-update --issue_id iss_001 --description "New description"
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| -------------------- | -------- | ----------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--title` | no | New title |
|
|
| `--description` | no | Inline description text |
|
|
| `--description_file` | no | Path to file containing description |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
|
|
### `linear-issue-assign`
|
|
|
|
Assign an issue to a user.
|
|
|
|
```bash
|
|
linear-issue-assign --issue_key ENG-123 --assignee_email "alice@example.com"
|
|
linear-issue-assign --issue_id iss_001 --assignee_id usr_001
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| ------------------ | -------- | ------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--assignee_id` | \*\* | Linear user ID |
|
|
| `--assignee_email` | \*\* | User email address |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
\*\* One of `--assignee_id` or `--assignee_email` is required.
|
|
|
|
### `linear-issue-transition`
|
|
|
|
Transition an issue to a different workflow state.
|
|
|
|
```bash
|
|
linear-issue-transition --issue_key ENG-123 --state_name "In Progress"
|
|
linear-issue-transition --issue_id iss_001 --state_id state_001
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| -------------- | -------- | ------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--state_id` | \*\* | Linear workflow state ID |
|
|
| `--state_name` | \*\* | Workflow state name |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
\*\* One of `--state_id` or `--state_name` is required.
|
|
|
|
### `linear-issue-set-priority`
|
|
|
|
Set the priority of an issue.
|
|
|
|
```bash
|
|
linear-issue-set-priority --issue_key ENG-123 --priority 1
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| ------------- | -------- | ---------------------------------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--priority` | yes | Priority level (0=none, 1=urgent, 2=high, 3=medium, 4=low) |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
|
|
### `linear-issue-set-project`
|
|
|
|
Assign an issue to a project.
|
|
|
|
```bash
|
|
linear-issue-set-project --issue_key ENG-123 --project_id proj_001
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| -------------- | -------- | ------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--project_id` | yes | Linear project ID |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
|
|
### `linear-issue-add-label`
|
|
|
|
Add a label to an issue.
|
|
|
|
```bash
|
|
linear-issue-add-label --issue_key ENG-123 --label_id lbl_001
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| ------------- | -------- | ------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--label_id` | yes | Linear label ID |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
|
|
### `linear-issue-comment-add`
|
|
|
|
Add a comment to an issue. Body can be passed via `--body`, `--body_file`, or stdin.
|
|
|
|
```bash
|
|
linear-issue-comment-add --issue_key ENG-123 --body "Looks good"
|
|
cat note.md | linear-issue-comment-add --issue_key ENG-123
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| ------------- | -------- | ------------------------------- |
|
|
| `--issue_id` | \* | Linear issue ID |
|
|
| `--issue_key` | \* | Linear issue key (e.g. ENG-123) |
|
|
| `--body` | \*\* | Inline comment text |
|
|
| `--body_file` | \*\* | Path to file containing body |
|
|
|
|
\* One of `--issue_id` or `--issue_key` is required.
|
|
\*\* One of `--body`, `--body_file`, or stdin is required.
|
|
|
|
### `linear-issue-comment-update`
|
|
|
|
Update an existing comment. Body can be passed via `--body`, `--body_file`, or stdin.
|
|
|
|
```bash
|
|
linear-issue-comment-update --comment_id cmt_001 --body "Updated text"
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| -------------- | -------- | ---------------------------- |
|
|
| `--comment_id` | yes | Linear comment ID |
|
|
| `--body` | \*\* | Inline comment text |
|
|
| `--body_file` | \*\* | Path to file containing body |
|
|
|
|
\*\* One of `--body`, `--body_file`, or stdin is required.
|
|
|
|
### `linear-search`
|
|
|
|
Search issues across the workspace.
|
|
|
|
```bash
|
|
linear-search --query "authentication bug"
|
|
```
|
|
|
|
| Option | Required | Description |
|
|
| --------- | -------- | ----------------- |
|
|
| `--query` | yes | Search query text |
|
|
|
|
Returns matching issues as a JSON array.
|