claude-dev-env 1.51.0 → 1.52.1

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.
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: update
3
+ description: Fast-forwards a local git repository's main branch to a remote's main, after confirming both the local repo path and the source remote through AskUserQuestion. Fetches the chosen remote, checks that the move is a true fast-forward (never a force, never a merge commit), and updates main whether or not main is the checked-out branch. Use when the user says "/update", "update main", "fast-forward main", "sync main from origin", "pull latest main into <path>", or "bring main up to date". Triggers on "/update", "update main", "fast-forward main", "sync main".
4
+ ---
5
+
6
+ # update
7
+
8
+ ## Overview
9
+
10
+ Fast-forwards the local `main` branch of a given repository to a chosen remote's `main`. The move is always a true fast-forward: the skill fetches the remote, checks that local `main` is an ancestor of the remote's `main`, and advances the ref. It never forces, never creates a merge commit, and never touches any branch other than `main`.
11
+
12
+ The repository is whatever path the user gives as the `/update <path>` argument. With no argument, the default is the current repository's top level. Either way the path is confirmed before any write.
13
+
14
+ **Announce at start:** "Confirming the repo path and source remote, then fast-forwarding main."
15
+
16
+ ## When this applies
17
+
18
+ Trigger on a request to bring a repo's `main` up to date from a remote: "/update", "update main", "fast-forward main", "sync main from origin", "pull latest main into <path>".
19
+
20
+ **Refusals — first match wins; respond with the quoted line exactly and stop:**
21
+
22
+ - Path is not a git repository → `<path> is not a git repository. Give me the path to a git working tree.`
23
+ - The chosen remote has no `main` → `<remote> has no main branch. Pick a remote whose main you want.`
24
+ - Local `main` has diverged from the remote's `main` (not a fast-forward) → `main has diverged from <remote>/main (ahead N, behind M). A fast-forward is not possible — use /rebase or reconcile manually.`
25
+
26
+ ## Instructions
27
+
28
+ ### Phase 1 — Resolve the local path
29
+
30
+ Take the path from the `/update <path>` argument. With no argument, use the current repo's top level:
31
+
32
+ ```
33
+ git -C "<path>" rev-parse --show-toplevel
34
+ ```
35
+
36
+ Confirm the path is a git working tree (`git -C "<path>" rev-parse --git-dir`). If not, give the first refusal line.
37
+
38
+ ### Phase 2 — Confirm the path and the source remote
39
+
40
+ List the candidate repo's remotes and their URLs:
41
+
42
+ ```
43
+ git -C "<path>" remote -v
44
+ ```
45
+
46
+ Confirm both in **one** `AskUserQuestion` question — header "Target". Each choice pairs the resolved path with one remote, labelled `<path> ← <remote>/main` and described with that remote's fetch URL. Picking a choice confirms the path and the remote together.
47
+
48
+ Recommend `<path> ← origin/main` first; the source-of-truth remote is not always the one named `origin`. The user picks "Other" to name a different path or remote. If they switch to a different repository, re-list its remotes and ask once more — remote names are per-repo.
49
+
50
+ ### Phase 3 — Fetch and fast-forward
51
+
52
+ Run every command with `git -C "<path>"`. Do not `cd` into the repo.
53
+
54
+ 1. Fetch the chosen remote's `main`, which moves the remote-tracking ref:
55
+
56
+ ```
57
+ git -C "<path>" fetch <remote> main
58
+ ```
59
+
60
+ Stop and report on failure (no network, no remote). If the remote has no `main`, give the second refusal line.
61
+
62
+ 2. Read the current branch and the two commits:
63
+
64
+ ```
65
+ git -C "<path>" branch --show-current
66
+ git -C "<path>" rev-parse <remote>/main
67
+ git -C "<path>" rev-parse --verify main # may not exist yet
68
+ ```
69
+
70
+ 3. Decide the case:
71
+
72
+ | Case | Condition | Action |
73
+ |---|---|---|
74
+ | Create | local `main` does not exist | `git -C "<path>" branch main <remote>/main` |
75
+ | Up to date | local `main` == `<remote>/main` | report, done |
76
+ | Diverged | `merge-base --is-ancestor main <remote>/main` is false | third refusal line, stop |
77
+ | Fast-forward, on main | current branch is `main` | clean check, then `merge --ff-only` |
78
+ | Fast-forward, off main | current branch is not `main` | `fetch <remote> main:main` |
79
+
80
+ The fast-forward gate:
81
+
82
+ ```
83
+ git -C "<path>" merge-base --is-ancestor main <remote>/main
84
+ ```
85
+
86
+ Exit 0 means a fast-forward is possible. Non-zero means diverged — refuse, never force.
87
+
88
+ 4. Apply the fast-forward for the matched case:
89
+
90
+ - **On `main`:** the working tree must be clean first — `git -C "<path>" status --porcelain` must be empty. If dirty, stop and report; never stash or discard. Then:
91
+
92
+ ```
93
+ git -C "<path>" merge --ff-only <remote>/main
94
+ ```
95
+
96
+ - **Off `main`:** advance the ref without touching the working tree:
97
+
98
+ ```
99
+ git -C "<path>" fetch <remote> main:main
100
+ ```
101
+
102
+ This is fast-forward-only (no leading `+`) and leaves the checked-out branch alone.
103
+
104
+ ### Phase 4 — Report
105
+
106
+ State the old and new `main` SHAs and the one-line subject of the new tip:
107
+
108
+ ```
109
+ git -C "<path>" log --oneline -1 main
110
+ ```
111
+
112
+ Report the move as `main <old> → <new>`, or "already up to date" when nothing changed.
113
+
114
+ ## Constraints (non-negotiable)
115
+
116
+ - **Fast-forward only.** If the remote's `main` is not a descendant of local `main`, stop. Never `--force`, never `branch -f`, never a merge commit. Divergence is a job for `/rebase`.
117
+ - **Always confirm both** the path and the source remote first, even when the path is given as an argument. Skipping a confirmation is not allowed — the confirmation is the point of this skill.
118
+ - **Touch only `main`.** Never switch the repo's checked-out branch. The single exception is advancing `main` in place when `main` is already checked out.
119
+ - **Never discard local work.** A dirty tree blocks the in-place fast-forward; stop and report rather than stash or reset.
120
+
121
+ ## Gotchas
122
+
123
+ - `git fetch <remote> main:main` refuses with "Refusing to fetch into branch ... checked out" when `main` is the current branch. That is why Phase 3 branches on `git branch --show-current` and uses `merge --ff-only` when on `main`.
124
+ - The same refusal fires when `main` is checked out in a **different worktree** of the same repo. Find it with `git -C "<path>" worktree list`, then run the fast-forward from that worktree's path, or report it and stop.
125
+ - `<remote>/main` only moves after an explicit `git fetch`. Fetch inside every run; never compare against a remote-tracking ref left over from an earlier fetch.
126
+ - `origin` is not always the source of truth. When a fork is `origin` and the canonical repo is another remote (often `upstream`), the confirmed remote should be the canonical one, not whichever is named `origin`.
127
+ - Quote the path on every command — `git -C "<path>"` — so paths with spaces or a NAS drive letter survive.
128
+
129
+ ## What this skill does NOT do
130
+
131
+ - Does not push, open a PR, or change any branch other than `main`.
132
+ - Does not create or switch feature branches — that is `/fresh-branch`.
133
+ - Does not reconcile a diverged `main` — that is `/rebase`.
134
+
135
+ ## File index
136
+
137
+ | File | Purpose |
138
+ |------|---------|
139
+ | `SKILL.md` | This hub — the complete skill. |
140
+
141
+ ## Folder map
142
+
143
+ - `SKILL.md` — the whole skill. Flat by design: the operation is a short, deterministic git sequence with no scripts or reference files to load.