@codyswann/lisa 2.176.12 → 2.178.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/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/agents/linear-agent.md +3 -3
- package/plugins/lisa/rules/eager/integration-access-layer.md +10 -0
- package/plugins/lisa/rules/reference/integration-access-layer.md +56 -0
- package/plugins/lisa/rules/reference/repo-scope-split.md +1 -1
- package/plugins/lisa/skills/intake/SKILL.md +2 -2
- package/plugins/lisa/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa/skills/jam-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa/skills/linear-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/linear-add-journey/SKILL.md +3 -3
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +11 -11
- package/plugins/lisa/skills/linear-create/SKILL.md +3 -3
- package/plugins/lisa/skills/linear-evidence/SKILL.md +5 -5
- package/plugins/lisa/skills/linear-journey/SKILL.md +2 -2
- package/plugins/lisa/skills/linear-prd-intake/SKILL.md +11 -11
- package/plugins/lisa/skills/linear-read-issue/SKILL.md +11 -11
- package/plugins/lisa/skills/linear-sync/SKILL.md +7 -7
- package/plugins/lisa/skills/linear-to-tracker/SKILL.md +7 -7
- package/plugins/lisa/skills/linear-validate-issue/SKILL.md +8 -8
- package/plugins/lisa/skills/linear-verify/SKILL.md +3 -3
- package/plugins/lisa/skills/linear-write-issue/SKILL.md +20 -20
- package/plugins/lisa/skills/linear-write-prd/SKILL.md +6 -6
- package/plugins/lisa/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa/skills/posthog-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/prd-backlink/SKILL.md +5 -5
- package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/skills/repair-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa/skills/sentry-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/setup-linear/SKILL.md +5 -5
- package/plugins/lisa/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa/skills/sonarcloud-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/tracker-journey/SKILL.md +1 -1
- package/plugins/lisa/skills/verify-prd/SKILL.md +2 -2
- package/plugins/lisa-agy/agents/linear-agent.md +3 -3
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/intake/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-agy/skills/linear-add-journey/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/linear-build-intake/SKILL.md +11 -11
- package/plugins/lisa-agy/skills/linear-create/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/linear-evidence/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/linear-journey/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/linear-prd-intake/SKILL.md +11 -11
- package/plugins/lisa-agy/skills/linear-read-issue/SKILL.md +11 -11
- package/plugins/lisa-agy/skills/linear-sync/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/linear-to-tracker/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/linear-validate-issue/SKILL.md +8 -8
- package/plugins/lisa-agy/skills/linear-verify/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/linear-write-issue/SKILL.md +20 -20
- package/plugins/lisa-agy/skills/linear-write-prd/SKILL.md +6 -6
- package/plugins/lisa-agy/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-agy/skills/prd-backlink/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/repair-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-agy/skills/setup-linear/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-agy/skills/tracker-journey/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/verify-prd/SKILL.md +2 -2
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/agents/linear-agent.agent.md +3 -3
- package/plugins/lisa-copilot/rules/eager/integration-access-layer.md +10 -0
- package/plugins/lisa-copilot/rules/reference/integration-access-layer.md +56 -0
- package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +1 -1
- package/plugins/lisa-copilot/skills/intake/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-copilot/skills/linear-add-journey/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/linear-build-intake/SKILL.md +11 -11
- package/plugins/lisa-copilot/skills/linear-create/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/linear-evidence/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/linear-journey/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/linear-prd-intake/SKILL.md +11 -11
- package/plugins/lisa-copilot/skills/linear-read-issue/SKILL.md +11 -11
- package/plugins/lisa-copilot/skills/linear-sync/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/linear-to-tracker/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/linear-validate-issue/SKILL.md +8 -8
- package/plugins/lisa-copilot/skills/linear-verify/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/linear-write-issue/SKILL.md +20 -20
- package/plugins/lisa-copilot/skills/linear-write-prd/SKILL.md +6 -6
- package/plugins/lisa-copilot/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-copilot/skills/prd-backlink/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/repair-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-copilot/skills/setup-linear/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-copilot/skills/tracker-journey/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/verify-prd/SKILL.md +2 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/linear-agent.md +3 -3
- package/plugins/lisa-cursor/rules/integration-access-layer-reference.mdc +61 -0
- package/plugins/lisa-cursor/rules/integration-access-layer.mdc +15 -0
- package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +1 -1
- package/plugins/lisa-cursor/skills/intake/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-cursor/skills/linear-add-journey/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/linear-build-intake/SKILL.md +11 -11
- package/plugins/lisa-cursor/skills/linear-create/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/linear-evidence/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/linear-journey/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/linear-prd-intake/SKILL.md +11 -11
- package/plugins/lisa-cursor/skills/linear-read-issue/SKILL.md +11 -11
- package/plugins/lisa-cursor/skills/linear-sync/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/linear-to-tracker/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/linear-validate-issue/SKILL.md +8 -8
- package/plugins/lisa-cursor/skills/linear-verify/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/linear-write-issue/SKILL.md +20 -20
- package/plugins/lisa-cursor/skills/linear-write-prd/SKILL.md +6 -6
- package/plugins/lisa-cursor/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-cursor/skills/prd-backlink/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/repair-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-cursor/skills/setup-linear/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-cursor/skills/tracker-journey/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/verify-prd/SKILL.md +2 -2
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/agents/linear-agent.md +3 -3
- package/plugins/src/base/rules/eager/integration-access-layer.md +10 -0
- package/plugins/src/base/rules/reference/integration-access-layer.md +56 -0
- package/plugins/src/base/rules/reference/repo-scope-split.md +1 -1
- package/plugins/src/base/skills/intake/SKILL.md +2 -2
- package/plugins/src/base/skills/jam-access/SKILL.md +51 -0
- package/plugins/src/base/skills/linear-access/SKILL.md +90 -0
- package/plugins/src/base/skills/linear-add-journey/SKILL.md +3 -3
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +11 -11
- package/plugins/src/base/skills/linear-create/SKILL.md +3 -3
- package/plugins/src/base/skills/linear-evidence/SKILL.md +5 -5
- package/plugins/src/base/skills/linear-journey/SKILL.md +2 -2
- package/plugins/src/base/skills/linear-prd-intake/SKILL.md +11 -11
- package/plugins/src/base/skills/linear-read-issue/SKILL.md +11 -11
- package/plugins/src/base/skills/linear-sync/SKILL.md +7 -7
- package/plugins/src/base/skills/linear-to-tracker/SKILL.md +7 -7
- package/plugins/src/base/skills/linear-validate-issue/SKILL.md +8 -8
- package/plugins/src/base/skills/linear-verify/SKILL.md +3 -3
- package/plugins/src/base/skills/linear-write-issue/SKILL.md +20 -20
- package/plugins/src/base/skills/linear-write-prd/SKILL.md +6 -6
- package/plugins/src/base/skills/posthog-access/SKILL.md +60 -0
- package/plugins/src/base/skills/prd-backlink/SKILL.md +5 -5
- package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/src/base/skills/repair-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/sentry-access/SKILL.md +56 -0
- package/plugins/src/base/skills/setup-linear/SKILL.md +5 -5
- package/plugins/src/base/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/src/base/skills/tracker-journey/SKILL.md +1 -1
- package/plugins/src/base/skills/verify-prd/SKILL.md +2 -2
- package/scripts/generate-codex-plugin-artifacts.mjs +28 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-sync
|
|
3
3
|
description: "Syncs plan progress to a linked Linear Issue. Posts plan contents, progress updates, branch links, and PR links at key milestones. Use this skill throughout the plan lifecycle to keep Linear Issues in sync. The Linear counterpart of lisa:jira-sync and lisa:github-sync."
|
|
4
|
-
allowed-tools: ["Bash", "Skill"
|
|
4
|
+
allowed-tools: ["Bash", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Sync Plan to Linear: $ARGUMENTS
|
|
@@ -37,7 +37,7 @@ This skill **suggests** transitions but does not auto-transition the native Line
|
|
|
37
37
|
|
|
38
38
|
1. If `$ARGUMENTS` includes an identifier, parse it.
|
|
39
39
|
2. Else search for the active plan file (most recent file under `plans/`) and extract the linked Linear Issue identifier from its frontmatter.
|
|
40
|
-
3. Fetch the Issue via `
|
|
40
|
+
3. Fetch the Issue via `lisa:linear-access operation: get-issue` to confirm it exists.
|
|
41
41
|
|
|
42
42
|
## Phase 2 — Compose Milestone Comment
|
|
43
43
|
|
|
@@ -65,7 +65,7 @@ Next: implementation begins. Suggested status: **Todo** (label: `status:ready`).
|
|
|
65
65
|
|
|
66
66
|
## Phase 3 — Post Comment
|
|
67
67
|
|
|
68
|
-
Call `
|
|
68
|
+
Call `lisa:linear-access operation: save-comment({issueId: <id>, body: <comment>})`.
|
|
69
69
|
|
|
70
70
|
## Phase 3b — Ensure PR Backlink
|
|
71
71
|
|
|
@@ -79,14 +79,14 @@ The PR branch/title/body identifier is the PR -> Linear side. This phase is the
|
|
|
79
79
|
|
|
80
80
|
## Phase 4 — Update Status Label (when caller requests)
|
|
81
81
|
|
|
82
|
-
If the caller passes `--update-label`, update the `status:*` label set via `
|
|
82
|
+
If the caller passes `--update-label`, update the `status:*` label set via `lisa:linear-access operation: save-issue`:
|
|
83
83
|
|
|
84
84
|
- `plan-created` → add `status:ready`
|
|
85
85
|
- `implementation-in-progress` → remove `status:ready`, add `status:in-progress`
|
|
86
86
|
- `pr-ready` → remove `status:in-progress`, add `status:code-review`
|
|
87
87
|
- `pr-merged` → remove `status:code-review`, add `status:done`
|
|
88
88
|
|
|
89
|
-
If the requested label doesn't exist on the team, create it via `
|
|
89
|
+
If the requested label doesn't exist on the team, create it via `lisa:linear-access operation: create-issue-label`.
|
|
90
90
|
|
|
91
91
|
Verify exactly one `status:*` label remains after the update — having two simultaneously breaks the build-queue invariant.
|
|
92
92
|
|
|
@@ -96,7 +96,7 @@ Without `--update-label`, this skill posts the comment only and does NOT touch l
|
|
|
96
96
|
|
|
97
97
|
When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
|
|
98
98
|
|
|
99
|
-
**Resolve the child set the same way `lisa:linear-read-issue` does** — `
|
|
99
|
+
**Resolve the child set the same way `lisa:linear-read-issue` does** — `lisa:linear-access operation: list-issues({project: <id>})` for a Project's Issues, or `lisa:linear-access operation: get-issue` per child for an Issue's sub-Issues (via `parentId`). Capture each child's `status:*` label. If the item has **no** children it is a leaf — rollup is N/A; behave as a normal milestone sync.
|
|
100
100
|
|
|
101
101
|
**Evaluate the required children over the env ladder `in-progress < dev < staging < production` (the ordered keys of the Linear env-keyed `done` map, e.g. `status:on-dev < status:on-stg < status:done`) and take the first match** (canonical roles from `config-resolution`; Linear label map is `status:blocked`, `status:in-progress`, `status:code-review`, env-keyed `done`):
|
|
102
102
|
|
|
@@ -115,7 +115,7 @@ When the caller passes `--rollup`, this skill **derives a parent/container's `st
|
|
|
115
115
|
|
|
116
116
|
**Single-environment collapse (this repo).** The env rungs resolve via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to the single `status:done` label, the only env rung is production, and the lifecycle is `status:ready → status:in-progress → status:code-review → status:done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map and roll a parent up to intermediate env labels (`status:on-dev`/`status:on-stg`).
|
|
117
117
|
|
|
118
|
-
**Apply the derived label** via `
|
|
118
|
+
**Apply the derived label** via `lisa:linear-access operation: save-issue` (Project or Issue), removing the parent's existing `status:*` and adding the derived one so exactly one `status:*` label remains. Post an idempotent rollup comment naming the derived state and the child tally. The native Linear `state` is **not** auto-transitioned — only the `status:*` label, mirroring the `--update-label` rule. **Safe default:** if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env `done`), do not guess — post the derived suggestion as a comment and leave the parent's label untouched.
|
|
119
119
|
|
|
120
120
|
## Rules
|
|
121
121
|
|
|
@@ -6,7 +6,7 @@ description: >
|
|
|
6
6
|
"break down this Linear project", "create tickets from a Linear project", "turn this Linear PRD into tickets", or similar. This skill mirrors `lisa:notion-to-tracker` and `lisa:confluence-to-tracker` for projects
|
|
7
7
|
whose PRDs live in Linear — the workflow, gates, dry-run mode, and validation rules are identical;
|
|
8
8
|
only the source-of-truth tool surface differs (Linear MCP instead of Notion / Confluence MCP).
|
|
9
|
-
allowed-tools: ["Skill", "Bash"
|
|
9
|
+
allowed-tools: ["Skill", "Bash"]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Linear PRD to Tracker Breakdown
|
|
@@ -21,8 +21,8 @@ This skill is the Linear counterpart of `lisa:notion-to-tracker` and `lisa:confl
|
|
|
21
21
|
Linear has no native "PRD" entity. This skill treats a **Linear Project** as the PRD container:
|
|
22
22
|
|
|
23
23
|
- **Project description** (markdown) is the PRD body — equivalent to a Notion page body or a Confluence page body.
|
|
24
|
-
- **Project documents** (Linear's long-form markdown docs attached to projects, fetched via `
|
|
25
|
-
- **Project sub-issues** (`
|
|
24
|
+
- **Project documents** (Linear's long-form markdown docs attached to projects, fetched via `list-documents({projectId})` / `get-document`) are treated as additional spec content and merged into the analysis. A multi-document Linear PRD is the analog of a multi-page Confluence PRD.
|
|
25
|
+
- **Project sub-issues** (`list-issues({project})`) act as the candidate set for epics and user stories — the same role child Epic pages play in a Notion/Confluence PRD.
|
|
26
26
|
- **Linear comments live on Issues, not on Projects.** This skill aggregates comments from every issue under the project to capture decisions and engineering notes. Project-level discussion that isn't reflected on an issue is invisible to this skill.
|
|
27
27
|
|
|
28
28
|
## Modes
|
|
@@ -127,10 +127,10 @@ If env vars are not available, ask the user to provide them explicitly before pr
|
|
|
127
127
|
|
|
128
128
|
### Phase 1: Fetch & Analyze the PRD
|
|
129
129
|
|
|
130
|
-
1. **Resolve the project** via `
|
|
131
|
-
2. **Fetch attached Linear documents** via `
|
|
132
|
-
3. **Identify candidate epics and user stories** from project sub-issues via `
|
|
133
|
-
4. **Fetch full comments per sub-issue** via `
|
|
130
|
+
1. **Resolve the project** via `lisa:linear-access operation: get-project` with the slug or ID, including milestones and resources (`includeMilestones: true`, `includeResources: true`). Capture the project title, description, state, labels, lead, dates, attached documents, attached links.
|
|
131
|
+
2. **Fetch attached Linear documents** via `lisa:linear-access operation: list-documents({projectId})` then `lisa:linear-access operation: get-document` per result. Treat each as additional PRD content. (A Linear PRD with a single rich project description and no attached documents is the common case; multi-document PRDs are valid too.)
|
|
132
|
+
3. **Identify candidate epics and user stories** from project sub-issues via `lisa:linear-access operation: list-issues({project: <id>})`. Capture identifier, title, description, labels, state, parent issue, and `parentId` chain so the issue hierarchy is reproducible.
|
|
133
|
+
4. **Fetch full comments per sub-issue** via `lisa:linear-access operation: list-comments({issueId})` for every issue surfaced in step 3. Walk thread parents/children — comments are threaded via `parentId` references on the comment object.
|
|
134
134
|
5. **Synthesize decisions and blockers** from the project description + every document + every issue comment:
|
|
135
135
|
- Decisions already confirmed by the team (look for agreement in comment threads)
|
|
136
136
|
- Open questions that need product/engineering input
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-validate-issue
|
|
3
3
|
description: "Validates a proposed Linear work item spec (Project, Issue, or sub-Issue) — or an existing Linear item — against the organizational quality gates without writing anything. Returns a structured PASS/FAIL report per gate with concrete remediation. Single source of truth for what makes a valid Linear item — both the write path (linear-write-issue runs it pre-write) and the dry-run path (linear-to-tracker runs it during PRD intake) call this skill so the bar can never drift."
|
|
4
|
-
allowed-tools: ["
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Validate Linear Work Item: $ARGUMENTS
|
|
@@ -65,7 +65,7 @@ build_ready: true # caller asserts the build-ready role (status:
|
|
|
65
65
|
child_refs: ["ENG-601", "ENG-602"] # known child work (sub-issues / project-member issues / blocked_by parentage) — see S15
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
If the caller passes only an identifier, fetch the item via `
|
|
68
|
+
If the caller passes only an identifier, fetch the item via `lisa:linear-access operation: get-issue` (Issue) or `lisa:linear-access operation: get-project` (Project), derive the same fields from the fetched data — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item — then run gates.
|
|
69
69
|
|
|
70
70
|
## Gates
|
|
71
71
|
|
|
@@ -235,28 +235,28 @@ Remediation: `"Build-ready (status:ready) is leaf-only per leaf-only-lifecycle.
|
|
|
235
235
|
|
|
236
236
|
#### F1 — Issue type valid in team
|
|
237
237
|
|
|
238
|
-
For Issue types: confirm the team supports the issue type via `
|
|
238
|
+
For Issue types: confirm the team supports the issue type via `lisa:linear-access operation: get-team`. Linear issue types are typically per-team; check that the requested type exists.
|
|
239
239
|
|
|
240
240
|
For Epic (Project): confirm the team allows projects.
|
|
241
241
|
|
|
242
242
|
#### F2 — Project parent exists and is in same team
|
|
243
243
|
|
|
244
|
-
When `parent_project_id` is set: fetch via `
|
|
244
|
+
When `parent_project_id` is set: fetch via `lisa:linear-access operation: get-project`, confirm it exists and belongs to the configured team.
|
|
245
245
|
|
|
246
|
-
When `parent_issue_id` is set (Sub-task case): fetch via `
|
|
246
|
+
When `parent_issue_id` is set (Sub-task case): fetch via `lisa:linear-access operation: get-issue`, confirm the issue is non-Sub-task and in the same team / project.
|
|
247
247
|
|
|
248
248
|
#### F3 — Linked items exist
|
|
249
249
|
|
|
250
|
-
For each entry in `relations`, call `
|
|
250
|
+
For each entry in `relations`, call `lisa:linear-access operation: get-issue` to confirm the identifier resolves. Flag broken identifiers.
|
|
251
251
|
|
|
252
252
|
#### F4 — Required labels exist (or can be created)
|
|
253
253
|
|
|
254
|
-
For each label referenced (`status:*`, `component:<name>`, `prd-*`), confirm via `
|
|
254
|
+
For each label referenced (`status:*`, `component:<name>`, `prd-*`), confirm via `lisa:linear-access operation: list-issue-labels` (or `lisa:linear-access operation: list-project-labels` for Project labels) that it exists OR is creatable. Linear labels are team-scoped or workspace-scoped; flag if the requested scope is wrong.
|
|
255
255
|
|
|
256
256
|
## Execution
|
|
257
257
|
|
|
258
258
|
1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item. Otherwise parse the YAML spec.
|
|
259
|
-
2. Resolve team ID via `
|
|
259
|
+
2. Resolve team ID via `lisa:linear-access operation: list-teams({query: <teamKey>})` if any feasibility gate will run.
|
|
260
260
|
3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
|
|
261
261
|
4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
|
|
262
262
|
5. Emit the report below.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-verify
|
|
3
3
|
description: "Verifies a Linear work item meets organizational standards by fetching the live item and running it through lisa:linear-validate-issue. Catches anything dropped or reformatted on write — same gates as the pre-write check, but applied to what Linear actually stored. Read-only."
|
|
4
|
-
allowed-tools: ["Bash", "Skill"
|
|
4
|
+
allowed-tools: ["Bash", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Verify Linear Work Item: $ARGUMENTS
|
|
@@ -25,14 +25,14 @@ If `$ARGUMENTS` is not parseable, stop and report.
|
|
|
25
25
|
## Phase 1 — Resolve Context
|
|
26
26
|
|
|
27
27
|
1. Read `linear.workspace`, `linear.teamKey` from `.lisa.config.json` (with `.local` override).
|
|
28
|
-
2. Resolve team ID via `
|
|
28
|
+
2. Resolve team ID via `lisa:linear-access operation: list-teams({query: <teamKey>})`.
|
|
29
29
|
3. Determine entity type from the identifier shape:
|
|
30
30
|
- `<TEAM>-<n>` → Issue
|
|
31
31
|
- URL containing `/project/<slug>-<id>` → Project
|
|
32
32
|
|
|
33
33
|
## Phase 2 — Fetch Live State
|
|
34
34
|
|
|
35
|
-
Call `
|
|
35
|
+
Call `lisa:linear-access operation: get-issue` (for Issues) or `lisa:linear-access operation: get-project` (for Projects). Capture every field, label, relation, comment, milestone, and project membership.
|
|
36
36
|
|
|
37
37
|
## Phase 3 — Delegate to Validator
|
|
38
38
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-write-issue
|
|
3
3
|
description: "Creates or updates a Linear work item — Project (Epic), Issue (Story), or sub-Issue (Sub-task) — following organizational best practices. Polymorphic: dispatches internally on issue_type to save_project (Epic) or save_issue (Story / Sub-task). Enforces description quality (three audiences), Gherkin acceptance criteria, project-as-parent for Stories, parentId for Sub-tasks, explicit relationship discovery (blocks / is blocked by / relates to / duplicates), labels, components-as-labels, project milestones for fix versions, native priority and estimate fields, and Validation Journey. Rejects thin items — use this skill any time a Linear work item is created or significantly edited."
|
|
4
|
-
allowed-tools: ["Bash", "Skill"
|
|
4
|
+
allowed-tools: ["Bash", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Write Linear Work Item: $ARGUMENTS
|
|
@@ -25,11 +25,11 @@ Linear's data model maps Epic / Story / Sub-task to **different entity types**.
|
|
|
25
25
|
|
|
26
26
|
| `issue_type` | Linear entity | MCP write tool | Parent field |
|
|
27
27
|
|--------------|---------------|----------------|--------------|
|
|
28
|
-
| `Epic` | **Project** | `
|
|
29
|
-
| `Story` / `Task` / `Improvement` | **Issue** | `
|
|
30
|
-
| `Sub-task` | **sub-Issue** | `
|
|
31
|
-
| `Bug` | **Issue** | `
|
|
32
|
-
| `Spike` | **Issue** | `
|
|
28
|
+
| `Epic` | **Project** | `lisa:linear-access operation: save-project` | (none — Projects are top-level within a team) |
|
|
29
|
+
| `Story` / `Task` / `Improvement` | **Issue** | `lisa:linear-access operation: save-issue` | `projectId` (the Epic Project) |
|
|
30
|
+
| `Sub-task` | **sub-Issue** | `lisa:linear-access operation: save-issue` | `parentId` (the Story Issue) |
|
|
31
|
+
| `Bug` | **Issue** | `lisa:linear-access operation: save-issue` | `projectId` if part of an Epic; else top-level |
|
|
32
|
+
| `Spike` | **Issue** | `lisa:linear-access operation: save-issue` | `projectId` if part of an Epic; else top-level |
|
|
33
33
|
|
|
34
34
|
Status workflow uses **labels** (`status:ready`, `status:in-progress`, `status:on-dev`, `status:done`) for portability across teams — Linear's per-team workflow state names vary, but labels are workspace-scoped and stable. Native Linear `state` is set to the team's default `Todo` state on create.
|
|
35
35
|
|
|
@@ -40,7 +40,7 @@ Determine from `$ARGUMENTS` and context whether this is a CREATE or UPDATE:
|
|
|
40
40
|
- **CREATE**: no existing identifier provided.
|
|
41
41
|
- **UPDATE**: identifier provided (`<TEAM>-<n>` for Issue, project slug + short-id for Project) — call `/linear-read-issue <ref>` first to load the full current state. Never overwrite without reading.
|
|
42
42
|
|
|
43
|
-
Resolve the team ID for `linear.teamKey` via `
|
|
43
|
+
Resolve the team ID for `linear.teamKey` via `lisa:linear-access operation: list-teams({query: <teamKey>})`. Cache it.
|
|
44
44
|
|
|
45
45
|
## Phase 2 — Gather Required Inputs
|
|
46
46
|
|
|
@@ -129,7 +129,7 @@ If the parent is explicitly provided, use it. Otherwise:
|
|
|
129
129
|
|
|
130
130
|
1. Search active Projects in the team:
|
|
131
131
|
```text
|
|
132
|
-
|
|
132
|
+
lisa:linear-access operation: list-projects({team: <teamKey>, state: ["backlog", "planned", "started"]})
|
|
133
133
|
```
|
|
134
134
|
Match on keywords from the summary and description.
|
|
135
135
|
2. If no matching Project exists, stop and ask the human to create or pick one. Do NOT orphan the item.
|
|
@@ -152,16 +152,16 @@ If the git search surfaces a PR or commit that relates to this work, capture the
|
|
|
152
152
|
|
|
153
153
|
```text
|
|
154
154
|
# Open items in the same Project
|
|
155
|
-
|
|
155
|
+
lisa:linear-access operation: list-issues({project: <projectId>, state_type: ["unstarted", "started"]})
|
|
156
156
|
|
|
157
157
|
# Open items with overlapping keywords (workspace-wide)
|
|
158
|
-
|
|
158
|
+
lisa:linear-access operation: list-issues({query: "<keyword>", state_type: ["unstarted", "started"]})
|
|
159
159
|
|
|
160
160
|
# Items with shared labels
|
|
161
|
-
|
|
161
|
+
lisa:linear-access operation: list-issues({label: "<label>", updatedAt: ">-30d"})
|
|
162
162
|
|
|
163
163
|
# Recently closed items in the same Project
|
|
164
|
-
|
|
164
|
+
lisa:linear-access operation: list-issues({project: <projectId>, state_type: ["completed", "canceled"], updatedAt: ">-30d"})
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
**Record the outcome.** Add a `## Relationship Search` subsection (or a comment if updating) listing the queries you ran and what they returned. If the searches yielded nothing, write that explicitly — "Searched git history for `<keywords>` and Linear for project=`X`, label=`Y`; no related work found." An item with zero relations and no documented search is rejected.
|
|
@@ -229,7 +229,7 @@ The validator is the **single source of truth** for what makes a valid Linear wo
|
|
|
229
229
|
If the validator reports `FAIL`:
|
|
230
230
|
- Surface the failure list and the per-gate remediation to the user.
|
|
231
231
|
- Do NOT proceed to Phase 6. Fix the spec (or stop and ask the human) and re-run validation.
|
|
232
|
-
- Never call `
|
|
232
|
+
- Never call `lisa:linear-access operation: save-project` or `lisa:linear-access operation: save-issue` while the validator's verdict is FAIL.
|
|
233
233
|
|
|
234
234
|
If the validator reports `PASS`, continue to Phase 6.
|
|
235
235
|
|
|
@@ -237,15 +237,15 @@ If the validator reports `PASS`, continue to Phase 6.
|
|
|
237
237
|
|
|
238
238
|
### CREATE — Epic (Project)
|
|
239
239
|
|
|
240
|
-
1. Resolve any required Project labels (`prd-ticketed`, etc.) via `
|
|
241
|
-
2. Call `
|
|
240
|
+
1. Resolve any required Project labels (`prd-ticketed`, etc.) via `lisa:linear-access operation: list-project-labels` (create via `lisa:linear-access operation: create-project-label` if missing).
|
|
241
|
+
2. Call `lisa:linear-access operation: save-project` with: `name` (summary), `description` (markdown), `teamIds: [<teamId>]`, `labelIds`, `priority` (Linear Project priority is also 0–4), `state` (default `backlog`), milestones if dated.
|
|
242
242
|
3. Capture the returned Project ID and slug — Phase 4 children need these.
|
|
243
243
|
4. If the Project is the parent for downstream Stories, record the ID for `lisa:linear-to-tracker` Phase 4 to use.
|
|
244
244
|
|
|
245
245
|
### CREATE — Story / Task / Bug / Spike / Improvement (Issue with projectId)
|
|
246
246
|
|
|
247
|
-
1. Resolve any required Issue labels (`component:<name>`, `prd-intake-feedback` only if this is a sentinel issue, etc.) via `
|
|
248
|
-
2. Call `
|
|
247
|
+
1. Resolve any required Issue labels (`component:<name>`, `prd-intake-feedback` only if this is a sentinel issue, etc.) via `lisa:linear-access operation: list-issue-labels` (create via `lisa:linear-access operation: create-issue-label` if missing). Include `status:ready` in `labelIds` only for a **leaf** work unit and only when `build_ready` is not `false` (per the Build-ready control input) — omit it for a container, and for a `build_ready: false` leaf which then waits in the backlog for a human to promote it.
|
|
248
|
+
2. Call `lisa:linear-access operation: save-issue` with: `team` (teamId), `title` (summary), `description` (markdown), `projectId` (the Epic Project), `priority` (0–4), `estimate`, `labelIds`, `assignee` if known.
|
|
249
249
|
3. Capture the returned identifier (e.g. `ENG-123`) — Phase 4 sub-tasks need it as `parentId`.
|
|
250
250
|
4. Add relationships from Phase 4b via `save_issue` (relations field) or paired relation calls.
|
|
251
251
|
5. If the item changes runtime behavior, invoke `lisa:linear-add-journey` to append the Validation Journey section.
|
|
@@ -253,13 +253,13 @@ If the validator reports `PASS`, continue to Phase 6.
|
|
|
253
253
|
### CREATE — Sub-task (Issue with parentId)
|
|
254
254
|
|
|
255
255
|
1. Resolve labels as above.
|
|
256
|
-
2. Call `
|
|
256
|
+
2. Call `lisa:linear-access operation: save-issue` with: `team` (teamId), `title` (`[<repo>] <summary>` prefix is mandatory), `description` (markdown), `parentId` (the Story Issue ID), `projectId` (inherit from parent), `priority`, `estimate`, `labelIds`.
|
|
257
257
|
3. Capture identifier.
|
|
258
258
|
4. Add relationships via Phase 4b.
|
|
259
259
|
|
|
260
260
|
### UPDATE
|
|
261
261
|
|
|
262
|
-
1. Call `
|
|
262
|
+
1. Call `lisa:linear-access operation: save-project` or `lisa:linear-access operation: save-issue` with **only the fields being changed**. Do NOT resend fields that weren't in the change set — Linear treats the call as a full overwrite of the listed fields.
|
|
263
263
|
2. Preserve description sections you are not editing — re-read via `/linear-read-issue` first, including any existing canonical managed `## Lisa Usage` section unless the caller intentionally supplied an updated canonical section. Use the shared `usage-accounting` serializer/merge path rather than freehand edits to ledger rows.
|
|
264
264
|
|
|
265
265
|
## Phase 7 — Verify
|
|
@@ -268,7 +268,7 @@ Call the `lisa:linear-verify` skill on the resulting item. `lisa:linear-verify`
|
|
|
268
268
|
|
|
269
269
|
## Phase 8 — Announce
|
|
270
270
|
|
|
271
|
-
Post a creation comment via `
|
|
271
|
+
Post a creation comment via `lisa:linear-access operation: save-comment` (on the Issue, or on a sentinel issue under the Project for Epic-level announcements) with:
|
|
272
272
|
|
|
273
273
|
- `[<repo>]` prefix if the item is repo-scoped
|
|
274
274
|
- Who the item is assigned to (if known)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-write-prd
|
|
3
3
|
description: "Creates or idempotently updates a PRD as a Linear Project carrying exactly one PRD lifecycle project-label (`prd-draft` by default, or `prd-ready` when initial_role is ready so lisa:linear-prd-intake auto-claims it). The Linear PRD-source writer behind lisa:prd-source-write. Dedupes by a stable marker embedded in the Project description (matched by marker, never by name). Uses the Linear MCP."
|
|
4
|
-
allowed-tools: ["Skill", "Bash"
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Write Linear PRD: $ARGUMENTS
|
|
@@ -37,17 +37,17 @@ PROGRESSED=("$PRD_IN_REVIEW" "$PRD_BLOCKED" "$PRD_TICKETED" "$PRD_SHIPPED" "$PRD
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
Resolve the target project-label from `initial_role`: `ready` → `$PRD_READY`, else `$PRD_DRAFT`.
|
|
40
|
-
Resolve its label id via `
|
|
41
|
-
`
|
|
40
|
+
Resolve its label id via `lisa:linear-access operation: list-project-labels` (create via
|
|
41
|
+
`lisa:linear-access operation: create-project-label` if missing).
|
|
42
42
|
|
|
43
43
|
## Phase 2 — Dedupe by marker (search before create)
|
|
44
44
|
|
|
45
45
|
The `marker` is embedded in the Project description. Find an existing Project carrying it — match the
|
|
46
46
|
marker, **never** the project name:
|
|
47
47
|
|
|
48
|
-
1. `
|
|
48
|
+
1. `lisa:linear-access operation: list-projects` scoped to the team/workspace (filtered by the `prd-*` label
|
|
49
49
|
set when supported), then inspect each candidate's description via
|
|
50
|
-
`
|
|
50
|
+
`lisa:linear-access operation: get-project` for the marker. If `source_ref` was passed, target it directly.
|
|
51
51
|
2. If a Project with the marker exists → **update**; else → **create**.
|
|
52
52
|
|
|
53
53
|
## Phase 3 — Create or update
|
|
@@ -59,7 +59,7 @@ dedupe. If the live Project description already contains the canonical managed `
|
|
|
59
59
|
section, preserve it verbatim unless the caller intentionally supplied an updated canonical section;
|
|
60
60
|
use the shared `usage-accounting` serializer/merge path rather than hand-editing ledger rows.
|
|
61
61
|
|
|
62
|
-
**CREATE:** `
|
|
62
|
+
**CREATE:** `lisa:linear-access operation: save-project` with:
|
|
63
63
|
- `name`: `$TITLE`
|
|
64
64
|
- `description`: the marker-normalized full PRD markdown
|
|
65
65
|
- `teamIds`: `[<resolved team id>]`
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: posthog-access
|
|
3
|
+
description: "Vendor-neutral access layer for PostHog. PostHog skills and observability rules MUST delegate through this skill rather than calling PostHog MCP tools or REST directly. Resolves PostHog MCP first when available, then falls back to POSTHOG_PERSONAL_API_KEY bearer auth."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PostHog Access: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Single chokepoint for PostHog operations. Caller skills and rules MUST NOT call
|
|
10
|
+
`mcp__posthog__*` tools or PostHog REST directly.
|
|
11
|
+
|
|
12
|
+
## Invocation Contract
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
operation: query project_id:<ID> payload:{...}
|
|
16
|
+
operation: insights project_id:<ID>
|
|
17
|
+
operation: persons project_id:<ID> [query:<QUERY>]
|
|
18
|
+
operation: events project_id:<ID> [after:<ISO>] [before:<ISO>]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Return parsed JSON in a `<result>` block.
|
|
22
|
+
|
|
23
|
+
## Substrate Selection
|
|
24
|
+
|
|
25
|
+
Probe in order:
|
|
26
|
+
|
|
27
|
+
1. PostHog MCP, if available and authenticated.
|
|
28
|
+
2. `POSTHOG_PERSONAL_API_KEY` bearer token against the configured PostHog host.
|
|
29
|
+
|
|
30
|
+
PostHog documents personal API keys and bearer authentication. The headless REST
|
|
31
|
+
tier uses:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
POSTHOG_HOST=${POSTHOG_HOST:-https://app.posthog.com}
|
|
35
|
+
posthog_api() {
|
|
36
|
+
local path="$1"
|
|
37
|
+
local method="${2:-GET}"
|
|
38
|
+
local body="${3:-}"
|
|
39
|
+
[ -n "$POSTHOG_PERSONAL_API_KEY" ] || {
|
|
40
|
+
echo "Error: POSTHOG_PERSONAL_API_KEY is not set." >&2
|
|
41
|
+
return 1
|
|
42
|
+
}
|
|
43
|
+
local args=(-sS -X "$method" -H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY")
|
|
44
|
+
[ -n "$body" ] && args+=(-H "Content-Type: application/json" --data-binary "$body")
|
|
45
|
+
curl "${args[@]}" "${POSTHOG_HOST%/}/api${path}"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If neither tier works, fail with:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
Error: no PostHog access substrate available. Authenticate the PostHog MCP or set POSTHOG_PERSONAL_API_KEY.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Invariants
|
|
56
|
+
|
|
57
|
+
- Fallback is gated on `POSTHOG_PERSONAL_API_KEY`.
|
|
58
|
+
- `POSTHOG_HOST` defaults to PostHog Cloud but can point at a self-hosted
|
|
59
|
+
deployment.
|
|
60
|
+
- Consumer skills do not embed PostHog REST paths.
|
|
@@ -162,7 +162,7 @@ Linear models top-level grouping two ways, and the PRD's own entity type decides
|
|
|
162
162
|
- **PRD is a Linear Project** (the common case — a PRD project groups its generated work). Generated top-level **Issues** are attached to the PRD by setting their `projectId` to the PRD Project's id. The Project *is* the native parent of its Issues; no separate parent-issue link is needed.
|
|
163
163
|
- **PRD is a Linear Issue** (a parent issue, not a project). Generated top-level Issues are attached as native **sub-Issues** of the PRD Issue by setting their `parentId` to the PRD Issue's id.
|
|
164
164
|
|
|
165
|
-
Either way the write surface is `
|
|
165
|
+
Either way the write surface is `lisa:linear-access operation: save-issue` with the single relevant field (`projectId` or `parentId`) — the same primitive `lisa:linear-write-issue` uses to set a Story's `projectId` (Epic Project) and a Sub-task's `parentId` (Story Issue). Send **only** that field on update; Linear treats `save_issue` as a full overwrite of the fields named (`lisa:linear-write-issue` Phase 6 UPDATE), so resending other fields would clobber them.
|
|
166
166
|
|
|
167
167
|
### What gets linked — generated top-level work only
|
|
168
168
|
|
|
@@ -178,14 +178,14 @@ So if the PRD generated `Epic E1 (Project) → Story S1 (Issue) → Sub-task T1
|
|
|
178
178
|
The dedupe key is **child-ref identity** — the Linear issue/project identifier (e.g. `TEAM-123`) or its UUID — per the `prd-lifecycle-rollup` idempotency rule. Before attaching any child, read the PRD's current children and skip any child already attached, so re-running `prd-backlink` never duplicates a relationship and is a no-op when everything is already attached.
|
|
179
179
|
|
|
180
180
|
1. **Read the PRD's existing children** (the same reads `lisa:linear-read-issue` uses for Project members and sub-Issues):
|
|
181
|
-
- PRD-as-Project → `
|
|
182
|
-
- PRD-as-Issue → `
|
|
181
|
+
- PRD-as-Project → `lisa:linear-access operation: list-issues({project: <prd_project_id>})` and collect each member Issue's identifier/UUID.
|
|
182
|
+
- PRD-as-Issue → `lisa:linear-access operation: get-issue({id: <prd_issue_id>})` and collect its sub-Issue identifiers/UUIDs.
|
|
183
183
|
|
|
184
184
|
The resulting identifiers/UUIDs are the existing child-ref set.
|
|
185
185
|
|
|
186
186
|
2. **For each generated top-level item** whose child-ref is **not** already in that set, attach it with a single-field `save_issue`:
|
|
187
|
-
- PRD-as-Project → `
|
|
188
|
-
- PRD-as-Issue → `
|
|
187
|
+
- PRD-as-Project → `lisa:linear-access operation: save-issue({id: <child_id>, projectId: <prd_project_id>})`.
|
|
188
|
+
- PRD-as-Issue → `lisa:linear-access operation: save-issue({id: <child_id>, parentId: <prd_issue_id>})`.
|
|
189
189
|
|
|
190
190
|
A child already in the existing-children set is a no-op — do not issue the `save_issue` call for it. Reading the child's current `projectId`/`parentId` and finding it already equal to the PRD's id is the same no-op (attaching to the value it already holds changes nothing).
|
|
191
191
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prd-ticket-coverage
|
|
3
3
|
description: "Verifies that every requirement in a PRD (Notion, Confluence, Linear, or GitHub Issues) is covered by at least one created destination ticket (JIRA, GitHub Issues, or Linear) — no silent drops. Parses the PRD into atomic items (goals, user stories, functional/non-functional requirements, acceptance criteria, important notes), maps each to the created tickets, and produces a coverage matrix and verdict (COMPLETE / COMPLETE_WITH_SCOPE_CREEP / GAPS_FOUND / NO_TICKETS_FOUND). Used by notion-prd-intake / confluence-prd-intake / linear-prd-intake / github-prd-intake post-write to gate the Ticketed transition; can also be invoked standalone for after-the-fact audits."
|
|
4
|
-
allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getConfluencePageFooterComments", "mcp__atlassian__getConfluencePageInlineComments", "mcp__atlassian__getConfluenceCommentChildren", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"
|
|
4
|
+
allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getConfluencePageFooterComments", "mcp__atlassian__getConfluencePageInlineComments", "mcp__atlassian__getConfluenceCommentChildren", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# PRD Ticket Coverage Audit: $ARGUMENTS
|
|
@@ -15,7 +15,7 @@ The PRD URL can be a **Notion page URL**, a **Confluence page URL**, a **Linear
|
|
|
15
15
|
|
|
16
16
|
- `notion.so` / `notion.site` → Notion. Fetch with `mcp__claude_ai_Notion__notion-fetch` (`include_discussions: true`) and `mcp__claude_ai_Notion__notion-get-comments`.
|
|
17
17
|
- Atlassian Confluence host (e.g. `*.atlassian.net/wiki/...`) → Confluence. Fetch with `mcp__atlassian__getConfluencePage`, `mcp__atlassian__getConfluencePageDescendants` (for child epic pages), `mcp__atlassian__getConfluencePageFooterComments`, `mcp__atlassian__getConfluencePageInlineComments`, and `mcp__atlassian__getConfluenceCommentChildren` for nested replies.
|
|
18
|
-
- `linear.app` host → Linear. Fetch with `
|
|
18
|
+
- `linear.app` host → Linear. Fetch with `lisa:linear-access operation: get-project` (capture description, labels, state, attached resources), `lisa:linear-access operation: list-documents({projectId})` + `lisa:linear-access operation: get-document` per attached document, `lisa:linear-access operation: list-issues({project})` for sub-issues that act as child epics / user stories, and `lisa:linear-access operation: list-comments({issueId})` per sub-issue for decisions and engineering notes. Comments do not exist on the project itself in the MCP surface — sub-issue comments are the substitute.
|
|
19
19
|
- `github.com` host → GitHub Issues. Fetch with the `gh` CLI (no GitHub MCP — Lisa uses the CLI exclusively for GitHub):
|
|
20
20
|
- `gh issue view <number> --repo <org>/<repo> --json number,title,body,labels,milestone,assignees,author,createdAt,comments,url` for the PRD body and comments.
|
|
21
21
|
- `gh api graphql` with the `subIssues` field for native sub-issue children (these stand in for child epic pages — see `lisa:github-read-issue` Phase 3 for the exact query).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: repair-intake
|
|
3
3
|
description: "Vendor-agnostic repair scanner — the recovery counterpart to lisa:intake. Where intake claims `ready` work, repair-intake finds work that got stuck or was left half-closed: items left in `blocked`, stalled in an in-progress role (build `claimed`, PRD `in_review`), terminal-labeled items that are still natively open, and rollup/container items whose children are all terminal but whose parent is not closed out. Scans the same queues lisa:intake serves (Notion / Confluence / Linear / GitHub PRD databases; JIRA / GitHub / Linear build queues), enumerates candidates up to `max_candidates`, and repairs every materially actionable one in that bounded set: resumes stalled in-progress work IN PLACE (build → the vendor agent + the scanner's post-agent transition; PRD → the source `*-to-tracker` dry-run validate→route pipeline) — but for a stalled build it first diagnoses the PR/deploy state: a PR that already merged is recovered by applying the env transition build-intake never got to (no re-dispatch); a PR that is merely behind its base is re-synced in place via `gh pr update-branch` so the already-enabled auto-merge can land (a clean rebase needs no human); and only a PR that cannot merge for a non-mechanical reason (true conflict, failing checks, unaddressed CodeRabbit/changes-requested) or a failed deploy gets a build-ready leaf fix ticket with the item moved to `blocked` (blocked by that ticket) rather than re-dispatching, re-validates blocked PRDs when new clarifying answers exist, re-dispatches blocked build items whose `is blocked by` dependencies have since closed OR whose validation/quality-gate self-block now re-validates PASS (re-running `lisa:tracker-validate` against current content — the build mirror of PRD re-validation), performs terminal native closure for terminal-labeled items, reconciles parent rollups to their derived state per leaf-only-lifecycle — including the intermediate-env case (e.g. all children at `On Stg` → parent `On Stg`) and a container wrongly stuck in `ready` — and closes out rollups whose associated child work is fully terminal. Idempotent, loop-protected via a [lisa-repair-intake] marker + state fingerprint + backoff. Never mutates product-owned states (`draft`, `verified`) and never touches `ready` leaves (a container wrongly carrying `ready` is the one exception — it is rolled up from its children, since `ready` on a parent is an invariant violation, not intake's claim signal). Designed as a /schedule cron target running alongside lisa:intake."
|
|
4
|
-
allowed-tools: ["Skill", "Bash", "Read", "Write", "Edit"
|
|
4
|
+
allowed-tools: ["Skill", "Bash", "Read", "Write", "Edit"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Repair Intake: $ARGUMENTS
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sentry-access
|
|
3
|
+
description: "Vendor-neutral access layer for Sentry. Sentry-oriented skills MUST delegate through this skill rather than calling Sentry MCP tools, sentry-cli, or REST directly. Resolves Sentry MCP/CLI first when available, then falls back to SENTRY_AUTH_TOKEN + Sentry REST API."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sentry Access: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Single chokepoint for Sentry operations. Caller skills MUST NOT call
|
|
10
|
+
`mcp__sentry__*`, `sentry-cli`, or `https://sentry.io/api/` directly.
|
|
11
|
+
|
|
12
|
+
## Invocation Contract
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
operation: list-issues org:<ORG> project:<PROJECT> query:<QUERY> [environment:<ENV>]
|
|
16
|
+
operation: get-issue issue_id:<ID>
|
|
17
|
+
operation: events org:<ORG> project:<PROJECT> query:<QUERY>
|
|
18
|
+
operation: releases org:<ORG> project:<PROJECT>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Return parsed JSON in a `<result>` block.
|
|
22
|
+
|
|
23
|
+
## Substrate Selection
|
|
24
|
+
|
|
25
|
+
Probe in order:
|
|
26
|
+
|
|
27
|
+
1. Sentry MCP, if available and authenticated.
|
|
28
|
+
2. `sentry-cli`, if installed and authenticated to the requested org/project.
|
|
29
|
+
3. `SENTRY_AUTH_TOKEN` bearer token against Sentry REST.
|
|
30
|
+
|
|
31
|
+
Sentry documents API auth tokens for REST API calls. The headless REST tier uses:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
sentry_api() {
|
|
35
|
+
local path="$1"
|
|
36
|
+
[ -n "$SENTRY_AUTH_TOKEN" ] || {
|
|
37
|
+
echo "Error: SENTRY_AUTH_TOKEN is not set." >&2
|
|
38
|
+
return 1
|
|
39
|
+
}
|
|
40
|
+
curl -sS "https://sentry.io/api/0${path}" \
|
|
41
|
+
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If neither tier works, fail with:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Error: no Sentry access substrate available. Authenticate Sentry MCP/CLI or set SENTRY_AUTH_TOKEN.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Invariants
|
|
52
|
+
|
|
53
|
+
- Fallback is gated on `SENTRY_AUTH_TOKEN`.
|
|
54
|
+
- Org/project come from `.sentryclirc`, `.lisa.config.json`, or explicit
|
|
55
|
+
operation args; never infer by searching all accessible orgs.
|
|
56
|
+
- Consumer skills do not embed Sentry REST paths.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-linear
|
|
3
3
|
description: "Configure Linear as the destination tracker and/or the PRD source for this project. Verifies Linear access (MCP OAuth or a personal API key in OS keychain), resolves the workspace slug and team key, scaffolds the build-queue issue-label namespace (`status:*`) when Linear is the tracker and/or the PRD-lifecycle project-label namespace (`prd-*` + issue-level sentinel) when Linear is the PRD source, writes the `linear` section into `.lisa.config.json`, and offers to set top-level `tracker: \"linear\"` and/or `source: \"linear\"`. Idempotent — re-running updates the existing section and reuses existing labels. No /lisa:setup:atlassian prerequisite."
|
|
4
|
-
allowed-tools: ["Bash", "Read", "Write", "Edit", "Skill", "AskUserQuestion", "mcp__linear-server__authenticate", "mcp__linear-server__complete_authentication"
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Write", "Edit", "Skill", "AskUserQuestion", "mcp__linear-server__authenticate", "mcp__linear-server__complete_authentication"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Setup Linear: $ARGUMENTS
|
|
@@ -40,7 +40,7 @@ The role answer drives Step 3 (which label namespaces to scaffold) and whether `
|
|
|
40
40
|
Verify the Linear MCP is authenticated to the right workspace by listing teams:
|
|
41
41
|
|
|
42
42
|
```text
|
|
43
|
-
|
|
43
|
+
lisa:linear-access operation: list-teams({})
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
If it errors / returns nothing, run `mcp__linear-server__authenticate` and have the user complete OAuth in the browser, then `mcp__linear-server__complete_authentication`, then re-list. A non-empty team list confirms the MCP is authed to a readable workspace.
|
|
@@ -137,7 +137,7 @@ echo "Linear key validated. Org: $(echo "$VIEWER" | jq -r '.data.organization.ur
|
|
|
137
137
|
### Step 2 — Resolve workspace slug + team key
|
|
138
138
|
|
|
139
139
|
- **Workspace slug**: honor `--workspace=<slug>`. Otherwise derive from the validated identity — the GraphQL `organization.urlKey` (API path) or the team list's workspace (MCP path). Confirm with the user; this slug is the keychain `account` key and the multi-workspace disambiguator.
|
|
140
|
-
- **Team key** (required when Linear is the **tracker**): honor `--team=<KEY>`. Otherwise enumerate teams via `
|
|
140
|
+
- **Team key** (required when Linear is the **tracker**): honor `--team=<KEY>`. Otherwise enumerate teams via `lisa:linear-access operation: list-teams({})` (or the GraphQL `teams` query) and present them via `AskUserQuestion` (label = team key, description = team name) for the user to pick the team that owns lisa's destination Issues. If Linear is source-only, `teamKey` is optional — skip unless the user wants to pin a team scope.
|
|
141
141
|
|
|
142
142
|
### Step 3 — Scaffold the lifecycle label namespaces
|
|
143
143
|
|
|
@@ -154,7 +154,7 @@ read_role() { # $1=namespace (build|prd) $2=role $3=default
|
|
|
154
154
|
|
|
155
155
|
#### 3a. Build-queue labels — ISSUE labels (only if Linear is the tracker)
|
|
156
156
|
|
|
157
|
-
Probe with `
|
|
157
|
+
Probe with `lisa:linear-access operation: list-issue-labels` (scoped to the team). For each role's resolved name, create it via `lisa:linear-access operation: create-issue-label` only if absent. The `done` role is env-keyed — create all three defaults; collapse to a single string in config later if the project's terminal state is env-independent.
|
|
158
158
|
|
|
159
159
|
| Role | Default |
|
|
160
160
|
|------|---------|
|
|
@@ -168,7 +168,7 @@ Probe with `mcp__linear-server__list_issue_labels` (scoped to the team). For eac
|
|
|
168
168
|
|
|
169
169
|
#### 3b. PRD-lifecycle labels — PROJECT labels (only if Linear is the PRD source)
|
|
170
170
|
|
|
171
|
-
Probe with `
|
|
171
|
+
Probe with `lisa:linear-access operation: list-project-labels`. Create missing ones via `lisa:linear-access operation: create-project-label`. This probe-then-create is find-or-create per label: a label already present is reused untouched, so re-running never duplicates `prd-*`. These are a **separate label kind** from issue labels — creating an issue label of the same name will NOT work for the PRD flow.
|
|
172
172
|
|
|
173
173
|
`prd-verified` is the terminal lifecycle state after `prd-shipped` (the `verified` role from config-resolution, #591): `/lisa:verify-prd` transitions a Linear PRD project into it once the shipped product has been empirically verified against the PRD. Scaffold it through the same find-or-create path as every other `prd-*` row.
|
|
174
174
|
|