@ervis/skills 0.1.0
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/LICENSE +21 -0
- package/README.md +335 -0
- package/bin/install.js +135 -0
- package/package.json +39 -0
- package/skills/README.md +18 -0
- package/skills/engineering/commit/SKILL.md +47 -0
- package/skills/engineering/implement-ruby/template.md +75 -0
- package/skills/engineering/ticket-grooming/SKILL.md +58 -0
- package/skills/incubator/qrspi-design/SKILL.md +131 -0
- package/skills/incubator/qrspi-implement/SKILL.md +123 -0
- package/skills/incubator/qrspi-plan/SKILL.md +113 -0
- package/skills/incubator/qrspi-question/SKILL.md +184 -0
- package/skills/incubator/qrspi-research/SKILL.md +109 -0
- package/skills/incubator/qrspi-research-resolve/SKILL.md +94 -0
- package/skills/incubator/qrspi-structure/SKILL.md +116 -0
- package/skills/incubator/qrspi-test-plan/SKILL.md +253 -0
- package/skills/incubator/qrspi-test-plan/references/example-test-plan.md +151 -0
- package/skills/productivity/brainstorm/SKILL.md +49 -0
- package/skills/productivity/brainstorm/references/assumption-mapping.md +24 -0
- package/skills/productivity/brainstorm/references/five-whys.md +20 -0
- package/skills/productivity/brainstorm/references/pre-mortem.md +21 -0
- package/skills/productivity/brainstorm/references/question-burst.md +23 -0
- package/skills/productivity/brainstorm/references/question-formulation-technique.md +27 -0
- package/skills/productivity/brainstorm/references/six-thinking-hats.md +24 -0
- package/skills/productivity/brainstorm/references/starbursting.md +19 -0
- package/skills/productivity/caveman/SKILL.md +49 -0
- package/skills/productivity/simple-english/SKILL.md +15 -0
- package/skills/research/.gitkeep +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ervis Zyka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Ervis Zyka's Skills
|
|
2
|
+
|
|
3
|
+
Agent skills I use day to day - engineering, productivity and research.
|
|
4
|
+
|
|
5
|
+
Runtime-neutral: plain `SKILL.md` files with no harness-specific tool names, so
|
|
6
|
+
they work on Claude Code, Codex, and anything else that speaks Agent Skills.
|
|
7
|
+
The exception is the `incubator/` bucket: those skills require specific
|
|
8
|
+
subagents and skills, and stop if one is missing (see [Incubator](#incubator)).
|
|
9
|
+
|
|
10
|
+
## Skills
|
|
11
|
+
|
|
12
|
+
### Engineering
|
|
13
|
+
|
|
14
|
+
| Skill | What it does |
|
|
15
|
+
|---|---|
|
|
16
|
+
| [`commit`](./skills/engineering/commit) | Groups the session's changes into focused commits with clear messages, shows the plan, and commits only after you approve. Adds no agent attribution. |
|
|
17
|
+
| [`ticket-grooming`](./skills/engineering/ticket-grooming) | Challenges a ticket until a coding agent could build it with zero open questions. Verifies the ticket's claims against the real code, then writes ranked blocking questions plus a rewritten dev-ready ticket. |
|
|
18
|
+
|
|
19
|
+
### Productivity
|
|
20
|
+
|
|
21
|
+
| Skill | What it does |
|
|
22
|
+
|---|---|
|
|
23
|
+
| [`brainstorm`](./skills/productivity/brainstorm) | Runs a structured brainstorm with a framework picked to fit: starbursting, QFT, question burst, pre-mortem, assumption mapping, 5 whys or six thinking hats. For scoping research it chains starbursting, pre-mortem and assumption mapping, then QFT. Saves the result to the vault under `brainstorm/`. |
|
|
24
|
+
| [`caveman`](./skills/productivity/caveman) | Ultra-terse reply mode that cuts about 75% of tokens by dropping filler while keeping full technical accuracy. Stays on until you say "stop caveman" or "normal mode". |
|
|
25
|
+
| [`simple-english`](./skills/productivity/simple-english) | Writes responses in ASD-STE100 Simplified Technical English: short sentences, active voice, one idea per sentence, simple words. |
|
|
26
|
+
|
|
27
|
+
### Research
|
|
28
|
+
|
|
29
|
+
Nothing here yet.
|
|
30
|
+
|
|
31
|
+
### Incubator
|
|
32
|
+
|
|
33
|
+
Skills being reworked. The QRSPI workflow lives here: eight skills, run one
|
|
34
|
+
after the other on a task directory that holds all the files of one task.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
task.md -> qrspi-question -> qrspi-research -> qrspi-research-resolve
|
|
38
|
+
-> qrspi-design -> qrspi-structure -> qrspi-plan -> qrspi-test-plan
|
|
39
|
+
-> qrspi-implement
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The flow only moves forward. Each skill takes the task directory as its first
|
|
43
|
+
argument, for example `qrspi-question ~/wiki/rate-limit`, and names the next
|
|
44
|
+
skill when it is done. You write `task.md`; the skills write the rest.
|
|
45
|
+
|
|
46
|
+
| Skill | What it does |
|
|
47
|
+
|---|---|
|
|
48
|
+
| [`qrspi-question`](./skills/incubator/qrspi-question) | Turns `task.md` into neutral research questions with the clean room method: it knows the goal, the researcher must not. Finds the affected areas and blind spots (same-shape features, producers and consumers, cascades), asks a fixed set of facets per area, and leak-tests the result. The number of questions comes from coverage, not a quota. |
|
|
49
|
+
| [`qrspi-research`](./skills/incubator/qrspi-research) | Answers `questions.md` blind, with facts only: every finding cites `file:line` or a URL. Writes `research-draft.md`. You can add a missing question before it hands off. |
|
|
50
|
+
| [`qrspi-research-resolve`](./skills/incubator/qrspi-research-resolve) | Grades each answer. Only when an answer is weak, contradictory or open does it interview you; you answer or skip each gap. Writes the final `research.md`. Research is done after this step. |
|
|
51
|
+
| [`qrspi-design`](./skills/incubator/qrspi-design) | Interviews you on the design decisions with the research as evidence, and writes `design.md`. Prefers patterns the code already uses and marks each decision as existing (with the `file:line` that already does it) or new (with the reason). Groups the current state into invariants, assumptions, cascades, dependents and lifecycle. |
|
|
52
|
+
| [`qrspi-structure`](./skills/incubator/qrspi-structure) | Breaks the design into vertical slices, each with its files, key signatures and a check, plus the invariants and dependents it touches. Writes `structure.md`. |
|
|
53
|
+
| [`qrspi-plan`](./skills/incubator/qrspi-plan) | Expands each slice into exact changes, code snippets where they are not obvious, and checks with checkboxes. Writes `plan.md`, which an agent can work from alone. |
|
|
54
|
+
| [`qrspi-test-plan`](./skills/incubator/qrspi-test-plan) | Writes the black-box test cases, in plain words, that guard the scope and the design: one goal case per slice, and exhaustive Given / When / Then cases at each public interface (anything a client depends on, behavior and data). Reads the design and the slices, not `plan.md`, so the tests check the code independently. Lists the expected contract changes, so implement can tell an expected failure from a bug. Writes `test-plan.md`; implement writes the tests from it. |
|
|
55
|
+
| [`qrspi-implement`](./skills/incubator/qrspi-implement) | Works through `plan.md` one slice at a time, and writes the code and the tests for the test cases of `test-plan.md`: a slice is done when its checks and its tests pass. Ticks checkboxes, makes one commit per slice, and changes an existing test only for a listed contract change. Asks you only for the checks by hand. |
|
|
56
|
+
|
|
57
|
+
These skills require:
|
|
58
|
+
|
|
59
|
+
- `simple-english` from this package.
|
|
60
|
+
- The subagents `codebase-locator`, `codebase-analyzer`, `codebase-pattern-finder`
|
|
61
|
+
and `web-search-researcher` from [`agents/`](./agents). They are Claude Code
|
|
62
|
+
only and are not in the npm package: install them with
|
|
63
|
+
`./scripts/link-skills.sh` (see [Local dev](#local-dev)).
|
|
64
|
+
- `grilling` from [Matt Pocock's skills](#complementary-skills), for the
|
|
65
|
+
interviews in `qrspi-research-resolve` and `qrspi-design`.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
For a new laptop. One command, no clone, no npm account.
|
|
70
|
+
|
|
71
|
+
### Prerequisites
|
|
72
|
+
|
|
73
|
+
- Node.js 18 or newer and npm (`node --version`, `npm --version`). Any current
|
|
74
|
+
Node install includes `npx`.
|
|
75
|
+
- No npm account or login: the package is public.
|
|
76
|
+
|
|
77
|
+
### Install the skills
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx @ervis/skills@latest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`@latest` makes npx fetch the newest release instead of reusing an old cached
|
|
84
|
+
one. The installer copies every skill into two places:
|
|
85
|
+
|
|
86
|
+
| Directory | Read by |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `~/.claude/skills` | Claude Code |
|
|
89
|
+
| `~/.agents/skills` | Codex and other Agent Skills harnesses |
|
|
90
|
+
|
|
91
|
+
Each skill lands as a plain directory named after the skill, for example
|
|
92
|
+
`~/.claude/skills/ticket-grooming`, with a `.ervis-skills` marker file inside.
|
|
93
|
+
The marker is how a later run knows the copy is its own.
|
|
94
|
+
|
|
95
|
+
To see what it would do first, without touching anything:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx @ervis/skills@latest --dry-run
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Complementary skills
|
|
102
|
+
|
|
103
|
+
[Matt Pocock's skills](https://github.com/mattpocock/skills) cover engineering
|
|
104
|
+
workflows this package does not - TDD, diagnosing bugs, resolving merge
|
|
105
|
+
conflicts, domain modelling - and are worth installing alongside this package
|
|
106
|
+
rather than instead of it:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx skills@latest add mattpocock/skills
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The installer lets you pick which skills to take and which agents to install
|
|
113
|
+
them on. This writes them into your repo as plain files, the same way
|
|
114
|
+
`@ervis/skills` does, so both sets stay editable and neither manages the other.
|
|
115
|
+
|
|
116
|
+
### Flags
|
|
117
|
+
|
|
118
|
+
| Flag | Effect |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `--dry-run` | Print what would be installed or updated, change nothing. |
|
|
121
|
+
| `--target <dir>` | Install into `<dir>` instead of the two defaults. Repeatable. |
|
|
122
|
+
| `--force` | Also replace a skill that was not installed by this tool. |
|
|
123
|
+
| `-h`, `--help` | Show usage. |
|
|
124
|
+
|
|
125
|
+
Overwrite behavior is deliberately conservative:
|
|
126
|
+
|
|
127
|
+
- A skill this tool installed earlier (it has the marker) is replaced in place.
|
|
128
|
+
The new copy is built next to the old one and swapped in, so a failed update
|
|
129
|
+
leaves the old skill intact.
|
|
130
|
+
- A skill directory or symlink that already exists without the marker - your own
|
|
131
|
+
skill of the same name, or a link from the local dev path below - is skipped,
|
|
132
|
+
with a message. Pass `--force` to replace it.
|
|
133
|
+
- Other skills in the target directories are never touched.
|
|
134
|
+
|
|
135
|
+
### Verify it worked
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
ls ~/.claude/skills ~/.agents/skills
|
|
139
|
+
find ~/.claude/skills ~/.agents/skills -maxdepth 2 -name .ervis-skills
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The first lists the installed skills, the second lists the marker of every copy
|
|
143
|
+
managed by this tool. Then start a new agent session: skills are read at session
|
|
144
|
+
start, so an already-running session will not see them.
|
|
145
|
+
|
|
146
|
+
### Update
|
|
147
|
+
|
|
148
|
+
Run the same command again:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx @ervis/skills@latest
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Managed copies are reported as `updated`. Nothing updates in the background.
|
|
155
|
+
|
|
156
|
+
### Uninstall
|
|
157
|
+
|
|
158
|
+
There is no uninstall flag. Remove the managed copies, which are exactly the
|
|
159
|
+
directories that contain the marker:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
find ~/.claude/skills ~/.agents/skills -maxdepth 2 -name .ervis-skills -exec dirname {} \; | while read -r d; do rm -r "$d"; done
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Run it without `rm -r "$d"` (use `echo "$d"`) first if you want to review the
|
|
166
|
+
list. Skills you installed some other way have no marker and are left alone.
|
|
167
|
+
|
|
168
|
+
### Troubleshooting
|
|
169
|
+
|
|
170
|
+
- **A skill says `skipped ... not installed by ervis-skills`.** A directory or
|
|
171
|
+
symlink with that name already exists and was not put there by this tool.
|
|
172
|
+
Move it away, or re-run with `--force` to replace it.
|
|
173
|
+
- **Permission denied.** The target directory is not writable by your user.
|
|
174
|
+
Check ownership with `ls -ld ~/.claude/skills ~/.agents/skills`, fix it, or
|
|
175
|
+
install somewhere you own with `--target`. Do not use `sudo`: it would leave
|
|
176
|
+
root-owned files in your home directory.
|
|
177
|
+
- **You keep getting an old version.** npx caches packages. Always use
|
|
178
|
+
`@latest`; if it still looks stale, clear the cache with
|
|
179
|
+
`npm cache clean --force` and run again.
|
|
180
|
+
- **Errors mentioning `node:fs`, `cpSync` or a syntax error.** Your Node is too
|
|
181
|
+
old. Upgrade to 18 or newer (`node --version` to check).
|
|
182
|
+
- **Duplicate skill name error.** Two skills in the package share a directory
|
|
183
|
+
name. That is a packaging bug; report it rather than working around it.
|
|
184
|
+
- **`404` or `E404` for `@ervis/skills`.** The package has not been published
|
|
185
|
+
yet, or the name is mistyped.
|
|
186
|
+
|
|
187
|
+
### Local dev
|
|
188
|
+
|
|
189
|
+
For working on this repo itself. Symlinks instead of copies, so `git pull` is all
|
|
190
|
+
it takes to stay current:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
./scripts/link-skills.sh
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
It links every skill into `~/.claude/skills` and `~/.agents/skills`, and every
|
|
197
|
+
subagent (`agents/<name>/AGENT.md`) into `~/.claude/agents/<name>.md`. Agents
|
|
198
|
+
are Claude Code only and are not part of the npm package. Do not
|
|
199
|
+
combine it with the npm install for the same skills: the installer skips the
|
|
200
|
+
links unless you pass `--force`, and `--force` replaces them with copies. To go
|
|
201
|
+
back, delete the links (`rm ~/.claude/skills/<skill-name>`).
|
|
202
|
+
|
|
203
|
+
## Layout
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
skills/<bucket>/<skill-name>/SKILL.md
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Buckets are `engineering/`, `productivity/`, `research/` and `incubator/` - see
|
|
210
|
+
[`skills/README.md`](./skills/README.md) for what belongs where. They are for
|
|
211
|
+
humans reading the repo and appear nowhere in how a skill is addressed: the
|
|
212
|
+
skill name comes from its own directory.
|
|
213
|
+
|
|
214
|
+
Subagents live beside `skills/` at `agents/<name>/AGENT.md`.
|
|
215
|
+
|
|
216
|
+
## Working on the skills
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
./scripts/list-skills.sh # every SKILL.md in the repo
|
|
220
|
+
./scripts/check-skills.sh # frontmatter and name/dir match
|
|
221
|
+
./scripts/link-skills.sh # install locally as symlinks
|
|
222
|
+
./scripts/setup-skills.sh # install Matt's and these skills with npm
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`setup-skills.sh` installs Matt Pocock's published skills (with
|
|
226
|
+
`npx skills add mattpocock/skills`) and the skills of this checkout (with
|
|
227
|
+
`bin/install.js`, the `@ervis/skills` installer). `--agent=` picks where:
|
|
228
|
+
`claude` (the default) installs into `~/.claude/skills`, `codex` (or
|
|
229
|
+
`chatgpt`) into `~/.agents/skills`, and `--agent=claude,codex` does both. For
|
|
230
|
+
`claude` it first uninstalls the `mattpocock-skills` Claude Code plugin, so the
|
|
231
|
+
same skills do not load twice. Matt's skills that are already there are left alone. The
|
|
232
|
+
`@ervis/skills` installer updates its own earlier copies and skips anything
|
|
233
|
+
else. `--force` installs everything again over what is there.
|
|
234
|
+
|
|
235
|
+
Run `check-skills.sh` before pushing. It catches the failures that are silent
|
|
236
|
+
and annoying to debug later: a skill whose frontmatter `name` drifted from its
|
|
237
|
+
directory, or a skill with missing frontmatter.
|
|
238
|
+
|
|
239
|
+
### Adding a skill to the package
|
|
240
|
+
|
|
241
|
+
1. Create `skills/<bucket>/<name>/SKILL.md` (the name must match the directory,
|
|
242
|
+
and be unique across buckets).
|
|
243
|
+
2. `./scripts/check-skills.sh`
|
|
244
|
+
3. `npm pack --dry-run` and confirm the new `SKILL.md` is in the list. There is
|
|
245
|
+
no manifest to edit: the package ships everything under `skills/` except
|
|
246
|
+
`deprecated/`, `in-progress/` and `draft/`.
|
|
247
|
+
4. Add a row to the skills table above, then release (see Publish).
|
|
248
|
+
|
|
249
|
+
## Publish
|
|
250
|
+
|
|
251
|
+
For the maintainer. The package is `@ervis/skills`, public, published to
|
|
252
|
+
npmjs.com. Agents and CI never run `npm login` or `npm publish`.
|
|
253
|
+
|
|
254
|
+
> **Publishing is public and hard to undo.** Every shipped skill becomes
|
|
255
|
+
> world-readable on the npm registry, even while the GitHub repo is private.
|
|
256
|
+
> npm restricts unpublishing (as a rule only a recent release with no
|
|
257
|
+
> dependents can be removed) and a published version number can never be
|
|
258
|
+
> reused. Treat every publish as permanent: inspect the tarball first.
|
|
259
|
+
|
|
260
|
+
### One-time setup
|
|
261
|
+
|
|
262
|
+
1. Create or confirm the npm account `ervis` at npmjs.com and verify its email.
|
|
263
|
+
2. Turn on two-factor authentication in the account settings on npmjs.com. Use
|
|
264
|
+
the "authorization and writes" level so publishing asks for a code.
|
|
265
|
+
3. Log in from your terminal and confirm who you are:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
npm login
|
|
269
|
+
npm whoami # should print: ervis
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
4. The scope `@ervis` is your username, so it is yours automatically. Access is
|
|
273
|
+
already `public` via `publishConfig` in `package.json`; scoped packages
|
|
274
|
+
default to private without it, and the first publish would otherwise fail.
|
|
275
|
+
|
|
276
|
+
### Release a version
|
|
277
|
+
|
|
278
|
+
1. Get on a clean, up-to-date branch with the changes merged.
|
|
279
|
+
2. Bump the version. npm refuses to republish a version, so every release needs
|
|
280
|
+
a new one:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
npm version patch --no-git-tag-version # or minor / major
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Commit the `package.json` change with a message that says what changed.
|
|
287
|
+
`CHANGELOG.md` is generated, so do not edit it by hand: the commit messages
|
|
288
|
+
and PR title are the release note.
|
|
289
|
+
3. Inspect what will ship:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
npm pack --dry-run # file list and sizes
|
|
293
|
+
npm pack && tar tzf ervis-skills-*.tgz # the actual tarball contents
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
It should hold only `bin/`, `skills/` (no `deprecated/`, `in-progress/` or `draft/`),
|
|
297
|
+
`package.json`, `README.md` and `LICENSE`. Delete the `.tgz` afterwards.
|
|
298
|
+
4. Try the tarball the way a new laptop would, in a throwaway home:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
HOME=$(mktemp -d) npx ./ervis-skills-<version>.tgz
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
5. Run the release script:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
./scripts/release.sh --dry-run # stops after the checks and pack
|
|
308
|
+
./scripts/release.sh # same, then asks y/N before publishing
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
It runs, in order: `./scripts/check-skills.sh`, `npm pack --dry-run`, a
|
|
312
|
+
`Publish @ervis/skills@<version>? [y/N]` prompt, then `npm publish`.
|
|
313
|
+
Anything but `y` aborts.
|
|
314
|
+
|
|
315
|
+
### Verify after publishing
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
npm view @ervis/skills version
|
|
319
|
+
HOME=$(mktemp -d) npx @ervis/skills@latest
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
The first should print the version you just released; the second installs into
|
|
323
|
+
an empty home, exactly like a new laptop. Registry caches can lag by a minute or
|
|
324
|
+
two, so retry before assuming it failed.
|
|
325
|
+
|
|
326
|
+
### Publish a fix
|
|
327
|
+
|
|
328
|
+
A published version is frozen. Fix the problem on a branch, merge it, bump the
|
|
329
|
+
version again (`npm version patch --no-git-tag-version`), and run the release
|
|
330
|
+
script. If a release is actively harmful, `npm deprecate @ervis/skills@<version>
|
|
331
|
+
"<reason>"` warns everyone who installs it without removing it.
|
|
332
|
+
|
|
333
|
+
## Licence
|
|
334
|
+
|
|
335
|
+
MIT
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Copies every published skill into the skill directories each agent harness
|
|
5
|
+
// reads. Dependency-free on purpose: `npx @ervis/skills` has to work on a fresh
|
|
6
|
+
// laptop with nothing but Node.
|
|
7
|
+
|
|
8
|
+
const fs = require('node:fs');
|
|
9
|
+
const os = require('node:os');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
|
|
12
|
+
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
13
|
+
const SKILLS_ROOT = path.join(PKG_ROOT, 'skills');
|
|
14
|
+
const MARKER = '.ervis-skills';
|
|
15
|
+
const SKIP_BUCKETS = new Set(['deprecated', 'in-progress', 'draft']);
|
|
16
|
+
const DEFAULT_TARGETS = [
|
|
17
|
+
path.join(os.homedir(), '.claude', 'skills'),
|
|
18
|
+
path.join(os.homedir(), '.agents', 'skills'),
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const USAGE = `Usage: ervis-skills [options]
|
|
22
|
+
|
|
23
|
+
Installs Ervis Zyka's agent skills into ~/.claude/skills and ~/.agents/skills.
|
|
24
|
+
Re-run it any time to update; copies it made earlier are replaced in place.
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--target <dir> Install into <dir> instead of the defaults (repeatable)
|
|
28
|
+
--dry-run Print what would happen and change nothing
|
|
29
|
+
--force Also replace skills it did not install (real dirs, symlinks)
|
|
30
|
+
-h, --help Show this help
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
const opts = { targets: [], dryRun: false, force: false };
|
|
35
|
+
for (let i = 0; i < argv.length; i++) {
|
|
36
|
+
const a = argv[i];
|
|
37
|
+
if (a === '--dry-run') opts.dryRun = true;
|
|
38
|
+
else if (a === '--force') opts.force = true;
|
|
39
|
+
else if (a === '-h' || a === '--help') opts.help = true;
|
|
40
|
+
else if (a === '--target') {
|
|
41
|
+
const v = argv[++i];
|
|
42
|
+
if (!v) throw new Error('--target needs a directory');
|
|
43
|
+
opts.targets.push(path.resolve(v));
|
|
44
|
+
} else if (a.startsWith('--target=')) {
|
|
45
|
+
opts.targets.push(path.resolve(a.slice('--target='.length)));
|
|
46
|
+
} else throw new Error(`unknown option: ${a}`);
|
|
47
|
+
}
|
|
48
|
+
if (opts.targets.length === 0) opts.targets = DEFAULT_TARGETS;
|
|
49
|
+
return opts;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function findSkills(dir, out = []) {
|
|
53
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
54
|
+
if (!entry.isDirectory() || entry.name === 'node_modules') continue;
|
|
55
|
+
if (SKIP_BUCKETS.has(entry.name)) continue;
|
|
56
|
+
const full = path.join(dir, entry.name);
|
|
57
|
+
if (fs.existsSync(path.join(full, 'SKILL.md'))) out.push({ name: entry.name, src: full });
|
|
58
|
+
else findSkills(full, out);
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function lstatOrNull(p) {
|
|
64
|
+
try {
|
|
65
|
+
return fs.lstatSync(p);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
if (e.code === 'ENOENT') return null;
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function install(skill, targetDir, opts) {
|
|
73
|
+
const dest = path.join(targetDir, skill.name);
|
|
74
|
+
const st = lstatOrNull(dest);
|
|
75
|
+
let action = 'install';
|
|
76
|
+
if (st) {
|
|
77
|
+
const ours = st.isDirectory() && fs.existsSync(path.join(dest, MARKER));
|
|
78
|
+
if (!ours && !opts.force) {
|
|
79
|
+
return `skipped ${dest} (not installed by ervis-skills; use --force to replace)`;
|
|
80
|
+
}
|
|
81
|
+
action = 'update';
|
|
82
|
+
}
|
|
83
|
+
if (opts.dryRun) return `would ${action} ${dest}`;
|
|
84
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
85
|
+
const staging = fs.mkdtempSync(path.join(targetDir, `.${skill.name}-`));
|
|
86
|
+
const backup = `${staging}.old`;
|
|
87
|
+
try {
|
|
88
|
+
fs.cpSync(skill.src, staging, { recursive: true });
|
|
89
|
+
fs.writeFileSync(path.join(staging, MARKER), 'Managed by @ervis/skills; re-run the installer to update.\n');
|
|
90
|
+
if (st) fs.renameSync(dest, backup);
|
|
91
|
+
try {
|
|
92
|
+
fs.renameSync(staging, dest);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
if (st) fs.renameSync(backup, dest);
|
|
95
|
+
throw e;
|
|
96
|
+
}
|
|
97
|
+
if (st) fs.rmSync(backup, { recursive: true, force: true });
|
|
98
|
+
} finally {
|
|
99
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
return `${action === 'install' ? 'installed' : 'updated'}`.padEnd(10) + dest;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function main() {
|
|
105
|
+
let opts;
|
|
106
|
+
try {
|
|
107
|
+
opts = parseArgs(process.argv.slice(2));
|
|
108
|
+
} catch (e) {
|
|
109
|
+
process.stderr.write(`error: ${e.message}\n\n${USAGE}`);
|
|
110
|
+
return 2;
|
|
111
|
+
}
|
|
112
|
+
if (opts.help) {
|
|
113
|
+
process.stdout.write(USAGE);
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
const skills = findSkills(SKILLS_ROOT);
|
|
117
|
+
if (skills.length === 0) {
|
|
118
|
+
process.stderr.write(`error: no skills found under ${SKILLS_ROOT}\n`);
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
const seen = new Map();
|
|
122
|
+
for (const skill of skills) {
|
|
123
|
+
if (seen.has(skill.name)) {
|
|
124
|
+
process.stderr.write(`error: duplicate skill name "${skill.name}": ${seen.get(skill.name)} and ${skill.src}\n`);
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
seen.set(skill.name, skill.src);
|
|
128
|
+
}
|
|
129
|
+
for (const targetDir of opts.targets) {
|
|
130
|
+
for (const skill of skills) console.log(install(skill, targetDir, opts));
|
|
131
|
+
}
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
process.exitCode = main();
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ervis/skills",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Ervis Zyka's agent skills - engineering, productivity and research. Runtime-neutral: Claude Code, Codex and any Agent Skills harness.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/ervis/skills.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"agent-skills",
|
|
12
|
+
"claude-code",
|
|
13
|
+
"codex",
|
|
14
|
+
"skills"
|
|
15
|
+
],
|
|
16
|
+
"bin": {
|
|
17
|
+
"ervis-skills": "bin/install.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin/",
|
|
21
|
+
"skills/",
|
|
22
|
+
"!skills/**/deprecated/",
|
|
23
|
+
"!skills/**/in-progress/",
|
|
24
|
+
"!skills/draft/",
|
|
25
|
+
"!skills/**/node_modules/"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"link": "./scripts/link-skills.sh",
|
|
35
|
+
"list": "./scripts/list-skills.sh",
|
|
36
|
+
"check": "./scripts/check-skills.sh",
|
|
37
|
+
"release": "./scripts/release.sh"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Skills
|
|
2
|
+
|
|
3
|
+
One directory per skill, grouped into buckets.
|
|
4
|
+
|
|
5
|
+
| Bucket | What belongs here |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `engineering/` | Working on code and the artefacts around it: specs, tickets, reviews, debugging, design, tests. |
|
|
8
|
+
| `productivity/` | Working on your own thinking and output: writing, planning, handoffs, learning, communication. |
|
|
9
|
+
| `research/` | Finding things out and recording them: investigating sources, exploring unfamiliar codebases, capturing what was found. |
|
|
10
|
+
| `incubator/` | Skills being reworked, such as the QRSPI workflow. Validated and published like any other bucket. |
|
|
11
|
+
| `draft/` | Unfinished imports, not validated and not published. See `AGENTS.md` for how to graduate one. |
|
|
12
|
+
|
|
13
|
+
Buckets are for humans reading the repo. They do not appear in how a skill is
|
|
14
|
+
addressed - a skill is addressed by its name, which comes from its own
|
|
15
|
+
directory.
|
|
16
|
+
|
|
17
|
+
If a skill genuinely fits two buckets, put it where you would go looking for it,
|
|
18
|
+
not where it is most technically correct.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create git commits with user approval and no Claude attribution
|
|
3
|
+
name: commit
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Commit Changes
|
|
7
|
+
|
|
8
|
+
If the `simple-english` skill is available, follow it for everything you write for the user.
|
|
9
|
+
|
|
10
|
+
You are tasked with creating git commits for the changes made during this session.
|
|
11
|
+
|
|
12
|
+
## Process:
|
|
13
|
+
|
|
14
|
+
1. **Think about what changed:**
|
|
15
|
+
- Review the conversation history and understand what was accomplished
|
|
16
|
+
- Run `git status` to see current changes
|
|
17
|
+
- Run `git diff` to understand the modifications
|
|
18
|
+
- Consider whether changes should be one commit or multiple logical commits
|
|
19
|
+
|
|
20
|
+
2. **Plan your commit(s):**
|
|
21
|
+
- Identify which files belong together
|
|
22
|
+
- Draft clear, descriptive commit messages
|
|
23
|
+
- Use imperative mood in commit messages
|
|
24
|
+
- Focus on why the changes were made, not just what
|
|
25
|
+
|
|
26
|
+
3. **Present your plan to the user:**
|
|
27
|
+
- List the files you plan to add for each commit
|
|
28
|
+
- Show the commit message(s) you'll use
|
|
29
|
+
- Ask: "I plan to create [N] commit(s) with these changes. Shall I proceed?"
|
|
30
|
+
|
|
31
|
+
4. **Execute upon confirmation:**
|
|
32
|
+
- Use `git add` with specific files (never use `-A` or `.`)
|
|
33
|
+
- Create commits with your planned messages
|
|
34
|
+
- Show the result with `git log --oneline -n [number]`
|
|
35
|
+
|
|
36
|
+
## Important:
|
|
37
|
+
- **NEVER add co-author information or Claude attribution**
|
|
38
|
+
- Commits should be authored solely by the user
|
|
39
|
+
- Do not include any "Generated with Claude" messages
|
|
40
|
+
- Do not add "Co-Authored-By" lines
|
|
41
|
+
- Write commit messages as if the user wrote them
|
|
42
|
+
|
|
43
|
+
## Remember:
|
|
44
|
+
- You have the full context of what was done in this session
|
|
45
|
+
- Group related changes together
|
|
46
|
+
- Keep commits focused and atomic when possible
|
|
47
|
+
- The user trusts your judgment - they asked you to commit
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Implementer agent template
|
|
2
|
+
|
|
3
|
+
Use this shape for any agent that takes a finished design and writes code.
|
|
4
|
+
Copy it and replace every `<placeholder>`.
|
|
5
|
+
|
|
6
|
+
Keep the agent file short. It holds the role, precedence, boundaries and handback.
|
|
7
|
+
Long style rules and exemplar files live in separate files it links to, so they
|
|
8
|
+
can change without rewriting the agent.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
```markdown
|
|
13
|
+
---
|
|
14
|
+
name: <role-name>
|
|
15
|
+
description: <what it does and when to use it, in one or two sentences, including the phrasings a user would type>
|
|
16
|
+
tools: <only what it needs>
|
|
17
|
+
model: <model>
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Role
|
|
21
|
+
|
|
22
|
+
<One paragraph. Who the agent is and what it does.>
|
|
23
|
+
It implements the design it is given. It does not design.
|
|
24
|
+
|
|
25
|
+
# Input contract
|
|
26
|
+
|
|
27
|
+
- Accepts: <design doc path, ticket, or spec with class and method sketches>.
|
|
28
|
+
- If the input is missing, ambiguous or incomplete, list the gaps and stop.
|
|
29
|
+
Do not invent design.
|
|
30
|
+
|
|
31
|
+
# Precedence
|
|
32
|
+
|
|
33
|
+
When rules conflict, follow them in this order:
|
|
34
|
+
|
|
35
|
+
1. The repo's own conventions (linter config, AGENTS.md, existing code).
|
|
36
|
+
2. The global house style below.
|
|
37
|
+
3. Language and framework defaults.
|
|
38
|
+
|
|
39
|
+
# Style
|
|
40
|
+
|
|
41
|
+
- Enforced by tools: <linter config that is the source of truth>.
|
|
42
|
+
- Judgment rules the linter cannot check: <naming, method shape, structure>.
|
|
43
|
+
One line each.
|
|
44
|
+
- Exemplars to imitate: <paths to 5 to 10 real files>.
|
|
45
|
+
|
|
46
|
+
# Working loop
|
|
47
|
+
|
|
48
|
+
1. Read the whole design.
|
|
49
|
+
2. Detect the project type and read the repo's conventions.
|
|
50
|
+
3. List gaps. Stop if any of them block the work.
|
|
51
|
+
4. Implement in small steps, writing tests with the code.
|
|
52
|
+
5. Run tests and linter. Fix until both are green.
|
|
53
|
+
|
|
54
|
+
# Boundaries
|
|
55
|
+
|
|
56
|
+
- Never design, widen scope, or refactor code the design does not mention.
|
|
57
|
+
- Never open a PR or merge.
|
|
58
|
+
- Never silence a linter rule to make it pass.
|
|
59
|
+
|
|
60
|
+
# Handback
|
|
61
|
+
|
|
62
|
+
Report back with:
|
|
63
|
+
|
|
64
|
+
- Files changed, one line each.
|
|
65
|
+
- Commands run and their results.
|
|
66
|
+
- Style conflicts flagged (design vs style, repo vs global).
|
|
67
|
+
- Gaps and assumptions.
|
|
68
|
+
- Anything left undone, and why.
|
|
69
|
+
|
|
70
|
+
# Stop and ask when
|
|
71
|
+
|
|
72
|
+
- The design is ambiguous about behavior.
|
|
73
|
+
- A change would touch code outside the design.
|
|
74
|
+
- Tests or linter cannot go green without changing the design.
|
|
75
|
+
```
|