@sassywares/skills 0.5.10 → 0.5.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassywares/skills",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "description": "Lean, explicit-invocation Agent Skills for shipping fast: plan, work, review, validate, ship.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@ disable-model-invocation: true
12
12
 
13
13
  # Sassy Skill
14
14
 
15
- **Outcome:** a well-formed Agent Skill at a location the user chose, or an existing skill improved and re-verified. The harness loads it with no diagnostics.
15
+ **Outcome:** a well-formed Agent Skill at a location the user chose, an existing skill improved and re-verified, or a report on one — and the harness loads it with no diagnostics.
16
16
 
17
17
  **Modes.** `mode:create` writes a new skill. `mode:retune` changes the smallest thing that fixes a named failure in an existing skill. `mode:verify` checks an existing skill against the checklist and reports — it edits nothing. Omitted, detect it from the argument: something that already resolves to a skill directory is `retune`, or `verify` when the user only asked whether it is any good; anything else is `create`. State the mode you picked and why; when both are plausible, ask instead of guessing.
18
18
 
@@ -20,11 +20,23 @@ disable-model-invocation: true
20
20
 
21
21
  **Scope:** skills only — not extensions, packages, or prompt templates.
22
22
 
23
+ ## One mode, one reference
24
+
25
+ Each mode's mechanics live in its own file. Read the one you were dispatched to — **and only that one**. A `create` never reads `retune`'s failure map, and a `verify` never picks up a fix from it: that adjacency is exactly how a read-only check turns into an edit.
26
+
27
+ | Mode | Load | It ends with |
28
+ |---|---|---|
29
+ | `create` | `references/create.md` | a new skill on disk, installed and verified |
30
+ | `retune` | `references/retune.md` | the smallest edit that kills one named failure, re-verified |
31
+ | `verify` | `references/verify.md` | a report, and no file touched |
32
+
33
+ Everything below is shared by all three: the location table, pi's rules, the shape rule, the checklist, and the verification run. Read it once, then your one reference.
34
+
23
35
  ## pi's rules (the essentials)
24
36
 
25
37
  - A skill is a **directory containing `SKILL.md`**. Discovered recursively.
26
38
  - **Name:** lowercase letters, numbers, hyphens; no leading/trailing/consecutive hyphens; ≤64 chars. Match the directory name.
27
- - **Description:** required, ≤1024 chars. Pi advertises name + description at startup; the body loads only when the skill is used. The description decides whether the skill ever fires — write **what it does and when to use it**.
39
+ - **Description:** required, ≤1024 chars. Pi advertises name + description at startup; the body loads only when the skill is used, so the description alone decides whether the skill ever fires. Write **what it does and when to use it**, with concrete verbs and the words a user would actually say — "can't trigger" is almost always a description that named the topic and never the moment.
28
40
  - **Frontmatter fields:** `name`, `description` (required); optional `license`, `compatibility`, `metadata`, `allowed-tools`, `disable-model-invocation`.
29
41
  - Use `disable-model-invocation: true` for skills that should run only via explicit `/skill:name`.
30
42
  - **Reference other skills by name, never by absolute path.** The suite can live in `~/.agents/skills/`, a project `.agents/skills/`, or inside `node_modules/`, so "load the sassy-commit skill" is portable where a `~/…` path is not. Name a bundled file as "the sassy-setup skill's `references/config.md`".
@@ -47,46 +59,44 @@ Internal is the only one that ships to everyone. Never choose it silently: once
47
59
 
48
60
  Paths in the table are the defaults. Harnesses also read `skills` arrays in settings and installed packages, so a skill may live elsewhere — write down where it actually went.
49
61
 
50
- ## Shape rule — the lean rule
62
+ ## Shape rule — split on outcomes, not on topics
51
63
 
