Compare commits
12 Commits
0c8ee69e90
...
021bc2b6b7
| Author | SHA1 | Date | |
|---|---|---|---|
| 021bc2b6b7 | |||
| 772f047c0a | |||
| 838b33c46b | |||
| cffed70a05 | |||
| 2bf640b6dc | |||
| dcad95069f | |||
| c8c6b04c6f | |||
| 6a3c6c5203 | |||
| 1aa1f35ca6 | |||
| 7a834f2a9a | |||
| 8c7e17edcb | |||
| 5212c303ee |
@@ -1,5 +1,13 @@
|
|||||||
# Task Board
|
# Task Board
|
||||||
_Updated: 2026-04-30_
|
_Updated: 2026-05-01_
|
||||||
|
|
||||||
|
## 🟢 [pulling-before-work-skill] — pulling-before-work skill + project-bootstrap 1.4.0 canonical trigger
|
||||||
|
**Status:** done
|
||||||
|
**Where I stopped:** `skills/pulling-before-work/` shipped at v1.0.0 (mode-3 activation: session start + on-demand re-sync; `git pull --ff-only`; skips on no-remote / no-upstream / dirty / detached); `assets/CLAUDE.md.template` gains `pull remote before work`; `project-bootstrap` 1.3.0→1.4.0 with new commentary paragraph in Step 5; root `CLAUDE.md` dogfood line added; both archives rebuilt in `dist/`; installed via `install.sh`; smoke scenarios 1/2/3/4/5/8/9 + inline bootstrap-merge check verified by controller, scenarios 6 (diverged remote) and 7 (re-sync trigger across a fresh session) deferred — both require multi-session orchestration not yet tooled; design rationale at `.wiki/concepts/pulling-before-work-design.md`
|
||||||
|
**Next action:** (none — kept until merged)
|
||||||
|
**Branch:** master
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🟢 [bootstrap-claude-md-merge] — project-bootstrap upgrade: idempotent merge of canonical CLAUDE.md triggers
|
## 🟢 [bootstrap-claude-md-merge] — project-bootstrap upgrade: idempotent merge of canonical CLAUDE.md triggers
|
||||||
**Status:** done
|
**Status:** done
|
||||||
|
|||||||
648
.tasks/pulling-before-work-skill.md
Normal file
648
.tasks/pulling-before-work-skill.md
Normal file
@@ -0,0 +1,648 @@
|
|||||||
|
# pulling-before-work — implementation plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Ship a new policy skill `pulling-before-work` (one pull at session start + on-demand re-sync) and wire it into the canonical `project-bootstrap` template, with the `claude-skills` repo dogfooding the trigger.
|
||||||
|
|
||||||
|
**Architecture:** Single-file policy skill (`skills/pulling-before-work/SKILL.md`) following the `active-platform` / `using-tasks` shape — frontmatter trigger description + body with deterministic shell algorithm. `project-bootstrap` v1.4.0 adds the canonical trigger line `pull remote before work` to `assets/CLAUDE.md.template`; the existing v1.3.0 idempotent merge propagates it into existing projects on upgrade. The `claude-skills` repo's own `CLAUDE.md` gets the line as dogfood.
|
||||||
|
|
||||||
|
**Tech Stack:** Markdown skills (no build for the skill body itself). Build pipeline: `scripts/build.ps1` produces `dist/<name>.skill` archives. Install: `scripts/install.sh` (or `.ps1`). Spec lives at `.wiki/concepts/pulling-before-work-design.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
**New:**
|
||||||
|
- `skills/pulling-before-work/SKILL.md` — frontmatter + body, ~80–120 lines
|
||||||
|
- `skills/pulling-before-work/README.md` — short user-facing intro mirroring `skills/using-tasks/README.md` shape
|
||||||
|
|
||||||
|
**Modified:**
|
||||||
|
- `skills/project-bootstrap/SKILL.md` — `version: 1.3.0` → `1.4.0`; Step 5 inline template gains the new line; new commentary paragraph after the inline template explaining the trigger (mirrors the existing paragraphs about `check across all projects` and `we're on Windows`)
|
||||||
|
- `skills/project-bootstrap/assets/CLAUDE.md.template` — `+ pull remote before work` before `we're on Windows`
|
||||||
|
- `CLAUDE.md` (repo root) — `+ pull remote before work` before `we're on Windows` (dogfood)
|
||||||
|
- `.wiki/log.md` — append decision entry
|
||||||
|
- `.wiki/index.md` — concept page link (added in spec commit; verify still listed)
|
||||||
|
- `.tasks/STATUS.md` — add `[pulling-before-work-skill]` block
|
||||||
|
|
||||||
|
**Built:**
|
||||||
|
- `dist/pulling-before-work.skill` — new
|
||||||
|
- `dist/project-bootstrap.skill` — rebuilt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: New skill — frontmatter only
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `skills/pulling-before-work/SKILL.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Write the frontmatter**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
name: pulling-before-work
|
||||||
|
version: 1.0.0
|
||||||
|
description: >
|
||||||
|
Pulls the current branch from origin once at session start and on explicit
|
||||||
|
re-sync requests. Use when CLAUDE.md contains the trigger line "pull remote
|
||||||
|
before work", or when the user says "sync", "resync", "pull", "обнови репо",
|
||||||
|
"git pull please", or close variants asking to refresh from the remote.
|
||||||
|
Runs `git pull --ff-only` — never auto-merges or rebases. Stays silent in
|
||||||
|
non-git folders. Prints one informational line and exits when there is no
|
||||||
|
origin remote, no upstream tracking, the working tree is dirty, or HEAD is
|
||||||
|
detached. Does not stash, commit, or push. Activated by `project-bootstrap`
|
||||||
|
v1.4.0+ via the canonical CLAUDE.md template.
|
||||||
|
---
|
||||||
|
|
||||||
|
# pulling-before-work
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify description length is under 900 chars**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```powershell
|
||||||
|
$c = Get-Content skills/pulling-before-work/SKILL.md -Raw
|
||||||
|
$start = $c.IndexOf('description: >') + 'description: >'.Length
|
||||||
|
$end = $c.IndexOf('---', $start)
|
||||||
|
$desc = $c.Substring($start, $end - $start).Trim()
|
||||||
|
"description chars: $($desc.Length)"
|
||||||
|
```
|
||||||
|
Expected: a number ≤ 900. (Per `feedback_skill_description_length_limit` memory: harness silently drops descriptions >~1024 and falls back to the H1.)
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add skills/pulling-before-work/SKILL.md
|
||||||
|
git commit -m "feat(pulling-before-work): scaffold skill frontmatter"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: New skill — body
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/pulling-before-work/SKILL.md` (append body)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Append the skill body after the H1**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
> Pull from `origin` once when work starts. Don't auto-merge. Don't trample dirty work-trees. Don't ask twice in the same session unless asked.
|
||||||
|
|
||||||
|
## When this runs
|
||||||
|
|
||||||
|
**At session start** — once, when the skill is activated by the `pull remote before work` line in `CLAUDE.md`. The cycle below runs immediately.
|
||||||
|
|
||||||
|
**On explicit re-sync** — when the user says any of: `sync`, `resync`, `pull`, `обнови репо`, `pull please`, `git pull`, `подтяни`, `pull from origin`. Re-runs the full cycle. There is no per-session counter; the user is always allowed to ask.
|
||||||
|
|
||||||
|
**Never** before each commit, before each tool call, on every message, or in any other implicit cadence. Mode-3 ("start + on-demand") was the explicit design choice — see `.wiki/concepts/pulling-before-work-design.md`.
|
||||||
|
|
||||||
|
## The pull cycle
|
||||||
|
|
||||||
|
Run these checks in order. Print at most one line of chat output per run.
|
||||||
|
|
||||||
|
### 1. Inside a git work-tree?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --is-inside-work-tree 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails or prints anything other than `true` → **exit silently, no chat output.** This is the not-a-git-repo case; the skill must not be noisy in random folders.
|
||||||
|
|
||||||
|
### 2. Has an `origin` remote?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git remote get-url origin 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails (no such remote) → print one line and exit:
|
||||||
|
|
||||||
|
```
|
||||||
|
no origin remote — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Is the working tree clean?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status --porcelain
|
||||||
|
```
|
||||||
|
|
||||||
|
If the output is non-empty → print one line and exit:
|
||||||
|
|
||||||
|
```
|
||||||
|
working tree dirty — skipping pull. commit/stash, потом скажи "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
Never stash automatically. Stash-pop conflicts are exactly the friction this skill exists to remove.
|
||||||
|
|
||||||
|
### 4. Is HEAD attached?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git symbolic-ref -q HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails (empty output, exit 1) → detached HEAD. Print:
|
||||||
|
|
||||||
|
```
|
||||||
|
detached HEAD — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Does the current branch have an upstream?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
Capture the upstream name (e.g. `origin/master`). If the command fails → no upstream tracking. Print:
|
||||||
|
|
||||||
|
```
|
||||||
|
no upstream tracking for <branch> — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
(Where `<branch>` is `git rev-parse --abbrev-ref HEAD`.)
|
||||||
|
|
||||||
|
### 6. Pull, fast-forward only
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull --ff-only
|
||||||
|
```
|
||||||
|
|
||||||
|
(No args — uses the configured upstream captured above.)
|
||||||
|
|
||||||
|
Classify by exit code and stdout:
|
||||||
|
|
||||||
|
| Result | Print |
|
||||||
|
|---|---|
|
||||||
|
| Already up to date | `✅ already up to date with <upstream>` |
|
||||||
|
| Fast-forward, N commits | `✅ pulled N commits from <upstream>` |
|
||||||
|
| Non-fast-forward / diverged (exit non-zero with "diverged" or "non-fast-forward" in output) | `⚠️ diverged from <upstream> — resolve manually (git pull --rebase or merge); skill never auto-merges/rebases` |
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
The skill never:
|
||||||
|
|
||||||
|
- commits, stashes, or pushes
|
||||||
|
- recurses into submodules
|
||||||
|
- pulls from non-`origin` remotes
|
||||||
|
- pulls on detached HEAD
|
||||||
|
- runs auto-merge or auto-rebase
|
||||||
|
- runs more than once per session unless the user asks
|
||||||
|
|
||||||
|
## Recovery hints
|
||||||
|
|
||||||
|
If the skill skipped because of a dirty tree:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows / PowerShell
|
||||||
|
git status # see what's dirty
|
||||||
|
git add . ; git commit -m "wip"
|
||||||
|
# then ask the agent: "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux / macOS
|
||||||
|
git status
|
||||||
|
git add . && git commit -m "wip"
|
||||||
|
# then say "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
If the skill reported `diverged`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option A: rebase your local commits on top of origin
|
||||||
|
git pull --rebase
|
||||||
|
|
||||||
|
# Option B: explicit merge (creates a merge commit)
|
||||||
|
git pull --no-ff
|
||||||
|
```
|
||||||
|
|
||||||
|
The skill stays out of these decisions on purpose — both options have valid use cases and the user owns the choice.
|
||||||
|
|
||||||
|
## Why this exists
|
||||||
|
|
||||||
|
Stale local branches are a silent footgun: edits land on top of yesterday's `origin`, the divergence shows up at push time, and by then there's a chunk of work to rebase or merge on the wrong base. One pull at start covers the common case; an explicit re-sync trigger handles long sessions where someone pushed mid-flight.
|
||||||
|
|
||||||
|
Full design rationale (mode choice, dirty-tree skip vs stash, `--ff-only` vs auto-merge, the upstream-check) lives in `.wiki/concepts/pulling-before-work-design.md`.
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Sanity-check the file rendered**
|
||||||
|
|
||||||
|
Read the file back and confirm:
|
||||||
|
- Frontmatter still parses (no `---` accidentally inside the body)
|
||||||
|
- All six numbered steps are present
|
||||||
|
- Recovery hints block has both PowerShell and bash variants
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add skills/pulling-before-work/SKILL.md
|
||||||
|
git commit -m "feat(pulling-before-work): skill body — pull cycle, recovery hints, rationale"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: New skill — README.md
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `skills/pulling-before-work/README.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Write README**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# pulling-before-work
|
||||||
|
|
||||||
|
Policy skill that pulls the current branch from `origin` once at session start
|
||||||
|
and on explicit re-sync requests. Designed to remove the "edited on stale base"
|
||||||
|
footgun without trampling dirty work-trees or auto-merging.
|
||||||
|
|
||||||
|
## When it triggers
|
||||||
|
|
||||||
|
- **Session start** — when `CLAUDE.md` contains the line `pull remote before work` (added by `project-bootstrap` v1.4.0+).
|
||||||
|
- **In-chat** — when the user says `sync`, `resync`, `pull`, `обнови репо`, `git pull please`, or close variants.
|
||||||
|
|
||||||
|
Stays silent in non-git folders. Prints one informational line and exits in:
|
||||||
|
no `origin` remote, no upstream tracking, dirty work-tree, detached HEAD.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
`git pull --ff-only` against the configured upstream — never auto-merges, never
|
||||||
|
auto-rebases, never stashes, never commits, never pushes. On divergence it prints
|
||||||
|
a warning with manual-resolution hints and exits.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
None. The skill is a no-op outside git repos and folders without an `origin`
|
||||||
|
remote, so it's safe to leave activated everywhere.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- `project-bootstrap` (v1.4.0+) — adds the trigger line to new and existing projects' `CLAUDE.md`.
|
||||||
|
- `.wiki/concepts/pulling-before-work-design.md` (in projects bootstrapped from this repo: this design lives in `claude-skills`) — full design rationale.
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add skills/pulling-before-work/README.md
|
||||||
|
git commit -m "docs(pulling-before-work): README"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: Bootstrap template — add trigger line
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/project-bootstrap/assets/CLAUDE.md.template`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Insert the new line before the platform line**
|
||||||
|
|
||||||
|
Current:
|
||||||
|
```markdown
|
||||||
|
# CLAUDE.md
|
||||||
|
# Agent instructions. Each line is a trigger for an installed skill.
|
||||||
|
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
Target:
|
||||||
|
```markdown
|
||||||
|
# CLAUDE.md
|
||||||
|
# Agent instructions. Each line is a trigger for an installed skill.
|
||||||
|
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `Edit` with `old_string="check across all projects\nwe're on Windows"` → `new_string="check across all projects\npull remote before work\nwe're on Windows"`.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Content skills/project-bootstrap/assets/CLAUDE.md.template
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: the seven trigger lines above, in that order.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add skills/project-bootstrap/assets/CLAUDE.md.template
|
||||||
|
git commit -m "feat(project-bootstrap): template gains 'pull remote before work' trigger"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 5: Bootstrap SKILL.md — version bump + Step 5 update
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/project-bootstrap/SKILL.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Bump version in frontmatter**
|
||||||
|
|
||||||
|
Edit:
|
||||||
|
- `old`: `version: 1.3.0`
|
||||||
|
- `new`: `version: 1.4.0`
|
||||||
|
|
||||||
|
- [ ] **Step 2: Update the Step 5 inline template (mirror of `assets/CLAUDE.md.template`)**
|
||||||
|
|
||||||
|
In Step 5, find the fenced markdown block:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Add commentary paragraph for the new trigger**
|
||||||
|
|
||||||
|
After the existing paragraph that explains `check across all projects` and before the paragraph about `we're on Windows`, insert:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
The `pull remote before work` line activates the `pulling-before-work` skill,
|
||||||
|
which runs one `git pull --ff-only` at session start (and on explicit re-sync
|
||||||
|
requests like "sync"). It's a no-op outside git repos and skips with a one-line
|
||||||
|
warning if the working tree is dirty, HEAD is detached, or the branch has no
|
||||||
|
upstream — never auto-merges, stashes, or pushes. Install the skill on the host
|
||||||
|
if `pulling-before-work` is not in `~/.claude/skills/`; otherwise the trigger is
|
||||||
|
silently dead like any other absent skill.
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Verify**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Select-String -Path skills/project-bootstrap/SKILL.md -Pattern '^version:|pull remote before work|pulling-before-work' | ForEach-Object { "$($_.LineNumber): $($_.Line)" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: at least 4 hits — `version: 1.4.0`, the line in the Step 5 fenced block, the new commentary paragraph mentioning the trigger, and a reference to `pulling-before-work`.
|
||||||
|
|
||||||
|
- [ ] **Step 5: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add skills/project-bootstrap/SKILL.md
|
||||||
|
git commit -m "feat(project-bootstrap): v1.4.0 — add 'pull remote before work' canonical trigger"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 6: Dogfood — add trigger to claude-skills root CLAUDE.md
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `CLAUDE.md` (repo root)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Insert the trigger before the platform line**
|
||||||
|
|
||||||
|
Use Edit:
|
||||||
|
- `old`: `check across all projects\nwe're on Windows`
|
||||||
|
- `new`: `check across all projects\npull remote before work\nwe're on Windows`
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Content CLAUDE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
```
|
||||||
|
# CLAUDE.md
|
||||||
|
# Agent instructions. Each line is a trigger for an installed skill.
|
||||||
|
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add CLAUDE.md
|
||||||
|
git commit -m "chore(claude-skills): dogfood 'pull remote before work' trigger"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 7: Build artifacts
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Build: `dist/pulling-before-work.skill` (new), `dist/project-bootstrap.skill` (rebuilt)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Run the build script**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pwsh scripts/build.ps1 -Names pulling-before-work,project-bootstrap
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output:
|
||||||
|
```
|
||||||
|
built: dist/pulling-before-work.skill
|
||||||
|
built: dist/project-bootstrap.skill
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify the archives**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-ChildItem dist/pulling-before-work.skill, dist/project-bootstrap.skill | Format-Table Name, Length, LastWriteTime
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: both files exist, `LastWriteTime` is the current minute, sizes nonzero.
|
||||||
|
|
||||||
|
Spot-check the new archive's structure (no Compress-Archive backslash bug):
|
||||||
|
```powershell
|
||||||
|
$arch = [System.IO.Compression.ZipFile]::OpenRead((Resolve-Path dist/pulling-before-work.skill))
|
||||||
|
$arch.Entries | Select-Object FullName | Format-Table -AutoSize
|
||||||
|
$arch.Dispose()
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: entries like `pulling-before-work/SKILL.md`, `pulling-before-work/README.md` — forward slashes, no backslashes.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add dist/pulling-before-work.skill dist/project-bootstrap.skill
|
||||||
|
git commit -m "build: pulling-before-work@1.0.0 + project-bootstrap@1.4.0 archives"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 8: Install on this machine
|
||||||
|
|
||||||
|
- [ ] **Step 1: Run installer**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
bash scripts/install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
(`install.sh` is portable — works in git-bash on Windows. No `.ps1` exists yet; that's a separate ⚪ Ready task `[install-ps1]`.)
|
||||||
|
|
||||||
|
Expected stdout: lines like `installed: pulling-before-work` and `installed: project-bootstrap` (and the rest of the skills, idempotent).
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify installed skills**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Test-Path "$env:USERPROFILE\.claude\skills\pulling-before-work\SKILL.md"
|
||||||
|
Test-Path "$env:USERPROFILE\.claude\skills\project-bootstrap\SKILL.md"
|
||||||
|
Select-String -Path "$env:USERPROFILE\.claude\skills\project-bootstrap\SKILL.md" -Pattern '^version:'
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
- both `Test-Path` return `True`
|
||||||
|
- `version: 1.4.0` for project-bootstrap
|
||||||
|
|
||||||
|
(No commit — install affects user-level state, not the repo.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 9: Manual smoke validation
|
||||||
|
|
||||||
|
Validation per spec scenarios. No automated harness — run each in a scratch dir or describe what to verify.
|
||||||
|
|
||||||
|
- [ ] **Scenario 1 (clean repo with remote, up to date):**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$tmp = Join-Path $env:TEMP "pull-smoke-1"
|
||||||
|
git clone https://github.com/anthropics/claude-code $tmp
|
||||||
|
cd $tmp
|
||||||
|
# In a *new* Claude Code session opened in $tmp with `pull remote before work` in CLAUDE.md,
|
||||||
|
# expect the agent to print: "✅ already up to date with origin/main"
|
||||||
|
```
|
||||||
|
|
||||||
|
This requires running a fresh agent session. Document the expected line in chat as proof.
|
||||||
|
|
||||||
|
- [ ] **Scenario 2 (no remote):**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$tmp = Join-Path $env:TEMP "pull-smoke-2"
|
||||||
|
New-Item -Type Directory $tmp | Out-Null
|
||||||
|
cd $tmp
|
||||||
|
git init
|
||||||
|
"pull remote before work" | Out-File CLAUDE.md
|
||||||
|
# Open agent session here. Expect: "no origin remote — skip pull"
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Scenario 4 (dirty tree):**
|
||||||
|
|
||||||
|
In a clean repo with origin, `Set-Content -Path test.txt -Value "wip"`. Open agent session. Expect: `working tree dirty — skipping pull. commit/stash, потом скажи "sync"`.
|
||||||
|
|
||||||
|
- [ ] **Scenario 8 (bootstrap upgrade on this very repo):**
|
||||||
|
|
||||||
|
Re-run `project-bootstrap` on `claude-skills` itself:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# In a fresh Claude Code session in claude-skills root, say: "upgrade project"
|
||||||
|
# Bootstrap detects CLAUDE.md exists, runs Step 5 idempotent merge.
|
||||||
|
# Expected: it reports CLAUDE.md is already canon (we added the line manually
|
||||||
|
# in Task 6, so the merge sees nothing missing). No prompt to append.
|
||||||
|
```
|
||||||
|
|
||||||
|
If Task 6 was skipped accidentally, this scenario would prompt to append `pull remote before work`. Either way demonstrates the merge logic works.
|
||||||
|
|
||||||
|
- [ ] **Document results in `.tasks/STATUS.md` `Where I stopped` field**
|
||||||
|
|
||||||
|
After running scenarios, update the task block (Task 11 below) with which scenarios passed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 10: Wiki log + index
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `.wiki/log.md`
|
||||||
|
- Modify: `.wiki/index.md` (verify)
|
||||||
|
|
||||||
|
- [ ] **Step 1: Append log entry**
|
||||||
|
|
||||||
|
Append to `.wiki/log.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## [2026-05-01] decision | pulling-before-work — new policy skill (v1.0.0): one `git pull --ff-only` at session start + on-demand re-sync; bootstrap template gains canonical trigger; project-bootstrap 1.3.0→1.4.0
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Verify `.wiki/index.md` lists the design page**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Select-String -Path .wiki/index.md -Pattern 'pulling-before-work-design'
|
||||||
|
```
|
||||||
|
|
||||||
|
If absent, add a line under `## Concepts`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
- [pulling-before-work-design.md](concepts/pulling-before-work-design.md) — design for the pulling-before-work skill (mode-3 + skip-on-dirty)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add .wiki/log.md .wiki/index.md
|
||||||
|
git commit -m "docs(wiki): log + index — pulling-before-work@1.0.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 11: Tasks board entry
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `.tasks/STATUS.md`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Insert a Done block at the top (after the header) for this task**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## 🟢 [pulling-before-work-skill] — pulling-before-work skill + project-bootstrap 1.4.0 canonical trigger
|
||||||
|
**Status:** done
|
||||||
|
**Where I stopped:** `skills/pulling-before-work/` shipped at v1.0.0 (mode-3 activation: session start + on-demand re-sync; `git pull --ff-only`; skips on no-remote / no-upstream / dirty / detached); `assets/CLAUDE.md.template` gains `pull remote before work`; `project-bootstrap` 1.3.0→1.4.0 with new commentary paragraph in Step 5; root `CLAUDE.md` dogfood line added; both archives rebuilt in `dist/`; installed via `install.sh`; smoke scenarios 1/2/4/8 verified manually; design rationale at `.wiki/concepts/pulling-before-work-design.md`
|
||||||
|
**Next action:** (none — kept until merged)
|
||||||
|
**Branch:** master
|
||||||
|
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Commit**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add .tasks/STATUS.md .tasks/pulling-before-work-skill.md
|
||||||
|
git commit -m "tasks: close [pulling-before-work-skill]"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Self-Review
|
||||||
|
|
||||||
|
**Spec coverage:**
|
||||||
|
- ✅ Skill description / activation rules → Task 1, 2
|
||||||
|
- ✅ Pull cycle (6 steps incl. upstream check) → Task 2
|
||||||
|
- ✅ Out-of-scope list → Task 2
|
||||||
|
- ✅ Mode-3 + skip-on-dirty + `--ff-only` rationale → Task 2 (body) + design doc cross-ref
|
||||||
|
- ✅ Template change → Task 4
|
||||||
|
- ✅ Bootstrap version bump + Step 5 commentary → Task 5
|
||||||
|
- ✅ Dogfood in repo root → Task 6
|
||||||
|
- ✅ Build + install → Tasks 7, 8
|
||||||
|
- ✅ Validation scenarios → Task 9
|
||||||
|
- ✅ Wiki + tasks bookkeeping → Tasks 10, 11
|
||||||
|
|
||||||
|
**Placeholder scan:** no TBD / TODO / "implement later". All steps have explicit code or commands.
|
||||||
|
|
||||||
|
**Type / wording consistency:** trigger line is `pull remote before work` everywhere (template, dogfood, commentary, README, design). Skill name `pulling-before-work` everywhere (folder, frontmatter, archive, install path, log, README cross-link). Version `1.0.0` for new skill, `1.4.0` for bootstrap — consistent across frontmatter, log, tasks block.
|
||||||
159
.wiki/concepts/pulling-before-work-design.md
Normal file
159
.wiki/concepts/pulling-before-work-design.md
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
---
|
||||||
|
title: "pulling-before-work — pull origin once at session start"
|
||||||
|
type: concept
|
||||||
|
updated: 2026-05-01
|
||||||
|
---
|
||||||
|
|
||||||
|
# pulling-before-work — pull origin once at session start
|
||||||
|
|
||||||
|
_2026-05-01._
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
When the user opens Claude in a project that has a git remote, work often starts against a stale local branch. Edits land on top of what `origin` had hours or days ago, and the divergence shows up only at push time — sometimes after a non-trivial chunk of work has been built on the wrong base. The user explicitly asked for a guardrail: "any work in a git project starts with a pull from the remote." Manual `git pull` discipline isn't reliable across machines and sessions.
|
||||||
|
|
||||||
|
The repo already has the right shape for this — policy skills (`using-wiki`, `using-tasks`, `using-projects-meta`, `active-platform`) activated by single-line triggers in each project's `CLAUDE.md`. The fix slots into that pattern.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Two artefacts:
|
||||||
|
|
||||||
|
1. **New policy skill** `pulling-before-work` (under `skills/pulling-before-work/SKILL.md`) — owns the pull logic, activates from the `CLAUDE.md` trigger and from in-chat re-sync phrases.
|
||||||
|
2. **`project-bootstrap` v1.4.0** — adds the line `pull remote before work` to `assets/CLAUDE.md.template`, before the platform line. The existing idempotent merge in Step 5 (introduced in v1.3.0) carries the new line into existing projects on upgrade with one confirmation prompt.
|
||||||
|
|
||||||
|
This repo (`claude-skills`) gets the trigger added to its own `CLAUDE.md` as dogfood.
|
||||||
|
|
||||||
|
## Skill behaviour
|
||||||
|
|
||||||
|
### Activation (description field)
|
||||||
|
|
||||||
|
Trigger conditions:
|
||||||
|
|
||||||
|
- `CLAUDE.md` contains the line `pull remote before work` — activates at session start, runs **one** pull cycle.
|
||||||
|
- User says `sync` / `resync` / `pull` / `обнови репо` / `git pull please` / close variants — runs the pull cycle again on demand.
|
||||||
|
|
||||||
|
Stays silent (no activation, no chat output) when the cwd is not a git repo. With no `origin` remote or no upstream tracking, prints one informational line and exits — those are conditions the user might want to know about, not pure no-ops.
|
||||||
|
|
||||||
|
### One pull cycle
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Inside a git work-tree? (git rev-parse --is-inside-work-tree)
|
||||||
|
no → exit silently, no chat output.
|
||||||
|
|
||||||
|
2. Has 'origin' remote? (git remote get-url origin)
|
||||||
|
no → print one line "no remote, skip", exit.
|
||||||
|
|
||||||
|
3. Working tree dirty? (git status --porcelain — non-empty)
|
||||||
|
yes → print "working tree dirty — skipping pull. commit/stash, потом скажи 'sync'."
|
||||||
|
exit.
|
||||||
|
|
||||||
|
4. Detached HEAD? (git symbolic-ref -q HEAD — empty)
|
||||||
|
yes → print "detached HEAD — skip", exit.
|
||||||
|
|
||||||
|
5. Current branch has upstream? (git rev-parse --abbrev-ref --symbolic-full-name @{u})
|
||||||
|
no → print "no upstream tracking for <branch> — skip", exit.
|
||||||
|
|
||||||
|
6. git pull --ff-only (no args — uses configured upstream)
|
||||||
|
classify result:
|
||||||
|
- "Already up to date" → "✅ already up to date with <upstream>"
|
||||||
|
- fast-forward, N commits → "✅ pulled N commits from <upstream>"
|
||||||
|
- non-ff / diverged → "⚠️ diverged from <upstream> — resolve
|
||||||
|
manually (git pull --rebase or merge);
|
||||||
|
skill never auto-merges/rebases."
|
||||||
|
```
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
- No commit, no stash, no push.
|
||||||
|
- No submodule recursion.
|
||||||
|
- No non-`origin` remotes.
|
||||||
|
- No detached-HEAD pulls.
|
||||||
|
- Not invoked before each commit or each tool call — only at session start and on explicit re-sync.
|
||||||
|
|
||||||
|
### Why mode 3 (start + on-demand) and not "before every commit"
|
||||||
|
|
||||||
|
User chose mode 3 explicitly during brainstorm. Pulling before every commit creates churn (a 30-minute coding session can have 5+ commits — pulling each time is noise) and shifts conflict surface late. One pull at start covers the common case (work begins on stale base); the explicit re-sync trigger handles long sessions where a teammate pushed mid-flight.
|
||||||
|
|
||||||
|
### Why skip-on-dirty (option 1) and not stash-pop or prompt
|
||||||
|
|
||||||
|
Stash + pop can fail mid-pop and leave the user with a half-applied stash to resolve — exactly the kind of friction this skill is supposed to remove. Prompting at every dirty start is noise when "I've got dirty edits" is the steady state during active work. Skip-with-warning is the cheapest correct answer: it never destroys work, it tells the user what to do next, and the next `sync` after commit/stash gets them current.
|
||||||
|
|
||||||
|
### Why `--ff-only` and not auto-merge/rebase
|
||||||
|
|
||||||
|
Auto-merge writes a merge commit the user didn't ask for; auto-rebase rewrites local history silently. Both are violations of "skill never makes the user lose track of where they are." `--ff-only` either succeeds cleanly or refuses with a message — the user retains the steering wheel for non-trivial cases.
|
||||||
|
|
||||||
|
### Why explicit upstream check (step 5)
|
||||||
|
|
||||||
|
`git pull --ff-only` without args relies on `branch.<name>.merge` being set. On a branch that was created locally and never pushed (or `git switch -c` from a remote-tracking branch with `--no-track`), there is no upstream — `git pull` errors out. The explicit check turns that error into a clean one-line skip. Bonus: the upstream name is exactly what we want in success/diverged messages, so we capture it once and reuse.
|
||||||
|
|
||||||
|
## Bootstrap integration
|
||||||
|
|
||||||
|
### Template change
|
||||||
|
|
||||||
|
`assets/CLAUDE.md.template` gains one line, inserted before the platform line:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
talk like a caveman
|
||||||
|
use superpowers
|
||||||
|
use project wiki
|
||||||
|
use task management system
|
||||||
|
check across all projects
|
||||||
|
+pull remote before work
|
||||||
|
we're on Windows
|
||||||
|
```
|
||||||
|
|
||||||
|
Position rationale: the platform line stays last because the bootstrap merge logic special-cases it (substitution on non-Windows hosts). Other trigger lines are unordered logically; placing the new one just before the platform line keeps the platform line as the visual end-anchor.
|
||||||
|
|
||||||
|
### Step 5 upgrade path
|
||||||
|
|
||||||
|
Already idempotent (per `bootstrap-claude-md-merge.md`). The substring + append-only diff treats `pull remote before work` like any other trigger line: existing projects on `project-bootstrap` v1.4.0+ see one diff entry, one confirmation, one appended line. Re-runs after that are no-ops.
|
||||||
|
|
||||||
|
### Version bump
|
||||||
|
|
||||||
|
`project-bootstrap`: 1.3.0 → 1.4.0. New user-visible behaviour (a new canonical trigger landing in projects) = minor bump per the versioning convention in `skill-versioning.md`.
|
||||||
|
|
||||||
|
`pulling-before-work`: starts at 1.0.0.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
```
|
||||||
|
skills/pulling-before-work/
|
||||||
|
SKILL.md NEW — frontmatter + body, ~80–120 lines, no assets
|
||||||
|
|
||||||
|
skills/project-bootstrap/
|
||||||
|
SKILL.md version 1.3.0 → 1.4.0; mention new trigger in
|
||||||
|
Step 5 commentary
|
||||||
|
assets/CLAUDE.md.template + "pull remote before work"
|
||||||
|
|
||||||
|
.wiki/concepts/
|
||||||
|
pulling-before-work-design.md NEW — this file
|
||||||
|
|
||||||
|
CLAUDE.md + "pull remote before work" — dogfood the trigger
|
||||||
|
in the claude-skills repo itself
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
No unit tests — skill is markdown + shell instructions. Validation = manual smoke run on representative scenarios:
|
||||||
|
|
||||||
|
1. Clean repo with remote, current branch tracks origin → `✅ already up to date` or `✅ pulled N commits`.
|
||||||
|
2. `git init`-only, no remote → one-line `no remote, skip`.
|
||||||
|
3. Non-git folder → silent, no output.
|
||||||
|
4. Dirty tree (`echo x > new.txt`) → `working tree dirty — skipping pull`.
|
||||||
|
5. Detached HEAD (`git checkout <sha>`) → `detached HEAD — skip`.
|
||||||
|
6. Diverged branch (local commit + remote commit on same branch) → diverged warning, no auto-merge.
|
||||||
|
7. Re-sync trigger (`sync` mid-session) → cycle repeats.
|
||||||
|
8. Bootstrap upgrade on this repo → diff prompts to append `pull remote before work`; confirm → appended.
|
||||||
|
9. Branch with no upstream (`git switch -c local-only`) → `no upstream tracking for local-only — skip`.
|
||||||
|
|
||||||
|
Scenarios 1, 2, 4, 8 are the load-bearing ones. The rest are edge-case assurance.
|
||||||
|
|
||||||
|
## Composition with existing skills
|
||||||
|
|
||||||
|
- **`active-platform`** — pull command (`git pull --ff-only origin <branch>`) is identical across Windows / Linux / macOS, so no platform branching needed inside the skill body. The active-platform contract still applies for any commands the skill prints in chat (e.g. recovery hints) — but those are git-only and platform-agnostic.
|
||||||
|
- **`using-wiki` / `using-tasks`** — independent. This skill never reads or writes `.wiki/` or `.tasks/`. No ordering constraint with them.
|
||||||
|
- **`superpowers:using-superpowers`** — skill discovery loads `pulling-before-work` from the trigger line just like other policy skills. No special handling.
|
||||||
|
|
||||||
|
## Pattern: lightweight policy skill from a single CLAUDE.md trigger
|
||||||
|
|
||||||
|
Same shape as `active-platform`: a single-line trigger in `CLAUDE.md` activates a small, focused skill that runs deterministic shell logic and returns to silence. Reusable for future "do this thing once at session start" guardrails — e.g. `check pre-commit hooks installed`, `warn if main branch behind upstream`. Bootstrap-template-line + tiny-policy-skill is the cheapest way to make a habit reliable across machines and sessions.
|
||||||
@@ -19,6 +19,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
|
|||||||
- [install-portability.md](concepts/install-portability.md) — `install.sh` / `build.sh` rewritten to drop `mapfile` (bash 4+) and `find -printf` (GNU only) so stock macOS (bash 3.2 + BSD find) works
|
- [install-portability.md](concepts/install-portability.md) — `install.sh` / `build.sh` rewritten to drop `mapfile` (bash 4+) and `find -printf` (GNU only) so stock macOS (bash 3.2 + BSD find) works
|
||||||
- [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key in `.mcp.json` as `--api-key`; now also captured as `setup-context7` skill (one-time install/migrate flow with key discovery)
|
- [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key in `.mcp.json` as `--api-key`; now also captured as `setup-context7` skill (one-time install/migrate flow with key discovery)
|
||||||
- [projects-meta-skills.md](concepts/projects-meta-skills.md) — `setup-projects-meta` + `using-projects-meta` skill pair for the local `projects-meta-mcp` stdio server (cross-project tasks + shared Gitea wiki); local-first rule + two-step mutation pattern
|
- [projects-meta-skills.md](concepts/projects-meta-skills.md) — `setup-projects-meta` + `using-projects-meta` skill pair for the local `projects-meta-mcp` stdio server (cross-project tasks + shared Gitea wiki); local-first rule + two-step mutation pattern
|
||||||
|
- [pulling-before-work-design.md](concepts/pulling-before-work-design.md) — design for the pulling-before-work skill (mode-3 + skip-on-dirty)
|
||||||
- [repo-layout.md](concepts/repo-layout.md) — flat `skills/`, committed `dist/`, bash + PowerShell scripts; install model
|
- [repo-layout.md](concepts/repo-layout.md) — flat `skills/`, committed `dist/`, bash + PowerShell scripts; install model
|
||||||
- [skill-versioning.md](concepts/skill-versioning.md) — why infra skills carry `version: <semver>` in frontmatter and how `project-bootstrap` records them in a per-project manifest
|
- [skill-versioning.md](concepts/skill-versioning.md) — why infra skills carry `version: <semver>` in frontmatter and how `project-bootstrap` records them in a per-project manifest
|
||||||
- [skill-vs-plugin.md](concepts/skill-vs-plugin.md) — when a bare SKILL.md is enough vs when you actually need a plugin (slash commands, hooks, sub-agents, MCP servers); concrete breakdown of `superpowers`
|
- [skill-vs-plugin.md](concepts/skill-vs-plugin.md) — when a bare SKILL.md is enough vs when you actually need a plugin (slash commands, hooks, sub-agents, MCP servers); concrete breakdown of `superpowers`
|
||||||
|
|||||||
@@ -37,3 +37,4 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`.
|
|||||||
## [2026-04-30] decision | project-bootstrap@1.2.0 — CLAUDE.md template gains `check across all projects` (verbatim trigger from using-projects-meta description); installs auto-load cross-project tasks + shared-wiki access in every bootstrapped repo; no Step 5.7 dependency-check mirror — Prerequisites pointer in using-projects-meta is self-correcting; local CLAUDE.md, both READMEs, dist/.skill, projects-meta-skills concept page synced
|
## [2026-04-30] decision | project-bootstrap@1.2.0 — CLAUDE.md template gains `check across all projects` (verbatim trigger from using-projects-meta description); installs auto-load cross-project tasks + shared-wiki access in every bootstrapped repo; no Step 5.7 dependency-check mirror — Prerequisites pointer in using-projects-meta is self-correcting; local CLAUDE.md, both READMEs, dist/.skill, projects-meta-skills concept page synced
|
||||||
## [2026-04-30] decision | Step 5.7 mirror of Step 5.6 (projects-meta-mcp dependency detector / `setup-projects-meta` recommendation) accepted as future work; tracked as ⚪ Ready task `[bootstrap-recommend-projects-meta]`; deferred until first observed fresh-machine miss so detector signal is informed by real failure mode; concept page `projects-meta-skills.md` updated to reflect new stance
|
## [2026-04-30] decision | Step 5.7 mirror of Step 5.6 (projects-meta-mcp dependency detector / `setup-projects-meta` recommendation) accepted as future work; tracked as ⚪ Ready task `[bootstrap-recommend-projects-meta]`; deferred until first observed fresh-machine miss so detector signal is informed by real failure mode; concept page `projects-meta-skills.md` updated to reflect new stance
|
||||||
## [2026-04-30] decision | project-bootstrap@1.3.0 — Step 5 upgrade path turned idempotent: read existing CLAUDE.md → substring-diff vs template → confirm → append-only-missing; closes silent gap where pre-1.2.0 projects never picked up new canonical triggers (`check across all projects`, `we're on Windows`); platform line preserved if user pinned a non-host one; concept page `bootstrap-claude-md-merge.md` written; README CLAUDE.md row updated to note idempotent merge
|
## [2026-04-30] decision | project-bootstrap@1.3.0 — Step 5 upgrade path turned idempotent: read existing CLAUDE.md → substring-diff vs template → confirm → append-only-missing; closes silent gap where pre-1.2.0 projects never picked up new canonical triggers (`check across all projects`, `we're on Windows`); platform line preserved if user pinned a non-host one; concept page `bootstrap-claude-md-merge.md` written; README CLAUDE.md row updated to note idempotent merge
|
||||||
|
## [2026-05-01] decision | pulling-before-work — new policy skill (v1.0.0): one `git pull --ff-only` at session start + on-demand re-sync; bootstrap template gains canonical trigger; project-bootstrap 1.3.0→1.4.0
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ use superpowers
|
|||||||
use project wiki
|
use project wiki
|
||||||
use task management system
|
use task management system
|
||||||
check across all projects
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
we're on Windows
|
we're on Windows
|
||||||
|
|||||||
BIN
dist/project-bootstrap.skill
vendored
BIN
dist/project-bootstrap.skill
vendored
Binary file not shown.
BIN
dist/pulling-before-work.skill
vendored
Normal file
BIN
dist/pulling-before-work.skill
vendored
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: project-bootstrap
|
name: project-bootstrap
|
||||||
version: 1.3.0
|
version: 1.4.0
|
||||||
description: >
|
description: >
|
||||||
Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
|
Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
|
||||||
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
|
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
|
||||||
@@ -263,6 +263,7 @@ use superpowers
|
|||||||
use project wiki
|
use project wiki
|
||||||
use task management system
|
use task management system
|
||||||
check across all projects
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
we're on Windows
|
we're on Windows
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -272,6 +273,14 @@ without an explicit verbal trigger. The skill is a no-op until the
|
|||||||
`projects-meta-mcp` server is registered — install via `setup-projects-meta`
|
`projects-meta-mcp` server is registered — install via `setup-projects-meta`
|
||||||
on a fresh machine if `mcp__projects-meta__*` tools are missing.
|
on a fresh machine if `mcp__projects-meta__*` tools are missing.
|
||||||
|
|
||||||
|
The `pull remote before work` line activates the `pulling-before-work` skill,
|
||||||
|
which runs one `git pull --ff-only` at session start (and on explicit re-sync
|
||||||
|
requests like "sync"). It's a no-op outside git repos and skips with a one-line
|
||||||
|
warning if the working tree is dirty, HEAD is detached, or the branch has no
|
||||||
|
upstream — never auto-merges, stashes, or pushes. Install the skill on the host
|
||||||
|
if `pulling-before-work` is not in `~/.claude/skills/`; otherwise the trigger is
|
||||||
|
silently dead like any other absent skill.
|
||||||
|
|
||||||
The `we're on Windows` line activates the `active-platform` skill and pins the
|
The `we're on Windows` line activates the `active-platform` skill and pins the
|
||||||
project's default platform to Windows / PowerShell — so generated commands and
|
project's default platform to Windows / PowerShell — so generated commands and
|
||||||
README quick-starts use PS-native syntax. Bootstrapping on a Linux or macOS
|
README quick-starts use PS-native syntax. Bootstrapping on a Linux or macOS
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ use superpowers
|
|||||||
use project wiki
|
use project wiki
|
||||||
use task management system
|
use task management system
|
||||||
check across all projects
|
check across all projects
|
||||||
|
pull remote before work
|
||||||
we're on Windows
|
we're on Windows
|
||||||
|
|||||||
29
skills/pulling-before-work/README.md
Normal file
29
skills/pulling-before-work/README.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# pulling-before-work
|
||||||
|
|
||||||
|
Policy skill that pulls the current branch from `origin` once at session start
|
||||||
|
and on explicit re-sync requests. Designed to remove the "edited on stale base"
|
||||||
|
footgun without trampling dirty work-trees or auto-merging.
|
||||||
|
|
||||||
|
## When it triggers
|
||||||
|
|
||||||
|
- **Session start** — when `CLAUDE.md` contains the line `pull remote before work` (added by `project-bootstrap` v1.4.0+).
|
||||||
|
- **In-chat** — when the user says `sync`, `resync`, `pull`, `обнови репо`, `git pull please`, or close variants.
|
||||||
|
|
||||||
|
Stays silent in non-git folders. Prints one informational line and exits in:
|
||||||
|
no `origin` remote, no upstream tracking, dirty work-tree, detached HEAD.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
`git pull --ff-only` against the configured upstream — never auto-merges, never
|
||||||
|
auto-rebases, never stashes, never commits, never pushes. On divergence it prints
|
||||||
|
a warning with manual-resolution hints and exits.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
None. The skill is a no-op outside git repos and folders without an `origin`
|
||||||
|
remote, so it's safe to leave activated everywhere.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- `project-bootstrap` (v1.4.0+) — adds the trigger line to new and existing projects' `CLAUDE.md`.
|
||||||
|
- `.wiki/concepts/pulling-before-work-design.md` (in projects bootstrapped from this repo: this design lives in `claude-skills`) — full design rationale.
|
||||||
153
skills/pulling-before-work/SKILL.md
Normal file
153
skills/pulling-before-work/SKILL.md
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
---
|
||||||
|
name: pulling-before-work
|
||||||
|
version: 1.0.0
|
||||||
|
description: >
|
||||||
|
Pulls the current branch from origin once at session start and on explicit
|
||||||
|
re-sync requests. Use when CLAUDE.md contains the trigger line "pull remote
|
||||||
|
before work", or when the user says "sync", "resync", "pull", "обнови репо",
|
||||||
|
"git pull please", or close variants asking to refresh from the remote.
|
||||||
|
Runs `git pull --ff-only` — never auto-merges or rebases. Stays silent in
|
||||||
|
non-git folders. Prints one informational line and exits when there is no
|
||||||
|
origin remote, no upstream tracking, the working tree is dirty, or HEAD is
|
||||||
|
detached. Does not stash, commit, or push. Activated by `project-bootstrap`
|
||||||
|
v1.4.0+ via the canonical CLAUDE.md template.
|
||||||
|
---
|
||||||
|
|
||||||
|
# pulling-before-work
|
||||||
|
|
||||||
|
> Pull from `origin` once when work starts. Don't auto-merge. Don't trample dirty work-trees. Don't ask twice in the same session unless asked.
|
||||||
|
|
||||||
|
## When this runs
|
||||||
|
|
||||||
|
**At session start** — once, when the skill is activated by the `pull remote before work` line in `CLAUDE.md`. The cycle below runs immediately.
|
||||||
|
|
||||||
|
**On explicit re-sync** — when the user says any of: `sync`, `resync`, `pull`, `обнови репо`, `pull please`, `git pull`, `подтяни`, `pull from origin`. Re-runs the full cycle. There is no per-session counter; the user is always allowed to ask.
|
||||||
|
|
||||||
|
**Never** before each commit, before each tool call, on every message, or in any other implicit cadence. Mode-3 ("start + on-demand") was the explicit design choice — see `.wiki/concepts/pulling-before-work-design.md`.
|
||||||
|
|
||||||
|
## The pull cycle
|
||||||
|
|
||||||
|
Run these checks in order. Print at most one line of chat output per run.
|
||||||
|
|
||||||
|
### 1. Inside a git work-tree?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --is-inside-work-tree 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails or prints anything other than `true` → **exit silently, no chat output.** This is the not-a-git-repo case; the skill must not be noisy in random folders.
|
||||||
|
|
||||||
|
### 2. Has an `origin` remote?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git remote get-url origin 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails (no such remote) → print one line and exit:
|
||||||
|
|
||||||
|
```
|
||||||
|
no origin remote — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Is the working tree clean?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status --porcelain
|
||||||
|
```
|
||||||
|
|
||||||
|
If the output is non-empty → print one line and exit:
|
||||||
|
|
||||||
|
```
|
||||||
|
working tree dirty — skipping pull. commit/stash, потом скажи "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
Never stash automatically. Stash-pop conflicts are exactly the friction this skill exists to remove.
|
||||||
|
|
||||||
|
### 4. Is HEAD attached?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git symbolic-ref -q HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command fails (empty output, exit 1) → detached HEAD. Print:
|
||||||
|
|
||||||
|
```
|
||||||
|
detached HEAD — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Does the current branch have an upstream?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
Capture the upstream name (e.g. `origin/master`). If the command fails → no upstream tracking. Print:
|
||||||
|
|
||||||
|
```
|
||||||
|
no upstream tracking for <branch> — skip pull
|
||||||
|
```
|
||||||
|
|
||||||
|
(Where `<branch>` is `git rev-parse --abbrev-ref HEAD`.)
|
||||||
|
|
||||||
|
### 6. Pull, fast-forward only
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git pull --ff-only
|
||||||
|
```
|
||||||
|
|
||||||
|
(No args — uses the configured upstream captured above.)
|
||||||
|
|
||||||
|
Classify by exit code and stdout:
|
||||||
|
|
||||||
|
| Result | Print |
|
||||||
|
|---|---|
|
||||||
|
| Already up to date | `✅ already up to date with <upstream>` |
|
||||||
|
| Fast-forward, N commits | `✅ pulled N commits from <upstream>` |
|
||||||
|
| Non-fast-forward / diverged (exit non-zero with "diverged" or "non-fast-forward" in output) | `⚠️ diverged from <upstream> — resolve manually (git pull --rebase or merge); skill never auto-merges/rebases` |
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
The skill never:
|
||||||
|
|
||||||
|
- commits, stashes, or pushes
|
||||||
|
- recurses into submodules
|
||||||
|
- pulls from non-`origin` remotes
|
||||||
|
- pulls on detached HEAD
|
||||||
|
- runs auto-merge or auto-rebase
|
||||||
|
- runs more than once per session unless the user asks
|
||||||
|
|
||||||
|
## Recovery hints
|
||||||
|
|
||||||
|
If the skill skipped because of a dirty tree:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows / PowerShell
|
||||||
|
git status # see what's dirty
|
||||||
|
git add . ; git commit -m "wip"
|
||||||
|
# then ask the agent: "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux / macOS
|
||||||
|
git status
|
||||||
|
git add . && git commit -m "wip"
|
||||||
|
# then say "sync"
|
||||||
|
```
|
||||||
|
|
||||||
|
If the skill reported `diverged`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option A: rebase your local commits on top of origin
|
||||||
|
git pull --rebase
|
||||||
|
|
||||||
|
# Option B: explicit merge (creates a merge commit)
|
||||||
|
git pull --no-ff
|
||||||
|
```
|
||||||
|
|
||||||
|
The skill stays out of these decisions on purpose — both options have valid use cases and the user owns the choice.
|
||||||
|
|
||||||
|
## Why this exists
|
||||||
|
|
||||||
|
Stale local branches are a silent footgun: edits land on top of yesterday's `origin`, the divergence shows up at push time, and by then there's a chunk of work to rebase or merge on the wrong base. One pull at start covers the common case; an explicit re-sync trigger handles long sessions where someone pushed mid-flight.
|
||||||
|
|
||||||
|
Full design rationale (mode choice, dirty-tree skip vs stash, `--ff-only` vs auto-merge, the upstream-check) lives in `.wiki/concepts/pulling-before-work-design.md`.
|
||||||
Reference in New Issue
Block a user