gem-contribute 0.2.0 → 0.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.
- checksums.yaml +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +14 -8
- data/.github/workflows/ci.yml +26 -0
- data/.github/workflows/pr-template-check.yml +100 -0
- data/CHANGELOG.md +26 -0
- data/CLAUDE.md +1 -1
- data/CONTRIBUTING.md +10 -4
- data/README.md +13 -1
- data/docs/OPEN_QUESTIONS.md +167 -0
- data/docs/ROADMAP.md +266 -0
- data/docs/adr/0006-standalone-gem-not-plugin.md +1 -1
- data/docs/adr/0008-rooibos-tui-framework.md +3 -3
- data/docs/adr/0010-charm-ruby-tui-framework.md +2 -2
- data/docs/adr/0011-host-adapter-owns-host-verbs.md +58 -0
- data/docs/adr/0012-output-free-service-objects-three-interface-architecture.md +79 -0
- data/docs/adr/0013-revert-to-rooibos.md +71 -0
- data/docs/adr/0014-ship-bundler-and-rubygems-plugins.md +75 -0
- data/docs/adr/README.md +7 -3
- data/docs/design-interface-layer.md +295 -0
- data/docs/design.md +31 -8
- data/docs/index.md +1 -1
- data/docs/prep-plan.md +6 -6
- data/lib/gem_contribute/cli/auth.rb +22 -44
- data/lib/gem_contribute/cli/config.rb +29 -15
- data/lib/gem_contribute/cli/fix.rb +122 -0
- data/lib/gem_contribute/cli/fork.rb +145 -0
- data/lib/gem_contribute/cli/init.rb +19 -24
- data/lib/gem_contribute/cli/issue_announcer.rb +42 -0
- data/lib/gem_contribute/cli/issues.rb +36 -47
- data/lib/gem_contribute/cli/platform_tools.rb +33 -0
- data/lib/gem_contribute/cli/post_clone_hooks.rb +50 -0
- data/lib/gem_contribute/cli/rate_limit_footer.rb +5 -3
- data/lib/gem_contribute/cli/scan.rb +20 -16
- data/lib/gem_contribute/cli/submit.rb +60 -64
- data/lib/gem_contribute/cli/workflow.rb +63 -0
- data/lib/gem_contribute/cli.rb +9 -16
- data/lib/gem_contribute/config.rb +27 -1
- data/lib/gem_contribute/git.rb +49 -0
- data/lib/gem_contribute/host_adapter.rb +52 -5
- data/lib/gem_contribute/host_adapters/github_adapter.rb +126 -37
- data/lib/gem_contribute/operations/announce.rb +52 -0
- data/lib/gem_contribute/operations/branch.rb +35 -0
- data/lib/gem_contribute/operations/clone.rb +41 -0
- data/lib/gem_contribute/operations/fix_pipeline.rb +70 -0
- data/lib/gem_contribute/operations/fork.rb +35 -0
- data/lib/gem_contribute/output/null.rb +20 -0
- data/lib/gem_contribute/output/standard.rb +71 -0
- data/lib/gem_contribute/version.rb +1 -1
- data/lib/gem_contribute.rb +10 -18
- metadata +109 -3
- data/lib/gem_contribute/cli/fork_clone_branch.rb +0 -204
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb726fe2025ba0cc501be01d13b4138ff4b21a9c755ad81c9b0181ef35f41c88
|
|
4
|
+
data.tar.gz: 33e6e83e38b27f2b4e2079fc79cfa76c2bfb178a2ba37424a05dfc8ad91398c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa04494e7ac4294f90d14ecb01d3f111d7e890dd5dc9ec1c5b77bc83aa215e8c0cac467f6bd9fa38ffa73c4665aece92520269473cf0f95555f48096a5a2b372
|
|
7
|
+
data.tar.gz: 4e9bfd2d676ac59d5d8c8c8db0e7928641c8e4f031a85fd435f1e52ec3b1b770aa41a705f456ad488a23019520093787d58e8326bbbf42e51f24a30e185a0cfc
|
|
@@ -2,21 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- One or two sentences. What changes, and why. The "why" is the part that's hard to recover later. -->
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Linked issue / ADR
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
<!--
|
|
8
|
+
Issue # this closes (or "none — drive-by fix").
|
|
9
|
+
For non-trivial changes: which ADR(s) does this touch? If you skipped that step, write "no ADR" plus a one-line reason.
|
|
10
|
+
-->
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
- [ ] **Full review, please.** Feedback on style, naming, idioms, and alternative designs welcome. I want the deep version, whether to learn the Ruby way or to stress-test a pattern I'm trying.
|
|
11
|
-
|
|
12
|
-
## Working agreement check
|
|
12
|
+
## Working agreement
|
|
13
13
|
|
|
14
14
|
- [ ] Single concern (multi-concern PRs get bounced — see [CLAUDE.md](../CLAUDE.md))
|
|
15
|
-
- [ ] ADRs touched: <!-- list ADR numbers, or "none" -->
|
|
16
15
|
- [ ] `bin/rubocop` and `bin/rspec` pass locally
|
|
17
16
|
- [ ] New behavior has a test; bug fix has a regression test
|
|
18
17
|
- [ ] Async work goes through Rooibos Commands (no direct threads / `Async` / synchronous shellouts)
|
|
19
18
|
|
|
19
|
+
## Test plan
|
|
20
|
+
|
|
21
|
+
<!--
|
|
22
|
+
How was this verified? Spec output, manual smoke, screenshots — whatever applies.
|
|
23
|
+
"`bin/rspec` passes" is the floor, not a test plan.
|
|
24
|
+
-->
|
|
25
|
+
|
|
20
26
|
## Notes for reviewer
|
|
21
27
|
|
|
22
|
-
<!-- Tradeoffs, open questions, follow-ups — anything not obvious from the diff. -->
|
|
28
|
+
<!-- Tradeoffs, open questions, follow-ups — anything not obvious from the diff. Delete the section if there's nothing to add. -->
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Specs and Rubocop
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Ruby
|
|
17
|
+
uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.2"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Run specs
|
|
23
|
+
run: bin/rspec
|
|
24
|
+
|
|
25
|
+
- name: Run rubocop
|
|
26
|
+
run: bin/rubocop
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: PR template check
|
|
2
|
+
|
|
3
|
+
# Verifies that PR descriptions include all required sections from
|
|
4
|
+
# .github/PULL_REQUEST_TEMPLATE.md. Posts (or updates) a single comment
|
|
5
|
+
# listing what's missing, and fails the check until the body is fixed.
|
|
6
|
+
#
|
|
7
|
+
# Security note: pull_request_target gives us write access to comment
|
|
8
|
+
# back on the PR. We never check out PR HEAD; the body is read via the
|
|
9
|
+
# event payload (data, not code).
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
pull_request_target:
|
|
13
|
+
types: [opened, edited, reopened, synchronize]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
pull-requests: write
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
template-check:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Verify required sections
|
|
23
|
+
env:
|
|
24
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
25
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
26
|
+
REPO: ${{ github.repository }}
|
|
27
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
28
|
+
run: |
|
|
29
|
+
set -euo pipefail
|
|
30
|
+
|
|
31
|
+
MARKER="<!-- pr-template-check -->"
|
|
32
|
+
|
|
33
|
+
# Required headings — must appear verbatim somewhere in the body.
|
|
34
|
+
required=(
|
|
35
|
+
"## Summary"
|
|
36
|
+
"## Linked issue / ADR"
|
|
37
|
+
"## Working agreement"
|
|
38
|
+
"## Test plan"
|
|
39
|
+
)
|
|
40
|
+
# "## Notes for reviewer" is intentionally optional — the template
|
|
41
|
+
# tells contributors to delete it when there's nothing to add.
|
|
42
|
+
|
|
43
|
+
missing=()
|
|
44
|
+
for heading in "${required[@]}"; do
|
|
45
|
+
if ! grep -Fq "$heading" <<< "${PR_BODY:-}"; then
|
|
46
|
+
missing+=("$heading")
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
# Strip HTML comments and template placeholder text, then check
|
|
51
|
+
# the body has *some* substance. Catches PRs filed with the raw
|
|
52
|
+
# unmodified template.
|
|
53
|
+
stripped=$(printf '%s' "${PR_BODY:-}" | perl -0777 -pe 's/<!--.*?-->//gs')
|
|
54
|
+
# Drop heading lines and checklist scaffolding; what's left should
|
|
55
|
+
# be the contributor's own prose.
|
|
56
|
+
prose=$(printf '%s' "$stripped" | grep -Ev '^\s*(##|- \[[ x]\]|$)' || true)
|
|
57
|
+
prose_chars=$(printf '%s' "$prose" | tr -d '[:space:]' | wc -c | tr -d ' ')
|
|
58
|
+
|
|
59
|
+
# Find any prior bot comment so we can edit instead of stacking.
|
|
60
|
+
prior_id=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" \
|
|
61
|
+
--jq ".[] | select(.user.login == \"github-actions[bot]\" and (.body | contains(\"$MARKER\"))) | .id" \
|
|
62
|
+
| head -n1)
|
|
63
|
+
|
|
64
|
+
if [ ${#missing[@]} -eq 0 ] && [ "$prose_chars" -ge 40 ]; then
|
|
65
|
+
echo "PR body looks good."
|
|
66
|
+
if [ -n "$prior_id" ]; then
|
|
67
|
+
gh api -X PATCH "repos/$REPO/issues/comments/$prior_id" \
|
|
68
|
+
-f body="$MARKER
|
|
69
|
+
✅ PR template check passed. Thanks for filling out the template."
|
|
70
|
+
fi
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
echo "$MARKER"
|
|
76
|
+
echo "👋 This PR is missing pieces from the [PR template](https://github.com/$REPO/blob/main/.github/PULL_REQUEST_TEMPLATE.md):"
|
|
77
|
+
echo ""
|
|
78
|
+
if [ ${#missing[@]} -gt 0 ]; then
|
|
79
|
+
echo "**Missing sections:**"
|
|
80
|
+
for m in "${missing[@]}"; do
|
|
81
|
+
echo "- \`$m\`"
|
|
82
|
+
done
|
|
83
|
+
echo ""
|
|
84
|
+
fi
|
|
85
|
+
if [ "$prose_chars" -lt 40 ]; then
|
|
86
|
+
echo "**Body looks unfilled** — the template comments are still there but no actual content has been written. Please fill in at least the Summary and Test plan."
|
|
87
|
+
echo ""
|
|
88
|
+
fi
|
|
89
|
+
echo "Edit the PR description (no new commit needed) and the check will re-run automatically. See [CLAUDE.md](https://github.com/$REPO/blob/main/CLAUDE.md) for why these sections matter."
|
|
90
|
+
} > /tmp/comment.md
|
|
91
|
+
|
|
92
|
+
if [ -n "$prior_id" ]; then
|
|
93
|
+
gh api -X PATCH "repos/$REPO/issues/comments/$prior_id" \
|
|
94
|
+
-F body=@/tmp/comment.md
|
|
95
|
+
else
|
|
96
|
+
gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file /tmp/comment.md
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
echo "::error::PR template is incomplete — see the bot comment on the PR."
|
|
100
|
+
exit 1
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ All notable changes to this project will be documented here. The format is based
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `gem-contribute fork <gem>` — the look-around-first counterpart to `fix`: fork the gem's repo, clone it, leave you on the default branch with no issue-tied work yet. Same `-e` / `-a` flags. Use this when you want to read the code before deciding whether to commit to a specific issue (closes [#12](https://github.com/cdhagmann/gem-contribute/issues/12)).
|
|
10
|
+
- `gem-contribute fix -e` opens your editor in the clone directory after fork/clone/branch. Uses the new `editor` config key, falling back to `$EDITOR` (closes [#14](https://github.com/cdhagmann/gem-contribute/issues/14)).
|
|
11
|
+
- `gem-contribute fix -a` launches your configured AI coding tool (new `ai_tool` config key) with the clone directory as cwd. Combine with `-e` to open both — editor first, AI tool second (closes [#14](https://github.com/cdhagmann/gem-contribute/issues/14)).
|
|
12
|
+
- `gem-contribute fix` posts a "👋 I've started working on this" comment to the issue by default so other contributors don't double up on the same work. Opt out per-invocation with `--no-comment`, globally with `comment_on_fix: false` in config, or per-repo via `comment_on_fix_overrides` (YAML-only). Posting is soft-fail — the fork/clone/branch part still succeeds even if the comment can't be posted (closes [#18](https://github.com/cdhagmann/gem-contribute/issues/18)).
|
|
13
|
+
- `scan` appends `· N claimed` to project lines whose open issues have already been claimed via the working-on-this marker, so you can spot already-in-progress work at a glance (closes [#20](https://github.com/cdhagmann/gem-contribute/issues/20)).
|
|
14
|
+
- `issues <gem|all>` prefixes claimed issues with `[claimed]` for the same reason (closes [#20](https://github.com/cdhagmann/gem-contribute/issues/20)).
|
|
15
|
+
- Long-running CLI operations (`fix`'s fork → clone → branch pipeline; `submit`'s `git push`) now show a tty-spinner in interactive terminals. Non-TTY contexts (CI, piped output, redirected stderr) fall back to plain status lines — no behavior change for scripted use (closes [#30](https://github.com/cdhagmann/gem-contribute/issues/30)).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- `gem-contribute init` reads input through `tty-prompt`. Cosmetic side effect: default values are now displayed in parens — `(~/code/oss)` — instead of brackets — `[~/code/oss]` — matching tty-prompt's convention. Y/n parsing is now built-in instead of hand-rolled (closes [#31](https://github.com/cdhagmann/gem-contribute/issues/31)).
|
|
20
|
+
- Internal class `ForkCloneBranch` renamed to `Fix` (the long name was cumbersome and didn't mirror the `fix` CLI verb). User-facing CLI surface unchanged.
|
|
21
|
+
- Internal architecture: `HostAdapter` now owns every host-API verb (`fork`, `comment`, `pull_request_url`) plus host-specific URL templating (`clone_url`, `repo_url`); the new `Operations::Fork` / `Operations::Clone` primitives compose those with `Git`; `CLI::Fork` and `CLI::Fix` are thin compositions on top. The fork-readiness polling moved into the adapter — multi-host adapters can model readiness however the host actually works. See [ADR-0011](docs/adr/0011-host-adapter-owns-host-verbs.md). User-facing CLI surface unchanged.
|
|
22
|
+
- Internal architecture (ADR-0012 Phase 1): `Operations::*` classes are now output-free and return `dry-monads` `Success` / `Failure` `Result` types; new `Operations::Branch` and `Operations::Announce` primitives; `Operations::FixPipeline` composes Fork → Clone → Branch → Announce via `dry-operation`; `Workflow#build_adapter` returns a `Result` and the old `with_workflow_rescues` rescue chain is gone; `CLI::Fork` / `CLI::Fix` initializers use `dry-initializer`. See [ADR-0012](docs/adr/0012-output-free-service-objects-three-interface-architecture.md). User-facing CLI surface unchanged.
|
|
23
|
+
- Internal architecture (ADR-0012 Phase 2): every CLI verb writes through a semantic `Output::Standard` (or `Output::Null` in tests) abstraction — `#info`, `#progress`, `#warn`, `#error` — instead of raw `@stdout.puts` / `@stderr.puts`. `#progress` accepts an optional block and wraps a `tty-spinner` in TTY contexts. Existing constructors still accept `stdout:` / `stderr:` and auto-wrap them, so test suites injecting StringIO streams keep working unchanged. New deps: `tty-spinner ~> 0.9`, `tty-prompt ~> 0.23` (both pure-Ruby) (closes [#29](https://github.com/cdhagmann/gem-contribute/issues/29)).
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- The `fork-clone-branch` CLI alias has been removed. Use `gem-contribute fix` instead — same behavior, shorter to type.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- `gem-contribute fork` no longer prints `cd <path> && explore` — `explore` was meant as English but read as a (non-existent) shell command, so a copy-paste produced `command not found`. The "Next:" hint is now conditional on `-e` / `-a`: with neither flag it suggests `cd <path> && $EDITOR .`; with either flag it skips the directory step (you're already in your editor) and just points at the `fix` command.
|
|
32
|
+
|
|
7
33
|
## [0.2.0] - 2026-05-02
|
|
8
34
|
|
|
9
35
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -4,7 +4,7 @@ This file is read by Claude Code when working in this repository. Treat it as th
|
|
|
4
4
|
|
|
5
5
|
## Project shape
|
|
6
6
|
|
|
7
|
-
`gem-contribute` is a terminal UI that reads a project's `Gemfile.lock`, surfaces open contributable issues from the gems' source repositories, and offers one-keystroke
|
|
7
|
+
`gem-contribute` is a terminal UI that reads a project's `Gemfile.lock`, surfaces open contributable issues from the gems' source repositories, and offers a one-keystroke `fix` flow.
|
|
8
8
|
|
|
9
9
|
Read `docs/design.md` and the ADRs in `docs/adr/` before making non-trivial changes. The design doc describes the architecture and the ADRs explain why specific decisions were made. If a change conflicts with an ADR, propose updating the ADR first; don't silently violate it.
|
|
10
10
|
|
data/CONTRIBUTING.md
CHANGED
|
@@ -6,11 +6,17 @@ Thanks for considering a contribution. This project is *about* lowering the fric
|
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
gem install gem-contribute
|
|
9
|
-
gem-contribute init
|
|
10
|
-
gem-contribute
|
|
9
|
+
gem-contribute init # set clone_root and auth with GitHub
|
|
10
|
+
gem-contribute fork gem-contribute # fork + clone; lands on the default branch
|
|
11
11
|
bundle install
|
|
12
|
-
bin/rspec
|
|
13
|
-
bin/gem-contribute
|
|
12
|
+
bin/rspec # tests should pass on a clean checkout
|
|
13
|
+
bin/gem-contribute # tool should run against this repo's own Gemfile.lock
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Once you've picked an issue to work on, branch off the default with `fix`:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
gem-contribute fix gem-contribute/<issue#> # creates gem-contribute/issue-<N> off the default branch
|
|
14
20
|
```
|
|
15
21
|
|
|
16
22
|
## What we welcome
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# gem-contribute
|
|
2
2
|
|
|
3
|
+
[](https://github.com/cdhagmann/gem-contribute/actions/workflows/ci.yml)
|
|
4
|
+
|
|
3
5
|
Find contributable issues in the gems your project already depends on.
|
|
4
6
|
|
|
5
7
|
```
|
|
@@ -39,7 +41,8 @@ gem-contribute init One-time interactive setup (sets clone_roo
|
|
|
39
41
|
gem-contribute scan [path] Summarize the contributable surface of a Gemfile.lock.
|
|
40
42
|
gem-contribute issues <gem|all> List "good first issue" issues for one gem (or all).
|
|
41
43
|
gem-contribute auth login Authenticate with GitHub via OAuth device flow.
|
|
42
|
-
gem-contribute
|
|
44
|
+
gem-contribute fork <gem|owner/repo> Fork and clone any GitHub repo, land on the default branch.
|
|
45
|
+
gem-contribute fix <gem>/<issue#> Fork, clone, and branch from main for a specific issue.
|
|
43
46
|
gem-contribute submit Push the branch and open a pre-filled PR in the browser.
|
|
44
47
|
gem-contribute config set <key> <val> Persist user preferences (e.g. clone_root).
|
|
45
48
|
```
|
|
@@ -56,6 +59,15 @@ $ cd ~/code/oss/rubocop/rubocop # whatever clone_root you set during in
|
|
|
56
59
|
$ gem-contribute submit # push + open the PR compare page in your browser
|
|
57
60
|
```
|
|
58
61
|
|
|
62
|
+
Or, when you want to look around a project before picking an issue, use `fork`:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
$ gem-contribute fork rubocop # fork-and-clone a gem by name
|
|
66
|
+
$ gem-contribute fork rubyevents/rubyevents -e # fork-and-clone any GitHub repo and open your editor
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`fork` does the same fork-clone-upstream sequence as `fix` but stops on the default branch — no issue branch, no comment. Handy for "build it locally and decide what to fix later." When you've picked an issue, `gem-contribute fix <gem>/<issue#>` branches off cleanly.
|
|
70
|
+
|
|
59
71
|
The auth step (run automatically by `init`, or directly via `gem-contribute auth login`) opens GitHub's device-flow page in your browser and copies the one-time code to your clipboard — same UX as `gh auth login`, no token paste, no client secret. Tokens cache at `~/.config/gem-contribute/auth.json` (mode 0600).
|
|
60
72
|
|
|
61
73
|
## Configuration
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Open Questions — Roadmap to v1
|
|
2
|
+
|
|
3
|
+
Working list of unresolved planning questions for the v1 roadmap (TUI + CLI + `bundle contribute` + `gem contribute`). Walked through one at a time with the maintainer; each gets crossed off and folded into the ROADMAP / ADRs as it's answered.
|
|
4
|
+
|
|
5
|
+
Order is rough priority — top items block downstream design, bottom items are polish.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Q1. ~~What is the "world map view"?~~ — ANSWERED 2026-05-03
|
|
10
|
+
|
|
11
|
+
A near-easter-egg view showing the locations of people who've kicked the tires on `gem-contribute`. Tracked as [issue #5](https://github.com/cdhagmann/gem-contribute/issues/5). Not a primary fragment — a hidden/discoverable view.
|
|
12
|
+
|
|
13
|
+
**Implications this surfaces:**
|
|
14
|
+
- Requires some form of opt-in usage reporting (the tool has to phone home with *something* to populate the map). New component: a tire-kicker reporting backend.
|
|
15
|
+
- Privacy/consent UX needs to live somewhere — likely first-run prompt or `init` flow.
|
|
16
|
+
- Backend service is itself a v1 dependency *if* the map ships in v1.
|
|
17
|
+
|
|
18
|
+
→ See **Q1a** below.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Q1a. ~~Does the world map ship in v1?~~ — ANSWERED 2026-05-03
|
|
23
|
+
|
|
24
|
+
No. Preserving the option by choosing Rooibos now; tire-kicker map waits until there's enough adoption to make the data interesting. No backend work in v1 scope.
|
|
25
|
+
|
|
26
|
+
**ADR-0013 reasoning lock-in:**
|
|
27
|
+
1. Workshop onboarding cost — the main argument for bubbletea — is no longer a constraint (workshop ended 2026-05-02)
|
|
28
|
+
2. Preserving the world map view (issue #5) as a future option
|
|
29
|
+
3. ADR-0008's original technical reasoning still stands (Command primitives matched our verbs, snapshot test helpers, fractal Router architecture)
|
|
30
|
+
4. Bubbletea-ruby's testing story was unverified per ADR-0010; Rooibos shipped tested helpers
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Q2. ~~Packaging shape~~ — ANSWERED 2026-05-03
|
|
35
|
+
|
|
36
|
+
One gem. `gem-contribute` ships the standalone CLI, the Bundler plugin hooks, and the RubyGems plugin hooks all together. ADR-0012's mention of a future `rubygems-contribute` gem is overridden by ADR-0014 (the new plugin ADR).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Q3. ~~What do `bundle contribute` / `gem contribute` do?~~ — ANSWERED 2026-05-03
|
|
41
|
+
|
|
42
|
+
CLI only — no TUI from the plugins. Reasoning: Bundler and RubyGems plugins aren't typically interactive; they're CLI subcommands. The TUI is a property of the standalone `gem-contribute` binary.
|
|
43
|
+
|
|
44
|
+
- `gem-contribute` (no args) → TUI
|
|
45
|
+
- `bundle contribute` (no args) → CLI default (`scan` or `list all` — see **Q3a**)
|
|
46
|
+
- `gem contribute` (no args) → CLI default (same)
|
|
47
|
+
- `<any>` `<verb>` → CLI verb
|
|
48
|
+
|
|
49
|
+
**Architectural consequence:** the plugin entry points never need to load Rooibos. Keeps plugin install lightweight.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Q3a. Bare-call default for the plugins: `scan` or `list all`?
|
|
54
|
+
|
|
55
|
+
User flagged as undecided. Both are read-only summary actions; difference is granularity and verbosity.
|
|
56
|
+
|
|
57
|
+
- **`scan`** — current verb; prints the summary table (`47 gems · 44 on github.com · 2 on gitlab.com · …`) plus top contributable projects by issue count. Hits the network for the issue counts (cached).
|
|
58
|
+
- **`list all`** — would presumably print every gem with its resolved source. Less network, more data, less curated.
|
|
59
|
+
|
|
60
|
+
No urgency to pick — can be deferred to Phase 4. Worth deciding alongside the verb taxonomy review (does `list` exist as a separate verb? sub-verbs of `list`?).
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Q4. ~~Default behavior of bare `gem-contribute`~~ — ANSWERED 2026-05-03
|
|
65
|
+
|
|
66
|
+
Packwerk-style launcher: `gem-contribute` (no args) opens a mini TUI that lists subcommands; arrow keys + enter pick one. `gem-contribute <verb>` runs the verb directly with no TUI in the way.
|
|
67
|
+
|
|
68
|
+
→ See **Q4a**: this reframes what the "full TUI" is.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Q4a. ~~What happens to the design.md "full TUI"?~~ — ANSWERED 2026-05-03
|
|
73
|
+
|
|
74
|
+
Bare `gem-contribute` launches the design.md four-fragment TUI (ProjectList → IssueList → IssueDetail → ContributingViewer + AuthOverlay + the eventual WorldMap). The packwerk reference was establishing "yes, raw command launches a TUI" as precedent — not a directive to mirror packwerk's exact subcommand-picker shape. Subcommands stay CLI.
|
|
75
|
+
|
|
76
|
+
Phase 3 of ROADMAP doesn't need rewriting; just confirm the entry-point wiring in `cli.rb` (no-arg → launch TUI vs print USAGE).
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Q5. ~~Multi-host adapters in v1?~~ — ANSWERED 2026-05-03
|
|
81
|
+
|
|
82
|
+
GitHub-only at v1.0. v1.x point releases will add adapters (GitLab, Codeberg, etc.). ADR-0011's architecture is the bet that paying off.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Q6. ~~Does ADR-0012's dry-rb adoption survive the framework revert?~~ — ANSWERED 2026-05-03
|
|
87
|
+
|
|
88
|
+
Yes. We need both a CLI and a TUI; output-free service objects with `Result` returns are what lets both consume the same service layer. ADR-0013 (Rooibos revert) doesn't touch ADR-0012.
|
|
89
|
+
|
|
90
|
+
Sub-question on `dry-cli` adoption is **deferred to Phase 4/5** when the plugin entry points get wired — easier to decide once the plugin shape is concrete.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Q7. Rooibos 0.7.x verification — ASSIGNED TO ME
|
|
95
|
+
|
|
96
|
+
Pre-Phase-3 task (no user decision needed): confirm Rooibos's current version on rubygems.org, verify Command primitives still exist, verify snapshot test helpers still ship. Folded into ROADMAP Phase 3.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Q8. ~~Workshop docs disposition~~ — MY CALL: archive
|
|
101
|
+
|
|
102
|
+
Moving workshop-era docs (`workshop.md`, `talk/`, `workshop-issues/`, `prep-plan.md`) to `docs/archive/` in Phase 6. Preserves history without polluting the active doc surface. Flag if you'd rather delete or keep them in place.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Q9. ~~Test framework + cassette policy~~ — MY CALL: keep design.md's strategy as-is
|
|
107
|
+
|
|
108
|
+
RSpec, VCR cassettes committed, no formal coverage target (just "every public method, every Update branch"). Snapshot helpers come from Rooibos — verified in Q7. Flag if you want a different testing posture for v1.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Q10. ~~v1 out-of-scope confirmation~~ — MY CALL: existing exclusions stand
|
|
113
|
+
|
|
114
|
+
All ADR-mandated out-of-scope items remain out for v1.0:
|
|
115
|
+
- Private repos / `repo` OAuth scope
|
|
116
|
+
- PR creation from inside the TUI (browser-based stays per ADR-0011)
|
|
117
|
+
- AI-anything
|
|
118
|
+
- Label normalization
|
|
119
|
+
- CONTRIBUTING parsing
|
|
120
|
+
- Multi-host adapters (per Q5; v1.x territory)
|
|
121
|
+
- World map view (per Q1a; post-v1)
|
|
122
|
+
|
|
123
|
+
Flag if anything moves into v1.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Q11. Branding / homepage — DEFER
|
|
128
|
+
|
|
129
|
+
Pre-release polish; revisit during Phase 6.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Q12. CHANGELOG.md / CONTRIBUTING.md / MAINTAINER.md — task list, not decision
|
|
134
|
+
|
|
135
|
+
Folded into ROADMAP Phase 6. No decision needed.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Q13. ~~OAuth App identity for v1 release~~ — ANSWERED 2026-05-03
|
|
140
|
+
|
|
141
|
+
Stay on the personal-account OAuth App for v1.0. Migrate to a dedicated identity when rate limits actually bite. Pragmatic — fits the rest of the v1 scope (don't pay for problems we don't have yet).
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Q14. ~~CI / release automation~~ — ANSWERED 2026-05-03
|
|
146
|
+
|
|
147
|
+
GitHub Actions, two workflows:
|
|
148
|
+
|
|
149
|
+
**CI (`ci.yml`)** — runs on push/PR:
|
|
150
|
+
- rubocop
|
|
151
|
+
- rspec
|
|
152
|
+
- integration tests gated behind `GEM_CONTRIBUTE_INTEGRATION=1` (off by default)
|
|
153
|
+
- smoke test: `bundle plugin install` + `gem install` on a clean Ruby image, verify both plugin entry points dispatch a verb
|
|
154
|
+
|
|
155
|
+
**Release (`release.yml`)** — runs on `v*` tag push:
|
|
156
|
+
- **Trusted Publishing via OIDC.** No API key stored as a secret; rubygems.org issues a short-lived token from the GitHub Actions OIDC claim. Compatible with `rubygems_mfa_required = true` (which the gemspec already sets).
|
|
157
|
+
- Setup: configure a trusted publisher entry on rubygems.org (gem name + repo + workflow filename) before the first automated release.
|
|
158
|
+
|
|
159
|
+
Multi-Ruby matrix and signed gems are post-v1.0 unless they become a real ask.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Notes / parking lot
|
|
164
|
+
|
|
165
|
+
- `docs/ideas.md` has one stray idea: "Make sure it respects PR templates" — file as a v1 issue.
|
|
166
|
+
- `docs/index.md` and `docs/_config.yml` suggest a Jekyll site; not yet investigated.
|
|
167
|
+
- `docs/claude-code-prompt.md` — not yet investigated.
|