Adds the conversion infrastructure for the Hermes-rollout (Nous Research): - hermes/mapping.yaml — per-skill schema (mode: auto|manual|skip|pending, category, replace-rules, source override). Every skills/<name>/ has an explicit entry; the build fails on unmapped skills. - scripts/build-hermes.py — Python converter. Reads mapping.yaml; for auto applies replace-rules to SKILL.md and copies the rest verbatim; for manual copies hermes/skills/<source>/ as-is; for skip / pending records to dist-hermes/SKIPPED.md. - dist-hermes/ — pre-converted Hermes-flavour tree (committed; consumed by the recursive installer in [hermes-installer-skill]). Includes 4 universal skills: pulling-before-work, active-platform (with Linux+bash replacement rule), project-discipline, using-markitdown. Plus SKIPPED.md listing 8 skip + 10 pending entries. - README.md — adds "Build for Hermes" section, updates layout, mentions hermes/, dist-hermes/, build-hermes.py. Mapping is the source of truth for the audit table from .wiki/concepts/hermes-skills-rollout-design.md (Q1-Q8). Pending entries preserve the audit decision (intended mode/category) for the follow-up tasks: hermes-flavour-mcp-setups, hermes-installer-skill, hermes-mvp-coverage. Security carry-forward (extraheader-pattern, POSIX-absolute paths, semver bumps) — infrastructure ready (replace-rules + manual mode); concrete content lands in hermes-flavour-mcp-setups. Smoke-tests: idempotent re-run produces no diff; replace-rules verified on active-platform (Linux+bash); strict-mapping fail-fast verified on a synthetic unmapped skill (exit 1). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
154 lines
4.7 KiB
Markdown
154 lines
4.7 KiB
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
|
|
|
|
> 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`.
|