linmux 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/bin/run.js +4 -0
- package/dist/commands/comment/create.js +94 -0
- package/dist/commands/comment/delete.js +74 -0
- package/dist/commands/comment/list.js +84 -0
- package/dist/commands/comment/update.js +80 -0
- package/dist/commands/cycle/current.js +78 -0
- package/dist/commands/cycle/list.js +84 -0
- package/dist/commands/cycle/move.js +91 -0
- package/dist/commands/describe.js +65 -0
- package/dist/commands/graphql/index.js +92 -0
- package/dist/commands/install-skill.js +54 -0
- package/dist/commands/issue/archive.js +75 -0
- package/dist/commands/issue/create.js +115 -0
- package/dist/commands/issue/get.js +84 -0
- package/dist/commands/issue/list.js +93 -0
- package/dist/commands/issue/purge.js +81 -0
- package/dist/commands/issue/search.js +109 -0
- package/dist/commands/issue/transition.js +91 -0
- package/dist/commands/issue/trash.js +75 -0
- package/dist/commands/issue/update.js +126 -0
- package/dist/commands/label/create.js +91 -0
- package/dist/commands/label/list.js +76 -0
- package/dist/commands/list-tools.js +47 -0
- package/dist/commands/me.js +71 -0
- package/dist/commands/project/create.js +101 -0
- package/dist/commands/project/get.js +83 -0
- package/dist/commands/project/list.js +75 -0
- package/dist/commands/project/update-status.js +99 -0
- package/dist/commands/project/update.js +99 -0
- package/dist/commands/raw/batch.js +85 -0
- package/dist/commands/raw/index.js +72 -0
- package/dist/commands/schema.js +69 -0
- package/dist/commands/state/list.js +77 -0
- package/dist/commands/team/get.js +73 -0
- package/dist/commands/team/list.js +73 -0
- package/dist/commands/whoami.js +71 -0
- package/dist/commands/workspace/add.js +97 -0
- package/dist/commands/workspace/list.js +47 -0
- package/dist/commands/workspace/remove.js +63 -0
- package/dist/commands/workspace/replace-token.js +89 -0
- package/dist/commands/workspace/use.js +54 -0
- package/dist/core/client/factory.js +28 -0
- package/dist/core/client/index.js +2 -0
- package/dist/core/config/index.js +4 -0
- package/dist/core/config/paths.js +30 -0
- package/dist/core/config/schema.js +36 -0
- package/dist/core/config/store.js +149 -0
- package/dist/core/errors/error.js +142 -0
- package/dist/core/errors/exit-codes.js +70 -0
- package/dist/core/output/envelope.js +53 -0
- package/dist/core/output/format.js +42 -0
- package/dist/core/output/index.js +3 -0
- package/dist/core/pagination/flags.js +29 -0
- package/dist/core/pagination/index.js +2 -0
- package/dist/core/projection/presets.js +116 -0
- package/dist/core/projection/project.js +282 -0
- package/dist/core/redact/redact.js +45 -0
- package/dist/core/resolvers/cycle.js +60 -0
- package/dist/core/resolvers/index.js +7 -0
- package/dist/core/resolvers/label.js +54 -0
- package/dist/core/resolvers/project-status.js +42 -0
- package/dist/core/resolvers/project.js +43 -0
- package/dist/core/resolvers/state.js +46 -0
- package/dist/core/resolvers/team.js +50 -0
- package/dist/core/transport/fetch-interceptor.js +109 -0
- package/dist/core/transport/index.js +3 -0
- package/dist/core/transport/rate-limit.js +167 -0
- package/dist/core/workspace/resolver.js +70 -0
- package/dist/core/workspace/write-guard.js +43 -0
- package/dist/generated/graphql.js +89428 -0
- package/dist/generated/operations.js +3013 -0
- package/dist/lib/comment-create-runtime.js +96 -0
- package/dist/lib/comment-delete-runtime.js +46 -0
- package/dist/lib/comment-list-runtime.js +182 -0
- package/dist/lib/comment-update-runtime.js +93 -0
- package/dist/lib/cycle-current-runtime.js +90 -0
- package/dist/lib/cycle-list-runtime.js +151 -0
- package/dist/lib/cycle-move-runtime.js +142 -0
- package/dist/lib/describe-runtime.js +180 -0
- package/dist/lib/filter-heuristics.js +59 -0
- package/dist/lib/graphql-runtime.js +202 -0
- package/dist/lib/include-fragments.js +73 -0
- package/dist/lib/install-skill-runtime.js +228 -0
- package/dist/lib/introspection-registry.js +488 -0
- package/dist/lib/issue-archive-runtime.js +89 -0
- package/dist/lib/issue-create-runtime.js +175 -0
- package/dist/lib/issue-get-runtime.js +153 -0
- package/dist/lib/issue-list-runtime.js +164 -0
- package/dist/lib/issue-purge-runtime.js +89 -0
- package/dist/lib/issue-search-runtime.js +114 -0
- package/dist/lib/issue-transition-runtime.js +131 -0
- package/dist/lib/issue-trash-runtime.js +84 -0
- package/dist/lib/issue-update-runtime.js +164 -0
- package/dist/lib/label-create-runtime.js +113 -0
- package/dist/lib/label-list-runtime.js +97 -0
- package/dist/lib/levenshtein.js +42 -0
- package/dist/lib/list-tools-runtime.js +38 -0
- package/dist/lib/me-runtime.js +55 -0
- package/dist/lib/project-create-runtime.js +103 -0
- package/dist/lib/project-get-runtime.js +134 -0
- package/dist/lib/project-list-runtime.js +84 -0
- package/dist/lib/project-update-runtime.js +110 -0
- package/dist/lib/project-update-status-runtime.js +91 -0
- package/dist/lib/raw-batch-runtime.js +229 -0
- package/dist/lib/raw-runtime.js +171 -0
- package/dist/lib/schema-loader.js +41 -0
- package/dist/lib/schema-runtime.js +65 -0
- package/dist/lib/state-list-runtime.js +93 -0
- package/dist/lib/team-get-runtime.js +55 -0
- package/dist/lib/team-list-runtime.js +52 -0
- package/dist/lib/workspace-runtime.js +112 -0
- package/dist/operations/_registry.zod.js +5337 -0
- package/oclif.manifest.json +3631 -0
- package/package.json +99 -0
- package/schema.graphql +30772 -0
- package/skills/linmux/SKILL.md +186 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: linmux
|
|
3
|
+
description: Operate Linear across all your workspaces from any agent that can shell out — the full GraphQL surface (~500 ops), multiple workspaces in one session, and stable versioned JSON. Use when the user asks about Linear issues, projects, cycles, comments, teams, labels, or workflow states, or wants to query/mutate Linear via CLI — especially when more than one Linear workspace is in play.
|
|
4
|
+
compatibility: Requires Node 22+ and a Linear API key (LINEAR_API_KEY env var or `linmux workspace add`).
|
|
5
|
+
metadata:
|
|
6
|
+
version: "0.1.0"
|
|
7
|
+
homepage: "https://github.com/ChuckMayo/linear-multi-workspace-cli"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# linmux
|
|
11
|
+
|
|
12
|
+
One CLI that drives **every** Linear operation across **all** your workspaces — the full GraphQL surface (~500 ops), multiple workspaces in a single session, JSON by default for agents.
|
|
13
|
+
|
|
14
|
+
Pinned version: `0.1.0`. Always invoke as `npx -y linmux@0.1.0 <command>`. Never the floating dist-tag — agents must pin so a registry update doesn't silently change the contract mid-session.
|
|
15
|
+
|
|
16
|
+
## When to invoke
|
|
17
|
+
|
|
18
|
+
Invoke `linmux` when the user wants to read or write Linear data and you can shell out. It shines when more than one Linear workspace is in play — each command resolves its workspace independently, so a single session can touch several. Trigger phrases include:
|
|
19
|
+
|
|
20
|
+
- "create / update / archive / list / search / get an issue"
|
|
21
|
+
- "add a comment", "find issues in <team>", "what's in cycle <n>"
|
|
22
|
+
- "create / update a project", "set project status"
|
|
23
|
+
- "list teams / labels / workflow states / cycles"
|
|
24
|
+
- "who am I" / "what workspace am I in" (use `me` or `whoami`)
|
|
25
|
+
- Anything spanning two workspaces ("compare my open issues in acme vs personal")
|
|
26
|
+
- Any GraphQL query a curated command doesn't cover — fall back to the raw layer
|
|
27
|
+
|
|
28
|
+
You do NOT need to ask the user for permission to call a read-only command (`*list*`, `*get*`, `*search*`, `me`, `whoami`, `describe`, `list-tools`, `schema`). For write commands (create/update/delete/archive/trash/transition/purge), confirm intent first unless the user has clearly asked for the write.
|
|
29
|
+
|
|
30
|
+
## Auth setup
|
|
31
|
+
|
|
32
|
+
`linmux` reads its Linear API key from one of two sources, in this order:
|
|
33
|
+
|
|
34
|
+
1. **Per-shell env var** (preferred for CI / one-shot invocations):
|
|
35
|
+
```
|
|
36
|
+
export LINEAR_API_KEY=lin_api_...
|
|
37
|
+
npx -y linmux@0.1.0 me --json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. **Persistent workspace registry** (preferred for interactive use, supports multiple workspaces):
|
|
41
|
+
```
|
|
42
|
+
npx -y linmux@0.1.0 workspace add acme --token lin_api_...
|
|
43
|
+
npx -y linmux@0.1.0 workspace add personal --token lin_api_...
|
|
44
|
+
npx -y linmux@0.1.0 workspace use acme
|
|
45
|
+
npx -y linmux@0.1.0 me --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The workspace name is a positional argument (`workspace add <name> --token ...`). Every command accepts `--workspace <name>` to target a specific registered workspace without changing the active default — that is how one session drives several workspaces:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
npx -y linmux@0.1.0 issue list --workspace acme --team ENG --json
|
|
52
|
+
npx -y linmux@0.1.0 issue list --workspace personal --team SIDE --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Tokens are stored at `$XDG_CONFIG_HOME/linear-agent/config.json`, default `~/.config/linear-agent/config.json` (the directory name predates the `linmux` rename), written with mode 0600. Personal API keys only — no OAuth in v1.
|
|
56
|
+
|
|
57
|
+
If neither source is set, every command exits with `WORKSPACE_NOT_RESOLVED` (exit 10). Run `linmux workspace list` to see what's registered.
|
|
58
|
+
|
|
59
|
+
## JSON-by-default contract
|
|
60
|
+
|
|
61
|
+
Every command emits a versioned envelope on stdout. **Pass `--json` for machine output** — pretty/human output is on by default but agents should always use `--json`.
|
|
62
|
+
|
|
63
|
+
Success envelope (locked key order):
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"$apiVersion": "1",
|
|
67
|
+
"ok": true,
|
|
68
|
+
"data": { /* command-specific payload */ },
|
|
69
|
+
"meta": { "command": "issue list", "workspace": "acme" }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Failure envelope:
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"$apiVersion": "1",
|
|
77
|
+
"ok": false,
|
|
78
|
+
"error": {
|
|
79
|
+
"code": "VALIDATION_FAILED",
|
|
80
|
+
"message": "Title is required",
|
|
81
|
+
"transient": false,
|
|
82
|
+
"details": { "field": "title" }
|
|
83
|
+
},
|
|
84
|
+
"meta": { "command": "issue create" }
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`ok: true` ⇒ exit 0. `ok: false` ⇒ exit > 0 (taxonomy below). The `data` payload shape is stable per command — pin tests against `data.*` paths, not human prose. The `meta.workspace` field tells you which workspace served the call — check it when working across several.
|
|
89
|
+
|
|
90
|
+
## Curated commands quick-reference
|
|
91
|
+
|
|
92
|
+
Top-of-funnel commands (one line each). Run `npx -y linmux@0.1.0 describe <command>` for full flag schema, or `npx -y linmux@0.1.0 list-tools` for the full inventory.
|
|
93
|
+
|
|
94
|
+
| Command | Purpose |
|
|
95
|
+
|---------|---------|
|
|
96
|
+
| `me --json` | Fetch viewer + organization (auth probe). |
|
|
97
|
+
| `whoami --json` | Active workspace + user identity. |
|
|
98
|
+
| `issue list --team <slug> --json` | Page through issues in a team. |
|
|
99
|
+
| `issue get <id> --json` | Fetch one issue by identifier (e.g. `ENG-123`). |
|
|
100
|
+
| `issue search "<query>" --json` | Full-text search. |
|
|
101
|
+
| `issue create --team <slug> --title "..." [--description "..." --state <name> --assignee <email> --labels <l1,l2>] --json` | Create. |
|
|
102
|
+
| `issue update <id> [--title --description --state --assignee --labels] --json` | Patch fields. |
|
|
103
|
+
| `issue transition <id> --state <name> --json` | Move to a workflow state. |
|
|
104
|
+
| `issue archive <id> --json` / `issue trash <id> --json` / `issue purge <id> --json` | Lifecycle ops (require confirmation). |
|
|
105
|
+
| `comment create --issue <id> --body "..." --json` | Add a comment. |
|
|
106
|
+
| `comment list --issue <id> --json` | List comments on an issue. |
|
|
107
|
+
| `project list [--team <slug>] --json` | List projects (optionally team-scoped). |
|
|
108
|
+
| `project create --team <slug> --name "..." [--description ...] --json` | Create project. |
|
|
109
|
+
| `project update-status <id> --status <name> --json` | Update a project's status field. |
|
|
110
|
+
| `cycle list --team <slug> --json` | List cycles for a team. |
|
|
111
|
+
| `team list --json` / `label list --team <slug> --json` / `state list --team <slug> --json` | Read-only catalogs. |
|
|
112
|
+
|
|
113
|
+
Any command above accepts `--workspace <name>` to target a specific workspace. Every write command short-circuits to a `CONFIRMATION_REQUIRED` error if it looks destructive without `--yes`. Pass `--yes` only when the user has explicitly approved the write.
|
|
114
|
+
|
|
115
|
+
## Raw GraphQL escape hatch
|
|
116
|
+
|
|
117
|
+
When a curated command doesn't expose a field you need, use the raw layer. Workflow:
|
|
118
|
+
|
|
119
|
+
1. **Discover the operation:**
|
|
120
|
+
```
|
|
121
|
+
npx -y linmux@0.1.0 describe IssueBatchCreate --json
|
|
122
|
+
```
|
|
123
|
+
`describe` returns a Zod-derived schema with required + optional fields.
|
|
124
|
+
|
|
125
|
+
2. **Invoke it via `raw`:**
|
|
126
|
+
```
|
|
127
|
+
npx -y linmux@0.1.0 raw IssueBatchCreate \
|
|
128
|
+
--vars '{"input":{"issues":[{"teamId":"...","title":"..."}]}}' \
|
|
129
|
+
--json
|
|
130
|
+
```
|
|
131
|
+
Output is the SAME envelope shape as curated commands.
|
|
132
|
+
|
|
133
|
+
3. **Or run an arbitrary GraphQL query string:**
|
|
134
|
+
```
|
|
135
|
+
npx -y linmux@0.1.0 graphql \
|
|
136
|
+
--query 'query { viewer { id } }' \
|
|
137
|
+
--json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The raw layer covers Linear's full GraphQL surface (~500+ operations) — this is the part the official Linear MCP doesn't reach. Use it when the user asks for something a curated command doesn't expose; otherwise prefer the curated command for cleaner UX and snapshot-stable output.
|
|
141
|
+
|
|
142
|
+
## Common error envelopes
|
|
143
|
+
|
|
144
|
+
The five most-likely failure codes you'll see:
|
|
145
|
+
|
|
146
|
+
| Code | Exit | Meaning |
|
|
147
|
+
|------|------|---------|
|
|
148
|
+
| `WORKSPACE_NOT_RESOLVED` | 10 | No `LINEAR_API_KEY` and no active workspace. Tell the user to run `linmux workspace add` or set `LINEAR_API_KEY`. |
|
|
149
|
+
| `AUTH_INVALID` | 11 | Token is malformed or has been revoked. Tell the user to regenerate at <https://linear.app/settings/api>. |
|
|
150
|
+
| `VALIDATION_FAILED` | 12 | A required field is missing or malformed. Inspect `error.details.field`. |
|
|
151
|
+
| `RATELIMITED` | 14 | Linear's rate limit is hit (3M points/hr authenticated). `error.transient: true` — back off and retry. |
|
|
152
|
+
| `NETWORK_ERROR` | 15 | Transport-level failure (DNS, TLS, timeout). `error.transient: true` — retry once before surfacing to the user. |
|
|
153
|
+
|
|
154
|
+
The table above covers the five most-frequent codes. Other codes follow the same envelope shape — inspect `error.code` to identify the failure and `error.transient` to decide whether to retry (codes 14 and 15 set `transient: true`).
|
|
155
|
+
|
|
156
|
+
### Token & Retry Knobs
|
|
157
|
+
|
|
158
|
+
Three flags help shave bytes or control retries in high-volume agent sessions.
|
|
159
|
+
|
|
160
|
+
- `--no-meta`: drop the `meta` block from success envelopes (failure envelopes unchanged for debuggability). Saves ~150–250 bytes per call.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
npx -y linmux@0.1.0 issue list --json --no-meta
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- `--quiet`: implies `--no-meta` AND suppresses pretty-mode banners. Useful for human pipelines and CI scripts that just want the data.
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
npx -y linmux@0.1.0 me --json --quiet
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
- `--retry N`: add N additional retries on top of the per-error-type defaults (3 for rate-limit, 3 for network). Only retries `transient: true` errors; auth and validation errors fail immediately regardless. Each retry attempt is logged to stderr unless `--quiet` is set.
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
npx -y linmux@0.1.0 issue list --json --retry 2
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Self-discovery (introspection)
|
|
179
|
+
|
|
180
|
+
The CLI ships with three introspection commands that let an agent learn the surface without external docs:
|
|
181
|
+
|
|
182
|
+
- `npx -y linmux@0.1.0 list-tools --json` — every command (curated + raw) with its one-line description.
|
|
183
|
+
- `npx -y linmux@0.1.0 describe <command-or-operation> --json` — flag schema, JSON output schema, examples.
|
|
184
|
+
- `npx -y linmux@0.1.0 schema --json` — the full Linear GraphQL schema (cached) for arbitrary queries.
|
|
185
|
+
|
|
186
|
+
Always prefer `describe` over reading source. The `describe` output is generated from the same Zod schemas that drive command parsing, so it's the canonical contract for what a command accepts and returns.
|