worclaude 2.4.12 → 2.5.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/CHANGELOG.md +18 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +132 -0
- package/README.md +1 -0
- package/SECURITY.md +21 -0
- package/package.json +9 -1
- package/templates/commands/commit-push-pr.md +24 -1
- package/templates/commands/sync.md +177 -10
- package/templates/skills/universal/git-conventions.md +49 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to worclaude are documented in this file. Format loosely fol
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.5.0] — 2026-04-21
|
|
8
|
+
|
|
9
|
+
First release under the new per-PR bump declaration workflow. Shifts release mechanism from "every `/sync` publishes" to "every PR declares a bump, `/sync` aggregates, and only user-visible work ships." PR authors now declare `Version bump: {major|minor|patch|none}` in their PR body; `/sync` picks the highest declared bump since the last tag using precedence `major > minor > patch > none`. All-`none` batches update shared-state files on develop but never cut a release — internal-only work (docs, CI, tests) accumulates without triggering noisy publishes.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Per-PR `Version bump:` declaration** (PR #99) — new step 6 in `/commit-push-pr` asks authors to declare `major`/`minor`/`patch`/`none` in the PR body; revert PRs match the bump of the PR being reverted; ambiguous cases ASK the user. The declaration is pasted into both `templates/commands/` (scaffolded into user projects) and `.claude/commands/` (Worclaude's own runtime), kept byte-identical by convention.
|
|
14
|
+
- **`/sync` aggregation rewrite** (PR #99) — replaces the single-step version bump with bootstrap (no-tag → yes/custom/cancel prompt, broadened semver regex accepts pre-release/build metadata, push-failure recovery), aggregation (`gh pr list --limit 500`, `%as` date format to avoid GitHub-search incompatibility with `%ai`, release-PR filter via `headRefName=develop`+`baseRefName=main`, missing-declarations treated as `none`+warning carried through to release PR body and CHANGELOG), ship/wait confirmation (always prompts including for `major`), CHANGELOG append with section defaults mapped from bump type (major/minor → Added, patch → Fixed) and content-driven placement across `### Added`/`### Changed`/`### Fixed`/`### Tests`/`### Docs`.
|
|
15
|
+
- **`tests/templates/version-bump-consistency.test.js`** (PR #99) — new 8-case Vitest asserts `Version bump:` appears literally in all 8 authoritative files (`CLAUDE.md`, both tree copies of `commit-push-pr.md`, `sync.md`, `git-conventions`, and `.github/pull_request_template.md`). Catches rename drift (e.g., `Version bump:` → `Release bump:` in one file without the others). Uses `import.meta.dirname`-derived `REPO_ROOT` matching the `v2-audit` test convention.
|
|
16
|
+
- **`.github/pull_request_template.md`** — required `Version bump:` field with HTML-comment placeholder.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **CLAUDE.md Rule #13** reworded: "every merge to `main` gets at least a patch bump" → "every merge to `main` IS a release." Internal-only `none`-only batches now update shared-state files on develop but never reach `main`.
|
|
21
|
+
- **`.claude/skills/git-conventions/SKILL.md`** — fixed two pre-existing statements that contradicted the new policy: line 117 "every merge to main gets at least a patch bump" replaced with release-carries-bump wording; line 124 table row for docs/CI/tests changed from `patch` to `none (no release)`. `templates/skills/universal/git-conventions.md` already said "no bump" so no contradiction-fix was needed there; both files now have the new `### Per-PR bump declarations` + `### Edge cases` subsections appended identically. Unrelated wording divergence between the two trees left alone.
|
|
22
|
+
- **`README.md`** — short "Batched releases" bullet in the "Why Worclaude" section.
|
|
23
|
+
- ⚠ **PR #98 (`fix(upstream): advance state on SKIP_ISSUE`)** — no `Version bump:` declaration (merged 2026-04-21 14:58 UTC, before PR #99 introduced the workflow). Treated as `none` with warning per bootstrap handling. Under-documentation made visible here rather than silently lost. The fix itself advances `.github/upstream-state.json` whenever Claude returns `SKIP_ISSUE` so no-new-item runs don't re-evaluate the same feed indefinitely.
|
|
24
|
+
|
|
7
25
|
## [2.4.12] — 2026-04-20
|
|
8
26
|
|
|
9
27
|
Internal fix release — first post-v2.4.11 `upstream-check` run on `main` (workflow run 24693290867) failed with `error_max_turns / num_turns: 16` at the Claude cross-reference step. Not a parser issue: the v2.4.11 format-drift fix still works; Claude simply couldn't fit the workload into 15 turns. The prompt requires ~9 `Read` calls (feed inputs + `.claude/commands/upstream-check.md` + cross-reference against agents/commands/hooks templates, `src/data/agents.js`, `src/data/agent-registry.js`, `docs/spec/BACKLOG-v2.1.md`, `CLAUDE.md`) before the final response — each Read burns a turn, so 15 was tight by luck, not by design.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity
|
|
10
|
+
and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
* Demonstrating empathy and kindness toward other people
|
|
21
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
* Giving and gracefully accepting constructive feedback
|
|
23
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
* Focusing on what is best not just for us as individuals, but for the
|
|
26
|
+
overall community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
* The use of sexualized language or imagery, and sexual attention or
|
|
31
|
+
advances of any kind
|
|
32
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
* Public or private harassment
|
|
34
|
+
* Publishing others' private information, such as a physical or email
|
|
35
|
+
address, without their explicit permission
|
|
36
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official e-mail address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to the community leaders responsible for enforcement at
|
|
63
|
+
sefaertunc@gmail.com.
|
|
64
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
65
|
+
|
|
66
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
67
|
+
reporter of any incident.
|
|
68
|
+
|
|
69
|
+
## Enforcement Guidelines
|
|
70
|
+
|
|
71
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
72
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
73
|
+
|
|
74
|
+
### 1. Correction
|
|
75
|
+
|
|
76
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
77
|
+
unprofessional or unwelcome in the community.
|
|
78
|
+
|
|
79
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
80
|
+
clarity around the nature of the violation and an explanation of why the
|
|
81
|
+
behavior was inappropriate. A public apology may be requested.
|
|
82
|
+
|
|
83
|
+
### 2. Warning
|
|
84
|
+
|
|
85
|
+
**Community Impact**: A violation through a single incident or series
|
|
86
|
+
of actions.
|
|
87
|
+
|
|
88
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
89
|
+
interaction with the people involved, including unsolicited interaction with
|
|
90
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
91
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
92
|
+
like social media. Violating these terms may lead to a temporary or
|
|
93
|
+
permanent ban.
|
|
94
|
+
|
|
95
|
+
### 3. Temporary Ban
|
|
96
|
+
|
|
97
|
+
**Community Impact**: A serious violation of community standards, including
|
|
98
|
+
sustained inappropriate behavior.
|
|
99
|
+
|
|
100
|
+
**Consequence**: A temporary ban from any sort of interaction or public
|
|
101
|
+
communication with the community for a specified period of time. No public or
|
|
102
|
+
private interaction with the people involved, including unsolicited interaction
|
|
103
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
104
|
+
Violating these terms may lead to a permanent ban.
|
|
105
|
+
|
|
106
|
+
### 4. Permanent Ban
|
|
107
|
+
|
|
108
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
109
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
110
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
111
|
+
|
|
112
|
+
**Consequence**: A permanent ban from any sort of public interaction within
|
|
113
|
+
the community.
|
|
114
|
+
|
|
115
|
+
## Attribution
|
|
116
|
+
|
|
117
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
118
|
+
version 2.0, available at
|
|
119
|
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
120
|
+
|
|
121
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
122
|
+
enforcement ladder](https://github.com/mozilla/diversity).
|
|
123
|
+
|
|
124
|
+
[homepage]: https://www.contributor-covenant.org
|
|
125
|
+
|
|
126
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
|
127
|
+
https://www.contributor-covenant.org/faq. Translations are available at
|
|
128
|
+
https://www.contributor-covenant.org/translations.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Contributing to Worclaude
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing to Worclaude! Whether it's a bug report, feature idea, or pull request, your input helps make this tool better for everyone.
|
|
4
|
+
|
|
5
|
+
## Branching Strategy
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
feature-branch ──PR──▶ develop ──PR──▶ main (release)
|
|
9
|
+
│
|
|
10
|
+
└── gh-pages (docs, auto-deployed)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| Branch | Purpose | Who can push | Who can PR to it |
|
|
14
|
+
| ---------- | ------------------- | ------------------------ | ------------------------------------ |
|
|
15
|
+
| `develop` | Active development | Maintainer | Contributors (from feature branches) |
|
|
16
|
+
| `main` | Production releases | Maintainer | Maintainer only (from `develop`) |
|
|
17
|
+
| `gh-pages` | Documentation site | Maintainer (auto-deploy) | Nobody |
|
|
18
|
+
|
|
19
|
+
**Contributors only interact with `develop`.** Fork the repo, create a feature branch from `develop`, and open a PR back to `develop`. You cannot push or open PRs against `main` — they will be closed.
|
|
20
|
+
|
|
21
|
+
## Development Setup
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone https://github.com/sefaertunc/Worclaude.git
|
|
25
|
+
cd Worclaude
|
|
26
|
+
git checkout develop
|
|
27
|
+
npm install
|
|
28
|
+
npm test
|
|
29
|
+
npm run lint
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Run the CLI locally during development:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
node src/index.js init
|
|
36
|
+
node src/index.js status
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Using the Worclaude Workflow
|
|
40
|
+
|
|
41
|
+
If you have [Claude Code](https://claude.com/claude-code), this project includes a 6-stage workflow pipeline to guide contributions:
|
|
42
|
+
|
|
43
|
+
`/start` → `/review-plan` → implement → `/review-changes` → `/verify` → `/commit-push-pr`
|
|
44
|
+
|
|
45
|
+
Run these as slash commands in Claude Code for a guided experience.
|
|
46
|
+
|
|
47
|
+
## Pull Request Guidelines
|
|
48
|
+
|
|
49
|
+
1. Fork the repo and create a branch from `develop`
|
|
50
|
+
2. Make your changes in focused, logical commits
|
|
51
|
+
3. Write or update tests for any new functionality
|
|
52
|
+
4. Run the full test suite: `npm test`
|
|
53
|
+
5. Run the linter: `npm run lint`
|
|
54
|
+
6. Run the formatter: `npm run format`
|
|
55
|
+
7. Open a PR **targeting `develop`** with a clear description of the change
|
|
56
|
+
|
|
57
|
+
**Never open PRs against `main`** — they will be closed. Only the maintainer merges `develop` into `main` for releases.
|
|
58
|
+
|
|
59
|
+
Keep PRs focused on a single concern. If you're fixing a bug and adding a feature, split them into separate PRs.
|
|
60
|
+
|
|
61
|
+
### What CI Checks
|
|
62
|
+
|
|
63
|
+
Every PR is validated by CI before merge:
|
|
64
|
+
|
|
65
|
+
- **Tests** — full test suite across Node 18, 20, and 22
|
|
66
|
+
- **ESLint** — code quality and style rules
|
|
67
|
+
- **Prettier** — formatting consistency check
|
|
68
|
+
- **Branch** — must be up-to-date with `develop`
|
|
69
|
+
|
|
70
|
+
## Release Process (maintainer only)
|
|
71
|
+
|
|
72
|
+
Releases are cut from `main` and published automatically by GitHub Actions with
|
|
73
|
+
npm provenance (SLSA attestations).
|
|
74
|
+
|
|
75
|
+
1. Open a PR from `develop` to `main` containing the version bump (handled by `/sync`).
|
|
76
|
+
2. After merge, create a GitHub Release against `main` with tag `vX.Y.Z`.
|
|
77
|
+
3. The `.github/workflows/release.yml` workflow runs `npm publish --provenance`.
|
|
78
|
+
4. Verify the "Provenance" badge on `https://www.npmjs.com/package/worclaude`.
|
|
79
|
+
|
|
80
|
+
Do not run `npm publish` from a local machine — manual publishes omit provenance
|
|
81
|
+
and weaken the Snyk security score.
|
|
82
|
+
|
|
83
|
+
## Reporting Bugs
|
|
84
|
+
|
|
85
|
+
Open an issue on [GitHub Issues](https://github.com/sefaertunc/Worclaude/issues) with:
|
|
86
|
+
|
|
87
|
+
- A clear, descriptive title
|
|
88
|
+
- Steps to reproduce the problem
|
|
89
|
+
- Expected behavior vs actual behavior
|
|
90
|
+
- Your Node.js version and OS
|
|
91
|
+
- Any relevant error output
|
|
92
|
+
|
|
93
|
+
## Suggesting Features
|
|
94
|
+
|
|
95
|
+
Open an issue on [GitHub Issues](https://github.com/sefaertunc/Worclaude/issues) with the **enhancement** label. Describe the use case and how you envision the feature working.
|
|
96
|
+
|
|
97
|
+
## Code Style
|
|
98
|
+
|
|
99
|
+
This project uses ESLint and Prettier for consistent formatting. Before submitting:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run format # Auto-format with Prettier
|
|
103
|
+
npm run lint # Check for lint errors
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
All code must pass both checks. The CI pipeline enforces this automatically.
|
|
107
|
+
|
|
108
|
+
## Testing
|
|
109
|
+
|
|
110
|
+
We use [Vitest](https://vitest.dev/) for testing. All tests must pass before a PR can be merged:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm test # Run the full test suite
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
When adding new features, include tests that cover:
|
|
117
|
+
|
|
118
|
+
- The expected happy path
|
|
119
|
+
- Edge cases and error conditions
|
|
120
|
+
- Integration with existing commands (init, upgrade, status)
|
|
121
|
+
|
|
122
|
+
Test all three scenarios (fresh project, existing project, upgrade) if your change touches merge logic or file generation.
|
|
123
|
+
|
|
124
|
+
## Template Format Requirements
|
|
125
|
+
|
|
126
|
+
- **Skills** must be in directory format: `templates/skills/universal/skill-name.md` is the source, scaffolded as `.claude/skills/skill-name/SKILL.md` in user projects. Flat `.md` files in `.claude/skills/` are silently ignored by Claude Code.
|
|
127
|
+
- **Agents** must have both `name` and `description` in YAML frontmatter. Without `description`, agents are invisible to Claude Code's `/agents` and routing system.
|
|
128
|
+
- **Commands** are flat `.md` files in `templates/commands/` and scaffolded as `.claude/commands/command-name.md`. This is the legacy format and is supported.
|
|
129
|
+
|
|
130
|
+
## Questions?
|
|
131
|
+
|
|
132
|
+
Open a discussion on GitHub or mention it in your issue/PR. We're happy to help.
|
package/README.md
CHANGED
|
@@ -144,6 +144,7 @@ See the [full command reference](https://sefaertunc.github.io/Worclaude/referenc
|
|
|
144
144
|
- **Hook profiles.** Dial strictness up or down via one environment variable. `minimal` for CI, `standard` for daily work, `strict` for type-heavy projects.
|
|
145
145
|
- **Smart merge.** Detects existing Claude Code setups and merges additively — existing files never overwritten without confirmation. Three-tier strategy: additive for missing content, safe-alongside for conflicts, interactive for CLAUDE.md.
|
|
146
146
|
- **Self-healing doctor.** Catches drift, stale hashes, deprecated models, broken learnings — before they bite.
|
|
147
|
+
- **Batched releases.** Every PR declares `Version bump: {major|minor|patch|none}` in its body; `/sync` aggregates declarations across merged PRs and only cuts a release when at least one rises above `none`. Internal-only work (docs, CI, tests) accumulates on `develop` without triggering noisy publishes.
|
|
147
148
|
|
|
148
149
|
---
|
|
149
150
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| ------- | ------------------ |
|
|
7
|
+
| 2.4.x | :white_check_mark: |
|
|
8
|
+
| < 2.4 | :x: |
|
|
9
|
+
|
|
10
|
+
## Reporting a Vulnerability
|
|
11
|
+
|
|
12
|
+
Please report security issues privately via
|
|
13
|
+
[GitHub Security Advisories](https://github.com/sefaertunc/Worclaude/security/advisories/new).
|
|
14
|
+
This is the preferred channel — it lets us coordinate a fix before disclosure.
|
|
15
|
+
|
|
16
|
+
As a fallback, you may email **sefaertunc@gmail.com**.
|
|
17
|
+
|
|
18
|
+
Please do **not** open a public issue for security vulnerabilities.
|
|
19
|
+
|
|
20
|
+
You can expect an initial response within 48 hours.
|
|
21
|
+
If the vulnerability is accepted, a fix will be prioritized and released as a patch version.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "worclaude",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "The Workflow Layer for Claude Code — scaffold agents, commands, skills, hooks, and memory into any project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"templates/",
|
|
13
13
|
"README.md",
|
|
14
14
|
"CHANGELOG.md",
|
|
15
|
+
"CONTRIBUTING.md",
|
|
16
|
+
"CODE_OF_CONDUCT.md",
|
|
17
|
+
"SECURITY.md",
|
|
15
18
|
"LICENSE"
|
|
16
19
|
],
|
|
17
20
|
"repository": {
|
|
@@ -22,6 +25,7 @@
|
|
|
22
25
|
"bugs": {
|
|
23
26
|
"url": "https://github.com/sefaertunc/Worclaude/issues"
|
|
24
27
|
},
|
|
28
|
+
"funding": "https://github.com/sponsors/sefaertunc",
|
|
25
29
|
"author": "Sefa Ertunç",
|
|
26
30
|
"engines": {
|
|
27
31
|
"node": ">=18.0.0"
|
|
@@ -37,6 +41,10 @@
|
|
|
37
41
|
"docs:preview": "vitepress preview docs",
|
|
38
42
|
"prepublishOnly": "npm test && npm run lint"
|
|
39
43
|
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"provenance": true
|
|
47
|
+
},
|
|
40
48
|
"keywords": [
|
|
41
49
|
"claude",
|
|
42
50
|
"claude-code",
|
|
@@ -45,12 +45,35 @@ files (see git-conventions.md for the canonical list).
|
|
|
45
45
|
3. Write a clear, conventional commit message
|
|
46
46
|
4. Push to the current branch
|
|
47
47
|
5. Create a PR targeting develop: gh pr create --base develop
|
|
48
|
-
6.
|
|
48
|
+
6. Determine the version bump level for this PR. Read the Versioning Policy
|
|
49
|
+
in the project's git-conventions document to decide: `major`, `minor`,
|
|
50
|
+
`patch`, or `none`.
|
|
51
|
+
- `major` — breaking change to public API, CLI, or scaffold contract
|
|
52
|
+
- `minor` — new feature, command, agent, or flag
|
|
53
|
+
- `patch` — bug fix or user-visible behavior change with no new surface
|
|
54
|
+
- `none` — docs, CI, tests, internal refactor (nothing consumers notice)
|
|
55
|
+
|
|
56
|
+
For revert PRs: declare the same bump level as the PR being reverted.
|
|
57
|
+
|
|
58
|
+
If the change is ambiguous, ASK THE USER. Do not guess.
|
|
59
|
+
|
|
60
|
+
The PR description MUST include this line on its own, verbatim:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Version bump: {major|minor|patch|none}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`/sync` parses this string exactly — other phrasings will be ignored.
|
|
67
|
+
7. Include in PR description: title, changes, testing done, reviewer notes
|
|
49
68
|
|
|
50
69
|
## On develop
|
|
51
70
|
|
|
52
71
|
Only used for release merges after /sync has been run.
|
|
53
72
|
|
|
73
|
+
Versioning happens in `/sync`, not here. The release PR body is pre-written
|
|
74
|
+
by `/sync` with the aggregated bump summary and the list of feature PRs
|
|
75
|
+
included in the release.
|
|
76
|
+
|
|
54
77
|
1. Write a session summary to .claude/sessions/:
|
|
55
78
|
- Filename: YYYY-MM-DD-HHMM-{short-branch-name}.md
|
|
56
79
|
- Same format as the feature branch session summary above
|
|
@@ -35,23 +35,190 @@ and tell the user to run /conflict-resolver first.
|
|
|
35
35
|
docs/spec/SPEC.md to reflect the current state.
|
|
36
36
|
If nothing changed spec-wise, leave it alone.
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Bootstrap: ensure a version tag exists
|
|
39
39
|
|
|
40
|
-
6.
|
|
41
|
-
|
|
40
|
+
6. Check for a version tag:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If no tag exists, prompt the user. Do NOT silently auto-tag:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
No version tag found. /sync needs a starting tag to compute release scope.
|
|
50
|
+
|
|
51
|
+
Proposed: tag current HEAD as v0.1.0
|
|
52
|
+
|
|
53
|
+
- yes → create v0.1.0 tag at HEAD and continue
|
|
54
|
+
- custom → specify your own starting version (e.g., v1.0.0 if this
|
|
55
|
+
project had releases before adopting this workflow)
|
|
56
|
+
- cancel → stop; tag manually before re-running
|
|
57
|
+
|
|
58
|
+
Choose (yes / custom / cancel):
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
On "yes": `git tag v0.1.0 && git push origin v0.1.0`, then set
|
|
62
|
+
`LAST_TAG="v0.1.0"`.
|
|
63
|
+
|
|
64
|
+
On "custom": prompt for the version string. Accept any string matching
|
|
65
|
+
`^v\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$` (semver with
|
|
66
|
+
optional pre-release and build metadata, e.g. `v1.0.0-rc.1`, `v2.0.0+build.5`).
|
|
67
|
+
Reject non-matching input with a clear message and re-prompt. Then tag
|
|
68
|
+
and push as above.
|
|
69
|
+
|
|
70
|
+
On "cancel": exit cleanly with "Tag the current state manually before
|
|
71
|
+
re-running /sync."
|
|
72
|
+
|
|
73
|
+
If `git push origin {tag}` fails (fork clone, expired credentials,
|
|
74
|
+
network): the local tag is already created and valid. Report:
|
|
75
|
+
"Local tag created but push failed — retry with `git push origin {tag}`
|
|
76
|
+
manually before opening a release PR." Then exit cleanly.
|
|
77
|
+
|
|
78
|
+
After bootstrap, proceed to step 7. Expect "Nothing publishable since
|
|
79
|
+
{tag}" if no PRs have been merged yet — that is correct behavior for
|
|
80
|
+
a first-release bootstrap, not an error.
|
|
81
|
+
|
|
82
|
+
## Aggregate version bumps from merged PRs
|
|
83
|
+
|
|
84
|
+
7. Collect `Version bump:` declarations from all PRs merged into develop
|
|
85
|
+
since the last version tag. Use `%as` for the date format (strict
|
|
86
|
+
YYYY-MM-DD; `%ai` breaks GitHub search due to space separator and
|
|
87
|
+
timezone offset). Pass `--limit 500` to avoid the `gh pr list` default
|
|
88
|
+
cap of 30, which would silently truncate on repos with infrequent
|
|
89
|
+
tagging:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
SINCE=$(git log -1 --format=%as "$LAST_TAG")
|
|
93
|
+
gh pr list --state merged --base develop \
|
|
94
|
+
--limit 500 \
|
|
95
|
+
--search "merged:>=$SINCE" \
|
|
96
|
+
--json number,title,body,headRefName,baseRefName
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Filter out release PRs — any PR with `headRefName: develop` AND
|
|
100
|
+
`baseRefName: main` is a release PR from a prior `/sync` run, not an
|
|
101
|
+
input. Skip those.
|
|
102
|
+
|
|
103
|
+
For each remaining PR, extract the `Version bump:` line from the body.
|
|
104
|
+
Valid values: `major`, `minor`, `patch`, `none`.
|
|
105
|
+
|
|
106
|
+
Missing declarations: treat as `none` and add to a warning list
|
|
107
|
+
(carried through to step 9's summary and step 10's CHANGELOG entry).
|
|
108
|
+
Do NOT guess a higher value. Do NOT stop.
|
|
109
|
+
|
|
110
|
+
8. Compute the release bump using precedence: `major > minor > patch > none`.
|
|
111
|
+
- If the highest is `none`: update PROGRESS.md and SPEC.md if needed,
|
|
112
|
+
commit those, push, and stop. Do NOT bump the version. Do NOT open
|
|
113
|
+
a PR to main. Report:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Nothing publishable since {last-tag}. Shared state updated.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- If the highest is `patch`, `minor`, or `major`: proceed to step 9.
|
|
120
|
+
|
|
121
|
+
9. Summarize the release group for the user and ask for confirmation.
|
|
122
|
+
Always prompt, including for `major` — that's exactly when the human
|
|
123
|
+
sanity-check is most valuable.
|
|
124
|
+
|
|
125
|
+
If the warnings list from step 7 is empty, omit the warnings section
|
|
126
|
+
entirely — do NOT render an empty block or a "no warnings" line.
|
|
127
|
+
|
|
128
|
+
Summary format (warnings section included only when warnings exist):
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
Release group since {last-tag}:
|
|
132
|
+
- #{num} {title} — {bump}
|
|
133
|
+
- #{num} {title} — {bump}
|
|
134
|
+
- ...
|
|
135
|
+
|
|
136
|
+
⚠ PRs without Version bump: declaration (treated as none):
|
|
137
|
+
- #{num} {title}
|
|
138
|
+
- ...
|
|
139
|
+
|
|
140
|
+
Proposed version: {old} → {new} ({highest-bump})
|
|
141
|
+
|
|
142
|
+
Ship now, or wait for more work to land? (ship/wait)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
If the user says "wait", stop without bumping. They will re-run `/sync`
|
|
146
|
+
later when more PRs have merged.
|
|
147
|
+
|
|
148
|
+
10. On "ship":
|
|
149
|
+
|
|
150
|
+
a. Update the `version` field in `package.json` to the new version.
|
|
151
|
+
|
|
152
|
+
b. Append to `CHANGELOG.md` at the top of the entries list (after the
|
|
153
|
+
`# Changelog` header and the `## [Unreleased]` marker if present).
|
|
154
|
+
If `CHANGELOG.md` does not exist, create it with this header:
|
|
155
|
+
|
|
156
|
+
```markdown
|
|
157
|
+
# Changelog
|
|
158
|
+
|
|
159
|
+
All notable changes to this project are documented in this file.
|
|
160
|
+
Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
161
|
+
versions follow [semver](https://semver.org/).
|
|
162
|
+
|
|
163
|
+
## [Unreleased]
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The new entry format:
|
|
167
|
+
|
|
168
|
+
```markdown
|
|
169
|
+
## [{new-version}] — {YYYY-MM-DD}
|
|
170
|
+
|
|
171
|
+
{one-paragraph prose summary of what this release does — synthesize
|
|
172
|
+
from the merged PR titles and bodies; no bullet list in the summary}
|
|
173
|
+
|
|
174
|
+
### {Section}
|
|
175
|
+
|
|
176
|
+
- {bullet per PR mapped to its section, including PR number}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Section mapping — the declared bump determines the MINIMUM section,
|
|
180
|
+
but each PR's content governs its actual placement. PRs may be filed
|
|
181
|
+
under any of `### Added` / `### Changed` / `### Fixed` / `### Tests` /
|
|
182
|
+
`### Docs` as content warrants. Do not force a mapping that fights
|
|
183
|
+
the content.
|
|
184
|
+
|
|
185
|
+
Defaults when content is ambiguous:
|
|
186
|
+
- `major`, `minor` → default `### Added` (or `### Changed` for
|
|
187
|
+
breaking changes)
|
|
188
|
+
- `patch` → default `### Fixed` (but `### Added` is fine for
|
|
189
|
+
patch-level additive surface like new optional flags)
|
|
190
|
+
- `none` with warning → `### Changed` with ⚠ prefix noting
|
|
191
|
+
"no Version bump declaration — under-documented"
|
|
192
|
+
|
|
193
|
+
If a release mixes levels, each PR goes under its own section.
|
|
194
|
+
Multiple sections per release entry are standard.
|
|
195
|
+
|
|
196
|
+
The warning list from step 9 MUST appear in the CHANGELOG entry as
|
|
197
|
+
⚠-prefixed bullets under `### Changed` — not just in the transient
|
|
198
|
+
prompt. This is how under-documentation becomes permanent record.
|
|
42
199
|
|
|
43
200
|
## Verify
|
|
44
201
|
|
|
45
|
-
|
|
46
|
-
|
|
202
|
+
11. Run /verify to confirm tests and lint pass.
|
|
203
|
+
If anything fails, fix it before proceeding.
|
|
47
204
|
|
|
48
205
|
## Commit, push, and PR
|
|
49
206
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
207
|
+
12. git add -A
|
|
208
|
+
13. git commit -m "chore: sync progress, spec, and version to [new version]"
|
|
209
|
+
Use exactly this message format — no trailers or Co-Authored-By lines.
|
|
210
|
+
14. git push origin develop
|
|
211
|
+
15. Create the PR to main. Use the release group summary from step 9 as the
|
|
212
|
+
PR body verbatim (including any warnings block) — that becomes the
|
|
213
|
+
release notes:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
gh pr create --base main --title "release: v{new-version}" --body "{step-9-summary}"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The maintainer then manually creates a GitHub Release against main
|
|
220
|
+
with tag vX.Y.Z — that triggers the release.yml workflow which
|
|
221
|
+
publishes to npm with provenance. /sync does not publish.
|
|
55
222
|
|
|
56
223
|
## Trigger Phrases
|
|
57
224
|
- "sync progress"
|
|
@@ -135,6 +135,55 @@ Follow [semver](https://semver.org/) when the project publishes releases:
|
|
|
135
135
|
|
|
136
136
|
**Rule of thumb:** If the change affects what users see, install, or depend on, it needs a version bump. If it only affects the project's internal development workflow, it does not.
|
|
137
137
|
|
|
138
|
+
### Per-PR bump declarations
|
|
139
|
+
|
|
140
|
+
Every PR targeting `develop` declares its intended version bump in the PR
|
|
141
|
+
description:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
Version bump: {major|minor|patch|none}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- `major` — breaking change to public API, CLI, or scaffold contract
|
|
148
|
+
- `minor` — new feature, command, agent, or flag
|
|
149
|
+
- `patch` — bug fix or user-visible behavior change with no new surface
|
|
150
|
+
- `none` — docs, CI, tests, internal refactor (nothing consumers notice)
|
|
151
|
+
|
|
152
|
+
`/sync` aggregates declarations from all PRs merged since the last version
|
|
153
|
+
tag and picks the highest: `major > minor > patch > none`. If all merged
|
|
154
|
+
PRs are `none`, no release is cut — `/sync` updates shared-state files but
|
|
155
|
+
does not bump the version or open a PR to `main`.
|
|
156
|
+
|
|
157
|
+
This is how release batching works: internal-only work accumulates on
|
|
158
|
+
develop without triggering publishes, and multiple user-facing PRs group
|
|
159
|
+
into a single well-documented release.
|
|
160
|
+
|
|
161
|
+
### Edge cases
|
|
162
|
+
|
|
163
|
+
- **Release PRs (develop → main):** `/sync` excludes these from scanning.
|
|
164
|
+
They ARE the release, not an input to one. Known limitation: any
|
|
165
|
+
develop→main PR is excluded regardless of content. Safe in practice
|
|
166
|
+
because that direction is only used for releases.
|
|
167
|
+
- **Revert PRs:** Declare the same bump level as the PR being reverted.
|
|
168
|
+
Reverting a `patch` is itself a `patch`. A `patch` + matching revert
|
|
169
|
+
in the same release group produces a net-zero user-visible change but
|
|
170
|
+
still bumps the version — something shipped internally and was
|
|
171
|
+
un-shipped, which is part of the release's history. Do not cancel
|
|
172
|
+
them out.
|
|
173
|
+
- **Missing declarations:** Treated as `none` with a warning that
|
|
174
|
+
propagates to the release PR body and CHANGELOG entry. Do not manually
|
|
175
|
+
backfill old PR bodies — let them flow through as `none` so
|
|
176
|
+
under-documentation is visible rather than silent.
|
|
177
|
+
- **No tags yet (first release):** `/sync` prompts to create a starting
|
|
178
|
+
tag (default `v0.1.0`, customizable, cancelable). The tool does NOT
|
|
179
|
+
silently invent a tag.
|
|
180
|
+
- **Hotfix merged directly to main:** Bypasses `/sync` entirely. Requires
|
|
181
|
+
manual version management. Known limitation; out of scope.
|
|
182
|
+
|
|
183
|
+
**Optional:** GitHub labels (`release:major`, `release:minor`, etc.) can
|
|
184
|
+
replace body-text declarations for maintainers who prefer them. Deferred
|
|
185
|
+
to a future phase; not scaffolded by default.
|
|
186
|
+
|
|
138
187
|
## Gotchas
|
|
139
188
|
|
|
140
189
|
- Never force-push to main/master. Force-push to feature branches only when you
|