mirror of https://github.com/garrytan/gstack.git
The version-path pin (--version-path / .gstack/version-path) already let a repo point
the version tooling anywhere, but two real-world shapes still failed — and both failed
CLOSED, which silently disabled /ship's queue-collision check rather than erroring:
1. A package.json as the version source. The readers treated the pinned path as raw
text, so a JSON file was whitespace-stripped into
'{"name":"frontend","version":"0.99.2",...' — which parseVersion rejected, so every
read fell through to the 0.0.0.0 default. This bites any repo whose version lives in
a package.json rather than a plain VERSION file, at the root or not.
2. 3-digit semver. parseVersion required exactly four components, so gstack-next-version
exited 2 on every invocation in such a repo. That CLI *is* the queue-collision check,
so /ship took its documented offline path — naive local patch arithmetic. Two branches
cut from the same base then pick the same version, and git merges that WITHOUT a
conflict because both sides set one line to identical text. The duplicate slot ships
silently: two PRs land as one version, and only one gets a CHANGELOG entry. We hit
this six times in one repo before working out why.
lib/version-source.ts now holds the semantics so both CLIs agree by construction.
Detection is by shape rather than new configuration: a version-path ending in .json is
read (and written) as JSON via .version; a version string with three components stays
three components through bumping and formatting. A repo with a root VERSION file and
4-digit versions sees no behaviour change.
Details worth reviewing:
- MICRO on a 3-digit version is carried out as a PATCH, with a warning in the output.
/ship auto-picks MICRO by default, so erroring would make it unusable in every 3-digit
repo; a silent no-op would be worse, since the caller would write back the version it
started with and claim a slot already taken.
- When the version-path IS a package.json, that file is the single source of truth: it is
the only file written, and the DRIFT_* states cannot arise (there is no second file to
drift from), so classify returns only FRESH / ALREADY_BUMPED and repair is a no-op.
Also syncing a root package.json there would be a guess about which of two JSON files
the repo publishes from.
- Fixes a pre-existing bug in gstack-version-bump: versionRel was derived from the CLI
flag alone, ignoring the .gstack/version-path pin, so a pinned repo compared its local
version against the BASE's root VERSION — two different files. On a repo with no root
VERSION the base then always read as 0.0.0.0 and every branch looked FRESH.
Two existing assertions encoded the old 4-digit-only contract (parseVersion('1.2.3')
is null; VERSION_RE rejects 3-digit). Both are updated with the reasoning inline, and
the garbage-rejection cases are kept and extended.
ship/SKILL.md is deliberately untouched: documenting the new shapes there also requires
regenerating the three host-variant copies and three golden fixtures, which looks like a
release chore rather than something to guess at from outside. Happy to add the prose in a
follow-up if you tell me the right way to regenerate those.
|
||
|---|---|---|
| .. | ||
| chrome-cdp | ||
| dev-setup | ||
| dev-teardown | ||
| gstack-analytics | ||
| gstack-artifacts-init | ||
| gstack-artifacts-url | ||
| gstack-brain-cache | ||
| gstack-brain-consumer | ||
| gstack-brain-context-load.ts | ||
| gstack-brain-enqueue | ||
| gstack-brain-reader | ||
| gstack-brain-restore | ||
| gstack-brain-sync | ||
| gstack-brain-uninstall | ||
| gstack-builder-profile | ||
| gstack-codex-probe | ||
| gstack-codex-session-import | ||
| gstack-community-dashboard | ||
| gstack-config | ||
| gstack-decision-log | ||
| gstack-decision-search | ||
| gstack-detach | ||
| gstack-developer-profile | ||
| gstack-diff-scope | ||
| gstack-distill-apply | ||
| gstack-distill-free-text | ||
| gstack-extension | ||
| gstack-first-task-detect | ||
| gstack-gbrain-detect | ||
| gstack-gbrain-install | ||
| gstack-gbrain-lib.sh | ||
| gstack-gbrain-mcp-verify | ||
| gstack-gbrain-repo-policy | ||
| gstack-gbrain-source-wireup | ||
| gstack-gbrain-supabase-provision | ||
| gstack-gbrain-supabase-verify | ||
| gstack-gbrain-sync.ts | ||
| gstack-global-discover.ts | ||
| gstack-ios-qa-daemon | ||
| gstack-ios-qa-mint | ||
| gstack-ios-qa-regen | ||
| gstack-jsonl-merge | ||
| gstack-learnings-log | ||
| gstack-learnings-search | ||
| gstack-memory-ingest.ts | ||
| gstack-model-benchmark | ||
| gstack-next-version | ||
| gstack-open-url | ||
| gstack-patch-names | ||
| gstack-paths | ||
| gstack-platform-detect | ||
| gstack-pr-title-rewrite.sh | ||
| gstack-question-log | ||
| gstack-question-preference | ||
| gstack-redact | ||
| gstack-redact-prepush | ||
| gstack-relink | ||
| gstack-repo-mode | ||
| gstack-review-log | ||
| gstack-review-read | ||
| gstack-security-dashboard | ||
| gstack-session-kind | ||
| gstack-session-update | ||
| gstack-settings-hook | ||
| gstack-slug | ||
| gstack-specialist-stats | ||
| gstack-taste-update | ||
| gstack-team-init | ||
| gstack-telemetry-log | ||
| gstack-telemetry-sync | ||
| gstack-timeline-log | ||
| gstack-timeline-read | ||
| gstack-uninstall | ||
| gstack-update-check | ||
| gstack-version-bump | ||