standup-mr 0.1.2 → 0.2.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,94 @@
1
+ # Changelog
2
+
3
+ All notable changes to standup-mr are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
+ [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.2.1] - 2026-08-31
8
+
9
+ ### Fixed
10
+
11
+ - A pull request whose CI timed out was reported as ready to merge. GitHub
12
+ reports a timed-out job with the conclusion `cancelled`, not `timed_out`, so
13
+ it normalised to a `canceled` pipeline — and a canceled pipeline was treated
14
+ as a green light. A canceled pipeline now blocks, on both providers: GitLab's
15
+ `canceled` status took the same path.
16
+ - Every error line in a GitHub blocker was reported twice. GitHub Actions echoes
17
+ a step's script inside a `##[group]Run …` block before running it, and those
18
+ echoed lines matched the error patterns. The body of a `Run` group is now
19
+ suppressed; other groups are still scanned, since they carry real output.
20
+
21
+ Both were found by testing 0.2.0 against the real GitHub Actions API — neither
22
+ was reachable from the test fixtures.
23
+
24
+ ## [0.2.0] - 2026-08-31
25
+
26
+ GitHub joins GitLab as a first-class provider, and the previous-day report
27
+ stops throwing work away. Both changes break existing shapes — read the
28
+ migration notes before upgrading.
29
+
30
+ ### Added
31
+
32
+ - **GitHub provider.** Pull requests, review requests, activity events, and
33
+ blockers, on `github.com` and on GitHub Enterprise (`/api/v3`). When CI is
34
+ red the failed Actions job's log is opened and its error lines reported, with
35
+ a fall back to a non-Actions check run's summary.
36
+ - **Provider selection.** `--provider github` / `--provider gitlab`, the
37
+ `STANDUP_PROVIDER` environment variable, host-name recognition, and a fall
38
+ back to whichever of `gh` / `glab` is logged in. Ambiguity fails with a clear
39
+ error rather than a guess.
40
+ - `provider` on the report and on every merge request, review, and blocker, so
41
+ a consumer can pick the right vocabulary (`!123` vs `#123`).
42
+
43
+ ### Changed
44
+
45
+ - **BREAKING — JSON output: `previous` and `previousEvents` are gone,**
46
+ replaced by `previousDays[]`. Each entry carries `date`, `label`, `gapDays`,
47
+ and its own `events`. The old single-day shape reported only the most recent
48
+ active day, so a Saturday with any activity at all silently discarded the
49
+ whole of Friday's work — which is exactly the day a Monday standup is about.
50
+ Anyone piping `standup fetch | jq .previous` now gets `null` with no error;
51
+ read `.previousDays` instead, and write up every entry.
52
+ - **BREAKING — library API:**
53
+ - `Provider.getReviews(identity, today)` takes an `Identity` object where it
54
+ previously took a numeric user id. GitHub searches by login, GitLab by
55
+ numeric id, so the contract has to carry both.
56
+ - `MergeRequest`, `Review` and `Blocker` each gained a **required**
57
+ `provider` field.
58
+ - `getJson` now **throws** an `ApiError` on an authentication or rate-limit
59
+ failure where it previously returned `null`. `null` is reserved for exactly
60
+ one case: a 404. Previously an invalid token produced an empty standup note
61
+ that looked like a quiet day.
62
+ - **BREAKING — MCP:** `CollectOptions.provider` changed meaning. It is now a
63
+ provider *name* (`'github'` / `'gitlab'`); the injection point for a
64
+ `Provider` instance is the new `CollectOptions.providerImpl`.
65
+ - The `standup` skill (`skills/standup/SKILL.md`) changed incompatibly with
66
+ 0.1.x: it reads `previousDays` and carries provider-specific vocabulary
67
+ rules. Run `/plugin marketplace update standup-mr` after upgrading.
68
+
69
+ ### Fixed
70
+
71
+ - A red pipeline whose Actions run or job **timed out** (or hit
72
+ `startup_failure` / `action_required`) now reaches the job log instead of
73
+ degrading silently to the check-run summary.
74
+ - An Actions blocker with no error lines no longer suppresses the check-run
75
+ fallback that held the real reason.
76
+ - GitHub's **secondary** rate limit (403 with `retry-after` and a non-zero
77
+ remaining count) is reported as a rate limit with the retry delay, not as a
78
+ missing-permissions error.
79
+ - An ambient `GITHUB_TOKEN` — exported by dotfiles and CI everywhere — no
80
+ longer hard-errors a working GitLab setup. When both environment pairs are
81
+ present, the pair that names a `*_HOST` wins.
82
+ - `getEvents` stops paging at GitHub's documented ~300-event feed cap instead
83
+ of requesting a page beyond it.
84
+ - An unreachable job log degrades to "no error lines" rather than failing the
85
+ whole run.
86
+
87
+ ## [0.1.2] - 2026-08-28
88
+
89
+ - Initial published line: GitLab merge requests, buckets, review queue, and
90
+ failed-pipeline diagnosis from the job trace. CLI, MCP server, and Claude
91
+ Code skill.
92
+
93
+ [0.2.0]: https://github.com/Jubstaaa/standup-mr/releases/tag/v0.2.0
94
+ [0.1.2]: https://github.com/Jubstaaa/standup-mr/releases/tag/v0.1.2
package/README.md CHANGED
@@ -3,35 +3,55 @@
3
3
  Standup notes from **merge request state**, not commit logs.
