@elnora-ai/linear 1.1.0 → 2.0.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.
@@ -11,7 +11,7 @@
11
11
  "name": "linear-workspace",
12
12
  "description": "Linear issue management for Claude Code — search, bulk operations, intelligent agents, config-driven curator.",
13
13
  "source": "./",
14
- "version": "1.1.0",
14
+ "version": "2.0.0",
15
15
  "category": "productivity",
16
16
  "tags": [
17
17
  "linear",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linear-workspace",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Linear issue management for Claude Code — search, bulk operations, intelligent agents, config-driven curator. Backed by the elnora-linear CLI.",
5
5
  "author": {
6
6
  "name": "Elnora AI",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.0](https://github.com/Elnora-AI/elnora-linear/compare/v1.1.0...v2.0.0) (2026-05-16)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * bulk creation paths (`issues batch-create`, `issues bulk-ops` create) now exit 2 with ProjectValidationError when a target team has projects available and the input/op lacks a project. This matches cc9566e's flip on `issues create`. Migration: - Add `--project` / `projectId` / `project` to every create input going to a team with projects, OR - Set `requiresProject: false` for teams that legitimately have unassigned issues in `references/label-policy.json`, OR - Pass `--skip-project-check` per-call (CLI) or `skipProjectCheck: true` per-op (bulk-ops) for placeholder issues.
9
+
10
+ ### Features
11
+
12
+ * enforce require-project on bypass routes + close install-guide curator gaps ([#28](https://github.com/Elnora-AI/elnora-linear/issues/28)) ([5521e8c](https://github.com/Elnora-AI/elnora-linear/commit/5521e8c15901272dd010f21929d6f65788771957))
13
+ * require a project on issues create by default + auto-sync postinstall + universal AGENTS.md ([#26](https://github.com/Elnora-AI/elnora-linear/issues/26)) ([92a4f26](https://github.com/Elnora-AI/elnora-linear/commit/92a4f26b9d71441fe411e0720831259c76b21c02))
14
+
3
15
  ## [1.1.0](https://github.com/Elnora-AI/elnora-linear/compare/v1.0.1...v1.1.0) (2026-05-16)
4
16
 
5
17
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # elnora-linear
2
2
 
3
- A Linear workspace toolkit: a fast CLI, a Claude Code plugin (slash commands + agents + skill router), and a config-driven curator that validates Linear issues against external signals.
3
+ **The full Linear API as a CLI, a Claude Code plugin, and a signal-driven hygiene curator purpose-built for AI coding agents to create, edit, review, and curate Linear issues safely at scale.**
4
4
 
5
5
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
6
6
  [![npm](https://img.shields.io/npm/v/@elnora-ai/linear)](https://www.npmjs.com/package/@elnora-ai/linear)
@@ -8,14 +8,176 @@ A Linear workspace toolkit: a fast CLI, a Claude Code plugin (slash commands + a
8
8
 
9
9
  ---
10
10
 
11
- ## What this is
11
+ ## What you get
12
+
13
+ Three surfaces, one npm package:
12
14
 
13
- One npm package, two surfaces:
15
+ - **`elnora-linear` CLI** — complete coverage of the Linear GraphQL API. Scriptable, JSON-pipeable, with structured errors that AI agents can self-correct from.
16
+ - **`linear-workspace` Claude Code plugin** — six slash commands, five specialized agents, and a router skill that picks the right one from intent. `/plugin install linear-workspace@elnora-linear`.
17
+ - **`elnora-linear curator-run`** — config-driven automation that polls GitHub, Slack, and custom shell signals, asks an LLM what to do, auto-applies safe state changes (capped, debounced, audit-logged), and queues the rest for human review.
14
18
 
15
- - **CLI** `elnora-linear`, complete coverage of the Linear GraphQL API (issues, projects, teams, labels, cycles, initiatives, milestones, attachments, status updates, agent sessions, webhooks, customers, customer needs, …). Bulk mutations, parallel reads, structured errors the agent layer can self-correct from.
16
- - **Claude Code plugin** — `linear-workspace`. Six slash commands, five specialized agents, a router skill. Drop-in: `/plugin install linear-workspace@elnora-linear`.
19
+ Built end-to-end so AI coding agents can drive Linear with confidence: structured errors for self-correction, bounded mutations, soft-delete defaults, and a hard `--yes` gate on anything destructive.
17
20
 
18
- Plus a curator (`elnora-linear curator-run`) that polls GitHub commits, GitHub PRs, Slack messages, sibling Linear issues, MCP tools, and arbitrary shell commands then asks an LLM to propose state changes, with HIGH-tier actions auto-applied (capped, debounced, audit-logged) and MEDIUM-tier actions queued for human confirmation.
21
+ **Using a non-Claude agent?** [`AGENTS.md`](AGENTS.md) gives Codex, Cursor, Aider, Continue, Amp, Jules, and Roo the same dispatch logic via the CLI drop it at the root of any repo and your agent picks up when to use which verb.
22
+
23
+ ---
24
+
25
+ ## What you can do with it
26
+
27
+ ### Read your workspace
28
+ - Natural-language search across issues, scoped by team / assignee / state / label
29
+ - Your assigned issues, grouped by state (`my-issues`)
30
+ - Fetch one issue, project, cycle, milestone, initiative, or document
31
+ - Team workflows, label catalogs, member rosters, saved views
32
+ - Project & initiative status updates (onTrack / atRisk / offTrack)
33
+ - Audit logs, notifications, agent activity threads
34
+ - Rate-limit headroom (`quota`)
35
+ - Cold-start any team (`context --team`) — projects + states + label catalog + members in one call
36
+
37
+ ### Write to your workspace
38
+ - Create one issue or batches of 50 (validated against team's label policy server-side)
39
+ - Update title / description / state / assignee / labels / priority / project / due date / parent
40
+ - Add, resolve, react to, and delete comments
41
+ - Link issues with `related` / `blocks` / `duplicate` / `similar` relations
42
+ - Manage projects, initiatives, milestones, cycles, documents, status updates
43
+ - Manage labels (team-scoped and workspace-wide; project labels separately)
44
+ - Attach URLs or upload local files (path-validated, symlink-resolved)
45
+ - Manage customers and customer needs
46
+ - Manage webhooks with secret rotation + signature verification
47
+ - Manage Linear agent sessions and activity events
48
+
49
+ ### Bulk and cleanup
50
+ - `bulk` — apply the same state change or comment to N issues filtered by query/team/assignee/state. Dry-run by default; `--yes` to commit
51
+ - `cleanup` — six-check audit (missing labels, stale, duplicates, wrong state, orphaned, unactionable) with per-category confirmation
52
+ - `batch-create` / `batch-update` — 50-issue caps, heterogeneous GraphQL aliasing (~10 HTTP requests per 100 mixed operations)
53
+ - `sync all` — refresh teams, projects, users, workflows from Linear in one batch
54
+ - `sync verify` — see which reference files are populated vs placeholder
55
+
56
+ ### Drive Linear from Claude Code
57
+
58
+ | Slash command | Does |
59
+ |---|---|
60
+ | `/linear-search` | Natural-language search across all issues |
61
+ | `/linear-my-issues` | Your assigned issues, grouped by state |
62
+ | `/linear-bulk` | Apply the same state change or comment to many issues — dry-run by default |
63
+ | `/linear-cleanup` | Six-check audit with per-category confirmation |
64
+ | `/linear-sync` | Refresh teams/projects/users/workflows from the Linear API |
65
+ | `/linear-curator-run` | Run the curator manually |
66
+
67
+ | Agent | For |
68
+ |---|---|
69
+ | `linear-issue-creator` | One issue from a description. Fast-path for fully-specified requests |
70
+ | `linear-url-to-issues` | N issues extracted from an article, design, blog, or doc URL |
71
+ | `linear-issue-updater` | Any modification: state, team, assignee, labels, comment, relations, close |
72
+ | `linear-issue-reviewer` | Validates an issue's Done Criteria against its linked PR diff and posts a verdict comment |
73
+ | `linear-state-curator` | Daily Linear hygiene — runs the curator headlessly |
74
+
75
+ A router skill (`linear-workspace`) dispatches to the right agent or command from intent, so you can say "find every stale ENG issue and close it" without naming a command.
76
+
77
+ > **Other agents** (Codex, Cursor, Aider, Continue, Amp, Jules, Roo) invoke the underlying CLI verbs directly — [`AGENTS.md`](AGENTS.md) contains the dispatch table mapping intent → CLI command.
78
+
79
+ ### Automate hygiene with the curator
80
+ Polls configured signal sources, builds an LLM snapshot of your open issues, and dispatches per tier:
81
+
82
+ - **HIGH** — state change applied immediately with a rationale comment. Capped at 20 mutations/run. Re-apply on the same `{issue, from, to}` debounced 14 days.
83
+ - **MEDIUM** — proposed action queued in `~/.config/elnora-linear/state/curator-state.json` for a human to review. Outbound Slack confirmation (DM-back + threaded replies) is in the spec but not yet shipped; today you read the state file directly or via the `linear-state-curator` agent.
84
+ - **LOW** — added to the run report. No side effects.
85
+
86
+ Signal sources supported:
87
+
88
+ | Type | Source |
89
+ |---|---|
90
+ | `github_commits` | Commit messages over a lookback window |
91
+ | `github_pr` | Open / closed / merged PR events |
92
+ | `slack_messages` | Messages in watched channels, optionally pattern-matched |
93
+ | `external_command` | Arbitrary CLI command output (JSON or text) — **off unless `LINEAR_ALLOW_EXTERNAL_COMMAND=1`** |
94
+
95
+ `mcp_tool` is reserved in the schema for a future release. Configuring one today raises a "not yet implemented" error at collect time.
96
+
97
+ Every applied action is appended to `~/.config/elnora-linear/state/curator-report.jsonl`. Without `ANTHROPIC_API_KEY` (or with `--collect-only`), the curator runs in diagnostic mode and only reports collected signals.
98
+
99
+ Recurring schedule: see [`docs/scheduling.md`](docs/scheduling.md) for launchd, systemd, and Task Scheduler templates.
100
+
101
+ #### Slack setup (for the `slack_messages` signal)
102
+
103
+ The curator reads channel history via Slack's `conversations.history` API. To wire it up:
104
+
105
+ 1. **Create a Slack app.** Go to [api.slack.com/apps](https://api.slack.com/apps) → **Create New App** → **From scratch**. Name it (e.g. `elnora-linear`) and pick your workspace.
106
+ 2. **Add bot token scopes.** Sidebar → **OAuth & Permissions** → **Bot Token Scopes** → add `channels:history` (public channels) and `groups:history` (private channels).
107
+ 3. **Install the app** to your workspace from the top of the same page and approve.
108
+ 4. **Copy the Bot User OAuth Token** (starts with `xoxb-`) and export it:
109
+ ```sh
110
+ export SLACK_TOKEN=xoxb-...
111
+ ```
112
+ 5. **Invite the bot to each channel** you want watched. In Slack, open the channel and run `/invite @your-app-name`. The bot only sees channels it's a member of.
113
+ 6. **Copy each channel's ID.** In Slack, click the channel name at the top → scroll to the bottom of the details panel → copy the ID (format `C0123ABCDEF`). Add them to `~/.config/elnora-linear/slack.json`:
114
+ ```json
115
+ {
116
+ "channels": [{ "id": "C0123ABCDEF", "name": "engineering" }],
117
+ "allowed_channels": ["C0123ABCDEF"]
118
+ }
119
+ ```
120
+
121
+ Verify with `elnora-linear curator-run --collect-only` — collected Slack signals should appear in the output.
122
+
123
+ ### Compliance templates
124
+ [`templates/`](templates/) ships 23 Linear issue templates for SOC 2 / change management / RCA / vulnerability / access provisioning / vendor risk / AI capability workflows. `elnora-linear templates list` and `templates sync` push them to Linear.
125
+
126
+ ### Pipe to anything
127
+ `--output json` on every read command. `--output csv` and `--output table` where it makes sense. Pipe directly into `jq`, scripts, dashboards, or another agent's input.
128
+
129
+ ---
130
+
131
+ ## Agent-safe by design
132
+
133
+ Every layer is engineered so AI agents can operate Linear at scale with sensible defaults:
134
+
135
+ - **Soft-delete by default.** Archive is the default for every removable entity; recovery is one command. Permanent removal is an explicit, opt-in path (`--permanent` + `--yes`).
136
+ - **Human-confirmed mutations.** Bulk, cleanup, permanent deletes, and team deletion confirm with a typed `--yes` before committing — a clear, auditable handoff between agent and human.
137
+ - **Structured errors for self-correction.** `issues create` returns `{ missing, availableForPrefix, suggestedRetry }` on label-policy violations and `{ availableProjects, suggestedRetry }` on the require-a-project rule (default on), so agents fix the request on the next call instead of retrying blind.
138
+ - **Every issue gets a project by default.** `issues create` requires `--project` whenever the target team has projects to choose from. Opt out per-team in `label-policy.json` (`requiresProject: false`) or per-call with `--skip-project-check`. Teams with zero projects auto-pass.
139
+ - **Bounded curator runs.** HIGH actions cap at 20 per run; each `{issue, from, to}` debounced 14 days; every applied action audit-logged to JSONL.
140
+ - **Validated upload paths.** Attachments resolve through `LINEAR_UPLOAD_ROOT` with symlink resolution.
141
+ - **Isolated credentials.** API key loaded from `LINEAR_API_KEY` → `~/.config/elnora-linear/.env` (mode `0600`) → interactive prompt. Masked in errors, omitted from JSON output, redacted in logs.
142
+
143
+ Full details in [SAFETY.md](SAFETY.md).
144
+
145
+ ---
146
+
147
+ ## Requirements
148
+
149
+ **Always needed**
150
+
151
+ | | |
152
+ |---|---|
153
+ | **Node.js** | `>=20` |
154
+ | **Package manager** | `npm` (or `pnpm` / `yarn`) for `npm install -g @elnora-ai/linear` |
155
+ | **Linear account** | A personal API key from [linear.app/settings/api](https://linear.app/settings/api) — the CLI prompts on first run and stores it in `~/.config/elnora-linear/.env` (mode `0600`) |
156
+
157
+ **For the Claude Code plugin surface (`linear-workspace`)**
158
+
159
+ | | |
160
+ |---|---|
161
+ | **Claude Code** | Latest version, with `/plugin install linear-workspace@elnora-linear` |
162
+
163
+ **For the curator** (`elnora-linear curator-run`) — each piece is opt-in per signal source
164
+
165
+ | | |
166
+ |---|---|
167
+ | **`ANTHROPIC_API_KEY`** | Required for the LLM dispatch step. Without it the curator runs in `--collect-only` diagnostic mode. |
168
+ | **`gh` CLI**, authenticated | Required for the `github_pr` signal source |
169
+ | **`git` + a local clone** | Required for the `github_commits` signal source; the repo entry in `repos.json` must include `local_path` |
170
+ | **`SLACK_TOKEN`** | Required for the `slack_messages` signal source (reading channel history). No outbound posting yet. |
171
+ | **`LINEAR_ALLOW_EXTERNAL_COMMAND=1`** | Off by default. Set this to enable the `external_command` signal source. |
172
+
173
+ **npm dependencies** (installed automatically)
174
+
175
+ - [`@linear/sdk`](https://www.npmjs.com/package/@linear/sdk) — Linear GraphQL client
176
+ - [`@anthropic-ai/sdk`](https://www.npmjs.com/package/@anthropic-ai/sdk) — curator LLM client
177
+ - [`commander`](https://www.npmjs.com/package/commander) — CLI parser
178
+ - [`ajv`](https://www.npmjs.com/package/ajv) + [`ajv-formats`](https://www.npmjs.com/package/ajv-formats) — JSON Schema validation for every reference file
179
+
180
+ ---
19
181
 
20
182
  ## Quick start
21
183
 
@@ -24,49 +186,73 @@ npm install -g @elnora-ai/linear
24
186
  elnora-linear issues list # prompts for your Linear API key on first run
25
187
  ```
26
188
 
27
- Or as a Claude Code plugin:
189
+ **As a Claude Code plugin** — native slash commands + dispatched subagents:
28
190
 
29
191
  ```
30
192
  /plugin marketplace add Elnora-AI/elnora-linear
31
193
  /plugin install linear-workspace@elnora-linear
32
194
  ```
33
195
 
34
- On your first Linear command, you'll be prompted for your Linear API key once (get one at [linear.app/settings/api](https://linear.app/settings/api)). It's saved to `~/.config/elnora-linear/.env` (mode 0600). Then populate workspace metadata:
196
+ **With any other AI coding agent** (Codex CLI, Cursor, Aider, Continue, Amp, Jules, Roo) install the CLI as above, then drop [`AGENTS.md`](AGENTS.md) at your project root; these agents read it natively:
197
+
198
+ ```sh
199
+ npm install -g @elnora-ai/linear
200
+ curl -O https://raw.githubusercontent.com/Elnora-AI/elnora-linear/main/AGENTS.md
201
+ export LINEAR_API_KEY=lin_api_...
202
+ ```
203
+
204
+ > **Setting this up via an AI agent?** Point it at [`INSTALL_FOR_AGENTS.md`](INSTALL_FOR_AGENTS.md) — a gated, step-by-step runbook for any agent to verify the install, collect the key, sync references, and smoke-test the stack.
205
+
206
+ Get a key at [linear.app/settings/api](https://linear.app/settings/api). On first use it's saved to `~/.config/elnora-linear/.env` (mode `0600`).
207
+
208
+ **Auto-sync on install.** If `LINEAR_API_KEY` is already set in your environment (or saved at `~/.config/elnora-linear/.env`) when you run `npm install -g`, the postinstall hook automatically populates teams / projects / users / workflows from your Linear workspace — no extra step needed. If no key is reachable, the install prints a notice telling you what to set; the install itself never fails.
209
+
210
+ To populate them later (or refresh after a workspace change):
35
211
 
36
212
  ```sh
37
213
  elnora-linear sync all
38
214
  ```
39
215
 
40
- That fetches your teams, projects, users, and workflow states from the Linear API in one batch.
216
+ That fetches your teams, projects, users, and workflow states from the Linear API.
41
217
 
42
- ## What you get
218
+ Escape hatches for the auto-sync (any one disables it):
219
+ - `ELNORA_LINEAR_SKIP_POSTINSTALL=1`
220
+ - `CI=true` (auto-detected on most CI systems)
221
+ - local (non-global) installs — only `npm install -g` triggers the sync
43
222
 
44
- **Slash commands** (Claude Code)
223
+ **What the sync does and doesn't cover:**
45
224
 
46
- | Command | Does |
47
- |---|---|
48
- | `/linear-search` | Natural-language search across all issues |
49
- | `/linear-my-issues` | Your assigned issues, grouped by state |
50
- | `/linear-bulk` | Apply the same state change or comment to many issues dry-run by default |
51
- | `/linear-cleanup` | Six-check audit (missing labels, stale, duplicates, wrong state, orphaned, unactionable) with per-category confirmation |
52
- | `/linear-sync` | Refresh teams/projects/users/workflows from the Linear API |
53
- | `/linear-curator-run` | Run the curator manually |
225
+ | File | Populated by | Why |
226
+ |---|---|---|
227
+ | `teams.json`, `projects.json`, `users.json`, `workflows.json` | auto-sync | Discoverable from the Linear API |
228
+ | `label-policy.json` | you (ask your agent) | Which labels are *required* per team is a policy choice, not data |
229
+ | `slack.json` | you (ask your agent) | Needs your channel IDs + outbound allowlist |
230
+ | `repos.json` | you (ask your agent) | Needs the GitHub repos you want the curator to watch |
231
+ | `signal-sources.json` | you (ask your agent) | Curator inputs — opt-in per source |
54
232
 
55
- **Agents** (Claude Code)
233
+ The four manual files are only needed if you want the curator. To finish setup, just say to your agent: **"set up my curator config"** it'll walk through each file using the populated examples in `references/*.example.json` as templates.
56
234
 
57
- | Agent | For |
58
- |---|---|
59
- | `linear-issue-creator` | One issue from a description. Fast-path for fully-specified requests |
60
- | `linear-url-to-issues` | N issues extracted from an article, design, blog, or doc URL |
61
- | `linear-issue-updater` | Any modification: state, team, assignee, labels, comment, relations, close |
62
- | `linear-issue-reviewer` | Validates an issue's done-criteria against its linked PR diff |
63
- | `linear-state-curator` | Daily Linear hygiene — runs the curator headlessly |
235
+ ---
236
+
237
+ ## Standalone usage
238
+
239
+ The package is fully useful without Claude Code:
240
+
241
+ ```sh
242
+ elnora-linear issues create "Refactor auth" --team ENG --project "Q3 platform" --priority 2
243
+ elnora-linear issues list --team ENG --state "In Progress" --limit 50 --output json
244
+ elnora-linear bulk --team ENG --state Todo --query bug --add-comment "triage round" --yes
245
+ elnora-linear cleanup --team ENG --stale-days 30 --action comment --yes
246
+ elnora-linear curator-run --dry-run
247
+ ```
64
248
 
65
- **CLI** — every slash-command path is scriptable: `elnora-linear --help`.
249
+ Run `elnora-linear --help` to see every verb.
250
+
251
+ ---
66
252
 
67
253
  ## Configuration
68
254
 
69
- Workspace-specific config lives under `~/.config/elnora-linear/` (override with `LINEAR_REFERENCES_DIR=/some/path`). The npm package ships **placeholders** only; you populate the real files via `elnora-linear sync` or by hand. Populated `references/*.json` files are gitignored at the repo level and excluded from the npm tarball — they never enter source control or a release.
255
+ Workspace-specific config lives under `~/.config/elnora-linear/` (override with `LINEAR_REFERENCES_DIR=/some/path`). The npm package ships **placeholders** only; you populate the real files via `elnora-linear sync` or by hand. Populated `references/*.json` files are gitignored and excluded from the npm tarball — they never enter source control or a release.
70
256
 
71
257
  ```
72
258
  ~/.config/elnora-linear/
@@ -81,38 +267,9 @@ Workspace-specific config lives under `~/.config/elnora-linear/` (override with
81
267
  └── signal-sources.json # curator inputs (manual; see references/signal-sources.example.json)
82
268
  ```
83
269
 
84
- Each file has a JSON Schema in [`schemas/`](schemas/) and a populated example at `references/<name>.example.json`. The loader validates every read against the schema and refuses malformed config in strict mode.
85
-
86
- Run `elnora-linear sync verify` any time to see which files are populated vs placeholder.
87
-
88
- ## The curator
89
-
90
- `elnora-linear curator-run` walks your configured signal sources, builds a snapshot of open issues, calls an LLM (Anthropic) with the workspace's curator rules, and dispatches per tier:
91
-
92
- - **HIGH** — state change applied immediately with a rationale comment. Capped at 20 mutations/run, debounced 14 days per `{issue_id, from, to}`.
93
- - **MEDIUM** — proposed action queued in `~/.config/elnora-linear/state/curator-state.json` for a human (or the Slack bot) to confirm.
94
- - **LOW** — added to the run report, no side effects.
95
-
96
- Every applied action is appended to `~/.config/elnora-linear/state/curator-report.jsonl`. Without `ANTHROPIC_API_KEY` (or with `--collect-only`), the curator runs in diagnostic mode and only reports collected signals.
97
-
98
- Recurring schedule: see [`docs/scheduling.md`](docs/scheduling.md) for launchd, systemd, and Task Scheduler templates.
99
-
100
- ## Safety
101
-
102
- The CLI is built so a prompt-injected agent can't do anything irreversible without a human-typed `--yes`. Soft-delete by default, gated permanent deletes, validated attachment-upload paths, redacted API keys, capped curator mutations. Full guarantees in [SAFETY.md](SAFETY.md).
103
-
104
- ## Standalone usage
105
-
106
- The package is useful without Claude Code:
107
-
108
- ```sh
109
- elnora-linear issues create --team ENG --title "Refactor auth" --priority High
110
- elnora-linear issues list --team ENG --state "In Progress" --limit 50 --output json
111
- elnora-linear bulk --team ENG --state Todo --query bug --add-comment "triage round" --yes
112
- elnora-linear curator-run --dry-run
113
- ```
270
+ Each file has a JSON Schema in [`schemas/`](schemas/) and a populated example at `references/<name>.example.json`. The loader validates every read and refuses malformed config in strict mode. Run `elnora-linear sync verify` any time to see what's populated.
114
271
 
115
- `--output json` makes every read pipe cleanly into `jq` / scripts.
272
+ ---
116
273
 
117
274
  ## Development
118
275
 
@@ -135,6 +292,7 @@ references/ — Bundled placeholders + populated examples (gitignored: *.js
135
292
  agents/ — Claude Code agent definitions (Markdown)
136
293
  commands/ — Claude Code slash-command definitions (Markdown)
137
294
  skills/ — Router skill (Markdown)
295
+ AGENTS.md — Universal dispatch guide (Codex / Cursor / Aider / Continue / Amp / Jules / Roo)
138
296
  templates/ — Linear issue templates for compliance workflows (SOC 2, change mgmt, RCA, …)
139
297
  __tests__/ — Vitest unit + integration tests
140
298
  docs/ — User-facing docs (scheduling, etc.)
@@ -142,6 +300,8 @@ docs/ — User-facing docs (scheduling, etc.)
142
300
 
143
301
  Linting: [Biome](https://biomejs.dev). Tests: [Vitest](https://vitest.dev). Releases: [release-please](https://github.com/googleapis/release-please).
144
302
 
303
+ ---
304
+
145
305
  ## Contributing
146
306
 
147
307
  Issues and PRs welcome. See [.github/CONTRIBUTING.md](.github/CONTRIBUTING.md). Security reports: [.github/SECURITY.md](.github/SECURITY.md) or `security@elnora.ai`.
@@ -40,6 +40,7 @@ elnora-linear issues create "Title" --team "Team" --description "md" \
40
40
  [--assignee "name"|"me"|"none"] [--state "Todo"|"Backlog"] \
41
41
  [--due-date "YYYY-MM-DD"] [--parent "ENG-123"] \
42
42
  [--skip-label-check] # bypass team label-policy validation
43
+ [--skip-project-check] # bypass require-a-project rule (placeholder issues only)
43
44
  elnora-linear relations create ENG-NEW ENG-OLD [--type related|blocks|duplicate|similar]
44
45
  ```
45
46
 
@@ -47,7 +48,12 @@ elnora-linear relations create ENG-NEW ENG-OLD [--type related|blocks|duplicate|
47
48
 
48
49
  **Pitfalls:** `--assignee` (not `--assign`), `--labels` (not `--label`), `--description` (not `--desc`). `--labels` REPLACES existing — for updates, get current first then include all.
49
50
 
50
- **Server-side validation:** `elnora-linear issues create` validates that the proposed labels satisfy the team's policy (from `label-policy.json`). If they don't, the command exits 2 with a structured JSON error containing `missing`, `availableForPrefix`, and `suggestedRetry` — re-run the suggested command verbatim or pick from `availableForPrefix` and retry. You don't need to read any reference file to recover.
51
+ **Server-side validation:** `elnora-linear issues create` validates two things and exits 2 with a structured JSON error on failure:
52
+
53
+ - **Label policy** (`error: "labels_invalid"`): JSON carries `missing`, `availableForPrefix`, `suggestedRetry`. Re-run the suggested command verbatim or pick from `availableForPrefix`.
54
+ - **Project policy** (`error: "project_required"`): fires when the team has projects available and `--project` was omitted. JSON carries `availableProjects: [{name, status}]` and `suggestedRetry`. Pick a project from `availableProjects` and retry, or — only for genuine placeholder issues — pass `--skip-project-check` AND document why in the report.
55
+
56
+ You don't need to read any reference file to recover from either error.
51
57
 
52
58
  ## Metadata completeness — applies to BOTH paths
53
59
 
@@ -55,7 +61,7 @@ Every issue MUST be created with the maximum metadata that can reasonably be inf
55
61
 
56
62
  For every create, you MUST attempt to set:
57
63
 
58
- 1. **Project** — never leave null unless you've checked and genuinely nothing fits. If the user didn't name one, follow the lookup precedence below.
64
+ 1. **Project** — never leave null unless you've checked and genuinely nothing fits. If the user didn't name one, follow the lookup precedence below. The CLI requires `--project` by default (teams with any projects); bare creates without it exit 2 with `ProjectValidationError` (read `availableProjects` from the JSON and retry, or use `--skip-project-check` with a documented reason).
59
65
  2. **Labels** — required labels per the team's policy (mandatory) PLUS any applicable optional labels you can infer (e.g. `Severity: *` if a bug has clear severity signals, `Source: *` if origin is obvious). More signal beats less.
60
66
  3. **Related issues** — every create runs `elnora-linear issues search "2-3 key terms" --limit 5`. If matches look topically related, call `elnora-linear relations create ENG-NEW ENG-OLD --type related` after creation. Do NOT auto-link as `duplicate` or `blocks` — those need user confirmation.
61
67
  4. **Priority + assignee + state + due date** — set whatever the user provided. Don't invent values, but don't drop signals either.
@@ -86,7 +92,7 @@ Use when ALL of these hold:
86
92
  - No compliance keywords: **incident, breach, vulnerability, CVE, pentest, onboarding, offboarding, access provision/revoke, audit, change request, risk assessment, vendor review, backup test, RCA, lessons learned**
87
93
  - No URL in the request
88
94
 
89
- Note: project is NOT required to be explicit — the workflow below will look it up.
95
+ Note: project is NOT required to be explicit in the dispatch — the workflow below looks it up. But the CLI itself now requires `--project` on the create call by default; if your lookup turns up nothing, recover from the `ProjectValidationError` JSON (pick from `availableProjects`) instead of silently omitting.
90
96
 
91
97
  Workflow (typically 2–3 CLI calls):
92
98
 
@@ -108,7 +114,7 @@ Use when any fast-path condition fails (vague title, missing team/project/priori
108
114
  1. **Dupe search:** `elnora-linear issues search "2-3 key terms" --limit 10`. If matches, ASK whether to update existing (→ `linear-issue-updater`), make sub-issue (`--parent`), or new+link (`relations create`).
109
115
  2. **Compliance:** if any compliance keyword above, Read `references/template-index.md` → pick one template → Read `templates/<chosen>.md` → use as `--description` → set due date from `references/sla-reference.md` → apply matching `Template: *` label → route to your workspace's compliance team.
110
116
  3. **Team:** from user → keyword routing (Read `references/workspace-routing.md` if unclear) → fallback to your workspace's default team. If user specified a team, USE IT.
111
- 4. **Project (mandatory):** Read `references/workspace-routing.md` first — keyword match against the Project Keywords table. If still unclear, Read `references/workspace-projects.md` for status/purpose details. Only fall back to `elnora-linear context --team "<Team>"` if the references are stale or the project might be brand new. ASK if still ambiguous. Projects are team-scoped; some span multiple teams — ASK which team. Never create without a project unless the user has explicitly said no project applies AND you've confirmed nothing fits.
117
+ 4. **Project (mandatory):** Read `references/workspace-routing.md` first — keyword match against the Project Keywords table. If still unclear, Read `references/workspace-projects.md` for status/purpose details. Only fall back to `elnora-linear context --team "<Team>"` if the references are stale or the project might be brand new. ASK if still ambiguous. Projects are team-scoped; some span multiple teams — ASK which team. Never create without a project unless the user has explicitly said no project applies AND you've confirmed nothing fits — in that case pass `--skip-project-check` and surface the reason in your final report.
112
118
  5. **State by project status:** `elnora-linear projects get "Project"` returns `currentStatus.recommendedIssueState` directly — pass it to `--state` verbatim. If `recommendedIssueState` is null, the response includes a `warning` field — surface it to the user and pick a different project.
113
119
  6. **Labels:** apply per the team's policy. For exotic labels, call `elnora-linear context --team "<Team>"` instead of reading any reference file.
114
120
  7. **Priority + assignee:** use `AskUserQuestion` if missing — never guess.
@@ -129,7 +135,7 @@ For full-path creates that need a structured description, Read `references/agent
129
135
 
130
136
  After creation, report from the create response JSON:
131
137
  - Issue identifier + URL
132
- - Team, **project** (or explicit "no project — nothing matched" if you genuinely couldn't find a fit), applied labels (required + any optional inferred)
138
+ - Team, **project** (or explicit "no project — nothing matched, --skip-project-check passed because <reason>" if you genuinely couldn't find a fit), applied labels (required + any optional inferred)
133
139
  - Any relations created (and any relation candidates you saw but didn't auto-link)
134
140
  - Anything that was missing/skipped, so the parent knows what to follow up on
135
141
 
@@ -139,7 +145,7 @@ Keep it terse. The parent already knows what they asked for.
139
145
 
140
146
  - [ ] Searched dupes
141
147
  - [ ] Team matches user intent (not overridden by project name)
142
- - [ ] **Project set** (asked if ambiguous; left null only if confirmed nothing fits)
148
+ - [ ] **Project set** (asked if ambiguous; if confirmed nothing fits, `--skip-project-check` passed with reason in report)
143
149
  - [ ] State matches project status
144
150
  - [ ] Required labels for team are present + any applicable optional labels (Severity, Source) inferred
145
151
  - [ ] Related-issue search done; topical matches linked as `related`
@@ -137,7 +137,7 @@ Return a single JSON object with this exact shape — no prose, no markdown fenc
137
137
  - One entry per issue you take a position on. Skip issues with no signal AND no decay condition (don't report them).
138
138
  - Always cite **actual** signals from the snapshot — never invent a PR, commit, or test ID.
139
139
  - If you can't decide between HIGH and MEDIUM, pick MEDIUM. Asking is cheap; a wrong auto-mutation is expensive.
140
- - For MEDIUM, write the `question_text` as a short conversational message TO the assignee — like a colleague pinging them, not a bot reciting evidence. Two short sentences max. Phrase it from the assignee's perspective ("Have you finished X or still working on it?"), then offer the path as a clear choice ("Shall I mark it done or move it to In Progress?"). Talk about the work itself, not PR numbers, signals, or rule codes. Mention the issue ID once for clickability (the bot turns `<TEAM>-NNN` into a Linear link automatically); do NOT include `<@username>` mentions in `question_text` — the bot prepends the @mention itself. No emoji, no Slack markdown decoration. The orchestrator posts it as a top-level message in a configured `allowed_channel` with `@mention` of the assignee anyone allow-listed can reply in the thread (free-form replies are LLM-classified). For label-blocked issues, the orchestrator DMs an allow-listed user instead; the question text should read naturally either way.
140
+ - For MEDIUM, write the `question_text` as a short conversational message TO the assignee — like a colleague pinging them, not a bot reciting evidence. Two short sentences max. Phrase it from the assignee's perspective ("Have you finished X or still working on it?"), then offer the path as a clear choice ("Shall I mark it done or move it to In Progress?"). Talk about the work itself, not PR numbers, signals, or rule codes. Mention the issue ID once for clickability; do NOT include `<@username>` mentions in `question_text` — any future delivery layer will add them itself. No emoji, no Slack markdown decoration. Today the question is staged in `curator-state.json` for a human (or the `linear-state-curator` agent) to read; the Slack-posting + threaded-reply orchestrator described in `curator-tiering-rules.md` is planned but not yet shipped, so write the text so it reads naturally in a plain JSON state file too.
141
141
 
142
142
  Whenever the question offers two paths ("done OR In Progress?", "cancel OR keep open?"), set BOTH `proposed_action` (the more aggressive / "yes" path) AND `alternative_action` (the softer / "no but keep moving" path). The reply handler uses these to apply whichever path the user picks. If the question is truly binary apply-or-skip (e.g. "is this stale, should I close it?"), omit `alternative_action`.
143
143
 
@@ -148,11 +148,11 @@ Return a single JSON object with this exact shape — no prose, no markdown fenc
148
148
  > "@assignee PR #819 is linked to ENG-611 — did that PR actually deliver the work, or is ENG-611 still open? Should I mark it Done?"
149
149
  - For HIGH, write the `rationale` as it will appear verbatim in a Linear comment: cite specific commit SHAs, PR numbers, test IDs.
150
150
  - Hard cap: at most 20 HIGH actions and at most 10 NEW MEDIUM actions in `actions[]`. The orchestrator enforces this too, but match it to keep the output tidy.
151
- - If a HIGH match would touch an issue carrying any of the workspace's never-touch labels (default: `customer:*`, `compliance:*`, `security:critical`, `sla:*`), downgrade to MEDIUM (rule M6) and route the question to the user(s) listed in `slack.json` `allowed_dm_users` regardless of assignee.
151
+ - If a HIGH match would touch an issue carrying any of the workspace's never-touch labels (default: `customer:*`, `compliance:*`, `security:critical`, `sla:*`), downgrade to MEDIUM (rule M6). When the DM-back delivery layer ships, those questions will route to the user(s) in `slack.json` `allowed_dm_users` regardless of assignee; until then they stage in the same `curator-state.json` queue with the assignee in `question_text`.
152
152
 
153
153
  ## Pending question resolution
154
154
 
155
- Reply resolution for pending Slack questions is handled in a separate codepath. The orchestrator runs a dedicated batch-resolver Claude call before invoking you. You do not return resolution decisions; treat the `## Pending Slack questions` snapshot section as awareness only (avoid re-proposing duplicates).
155
+ The Slack reply-resolver is planned but not yet shipped. Today, pending questions are read from `curator-state.json` directly by a human (or the `linear-state-curator` agent on a re-run). Treat the `## Pending Slack questions` snapshot section as awareness only avoid re-proposing duplicates of items already staged there.
156
156
 
157
157
  ## Don't
158
158
 
@@ -39,6 +39,7 @@ elnora-linear issues create "Title" --team "Team" --description "md" \
39
39
  [--project "P"] [--labels "L1,L2"] [--priority 0-4] \
40
40
  [--assignee "name"|"me"|"none"] [--state "Todo"|"Backlog"] \
41
41
  [--skip-label-check] # bypass team label-policy validation
42
+ [--skip-project-check] # bypass require-a-project rule (placeholder issues only)
42
43
  elnora-linear relations create ENG-NEW ENG-OLD --type related|blocks|duplicate|similar
43
44
  ```
44
45
 
@@ -54,7 +55,7 @@ Every issue MUST be created with the maximum metadata that can reasonably be inf
54
55
 
55
56
  For every create, you MUST attempt to set:
56
57
 
57
- 1. **Project** — never leave null. Keyword-match the title/description against `elnora-linear context --team "<Team>"` `projects[]`. Pick the best fit. Only omit `--project` if you've confirmed nothing reasonably matches and report that explicitly ("no matching project; left unassigned").
58
+ 1. **Project** — never leave null. Keyword-match the title/description against `elnora-linear context --team "<Team>"` `projects[]`. Pick the best fit. Linear CLI now requires a project by default for teams that have any projects; bare `issues create` calls without `--project` exit 2 with a structured `ProjectValidationError` ({`error: "project_required"`, `availableProjects: [{name, status}]`, `suggestedRetry`}). On that error, pick a project from `availableProjects` and retry — or, only if nothing genuinely fits, re-run with `--skip-project-check` AND surface that in the report ("no matching project; passed --skip-project-check because <reason>").
58
59
  2. **Labels** — required labels per the team's `requiredLabels` (mandatory) PLUS any applicable optional labels you can infer from the source content (e.g. `Severity: *` for bugs with clear severity, `Source: *` if origin is obvious). More signal beats less.
59
60
  3. **Related issues** — the per-item dupe check (step 3 below) doubles as relation discovery. Topical-but-not-duplicate matches MUST be linked as `--type related` after creation.
60
61
  4. **Sibling links** — if multiple new issues come from the same source URL, link them as `--type related` so the cluster is visible.
@@ -110,12 +111,12 @@ Decision tree on matches:
110
111
  2. Read `references/workspace-projects.md` if you need status/purpose to disambiguate.
111
112
  3. Only fall back to `elnora-linear context --team "<Team>"` if the references are stale or the project might be brand new.
112
113
 
113
- - **Project (mandatory)**: keyword-match the issue title/description per the precedence above. Pick the best fit. Only omit `--project` if NOTHING reasonably fits and surface that in the report.
114
+ - **Project (mandatory by default)**: keyword-match the issue title/description per the precedence above. Pick the best fit. The CLI now rejects creates without `--project` for teams that have projects available (`ProjectValidationError`, exit 2). If NOTHING fits, pass `--skip-project-check` AND document why in the report — never silently omit.
114
115
  - **Project↔team binding**: projects are team-scoped. If a project name truly spans teams, ASK which one.
115
116
  - **Required labels**: per-team policy is enforced server-side by the CLI. For exotic labels call `elnora-linear context --team "<Team>"` and use `labels.byPrefix`.
116
117
  - **Optional labels — infer when signal is clear**: from the source content, also set `Severity: *` for bugs, `Source: *` for known origins, etc. Don't force values that aren't supported by the content.
117
118
 
118
- If you skipped the cold-start `context` call (single-issue run), the structured error from `issues create` carries `availableForPrefix` for any failed validation — re-run the suggested command verbatim.
119
+ If you skipped the cold-start `context` call (single-issue run), the structured error from `issues create` carries `availableForPrefix` (label policy) or `availableProjects` (project policy) for any failed validation — re-run the suggested command verbatim or pick a value from the list and retry.
119
120
 
120
121
  ### 5. Create
121
122
 
@@ -189,7 +190,7 @@ If multiple new issues all derive from the same article, optionally link sibling
189
190
  - [ ] Technical detail traceable to source
190
191
  - [ ] At least one testable acceptance criterion
191
192
  - [ ] Source URL preserved in description
192
- - [ ] **Project set** (or explicit "no project — nothing matched" surfaced)
193
+ - [ ] **Project set** (or `--skip-project-check` passed with explicit "no project — nothing matched: <reason>" surfaced)
193
194
  - [ ] Required labels present + applicable optional labels inferred
194
195
  - [ ] Topical relations linked as `related`; sibling issues from same source linked
195
196
 
package/dist/cli.js CHANGED
@@ -8,6 +8,7 @@ import { readFileSync } from "node:fs";
8
8
  import { dirname, join } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { Command, Option } from "commander";
11
+ import { loadEnvFile } from "./client/auth.js";
11
12
  import { setupAgentActivitiesCommand } from "./commands/agent-activities.js";
12
13
  import { setupAgentSessionsCommand } from "./commands/agent-sessions.js";
13
14
  import { setupAttachmentsCommand } from "./commands/attachments.js";
@@ -44,6 +45,10 @@ import { setupTemplatesCommand } from "./commands/templates.js";
44
45
  import { setupUsersCommand } from "./commands/users.js";
45
46
  import { setupViewsCommand } from "./commands/views.js";
46
47
  import { setupWebhooksCommand } from "./commands/webhooks.js";
48
+ // Hydrate process.env from ~/.config/elnora-linear/.env before any subcommand
49
+ // reads ANTHROPIC_API_KEY, SLACK_TOKEN, etc. Real env vars still win — this
50
+ // only fills in entries that aren't already set.
51
+ loadEnvFile();
47
52
  const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8"));
48
53
  const VERSION = pkg.version;
49
54
  function positiveInt(name) {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,15 @@ export declare class AuthError extends Error {
3
3
  }
4
4
  declare function validateKey(key: string): string;
5
5
  declare function readKeyFromEnvFile(path: string): string | null;
6
+ declare function parseEnvFile(path: string): Record<string, string>;
7
+ /**
8
+ * Load entries from `~/.config/elnora-linear/.env` (or the override path) into
9
+ * `process.env`, without overwriting variables that are already set. Used at
10
+ * CLI startup so secrets persisted to the env file — like `ANTHROPIC_API_KEY`
11
+ * and `SLACK_TOKEN` — are available to downstream code that reads
12
+ * `process.env` directly. Safe to call multiple times.
13
+ */
14
+ export declare function loadEnvFile(path?: string): void;
6
15
  declare function saveKeyToEnvFile(key: string, path?: string): void;
7
16
  export interface GetApiKeyOptions {
8
17
  /** Override env-file path (default: ~/.config/elnora-linear/.env). */
@@ -15,6 +24,7 @@ export declare const _internal: {
15
24
  validateKey: typeof validateKey;
16
25
  readKeyFromEnvFile: typeof readKeyFromEnvFile;
17
26
  saveKeyToEnvFile: typeof saveKeyToEnvFile;
27
+ parseEnvFile: typeof parseEnvFile;
18
28
  DEFAULT_ENV_FILE: string;
19
29
  };
20
30
  export {};