github-delivery-os 1.2.1 → 1.3.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/.claude/skills/delivery-ops/SKILL.md +58 -1
- package/.github/scripts/package.json +3 -0
- package/README.md +249 -10
- package/package.json +2 -1
- package/src/install.js +65 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: delivery-ops
|
|
3
|
-
description: Operate a repo that has GitHub Delivery OS installed — create sprint/production-release/QA-request/bug issues that actually trigger its automation, comment as an approver in phrasing its workflows recognize,
|
|
3
|
+
description: Operate a repo that has GitHub Delivery OS installed — create sprint/production-release/QA-request/bug issues that actually trigger its automation, comment as an approver in phrasing its workflows recognize, check status (labels, latest comments, burn-down), and run autonomous task tracking (identify tasks/bugs, group them into phases via sprints, maintain a roadmap issue, update status, comment, and close as work progresses). Targets a specific repo via --repo; defaults to the current repo if this skill was installed into it and none is named. Use when asked to create a sprint, request a release, approve/decline a release, check release or sprint status, track/file a task or bug found during work, plan or check a roadmap/phase, or demo/test Delivery OS against a given repo.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Operate Delivery OS
|
|
@@ -30,6 +30,8 @@ Before creating anything that depends on configuration, check the target repo ac
|
|
|
30
30
|
|
|
31
31
|
**Show the constructed title, body, and labels before actually creating the issue** — this is a real, visible action in someone else's repo, not a preview in this conversation. Get confirmation on the content, not just the target repo, before calling `gh issue create`.
|
|
32
32
|
|
|
33
|
+
This confirm-first default is for issues created **on explicit request** ("file a bug for this", "create a sprint"). The "Autonomous tracking" section below describes a *different* mode — noticing and filing work on its own during a session — and overrides this default there: act first, confirm after, per its own "Confirm only when unsure" rule. Don't apply both rules to the same action.
|
|
34
|
+
|
|
33
35
|
**Sprint Planning** — triggers `sprint-child-creator` (one child issue per feature line, each labeled `sprint-active`, on open):
|
|
34
36
|
- Title **must contain** the literal string `SPRINT -`, e.g. `SPRINT - Sprint 14`
|
|
35
37
|
- Labels: `sprint`, `planning`
|
|
@@ -163,6 +165,61 @@ gh issue close <number> --repo <owner>/<repo>
|
|
|
163
165
|
|
|
164
166
|
`auto-close-sprint` fires on close, re-reads every `sprint-active` issue whose body contains `Parent Sprint: #<N>`, recomputes progress, and rewrites the sprint issue's `## 🚦 Sprint Status` section. At 100% it also closes the sprint issue itself and posts a completion comment. Re-check the sprint issue's body afterward to see the update — it happens as a side effect of closing the child, not as a response visible on the child issue itself.
|
|
165
167
|
|
|
168
|
+
## Autonomous tracking (identify → file → update → close)
|
|
169
|
+
|
|
170
|
+
Beyond filing one issue on request, this skill can run a piece of work's whole lifecycle: notice it, classify it, file it, keep it in sync as work happens, and close it out. GitHub issues are the only source of truth — there is no local state, and nothing here persists across sessions except what's written back to the repo.
|
|
171
|
+
|
|
172
|
+
### Confirm only when unsure
|
|
173
|
+
|
|
174
|
+
Don't ask before every action — that defeats the point. Act, then say so in one line of the conversation ("Filed #23: TASK - ...", "Updated #17 to In Progress", "Closed #17 — acceptance criteria met"). Every GitHub-visible action gets that line, regardless of confidence, so nothing happens invisibly even when nothing was asked first.
|
|
175
|
+
|
|
176
|
+
Ask first only when something is genuinely ambiguous:
|
|
177
|
+
- Unclear whether this is actually a new item or an update to an existing open issue
|
|
178
|
+
- Unclear which category it is (Task vs. Bug vs. part of a Sprint)
|
|
179
|
+
- Unclear whether it's actually done (e.g. a PR opened but CI hasn't run, or the acceptance criteria are only partly met)
|
|
180
|
+
|
|
181
|
+
A clear-cut case — an obvious bug just reproduced, a PR that visibly closes an issue's acceptance criteria — doesn't need a question, just the confirmation line afterward.
|
|
182
|
+
|
|
183
|
+
### Classifying a candidate
|
|
184
|
+
|
|
185
|
+
- Bug reproduced or reported while working → **Bug Report**
|
|
186
|
+
- Scoped, actionable follow-up (including things deliberately deferred, like [Phaneroo/github-delivery-operating-system#12](https://github.com/Phaneroo/github-delivery-operating-system/issues/12)) → **Task**
|
|
187
|
+
- A batch of related work with a start/end date → **Sprint** (see "Phases" below)
|
|
188
|
+
- Something that blocks a release or needs sign-off → **Production Release** / **QA Request** (rare mid-session; only when it's actually that, not just "important")
|
|
189
|
+
|
|
190
|
+
### Phases = Sprints, roadmap = one tracking issue
|
|
191
|
+
|
|
192
|
+
No new issue type needed — reuse what's already documented above:
|
|
193
|
+
- **A phase is a Sprint Planning issue.** Group Task issues under it exactly the way `sprint-child-creator` does: each child's body contains `Parent Sprint: #<N>`. This keeps the existing burn-down and auto-close automation working even though Claude, not a human, opened the children.
|
|
194
|
+
- **A roadmap is one persistent issue** that lists phases/sprints and their state. Title it `ROADMAP - <project/area>`. No labels or automation attach to it — Claude keeps its body current with `gh issue edit --body-file`, the same rewrite pattern `auto-close-sprint` uses for a sprint's `## 🚦 Sprint Status` section, just done by Claude on request or after a phase's state changes rather than by a workflow.
|
|
195
|
+
|
|
196
|
+
### Reconcile by querying, never by remembering
|
|
197
|
+
|
|
198
|
+
Don't rely on recalling an issue number from earlier in the conversation, and never assume it's still accurate after a gap. Before updating or closing something, requery — by keyword search, not just by label, since a filed issue may carry no label at all (labels like `task`/`bug` only exist once `Setup Labels` has been run for that repo; see the pre-flight check) or may be a Bug/Sprint-child/QA item instead of a Task:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
gh issue list --repo <owner>/<repo> --state open --search "<keywords from the work>"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Narrow with `--label task` (or `bug`, `sprint-active`, `qa-request`) only once the category is known and the target repo actually has that label — don't assume `--label task` alone finds everything relevant.
|
|
205
|
+
|
|
206
|
+
This is also what makes picking work back up in a *new* session possible without any local memory — the issue list itself is the state.
|
|
207
|
+
|
|
208
|
+
### Keeping a Task issue in sync
|
|
209
|
+
|
|
210
|
+
The `### Status` field in the Task template body is the thing to keep current:
|
|
211
|
+
- `Backlog` → `In Progress` when work actually starts on it
|
|
212
|
+
- → `Ready for Review` when a PR opens against it
|
|
213
|
+
- → `Done` right before closing
|
|
214
|
+
|
|
215
|
+
To edit just that field: `gh issue view <number> --repo <owner>/<repo> --json body -q .body`, replace the line under `### Status` with the new value, then `gh issue edit <number> --repo <owner>/<repo> --body-file <file>`. Post a comment alongside any status change that isn't self-explanatory from the status alone (blocked and why, PR link, what shipped) — `gh issue comment <number> --repo <owner>/<repo> --body "<update>"`.
|
|
216
|
+
|
|
217
|
+
Close with `gh issue close <number> --repo <owner>/<repo> --comment "<summary of what was done>"` once the acceptance criteria are actually met — quote which ones, don't just say "done."
|
|
218
|
+
|
|
219
|
+
### Known limitation
|
|
220
|
+
|
|
221
|
+
This only tracks what happens while a Claude session is actively working — nothing reconciles state that changes in the background (a human merges a PR or closes an issue manually with no session running). That gap is tracked as its own deferred item rather than solved here: [Phaneroo/github-delivery-operating-system#12](https://github.com/Phaneroo/github-delivery-operating-system/issues/12). Mitigate it by always reconciling via `gh issue list` at the start of relevant work (see above) rather than trusting anything remembered from earlier.
|
|
222
|
+
|
|
166
223
|
## Finding things
|
|
167
224
|
|
|
168
225
|
When there's no issue number in hand yet:
|
package/README.md
CHANGED
|
@@ -61,23 +61,36 @@ npx github-delivery-os uninstall --dry-run . # Preview (no changes)
|
|
|
61
61
|
|
|
62
62
|
`status` also checks npm for a newer release and tells you if you're behind (e.g. `⬆️ Update available: 1.0.3 → 1.1.0`), along with the exact command to update. That check is silent and non-fatal if you're offline — use `--offline` to skip it outright (e.g. in CI).
|
|
63
63
|
|
|
64
|
+
**Command variations — which one to run when:**
|
|
65
|
+
|
|
66
|
+
| Command | When to run it |
|
|
67
|
+
|---------|-----------------|
|
|
68
|
+
| `npx github-delivery-os install --with-templates .` | First install of Delivery OS in a repo without Claude Code — workflows + issue templates. The default recommendation above. |
|
|
69
|
+
| `npx github-delivery-os install --with-templates --with-labels .` | Same, plus creating all required labels immediately via `gh` CLI — skips the manual "Actions → Setup Labels → Run workflow" step. Needs `gh auth`. |
|
|
70
|
+
| `npx github-delivery-os install --with-templates --with-skill .` | You (or your team) will operate this repo's Delivery OS from [Claude Code](https://claude.com/claude-code) — adds the `delivery-ops` skill so issues/comments/status checks can be done in plain language. |
|
|
71
|
+
| `npx github-delivery-os install --with-templates --with-labels --with-skill .` | Everything at once — the fastest path to a fully working, Claude-Code-operable install in one command. |
|
|
72
|
+
| `npx github-delivery-os install --with-templates --with-skill --dry-run .` | Preview any of the above combinations first — prints what would be created without writing anything. Combine with any other flags. |
|
|
73
|
+
| `npx github-delivery-os install --with-templates --with-skill --overwrite .` | Updating an existing install to the latest release, or retroactively adding `--with-templates`/`--with-skill` to a repo that skipped them originally. **Only** command here that replaces existing files — everything above is always skip-existing/safe. |
|
|
74
|
+
| `npx github-delivery-os status .` | Not sure what's currently installed, whether it's up to date, or whether a workflow is broken (e.g. a required script silently missing). Safe, read-only. |
|
|
75
|
+
| `npx github-delivery-os uninstall --with-templates --with-skill .` | Removing Delivery OS entirely — workflows, scripts, templates, and the skill. Omit either flag to keep that part (both are kept by default). |
|
|
76
|
+
|
|
64
77
|
**What gets installed:**
|
|
65
78
|
|
|
66
|
-
| Workflow | Purpose |
|
|
67
|
-
|
|
68
|
-
| `sprint-child-creator` |
|
|
69
|
-
| `auto-close-sprint` |
|
|
70
|
-
| `notify-release-approver` |
|
|
71
|
-
| `authorize-deployment` |
|
|
72
|
-
| `auto-assign-qa` |
|
|
73
|
-
| `telegram-issues` | Telegram
|
|
74
|
-
| `setup-labels` | One-time
|
|
79
|
+
| Workflow | Trigger | Purpose |
|
|
80
|
+
|----------|---------|---------|
|
|
81
|
+
| `sprint-child-creator` | Issue opened, title contains `SPRINT -` | Parses "Sprint Features (One Per Line)" and creates one child issue per line, each linked back with `Parent Sprint: #N` |
|
|
82
|
+
| `auto-close-sprint` | Issue closed, body contains `Parent Sprint` | Recomputes the parent sprint's burn-down/health and rewrites its status section; auto-closes the sprint at 100% |
|
|
83
|
+
| `notify-release-approver` | Issue opened, labeled `production` | Comments on the issue tagging the repo's `RELEASE_APPROVER` |
|
|
84
|
+
| `authorize-deployment` | Comment posted on a `production`-labeled issue | Checks the commenter and keyword against `RELEASE_APPROVER`/`QA_APPROVER`; once both approve, adds `ready-for-deploy` |
|
|
85
|
+
| `auto-assign-qa` | Issue opened/labeled `qa` or `qa-request` | Assigns the repo's configured `QA_ASSIGNEES` |
|
|
86
|
+
| `telegram-issues` | Issue/comment/PR events | Sends a Telegram alert if `TELEGRAM_BOT_TOKEN`/`TELEGRAM_CHAT_ID` are configured |
|
|
87
|
+
| `setup-labels` | Manual (`workflow_dispatch`) | One-time run that creates all labels Delivery OS needs |
|
|
75
88
|
|
|
76
89
|
Workflows and templates are **copied directly** into your repo. No `workflow_call` or external references.
|
|
77
90
|
|
|
78
91
|
Installing via `npx github-delivery-os` (not the `scripts/install.sh` clone path) also writes `.github/delivery-os.json`, a small manifest recording the installed version — this is what powers the update check in `status`. It's only written when the files it describes are actually current (a fresh install, or `--overwrite`); a skip-mode install over existing files leaves it untouched rather than claiming a version that isn't really on disk. `uninstall` removes it.
|
|
79
92
|
|
|
80
|
-
With `--with-skill`, a `.claude/skills/delivery-ops/SKILL.md` file is also written — a Claude Code skill scoped to this repo, so anyone working here with Claude Code can create issues that correctly trigger the workflows above, comment as an approver,
|
|
93
|
+
With `--with-skill`, a `.claude/skills/delivery-ops/SKILL.md` file is also written — a Claude Code skill scoped to this repo, so anyone working here with Claude Code can create issues that correctly trigger the workflows above, comment as an approver, check status, and run autonomous task tracking (identify and file tasks/bugs, group them into phases via sprints, maintain a roadmap issue, and update/close issues as work progresses) without knowing the underlying `gh` commands or issue-body formats by heart. It's opt-in and retroactive: `--with-skill` on any later `install` call adds it if it isn't there yet.
|
|
81
94
|
|
|
82
95
|
---
|
|
83
96
|
|
|
@@ -104,6 +117,232 @@ When you open an issue using the **Sprint Planning** template with a title like
|
|
|
104
117
|
|
|
105
118
|
---
|
|
106
119
|
|
|
120
|
+
## Operating From Claude Code (`--with-skill`)
|
|
121
|
+
|
|
122
|
+
Installing with `--with-skill` drops a `.claude/skills/delivery-ops/SKILL.md` skill into the repo, scoped to *this* repo's Delivery OS install. It lets anyone using [Claude Code](https://claude.com/claude-code) drive the workflows above by asking in plain language — e.g. "create a sprint for the checkout redesign" — instead of hand-building `gh issue create` calls and remembering each template's exact field names.
|
|
123
|
+
|
|
124
|
+
Before doing anything, it checks the target repo: confirms Delivery OS is actually installed, that `Setup Labels` has been run, and that `RELEASE_APPROVER` / `QA_APPROVER` / `QA_ASSIGNEES` are configured — flagging (or offering to fix) gaps instead of silently creating an issue that does nothing. It also always shows the constructed title/body/labels or comment text for confirmation before creating or posting for real, since these are visible actions in the repo's activity, not a local preview.
|
|
125
|
+
|
|
126
|
+
It can also run the full lifecycle of a piece of work on its own: notice something worth tracking, classify it, file it, keep its status/comments in sync as work happens, and close it out — acting without asking when the outcome is clear (always posting a one-line notice in the conversation so nothing happens invisibly), and asking first only when the classification or "is this actually done" is genuinely ambiguous. A "phase" is just a Sprint Planning issue; a "roadmap" is one persistent issue Claude keeps rewritten with each phase's state — no new issue types or automation involved.
|
|
127
|
+
|
|
128
|
+
### Create a sprint
|
|
129
|
+
1. Ask: *"Create a sprint called Sprint 14 for \<goal>, running \<start> to \<end>, with features: \<one per line>"*
|
|
130
|
+
2. It opens an issue titled `SPRINT - Sprint 14`, labeled `sprint` + `planning`, with `### Sprint Name` / `Start` / `End` / `Goal` / `Features (One Per Line)` / `Approved` fields filled in.
|
|
131
|
+
3. On open, `sprint-child-creator` splits each feature line into its own child issue, labeled `sprint-active` and linked back with `Parent Sprint: #N`.
|
|
132
|
+
4. Close each child issue as work finishes — that's what advances the burn-down; `auto-close-sprint` recomputes it and rewrites the parent's `## 🚦 Sprint Status` section, auto-closing the sprint at 100%.
|
|
133
|
+
|
|
134
|
+
### Request a production release
|
|
135
|
+
1. Ask: *"Open a production release for \<project> v1.2.0, sprint #N, summary: \<summary>"*
|
|
136
|
+
2. It opens an issue titled `PRODUCTION RELEASE - <project> - v1.2.0`, labeled `release` + `production` + `approval`, with the sprint reference, version, release summary, QA summary/links, and `Deployment Authorized: No`.
|
|
137
|
+
3. On open, `notify-release-approver` comments tagging the repo's configured `RELEASE_APPROVER`.
|
|
138
|
+
|
|
139
|
+
### Approve or decline a release
|
|
140
|
+
1. Ask: *"Approve release #N"* or *"Decline release #N — \<reason>"*.
|
|
141
|
+
2. It checks that the currently authenticated `gh` login matches the repo's `RELEASE_APPROVER` — if not, it stops and says so instead of posting a comment that would silently do nothing.
|
|
142
|
+
3. It posts a comment starting with a recognized keyword (`approved`, `ok`, `go ahead` to approve; `declined`, `rejected`, `not approved` to decline) — `authorize-deployment` only reacts to that leading keyword from the exact configured approver. A later comment from the same approver overrides an earlier one.
|
|
143
|
+
|
|
144
|
+
### Request QA
|
|
145
|
+
1. Ask: *"Open a QA request for \<feature>, related to issue #N, testing \<what/where>"*
|
|
146
|
+
2. It opens an issue titled `QA REQUEST - <feature>`, labeled `qa-request`, with the related task, what to test, environment/build link, and acceptance criteria.
|
|
147
|
+
3. On open, `auto-assign-qa` assigns the repo's configured `QA_ASSIGNEES`.
|
|
148
|
+
|
|
149
|
+
### Approve QA
|
|
150
|
+
1. Ask: *"Mark QA #N as approved"* (or *"looks good"*).
|
|
151
|
+
2. Same login check as release approval, but against `QA_APPROVER`.
|
|
152
|
+
3. Posts a comment starting with `qa approved`, `approved`, `qa ok`, or `looks good`.
|
|
153
|
+
|
|
154
|
+
### Report a bug
|
|
155
|
+
1. Ask: *"File a bug: \<one-line summary>, severity \<level>, steps: \<...>"*
|
|
156
|
+
2. It opens an issue titled `[BUG] <summary>`, labeled `bug` + `qa`, with platform, severity, build/version, steps to reproduce, expected vs. actual result, and test environment.
|
|
157
|
+
|
|
158
|
+
### Track a task
|
|
159
|
+
1. Ask: *"Create a task to \<summary>, owner \<name>, priority P1"*
|
|
160
|
+
2. It opens an issue titled `TASK - <summary>`, labeled `task`, with owner, priority, status, acceptance criteria, and links. (No workflow trigger — this is plain tracking.)
|
|
161
|
+
|
|
162
|
+
### Check status
|
|
163
|
+
- *"What's the status of issue #N?"* → current labels and latest comments.
|
|
164
|
+
- *"How's Sprint 14 doing?"* → reads the parent issue's `## 🚦 Sprint Status` section (progress %, time elapsed, health, burn-down bar).
|
|
165
|
+
- *"What releases are waiting on approval?"* / *"What sprints are active?"* / *"What QA requests are open?"* → lists issues by label (`production`, `sprint`, `qa-request`) so you don't need an issue number in hand.
|
|
166
|
+
|
|
167
|
+
See [How To](docs/how-to.md) for the underlying workflows this drives, field by field.
|
|
168
|
+
|
|
169
|
+
### Example: filing a bug and a task, step by step
|
|
170
|
+
|
|
171
|
+
Worked against `jkaweesi22/klero`, a repo with Delivery OS installed. The bug part of this was actually run — that issue really exists at [jkaweesi22/klero#1](https://github.com/jkaweesi22/klero/issues/1); the task part follows the identical steps but wasn't actually created, shown for the field shape only.
|
|
172
|
+
|
|
173
|
+
**Filing the bug:**
|
|
174
|
+
|
|
175
|
+
1. In Claude Code, inside (or pointed at, via `--repo`) the target repo, describe the bug in plain language:
|
|
176
|
+
> *File a bug on jkaweesi22/klero — the order request form submits with an empty phone number, severity high. Steps: fill in the form, leave phone blank, submit. Expected: should block submission. Actual: submits anyway, so there's no way to contact the customer. Tested on Chrome, desktop, production.*
|
|
177
|
+
2. Claude pre-flights the repo — confirms Delivery OS is installed and the `bug`/`qa` labels exist.
|
|
178
|
+
3. Claude shows the exact issue it's about to create before doing anything:
|
|
179
|
+
- Title: `[BUG] Order request form submits with empty phone number`
|
|
180
|
+
- Labels: `bug`, `qa`
|
|
181
|
+
- Body, field by field: `Platform(s) Affected` → Web, `Severity` → High, `Build / Version` → main (as deployed), `Bug Summary`, `Steps to Reproduce` (numbered), `Expected Result`, `Actual Result`, `Test Environment` → Chrome, desktop, production.
|
|
182
|
+
4. Confirm ("yes") when asked to create it.
|
|
183
|
+
5. Claude runs `gh issue create` and reports back the issue — [jkaweesi22/klero#1](https://github.com/jkaweesi22/klero/issues/1). Nothing else happens automatically; bug reports don't trigger a workflow, they're just labeled and tracked.
|
|
184
|
+
|
|
185
|
+
**Filing the follow-up task:**
|
|
186
|
+
|
|
187
|
+
1. Ask Claude to turn the bug into tracked work, referencing the bug's issue number:
|
|
188
|
+
> *Create a task to add phone number validation to the order form, owner @jkaweesi22, priority P1, status Backlog, acceptance: form blocks submission until a valid phone number is entered. Link it to #1.*
|
|
189
|
+
2. Claude shows the constructed issue:
|
|
190
|
+
- Title: `TASK - Add phone number validation to order form`
|
|
191
|
+
- Labels: `task`
|
|
192
|
+
- Body: `Task Summary`, `Description` (references #1), `Owner` → @jkaweesi22, `Priority` → P1 - High, `Status` → Backlog, `Acceptance Criteria`, `Artifacts / Links` → Related bug: #1.
|
|
193
|
+
3. Confirm ("yes") to create it.
|
|
194
|
+
4. Claude runs `gh issue create`. Same as the bug — no workflow trigger, just labeled and tracked, now linked back to the bug it addresses.
|
|
195
|
+
|
|
196
|
+
### Full example: shipping a feature end-to-end
|
|
197
|
+
|
|
198
|
+
A realistic Claude Code session, run from inside the consumer repo (the skill defaults to it since it was installed with `--with-skill` there). `RELEASE_APPROVER`, `QA_APPROVER`, and `QA_ASSIGNEES` are already configured.
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
You: Create a sprint called "Sprint 14 - Checkout Revamp", running 2026-09-16 to
|
|
202
|
+
2026-09-30, goal is shipping the new checkout flow, features:
|
|
203
|
+
- Redesign cart summary
|
|
204
|
+
- Add saved payment methods
|
|
205
|
+
- Fix tax rounding bug
|
|
206
|
+
|
|
207
|
+
Claude: This will create an issue in acme/storefront:
|
|
208
|
+
|
|
209
|
+
Title: SPRINT - Sprint 14 - Checkout Revamp
|
|
210
|
+
Labels: sprint, planning
|
|
211
|
+
Body:
|
|
212
|
+
### Sprint Name
|
|
213
|
+
Sprint 14 - Checkout Revamp
|
|
214
|
+
### Sprint Start
|
|
215
|
+
2026-09-16
|
|
216
|
+
### Sprint End
|
|
217
|
+
2026-09-30
|
|
218
|
+
### Sprint Goal
|
|
219
|
+
Ship the new checkout flow
|
|
220
|
+
### Sprint Features (One Per Line)
|
|
221
|
+
Redesign cart summary
|
|
222
|
+
Add saved payment methods
|
|
223
|
+
Fix tax rounding bug
|
|
224
|
+
### Sprint Approved
|
|
225
|
+
Pending
|
|
226
|
+
|
|
227
|
+
Create this issue?
|
|
228
|
+
|
|
229
|
+
You: yes
|
|
230
|
+
|
|
231
|
+
Claude: Created #52. sprint-child-creator will fire on open and create one child
|
|
232
|
+
issue per feature — #53 "Redesign cart summary", #54 "Add saved payment
|
|
233
|
+
methods", #55 "Fix tax rounding bug" — each labeled sprint-active and
|
|
234
|
+
linked back with "Parent Sprint: #52".
|
|
235
|
+
|
|
236
|
+
[ ... engineers do the work, close #53 and #54 as they land ... ]
|
|
237
|
+
|
|
238
|
+
You: How's Sprint 14 doing?
|
|
239
|
+
|
|
240
|
+
Claude: Reading #52... ## 🚦 Sprint Status: 67% complete (2/3 closed), 20% of
|
|
241
|
+
sprint time elapsed, 🟢 on track.
|
|
242
|
+
|
|
243
|
+
You: QA found a rounding issue in the tax calc — file a bug. Severity high,
|
|
244
|
+
repros on checkout with 3+ items, expected total matches line items,
|
|
245
|
+
actual is off by $0.01.
|
|
246
|
+
|
|
247
|
+
Claude: This will create an issue in acme/storefront:
|
|
248
|
+
|
|
249
|
+
Title: [BUG] Tax rounding off by $0.01 with 3+ items
|
|
250
|
+
Labels: bug, qa
|
|
251
|
+
Body: (Platform, Severity: High, Steps to Reproduce, Expected vs.
|
|
252
|
+
Actual Result, Test Environment filled in from what you said)
|
|
253
|
+
|
|
254
|
+
Create this issue?
|
|
255
|
+
|
|
256
|
+
You: yes
|
|
257
|
+
|
|
258
|
+
Claude: Created #56.
|
|
259
|
+
|
|
260
|
+
[ ... #55 fixed, referencing #56 ... ]
|
|
261
|
+
|
|
262
|
+
You: Open a QA request for the tax rounding fix, related to #55, test on
|
|
263
|
+
staging, acceptance: totals match to the cent for carts of 1-10 items.
|
|
264
|
+
|
|
265
|
+
Claude: This will create an issue in acme/storefront:
|
|
266
|
+
|
|
267
|
+
Title: QA REQUEST - Tax rounding fix
|
|
268
|
+
Labels: qa-request
|
|
269
|
+
Body: (Related Sprint Task Issue #55, What to Test, Environment +
|
|
270
|
+
Build Link: staging, Acceptance Criteria filled in)
|
|
271
|
+
|
|
272
|
+
Create this issue?
|
|
273
|
+
|
|
274
|
+
You: yes
|
|
275
|
+
|
|
276
|
+
Claude: Created #57. auto-assign-qa will assign it to the configured
|
|
277
|
+
QA_ASSIGNEES.
|
|
278
|
+
|
|
279
|
+
[ ... QA tests it, comes back clean ... ]
|
|
280
|
+
|
|
281
|
+
You: Mark QA #57 as approved, looks good.
|
|
282
|
+
|
|
283
|
+
Claude: Checking gh auth status... authenticated as jane-qa, which matches this
|
|
284
|
+
repo's QA_APPROVER. Posting:
|
|
285
|
+
|
|
286
|
+
"looks good — verified on staging, totals match to the cent"
|
|
287
|
+
|
|
288
|
+
on #57.
|
|
289
|
+
|
|
290
|
+
You: yes, post it
|
|
291
|
+
|
|
292
|
+
Claude: Posted. Now close #55 to update the sprint burn-down?
|
|
293
|
+
|
|
294
|
+
You: yes
|
|
295
|
+
|
|
296
|
+
Claude: Closed #55. Sprint 14 is now 100% complete — auto-close-sprint closed
|
|
297
|
+
#52 and posted a completion comment.
|
|
298
|
+
|
|
299
|
+
You: Open a production release for storefront v2.4.1, sprint #52, summary
|
|
300
|
+
"checkout revamp: new cart summary, saved payment methods, tax rounding
|
|
301
|
+
fix", QA evidence: #57.
|
|
302
|
+
|
|
303
|
+
Claude: This will create an issue in acme/storefront:
|
|
304
|
+
|
|
305
|
+
Title: PRODUCTION RELEASE - storefront - v2.4.1
|
|
306
|
+
Labels: release, production, approval
|
|
307
|
+
Body:
|
|
308
|
+
### Sprint Reference (Sprint Planning Issue #)
|
|
309
|
+
#52
|
|
310
|
+
### Version / Build Number
|
|
311
|
+
v2.4.1
|
|
312
|
+
### Release Summary
|
|
313
|
+
Checkout revamp: new cart summary, saved payment methods, tax
|
|
314
|
+
rounding fix
|
|
315
|
+
### QA Summary + Evidence Links
|
|
316
|
+
#57
|
|
317
|
+
### Overall QA Recommendation
|
|
318
|
+
Approve for Production
|
|
319
|
+
### Deployment Authorized
|
|
320
|
+
No
|
|
321
|
+
|
|
322
|
+
Create this issue?
|
|
323
|
+
|
|
324
|
+
You: yes
|
|
325
|
+
|
|
326
|
+
Claude: Created #58. notify-release-approver posted a comment tagging this
|
|
327
|
+
repo's RELEASE_APPROVER (john-lead).
|
|
328
|
+
|
|
329
|
+
[ ... some time later, as john-lead ... ]
|
|
330
|
+
|
|
331
|
+
You: Approve release #58.
|
|
332
|
+
|
|
333
|
+
Claude: Checking gh auth status... authenticated as john-lead, which matches
|
|
334
|
+
RELEASE_APPROVER. Posting "approved" on #58.
|
|
335
|
+
|
|
336
|
+
You: yes
|
|
337
|
+
|
|
338
|
+
Claude: Posted. authorize-deployment will add ready-for-deploy once both
|
|
339
|
+
approvers (release + QA) have a qualifying comment on record.
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Each `yes` above is a real confirmation gate — Claude shows the exact issue/comment content before it creates or posts anything, since it's a visible action in the repo.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
107
346
|
## Documentation
|
|
108
347
|
|
|
109
348
|
| Document | Description |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "github-delivery-os",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A GitHub-native Delivery Governance Framework for structured sprint execution, QA review, and collaborative production release control.",
|
|
5
5
|
"main": "src/install.js",
|
|
6
6
|
"bin": {
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
".github/scripts/authorize-deployment-verdict.js",
|
|
49
49
|
".github/scripts/auto-close-sprint.js",
|
|
50
50
|
".github/scripts/sprint-child-creator.js",
|
|
51
|
+
".github/scripts/package.json",
|
|
51
52
|
".github/ISSUE_TEMPLATE",
|
|
52
53
|
".claude/skills/delivery-ops"
|
|
53
54
|
],
|
package/src/install.js
CHANGED
|
@@ -27,6 +27,17 @@ const WORKFLOWS = [
|
|
|
27
27
|
// them explicitly in package.json's "files".
|
|
28
28
|
const SCRIPTS = ['authorize-deployment-verdict', 'auto-close-sprint', 'sprint-child-creator'];
|
|
29
29
|
|
|
30
|
+
// These scripts are CommonJS (`require`/`module.exports`). Node picks CJS vs.
|
|
31
|
+
// ESM per-file by walking up to the nearest package.json — so a consumer repo
|
|
32
|
+
// whose own root package.json has `"type": "module"` would otherwise make
|
|
33
|
+
// Node treat these .js files as ES modules too, breaking `require()` at
|
|
34
|
+
// runtime with "ReferenceError: module is not defined in ES module scope".
|
|
35
|
+
// This override pins the .github/scripts subtree to CommonJS regardless of
|
|
36
|
+
// the consumer's own type field. Always installed alongside SCRIPTS, same as
|
|
37
|
+
// SCRIPTS is alongside WORKFLOWS — not itself require()'d by anything, but a
|
|
38
|
+
// required dependency of every script that is.
|
|
39
|
+
const SCRIPTS_PACKAGE_JSON = 'package.json';
|
|
40
|
+
|
|
30
41
|
// Which workflow requires which script, so `status` can flag a workflow
|
|
31
42
|
// that's present but whose required script is missing (an install that will
|
|
32
43
|
// fail with MODULE_NOT_FOUND the next time that workflow actually runs).
|
|
@@ -240,6 +251,21 @@ function runInstall(options) {
|
|
|
240
251
|
{ overwrite, dryRun, relDir: '.github/scripts' }
|
|
241
252
|
));
|
|
242
253
|
|
|
254
|
+
// The CommonJS-pinning package.json (see SCRIPTS_PACKAGE_JSON above) —
|
|
255
|
+
// always installed alongside SCRIPTS, via the same helper, counted the
|
|
256
|
+
// same way (mirrors how scripts/install.sh reuses copy_managed_files for
|
|
257
|
+
// this exact file rather than hand-rolling the copy).
|
|
258
|
+
const { name: scriptsPkgName, ext: scriptsPkgExt } = path.parse(SCRIPTS_PACKAGE_JSON);
|
|
259
|
+
const scriptsPkgResult = copyManagedFiles(
|
|
260
|
+
[scriptsPkgName],
|
|
261
|
+
scriptsPkgExt,
|
|
262
|
+
scriptsSrc,
|
|
263
|
+
scriptsDest,
|
|
264
|
+
{ overwrite, dryRun, relDir: '.github/scripts' }
|
|
265
|
+
);
|
|
266
|
+
scriptsCopied += scriptsPkgResult.copied;
|
|
267
|
+
scriptsSkipped += scriptsPkgResult.skipped;
|
|
268
|
+
|
|
243
269
|
let templatesSkipped = 0;
|
|
244
270
|
let skillSkipped = 0;
|
|
245
271
|
|
|
@@ -472,6 +498,19 @@ async function runStatus(options) {
|
|
|
472
498
|
return !fs.existsSync(path.join(targetAbs, '.github', 'scripts', `${requiredScript}.js`));
|
|
473
499
|
});
|
|
474
500
|
|
|
501
|
+
// A script can be present while the CommonJS-pinning package.json (see
|
|
502
|
+
// SCRIPTS_PACKAGE_JSON in src/install.js) is missing — e.g. an install from
|
|
503
|
+
// before this fix existed. That's fine in a repo whose own package.json
|
|
504
|
+
// has no "type" field or "type": "commonjs", but breaks with
|
|
505
|
+
// "ReferenceError: module is not defined in ES module scope" the moment
|
|
506
|
+
// the consumer repo's package.json has "type": "module". Flagged
|
|
507
|
+
// separately from brokenWorkflows since it's silent until that condition
|
|
508
|
+
// is hit, not an immediate break.
|
|
509
|
+
const scriptsRequiringPkgJson = installedWorkflows.some((wf) => REQUIRED_SCRIPT_BY_WORKFLOW[wf]);
|
|
510
|
+
const scriptsPkgJsonMissing =
|
|
511
|
+
scriptsRequiringPkgJson &&
|
|
512
|
+
!fs.existsSync(path.join(targetAbs, '.github', 'scripts', SCRIPTS_PACKAGE_JSON));
|
|
513
|
+
|
|
475
514
|
if (installedWorkflows.length > 0 || installedTemplates.length > 0 || skillInstalled) {
|
|
476
515
|
const manifest = readManifest(targetAbs);
|
|
477
516
|
if (manifest && manifest.version) {
|
|
@@ -514,6 +553,15 @@ async function runStatus(options) {
|
|
|
514
553
|
console.log('');
|
|
515
554
|
}
|
|
516
555
|
|
|
556
|
+
if (scriptsPkgJsonMissing) {
|
|
557
|
+
console.log(`⚠️ .github/scripts/${SCRIPTS_PACKAGE_JSON} is missing.`);
|
|
558
|
+
console.log(' If this repo\'s own package.json has "type": "module", every workflow that');
|
|
559
|
+
console.log(' require()s a script under .github/scripts will fail with "module is not');
|
|
560
|
+
console.log(' defined in ES module scope" the next time it runs.');
|
|
561
|
+
console.log(' Fix: npx github-delivery-os@latest install --overwrite .');
|
|
562
|
+
console.log('');
|
|
563
|
+
}
|
|
564
|
+
|
|
517
565
|
if (installedTemplates.length > 0) {
|
|
518
566
|
console.log('Templates:');
|
|
519
567
|
installedTemplates.forEach((t) => console.log(` ✓ ${t}`));
|
|
@@ -592,6 +640,19 @@ function runUninstall(options) {
|
|
|
592
640
|
}
|
|
593
641
|
}
|
|
594
642
|
|
|
643
|
+
// The CommonJS-pinning package.json travels with SCRIPTS — same
|
|
644
|
+
// unconditional removal.
|
|
645
|
+
const scriptsPkgDest = path.join(scriptsDest, SCRIPTS_PACKAGE_JSON);
|
|
646
|
+
if (fs.existsSync(scriptsPkgDest)) {
|
|
647
|
+
if (dryRun) {
|
|
648
|
+
console.log(` [dry-run] Would remove: .github/scripts/${SCRIPTS_PACKAGE_JSON}`);
|
|
649
|
+
} else {
|
|
650
|
+
fs.unlinkSync(scriptsPkgDest);
|
|
651
|
+
console.log(` Removed: .github/scripts/${SCRIPTS_PACKAGE_JSON}`);
|
|
652
|
+
}
|
|
653
|
+
scriptsRemoved++;
|
|
654
|
+
}
|
|
655
|
+
|
|
595
656
|
if (withTemplates) {
|
|
596
657
|
for (const t of TEMPLATES) {
|
|
597
658
|
const dest = path.join(templatesDest, t);
|
|
@@ -634,7 +695,9 @@ function runUninstall(options) {
|
|
|
634
695
|
// reason the other three are checked explicitly rather than assumed:
|
|
635
696
|
// defensive completeness against a future change (e.g. a failed unlink,
|
|
636
697
|
// or script removal ever becoming flag-gated like templates/skill).
|
|
637
|
-
const anyScriptsRemain =
|
|
698
|
+
const anyScriptsRemain =
|
|
699
|
+
SCRIPTS.some((name) => fs.existsSync(path.join(scriptsDest, `${name}.js`))) ||
|
|
700
|
+
fs.existsSync(path.join(scriptsDest, SCRIPTS_PACKAGE_JSON));
|
|
638
701
|
const skillRemains = fs.existsSync(skillPath(targetAbs));
|
|
639
702
|
const nothingLeft = !anyWorkflowsRemain && !anyTemplatesRemain && !anyScriptsRemain && !skillRemains;
|
|
640
703
|
|
|
@@ -688,6 +751,7 @@ module.exports = {
|
|
|
688
751
|
WORKFLOWS,
|
|
689
752
|
TEMPLATES,
|
|
690
753
|
SCRIPTS,
|
|
754
|
+
SCRIPTS_PACKAGE_JSON,
|
|
691
755
|
REQUIRED_SCRIPT_BY_WORKFLOW,
|
|
692
756
|
},
|
|
693
757
|
};
|