4
4
 
5
5
  Most standup tools read your local `git log`. That answers "what did I type",
6
- which is not what anyone asks in a standup. This one reads GitLab: what is ready
7
- to merge, what is blocked, what is waiting on you — and when a pipeline is red,
8
- it opens the job log and tells you **why**.
6
+ which is not what anyone asks in a standup. This one reads GitLab or GitHub:
7
+ what is ready to merge, what is blocked, what is waiting on you — and when a
8
+ pipeline is red, it opens the job log and tells you **why**.
9
9
 
10
10
  ## What makes it different
11
11
 
12
12
  | | commit-log tools | standup-mr |
13
13
  |---|---|---|
14
- | Source | local `git log` | GitLab API |
14
+ | Source | local `git log` | GitLab or GitHub API |
15
15
  | Merge request state | ✗ | ready / blocked / draft / stale |
16
16
  | Review queue | ✗ | pending only, approvals filtered out |
17
- | Failed pipeline | ✗ | error lines pulled from the job trace |
18
- | Self-hosted GitLab | varies | first class |
17
+ | Failed pipeline | ✗ | error lines from the job trace or the Actions job log |
18
+ | Self-hosted (GitLab CE/EE, GitHub Enterprise) | varies | first class |
19
19
 
20
20
  ## Use
21
21
 
22
22
  ```bash
23
- npx standup-mr fetch # JSON
24
- npx standup-mr fetch --markdown # structured digest
25
- npx standup-mr fetch --lang tr # Turkish date labels
23
+ npx standup-mr fetch # JSON, provider auto-detected
24
+ npx standup-mr fetch --provider github # GitHub
25
+ npx standup-mr fetch --provider gitlab # GitLab
26
+ npx standup-mr fetch --markdown # structured digest
27
+ npx standup-mr fetch --lang tr # Turkish date labels
26
28
  ```
27
29
 
28
- Credentials resolve in this order, independently for host and token:
30
+ ### Identity
29
31
 
