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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Charlie Helman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# linmux
|
|
2
|
+
|
|
3
|
+
> One CLI for Linear across **all** your workspaces — the full GraphQL surface (~500 ops), multiple workspaces in a single session, and stable versioned JSON built for AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/ChuckMayo/linear-multi-workspace-cli/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/linmux)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
|
|
10
|
+
`linmux` is a single shell-out CLI for Linear. It registers **as many Linear workspaces as you have** and lets one agent session route any command at any of them, it reaches **every operation in Linear's GraphQL schema** (~500, not a curated handful), and it emits a stable, versioned JSON envelope on every call. No per-workspace server to stand up — if your agent can run a shell command, it can drive Linear.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx -y linmux@latest workspace add acme --token lin_api_...
|
|
14
|
+
npx -y linmux@latest workspace add personal --token lin_api_...
|
|
15
|
+
npx -y linmux@latest issue list --workspace acme --team ENG --json
|
|
16
|
+
npx -y linmux@latest issue list --workspace personal --team SIDE --json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> **Alpha (v0.1.0).** First public release, solo-maintained. Personal API keys only (no OAuth yet). The JSON envelope (`data.*` paths) is the stable contract; everything else may move. See [Project status](#project-status).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Why this exists
|
|
24
|
+
|
|
25
|
+
Linear's official MCP server is good, and it works in any MCP-capable agent. Two things it doesn't do — by design — are where `linmux` earns its place:
|
|
26
|
+
|
|
27
|
+
- **Multiple workspaces in one session.** A Linear personal API key is scoped to a single workspace, and the official MCP authorizes one workspace per connection. To work across three workspaces you stand up three MCP server entries and juggle which is which. `linmux` registers all of them once and resolves a workspace **per command** (`--workspace <name>`), so a single session moves freely between them.
|
|
28
|
+
- **The full API surface.** The official MCP exposes a curated subset of operations. `linmux` generates every operation in Linear's vendored GraphQL schema and dispatches it through a `raw` layer — so when you need `IssueBatchCreate` or some field the curated commands don't expose, it's already there.
|
|
29
|
+
|
|
30
|
+
On top of those two, it's a plain shell-out: versioned JSON for agents to parse without prompting, token-saving flags for high-volume loops, and self-describing schemas so an agent can learn the surface on its own.
|
|
31
|
+
|
|
32
|
+
| Capability | Official Linear MCP | `linmux` |
|
|
33
|
+
| -------------------------------------------- | ------------------------------- | ------------------------------------- |
|
|
34
|
+
| Multiple Linear workspaces in one session | ❌ one workspace per connection | ✅ N workspaces, chosen per command |
|
|
35
|
+
| Full GraphQL surface (~500 ops) | ⚠️ curated subset | ✅ every operation, via the raw layer |
|
|
36
|
+
| Adding a workspace | OAuth + a server entry each | one `workspace add`, no server to run |
|
|
37
|
+
| Transport | MCP server (any MCP client) | shell-out CLI (any agent that shells) |
|
|
38
|
+
| Output for agents | MCP structured results | versioned JSON envelope on stdout |
|
|
39
|
+
| Token-saving / self-discovery flags | n/a | `--no-meta`, `--quiet`, `describe`, `list-tools` |
|
|
40
|
+
|
|
41
|
+
Honest scope: other community CLIs (e.g. `schpet/linear-cli`) also do multi-workspace. What `linmux` bundles is multi-workspace **plus** the full surface **plus** an agent-stable JSON contract in one shell-out — that combination is the point, not multi-workspace alone.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Quickstart
|
|
46
|
+
|
|
47
|
+
### Requirements
|
|
48
|
+
- Node.js **22** or newer
|
|
49
|
+
- A Linear personal API key — generate one at [linear.app/settings/api](https://linear.app/settings/api)
|
|
50
|
+
|
|
51
|
+
### 1. Register a workspace
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx -y linmux@latest workspace add acme --token lin_api_...
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The workspace name is positional (`workspace add <name> --token ...`). The registry is a plain JSON file written with mode `0600` at `$XDG_CONFIG_HOME/linear-agent/config.json` (default `~/.config/linear-agent/config.json`; the directory name predates the rename — see [Project status](#project-status)). Tokens never leave your machine.
|
|
58
|
+
|
|
59
|
+
### 2. Probe auth
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx -y linmux@latest whoami --json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Returns the resolved viewer + active workspace. Use it as your "did auth work" probe. (`me --json` returns viewer + organization.)
|
|
66
|
+
|
|
67
|
+
### 3. Use it
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Curated commands
|
|
71
|
+
npx -y linmux@latest issue list --team ENG --json
|
|
72
|
+
npx -y linmux@latest issue create --team ENG --title "Fix the thing" --json
|
|
73
|
+
npx -y linmux@latest comment create --issue ENG-123 --body "Done." --json
|
|
74
|
+
|
|
75
|
+
# Any of the ~500 raw GraphQL operations
|
|
76
|
+
npx -y linmux@latest describe IssueBatchCreate --json
|
|
77
|
+
npx -y linmux@latest raw IssueBatchCreate --vars '{"input":{...}}' --json
|
|
78
|
+
|
|
79
|
+
# Or an arbitrary GraphQL query
|
|
80
|
+
npx -y linmux@latest graphql --query 'query { viewer { id } }' --json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Every command supports `--workspace <name>` to target a workspace inline — no `workspace use` required.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## The JSON envelope contract
|
|
88
|
+
|
|
89
|
+
Every command emits a versioned envelope. Pin tests against `data.*` paths, not human prose. The `meta.workspace` field tells you which workspace served the call.
|
|
90
|
+
|
|
91
|
+
**Success:**
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"$apiVersion": "1",
|
|
95
|
+
"ok": true,
|
|
96
|
+
"data": { /* command-specific payload */ },
|
|
97
|
+
"meta": { "command": "issue list", "workspace": "acme" }
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Failure:**
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"$apiVersion": "1",
|
|
105
|
+
"ok": false,
|
|
106
|
+
"error": {
|
|
107
|
+
"code": "VALIDATION_FAILED",
|
|
108
|
+
"message": "Title is required",
|
|
109
|
+
"transient": false,
|
|
110
|
+
"details": { "field": "title" }
|
|
111
|
+
},
|
|
112
|
+
"meta": { "command": "issue create" }
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`ok: true` → exit 0. `ok: false` → exit > 0 (see the error-code taxonomy via `describe`). `error.transient: true` means a retry is appropriate.
|
|
117
|
+
|
|
118
|
+
Token-saving flags:
|
|
119
|
+
- `--no-meta` — drop the `meta` block from success envelopes (~150–250 bytes saved per call)
|
|
120
|
+
- `--quiet` — implies `--no-meta` + suppresses pretty banners
|
|
121
|
+
- `--retry N` — add N transient-error retries on top of the defaults
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Multiple Linear workspaces, one session
|
|
126
|
+
|
|
127
|
+
Register as many workspaces as you like:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx -y linmux@latest workspace add work --token lin_api_...
|
|
131
|
+
npx -y linmux@latest workspace add oss --token lin_api_...
|
|
132
|
+
npx -y linmux@latest workspace add side --token lin_api_...
|
|
133
|
+
npx -y linmux@latest workspace list --json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Then route any command at any workspace per-call:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx -y linmux@latest issue list --workspace work --team ENG --json
|
|
140
|
+
npx -y linmux@latest issue list --workspace oss --team CORE --json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Workspace resolution order: `--workspace <name>` flag → `LINEAR_WORKSPACE` env var → registry's active workspace → sole registered workspace → `LINEAR_API_KEY` env var (bypasses the registry entirely; useful in CI).
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Agent integrations
|
|
148
|
+
|
|
149
|
+
### Claude Code (bundled skill)
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx -y linmux@latest install-skill
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Copies a Claude Code skill to `~/.claude/skills/linmux/SKILL.md`. The skill tells Claude when to invoke `linmux`, the envelope shape, and the self-discovery commands (`describe`, `list-tools`, `schema`).
|
|
156
|
+
|
|
157
|
+
### Codex CLI, Gemini CLI, Cursor, anything else
|
|
158
|
+
|
|
159
|
+
There's no plugin to install — point your agent at the binary:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Codex CLI
|
|
163
|
+
codex exec "list my open Linear issues using 'npx -y linmux@latest issue list --json'"
|
|
164
|
+
|
|
165
|
+
# Gemini CLI / Cursor / Copilot CLI / etc. — same pattern: shell out to npx -y linmux@latest <cmd> --json
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
For best results, give your agent a short system prompt: auth lives in `LINEAR_API_KEY` or `linmux workspace add`; pass `--json`; `linmux list-tools --json` enumerates everything; `linmux describe <cmd> --json` returns the Zod-derived input/output schema for any command or raw operation.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Self-discovery
|
|
173
|
+
|
|
174
|
+
The CLI is introspectable so agents can learn the surface without external docs:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
linmux list-tools --json # every curated + raw command, one line each
|
|
178
|
+
linmux describe issue create --json # full Zod schema: required/optional flags, output shape, examples
|
|
179
|
+
linmux schema --json # the entire vendored Linear GraphQL schema (introspection JSON)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`describe` is generated from the same Zod schemas that validate flags at runtime, so it's the canonical contract for what a command accepts and returns. Agents should prefer `describe` over reading source.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Architecture
|
|
187
|
+
|
|
188
|
+
- **Language:** TypeScript, ESM-only, Node 22+
|
|
189
|
+
- **CLI framework:** [oclif](https://oclif.io/) (built-in `--json` mode, topic-based command organization)
|
|
190
|
+
- **API client:** [`@linear/sdk`](https://www.npmjs.com/package/@linear/sdk) (official, codegen'd from Linear's GraphQL schema)
|
|
191
|
+
- **Raw layer:** every operation in Linear's vendored schema is generated as a `TypedDocumentNode` and dispatched via the SDK's `rawRequest` escape hatch
|
|
192
|
+
- **Validation:** [Zod 4](https://zod.dev/) for flag parsing AND output schema generation (`describe` reuses the same schemas)
|
|
193
|
+
- **Bundling:** [tsdown](https://tsdown.dev/) for fast cold-start (<500 ms median target)
|
|
194
|
+
- **Config:** a custom 0600 JSON store (no external config dependency); just workspace names + tokens + an active-workspace pointer
|
|
195
|
+
|
|
196
|
+
The CLI stores nothing beyond the workspace registry and a single active-workspace pointer. No telemetry, no analytics, no network calls outside the Linear API.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git clone https://github.com/ChuckMayo/linear-multi-workspace-cli.git
|
|
204
|
+
cd linear-multi-workspace-cli
|
|
205
|
+
npm install
|
|
206
|
+
cp .env.example .env # add your LINEAR_API_KEY for smoke tests
|
|
207
|
+
npm run build
|
|
208
|
+
npm test
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Useful scripts:
|
|
212
|
+
- `npm run lint` — Biome lint + format check
|
|
213
|
+
- `npm run typecheck` — `tsc --noEmit`
|
|
214
|
+
- `npm run codegen` — re-vendor the Linear schema + regenerate the raw operation registry
|
|
215
|
+
- `npm run smoke:phase-2` — end-to-end smoke against a real workspace (requires `.env`; **writes to live Linear**)
|
|
216
|
+
|
|
217
|
+
The vendored Linear schema lives at `schema.graphql`. A weekly GitHub Action (`schema-diff.yml`) detects drift against the live Linear API and opens a sync PR for additive changes.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Project status
|
|
222
|
+
|
|
223
|
+
**v0.1.0 — alpha, first public release, solo-maintained.** The curated command surface, raw-layer dispatch, JSON envelope contract, multi-workspace registry, and the Claude Code skill bundle are all in place and covered by the test suite.
|
|
224
|
+
|
|
225
|
+
Known limitations:
|
|
226
|
+
- Personal API keys only — no OAuth.
|
|
227
|
+
- The on-disk config directory is `~/.config/linear-agent/` (the tool's former name), retained so existing registrations survive the rename. A clean migration to `~/.config/linmux/` is a follow-up.
|
|
228
|
+
- Native Windows path defaults (`%APPDATA%`) are out of scope; XDG paths work on Linux/macOS and on Windows shells that set `XDG_CONFIG_HOME`.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Contributing
|
|
233
|
+
|
|
234
|
+
This repository is **maintained by [@ChuckMayo](https://github.com/ChuckMayo)**. External pull requests are not accepted at this stage — see [CONTRIBUTING.md](./CONTRIBUTING.md) for the rationale and the right way to contribute (issues, discussions, forks).
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT — see [LICENSE](./LICENSE).
|
package/bin/run.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
|
|
2
|
+
import { commentCreateRuntime } from "../../lib/comment-create-runtime.js";
|
|
3
|
+
import { Command, Flags } from "@oclif/core";
|
|
4
|
+
//#region src/commands/comment/create.ts
|
|
5
|
+
/**
|
|
6
|
+
* `linmux comment create` -- Phase 2 PLAN 02-06 Task 1, CMT-01.create.
|
|
7
|
+
*
|
|
8
|
+
* Write command. Creates a Linear comment with `--issue` (UUID or ENG-123)
|
|
9
|
+
* + `--body`. Optional `--parent <comment-uuid>` for threaded replies.
|
|
10
|
+
*
|
|
11
|
+
* Per RESEARCH 02-06 line 887, CommentCreateInput.issueId accepts a Linear
|
|
12
|
+
* identifier (ENG-123) directly -- the runtime passes the user value through
|
|
13
|
+
* without a client-side resolution round-trip.
|
|
14
|
+
*
|
|
15
|
+
* WSP-06 + required-flag validation both run in the runtime BEFORE any SDK
|
|
16
|
+
* call.
|
|
17
|
+
*
|
|
18
|
+
* Implementation lives in `src/lib/comment-create-runtime.ts` per the Phase 1
|
|
19
|
+
* PLAN-04 invariant. This file exports BOTH the oclif Command class AND a
|
|
20
|
+
* named `runCommentCreate(args)` function.
|
|
21
|
+
*/
|
|
22
|
+
async function runCommentCreate(args) {
|
|
23
|
+
const runArgs = {
|
|
24
|
+
commandPath: "comment create",
|
|
25
|
+
pretty: args.pretty,
|
|
26
|
+
handler: async (retryOpts) => {
|
|
27
|
+
const runtimeFlags = {};
|
|
28
|
+
if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
|
|
29
|
+
if (args.fields !== void 0) runtimeFlags.fields = args.fields;
|
|
30
|
+
if (args.allowActiveWorkspaceWrite !== void 0) runtimeFlags.allowActiveWorkspaceWrite = args.allowActiveWorkspaceWrite;
|
|
31
|
+
if (args.issue !== void 0) runtimeFlags.issue = args.issue;
|
|
32
|
+
if (args.body !== void 0) runtimeFlags.body = args.body;
|
|
33
|
+
if (args.parent !== void 0) runtimeFlags.parent = args.parent;
|
|
34
|
+
const result = await commentCreateRuntime({
|
|
35
|
+
args: {},
|
|
36
|
+
flags: runtimeFlags,
|
|
37
|
+
env: process.env,
|
|
38
|
+
retryOptsOverride: retryOpts
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
data: result.data,
|
|
42
|
+
meta: result.meta
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
|
|
47
|
+
if (args.quiet !== void 0) runArgs.quiet = args.quiet;
|
|
48
|
+
if (args.retry !== void 0) runArgs.retry = args.retry;
|
|
49
|
+
return runCommand(runArgs);
|
|
50
|
+
}
|
|
51
|
+
var CommentCreate = class CommentCreate extends Command {
|
|
52
|
+
static description = "Create a comment on a Linear issue. --issue + --body required; --parent optional for threaded replies.";
|
|
53
|
+
static enableJsonFlag = true;
|
|
54
|
+
static flags = {
|
|
55
|
+
...BASE_FLAGS,
|
|
56
|
+
workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
|
|
57
|
+
"allow-active-workspace-write": Flags.boolean({ description: "Per-invocation opt-in to use the active default workspace for this write (WSP-06)" }),
|
|
58
|
+
fields: Flags.string({
|
|
59
|
+
description: "Field preset (ids|defaults|full) or comma-separated list",
|
|
60
|
+
default: "defaults"
|
|
61
|
+
}),
|
|
62
|
+
issue: Flags.string({
|
|
63
|
+
required: true,
|
|
64
|
+
description: "Issue UUID or identifier (ENG-123) to comment on (required)"
|
|
65
|
+
}),
|
|
66
|
+
body: Flags.string({
|
|
67
|
+
required: true,
|
|
68
|
+
description: "Comment body (markdown) (required)"
|
|
69
|
+
}),
|
|
70
|
+
parent: Flags.string({ description: "Parent comment UUID (for threaded replies)" })
|
|
71
|
+
};
|
|
72
|
+
async run() {
|
|
73
|
+
const { flags } = await this.parse(CommentCreate);
|
|
74
|
+
const callArgs = {
|
|
75
|
+
pretty: flags.pretty,
|
|
76
|
+
allowActiveWorkspaceWrite: flags["allow-active-workspace-write"]
|
|
77
|
+
};
|
|
78
|
+
if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
|
|
79
|
+
if (flags.fields !== void 0) callArgs.fields = flags.fields;
|
|
80
|
+
if (flags.issue !== void 0) callArgs.issue = flags.issue;
|
|
81
|
+
if (flags.body !== void 0) callArgs.body = flags.body;
|
|
82
|
+
if (flags.parent !== void 0) callArgs.parent = flags.parent;
|
|
83
|
+
if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
|
|
84
|
+
if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
|
|
85
|
+
if (flags.retry !== void 0) callArgs.retry = flags.retry;
|
|
86
|
+
const out = await runCommentCreate(callArgs);
|
|
87
|
+
if (!flags.json) process.stdout.write(out.stdout);
|
|
88
|
+
if (out.stderr) process.stderr.write(out.stderr);
|
|
89
|
+
if (out.exitCode !== 0) process.exitCode = out.exitCode;
|
|
90
|
+
return JSON.parse(out.stdout);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
//#endregion
|
|
94
|
+
export { CommentCreate as default, runCommentCreate };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
|
|
2
|
+
import { commentDeleteRuntime } from "../../lib/comment-delete-runtime.js";
|
|
3
|
+
import { Args, Command, Flags } from "@oclif/core";
|
|
4
|
+
//#region src/commands/comment/delete.ts
|
|
5
|
+
/**
|
|
6
|
+
* `linmux comment delete <id>` -- Phase 2 PLAN 02-06 Task 2,
|
|
7
|
+
* CMT-01.delete.
|
|
8
|
+
*
|
|
9
|
+
* Write command. Deletes a Linear comment. WSP-06 enforced. NO `--yes` gate
|
|
10
|
+
* -- comments are individually low-stakes; --yes is reserved for irreversible
|
|
11
|
+
* operations (only `issue purge` per CONTEXT line 49). Linear's UI also
|
|
12
|
+
* offers undo for comment deletion.
|
|
13
|
+
*
|
|
14
|
+
* Implementation lives in `src/lib/comment-delete-runtime.ts` per the Phase 1
|
|
15
|
+
* PLAN-04 invariant. This file exports BOTH the oclif Command class AND a
|
|
16
|
+
* named `runCommentDelete(args)` function.
|
|
17
|
+
*/
|
|
18
|
+
async function runCommentDelete(args) {
|
|
19
|
+
const runArgs = {
|
|
20
|
+
commandPath: "comment delete",
|
|
21
|
+
pretty: args.pretty,
|
|
22
|
+
handler: async (retryOpts) => {
|
|
23
|
+
const runtimeFlags = {};
|
|
24
|
+
if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
|
|
25
|
+
if (args.allowActiveWorkspaceWrite !== void 0) runtimeFlags.allowActiveWorkspaceWrite = args.allowActiveWorkspaceWrite;
|
|
26
|
+
const result = await commentDeleteRuntime({
|
|
27
|
+
args: { id: args.id },
|
|
28
|
+
flags: runtimeFlags,
|
|
29
|
+
env: process.env,
|
|
30
|
+
retryOptsOverride: retryOpts
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
data: result.data,
|
|
34
|
+
meta: result.meta
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
|
|
39
|
+
if (args.quiet !== void 0) runArgs.quiet = args.quiet;
|
|
40
|
+
if (args.retry !== void 0) runArgs.retry = args.retry;
|
|
41
|
+
return runCommand(runArgs);
|
|
42
|
+
}
|
|
43
|
+
var CommentDelete = class CommentDelete extends Command {
|
|
44
|
+
static description = "Delete a Linear comment by UUID.";
|
|
45
|
+
static enableJsonFlag = true;
|
|
46
|
+
static args = { id: Args.string({
|
|
47
|
+
required: true,
|
|
48
|
+
description: "Comment UUID"
|
|
49
|
+
}) };
|
|
50
|
+
static flags = {
|
|
51
|
+
...BASE_FLAGS,
|
|
52
|
+
workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
|
|
53
|
+
"allow-active-workspace-write": Flags.boolean({ description: "Per-invocation opt-in to use the active default workspace for this write (WSP-06)" })
|
|
54
|
+
};
|
|
55
|
+
async run() {
|
|
56
|
+
const { args, flags } = await this.parse(CommentDelete);
|
|
57
|
+
const callArgs = {
|
|
58
|
+
id: args.id,
|
|
59
|
+
pretty: flags.pretty,
|
|
60
|
+
allowActiveWorkspaceWrite: flags["allow-active-workspace-write"]
|
|
61
|
+
};
|
|
62
|
+
if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
|
|
63
|
+
if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
|
|
64
|
+
if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
|
|
65
|
+
if (flags.retry !== void 0) callArgs.retry = flags.retry;
|
|
66
|
+
const out = await runCommentDelete(callArgs);
|
|
67
|
+
if (!flags.json) process.stdout.write(out.stdout);
|
|
68
|
+
if (out.stderr) process.stderr.write(out.stderr);
|
|
69
|
+
if (out.exitCode !== 0) process.exitCode = out.exitCode;
|
|
70
|
+
return JSON.parse(out.stdout);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
export { CommentDelete as default, runCommentDelete };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
|
|
2
|
+
import { PAGINATION_FLAGS } from "../../core/pagination/flags.js";
|
|
3
|
+
import "../../core/pagination/index.js";
|
|
4
|
+
import { commentListRuntime } from "../../lib/comment-list-runtime.js";
|
|
5
|
+
import { Command, Flags } from "@oclif/core";
|
|
6
|
+
//#region src/commands/comment/list.ts
|
|
7
|
+
/**
|
|
8
|
+
* `linmux comment list` -- Phase 2 PLAN 02-06 Task 1, CMT-01.list.
|
|
9
|
+
*
|
|
10
|
+
* Read command. Lists comments either workspace-wide or scoped to a single
|
|
11
|
+
* issue (--issue ENG-123 or UUID). NO WSP-06 enforcement -- reads are
|
|
12
|
+
* allowed against the active default workspace.
|
|
13
|
+
*
|
|
14
|
+
* Implementation lives in `src/lib/comment-list-runtime.ts` per the Phase 1
|
|
15
|
+
* PLAN-04 invariant. This file exports BOTH the oclif Command class AND a
|
|
16
|
+
* named `runCommentList(args)` async function so tests can call the runtime
|
|
17
|
+
* without spawning a subprocess.
|
|
18
|
+
*/
|
|
19
|
+
async function runCommentList(args) {
|
|
20
|
+
const runArgs = {
|
|
21
|
+
commandPath: "comment list",
|
|
22
|
+
pretty: args.pretty,
|
|
23
|
+
handler: async (retryOpts) => {
|
|
24
|
+
const runtimeFlags = {};
|
|
25
|
+
if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
|
|
26
|
+
if (args.fields !== void 0) runtimeFlags.fields = args.fields;
|
|
27
|
+
if (args.limit !== void 0) runtimeFlags.limit = args.limit;
|
|
28
|
+
if (args.cursor !== void 0) runtimeFlags.cursor = args.cursor;
|
|
29
|
+
if (args.issue !== void 0) runtimeFlags.issue = args.issue;
|
|
30
|
+
if (args.include !== void 0) runtimeFlags.include = args.include;
|
|
31
|
+
const result = await commentListRuntime({
|
|
32
|
+
flags: runtimeFlags,
|
|
33
|
+
env: process.env,
|
|
34
|
+
retryOptsOverride: retryOpts
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
data: result.data,
|
|
38
|
+
meta: result.meta
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
|
|
43
|
+
if (args.quiet !== void 0) runArgs.quiet = args.quiet;
|
|
44
|
+
if (args.retry !== void 0) runArgs.retry = args.retry;
|
|
45
|
+
return runCommand(runArgs);
|
|
46
|
+
}
|
|
47
|
+
var CommentList = class CommentList extends Command {
|
|
48
|
+
static description = "List Linear comments. Pass --issue ENG-123 (or UUID) to scope to one issue, otherwise lists workspace-wide.";
|
|
49
|
+
static enableJsonFlag = true;
|
|
50
|
+
static flags = {
|
|
51
|
+
...BASE_FLAGS,
|
|
52
|
+
...PAGINATION_FLAGS,
|
|
53
|
+
workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
|
|
54
|
+
fields: Flags.string({
|
|
55
|
+
description: "Field preset (ids|defaults|full) or comma-separated list",
|
|
56
|
+
default: "defaults"
|
|
57
|
+
}),
|
|
58
|
+
issue: Flags.string({ description: "Filter to comments on this issue (UUID or ENG-123)" }),
|
|
59
|
+
include: Flags.string({
|
|
60
|
+
description: "Hydrate related entities in a single GraphQL round-trip (e.g. reactions, parent). Available: reactions, parent.",
|
|
61
|
+
multiple: true
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
async run() {
|
|
65
|
+
const { flags } = await this.parse(CommentList);
|
|
66
|
+
const callArgs = { pretty: flags.pretty };
|
|
67
|
+
if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
|
|
68
|
+
if (flags.fields !== void 0) callArgs.fields = flags.fields;
|
|
69
|
+
if (flags.limit !== void 0) callArgs.limit = flags.limit;
|
|
70
|
+
if (flags.cursor !== void 0) callArgs.cursor = flags.cursor;
|
|
71
|
+
if (flags.issue !== void 0) callArgs.issue = flags.issue;
|
|
72
|
+
if (flags.include !== void 0) callArgs.include = flags.include;
|
|
73
|
+
if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
|
|
74
|
+
if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
|
|
75
|
+
if (flags.retry !== void 0) callArgs.retry = flags.retry;
|
|
76
|
+
const out = await runCommentList(callArgs);
|
|
77
|
+
if (!flags.json) process.stdout.write(out.stdout);
|
|
78
|
+
if (out.stderr) process.stderr.write(out.stderr);
|
|
79
|
+
if (out.exitCode !== 0) process.exitCode = out.exitCode;
|
|
80
|
+
return JSON.parse(out.stdout);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { CommentList as default, runCommentList };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
|
|
2
|
+
import { commentUpdateRuntime } from "../../lib/comment-update-runtime.js";
|
|
3
|
+
import { Args, Command, Flags } from "@oclif/core";
|
|
4
|
+
//#region src/commands/comment/update.ts
|
|
5
|
+
/**
|
|
6
|
+
* `linmux comment update <id>` -- Phase 2 PLAN 02-06 Task 2, CMT-01.update.
|
|
7
|
+
*
|
|
8
|
+
* Write command. Updates a Linear comment's body. WSP-06 enforcement and
|
|
9
|
+
* VALIDATION_NO_FIELDS guard both run in the runtime BEFORE any SDK call.
|
|
10
|
+
*
|
|
11
|
+
* Implementation lives in `src/lib/comment-update-runtime.ts` per the Phase 1
|
|
12
|
+
* PLAN-04 invariant. This file exports BOTH the oclif Command class AND a
|
|
13
|
+
* named `runCommentUpdate(args)` function.
|
|
14
|
+
*/
|
|
15
|
+
async function runCommentUpdate(args) {
|
|
16
|
+
const runArgs = {
|
|
17
|
+
commandPath: "comment update",
|
|
18
|
+
pretty: args.pretty,
|
|
19
|
+
handler: async (retryOpts) => {
|
|
20
|
+
const runtimeFlags = {};
|
|
21
|
+
if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
|
|
22
|
+
if (args.fields !== void 0) runtimeFlags.fields = args.fields;
|
|
23
|
+
if (args.allowActiveWorkspaceWrite !== void 0) runtimeFlags.allowActiveWorkspaceWrite = args.allowActiveWorkspaceWrite;
|
|
24
|
+
if (args.body !== void 0) runtimeFlags.body = args.body;
|
|
25
|
+
const result = await commentUpdateRuntime({
|
|
26
|
+
args: { id: args.id },
|
|
27
|
+
flags: runtimeFlags,
|
|
28
|
+
env: process.env,
|
|
29
|
+
retryOptsOverride: retryOpts
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
data: result.data,
|
|
33
|
+
meta: result.meta
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
|
|
38
|
+
if (args.quiet !== void 0) runArgs.quiet = args.quiet;
|
|
39
|
+
if (args.retry !== void 0) runArgs.retry = args.retry;
|
|
40
|
+
return runCommand(runArgs);
|
|
41
|
+
}
|
|
42
|
+
var CommentUpdate = class CommentUpdate extends Command {
|
|
43
|
+
static description = "Update a Linear comment. --body is the only updatable field; pass \"\" to clear.";
|
|
44
|
+
static enableJsonFlag = true;
|
|
45
|
+
static args = { id: Args.string({
|
|
46
|
+
required: true,
|
|
47
|
+
description: "Comment UUID"
|
|
48
|
+
}) };
|
|
49
|
+
static flags = {
|
|
50
|
+
...BASE_FLAGS,
|
|
51
|
+
workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
|
|
52
|
+
"allow-active-workspace-write": Flags.boolean({ description: "Per-invocation opt-in to use the active default workspace for this write (WSP-06)" }),
|
|
53
|
+
fields: Flags.string({
|
|
54
|
+
description: "Field preset (ids|defaults|full) or comma-separated list",
|
|
55
|
+
default: "defaults"
|
|
56
|
+
}),
|
|
57
|
+
body: Flags.string({ description: "New comment body (markdown). Pass \"\" to clear." })
|
|
58
|
+
};
|
|
59
|
+
async run() {
|
|
60
|
+
const { args, flags } = await this.parse(CommentUpdate);
|
|
61
|
+
const callArgs = {
|
|
62
|
+
id: args.id,
|
|
63
|
+
pretty: flags.pretty,
|
|
64
|
+
allowActiveWorkspaceWrite: flags["allow-active-workspace-write"]
|
|
65
|
+
};
|
|
66
|
+
if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
|
|
67
|
+
if (flags.fields !== void 0) callArgs.fields = flags.fields;
|
|
68
|
+
if (flags.body !== void 0) callArgs.body = flags.body;
|
|
69
|
+
if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
|
|
70
|
+
if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
|
|
71
|
+
if (flags.retry !== void 0) callArgs.retry = flags.retry;
|
|
72
|
+
const out = await runCommentUpdate(callArgs);
|
|
73
|
+
if (!flags.json) process.stdout.write(out.stdout);
|
|
74
|
+
if (out.stderr) process.stderr.write(out.stderr);
|
|
75
|
+
if (out.exitCode !== 0) process.exitCode = out.exitCode;
|
|
76
|
+
return JSON.parse(out.stdout);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { CommentUpdate as default, runCommentUpdate };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { BASE_FLAGS, runCommand } from "../../lib/workspace-runtime.js";
|
|
2
|
+
import { cycleCurrentRuntime } from "../../lib/cycle-current-runtime.js";
|
|
3
|
+
import { Command, Flags } from "@oclif/core";
|
|
4
|
+
//#region src/commands/cycle/current.ts
|
|
5
|
+
/**
|
|
6
|
+
* `linmux cycle current --team <ref>` -- Phase 2 PLAN 02-08 Task 1,
|
|
7
|
+
* CYC-01.current.
|
|
8
|
+
*
|
|
9
|
+
* Single-entity read. Fetches the active cycle for a specific team. The
|
|
10
|
+
* `--team` flag is REQUIRED -- the runtime throws WORKFLOW_TEAM_REQUIRED
|
|
11
|
+
* (exit 2) BEFORE any SDK call when --team is absent. We deliberately do
|
|
12
|
+
* NOT mark the oclif flag as `required: true` because that would surface a
|
|
13
|
+
* generic oclif USAGE message rather than the structured agent-readable
|
|
14
|
+
* error envelope.
|
|
15
|
+
*
|
|
16
|
+
* NO WSP-06 enforcement -- reads are allowed against the active default
|
|
17
|
+
* workspace.
|
|
18
|
+
*
|
|
19
|
+
* Implementation lives in `src/lib/cycle-current-runtime.ts` per the Phase 1
|
|
20
|
+
* PLAN-04 invariant. This file exports BOTH the oclif Command class AND a
|
|
21
|
+
* named `runCycleCurrent(args)` async function so tests can call the runtime
|
|
22
|
+
* without spawning a subprocess.
|
|
23
|
+
*/
|
|
24
|
+
async function runCycleCurrent(args) {
|
|
25
|
+
const runArgs = {
|
|
26
|
+
commandPath: "cycle current",
|
|
27
|
+
pretty: args.pretty,
|
|
28
|
+
handler: async (retryOpts) => {
|
|
29
|
+
const runtimeFlags = {};
|
|
30
|
+
if (args.workspace !== void 0) runtimeFlags.workspace = args.workspace;
|
|
31
|
+
if (args.fields !== void 0) runtimeFlags.fields = args.fields;
|
|
32
|
+
if (args.team !== void 0) runtimeFlags.team = args.team;
|
|
33
|
+
const result = await cycleCurrentRuntime({
|
|
34
|
+
flags: runtimeFlags,
|
|
35
|
+
env: process.env,
|
|
36
|
+
retryOptsOverride: retryOpts
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
data: result.data,
|
|
40
|
+
meta: result.meta
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
if (args.noMeta !== void 0) runArgs.noMeta = args.noMeta;
|
|
45
|
+
if (args.quiet !== void 0) runArgs.quiet = args.quiet;
|
|
46
|
+
if (args.retry !== void 0) runArgs.retry = args.retry;
|
|
47
|
+
return runCommand(runArgs);
|
|
48
|
+
}
|
|
49
|
+
var CycleCurrent = class CycleCurrent extends Command {
|
|
50
|
+
static description = "Get the active cycle for a team. --team is REQUIRED.";
|
|
51
|
+
static enableJsonFlag = true;
|
|
52
|
+
static flags = {
|
|
53
|
+
...BASE_FLAGS,
|
|
54
|
+
workspace: Flags.string({ description: "Workspace name (overrides active default and LINEAR_WORKSPACE)" }),
|
|
55
|
+
team: Flags.string({ description: "Team key (e.g. \"ENG\"), name, or UUID -- REQUIRED" }),
|
|
56
|
+
fields: Flags.string({
|
|
57
|
+
description: "Field preset (ids|defaults|full) or comma-separated list",
|
|
58
|
+
default: "defaults"
|
|
59
|
+
})
|
|
60
|
+
};
|
|
61
|
+
async run() {
|
|
62
|
+
const { flags } = await this.parse(CycleCurrent);
|
|
63
|
+
const callArgs = { pretty: flags.pretty };
|
|
64
|
+
if (flags.workspace !== void 0) callArgs.workspace = flags.workspace;
|
|
65
|
+
if (flags.fields !== void 0) callArgs.fields = flags.fields;
|
|
66
|
+
if (flags.team !== void 0) callArgs.team = flags.team;
|
|
67
|
+
if (flags.quiet !== void 0) callArgs.quiet = flags.quiet;
|
|
68
|
+
if (flags.noMeta !== void 0) callArgs.noMeta = flags.noMeta;
|
|
69
|
+
if (flags.retry !== void 0) callArgs.retry = flags.retry;
|
|
70
|
+
const out = await runCycleCurrent(callArgs);
|
|
71
|
+
if (!flags.json) process.stdout.write(out.stdout);
|
|
72
|
+
if (out.stderr) process.stderr.write(out.stderr);
|
|
73
|
+
if (out.exitCode !== 0) process.exitCode = out.exitCode;
|
|
74
|
+
return JSON.parse(out.stdout);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
//#endregion
|
|
78
|
+
export { CycleCurrent as default, runCycleCurrent };
|