@neikyun/ciel 6.11.2 → 6.13.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/assets/.claude/agents/ciel-critic.md +71 -12
- package/assets/.claude/agents/ciel-explorer.md +59 -18
- package/assets/.claude/agents/ciel-improver.md +6 -3
- package/assets/.claude/agents/ciel-researcher.md +85 -25
- package/assets/.claude/hooks/block-destructive.sh +2 -2
- package/assets/.claude/hooks/check-test-first.sh +2 -2
- package/assets/.claude/hooks/memory-bootstrap.sh +0 -0
- package/assets/.claude/hooks/memory-engine.py +82 -15
- package/assets/.claude/hooks/post-tool-write.sh +32 -0
- package/assets/.claude/hooks/pre-agent-gate.sh +11 -6
- package/assets/.claude/hooks/pre-compact.sh +18 -0
- package/assets/.claude/hooks/pre-tool-write.sh +56 -31
- package/assets/.claude/hooks/session-start.sh +22 -1
- package/assets/.claude/hooks/session-version-check.sh +1 -1
- package/assets/.claude/hooks/stop.sh +104 -0
- package/assets/.claude/hooks/subagent-stop.sh +54 -0
- package/assets/.claude/hooks/track-file.sh +2 -2
- package/assets/.claude/hooks/user-prompt-submit.sh +11 -15
- package/assets/.claude/settings.json +18 -4
- package/assets/AGENTS.md +1 -1
- package/assets/CLAUDE.md +103 -175
- package/assets/commands/ciel-audit.md +58 -399
- package/assets/commands/ciel-create-skill.md +24 -38
- package/assets/commands/ciel-eval.md +25 -37
- package/assets/commands/ciel-init.md +36 -126
- package/assets/commands/ciel-status.md +22 -19
- package/assets/commands/ciel-update.md +20 -39
- package/assets/platforms/opencode/.opencode/agents/ciel-researcher.md +71 -895
- package/assets/platforms/opencode/.opencode/commands/ciel-audit.md +58 -296
- package/assets/platforms/opencode/.opencode/commands/ciel-create-skill.md +24 -46
- package/assets/platforms/opencode/.opencode/commands/ciel-eval.md +25 -45
- package/assets/platforms/opencode/.opencode/commands/ciel-init.md +36 -131
- package/assets/platforms/opencode/.opencode/commands/ciel-status.md +22 -24
- package/assets/platforms/opencode/.opencode/commands/ciel-update.md +20 -40
- package/assets/platforms/opencode/AGENTS.md +4 -4
- package/assets/rules/security.md +30 -0
- package/assets/rules/testing.md +23 -0
- package/assets/skills/agile/SKILL.md +42 -0
- package/assets/skills/alerting/SKILL.md +55 -0
- package/assets/skills/api-design/SKILL.md +46 -0
- package/assets/skills/appsec/SKILL.md +43 -0
- package/assets/skills/architecture/SKILL.md +74 -0
- package/assets/skills/backend/SKILL.md +41 -0
- package/assets/skills/backup-recovery/SKILL.md +42 -0
- package/assets/skills/caching/SKILL.md +44 -0
- package/assets/skills/cdn/SKILL.md +42 -0
- package/assets/skills/chaos/SKILL.md +41 -0
- package/assets/skills/cicd-pipeline/SKILL.md +56 -0
- package/assets/skills/cloud/SKILL.md +42 -0
- package/assets/skills/code-quality/SKILL.md +42 -0
- package/assets/skills/code-review/SKILL.md +41 -0
- package/assets/skills/communication/SKILL.md +42 -0
- package/assets/skills/containers/SKILL.md +42 -0
- package/assets/skills/cqrs/SKILL.md +41 -0
- package/assets/skills/crypto/SKILL.md +46 -0
- package/assets/skills/data-engineering/SKILL.md +42 -0
- package/assets/skills/database-design/SKILL.md +46 -0
- package/assets/skills/ddd/SKILL.md +45 -0
- package/assets/skills/deployment-strategies/SKILL.md +51 -0
- package/assets/skills/desktop/SKILL.md +42 -0
- package/assets/skills/devsecops/SKILL.md +43 -0
- package/assets/skills/event-driven/SKILL.md +46 -0
- package/assets/skills/frontend/SKILL.md +41 -0
- package/assets/skills/functional/SKILL.md +42 -0
- package/assets/skills/high-availability/SKILL.md +42 -0
- package/assets/skills/iac/SKILL.md +46 -0
- package/assets/skills/logging/SKILL.md +46 -0
- package/assets/skills/meta/ciel-improve/SKILL.md +127 -0
- package/assets/skills/meta/learnings-capture/SKILL.md +105 -0
- package/assets/skills/meta/patch-spec/patch-spec.md +50 -0
- package/assets/skills/meta/skill-creator/SKILL.md +115 -0
- package/assets/skills/meta/skill-freshness-auditor/SKILL.md +164 -0
- package/assets/skills/meta/skill-variant-evaluator/SKILL.md +100 -0
- package/assets/skills/meta/skills-first-design-auditor/SKILL.md +192 -0
- package/assets/skills/ml-engineering/SKILL.md +42 -0
- package/assets/skills/mobile/SKILL.md +42 -0
- package/assets/skills/monitoring/SKILL.md +54 -0
- package/assets/skills/networking/SKILL.md +42 -0
- package/assets/skills/nosql/SKILL.md +41 -0
- package/assets/skills/oop-solid/SKILL.md +42 -0
- package/assets/skills/performance/SKILL.md +41 -0
- package/assets/skills/reactive/SKILL.md +42 -0
- package/assets/skills/release-management/SKILL.md +51 -0
- package/assets/skills/research/fact-check-claims/SKILL.md +98 -0
- package/assets/skills/research/research-forums/SKILL.md +103 -0
- package/assets/skills/research/research-github-issues/SKILL.md +103 -0
- package/assets/skills/research/research-web-sources/SKILL.md +108 -0
- package/assets/skills/research/synthesize-findings/SKILL.md +112 -0
- package/assets/skills/research/validate-source-credibility/SKILL.md +103 -0
- package/assets/skills/resilience/SKILL.md +41 -0
- package/assets/skills/serverless/SKILL.md +42 -0
- package/assets/skills/servers/SKILL.md +41 -0
- package/assets/skills/sql/SKILL.md +45 -0
- package/assets/skills/supply-chain/SKILL.md +41 -0
- package/assets/skills/system-design/SKILL.md +91 -0
- package/assets/skills/tech-leadership/SKILL.md +46 -0
- package/assets/skills/testing/SKILL.md +41 -0
- package/assets/skills/tracing/SKILL.md +36 -0
- package/assets/skills/utility/branch-cleaner/SKILL.md +195 -0
- package/assets/skills/utility/branch-setup/SKILL.md +144 -0
- package/assets/skills/utility/changelog-updater/SKILL.md +125 -0
- package/assets/skills/utility/commit-writer/SKILL.md +154 -0
- package/assets/skills/utility/issue-closer/SKILL.md +106 -0
- package/assets/skills/utility/issue-creator/SKILL.md +200 -0
- package/assets/skills/utility/pr-merger/SKILL.md +189 -0
- package/assets/skills/utility/pr-opener/SKILL.md +180 -0
- package/assets/skills/utility/release-publisher/SKILL.md +224 -0
- package/assets/skills/workflow/ciel-dev-process/SKILL.md +94 -0
- package/assets/skills/workflow/faire-gatekeeper/SKILL.md +3 -1
- package/assets/skills/workflow/prouver-verifier/SKILL.md +11 -2
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +11 -2
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/claude.d.ts.map +1 -1
- package/dist/cli/claude.js +0 -2
- package/dist/cli/claude.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +11 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/opencode.d.ts.map +1 -1
- package/dist/cli/opencode.js +2 -1
- package/dist/cli/opencode.js.map +1 -1
- package/package.json +1 -1
- package/assets/commands/ciel-migrate.md +0 -35
- package/assets/commands/ciel-refresh.md +0 -91
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: branch-cleaner
|
|
3
|
+
description: Deletes merged branches safely — `git branch --merged` for locals, `git fetch --prune` for stale tracking refs, opt-in `git push origin --delete` per-branch confirm. Excludes main/master/develop + current. Invoke post-merge, on "clean up branches", or when >20 stale branches. Inline.
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
context: inline
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# branch-cleaner — Delete merged, keep history tidy
|
|
9
|
+
|
|
10
|
+
Local + remote branches accumulate silently. After 3 months, `git branch` shows 40+ old branches, most of them merged. This skill deletes safely.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
BASE_BRANCH: [default: origin's default branch — main/master]
|
|
18
|
+
REMOTE_CLEANUP: [true | false — default false; requires explicit confirmation for remote deletes]
|
|
19
|
+
PROTECTED: [comma-separated list — default: main,master,develop,release/*]
|
|
20
|
+
DRY_RUN: [true | false — default true on first invocation; shows what would be deleted]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Auto-inference sources
|
|
24
|
+
|
|
25
|
+
- **BASE_BRANCH** → `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'`
|
|
26
|
+
- **Current branch** → always protected (cannot delete the branch you're on)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Preflight
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git rev-parse --git-dir > /dev/null 2>&1 || { echo "Not a git repo"; exit 1; }
|
|
34
|
+
|
|
35
|
+
# Don't run with dirty tree — in case user is in the middle of something
|
|
36
|
+
git status --porcelain | grep -q . && { echo "Working tree dirty — commit or stash first"; exit 1; }
|
|
37
|
+
|
|
38
|
+
# Fetch to get fresh remote state
|
|
39
|
+
git fetch --all --prune --quiet
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`--prune` already removes stale remote-tracking refs (remotes of branches deleted on origin).
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Process
|
|
47
|
+
|
|
48
|
+
### 1. Identify merged local branches
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
BASE=${BASE_BRANCH:-$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')}
|
|
52
|
+
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
53
|
+
|
|
54
|
+
# Branches merged into BASE, excluding protected
|
|
55
|
+
MERGED=$(git branch --merged "origin/$BASE" --format='%(refname:short)' \
|
|
56
|
+
| grep -vE "^(main|master|develop|${CURRENT}|release/.*)$" \
|
|
57
|
+
| grep -v "^\*")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`git branch --merged` is safer than `--no-merged`: only shows branches whose tip commit is reachable from BASE.
|
|
61
|
+
|
|
62
|
+
**Caveat**: squash-merged PRs are NOT detected by `--merged` (the commit SHA is different). For these, use the PR-title heuristic:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Branches that match a closed-merged PR title
|
|
66
|
+
CLOSED_PRS=$(gh pr list --state=closed --search "is:merged" --limit=100 --json headRefName --jq '.[].headRefName')
|
|
67
|
+
for BRANCH in $(git branch --format='%(refname:short)' | grep -v "^\*"); do
|
|
68
|
+
echo "$CLOSED_PRS" | grep -qx "$BRANCH" && SQUASH_MERGED+=("$BRANCH")
|
|
69
|
+
done
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. Show what would be deleted (DRY_RUN)
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
[BRANCH CLEANER — DRY RUN]
|
|
76
|
+
|
|
77
|
+
Local branches merged into origin/$BASE:
|
|
78
|
+
- fix/1042-library-update (last commit: 2026-03-15, 4 weeks ago)
|
|
79
|
+
- feat/1055-new-endpoint (last commit: 2026-04-02, 2 weeks ago)
|
|
80
|
+
|
|
81
|
+
Squash-merged (by PR title match):
|
|
82
|
+
- fix/1048-typo (PR #1048 closed 2026-04-10)
|
|
83
|
+
|
|
84
|
+
Protected (not deleted):
|
|
85
|
+
- main, master, develop, release/2026-q2
|
|
86
|
+
- <current: your current branch>
|
|
87
|
+
|
|
88
|
+
Remote branches fully merged (would delete with REMOTE_CLEANUP=true):
|
|
89
|
+
- origin/fix/1042-library-update
|
|
90
|
+
- origin/fix/1048-typo
|
|
91
|
+
|
|
92
|
+
To proceed: re-run with DRY_RUN=false
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 3. Delete local branches (on user confirmation)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
for B in $MERGED $SQUASH_MERGED; do
|
|
99
|
+
git branch -d "$B" 2>&1 || {
|
|
100
|
+
# -d refuses if upstream diverged; confirm before -D
|
|
101
|
+
if [ -n "$ASSUME_YES" ]; then
|
|
102
|
+
if [ "$ASSUME_YES" = "force" ]; then
|
|
103
|
+
git branch -D "$B"
|
|
104
|
+
else
|
|
105
|
+
echo "Branch '$B' not fully merged; skipping (set ASSUME_YES=force to force-delete)"
|
|
106
|
+
fi
|
|
107
|
+
else
|
|
108
|
+
echo "Branch '$B' not fully merged per -d — use -D? [y/N]"
|
|
109
|
+
read CONFIRM
|
|
110
|
+
[ "$CONFIRM" = "y" ] && git branch -D "$B"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
done
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`-d` is the safe delete (requires merged). `-D` force-deletes — only use after explicit confirmation.
|
|
117
|
+
|
|
118
|
+
### 4. Delete remote branches (only if REMOTE_CLEANUP=true)
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
if [ "$REMOTE_CLEANUP" = "true" ]; then
|
|
122
|
+
for B in $MERGED $SQUASH_MERGED; do
|
|
123
|
+
# Only if remote branch still exists
|
|
124
|
+
git ls-remote --exit-code origin "$B" > /dev/null 2>&1 || continue
|
|
125
|
+
|
|
126
|
+
echo "Delete origin/$B? [y/N]"
|
|
127
|
+
read CONFIRM
|
|
128
|
+
[ "$CONFIRM" = "y" ] && git push origin --delete "$B"
|
|
129
|
+
done
|
|
130
|
+
fi
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 5. Prune remote-tracking refs (already done in preflight, re-run for safety)
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
git remote prune origin
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 6. Emit summary
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
[BRANCH CLEANED]
|
|
143
|
+
Local deleted: <N> branches
|
|
144
|
+
Remote deleted: <N> branches (skipped if REMOTE_CLEANUP=false)
|
|
145
|
+
Remote-tracking pruned: <N> refs
|
|
146
|
+
Branches remaining: <N> local / <N> remote
|
|
147
|
+
|
|
148
|
+
Protected (untouched): main, master, develop, <current>, release/*
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Guardrails
|
|
154
|
+
|
|
155
|
+
- **DRY_RUN by default on first call** — show before delete. Second call with DRY_RUN=false actually deletes.
|
|
156
|
+
- **Never delete the current branch** — `git branch -d` would fail anyway; bail early.
|
|
157
|
+
- **Never delete protected branches** — hard-coded: main, master, develop, release/*. Add repo-specific via `.ciel-protected-branches` (one branch per line).
|
|
158
|
+
- **Squash-merge detection is heuristic** — a branch name matching a closed-merged PR isn't proof of merge (someone could have renamed + re-used). Confirm per branch in non-dry mode.
|
|
159
|
+
- **Remote deletes require REMOTE_CLEANUP=true** — two opt-ins (flag + per-branch confirm) before touching origin.
|
|
160
|
+
- **Force-delete `-D` requires per-branch confirm** — don't silently `-D`. Diverged branches might hold unpushed work.
|
|
161
|
+
- **Backup via `git reflog`** — informative only; `git reflog` keeps deleted commits for 90 days. Mention this before force-delete so user knows recovery exists.
|
|
162
|
+
- **Never `git push --force` in this skill** — deletion is `--delete`, not force.
|
|
163
|
+
- **Respect in-progress work** — preflight dirty-tree check prevents deleting branches while user is switching contexts.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## When triggered
|
|
168
|
+
|
|
169
|
+
- Post-merge handoff from `pr-merger` (after `issue-closer`)
|
|
170
|
+
- `meta-critiquer` item 4 "Stale branches?" when count > 20
|
|
171
|
+
- User says: "clean up branches", "delete merged", "prune stale"
|
|
172
|
+
- Session end when `git branch | wc -l` is high and user confirms cleanup
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Anti-pattern
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
❌ git branch -D $(git branch | grep -v main) # nukes everything including unmerged work
|
|
180
|
+
✅ git branch -d <merged-only> # safe, refuses diverged
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
❌ git push origin --delete $(git branch -r) # deletes remote branches blind
|
|
185
|
+
✅ Per-branch confirm with REMOTE_CLEANUP flag
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## References
|
|
191
|
+
|
|
192
|
+
- `git branch --merged` — git-scm.com/docs/git-branch
|
|
193
|
+
- `git fetch --prune` — git-scm.com/docs/git-fetch
|
|
194
|
+
- `git reflog` (recovery) — git-scm.com/docs/git-reflog
|
|
195
|
+
- Ciel pipeline: pr-merger → issue-closer → branch-cleaner → (changelog-updater | release-publisher)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: branch-setup
|
|
3
|
+
description: Creates a git branch named with Ciel's convention — `fix/<issue-number>-<slug>` for bug fixes, `feat/<issue-number>-<slug>` for features. Verifies clean working tree first. Records branch as work context so commit-writer adds `Refs #<issue>` footers. Inline — fast git commands, no fork needed.
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
context: inline
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# branch-setup — Branch name as audit trail
|
|
9
|
+
|
|
10
|
+
## What this covers
|
|
11
|
+
Naming the branch after the issue makes traceability automatic — GitHub auto-links, reviewers see the reason, the history tells the story.
|
|
12
|
+
|
|
13
|
+
## Core principle
|
|
14
|
+
**Every branch traces to an issue. No orphan branches.** The branch name IS the audit trail.
|
|
15
|
+
|
|
16
|
+
## Inputs
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ISSUE_NUMBER: [e.g., "123" — from issue-creator OR explicit user reference]
|
|
20
|
+
TITLE_SLUG: [kebab-case short description, ≤ 40 chars]
|
|
21
|
+
TYPE: [fix | feat | chore | docs | refactor | test | perf]
|
|
22
|
+
BASE_BRANCH: [usually "main" — override if working off release/*]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Auto-inference sources
|
|
26
|
+
|
|
27
|
+
- **ISSUE_NUMBER** → from `issue-creator` output, or parse `#N` from user prompt, or from `gh issue view`
|
|
28
|
+
- **TITLE_SLUG** → from issue title, lowercase, keep first 4-5 meaningful words, kebab-case
|
|
29
|
+
- **TYPE** → infer from issue labels: `bug` → `fix`, `enhancement` → `feat`, else `chore`
|
|
30
|
+
- **BASE_BRANCH** → `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'`
|
|
31
|
+
|
|
32
|
+
## Preflight
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# 1. Working tree is clean
|
|
36
|
+
git status --porcelain | grep -q . && { echo "Working tree dirty — stash or commit first"; exit 1; }
|
|
37
|
+
|
|
38
|
+
# 2. We're in a git repo
|
|
39
|
+
git rev-parse --git-dir > /dev/null 2>&1 || { echo "Not a git repo"; exit 1; }
|
|
40
|
+
|
|
41
|
+
# 3. Base branch is reachable
|
|
42
|
+
git rev-parse --verify "origin/$BASE_BRANCH" > /dev/null 2>&1 || { echo "Base branch $BASE_BRANCH not found on origin"; exit 1; }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If dirty, offer 3 options:
|
|
46
|
+
1. Stash (`git stash push -m "ciel pre-branch stash"`)
|
|
47
|
+
2. Commit to current branch first (user's call)
|
|
48
|
+
3. Abort
|
|
49
|
+
|
|
50
|
+
## Process
|
|
51
|
+
|
|
52
|
+
### 1. Compute branch name
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
BRANCH_NAME="${TYPE}/${ISSUE_NUMBER}-${TITLE_SLUG}"
|
|
56
|
+
# Example: fix/1042-library-update-db-timeout
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Validate:
|
|
60
|
+
- ≤ 80 chars total (many git hosts truncate)
|
|
61
|
+
- Only `[a-z0-9/-]` (no uppercase, no underscore, no special)
|
|
62
|
+
- Not already exists locally OR remotely
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git rev-parse --verify "$BRANCH_NAME" 2>/dev/null && { echo "Branch exists locally — checkout instead?"; exit 1; }
|
|
66
|
+
git ls-remote --exit-code origin "$BRANCH_NAME" && { echo "Branch exists on origin — checkout instead?"; exit 1; }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Create + checkout from fresh base
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git fetch origin "$BASE_BRANCH" --quiet
|
|
73
|
+
git checkout -b "$BRANCH_NAME" "origin/$BASE_BRANCH"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Record the work context
|
|
77
|
+
|
|
78
|
+
Write to `.git/ciel-work-context` (local, not committed):
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
ISSUE: #<N>
|
|
82
|
+
BRANCH: <branch>
|
|
83
|
+
TYPE: <type>
|
|
84
|
+
STARTED: <ISO timestamp>
|
|
85
|
+
BASE: <base branch>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 4. Emit output
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
[BRANCH CREATED]
|
|
92
|
+
Name: fix/1042-library-update-db-timeout
|
|
93
|
+
From: origin/main (SHA <short>)
|
|
94
|
+
Issue: #1042
|
|
95
|
+
Work context recorded.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Common patterns
|
|
99
|
+
|
|
100
|
+
### Good branch names
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
fix/342-null-pointer-auth-login
|
|
104
|
+
feat/567-user-avatar-upload
|
|
105
|
+
chore/890-update-ci-node-version
|
|
106
|
+
refactor/123-extract-payment-service
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Bad branch names
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
myfix # no type, no issue
|
|
113
|
+
fix/library-timeout # no issue number
|
|
114
|
+
feature/add-the-thing-with-all-the-details # way too long
|
|
115
|
+
FIX/123-UPPERCASE # uppercase breaks some tools
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Anti-patterns
|
|
119
|
+
|
|
120
|
+
- `git checkout -b myfix` → no issue link, no type prefix, untraceable
|
|
121
|
+
- Working directly on `main` → violates every workflow — Ciel refuses and forces branching
|
|
122
|
+
- `git checkout -b fix/library-timeout` without issue number → enforce the `#N` prefix
|
|
123
|
+
- Branching from stale local `main` → always fetch + branch from `origin/main`
|
|
124
|
+
- Branch names > 80 chars → GitHub truncates, CI tools break
|
|
125
|
+
|
|
126
|
+
## How to verify
|
|
127
|
+
|
|
128
|
+
- [ ] Branch name matches `<type>/<N>-<slug>` pattern? (`git branch --show-current | grep -E '^[a-z]+/[0-9]+-'`)
|
|
129
|
+
- [ ] ≤ 80 chars total? (`git branch --show-current | wc -c` ≤ 81)
|
|
130
|
+
- [ ] Working tree clean before branch? (preflight passed)
|
|
131
|
+
- [ ] Branched from `origin/<base>`, not stale local? (`git log --oneline -1 origin/main` matches recent)
|
|
132
|
+
- [ ] `.git/ciel-work-context` written with ISSUE + BRANCH + TYPE?
|
|
133
|
+
|
|
134
|
+
## When triggered
|
|
135
|
+
|
|
136
|
+
- Right after `issue-creator` returns a number
|
|
137
|
+
- User says "start working on issue #N"
|
|
138
|
+
- Beginning of FAIRE step when depth is Standard/Critical AND an issue exists
|
|
139
|
+
|
|
140
|
+
## References
|
|
141
|
+
|
|
142
|
+
- Conventional branches — conventional-branch.org
|
|
143
|
+
- Conventional commits — conventionalcommits.org
|
|
144
|
+
- Ciel pipeline: issue-creator → branch-setup → FAIRE → commit-writer → pr-opener → issue-closer
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: changelog-updater
|
|
3
|
+
description: Appends a versioned entry to CHANGELOG.md following Keep-a-Changelog format, with Added/Changed/Fixed/Removed sections and fix/revert ratio metric when available. Auto-triggered by version bumps or when /ciel-improve adopts new skill variants.
|
|
4
|
+
allowed-tools: Read, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# changelog-updater — Structured version history
|
|
8
|
+
|
|
9
|
+
## What this covers
|
|
10
|
+
Keeps `CHANGELOG.md` up to date with a consistent format. The changelog is the project's public-facing history — every user and contributor reads it.
|
|
11
|
+
|
|
12
|
+
## Core principle
|
|
13
|
+
**Changelog is append-only history.** Never rewrite old entries. Each new entry answers: "What changed since last release, and why should I care?"
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
- **version**: new version number (semver)
|
|
18
|
+
- **date**: release date (YYYY-MM-DD)
|
|
19
|
+
- **changes**: structured changes — added / changed / fixed / removed / security
|
|
20
|
+
- **metric** (optional): fix/revert ratio measured since last release
|
|
21
|
+
|
|
22
|
+
## Process
|
|
23
|
+
|
|
24
|
+
### 1. Read current CHANGELOG.md
|
|
25
|
+
|
|
26
|
+
Confirm format. If the file follows Keep-a-Changelog structure, preserve it. If not, migrate to that structure.
|
|
27
|
+
|
|
28
|
+
### 2. Compose new entry
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
## [<version>] — <YYYY-MM-DD>
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- <new feature / skill / command>
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- <modified behavior / skill rewrite>
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- <bug fix with reference>
|
|
41
|
+
|
|
42
|
+
### Removed
|
|
43
|
+
- <deprecated / removed>
|
|
44
|
+
|
|
45
|
+
### Security
|
|
46
|
+
- <security fix (CVE-like severity)>
|
|
47
|
+
|
|
48
|
+
### Metrics
|
|
49
|
+
- Fix/revert ratio: <X%> (baseline v<prev>: <Y%>)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Omit sections that have no entries.
|
|
53
|
+
|
|
54
|
+
### 3. Insert at top (most recent first)
|
|
55
|
+
|
|
56
|
+
After any header/preamble, before previous version entries.
|
|
57
|
+
|
|
58
|
+
### 4. Preserve previous entries
|
|
59
|
+
|
|
60
|
+
Never rewrite old entries — append only.
|
|
61
|
+
|
|
62
|
+
## Common patterns
|
|
63
|
+
|
|
64
|
+
### Good changelog entry
|
|
65
|
+
|
|
66
|
+
```markdown
|
|
67
|
+
## [3.5.0] — 2026-04-17
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- `test-strategy-vitest-playwright` skill — 2026 test pyramid (70/20/10) with decision rules per test type
|
|
71
|
+
- `playwright-visual-critic` skill — accessibility-first UI review using Playwright MCP
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- Skills refactored from pipeline steps to knowledge references (Phase 5 of v4.0.0 plan)
|
|
75
|
+
- Agent frontmatter: added `model`, `memory`, `skills` preload fields
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
- Hook `session.deleted` renamed to `session.destroy` (OpenCode 0.4 breaking change)
|
|
79
|
+
- Agent dispatch: removed stale `context: fork` from 3 workflow skills
|
|
80
|
+
|
|
81
|
+
### Removed
|
|
82
|
+
- Platform directories for Cursor, Windsurf, Codex, KiloCode, LMStudio, Ollama (unsupported)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Bad changelog entry
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
## update
|
|
89
|
+
- fixed stuff
|
|
90
|
+
- changed things
|
|
91
|
+
- added new features
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Problems: no version, no date, no specifics, sections not following Keep-a-Changelog.
|
|
95
|
+
|
|
96
|
+
## Anti-patterns
|
|
97
|
+
|
|
98
|
+
- **Rewriting old entries** — changelog is historical record, additive only
|
|
99
|
+
- **Missing date** — every entry needs a `YYYY-MM-DD` date
|
|
100
|
+
- **Vague descriptions** — "fixed bugs" says nothing. Link to issue: "fix: prevent N+1 query in dashboard (#567)"
|
|
101
|
+
- **Missing breaking changes** — breaking changes must be prominent, in a separate section or with `!` marker
|
|
102
|
+
- **Empty sections** — omit sections with no entries, don't leave empty headers
|
|
103
|
+
- **Not linking to issues/PRs** — each entry should reference `#N` where possible
|
|
104
|
+
|
|
105
|
+
## How to verify
|
|
106
|
+
|
|
107
|
+
- [ ] Version follows semver? (`MAJOR.MINOR.PATCH`)
|
|
108
|
+
- [ ] Date is ISO 8601? (`YYYY-MM-DD`)
|
|
109
|
+
- [ ] Entry inserted at top (most recent first)?
|
|
110
|
+
- [ ] Previous entries untouched?
|
|
111
|
+
- [ ] Breaking changes highlighted (if any)?
|
|
112
|
+
- [ ] Each entry references issue/PR number (where applicable)?
|
|
113
|
+
- [ ] Sections follow Keep-a-Changelog names? (Added, Changed, Fixed, Removed, Security)
|
|
114
|
+
|
|
115
|
+
## When triggered
|
|
116
|
+
|
|
117
|
+
- Version bump (SHA change in `.version`)
|
|
118
|
+
- After `/ciel-improve` adopts new skill variants
|
|
119
|
+
- User request: "update changelog" / "release notes"
|
|
120
|
+
- CI/CD pre-release step
|
|
121
|
+
|
|
122
|
+
## References
|
|
123
|
+
|
|
124
|
+
- Keep a Changelog v1.1.0 — keepachangelog.com
|
|
125
|
+
- Semantic Versioning v2.0.0 — semver.org
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit-writer
|
|
3
|
+
description: Writes commit messages in conventional commit format (feat/fix/chore/docs/refactor/test/perf) with imperative mood, issue references, and warnings on secret files. Invoked before git commit. Short, structured, mechanical — for reviewer clarity and changelog automation.
|
|
4
|
+
allowed-tools: Bash, Read
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# commit-writer — Conventional commit messages
|
|
8
|
+
|
|
9
|
+
## What this covers
|
|
10
|
+
Ensures every commit is structured, informative, traceable to an issue, and free of secrets. The commit message is the first thing a reviewer reads — make it count.
|
|
11
|
+
|
|
12
|
+
## Core principle
|
|
13
|
+
**The commit message explains WHY, not WHAT.** The diff shows what changed. The message explains why it changed. "Fix null pointer in auth" is better than "Update auth.ts".
|
|
14
|
+
|
|
15
|
+
## Methodology
|
|
16
|
+
|
|
17
|
+
Reads from current git state:
|
|
18
|
+
- `git status --porcelain` — staged files
|
|
19
|
+
- `git diff --staged` — diff content
|
|
20
|
+
- Optional: recent commit history for style matching
|
|
21
|
+
|
|
22
|
+
### 1. Scan staged files — secrets gate
|
|
23
|
+
|
|
24
|
+
Flag if any of:
|
|
25
|
+
- `.env*` (not `.env.example`)
|
|
26
|
+
- `credentials.*`, `secrets.*`, `*-keys.*`
|
|
27
|
+
- Files > 10 MB (binary?)
|
|
28
|
+
- `id_rsa`, `id_ed25519`, other SSH keys
|
|
29
|
+
|
|
30
|
+
**Block immediately.** Do NOT commit secrets.
|
|
31
|
+
|
|
32
|
+
### 2. Classify change type
|
|
33
|
+
|
|
34
|
+
From diff content:
|
|
35
|
+
- New feature (new endpoint / component / capability) → `feat`
|
|
36
|
+
- Bug fix → `fix`
|
|
37
|
+
- Build config / CI / dependencies → `chore` or `build`
|
|
38
|
+
- Docs only → `docs`
|
|
39
|
+
- Refactor (no behavior change) → `refactor`
|
|
40
|
+
- Test only → `test`
|
|
41
|
+
- Performance → `perf`
|
|
42
|
+
- Breaking change → add `!` suffix: `feat!:` or include `BREAKING CHANGE:` in body
|
|
43
|
+
|
|
44
|
+
### 3. Identify scope (optional)
|
|
45
|
+
|
|
46
|
+
From top-level folder(s) changed: `feat(auth):`, `fix(users):`, `refactor(db):`.
|
|
47
|
+
|
|
48
|
+
### 4. Write subject line
|
|
49
|
+
|
|
50
|
+
- Imperative mood: "add" not "added", "fix" not "fixed"
|
|
51
|
+
- ≤ 72 chars (hard limit — git log truncates beyond this)
|
|
52
|
+
- No trailing period
|
|
53
|
+
- Lowercase after type prefix
|
|
54
|
+
|
|
55
|
+
### 5. Write body (optional)
|
|
56
|
+
|
|
57
|
+
If non-trivial:
|
|
58
|
+
- What changed (1-2 sentences)
|
|
59
|
+
- Why (the rationale — the most important part)
|
|
60
|
+
- Any side effects / migration notes
|
|
61
|
+
|
|
62
|
+
### 6. Add issue reference
|
|
63
|
+
|
|
64
|
+
If branch name matches pattern `<type>/<N>-<slug>` or an open issue is linked, add at the bottom:
|
|
65
|
+
```
|
|
66
|
+
Closes #<N>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Output format
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
<type>(<scope>): <subject ≤72 chars>
|
|
73
|
+
|
|
74
|
+
<body: what + why>
|
|
75
|
+
|
|
76
|
+
Closes #<N>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Common patterns
|
|
80
|
+
|
|
81
|
+
### Good commits (before → after)
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
# Feature — clear scope, imperative, issue linked
|
|
85
|
+
feat(auth): add OAuth2 PKCE flow for mobile clients
|
|
86
|
+
|
|
87
|
+
Mobile apps can't safely store client secrets. PKCE eliminates
|
|
88
|
+
the need by using a code verifier/challenge pair.
|
|
89
|
+
|
|
90
|
+
Closes #342
|
|
91
|
+
|
|
92
|
+
# Bug fix — explains the root cause, not just the symptom
|
|
93
|
+
fix(db): prevent N+1 query in user dashboard endpoint
|
|
94
|
+
|
|
95
|
+
The /dashboard endpoint was loading each user's posts in a
|
|
96
|
+
separate query. Eager-load posts via JOIN to reduce 101 queries
|
|
97
|
+
to 1.
|
|
98
|
+
|
|
99
|
+
Closes #567
|
|
100
|
+
|
|
101
|
+
# Chore — explains WHY the dependency was updated
|
|
102
|
+
chore(deps): bump @auth/core from 3.1 to 4.0
|
|
103
|
+
|
|
104
|
+
v4.0 fixes CVE-2026-1234 (session fixation). Breaking change:
|
|
105
|
+
useSession() now returns null instead of throwing on expired
|
|
106
|
+
tokens. Updated 3 call sites.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Bad commits
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
# BAD — no type prefix, no scope, no issue
|
|
113
|
+
update auth stuff
|
|
114
|
+
|
|
115
|
+
# BAD — describes WHAT not WHY
|
|
116
|
+
fix(users): change line 42 in users.ts
|
|
117
|
+
|
|
118
|
+
# BAD — too vague, could be anything
|
|
119
|
+
fix: bugs
|
|
120
|
+
|
|
121
|
+
# BAD — past tense, trailing period, > 72 chars
|
|
122
|
+
Fixed the authentication module to properly handle the case where users have expired tokens and the refresh flow fails silently.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Anti-patterns
|
|
126
|
+
|
|
127
|
+
- **"Update X"** — update is not a type. Use `fix`, `feat`, `refactor`, or `chore`.
|
|
128
|
+
- **Past tense** — "added", "fixed", "changed" — use imperative: "add", "fix", "change".
|
|
129
|
+
- **No issue reference on feat/fix** — every feature and bug fix should trace to an issue. If no issue exists, prompt user to create one first.
|
|
130
|
+
- **Secrets in diff** — never commit `.env`, API keys, credentials. Block and warn.
|
|
131
|
+
- **Squashing unrelated changes** — one logical change per commit. If you fixed a bug AND added a feature, make two commits.
|
|
132
|
+
- **Bodyless non-trivial commits** — if the diff touches > 3 files or > 50 lines, write a body explaining why.
|
|
133
|
+
|
|
134
|
+
## How to verify
|
|
135
|
+
|
|
136
|
+
- [ ] Subject line ≤ 72 chars? (`echo "$SUBJECT" | wc -c` ≤ 73)
|
|
137
|
+
- [ ] Starts with valid type prefix? (`feat|fix|chore|docs|refactor|test|perf|build|ci`)
|
|
138
|
+
- [ ] Imperative mood? (not "added", "fixed", "changed")
|
|
139
|
+
- [ ] No trailing period?
|
|
140
|
+
- [ ] `feat`/`fix` commits have issue reference (`Closes #N` or `Refs #N`)?
|
|
141
|
+
- [ ] No secrets in staged files? (check `.env`, `credentials.*`, `*-keys.*`)
|
|
142
|
+
- [ ] Style matches recent commits? (`git log --oneline -5` for reference)
|
|
143
|
+
|
|
144
|
+
## When triggered
|
|
145
|
+
|
|
146
|
+
- Before `git commit`
|
|
147
|
+
- User says "write a commit message for these changes"
|
|
148
|
+
- In `/ciel` workflow at end of FAIRE before pushing
|
|
149
|
+
|
|
150
|
+
## References
|
|
151
|
+
|
|
152
|
+
- Conventional Commits v1.0.0 — conventionalcommits.org
|
|
153
|
+
- Angular commit convention (widely adopted baseline) — github.com/angular/angular/blob/main/CONTRIBUTING.md
|
|
154
|
+
- Ciel pipeline: FAIRE → commit-writer → push
|