30
- 1. `--host` / `--token`
31
- 2. `GITLAB_HOST` / `GITLAB_TOKEN`
32
- 3. the local [`glab`](https://gitlab.com/gitlab-org/cli) CLI config
32
+ | | GitHub | GitLab |
33
+ |---|---|---|
34
+ | Flags | `--host` / `--token` | `--host` / `--token` |
35
+ | Env | `GITHUB_HOST` / `GITHUB_TOKEN` | `GITLAB_HOST` / `GITLAB_TOKEN` |
36
+ | CLI session | [`gh`](https://cli.github.com/) auth config | [`glab`](https://gitlab.com/gitlab-org/cli) auth config |
37
+
38
+ GitHub defaults to `github.com` when no host is given. GitLab has no default —
39
+ self-hosted is the norm there, so a host must come from a flag, env var, or
40
+ `glab`'s own config.
41
+
42
+ The provider itself is picked in this order:
43
+
44
+ 1. `--provider github` / `--provider gitlab`, if passed
45
+ 2. a recognizable `--host` (`github.com`, `gitlab.com`, or a hostname
46
+ containing `github`/`gitlab`)
47
+ 3. `STANDUP_PROVIDER`, or whichever of the `GITHUB_*` / `GITLAB_*` env pairs
48
+ is set
49
+ 4. whichever of `gh` / `glab` is logged in
33
50
 
34
- So if you already use `glab`, there is nothing to configure.
51
+ If none of these resolve or both do, ambiguously — the command fails with a
52
+ clear error instead of guessing.
53
+
54
+ So if you already use `gh` or `glab`, there is nothing to configure.
35
55
 
36
56
  ### Post it to chat
37
57
 
@@ -46,21 +66,15 @@ npx standup-mr fetch --markdown | npx standup-mr post --slack "$SLACK_WEBHOOK_UR
46
66
  **MCP server** (`mcp/`) — one tool, `get_standup_data`, for Claude Desktop,
47
67
  Cursor, or any MCP client. See [`mcp/README.md`](mcp/README.md).
48
68
 
49
- **Claude Code skill** (`skills/standup/`) — the note-writing playbook. Install
50
- it as a plugin from inside Claude Code:
69
+ **Claude Code plugin** — the note-writing playbook, shipped as the `standup`
70
+ skill. From inside Claude Code:
51
71
 
52
72
  ```
53
73
  /plugin marketplace add Jubstaaa/standup-mr
54
74
  /plugin install standup@standup-mr
55
75
  ```
56
76
 
57
- Then type `/standup`.
58
-
59
- Or, without the plugin marketplace, copy it in manually:
60
-
61
- ```bash
62
- cp -r skills/standup ~/.claude/skills/standup
63
- ```
77
+ Then type `/standup`. Updates come with `/plugin marketplace update standup-mr`.
64
78
 
65
79
  ## `--markdown` is a digest, not a written note
66
80
 
@@ -71,6 +85,81 @@ lives in the MCP client's prompt or in the Claude Code skill.
71
85
  - Without AI: a structured digest.
72
86
  - With AI: a note you can read out.
73
87
 
88
+ ## What the digest looks like
89
+
90
+ Anonymised output from a real Monday run — note that Friday and Saturday each
91
+ get their own section, and that a merge request GitLab has not evaluated is not
92
+ called ready:
93
+
94
+ ```markdown
95
+ # Monday, 31 August — dev
96
+
97
+ _Structured digest — not a written note._
98
+
99
+ ## Previous working day: Friday, 28 August
100
+
101
+ - `acme/ui` pushed to — fix(keyboard): scale keys to viewport (4 commits)
102
+ - `acme/ui` accepted — chore(deps): bump @acme/ui to 0.5.18
103
+ - `acme/api` opened — feat: package subscription sales
104
+
105
+ ## Previous working day: Saturday, 29 August
106
+
107
+ - `acme/ui` pushed to — fix(keyboard): close the autofill bar (1 commit)
108
+
109
+ ## Ready to merge (2)
110
+
111
+ - `acme/api` !196 fix: normalise the +90 trunk prefix
112
+ - `acme/web` !194 refactor: loading state — **no pipeline ran**
113
+
114
+ ## Blocked (1)
115
+
116
+ - `acme/terminal` !49 fix: relative date chips — **1 unresolved comment(s)**
117
+
118
+ ## Reviews (2 pending)
119
+
120
+ - `acme/mobile` !501 chore: upgrade to RN 0.87 — Teammate
121
+
122
+ ## Blockers
123
+
124
+ - `acme/mobile` !6 — job `quality`
125
+ - `npm ERR! code E404`
126
+ - `npm ERR! 404 Not Found - GET https://registry.example.com/@acme%2fui`
127
+ ```
128
+
129
+ The last section is the point of the tool. Every other standup tool can tell you
130
+ that pipeline is red; this one opens the failed job's log and shows you the
131
+ 404 — and a 404 rather than a 403 usually means the token's scope is wrong, not
132
+ that the package is missing.
133
+
134
+ ## Known limits
135
+
136
+ - **GitHub's events feed is shallow.** It is capped at roughly 300 events over
137
+ the last 90 days, so a very active account or an old gap can silently lose
138
+ the earliest events. GitLab has no comparable documented cap.
139
+ - **GitHub activity is only visible to a token belonging to that same
140
+ account**, and private-repository events do not show up for anyone else's
141
+ token, even with otherwise sufficient scopes.
142
+ - **On GitHub, CI that reports only through the legacy commit-statuses API**
143
+ — still how some vendors integrate — shows up as `pipelineMissing`. Check
144
+ state is read from check-runs only.
145
+
146
+ ## Upgrading from 0.1.x
147
+
148
+ 0.2.0 changes the JSON output, the library API, and the MCP options. If you
149
+ pipe `standup fetch` into anything, or import the package, read
150
+ [`CHANGELOG.md`](CHANGELOG.md) before upgrading. The short version:
151
+
152
+ - `previous` and `previousEvents` are replaced by `previousDays[]`, one entry
153
+ per active day, so a weekend no longer swallows Friday. `jq .previous` now
154
+ returns `null` with no error.
155
+ - `MergeRequest`, `Review` and `Blocker` carry a required `provider` field, and
156
+ `Provider.getReviews` takes an `Identity` rather than a numeric id.
157
+ - The MCP `CollectOptions.provider` is now a provider *name*; inject a
158
+ `Provider` instance through `providerImpl`.
159
+
160
+ Claude Code plugin users should run `/plugin marketplace update standup-mr` —
161
+ the `standup` skill changed along with the report shape.
162
+
74
163
  ## Requirements
75
164
 
76
165
  Node 20 or newer. No runtime dependencies.