@ericrisco/rsc 3.7.0 → 3.7.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.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![npm](https://img.shields.io/npm/v/@ericrisco/rsc?color=63d68a&labelColor=12161c&label=npm)](https://www.npmjs.com/package/@ericrisco/rsc)
10
10
  [![downloads](https://img.shields.io/npm/dm/@ericrisco/rsc?color=63d68a&labelColor=12161c&label=downloads)](https://www.npmjs.com/package/@ericrisco/rsc)
11
- [![skills](https://img.shields.io/badge/skills-273-63d68a?labelColor=12161c)](#the-catalog)
11
+ [![skills](https://img.shields.io/badge/skills-274-63d68a?labelColor=12161c)](#the-catalog)
12
12
  [![license](https://img.shields.io/badge/license-MIT-63d68a?labelColor=12161c)](LICENSE)
13
13
  [![stars](https://img.shields.io/github/stars/ericrisco/rsc-harness?color=63d68a&labelColor=12161c)](https://github.com/ericrisco/rsc-harness/stargazers)
14
14
 
@@ -71,7 +71,7 @@ The decisions your agent needs should have a place to live outside the chat.
71
71
  | --- | --- |
72
72
  | **Knowledge** | A local `02-DOCS/` wiki for project context, decisions and evidence. |
73
73
  | **Tools** | A `01-TOOLS/` convention for documenting real connections and their checks. |
74
- | **Skills** | A selection from 273 available skills, loaded progressively when relevant. |
74
+ | **Skills** | A selection from 274 available skills, loaded progressively when relevant. |
75
75
  | **Controls** | Working rules and provider-specific hooks, with explicit support limits. |
76
76
 
77
77
  The mechanism is practical: keep the decision, make it discoverable, and have the next task consult it.
@@ -501,7 +501,7 @@ price, customer testimonial, deadline or guarantee is needed to explain a useful
501
501
 
502
502
  ## The catalog
503
503
 
504
- 273 skills, grouped by what you are trying to do. Click any skill to read its `SKILL.md`. It fires on
504
+ 274 skills, grouped by what you are trying to do. Click any skill to read its `SKILL.md`. It fires on
505
505
  its own when a task matches.
506
506
 
507
507
  ### 🧭 Core & control plane
@@ -513,7 +513,7 @@ its own when a task matches.
513
513
  Two lanes for change: `ftd` for ordinary work, and the ten-phase chain when durable artifacts would
514
514
  settle a real ambiguity. `idea-refinement` runs inside `specify`; `decision-challenge` is on demand.
515
515
 
516
- [ftd](skills/ftd/) · [sdd](skills/sdd/) · [constitution](skills/constitution/) · [idea-refinement](skills/idea-refinement/) · [specify](skills/specify/) · [clarify](skills/clarify/) · [plan](skills/plan/) · [tasks](skills/tasks/) · [analyze](skills/analyze/) · [decision-challenge](skills/decision-challenge/) · [implement](skills/implement/) · [source-grounded-development](skills/source-grounded-development/) · [verify](skills/verify/) · [review](skills/review/) · [simplify-code](skills/simplify-code/) · [ship](skills/ship/) · [debug](skills/debug/) · [worktrees](skills/worktrees/) · [parallel](skills/parallel/)
516
+ [ftd](skills/ftd/) · [sdd](skills/sdd/) · [constitution](skills/constitution/) · [idea-refinement](skills/idea-refinement/) · [specify](skills/specify/) · [clarify](skills/clarify/) · [plan](skills/plan/) · [tasks](skills/tasks/) · [analyze](skills/analyze/) · [decision-challenge](skills/decision-challenge/) · [implement](skills/implement/) · [source-grounded-development](skills/source-grounded-development/) · [verify](skills/verify/) · [review](skills/review/) · [simplify-code](skills/simplify-code/) · [ship](skills/ship/) · [debug](skills/debug/) · [worktrees](skills/worktrees/) · [parallel](skills/parallel/) · [tidy](skills/tidy/)
517
517
 
518
518
  ### 💼 Run a business
519
519
 
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "3.7.0",
2
+ "version": "3.7.1",
3
3
  "counts": {
4
- "skills": 273,
4
+ "skills": 274,
5
5
  "agents": 34,
6
6
  "commands": 53,
7
7
  "fixedCommands": 20
@@ -5056,6 +5056,29 @@
5056
5056
  ],
5057
5057
  "profiles": []
5058
5058
  },
5059
+ {
5060
+ "id": "tidy",
5061
+ "description": "Use when every repository in the workspace must end synced and clean: each one on its default branch, everything pushed, everything pulled, no leftover branches or worktrees. Covers the root repo and every nested repo (child projects). Fires on 'limpia el harness', 'actualiza todo', 'sincroniza todo', 'déjalo todo en main', 'sube y baja todo', 'tidy up the repos', 'sync everything'. NOT upgrading the rsc version (that is `npx @ericrisco/rsc upgrade`), NOT opening isolation for new work (that is `worktrees`), NOT landing one finished branch (that is `ship`).",
5062
+ "tags": [
5063
+ "git",
5064
+ "sync",
5065
+ "cleanup",
5066
+ "branches",
5067
+ "worktrees",
5068
+ "limpieza",
5069
+ "sincronizar",
5070
+ "main"
5071
+ ],
5072
+ "recommends": [
5073
+ "worktrees",
5074
+ "ship"
5075
+ ],
5076
+ "profiles": [
5077
+ "minimal",
5078
+ "core",
5079
+ "full"
5080
+ ]
5081
+ },
5059
5082
  {
5060
5083
  "id": "tiktok-api",
5061
5084
  "description": "Use when connecting a real TikTok account to code via the Content Posting, Display and Business Account APIs — OAuth, chunked video publish with status polling, and pulling views, watch time and impression sources, then logging that performance into the wiki as a dated feedback record. Covers short-lived tokens breaking a cron, unverified pull-from-URL ownership, and rate limits. NOT what to post or how to package it (that is `shortform-strategy` and `shortform-packaging`).",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ericrisco/rsc",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "A guided harness builder that turns your goal into a minimal, verified AI-agent setup using strict best practices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,7 +22,11 @@
22
22
  // `ux` joined in 3.4.0: `design` decides how a screen looks, `ux` decides whether people can use it —
23
23
  // the whole flow, every state, the browser walk. It replaced `ui-engineering`, which was core-only.
24
24
  // Only its description is paid for on other turns; the upstream references load on demand.
25
- export const DEFAULT_SKILL_FLOOR = Object.freeze(['orient', 'suggest', 'unslop', 'ftd', 'connect-tool', 'design', 'ux']);
25
+ //
26
+ // `tidy` joined in 3.8.0: "limpia el harness" / "actualiza todo" — every repo on its default branch,
27
+ // pushed, pulled, no landed branch or worktree left. Leftovers pile up in every workspace, not only in
28
+ // the ones that picked a profile with git skills, and the person asks for it in their own words.
29
+ export const DEFAULT_SKILL_FLOOR = Object.freeze(['orient', 'suggest', 'unslop', 'ftd', 'connect-tool', 'design', 'ux', 'tidy']);
26
30
 
27
31
  export function withDefaultSkillFloor(skillIds = []) {
28
32
  return [...new Set([...DEFAULT_SKILL_FLOOR, ...skillIds])];
@@ -5,7 +5,7 @@
5
5
 
6
6
  export const DOMAINS = [
7
7
  { title: 'Core & control plane', ids: ['init', 'harness', 'orient', 'suggest', 'unslop', 'author-skill', 'sdd-init'] },
8
- { title: 'Spec-Driven Development', ids: ['ftd', 'sdd', 'constitution', 'idea-refinement', 'specify', 'clarify', 'plan', 'tasks', 'analyze', 'decision-challenge', 'implement', 'source-grounded-development', 'verify', 'review', 'simplify-code', 'ship', 'debug', 'worktrees', 'parallel'] },
8
+ { title: 'Spec-Driven Development', ids: ['ftd', 'sdd', 'constitution', 'idea-refinement', 'specify', 'clarify', 'plan', 'tasks', 'analyze', 'decision-challenge', 'implement', 'source-grounded-development', 'verify', 'review', 'simplify-code', 'ship', 'debug', 'worktrees', 'parallel', 'tidy'] },
9
9
  { title: 'Run a business', ids: ['finance-ops', 'invoicing', 'bookkeeping', 'pricing', 'sales-pipeline', 'lead-gen', 'cold-outreach', 'proposals', 'contracts', 'customer-support', 'client-onboarding', 'retention', 'hiring', 'people-ops', 'inventory', 'logistics-ops', 'procurement', 'meeting-notes', 'sop-builder', 'project-ops'] },
10
10
  { title: 'Raise & model money', ids: ['pitch-deck', 'investor-materials', 'financial-model', 'fundraising', 'unit-economics', 'grants'] },
11
11
  { title: 'Legal, privacy & compliance', ids: ['gdpr-privacy', 'terms-conditions', 'compliance', 'data-policy', 'ip-trademark'] },
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: tidy
3
+ description: "Use when every repository in the workspace must end synced and clean: each one on its default branch, everything pushed, everything pulled, no leftover branches or worktrees. Covers the root repo and every nested repo (child projects). Fires on 'limpia el harness', 'actualiza todo', 'sincroniza todo', 'déjalo todo en main', 'sube y baja todo', 'tidy up the repos', 'sync everything'. NOT upgrading the rsc version (that is `npx @ericrisco/rsc upgrade`), NOT opening isolation for new work (that is `worktrees`), NOT landing one finished branch (that is `ship`)."
4
+ tags: [git, sync, cleanup, branches, worktrees, limpieza, sincronizar, main]
5
+ recommends: [worktrees, ship]
6
+ profiles: [minimal, core, full]
7
+ origin: risco
8
+ ---
9
+
10
+ # tidy — every repo on main, pushed, pulled, nothing left over
11
+
12
+ One request, every repository in the workspace. When it ends, each repo shows the same picture:
13
+
14
+ - the main checkout is on the **default branch**, up to date with the remote;
15
+ - **nothing local is missing from the remote** — no unpushed commit, on any branch;
16
+ - **no worktree and no branch whose work has already landed**, locally or on the remote.
17
+
18
+ The job is cleanup, and cleanup is where work gets lost. So the rule under every step: **delete only
19
+ what is proven to be in the default branch already.** Anything else is pushed, kept and reported —
20
+ never thrown away to make the picture look clean.
21
+
22
+ ## 1. Find the repositories
23
+
24
+ The workspace root, plus every nested git repository below it (child projects keep their own git):
25
+
26
+ ```bash
27
+ git rev-parse --show-toplevel # the root repo, if any
28
+ find . -name .git -maxdepth 4 -not -path '*/node_modules/*' -not -path '*/.worktrees/*'
29
+ ```
30
+
31
+ A `.git` that is a *file* is a linked worktree or a submodule, not a repo of its own: skip it here,
32
+ it is handled from its parent in step 4. Name the list in one line before touching anything.
33
+
34
+ **Never change the working directory into a child repo.** Use `git -C <repo>` and absolute paths.
35
+ Session hooks take the cwd as the project, and a `cd` plants state inside the child.
36
+
37
+ ## 2. Read everything before changing anything
38
+
39
+ Per repo, one pass, no writes except the fetch:
40
+
41
+ ```bash
42
+ git -C <repo> fetch --all --prune --quiet
43
+ git -C <repo> symbolic-ref --short refs/remotes/origin/HEAD # the default branch (origin/main)
44
+ git -C <repo> status --short --branch # current branch, ahead/behind, dirty
45
+ git -C <repo> for-each-ref --format='%(refname:short) %(upstream:short) %(upstream:track)' refs/heads
46
+ git -C <repo> worktree list --porcelain
47
+ git -C <repo> stash list
48
+ gh pr list --state open --json number,headRefName 2>/dev/null # open PRs, when gh is there
49
+ ```
50
+
51
+ No remote at all → the repo cannot be "pushed"; report it and only tidy what is local.
52
+
53
+ ## 3. Classify every item
54
+
55
+ Each branch, worktree and remote branch lands in exactly one row. Decide by the commands, not by
56
+ reading names.
57
+
58
+ | Item | Proof | Action |
59
+ | --- | --- | --- |
60
+ | Worktree whose work landed | `npx @ericrisco/rsc worktrees` calls it safe | `npx @ericrisco/rsc worktrees reap` |
61
+ | Worktree whose directory is gone | `prunable` in the porcelain list | `git -C <repo> worktree prune` |
62
+ | Worktree with live or unsaved work | anything the reaper refuses | keep; report the reaper's reason |
63
+ | Local branch merged into the default | `merge-base --is-ancestor <b> origin/<default>` | `git branch -d <b>` |
64
+ | Local branch squash-merged | its content is in the default (below) | `git branch -D <b>`, tip SHA in the report |
65
+ | Local branch with unlanded commits | neither of the two above | push it (`git push -u origin <b>`), keep it |
66
+ | Remote branch whose content landed | same content check, against `origin/<b>` | delete it, after one confirmation (step 6) |
67
+ | Remote branch with an open PR | `gh pr list` | keep; it is live |
68
+ | Remote branch unlanded, no PR | not in the default, no PR | keep; report it as an open question |
69
+ | Stash | any | keep; report it. Never `stash drop` without a yes |
70
+
71
+ **The content check** (what makes a squash merge count as landed): merge the branch into the default
72
+ in memory and see whether anything changes.
73
+
74
+ ```bash
75
+ git -C <repo> merge-tree --write-tree origin/<default> <branch> | head -1 # resulting tree
76
+ git -C <repo> rev-parse origin/<default>^{tree} # default's tree
77
+ ```
78
+
79
+ Same tree → the branch adds nothing; it has landed. A conflict, a different tree, or a git older
80
+ than 2.38 (no `--write-tree`) → **not proven**, so it is kept. A branch that never carried a commit
81
+ of its own is a live workspace someone just opened, not leftovers: keep it.
82
+
83
+ Never delete the default branch, the current branch of another checkout, or `rsc/knowledge`.
84
+
85
+ ## 4. Act, in this order
86
+
87
+ 1. **Uncommitted changes stop that repo.** Show the files and ask once: commit them, stash them, or
88
+ leave the repo as is. Never commit or discard someone's work in progress on your own. Another
89
+ session working in that checkout (the isolation notice says so) → do not touch its branch or its
90
+ files at all; report it.
91
+ 2. **Push what is only local.** Every branch with unlanded commits goes to the remote. The default
92
+ branch ahead of `origin`: push it if the default branch is open here; if it is protected
93
+ (branches and PRs), move those commits to a branch and open a PR — ask first.
94
+ 3. **Retire what landed.** `npx @ericrisco/rsc worktrees reap` for worktrees (it refuses anything
95
+ that would lose a file, and its refusal stands), `worktree prune`, then the branches from step 3.
96
+ Without rsc in that repo, follow the manual path in `../worktrees/SKILL.md`.
97
+ 4. **Back to the default and pull.** Clean checkout on another branch whose work is pushed →
98
+ `git -C <repo> switch <default>`. Then `git -C <repo> pull --ff-only`. A pull that cannot
99
+ fast-forward means the local default diverged: stop and report, never `reset --hard`.
100
+
101
+ ## 5. What is never done
102
+
103
+ - `reset --hard`, `clean -fdx`, `push --force`, `worktree remove --force`, `stash drop` or `clear` —
104
+ not to make the picture tidy, not on a "probably fine".
105
+ - Deleting a branch or worktree because its name looks old. Only the proofs in step 3 count.
106
+ - Committing straight to a protected default branch.
107
+
108
+ ## 6. Remote branches: one confirmation, for all of them
109
+
110
+ Deleting a remote branch reaches everyone who clones the repo. Collect every remote branch whose
111
+ content landed, across all repos, and ask **once** with the full list:
112
+
113
+ > Remote branches already in main, to delete: `rsc-harness: feat/x, fix/y` · `rsc-brain: feat/z`.
114
+ > ¿Las borro? (sí/no)
115
+
116
+ On yes: `git -C <repo> push origin --delete <b> ...`. On no: keep them and say so in the report.
117
+
118
+ ## 7. The report
119
+
120
+ One table, one row per repo, then the open questions. Only facts you observed in this run.
121
+
122
+ | Repo | Branch | ↑ / ↓ | Worktrees | Local branches | Remote branches | Pending |
123
+ | --- | --- | --- | --- | --- | --- | --- |
124
+ | rsc-harness | main | 0 / 0 | 0 | 0 | 2 deleted | — |
125
+ | rsc-brain | main | 0 / 0 | 1 kept | 1 pushed | — | `feat/z`: live, no PR |
126
+
127
+ Under it: every deleted squash-merged branch with its tip SHA (it can be brought back with
128
+ `git branch <name> <sha>`), and every item kept with the one action that would close it. A repo that
129
+ is not fully clean is reported as not clean, with the reason; a tidy-looking summary that hides one
130
+ kept item is the failure this skill exists to prevent.
131
+
132
+ ## Anti-patterns → STOP
133
+
134
+ | Rationalization | Reality / Fix |
135
+ | --- | --- |
136
+ | "It's an old branch, nobody uses it" | Age proves nothing. Ancestor or same tree, or it stays. |
137
+ | "Squash-merged, so `-D` is fine without checking" | Check the tree first. A branch with one extra commit after the PR looks identical by name. |
138
+ | "The tree is dirty, I'll stash it to switch to main" | That is someone's work. Ask first; a stash is easy to forget for ever. |
139
+ | "Pull failed, I'll `reset --hard origin/main`" | That throws away local commits. Report the divergence instead. |
140
+ | "I'll `cd` into each child to run git" | `git -C <repo>`. A `cd` plants session state inside the child. |
141
+ | "I'll delete the remote branches as I go" | One list, one confirmation, at the end. |
142
+ | "Report says clean; the kept worktree is a detail" | Say what was kept and why. The report is the deliverable. |
143
+
144
+ **Next:** after a clean report there is nothing to hand over. Neighbours: `../worktrees/SKILL.md`
145
+ opens isolation for new work; `../ship/SKILL.md` lands one finished branch; `npx @ericrisco/rsc
146
+ upgrade` updates the harness itself, which is a different "actualiza".
147
+
148
+ ## Orientación (siempre)
149
+
150
+ Habla con la voz de `orient`: frases cortas, una idea por frase, y cada respuesta se entiende sola. Registro técnico o con analogías según `technical_level` en `02-DOCS/wiki/harness/user-profile.md`. Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ➡️ siguiente, terminando en pregunta; ✅ y 🧭 cuando hay algo hecho o decidido). **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
@@ -0,0 +1,23 @@
1
+ # Evals — tidy
2
+
3
+ The claim under test is the boundary with three neighbours that also say "update" or "clean":
4
+ `rsc upgrade` (the harness version), `worktrees` (opening isolation) and `ship` (landing one
5
+ branch). The negatives prove the split.
6
+
7
+ ## Triggering
8
+
9
+ Load only `tidy` and run every prompt in 3–5 fresh sessions. A positive passes when `tidy` loads in
10
+ a majority of trials; a negative passes when it stays quiet. Require at least 90% accuracy, and treat
11
+ a trigger on "actualiza rsc a la última versión" as blocking: that one is the same verb, a
12
+ different job.
13
+
14
+ ## Capability
15
+
16
+ Fixture: a workspace with a root repo and two child repos holding, between them, a merge-landed
17
+ branch, a squash-landed branch whose remote is gone, a branch with one unpushed commit, a landed
18
+ worktree, a worktree with an untracked `.env`, and a child checkout left on a feature branch.
19
+
20
+ Pass when, after the run: both landed branches are gone (the squash one with its SHA reported); the
21
+ unpushed branch exists on the remote and locally; the landed worktree is gone; the `.env` worktree is
22
+ still there and reported; every checkout is on `main`, 0 ahead and 0 behind; and no remote branch was
23
+ deleted before the single confirmation. Any lost commit or file fails the run outright.
@@ -0,0 +1,53 @@
1
+ skill: tidy
2
+
3
+ # `tidy` owns the end-of-day sweep across every repo in the workspace: each on its default
4
+ # branch, pushed, pulled, no landed branch or worktree left. Upgrading rsc itself, opening
5
+ # isolation for new work and landing one branch belong to neighbours.
6
+ should_trigger:
7
+ - prompt: "Limpia el harness."
8
+ why: "The owner's own phrase for the whole sweep."
9
+
10
+ - prompt: "Actualiza todo a main en estos proyectos, que esté todo subido y sin ramas."
11
+ why: "Default branch, pushed, no branches: the contract in one sentence."
12
+
13
+ - prompt: "Sube y baja todo y quita los worktrees que sobren."
14
+ why: "Push, pull and retire leftovers across the workspace."
15
+
16
+ - prompt: "Tidy up the repos, I have branches and worktrees everywhere."
17
+ why: "Leftover branches and worktrees across repos, in English."
18
+
19
+ - prompt: "Déjalo todo en main y limpio antes de irme."
20
+ why: "End-of-session state for every repo."
21
+
22
+ - prompt: "Sync everything with GitHub and delete the merged branches."
23
+ why: "Push/pull plus landed-branch cleanup is this skill's whole job."
24
+
25
+ should_not_trigger:
26
+ - prompt: "Actualiza rsc a la última versión."
27
+ route_to: "suggest"
28
+ why: "Upgrading the harness itself is `rsc upgrade`, not a git sweep."
29
+
30
+ - prompt: "Abre un worktree para empezar la feature de pagos."
31
+ route_to: "worktrees"
32
+ why: "Opening isolation for new work is the opposite move."
33
+
34
+ - prompt: "Esta rama ya pasó review, fusiónala."
35
+ route_to: "ship"
36
+ why: "Landing one verified branch is ship."
37
+
38
+ - prompt: "Borra los ficheros temporales y el node_modules del proyecto."
39
+ route_to: "bash-scripting"
40
+ why: "Disk cleanup inside a project is not branch and remote hygiene."
41
+
42
+ capability:
43
+ - scenario: "User says: 'Limpia el harness.' The workspace has a root repo and two child repos. Between them: a branch merged into main, a squash-merged branch whose remote is gone, a branch with one unpushed commit, a worktree whose work landed, a worktree holding an untracked `.env`, and one child checkout left on a clean, pushed feature branch. Another child has an uncommitted edit to README.md."
44
+ must_include:
45
+ - "Lists the repos it found (root plus every nested repo) before changing anything, and runs git with `git -C <repo>` instead of changing directory into a child"
46
+ - "Fetches with prune and reads branches, worktrees, stashes and status for every repo before the first write"
47
+ - "Deletes the merged branch with `git branch -d`, and the squash-merged one only after the content check (merge-tree tree equals the default's tree), reporting its tip SHA"
48
+ - "Pushes the branch with the unpushed commit and keeps it, instead of deleting it"
49
+ - "Retires the landed worktree through `npx @ericrisco/rsc worktrees reap` and keeps the `.env` worktree, reporting the reaper's reason"
50
+ - "Stops on the uncommitted README.md edit and asks (commit, stash or leave) instead of stashing or discarding it on its own"
51
+ - "Switches the clean child checkout back to main and pulls with `--ff-only`"
52
+ - "Asks once, with the full list, before deleting any remote branch"
53
+ - "Ends with one table per repo plus the kept items and the action that would close each, and never uses reset --hard, push --force, clean -fdx or stash drop"