@codyswann/lisa 2.6.4 → 2.8.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 +10 -1
- package/plugins/lisa/agents/confluence-prd-intake.md +5 -5
- package/plugins/lisa/agents/github-agent.md +141 -0
- package/plugins/lisa/agents/github-build-intake.md +62 -0
- package/plugins/lisa/agents/github-prd-intake.md +64 -0
- package/plugins/lisa/agents/linear-prd-intake.md +5 -5
- package/plugins/lisa/agents/notion-prd-intake.md +5 -5
- package/plugins/lisa/agents/verification-specialist.md +8 -2
- package/plugins/lisa/commands/codify-verification.md +6 -0
- package/plugins/lisa/commands/intake.md +2 -2
- package/plugins/lisa/commands/plan.md +2 -2
- package/plugins/lisa/hooks/block-no-verify.sh +37 -0
- package/plugins/lisa/rules/intent-routing.md +21 -15
- package/plugins/lisa/rules/tracker-resolution.md +76 -0
- package/plugins/lisa/rules/verification.md +2 -2
- package/plugins/lisa/skills/codify-verification/SKILL.md +152 -0
- package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +11 -11
- package/plugins/lisa/skills/{confluence-to-jira → confluence-to-tracker}/SKILL.md +31 -31
- package/plugins/lisa/skills/github-add-journey/SKILL.md +114 -0
- package/plugins/lisa/skills/github-build-intake/SKILL.md +188 -0
- package/plugins/lisa/skills/github-create/SKILL.md +101 -0
- package/plugins/lisa/skills/github-evidence/SKILL.md +116 -0
- package/plugins/lisa/skills/github-journey/SKILL.md +121 -0
- package/plugins/lisa/skills/github-prd-intake/SKILL.md +286 -0
- package/plugins/lisa/skills/github-read-issue/SKILL.md +248 -0
- package/plugins/lisa/skills/github-sync/SKILL.md +73 -0
- package/plugins/lisa/skills/github-to-tracker/SKILL.md +312 -0
- package/plugins/lisa/skills/github-validate-issue/SKILL.md +288 -0
- package/plugins/lisa/skills/github-verify/SKILL.md +29 -0
- package/plugins/lisa/skills/github-write-issue/SKILL.md +304 -0
- package/plugins/lisa/skills/implement/SKILL.md +4 -4
- package/plugins/lisa/skills/intake/SKILL.md +14 -4
- package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +1 -1
- package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +3 -3
- package/plugins/lisa/skills/jira-verify/SKILL.md +1 -1
- package/plugins/lisa/skills/jira-write-ticket/SKILL.md +3 -3
- package/plugins/lisa/skills/linear-prd-intake/SKILL.md +10 -10
- package/plugins/lisa/skills/{linear-to-jira → linear-to-tracker}/SKILL.md +30 -31
- package/plugins/lisa/skills/notion-prd-intake/SKILL.md +11 -11
- package/plugins/{src/base/skills/notion-to-jira → lisa/skills/notion-to-tracker}/SKILL.md +34 -34
- package/plugins/lisa/skills/plan/SKILL.md +8 -6
- package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +22 -12
- package/plugins/lisa/skills/product-walkthrough/SKILL.md +1 -1
- package/plugins/lisa/skills/spec-conformance/SKILL.md +2 -3
- package/plugins/lisa/skills/ticket-triage/SKILL.md +7 -7
- package/plugins/lisa/skills/tracker-add-journey/SKILL.md +24 -0
- package/plugins/lisa/skills/tracker-build-intake/SKILL.md +25 -0
- package/plugins/lisa/skills/tracker-create/SKILL.md +24 -0
- package/plugins/lisa/skills/tracker-evidence/SKILL.md +24 -0
- package/plugins/lisa/skills/tracker-journey/SKILL.md +24 -0
- package/plugins/lisa/skills/tracker-read/SKILL.md +25 -0
- package/plugins/lisa/skills/tracker-sync/SKILL.md +26 -0
- package/plugins/lisa/skills/tracker-validate/SKILL.md +35 -0
- package/plugins/lisa/skills/tracker-verify/SKILL.md +25 -0
- package/plugins/lisa/skills/tracker-write/SKILL.md +43 -0
- package/plugins/lisa/skills/verification-lifecycle/SKILL.md +31 -9
- package/plugins/lisa/skills/verify/SKILL.md +7 -6
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/skills/jira-verify/SKILL.md +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/skills/jira-verify/SKILL.md +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/.claude-plugin/plugin.json +6 -0
- package/plugins/src/base/agents/confluence-prd-intake.md +5 -5
- package/plugins/src/base/agents/github-agent.md +141 -0
- package/plugins/src/base/agents/github-build-intake.md +62 -0
- package/plugins/src/base/agents/github-prd-intake.md +64 -0
- package/plugins/src/base/agents/linear-prd-intake.md +5 -5
- package/plugins/src/base/agents/notion-prd-intake.md +5 -5
- package/plugins/src/base/agents/verification-specialist.md +8 -2
- package/plugins/src/base/commands/codify-verification.md +6 -0
- package/plugins/src/base/commands/intake.md +2 -2
- package/plugins/src/base/commands/plan.md +2 -2
- package/plugins/src/base/hooks/block-no-verify.sh +37 -0
- package/plugins/src/base/rules/intent-routing.md +21 -15
- package/plugins/src/base/rules/tracker-resolution.md +76 -0
- package/plugins/src/base/rules/verification.md +2 -2
- package/plugins/src/base/skills/codify-verification/SKILL.md +152 -0
- package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +11 -11
- package/plugins/src/base/skills/{confluence-to-jira → confluence-to-tracker}/SKILL.md +31 -31
- package/plugins/src/base/skills/github-add-journey/SKILL.md +114 -0
- package/plugins/src/base/skills/github-build-intake/SKILL.md +188 -0
- package/plugins/src/base/skills/github-create/SKILL.md +101 -0
- package/plugins/src/base/skills/github-evidence/SKILL.md +116 -0
- package/plugins/src/base/skills/github-journey/SKILL.md +121 -0
- package/plugins/src/base/skills/github-prd-intake/SKILL.md +286 -0
- package/plugins/src/base/skills/github-read-issue/SKILL.md +248 -0
- package/plugins/src/base/skills/github-sync/SKILL.md +73 -0
- package/plugins/src/base/skills/github-to-tracker/SKILL.md +312 -0
- package/plugins/src/base/skills/github-validate-issue/SKILL.md +288 -0
- package/plugins/src/base/skills/github-verify/SKILL.md +29 -0
- package/plugins/src/base/skills/github-write-issue/SKILL.md +304 -0
- package/plugins/src/base/skills/implement/SKILL.md +4 -4
- package/plugins/src/base/skills/intake/SKILL.md +14 -4
- package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +1 -1
- package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +3 -3
- package/plugins/src/base/skills/jira-verify/SKILL.md +1 -1
- package/plugins/src/base/skills/jira-write-ticket/SKILL.md +3 -3
- package/plugins/src/base/skills/linear-prd-intake/SKILL.md +10 -10
- package/plugins/src/base/skills/{linear-to-jira → linear-to-tracker}/SKILL.md +30 -31
- package/plugins/src/base/skills/notion-prd-intake/SKILL.md +11 -11
- package/plugins/{lisa/skills/notion-to-jira → src/base/skills/notion-to-tracker}/SKILL.md +34 -34
- package/plugins/src/base/skills/plan/SKILL.md +8 -6
- package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +22 -12
- package/plugins/src/base/skills/product-walkthrough/SKILL.md +1 -1
- package/plugins/src/base/skills/spec-conformance/SKILL.md +2 -3
- package/plugins/src/base/skills/ticket-triage/SKILL.md +7 -7
- package/plugins/src/base/skills/tracker-add-journey/SKILL.md +24 -0
- package/plugins/src/base/skills/tracker-build-intake/SKILL.md +25 -0
- package/plugins/src/base/skills/tracker-create/SKILL.md +24 -0
- package/plugins/src/base/skills/tracker-evidence/SKILL.md +24 -0
- package/plugins/src/base/skills/tracker-journey/SKILL.md +24 -0
- package/plugins/src/base/skills/tracker-read/SKILL.md +25 -0
- package/plugins/src/base/skills/tracker-sync/SKILL.md +26 -0
- package/plugins/src/base/skills/tracker-validate/SKILL.md +35 -0
- package/plugins/src/base/skills/tracker-verify/SKILL.md +25 -0
- package/plugins/src/base/skills/tracker-write/SKILL.md +43 -0
- package/plugins/src/base/skills/verification-lifecycle/SKILL.md +31 -9
- package/plugins/src/base/skills/verify/SKILL.md +7 -6
- package/plugins/src/expo/skills/jira-verify/SKILL.md +1 -1
- package/plugins/src/rails/skills/jira-verify/SKILL.md +1 -1
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-prd-intake
|
|
3
|
+
description: "Scans a GitHub repository for issues labeled `prd-ready` and runs each one through the dry-run validation pipeline. PRDs that pass every gate get tickets written (to whatever destination tracker is configured — JIRA or GitHub Issues itself) and the label flipped to `prd-ticketed`; PRDs that fail get clarifying-question comments and the label flipped to `prd-blocked`. The GitHub counterpart of lisa:notion-prd-intake / lisa:confluence-prd-intake / lisa:linear-prd-intake. Composes existing skills (github-to-tracker, tracker-validate, jira-source-artifacts, product-walkthrough)."
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GitHub PRD Intake: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
`$ARGUMENTS` is one of:
|
|
10
|
+
|
|
11
|
+
- A GitHub `org/repo` token (e.g., `acme/product-prds`) — scans the repo for issues labeled `prd-ready`.
|
|
12
|
+
- A full GitHub repo URL (e.g., `https://github.com/acme/product-prds`).
|
|
13
|
+
- The literal token `github` — falls back to `.lisa.config.json` (`github.org` / `github.repo`).
|
|
14
|
+
|
|
15
|
+
Run one intake cycle against that repo. Each issue with the `prd-ready` label is claimed, validated, and routed to either `prd-blocked` (with clarifying comments) or `prd-ticketed` (with destination tickets created).
|
|
16
|
+
|
|
17
|
+
This skill is the GitHub counterpart of `lisa:notion-prd-intake`, `lisa:confluence-prd-intake`, and `lisa:linear-prd-intake`. Phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **issue labels** (mirroring Linear's project labels and Confluence's page labels), (2) the fetch / update tools are the `gh` CLI, and (3) clarifying-question comments land directly on the source PRD issue (because GitHub Issues *do* have native comments — no sentinel issue required, unlike Linear). Keep all four skills behaviorally aligned: when changing intake logic, change them together.
|
|
18
|
+
|
|
19
|
+
## Confirmation policy
|
|
20
|
+
|
|
21
|
+
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim, validate, branch to `prd-blocked` or `prd-ticketed`, write the summary. The caller has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background batch.
|
|
22
|
+
|
|
23
|
+
Specifically forbidden:
|
|
24
|
+
|
|
25
|
+
- Previewing projected scope and asking whether to continue.
|
|
26
|
+
- Offering A/B/C-style choices like "proceed / skip / dry-run only" — the documented behavior IS the default.
|
|
27
|
+
- Pausing because a PRD looks large, has many open questions, or is likely to end in `prd-blocked`. `prd-blocked` is a valid terminal state of this lifecycle, not a failure mode.
|
|
28
|
+
- Pausing because the dry-run validation looks expensive.
|
|
29
|
+
|
|
30
|
+
The only legitimate reasons to stop early:
|
|
31
|
+
|
|
32
|
+
- Missing repo argument or required configuration. Surface and exit.
|
|
33
|
+
- Repo unreachable, or the labelling convention not yet adopted (no issue carries any of `prd-ready` / `prd-in-review` / `prd-blocked` / `prd-ticketed`). Surface and exit.
|
|
34
|
+
- Empty `prd-ready` set. Exit cleanly with `"No GitHub issues labeled prd-ready in <org>/<repo>. Nothing to do."`
|
|
35
|
+
|
|
36
|
+
## Lifecycle assumed
|
|
37
|
+
|
|
38
|
+
The PRD lifecycle is encoded as **issue labels**:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
prd-draft → prd-ready → prd-in-review → prd-blocked | prd-ticketed → prd-shipped
|
|
42
|
+
(product) (us) (us) (product)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Exactly one of these labels is expected on a PRD issue at any time.
|
|
46
|
+
|
|
47
|
+
This skill ONLY transitions:
|
|
48
|
+
|
|
49
|
+
- `prd-ready` → `prd-in-review` (claim)
|
|
50
|
+
- `prd-in-review` → `prd-blocked` (gate failures or coverage gaps)
|
|
51
|
+
- `prd-in-review` → `prd-ticketed` (success)
|
|
52
|
+
- `prd-ticketed` → `prd-blocked` (post-write coverage gaps from Phase 3e)
|
|
53
|
+
|
|
54
|
+
It never adds, removes, or touches `prd-draft` or `prd-shipped`. Those labels are owned by product.
|
|
55
|
+
|
|
56
|
+
A "transition" means: remove the old lifecycle label and add the new one (`gh issue edit <num> --remove-label <old> --add-label <new>`). The skill MUST verify exactly one lifecycle label is present after the update.
|
|
57
|
+
|
|
58
|
+
If the repo has not yet adopted `prd-*` labels, this skill cannot run. See "Adoption" at the bottom.
|
|
59
|
+
|
|
60
|
+
**Label namespace separation:** the PRD lifecycle uses the `prd-*` namespace. The build-queue lifecycle (used by `lisa:github-build-intake`) uses the `status:*` namespace. The two never overlap. When the destination tracker is also GitHub Issues (self-host case), the same repo can host both — but a single issue is either a PRD (carrying a `prd-*` label) or a build ticket (carrying a `status:*` label), never both.
|
|
61
|
+
|
|
62
|
+
## Phases
|
|
63
|
+
|
|
64
|
+
### Phase 1 — Resolve the repo
|
|
65
|
+
|
|
66
|
+
1. Parse `$ARGUMENTS`:
|
|
67
|
+
- `org/repo` token → use as-is.
|
|
68
|
+
- GitHub URL → extract `org` and `repo`.
|
|
69
|
+
- Literal `github` → resolve from `.lisa.config.json`; error if not set.
|
|
70
|
+
2. Confirm `gh auth status` succeeds.
|
|
71
|
+
3. Confirm the repo is reachable: `gh repo view <org>/<repo> --json name`.
|
|
72
|
+
4. Verify the `prd-*` label set exists:
|
|
73
|
+
```bash
|
|
74
|
+
gh label list --repo <org>/<repo> --json name --jq '[.[] | select(startswith("prd-"))] | sort'
|
|
75
|
+
```
|
|
76
|
+
If none of `prd-ready` / `prd-in-review` / `prd-blocked` / `prd-ticketed` are present, surface a label-convention error and exit (see "Adoption").
|
|
77
|
+
|
|
78
|
+
### Phase 2 — Find Ready PRDs
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
gh issue list --repo <org>/<repo> --label prd-ready --state open --limit 100 \
|
|
82
|
+
--json number,title,body,labels,author,milestone,createdAt,updatedAt,url
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For each candidate, confirm exactly one lifecycle label is present (the `--label` filter selects `prd-ready` matches, but a PRD could have ended up with two labels by hand — that's a misconfiguration, not a normal queue entry).
|
|
86
|
+
|
|
87
|
+
If empty, run a secondary check:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
gh issue list --repo <org>/<repo> --state open --limit 100 --json number,labels --jq '[.[] | .labels[] | select(.name | startswith("prd-")) | .name] | unique'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If no `prd-*` labels appear on any open issue → convention not adopted; surface error and exit. If `prd-*` labels exist but none are `prd-ready` → genuinely empty queue, exit cleanly with the idle message.
|
|
94
|
+
|
|
95
|
+
### Phase 3 — Process each Ready PRD
|
|
96
|
+
|
|
97
|
+
Process serially to keep label transitions auditable.
|
|
98
|
+
|
|
99
|
+
#### 3a. Claim
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
gh issue edit <num> --repo <org>/<repo> --remove-label prd-ready --add-label prd-in-review
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This is the idempotency lock — a re-entrant cycle's `--label prd-ready` filter won't see this issue again.
|
|
106
|
+
|
|
107
|
+
If the relabel fails (permission, race), log and skip. Do not proceed to validation on a PRD you didn't successfully claim.
|
|
108
|
+
|
|
109
|
+
This skill never edits the PRD body. Communication with product happens only through comments.
|
|
110
|
+
|
|
111
|
+
#### 3b. Dry-run validation
|
|
112
|
+
|
|
113
|
+
Invoke the `lisa:github-to-tracker` skill with `dry_run: true` and the PRD issue ref. The skill returns a structured report containing:
|
|
114
|
+
- The planned ticket hierarchy
|
|
115
|
+
- Per-ticket validation verdicts and remediation
|
|
116
|
+
- An overall PASS / FAIL verdict
|
|
117
|
+
- A failure count
|
|
118
|
+
|
|
119
|
+
This call indirectly invokes `lisa:jira-source-artifacts` (artifact extraction + classification) and `lisa:product-walkthrough` (when the PRD touches existing user-facing surfaces). All gate logic lives in `lisa:tracker-validate` (which dispatches to `lisa:jira-validate-ticket` or `lisa:github-validate-issue` depending on the configured destination).
|
|
120
|
+
|
|
121
|
+
#### 3c. Branch on the verdict
|
|
122
|
+
|
|
123
|
+
**If `PASS`** (every planned ticket passed every applicable gate):
|
|
124
|
+
|
|
125
|
+
1. Re-invoke `lisa:github-to-tracker` with `dry_run: false` to actually write tickets. This re-runs the planning phases and the preservation gate.
|
|
126
|
+
2. Capture the created ticket refs.
|
|
127
|
+
3. Post a comment on the PRD issue listing the created tickets with their URLs:
|
|
128
|
+
```bash
|
|
129
|
+
gh issue comment <prd-num> --repo <org>/<repo> --body-file /tmp/ticketed-comment.md
|
|
130
|
+
```
|
|
131
|
+
Lead with: `"Ticketed by Claude. Created N tickets in <destination> — see below. Add the prd-shipped label after the work is delivered."` The destination is named (JIRA / GitHub Issues) so product knows where to look.
|
|
132
|
+
4. Transition labels: `gh issue edit <prd-num> --remove-label prd-in-review --add-label prd-ticketed`.
|
|
133
|
+
5. **Run Phase 3e (coverage audit)** before considering this PRD done.
|
|
134
|
+
|
|
135
|
+
**If `FAIL`**:
|
|
136
|
+
|
|
137
|
+
The audience is the **product team**, not engineers. Follow the strict comment rules below.
|
|
138
|
+
|
|
139
|
+
##### 3c.1 Partition failures
|
|
140
|
+
|
|
141
|
+
1. Drop every failure where `product_relevant = false`. Internal data-quality problems — the agent should fix its own spec, not ask product. Record dropped failures under `Errors` in the cycle summary.
|
|
142
|
+
2. Group remaining product-relevant failures by `prd_anchor` (a section heading or a `selection_with_ellipsis` snippet from the PRD body). Failures sharing an anchor become one comment.
|
|
143
|
+
|
|
144
|
+
##### 3c.2 Render each comment
|
|
145
|
+
|
|
146
|
+
GitHub Issues do not have selection-anchored comments (unlike Confluence inline comments). Approximate by quoting the relevant body excerpt at the top of each comment:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
gh issue comment <prd-num> --repo <org>/<repo> --body-file /tmp/anchored-comment-N.md
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Each comment template MUST contain these parts in this order, no exceptions:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
[<Category badge>] <prd_section heading text>
|
|
156
|
+
|
|
157
|
+
> <quoted excerpt from the PRD body, ~10–30 words around the anchor — this stands in for inline anchoring>
|
|
158
|
+
|
|
159
|
+
**What's unclear:** <validator's `what` field, verbatim — already product-readable>
|
|
160
|
+
|
|
161
|
+
**Recommendation:** <validator's `recommendation` field, verbatim — must contain 1–3 concrete options, never a generic "please clarify">
|
|
162
|
+
|
|
163
|
+
**Action:** Update this section in the PRD, then replace the `prd-blocked` label with `prd-ready` on the issue and Claude will re-run intake.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If multiple failures share an anchor, render each as its own `**What's unclear:** ... **Recommendation:** ...` block within the same comment, separated by `---`. Keep the single `[Category badge]` heading at the top.
|
|
167
|
+
|
|
168
|
+
For unanchored failures (`prd_anchor: null`), post one rollup comment prefixed with `Issues without a specific section anchor:`.
|
|
169
|
+
|
|
170
|
+
##### 3c.3 Category badges
|
|
171
|
+
|
|
172
|
+
| Validator category | Badge label |
|
|
173
|
+
|---------------------|-------------|
|
|
174
|
+
| `product-clarity` | `[Product clarity]` |
|
|
175
|
+
| `acceptance-criteria` | `[Acceptance criteria]` |
|
|
176
|
+
| `design-ux` | `[Design / UX]` |
|
|
177
|
+
| `scope` | `[Scope]` |
|
|
178
|
+
| `dependency` | `[Dependency]` |
|
|
179
|
+
| `data` | `[Data]` |
|
|
180
|
+
| `technical` | `[Technical]` |
|
|
181
|
+
|
|
182
|
+
`structural` failures must never reach this step (filtered in 3c.1).
|
|
183
|
+
|
|
184
|
+
##### 3c.4 Forbidden in product comments
|
|
185
|
+
|
|
186
|
+
- Gate IDs (`S4`, `F2`, etc.).
|
|
187
|
+
- GitHub-Issues-specific terminology (`gh`, `sub-issue`, `label namespace`) — paraphrase before posting.
|
|
188
|
+
- Internal skill names (`lisa:tracker-validate`, `github-to-tracker`).
|
|
189
|
+
- Engineering shorthand (`AC`, `OOS`, `repo`, `env var`).
|
|
190
|
+
- "Clarify this" / "Please specify" without candidate resolutions.
|
|
191
|
+
|
|
192
|
+
##### 3c.5 Label transition
|
|
193
|
+
|
|
194
|
+
After all comments are posted, transition: `gh issue edit <num> --remove-label prd-in-review --add-label prd-blocked`. Do NOT write any tickets.
|
|
195
|
+
|
|
196
|
+
#### 3d. Continue
|
|
197
|
+
|
|
198
|
+
Move to the next Ready PRD. One PRD failing does not affect others.
|
|
199
|
+
|
|
200
|
+
#### 3e. Coverage audit (mandatory after prd-ticketed)
|
|
201
|
+
|
|
202
|
+
Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* of tickets covers the *whole* PRD. Invoke `lisa:prd-ticket-coverage` to catch silent drops.
|
|
203
|
+
|
|
204
|
+
1. Invoke `lisa:prd-ticket-coverage` with `<PRD URL> tickets=[<created refs from 3c step 2>]`. The coverage skill auto-detects the PRD vendor from the URL host (`github.com` → GitHub).
|
|
205
|
+
2. Read the verdict:
|
|
206
|
+
|
|
207
|
+
| Verdict | Action |
|
|
208
|
+
|---------|--------|
|
|
209
|
+
| `COMPLETE` | Done. Leave label as `prd-ticketed`. Move to next PRD. |
|
|
210
|
+
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory comment on the PRD issue naming the scope-creep tickets. Leave label as `prd-ticketed`. |
|
|
211
|
+
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.2 — anchored when `prd_anchor` is non-null. (b) Post one summary comment listing the tickets that *were* successfully created. (c) Transition labels from `prd-ticketed` back to `prd-blocked`. |
|
|
212
|
+
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. Log as Error; leave label as `prd-ticketed` with a flag comment. |
|
|
213
|
+
|
|
214
|
+
3. The created tickets remain in the destination tracker regardless of the verdict. The audit only tells us whether *more* are needed.
|
|
215
|
+
|
|
216
|
+
### Phase 4 — Summary report
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
## github-prd-intake summary
|
|
220
|
+
|
|
221
|
+
Repo: <org>/<repo> (<URL>)
|
|
222
|
+
Cycle started: <ISO timestamp>
|
|
223
|
+
Cycle completed: <ISO timestamp>
|
|
224
|
+
|
|
225
|
+
PRDs processed: <n>
|
|
226
|
+
- prd-ticketed: <n>
|
|
227
|
+
- <issue-ref> "<title>" → <epic-ref> + <story-count> stories + <subtask-count> sub-tasks (coverage: COMPLETE | COMPLETE_WITH_SCOPE_CREEP)
|
|
228
|
+
- prd-blocked: <n>
|
|
229
|
+
- <issue-ref> "<title>" → <gate-failure-count> gate failures (pre-write) OR <gap-count> coverage gaps (post-write)
|
|
230
|
+
- Errors (claim failed, etc): <n>
|
|
231
|
+
- <issue-ref> "<title>" — <reason>
|
|
232
|
+
|
|
233
|
+
Total tickets created: <n>
|
|
234
|
+
Coverage audit summary: <n> COMPLETE / <n> COMPLETE_WITH_SCOPE_CREEP / <n> GAPS_FOUND
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Print to the agent's output. Do not write this summary to GitHub.
|
|
238
|
+
|
|
239
|
+
## Self-host edge case (PRD repo = destination repo)
|
|
240
|
+
|
|
241
|
+
When the configured destination tracker is GitHub Issues AND the PRD repo is the same as the destination repo, both reads and writes hit the same place. Disambiguation rules:
|
|
242
|
+
|
|
243
|
+
- A PRD issue carries a `prd-*` label. Built tickets carry a `type:*` + `status:*` label set, but never a `prd-*` label.
|
|
244
|
+
- The "Ticketed by Claude" comment on the PRD links to the destination ticket numbers (which live in the same repo, so the links are simple `#<n>` refs).
|
|
245
|
+
- `lisa:prd-ticket-coverage` filters out the source PRD itself when listing destination tickets — the PRD is never a ticket of its own work.
|
|
246
|
+
|
|
247
|
+
## Idempotency & safety
|
|
248
|
+
|
|
249
|
+
- **Single-cycle scope**: this skill processes the `prd-ready` set as it exists at the start of Phase 2. New `prd-ready` issues added mid-cycle are picked up next run.
|
|
250
|
+
- **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:github-to-tracker` (which delegates to `lisa:tracker-write`), only ever changes labels among `prd-in-review`, `prd-blocked`, `prd-ticketed`, only ever comments on the source PRD issue. It never edits PRD bodies, never touches `prd-draft` or `prd-shipped`, never closes or deletes PRD issues.
|
|
251
|
+
- **Claim-first ordering**: the label flip to `prd-in-review` happens BEFORE validation runs.
|
|
252
|
+
- **Failure isolation**: an exception processing one PRD must not stop the cycle. Catch, record under "Errors" in the summary, continue. The PRD that errored is left labeled `prd-in-review` — humans investigate from there.
|
|
253
|
+
- **Single-label invariant**: after every transition, verify exactly one lifecycle label is present.
|
|
254
|
+
|
|
255
|
+
## Configuration
|
|
256
|
+
|
|
257
|
+
Same env vars as `lisa:github-to-tracker` plus `.lisa.config.json` `github.org` / `github.repo`. If any required value is missing, surface and exit — never invent values.
|
|
258
|
+
|
|
259
|
+
## Rules
|
|
260
|
+
|
|
261
|
+
- Never write to the destination tracker outside of `lisa:github-to-tracker` → `lisa:tracker-write`.
|
|
262
|
+
- Never add or remove a label this skill doesn't own (`prd-in-review`, `prd-blocked`, `prd-ticketed`). Product owns `prd-draft`, `prd-ready`, `prd-shipped`.
|
|
263
|
+
- Never edit a PRD's body. Communication with product happens only via comments.
|
|
264
|
+
- Never post a single dump of all gate failures on one comment. One comment per `prd_anchor` group, plus one rollup for unanchored failures.
|
|
265
|
+
- Never include a gate ID, internal skill name, or engineering shorthand in a comment body.
|
|
266
|
+
- Never run more than one intake cycle concurrently against the same repo.
|
|
267
|
+
- If `lisa:github-to-tracker` returns errors, treat them as gate failures: comment + `prd-blocked`. Don't silently fail.
|
|
268
|
+
|
|
269
|
+
## Adoption (one-time per repo)
|
|
270
|
+
|
|
271
|
+
Before this skill can run, the repo must adopt the `prd-*` issue-label convention:
|
|
272
|
+
|
|
273
|
+
1. Create the labels:
|
|
274
|
+
```bash
|
|
275
|
+
gh label create prd-draft --color C5DEF5 --description "PRD in progress (product owns)" --repo <org>/<repo>
|
|
276
|
+
gh label create prd-ready --color FBCA04 --description "PRD ready for ticketing" --repo <org>/<repo>
|
|
277
|
+
gh label create prd-in-review --color 5319E7 --description "Claude is reviewing this PRD" --repo <org>/<repo>
|
|
278
|
+
gh label create prd-blocked --color D93F0B --description "PRD blocked — see comments" --repo <org>/<repo>
|
|
279
|
+
gh label create prd-ticketed --color 0E8A16 --description "Tickets created — see comments" --repo <org>/<repo>
|
|
280
|
+
gh label create prd-shipped --color 1D76DB --description "Work delivered (product owns)" --repo <org>/<repo>
|
|
281
|
+
```
|
|
282
|
+
2. Apply `prd-ready` to issues that are ready for ticketing.
|
|
283
|
+
3. Reserve `prd-in-review`, `prd-blocked`, `prd-ticketed` for this skill — humans should not set them manually except to recover from an error.
|
|
284
|
+
4. Keep the `prd-*` namespace strictly separate from the build-queue `status:*` namespace owned by `lisa:github-build-intake`.
|
|
285
|
+
|
|
286
|
+
If the repo hasn't adopted these labels, the first run exits with a label-convention error (not the idle empty-set message) — this distinguishes setup from a genuinely empty queue.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-read-issue
|
|
3
|
+
description: "Fetches the full scope of a GitHub Issue — metadata, body sections, all comments, native sub-issue parent and children, linked PRs, related issues parsed from `Blocks/Blocked by/Relates to/Duplicates/Cloned from` lines, and any cross-repo references. Produces a consolidated context bundle that downstream agents consume so they never act on an issue in isolation. The GitHub counterpart of lisa:jira-read-ticket."
|
|
4
|
+
allowed-tools: ["Bash", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Read GitHub Issue: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Fetch the full scope of the issue AND its related graph. Downstream agents must never act on an issue in isolation — always call this skill first so they see blockers, sibling sub-issues, linked PRs, and historical comments.
|
|
10
|
+
|
|
11
|
+
This skill is the GitHub counterpart of `lisa:jira-read-ticket`. The output bundle structure mirrors the JIRA bundle so vendor-neutral consumers can parse either with minimal branching.
|
|
12
|
+
|
|
13
|
+
Repository name for scoped comments and logs: `basename $(git rev-parse --show-toplevel)`.
|
|
14
|
+
|
|
15
|
+
## Phase 1 — Resolve Context
|
|
16
|
+
|
|
17
|
+
1. Confirm `gh auth status` succeeds.
|
|
18
|
+
2. Parse `$ARGUMENTS`. Accept either:
|
|
19
|
+
- `<org>/<repo>#<number>` token, OR
|
|
20
|
+
- `https://github.com/<org>/<repo>/issues/<number>` URL.
|
|
21
|
+
|
|
22
|
+
If `$ARGUMENTS` is just `#<number>` or `<number>`, resolve `<org>/<repo>` from `.lisa.config.json` (`github.org` / `github.repo`).
|
|
23
|
+
3. If the input doesn't parse cleanly, stop and report. Do NOT guess.
|
|
24
|
+
|
|
25
|
+
## Phase 2 — Fetch Primary Issue
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
gh issue view <number> --repo <org>/<repo> --json number,title,body,state,stateReason,author,assignees,labels,milestone,createdAt,updatedAt,closedAt,url,comments,reactionGroups,projectItems
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Extract and preserve:
|
|
32
|
+
|
|
33
|
+
### Metadata
|
|
34
|
+
|
|
35
|
+
- `number`, `title`, `state` (open/closed), `stateReason` (completed/not_planned/reopened/null)
|
|
36
|
+
- `author` (immutable original reporter), `assignees`
|
|
37
|
+
- All labels — partition by namespace: `type:<...>` (issue type), `status:<...>` (workflow status), `priority:<...>`, `component:<...>`, `points:<...>`, `fix-version:<...>`, `claude-triaged-<repo>`, plus any free-form labels
|
|
38
|
+
- `milestone` (name + url)
|
|
39
|
+
- `createdAt`, `updatedAt`, `closedAt`
|
|
40
|
+
- `url` (canonical issue URL)
|
|
41
|
+
|
|
42
|
+
### Body — parse markdown sections
|
|
43
|
+
|
|
44
|
+
Walk the markdown body and capture each top-level `## ` section by name. Standard sections (per `lisa:github-write-issue` Phase 3):
|
|
45
|
+
|
|
46
|
+
- `Context / Business Value`
|
|
47
|
+
- `Technical Approach`
|
|
48
|
+
- `Acceptance Criteria` (preserve the Gherkin code-fence verbatim)
|
|
49
|
+
- `Out of Scope`
|
|
50
|
+
- `Target Backend Environment`
|
|
51
|
+
- `Sign-in Required`
|
|
52
|
+
- `Repository`
|
|
53
|
+
- `Source Artifacts`
|
|
54
|
+
- `Source Precedence`
|
|
55
|
+
- `Links`
|
|
56
|
+
- `Relationship Search`
|
|
57
|
+
- `Validation Journey` (preserve verbatim — pass through to verifier agents)
|
|
58
|
+
- `Open Questions`
|
|
59
|
+
- `Current Product`
|
|
60
|
+
|
|
61
|
+
Any other `##` section: capture under `extra_sections` so callers can see PRDs that adopt non-standard sections.
|
|
62
|
+
|
|
63
|
+
### Comments
|
|
64
|
+
|
|
65
|
+
Fetch ALL comments. Do not truncate. The `comments` field from `gh issue view --json comments` includes author, body, createdAt for each. Flag comments that contain:
|
|
66
|
+
- Credentials, reproduction steps
|
|
67
|
+
- Status updates from stakeholders
|
|
68
|
+
- Decisions
|
|
69
|
+
- Triage headers like `[<repo>]`
|
|
70
|
+
|
|
71
|
+
If pagination matters (issues with hundreds of comments), use `gh api repos/<org>/<repo>/issues/<number>/comments --paginate` to get the full set.
|
|
72
|
+
|
|
73
|
+
## Phase 3 — Fetch Sub-issue Graph (Parent + Children)
|
|
74
|
+
|
|
75
|
+
GitHub native sub-issues are exposed via GraphQL:
|
|
76
|
+
|
|
77
|
+
```graphql
|
|
78
|
+
query($org:String!,$repo:String!,$number:Int!){
|
|
79
|
+
repository(owner:$org,name:$repo){
|
|
80
|
+
issue(number:$number){
|
|
81
|
+
id
|
|
82
|
+
parent { number title state url repository { nameWithOwner } }
|
|
83
|
+
subIssues(first: 100) {
|
|
84
|
+
nodes {
|
|
85
|
+
number title state url
|
|
86
|
+
repository { nameWithOwner }
|
|
87
|
+
labels(first: 50) { nodes { name } }
|
|
88
|
+
assignees(first: 5) { nodes { login } }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
gh api graphql -f query='<above>' -F org=<org> -F repo=<repo> -F number=<number>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Capture:
|
|
101
|
+
- **Parent sub-issue**: number, title, state, url, repo.
|
|
102
|
+
- **Child sub-issues**: list with number, title, state, url, repo, labels (especially `type:` and `status:`), assignees.
|
|
103
|
+
|
|
104
|
+
If the GraphQL `parent` / `subIssues` fields aren't available (older GHES), fall back to parsing `Parent: #<n>` text in the body and recording sub-issue text references — note "GraphQL sub-issues unavailable" in the bundle so callers know parent-link is text-based.
|
|
105
|
+
|
|
106
|
+
## Phase 4 — Parse Issue Links from Body
|
|
107
|
+
|
|
108
|
+
The body's `## Links` section encodes typed relationships. Parse:
|
|
109
|
+
|
|
110
|
+
| Pattern (case-insensitive) | Link type |
|
|
111
|
+
|----------------------------|-----------|
|
|
112
|
+
| `Blocks #<n>` or `Blocks <org>/<repo>#<n>` | `blocks` |
|
|
113
|
+
| `Blocked by #<n>` or `Blocked by <org>/<repo>#<n>` | `is blocked by` |
|
|
114
|
+
| `Relates to #<n>` or `Relates to <org>/<repo>#<n>` | `relates to` |
|
|
115
|
+
| `Duplicates #<n>` or `Duplicates <org>/<repo>#<n>` | `duplicates` |
|
|
116
|
+
| `Cloned from #<n>` or `Cloned from <org>/<repo>#<n>` | `clones` |
|
|
117
|
+
| `Resolves #<n>` or `Closes #<n>` or `Fixes #<n>` (PR refs) | remote-link to PR |
|
|
118
|
+
|
|
119
|
+
For each parsed reference, fetch the linked issue/PR:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
gh issue view <link-number> --repo <link-org>/<link-repo> --json number,title,state,labels,assignees,url
|
|
123
|
+
gh pr view <link-number> --repo <link-org>/<link-repo> --json number,title,state,reviewDecision,merged,mergedAt,url,reviewRequests,reviews,comments
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For each linked **issue**, capture: number, title, state, type (from labels), status (from labels), assignees, url.
|
|
127
|
+
|
|
128
|
+
For each linked **PR**, capture: number, title, state, mergedAt, reviewDecision, unresolved review comments, url.
|
|
129
|
+
|
|
130
|
+
**Special handling for `is blocked by`:** include the linked issue's PR refs (parse `Resolves` lines in its body) and fetch each PR's state, so the agent knows whether the blocker is actually shipped.
|
|
131
|
+
|
|
132
|
+
## Phase 5 — Fetch Sibling Sub-issues (Epic Context)
|
|
133
|
+
|
|
134
|
+
If the primary issue has a parent sub-issue (i.e., is a Story / Task / Sub-task / Improvement under an Epic):
|
|
135
|
+
|
|
136
|
+
1. Fetch the parent Epic in full via Phase 2 logic — full body, all comments, Validation Journey if present.
|
|
137
|
+
2. Fetch the parent Epic's other sub-issues (siblings) via the same GraphQL `subIssues` query against the parent. Filter out the primary issue itself.
|
|
138
|
+
3. For each sibling, capture: number, title, type label, status label, assignee, url. Read the first paragraph of each sibling's body for context. If a sibling has `status:in-progress` with an assignee different from the primary issue's assignee, **flag prominently** so the caller can avoid duplicate work.
|
|
139
|
+
|
|
140
|
+
If the primary issue IS an Epic, capture all children via Phase 3's `subIssues` traversal (already done).
|
|
141
|
+
|
|
142
|
+
## Phase 6 — Fetch Linked PRs (Native `Resolves` / Cross-references)
|
|
143
|
+
|
|
144
|
+
GitHub's native `closingIssuesReferences` and timeline give the canonical PR↔Issue relationship:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){closedByPullRequestsReferences(first:50){nodes{number title state merged mergedAt url repository{nameWithOwner}}}timelineItems(first:100,itemTypes:[CROSS_REFERENCED_EVENT]){nodes{...on CrossReferencedEvent{source{...on PullRequest{number title state url repository{nameWithOwner}}}}}}}}}' -F org=<org> -F repo=<repo> -F number=<number>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Capture: PR number, title, state, mergedAt, repo, url. Dedupe with PRs found in Phase 4.
|
|
151
|
+
|
|
152
|
+
For each PR, fetch unresolved review comments via `gh pr view <num> --repo <org>/<repo> --json reviews,reviewThreads`.
|
|
153
|
+
|
|
154
|
+
## Phase 7 — Assemble Context Bundle
|
|
155
|
+
|
|
156
|
+
Produce a single structured output that the caller can pass verbatim to downstream agents. Use this format:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
# Issue Context: <org>/<repo>#<number>
|
|
160
|
+
|
|
161
|
+
## Primary Issue
|
|
162
|
+
- Ref: <org>/<repo>#<number>
|
|
163
|
+
- URL: <url>
|
|
164
|
+
- Type: <type from `type:` label>
|
|
165
|
+
- Status: <status from `status:` label>
|
|
166
|
+
- State: <open|closed> (<stateReason>)
|
|
167
|
+
- Priority: <priority from `priority:` label>
|
|
168
|
+
- Author: <login>
|
|
169
|
+
- Assignees: <list>
|
|
170
|
+
- Parent: <parent-ref> — <parent-title> (or "None")
|
|
171
|
+
- Milestone: <name> (or "None")
|
|
172
|
+
- Labels: <comma-separated raw labels>
|
|
173
|
+
- Components: <list from `component:` labels>
|
|
174
|
+
- Story points: <n from `points:` label> (or "None")
|
|
175
|
+
- Fix version: <from `fix-version:` label or milestone>
|
|
176
|
+
- Created: <ISO> | Updated: <ISO> | Closed: <ISO or "—">
|
|
177
|
+
|
|
178
|
+
### Body sections
|
|
179
|
+
#### Context / Business Value
|
|
180
|
+
<verbatim>
|
|
181
|
+
|
|
182
|
+
#### Technical Approach
|
|
183
|
+
<verbatim>
|
|
184
|
+
|
|
185
|
+
#### Acceptance Criteria
|
|
186
|
+
<verbatim, including the gherkin fence>
|
|
187
|
+
|
|
188
|
+
#### Validation Journey
|
|
189
|
+
<verbatim or "None">
|
|
190
|
+
|
|
191
|
+
#### Out of Scope
|
|
192
|
+
<verbatim>
|
|
193
|
+
|
|
194
|
+
#### Source Artifacts / Source Precedence / Links / Relationship Search / Repository / Sign-in Required / Target Backend Environment / Open Questions / Current Product
|
|
195
|
+
<each verbatim, omit those not present>
|
|
196
|
+
|
|
197
|
+
### Comments (<count>)
|
|
198
|
+
<chronological comments with author + ISO timestamp + body. Flagged items called out.>
|
|
199
|
+
|
|
200
|
+
## Sub-issue graph
|
|
201
|
+
### Parent
|
|
202
|
+
<parent block: ref, title, state, url, type label> (or "None — this is an Epic / unparented")
|
|
203
|
+
|
|
204
|
+
### Sub-issues (children, <count>)
|
|
205
|
+
- <ref> — <type> — <status> — <state> — <title>
|
|
206
|
+
- <one-paragraph body summary>
|
|
207
|
+
- <FLAG: in progress by other assignee> if applicable
|
|
208
|
+
|
|
209
|
+
## Linked Issues (parsed from body `## Links`)
|
|
210
|
+
### Blocks (<count>)
|
|
211
|
+
<per-issue block>
|
|
212
|
+
|
|
213
|
+
### Is Blocked By (<count>)
|
|
214
|
+
<per-issue block; include shipped/not-shipped state of any linked PRs>
|
|
215
|
+
|
|
216
|
+
### Relates To (<count>)
|
|
217
|
+
<per-issue block>
|
|
218
|
+
|
|
219
|
+
### Duplicates / Clones
|
|
220
|
+
<per-issue block>
|
|
221
|
+
|
|
222
|
+
## Linked Pull Requests
|
|
223
|
+
### Native (closedByPullRequestsReferences + cross-references)
|
|
224
|
+
- <pr-ref> — <state> — <title> — <reviewDecision>
|
|
225
|
+
<body summary + unresolved review comments>
|
|
226
|
+
|
|
227
|
+
### Body-referenced (`Resolves #<n>`)
|
|
228
|
+
<per-PR block>
|
|
229
|
+
|
|
230
|
+
## Sibling Sub-issues (other children of the same parent, <count>)
|
|
231
|
+
- <ref> — <type> — <status> — <assignee> — <title> **[FLAG: in progress by other assignee]**
|
|
232
|
+
|
|
233
|
+
## Summary for Downstream
|
|
234
|
+
- Full graph fetched: <issue-count>
|
|
235
|
+
- Blockers still open: <list>
|
|
236
|
+
- Related in-flight work: <list>
|
|
237
|
+
- Relevant PRs: <list with state>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Rules
|
|
241
|
+
|
|
242
|
+
- Never summarize or truncate the primary issue's body or Validation Journey section.
|
|
243
|
+
- Never skip a link type, even if it seems unrelated — the agent downstream decides relevance.
|
|
244
|
+
- If a linked issue / PR returns an access error (private repo, deleted, etc.), capture the error and continue. Do not abort the read.
|
|
245
|
+
- Flag in-flight sibling work prominently so the caller can avoid duplicate implementation.
|
|
246
|
+
- If the issue has no parent sub-issue, state this explicitly — do not silently skip Phase 5.
|
|
247
|
+
- Output is pure context. This skill never modifies the issue.
|
|
248
|
+
- The body parser must be tolerant of small format variations (different `##` casings, missing optional sections) but strict enough that downstream skills can rely on the named sections being present when they exist.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-sync
|
|
3
|
+
description: "Syncs plan progress to a linked GitHub Issue. Posts plan contents, progress updates, branch links, and PR links at key milestones. Use this skill throughout the plan lifecycle to keep issues in sync. The GitHub counterpart of lisa:jira-sync."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Glob", "Grep"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GitHub Issue Sync
|
|
8
|
+
|
|
9
|
+
Sync current plan progress to a GitHub Issue: `$ARGUMENTS`
|
|
10
|
+
|
|
11
|
+
If no argument is provided, search for an issue ref (`org/repo#<number>` or `https://github.com/<org>/<repo>/issues/<n>` URL) in the active plan file (most recently modified `.md` in `plans/`).
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
### Step 1: Identify Issue and Context
|
|
16
|
+
|
|
17
|
+
1. **Parse issue ref** from `$ARGUMENTS` or extract from the active plan file.
|
|
18
|
+
2. **Fetch current issue state**:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
gh issue view <number> --repo <org>/<repo> --json number,title,state,labels,milestone,assignees,comments,url
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. **Determine current milestone** by checking:
|
|
25
|
+
- Does a plan file exist? → Plan created
|
|
26
|
+
- Is there a working branch? → Implementation started
|
|
27
|
+
- Are tasks in progress? → Active implementation
|
|
28
|
+
- Is there an open PR? → PR ready for review
|
|
29
|
+
- Is the PR merged? → Complete
|
|
30
|
+
|
|
31
|
+
### Step 2: Gather Update Content
|
|
32
|
+
|
|
33
|
+
| Milestone | Content to post |
|
|
34
|
+
|-----------|-----------------|
|
|
35
|
+
| **Plan created** | Plan summary, branch name, link to PR (if draft exists) |
|
|
36
|
+
| **Implementation in progress** | Task completion summary (X of Y tasks done), any blockers |
|
|
37
|
+
| **PR ready** | PR link, summary of changes, test results |
|
|
38
|
+
| **PR merged** | Final summary, suggest moving issue to `status:done` |
|
|
39
|
+
|
|
40
|
+
### Step 3: Post Update
|
|
41
|
+
|
|
42
|
+
1. **Idempotency check** — read the issue's recent comments. If the most recent comment with the prefix `[claude-sync] <milestone>` matches the current milestone AND the body content is unchanged, skip the post (no duplicate).
|
|
43
|
+
2. **Add the comment**:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
gh issue comment <number> --repo <org>/<repo> --body-file /tmp/sync-comment.md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The body must start with `[claude-sync] <milestone>` so the next sync run can dedupe.
|
|
50
|
+
|
|
51
|
+
3. **Report** to the user what was synced.
|
|
52
|
+
|
|
53
|
+
### Step 4: Suggest Status Transition
|
|
54
|
+
|
|
55
|
+
Based on the milestone, suggest (but do NOT automatically perform) a label transition:
|
|
56
|
+
|
|
57
|
+
| Milestone | Suggested label |
|
|
58
|
+
|-----------|-----------------|
|
|
59
|
+
| Plan created | `status:in-progress` |
|
|
60
|
+
| PR ready | `status:code-review` |
|
|
61
|
+
| PR merged | `status:done` |
|
|
62
|
+
|
|
63
|
+
The actual `status:in-progress` flip is owned by `lisa:github-build-intake` (claim) and `lisa:github-agent`. The `status:code-review` flip is owned by `lisa:github-evidence`. The `status:done` flip is typically owned by merge automation or PM. This skill never relabels.
|
|
64
|
+
|
|
65
|
+
## Important Notes
|
|
66
|
+
|
|
67
|
+
- **Never auto-transition labels** — always suggest and let the user / pipeline confirm.
|
|
68
|
+
- **Idempotent updates** — the `[claude-sync] <milestone>` prefix on the most-recent comment is the dedupe key.
|
|
69
|
+
- **Comment format** — use GitHub-flavored markdown (`##` headings, fenced code blocks). The same template is used for the JIRA path (rendered as wiki markup there); keep the markdown source canonical.
|
|
70
|
+
|
|
71
|
+
## Execution
|
|
72
|
+
|
|
73
|
+
Sync the issue now.
|