52
- - **Default to one `SKILL.md`.**
53
- - Add `references/` **only** for content that is **conditionally read** (or genuinely bulky and only sometimes needed). A reference that is read on *every* run saves nothing and may cost a little.
54
- - Keep `SKILL.md` an index: outcome → hard rules → workflow → explicit pointers ("read `references/x.md` before doing Y").
55
- - Never bury conditional detail in a monolithic `SKILL.md`.
56
-
57
- ## Workflow
58
-
59
- 1. **Intake.** Settle the mode (above), then what the skill does, when it should trigger, and **where it lives** — internal, project, or user (see above). Ask; do not infer from the cwd. In `mode:retune`, read the existing skill and name the specific failure (won't trigger, too long, wrong steps, stale, wrong scope). In `mode:verify`, read it, run the checklist and Verify, report, and stop without writing.
60
- 2. **Choose the shape.** Single file, or `SKILL.md` + `references/` per the rule above.
61
- 3. **Write the frontmatter.** A description that states both what and when.
62
- 4. **Write the body.** Outcome, a hard-rules table, the workflow, and reference pointers. Plain English. Structured output where the skill returns a result. Match this setup's house style.
63
- 5. **Self-check** against the checklist below.
64
- 6. **Install and verify.** Place it at the right path, run `/reload`, confirm no startup diagnostics, and test `/skill:<name>`.
64
+ - **One `SKILL.md` is the default, but it is a decision, not a reflex.** Length never decides the shape; the paths do.
65
+ - **Split whenever the skill branches into paths that end differently.** A mode, trigger, or branch that writes a different thing, forbids a different thing, or is never needed in the same run as its sibling gets its own `references/<path>.md` — **even at three paragraphs**. How small each path is does not matter: what matters is that a model running path A never reads path B's instructions next to A's. Divergent outcomes sharing one file bleed into each other, and the bleed looks like helpfulness until it has already written the wrong thing. Think ahead when you write it, not after the first misfire. This skill is shaped by its own rule.
66
+ - **Never split a shared surface.** What every path needs — ids, board or table values, hard rules, API quirks, house style — stays in `SKILL.md`, or each path pays to load it and they drift apart. One reference per **outcome**, never one per **section**: `references/` holding five short topic files is the oversplit, and it makes routing vaguer, not sharper.
67
+ - **`SKILL.md` becomes routing.** State the dispatch explicitly — a table naming exactly one reference per path, plus "read that one only". That sentence is what prevents the bleed; a pointer buried in a paragraph does not.
68
+ - A reference that is read on *every* run saves nothing and may cost a little, so it belongs in the body.
69
+ - Keep `SKILL.md` an index: outcome → hard rules → workflow → explicit pointers ("read `references/x.md` before doing Y"). Never bury path-specific detail in a monolithic file.
65
70
 
66
71
  ## Self-check checklist
67
72
 
73
+ The gate for a new or edited skill, and the instrument in `mode:verify`.
74
+
68
75
  - [ ] `name`: lowercase/hyphens, ≤64, matches the directory.
69
76
  - [ ] `description`: states what **and** when, ≤1024, not vague.
70
77
  - [ ] Frontmatter is valid YAML with the required fields.
71
78
  - [ ] Every `references/…` path exists and is pointed to explicitly in the body.
79
+ - [ ] Each outcome path that ends differently has its own reference, and the body dispatches to exactly one of them per run.
80
+ - [ ] No reference exists merely because its content was a separate section — that is oversplitting, not shaping.
72
81
  - [ ] The body is lean; no always-read detail needlessly hidden in a reference.
73
82
  - [ ] No secrets, and no capability the skill cannot actually use.
74
83
 
75
- ## Retune
76
-
77
- In `mode:retune`, change the **smallest** thing that fixes the named failure:
78
-
79
- - **Won't trigger** → rewrite the description (what + when, concrete verbs).
80
- - **Too long / bloated** → extract conditional content to `references/`, or delete what never gets used.
81
- - **Wrong or stale steps** → correct the workflow against the current tree.
82
- - **Wrong scope** → move it between internal, project, and user. Moving into the suite is a release; moving out of it means the next release drops the skill for everyone.
83
-
84
- Re-verify after any retune.
85
-
86
- ## Verify
87
-
88
- Run this at the end of `create` and `retune`, and as the whole job in `mode:verify`.
84
+ ## Verification — how every mode ends
89
85
 
90
86
  - `/reload`.
91
87
  - Check pi's startup output for warnings about the skill.
92
88
  - Run `/skill:<name>` and confirm it loads and behaves.
89
+
90
+ `create` and `retune` are not finished until this passes; `verify` exists to run it and report.
91
+
92
+ ## Hard rules
93
+
94
+ | Rule | Requirement |
95
+ |------|-------------|
96
+ | Ask before writing | The location — internal, project, or user — is the user's call, never the cwd's. State the mode you inferred. |
97
+ | Verify writes nothing | `mode:verify` ends with a report. If you spot a fix while verifying, name it and let the user ask for the retune. |
98
+ | Retune is minimal | One named failure, the smallest change that kills it. No drive-by rewrites, no tidy-ups nobody asked for. |
99
+ | Split by outcome | Divergent paths get their own reference even when tiny; shared surfaces stay in the body. |
100
+ | Name skills, not paths | Reference another skill by name so the suite stays portable across install locations. |
101
+ | Internal is a release | Putting a skill in the suite ships it to every consumer on `main`. Never choose it silently. |
102
+ | Nothing untestable | No secrets, and no capability the skill cannot actually perform. |
@@ -0,0 +1,48 @@
1
+ # Mode: create — write a new skill
2
+
3
+ Read the skill's shared sections first (locations, pi's rules, shape rule, checklist). This file is the write side only.
4
+
5
+ ## 1. Intake
6
+
7
+ Settle three things by asking, not inferring:
8
+
9
+ - **What it does** — the one outcome, stated as a result ("a merged PR", "a filed ticket", "a plan on disk"), not as an activity.
10
+ - **When it fires** — the words a user will actually say. These become the description's *when* half.
11
+ - **Where it lives** — internal, project, or user, per the location table. Ask; the cwd proves nothing.
12
+
13
+ If any of the three is missing, ask before writing a file. A skill authored on a guess is the one that gets retuned next week.
14
+
15
+ ## 2. Choose the shape — enumerate the outcome paths first
16
+
17
+ List the ways a run can end (for example: file / comment / move a state; plan / implement / ship; create / retune / verify). Then apply the shape rule:
18
+
19
+ - A path that ends differently, forbids something different, or is never needed alongside its sibling → its own `references/<path>.md`, however short.
20
+ - What every path needs → the body.
21
+ - Then write the dispatch table in the body that names **exactly one** reference per path, and the sentence that says read only that one.
22
+
23
+ Two paragraphs of route-specific instruction are worth their own file; a shared field table is not worth splitting.
24
+
25
+ ## 3. Frontmatter
26
+
27
+ `name` matches the directory. `description` states what and when, ≤1024 chars, in the user's vocabulary. Add `disable-model-invocation: true` when the skill should only run via `/skill:<name>`, and an `argument-hint` when it takes one.
28
+
29
+ Do not put workflow detail in the description — it decides triggering, not execution.
30
+
31
+ ## 4. Body
32
+
33
+ House shape, in this order:
34
+
35
+ 1. **Outcome** — one sentence, a result.
36
+ 2. **Hard rules** — a table of the few invariants that, if broken, make the output wrong regardless of how the steps went.
37
+ 3. **Workflow** — numbered steps a competent agent can follow without re-deriving them, with the reference pointer for each path.
38
+ 4. **Pointers** — "read `references/x.md` before doing Y", never a bare file list.
39
+
40
+ Plain English, no filler. Where the skill returns a result, give the shape of that result so two runs look alike.
41
+
42
+ ## 5. Place and install
43
+
44
+ - **Internal:** `skills/<name>/` in the sassy-skills repo, named `sassy-<name>`; then `scripts/sync.sh` — it commits, bumps the patch version, tags, and publishes. Say that this ships to everyone before you do it.
45
+ - **Project:** `<repo>/.agents/skills/<name>/`, prefixed with the project so it cannot collide with a suite skill or a harness built-in; then commit it.
46
+ - **User:** `~/.agents/skills/<name>/`. Nothing gates it, so check it actually works before trusting it.
47
+
48
+ Then run the skill's Verification section: `/reload`, no startup warnings, `/skill:<name>` behaves. A skill that has never been invoked has not been written.
@@ -0,0 +1,33 @@
1
+ # Mode: retune — the smallest fix for one named failure
2
+
3
+ Read the skill's shared sections first (locations, pi's rules, shape rule, checklist). This file is the failure map.
4
+
5
+ ## 1. Name the failure before touching anything
6
+
7
+ Read the skill and say which of these it is, in one line. "It feels long" is not a failure; "it fires on status moves too" is.
8
+
9
+ ## 2. Failure → smallest fix
10
+
11
+ | Named failure | The fix |
12
+ |---|---|
13
+ | **Won't trigger** | Rewrite the description: what + when, concrete verbs, the user's own words. Not the body. |
14
+ | **Fires when it shouldn't** | Tighten the description's *when* half, or add `disable-model-invocation: true` if it is an explicit-only skill. |
15
+ | **One path's rules bleed into another's** (a mode doing the neighbouring mode's job) | A shape bug, not a wording bug: split the divergent outcomes into `references/`, one file per path, and give the body a dispatch table naming exactly one file per mode. Rewording the paragraph does not fix adjacency. |
16
+ | **Too long / bloated** | Extract conditional content to `references/`, or delete what never gets used. Never delete a hard rule to save lines. |
17
+ | **Wrong or stale steps** | Correct the workflow against the current tree — read the files the steps name before trusting them. |
18
+ | **Wrong scope** | Move it between internal, project, and user. Moving into the suite is a release; moving out means the next release drops the skill for everyone. |
19
+ | **Oversplit** (five topic files, vague routing) | Fold shared surfaces back into the body and keep one reference per outcome. |
20
+
21
+ If the request names no failure, ask for one. A retune without a failure is a rewrite with extra steps.
22
+
23
+ ## 3. Change that thing only
24
+
25
+ - One failure, the smallest edit that kills it, no drive-by rewrites or tidy-ups.
26
+ - Re-read the surrounding lines so the fix does not contradict a rule elsewhere in the file.
27
+ - If the fix moves content into `references/`, the body must dispatch to it by name and say to read only that one.
28
+
29
+ ## 4. Ship and re-verify
30
+
31
+ - Internal skill → `scripts/sync.sh` (commit, bump, tag, publish; say so before running it).
32
+ - Project or user skill → committed or written in place, as its location requires.
33
+ - Then run the skill's Verification section: `/reload`, no startup warnings, `/skill:<name>` behaves. A retune that was never invoked has not been verified.
@@ -0,0 +1,41 @@
1
+ # Mode: verify — read, judge, report, change nothing
2
+
3
+ Read the skill's shared sections first (locations, pi's rules, shape rule, checklist). This file is the read-only sweep.
4
+
5
+ **No writes. Not one.** No edits, no renames, no moving files between locations, no version bumps, no `scripts/sync.sh`. A verify run that "just fixes a typo while it is there" has become a retune without a named failure, and the user loses the report they asked for.
6
+
7
+ ## 1. Read the whole skill as the harness will
8
+
9
+ - `SKILL.md`, then every file under `references/` — you cannot judge routing without seeing what it routes to.
10
+ - Check the frontmatter parses and the directory name matches `name`.
11
+ - If it ships from the suite or a package, note the pinned version: verification is against what consumers actually got.
12
+
13
+ ## 2. Run the checklist
14
+
15
+ Walk the shared **Self-check checklist** item by item. For each, the evidence is the file, not an impression:
16
+
17
+ - Description: quote it and count the characters; does it name the *moment* it fires?
18
+ - References: every pointer resolves to a file that exists, and the body says read only one at a time.
19
+ - Shape: do the divergent paths sit in separate files, and is each shared surface back in the body?
20
+ - Leanness: is anything in the body only sometimes needed, or anything in a reference read on every run?
21
+
22
+ ## 3. Run the skill, if it is installed
23
+
24
+ `/reload`, then check pi's startup output for warnings, then `/skill:<name>`. Quote what it did. If it cannot be invoked here — different harness, uninstalled, needs credentials — say that plainly instead of implying a pass.
25
+
26
+ ## 4. Report in one shape
27
+
28
+ ```md
29
+ **<skill name> — <verdict: sound | needs a retune | malformed>**
30
+
31
+ **Passes**
32
+ - Each checklist item that held, with the evidence in a clause.
33
+
34
+ **Fails**
35
+ - `<checklist item>`: what is wrong, `path:line`, and the one-line fix a retune would make.
36
+
37
+ **Unverified**
38
+ - What you could not check here, and why.
39
+ ```
40
+
41
+ Then stop. Name the retunes you would make; do not make them. If the user wants one, that is a new run in `mode:retune`, with the failure named.