@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.
Files changed (28) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/bin/install.js +135 -0
  4. package/package.json +39 -0
  5. package/skills/README.md +18 -0
  6. package/skills/engineering/commit/SKILL.md +47 -0
  7. package/skills/engineering/implement-ruby/template.md +75 -0
  8. package/skills/engineering/ticket-grooming/SKILL.md +58 -0
  9. package/skills/incubator/qrspi-design/SKILL.md +131 -0
  10. package/skills/incubator/qrspi-implement/SKILL.md +123 -0
  11. package/skills/incubator/qrspi-plan/SKILL.md +113 -0
  12. package/skills/incubator/qrspi-question/SKILL.md +184 -0
  13. package/skills/incubator/qrspi-research/SKILL.md +109 -0
  14. package/skills/incubator/qrspi-research-resolve/SKILL.md +94 -0
  15. package/skills/incubator/qrspi-structure/SKILL.md +116 -0
  16. package/skills/incubator/qrspi-test-plan/SKILL.md +253 -0
  17. package/skills/incubator/qrspi-test-plan/references/example-test-plan.md +151 -0
  18. package/skills/productivity/brainstorm/SKILL.md +49 -0
  19. package/skills/productivity/brainstorm/references/assumption-mapping.md +24 -0
  20. package/skills/productivity/brainstorm/references/five-whys.md +20 -0
  21. package/skills/productivity/brainstorm/references/pre-mortem.md +21 -0
  22. package/skills/productivity/brainstorm/references/question-burst.md +23 -0
  23. package/skills/productivity/brainstorm/references/question-formulation-technique.md +27 -0
  24. package/skills/productivity/brainstorm/references/six-thinking-hats.md +24 -0
  25. package/skills/productivity/brainstorm/references/starbursting.md +19 -0
  26. package/skills/productivity/caveman/SKILL.md +49 -0
  27. package/skills/productivity/simple-english/SKILL.md +15 -0
  28. 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
+ }
@@ -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
+ ```