init
This commit is contained in:
103
.opencode/skills/ship/references/auto-detect.md
Normal file
103
.opencode/skills/ship/references/auto-detect.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Auto-Detection Logic
|
||||
|
||||
Detect test runner, version file, and changelog format from project files.
|
||||
|
||||
## Test Runner Detection
|
||||
|
||||
Check in order (first match wins):
|
||||
|
||||
| Check | Test Command |
|
||||
|-------|-------------|
|
||||
| `package.json` → `scripts.test` exists | `npm test` |
|
||||
| `Makefile` → has `test:` target | `make test` |
|
||||
| `pytest.ini` OR `pyproject.toml` has `[tool.pytest]` | `pytest` |
|
||||
| `Cargo.toml` exists | `cargo test` |
|
||||
| `go.mod` exists | `go test ./...` |
|
||||
| `Gemfile` + `Rakefile` with test task | `bundle exec rake test` |
|
||||
| `build.gradle` or `build.gradle.kts` | `./gradlew test` |
|
||||
| `pom.xml` | `mvn test` |
|
||||
| `mix.exs` | `mix test` |
|
||||
| `deno.json` | `deno test` |
|
||||
|
||||
**Detection script:**
|
||||
```bash
|
||||
if [ -f package.json ] && grep -q '"test"' package.json 2>/dev/null; then
|
||||
echo "npm test"
|
||||
elif [ -f Makefile ] && grep -q '^test:' Makefile 2>/dev/null; then
|
||||
echo "make test"
|
||||
elif [ -f pytest.ini ] || ([ -f pyproject.toml ] && grep -q '\[tool.pytest' pyproject.toml 2>/dev/null); then
|
||||
echo "pytest"
|
||||
elif [ -f Cargo.toml ]; then
|
||||
echo "cargo test"
|
||||
elif [ -f go.mod ]; then
|
||||
echo "go test ./..."
|
||||
else
|
||||
echo "NONE"
|
||||
fi
|
||||
```
|
||||
|
||||
**If NONE:** Use `AskUserQuestion` — "No test runner detected. Options: A) Skip tests, B) Provide test command"
|
||||
|
||||
## Version File Detection
|
||||
|
||||
Check in order:
|
||||
|
||||
| Check | Read Pattern |
|
||||
|-------|-------------|
|
||||
| `VERSION` file | Read as semver string |
|
||||
| `package.json` → `version` field | `jq -r .version package.json` |
|
||||
| `pyproject.toml` → `version` | grep `version = "..."` |
|
||||
| `Cargo.toml` → `version` | grep `version = "..."` |
|
||||
| `mix.exs` → `@version` | grep `@version "..."` |
|
||||
|
||||
**If none found:** Skip version bump silently. Not all projects use versioning.
|
||||
|
||||
**Bump logic:**
|
||||
```
|
||||
Lines changed < 50 → patch (X.Y.Z → X.Y.Z+1)
|
||||
Lines changed >= 50 → patch (safe default)
|
||||
User explicitly says "breaking" or "major feature" → AskUserQuestion for minor/major
|
||||
```
|
||||
|
||||
## Changelog Detection
|
||||
|
||||
| Check | Format |
|
||||
|-------|--------|
|
||||
| `CHANGELOG.md` | Keep-a-changelog format |
|
||||
| `CHANGES.md` | Same |
|
||||
| `HISTORY.md` | Same |
|
||||
|
||||
**If none found:** Skip changelog silently.
|
||||
|
||||
**Entry format:**
|
||||
```markdown
|
||||
## [X.Y.Z] - YYYY-MM-DD
|
||||
|
||||
### Added
|
||||
- New features from commits with `feat:` prefix
|
||||
|
||||
### Changed
|
||||
- Changes from commits with `refactor:`, `perf:` prefix
|
||||
|
||||
### Fixed
|
||||
- Bug fixes from commits with `fix:` prefix
|
||||
|
||||
### Removed
|
||||
- Removals mentioned in commit messages
|
||||
```
|
||||
|
||||
**Infer categories from:**
|
||||
1. Conventional commit prefixes in `git log main..HEAD --oneline`
|
||||
2. File types changed (test files → test improvements, docs → documentation)
|
||||
3. Diff content (new functions = Added, modified functions = Changed)
|
||||
|
||||
## Main Branch Detection
|
||||
|
||||
```bash
|
||||
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
|
||||
```
|
||||
|
||||
Fallback: check if `main` or `master` exists:
|
||||
```bash
|
||||
git rev-parse --verify origin/main 2>/dev/null && echo "main" || echo "master"
|
||||
```
|
||||
90
.opencode/skills/ship/references/pr-template.md
Normal file
90
.opencode/skills/ship/references/pr-template.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# PR Body Template
|
||||
|
||||
Use this template when creating PRs via `gh pr create`.
|
||||
|
||||
## Template
|
||||
|
||||
```markdown
|
||||
## Summary
|
||||
<bullet points — infer from changelog entry or commit messages>
|
||||
|
||||
## Linked Issues
|
||||
<list issues from Step 2>
|
||||
- Closes #XX — <issue title>
|
||||
- Relates to #YY — <issue title>
|
||||
<or "No linked issues.">
|
||||
|
||||
## Pre-Landing Review
|
||||
<findings from review step>
|
||||
<format: "N issues (X critical, Y informational)" or "No issues found.">
|
||||
|
||||
<if informational issues exist, list them:>
|
||||
- [file:line] Issue description
|
||||
|
||||
## Test Results
|
||||
- [x] All tests pass (<count> tests, 0 failures)
|
||||
<or>
|
||||
- [x] Tests skipped (--skip-tests)
|
||||
|
||||
## Changes
|
||||
<output of git diff --stat, trimmed to key files>
|
||||
|
||||
## Ship Mode
|
||||
- Mode: <official|beta>
|
||||
- Target: <target-branch>
|
||||
```
|
||||
|
||||
## PR Title Format
|
||||
|
||||
```
|
||||
type(scope): brief description
|
||||
```
|
||||
|
||||
Infer type from changes:
|
||||
- `feat`: new feature or capability
|
||||
- `fix`: bug fix
|
||||
- `refactor`: code restructuring without behavior change
|
||||
- `perf`: performance improvement
|
||||
- `chore`: maintenance, dependencies, config
|
||||
|
||||
## Example
|
||||
|
||||
```markdown
|
||||
## Summary
|
||||
- Add OAuth2 login flow with Google and GitHub providers
|
||||
- Implement session management with secure cookie storage
|
||||
- Add logout endpoint with token revocation
|
||||
|
||||
## Linked Issues
|
||||
- Closes #42 — Add OAuth2 authentication support
|
||||
- Relates to #38 — Security audit for auth module
|
||||
|
||||
## Pre-Landing Review
|
||||
Pre-Landing Review: 1 issue (0 critical, 1 informational)
|
||||
|
||||
- [src/auth/session.ts:42] Magic number 3600 for session TTL
|
||||
Fix: Extract to named constant SESSION_TTL_SECONDS
|
||||
|
||||
## Test Results
|
||||
- [x] All tests pass (127 tests, 0 failures)
|
||||
|
||||
## Changes
|
||||
src/auth/oauth.ts | 89 +++++++++
|
||||
src/auth/session.ts | 45 +++++
|
||||
src/routes/auth.ts | 32 ++++
|
||||
tests/auth.test.ts | 67 +++++++
|
||||
4 files changed, 233 insertions(+)
|
||||
|
||||
## Ship Mode
|
||||
- Mode: official
|
||||
- Target: main
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Keep summary bullets concise — one line per change
|
||||
- Include review findings even if "No issues found" — shows review happened
|
||||
- Test counts should match actual output, not estimates
|
||||
- If PR already exists, use `gh pr edit` instead of `gh pr create`
|
||||
- Always include linked issues section — traceability is critical
|
||||
- For beta PRs, target the dev/beta branch, not main
|
||||
241
.opencode/skills/ship/references/ship-workflow.md
Normal file
241
.opencode/skills/ship/references/ship-workflow.md
Normal file
@@ -0,0 +1,241 @@
|
||||
# Ship Workflow — Detailed Steps
|
||||
|
||||
## Step 1: Pre-flight
|
||||
|
||||
1. Check current branch: `git branch --show-current`
|
||||
- If on target branch (main/master/dev): **ABORT** — "Ship from a feature branch, not the target branch."
|
||||
2. Determine ship mode from arguments:
|
||||
- `official` → target = auto-detect default branch (main/master)
|
||||
- `beta` → target = auto-detect dev branch (dev/beta/develop)
|
||||
- No argument → infer from branch name:
|
||||
- `feature/* hotfix/* bugfix/*` → official
|
||||
- `dev/* beta/* experiment/*` → beta
|
||||
- Unclear → `AskUserQuestion` with options: "Official (main)", "Beta (dev)"
|
||||
3. Auto-detect target branch:
|
||||
```bash
|
||||
# For official: detect default branch
|
||||
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
|
||||
# Fallback
|
||||
git rev-parse --verify origin/main 2>/dev/null && echo "main" || echo "master"
|
||||
|
||||
# For beta: detect dev branch
|
||||
for b in dev beta develop; do
|
||||
git rev-parse --verify origin/$b 2>/dev/null && echo "$b" && break
|
||||
done
|
||||
```
|
||||
4. Run `git status` (never use `-uall`). Uncommitted changes are always included.
|
||||
5. Run `git diff <target>...HEAD --stat` and `git log <target>..HEAD --oneline` to understand what's being shipped.
|
||||
6. If `--dry-run`: output what would happen at each step and stop here.
|
||||
|
||||
## Step 2: Link Issues
|
||||
|
||||
Find or create related GitHub issues for traceability.
|
||||
|
||||
1. Search for related open issues by keywords from branch name and commit messages:
|
||||
```bash
|
||||
# Extract keywords from branch name
|
||||
BRANCH=$(git branch --show-current)
|
||||
KEYWORDS=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9]/ /g' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Search existing issues
|
||||
gh issue list --state open --limit 10 --search "$KEYWORDS"
|
||||
```
|
||||
|
||||
2. Also check if any issues are referenced in commit messages:
|
||||
```bash
|
||||
git log <target>..HEAD --oneline | grep -oE '#[0-9]+' | sort -u
|
||||
```
|
||||
|
||||
3. **If related issues found:** Note issue numbers for PR linking.
|
||||
|
||||
4. **If NO related issues found:** Create a new issue with structured format:
|
||||
```bash
|
||||
gh issue create --title "<type>: <summary from commits>" --body "$(cat <<'EOF'
|
||||
## Problem Statement
|
||||
<infer from diff and commit messages>
|
||||
|
||||
## Proposal
|
||||
<summarize the implementation approach>
|
||||
|
||||
## How It Works
|
||||
<describe key changes with bullet points>
|
||||
|
||||
### Architecture
|
||||
```
|
||||
<ASCII diagram of component interactions>
|
||||
```
|
||||
|
||||
## Challenges
|
||||
- <potential edge cases or risks>
|
||||
|
||||
## Plan & Phases
|
||||
- [x] Implementation complete
|
||||
- [x] Tests passing
|
||||
- [ ] Code review approved
|
||||
- [ ] Merged to <target>
|
||||
|
||||
## Human Review Tasks
|
||||
- [ ] Verify business logic correctness
|
||||
- [ ] Check for edge cases not covered by tests
|
||||
- [ ] Validate UX/API contract changes (if any)
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
5. Store issue numbers for Step 12 (PR creation).
|
||||
|
||||
## Step 3: Merge target branch
|
||||
|
||||
Fetch and merge so tests run against the merged state:
|
||||
|
||||
```bash
|
||||
git fetch origin <target> && git merge origin/<target> --no-edit
|
||||
```
|
||||
|
||||
- **If merge conflicts:** Try auto-resolve simple ones (lockfiles, version files). For complex conflicts, **STOP** and show them.
|
||||
- **If already up to date:** Continue silently.
|
||||
|
||||
## Step 4: Run Tests
|
||||
|
||||
**Skip if:** `--skip-tests` flag.
|
||||
|
||||
1. Auto-detect test command (see `auto-detect.md`)
|
||||
2. Delegate to `tester` subagent — don't inline test execution
|
||||
3. Check pass/fail from agent result
|
||||
|
||||
- **If any test fails:** Show failures and **STOP**. Do not proceed.
|
||||
- **If all pass:** Note counts briefly and continue.
|
||||
- **If no test runner detected:** Use `AskUserQuestion` — "No test runner detected. Skip tests or provide command?"
|
||||
|
||||
## Step 5: Pre-Landing Review
|
||||
|
||||
**Skip if:** `--skip-review` flag.
|
||||
|
||||
1. Run `git diff origin/<target>` to get the full diff
|
||||
2. Delegate to `code-reviewer` subagent with the diff
|
||||
3. Two-pass model:
|
||||
- **Pass 1 (CRITICAL):** Security, injection, race conditions, auth bypass
|
||||
- **Pass 2 (INFORMATIONAL):** Dead code, magic numbers, test gaps, style
|
||||
|
||||
4. **Output findings:**
|
||||
```
|
||||
Pre-Landing Review: N issues (X critical, Y informational)
|
||||
```
|
||||
|
||||
5. **If critical issues found:** For EACH critical issue, use `AskUserQuestion`:
|
||||
- Problem description with `file:line`
|
||||
- Recommended fix
|
||||
- Options: A) Fix now (recommended), B) Acknowledge and ship, C) False positive — skip
|
||||
|
||||
6. **If user chose Fix (A):** Apply fixes, commit fixed files, then **re-run tests** (Step 4) before continuing.
|
||||
7. **If only informational:** Include in PR body, continue.
|
||||
8. **If no issues:** Output "No issues found." and continue.
|
||||
|
||||
## Step 6: Version Bump (conditional)
|
||||
|
||||
1. Auto-detect version source (see `auto-detect.md`)
|
||||
2. If no version file found: **skip silently**
|
||||
3. Auto-decide bump level from diff size:
|
||||
- **< 50 lines:** patch bump
|
||||
- **50+ lines:** patch bump (default safe choice)
|
||||
- **Major feature or breaking change:** Use `AskUserQuestion` — "This looks like a significant change. Bump minor or patch?"
|
||||
4. For beta mode: use prerelease suffix (e.g., `1.2.4-beta.1`)
|
||||
5. Write new version to detected file
|
||||
|
||||
## Step 7: Changelog (conditional)
|
||||
|
||||
1. Check for CHANGELOG.md or CHANGES.md
|
||||
2. If not found: **skip silently**
|
||||
3. Auto-generate entry from ALL commits on branch:
|
||||
- `git log <target>..HEAD --oneline` for commit list
|
||||
- `git diff <target>...HEAD` for full diff context
|
||||
4. Categorize into: Added, Changed, Fixed, Removed
|
||||
5. Insert after file header, dated today
|
||||
6. Format: `## [X.Y.Z] - YYYY-MM-DD`
|
||||
|
||||
**Do NOT ask user to describe changes.** Infer from diff and commits.
|
||||
|
||||
## Step 8: Journal (background)
|
||||
|
||||
**Skip if:** `--skip-journal` flag.
|
||||
|
||||
Write a technical journal entry capturing this ship session. Run as **background task** to not block pipeline.
|
||||
|
||||
1. Invoke `/ck:journal` skill via `journal-writer` subagent in background:
|
||||
- Topic: summary of shipped changes (from commit messages + diff stats)
|
||||
- Include: what was shipped, key decisions, technical challenges encountered
|
||||
- Output: saved to `./docs/journals/` directory
|
||||
2. Don't wait for completion — continue to next step immediately.
|
||||
|
||||
## Step 9: Docs Update (conditional, background)
|
||||
|
||||
**Skip if:** `--skip-docs` flag OR ship mode is `beta`.
|
||||
|
||||
Update project documentation for official releases. Run as **background task**.
|
||||
|
||||
1. Invoke `/ck:docs update` skill via `docs-manager` subagent in background:
|
||||
- Analyzes code changes since last release
|
||||
- Updates relevant docs in `./docs/` directory
|
||||
2. Don't wait for completion — continue to next step immediately.
|
||||
|
||||
## Step 10: Commit
|
||||
|
||||
1. Stage all changes: `git add -A`
|
||||
2. Security check: scan staged diff for secrets (API keys, tokens, passwords)
|
||||
- If secrets found: **STOP**, warn user, suggest `.gitignore`
|
||||
3. Compose commit message:
|
||||
- Format: `type(scope): description`
|
||||
- Infer type from changes (feat/fix/refactor/chore)
|
||||
- If version + changelog present, include in same commit
|
||||
4. Commit:
|
||||
|
||||
```bash
|
||||
git commit -m "$(cat <<'EOF'
|
||||
type(scope): description
|
||||
|
||||
Brief body describing the changes.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
## Step 11: Push
|
||||
|
||||
```bash
|
||||
git push -u origin $(git branch --show-current)
|
||||
```
|
||||
|
||||
- **Never force push.**
|
||||
- If push rejected: suggest `git pull --rebase` and retry once.
|
||||
|
||||
## Step 12: Create PR
|
||||
|
||||
Check if `gh` CLI is available:
|
||||
```bash
|
||||
which gh 2>/dev/null || echo "MISSING"
|
||||
```
|
||||
|
||||
If missing: output "Install GitHub CLI (gh) to auto-create PRs" and stop after push.
|
||||
|
||||
Create PR targeting the correct branch:
|
||||
```bash
|
||||
gh pr create --base <target-branch> --title "<type>: <summary>" --body "$(cat <<'EOF'
|
||||
<PR body from pr-template.md>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
**Link issues** collected from Step 2:
|
||||
```bash
|
||||
# If issues were found/created, add closing keywords in PR body
|
||||
# e.g., "Closes #42, Relates to #43"
|
||||
```
|
||||
|
||||
**Output the PR URL** — this is the final output the user sees.
|
||||
|
||||
If PR already exists for this branch, update it instead:
|
||||
```bash
|
||||
gh pr edit --title "<type>: <summary>" --body "$(cat <<'EOF'
|
||||
<PR body>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
Reference in New Issue
Block a user