Skip to content

Commit 7fe9353

Browse files
authored
docs(skills): align lint/build/lifecycle skills with current bsh behavior (#55)
* docs(skills): align lint/build/lifecycle skills with current bsh behavior - lint skill: drop false publint-in-lint claim, document --strict/ --warnings/--format json, add remedies table, surface scoping notes - build skill: dts default, publint publish gate, entry error message - lifecycle skill: strict lint pass moves to PR handoff step * docs(skills): bump stale library_version metadata to 0.6.0 All skills claimed 0.3.1 while the package is at 0.5.6 and the pending changesets ship in 0.6.0.
1 parent 7a80756 commit 7fe9353

11 files changed

Lines changed: 133 additions & 45 deletions

File tree

.changeset/skills-updates.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@bomb.sh/tools': patch
3+
---
4+
5+
Updates the `lint`, `build`, and `lifecycle` skills to match current `bsh` behavior
6+
7+
The lint skill no longer claims publint runs in `pnpm run lint` (it gates `pnpm run build`), documents `--strict`, `--warnings`, and `--format json`, and adds a remedies table mapping common violations to their sanctioned fixes. The lifecycle skill moves the knip dead-code gate (`lint --strict`) to the PR handoff step.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ If you'd like to use this package for your own projects, please consider forking
1010
- `bsh test` command, using [`vitest`](https://vitest.dev/)
1111
- `bsh format` command, using [`oxfmt`](https://oxc.rs/docs/guide/usage/formatter)
1212
- `bsh lint` command, using [`oxlint`](https://oxc.rs/docs/guide/usage/linter), [`knip`](https://knip.dev), [`tsgo`](https://npmx.dev/@typescript/native-preview)
13-
- `bsh publint` command, using [`publint`](https://publint.dev/)
13+
- `bsh publint` command, using [`publint`](https://publint.dev/) (also runs automatically as a publish gate in `bsh build`)
1414
- `bsh sync` command, which links our shared [agent skills](#agent-skills) into your project
1515
- shared `tsconfig.json` file
1616

skills/build/SKILL.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
name: build
33
description: >
44
TypeScript to ESM compilation via tsdown with opinionated defaults. Sourcemaps,
5-
clean dist/, unbundled output. Flags: --dts, --bundle, --minify. Default entry
6-
src/**/*.ts. Use when building a package for publish or generating declarations.
5+
clean dist/, unbundled output, .d.mts types by default, publint publish gate.
6+
Flags: --no-dts, --bundle, --minify. Default entry src/**/*.ts. Use when
7+
building a package for publish or generating declarations.
78
metadata:
89
type: core
910
library: '@bomb.sh/tools'
10-
library_version: '0.3.1'
11+
library_version: '0.6.0'
1112
requires:
1213
- lifecycle
1314
sources:
@@ -31,28 +32,42 @@ pnpm run build
3132
- **Sourcemaps:** enabled
3233
- **Clean:** removes dist/ before building
3334
- **Unbundled** by default (each source file produces one output file)
35+
- **Types:** `.d.mts` declarations generated by default (via tsgo)
3436
- **Entry:** defaults to `src/**/*.ts`
3537
- **Config:** explicitly disabled (`config: false`) — tsdown.config.ts is ignored
3638

39+
## Publish gate
40+
41+
After a successful build, `bsh build` runs **publint** (strict mode) against
42+
the emitted `dist/` and fails the build on errors — broken `exports` targets,
43+
missing declaration files, and invalid `package.json` fields are caught here,
44+
not at publish time. Warnings and suggestions are advisory.
45+
46+
A failed gate after `--no-dts` almost always means `package.json` declares
47+
types that weren't emitted — either rebuild with types (the default) or fix
48+
the `exports` map.
49+
3750
## Flags
3851

3952
Pass flags after `--` in pnpm:
4053

4154
| Flag | Effect |
4255
|------|--------|
43-
| `--dts` | Generate `.d.mts` declaration files |
56+
| `--no-dts` | Skip `.d.mts` declaration generation (on by default) |
4457
| `--bundle` | Bundle into single output (disables unbundled mode) |
4558
| `--minify` | Minify output |
4659
| positional args | Custom entry points (replaces default `src/**/*.ts`) |
4760

4861
```sh
49-
pnpm run build -- --dts
62+
pnpm run build -- --no-dts
5063
pnpm run build -- --bundle
5164
pnpm run build -- --minify
5265
pnpm run build -- src/index.ts
53-
pnpm run build -- --dts --minify
5466
```
5567

68+
If no entry files match, the build fails with `No entry files matched: …`
69+
pass explicit entries or check that `src/` exists.
70+
5671
## Common Mistakes
5772

5873
### MEDIUM: Passing unnecessary flags

skills/dev/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: >
77
metadata:
88
type: core
99
library: '@bomb.sh/tools'
10-
library_version: '0.3.1'
10+
library_version: '0.6.0'
1111
requires:
1212
- lifecycle
1313
sources:

skills/format/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: >
77
metadata:
88
type: core
99
library: '@bomb.sh/tools'
10-
library_version: '0.3.1'
10+
library_version: '0.6.0'
1111
requires:
1212
- lifecycle
1313
sources:

skills/init/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: >
77
metadata:
88
type: core
99
library: '@bomb.sh/tools'
10-
library_version: '0.3.1'
10+
library_version: '0.6.0'
1111
sources:
1212
- 'bombshell-dev/tools:src/commands/init.ts'
1313
---

skills/lifecycle/SKILL.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description: >
88
metadata:
99
type: lifecycle
1010
library: '@bomb.sh/tools'
11-
library_version: '0.3.1'
11+
library_version: '0.6.0'
1212
sources:
1313
- 'bombshell-dev/tools:skills/lifecycle/SKILL.md'
1414
- 'bombshell-dev/tools:src/bin.ts'
@@ -27,7 +27,7 @@ All scripts proxy to `bsh <command>` via `package.json`. Never bypass them.
2727
| `pnpm run build` | `bsh build` | Build with tsdown (ESM, sourcemaps, clean) |
2828
| `pnpm run dev` | `bsh dev` | Watch mode with native Node TS transforms |
2929
| `pnpm run format` | `bsh format` | Format with oxfmt |
30-
| `pnpm run lint` | `bsh lint` | Parallel: oxlint + publint + knip + tsgo |
30+
| `pnpm run lint` | `bsh lint` | Parallel: oxlint + knip + tsgo |
3131
| `pnpm run test` | `bsh test` | Run tests with vitest (single run) |
3232
| `pnpm run init` | `bsh init` | Scaffold new project from template |
3333

@@ -101,6 +101,9 @@ pnpm run lint
101101
pnpm run lint -- --fix
102102
```
103103

104+
- [ ] Warnings are collapsed by default (they never fail the run). Expand them
105+
with `--warnings` when triaging.
106+
104107
### 4. Format
105108

106109
- [ ] Normalize code style:
@@ -111,7 +114,8 @@ pnpm run format
111114

112115
### 5. Build
113116

114-
- [ ] Verify the package compiles:
117+
- [ ] Verify the package compiles (types are generated by default) and passes
118+
the publint publish gate:
115119

116120
```sh
117121
pnpm run build
@@ -127,6 +131,13 @@ pnpm run test
127131

128132
### 7. PR Handoff
129133

134+
- [ ] Run the strict lint pass — this is the dead-code gate (knip unused
135+
exports/types/files) that doesn't run during the TDD loop:
136+
137+
```sh
138+
pnpm run lint -- --strict
139+
```
140+
130141
- [ ] Present a summary of changes to the human
131142
- [ ] **Human creates the PR** — agents do not create or merge PRs autonomously
132143

skills/lint/SKILL.md

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
---
22
name: lint
33
description: >
4-
Multi-tool linting pipeline: oxlint, publint, knip, tsgo run in parallel via
5-
pnpm run lint. Covers Bombshell conventions: URL over node:path, max 2 params
6-
with options bag, named exports only, import type, prefer node builtins, no
7-
console.log, no generic Error. Use when checking code quality or understanding
8-
lint violations.
4+
Multi-tool linting pipeline: oxlint, knip, and tsgo run in parallel via
5+
pnpm run lint (publint gates pnpm run build instead). Covers Bombshell
6+
conventions: URL over node:path, max 2 params with options bag, named
7+
exports only, import type, prefer node builtins, no console.log, no
8+
generic Error. Use when checking code quality or understanding lint
9+
violations.
910
metadata:
1011
type: core
1112
library: '@bomb.sh/tools'
12-
library_version: '0.3.1'
13+
library_version: '0.6.0'
1314
requires:
1415
- lifecycle
1516
sources:
@@ -20,32 +21,63 @@ metadata:
2021

2122
# Lint
2223

23-
Multi-tool linting pipeline. All four tools run in parallel with unified output.
24+
Multi-tool linting pipeline. oxlint, knip, and tsgo run in parallel with unified output.
2425

2526
## Setup
2627

2728
```sh
28-
pnpm run lint # Report violations
29-
pnpm run lint -- --fix # Auto-fix (oxlint only), then report remaining
30-
pnpm run lint -- src/foo.ts # Target specific files (default: ./src)
29+
pnpm run lint # Report errors (warnings collapsed to counts)
30+
pnpm run lint -- --warnings # Show warnings in full
31+
pnpm run lint -- --strict # Include knip dead-code checks (pre-commit gate)
32+
pnpm run lint -- --fix # Auto-fix (oxlint only), then report remaining
33+
pnpm run lint -- src/foo.ts # Target specific files (default: whole project)
34+
pnpm -s run lint -- --format json # Machine-readable report for agents/CI
3135
```
3236

33-
Do not run oxlint, publint, knip, or tsgo directly. Always use `pnpm run lint`.
37+
Do not run oxlint, knip, or tsgo directly. Always use `pnpm run lint`.
38+
(`--format json` needs `pnpm -s` to keep pnpm's banner out of stdout.)
3439

35-
See [lifecycle/SKILL.md](../lifecycle/SKILL.md) for where lint fits in the development workflow (step 5: after tests pass, before format).
40+
See [lifecycle/SKILL.md](../lifecycle/SKILL.md) for where lint fits in the development workflow (step 3: after tests pass, before format). Run `--strict` at PR handoff, not during the TDD loop.
3641

3742
## How It Works
3843

39-
`pnpm run lint` runs `bsh lint`, which executes four tools via `Promise.allSettled`:
44+
`pnpm run lint` runs `bsh lint`, which executes three tools via `Promise.allSettled`:
4045

4146
| Tool | What It Checks | Fix Support |
4247
|------|---------------|-------------|
4348
| **oxlint** | JS/TS linting via Rust-based engine with Bombshell config | Yes (`--fix`) |
44-
| **publint** | `package.json` exports, types, and field correctness (strict mode) | No |
45-
| **knip** | Unused dependencies, devDependencies, exports, types, files | No |
46-
| **tsgo** | TypeScript type errors (`--noEmit`, native Go compiler) | No |
49+
| **knip** | Unused dependencies/devDependencies (always); unused exports, types, files (`--strict` only) | No |
50+
| **tsgo** | TypeScript type errors (`--noEmit`, project mode) | No |
4751

48-
Results merge into a single report grouped by file. Exit code 1 if any errors exist.
52+
Results merge into a single report grouped by file. **Errors print in full;
53+
warnings collapse to a per-rule count** (they never affect the exit code —
54+
pass `--warnings` to expand them). Exit code 1 if any errors exist.
55+
56+
publint is deliberately not part of lint: its file-existence checks need
57+
`dist/`, so it runs as a publish gate in `pnpm run build` (see
58+
[build/SKILL.md](../build/SKILL.md)) and standalone via `pnpm run publint`.
59+
60+
## Remedies
61+
62+
The sanctioned fix for the most common violations. Do not improvise
63+
alternatives (e.g. sprinkling disable comments).
64+
65+
| Violation | Fix |
66+
|-----------|-----|
67+
| `tsc/TS2688` — Cannot find type definition file for 'node' | `pnpm add -D @types/node` |
68+
| `tsc/TS2591` — Cannot find name 'process'/'Buffer' | `pnpm add -D @types/node` |
69+
| `oxlint/eslint(no-restricted-imports)` | Use the `URL` API; `fileURLToPath()` only at third-party boundaries |
70+
| `oxlint/eslint(max-params)` / `bombshell-dev(max-params)` | Options bag with a typed interface. If conforming to a platform interface, say so with `override`/`implements` — the rule exempts those |
71+
| `oxlint/import(no-default-export)` | Use a named export |
72+
| `oxlint/bombshell-dev(no-generic-error)` | Define a project error class with a `code`; throw that |
73+
| `oxlint/bombshell-dev(exported-function-async)` | Only fires on public entry files: make it `async`, or move the export out of the public surface |
74+
| `oxlint/bombshell-dev(require-export-jsdoc)` | Only fires on public entry files: add a one-line `/** ... */` |
75+
| `knip/unused-dependency` | Remove it from `package.json` |
76+
| `knip/unused-export` (`--strict`) | Un-export it, or delete it if nothing consumes it |
77+
78+
Inline `// oxlint-disable` comments are a last resort for genuinely
79+
exceptional cases, never a workflow. If a rule is wrong for your project
80+
shape, raise it — the fix belongs upstream in `oxlintrc.json`.
4981

5082
## Core Patterns
5183

@@ -68,7 +100,12 @@ await thirdPartyLib(configPath);
68100

69101
### Options bag for >2 parameters
70102

71-
Functions must have at most 2 parameters. Use an options object for anything beyond that.
103+
Functions we author must have at most 2 parameters. Use an options object for anything beyond that.
104+
105+
Signatures conforming to an API you don't control are exempt — `override`
106+
methods, members of classes that `extends` or `implements`, and inline
107+
callbacks. If a platform interface forces more parameters on you, express the
108+
conformance (`override`, `implements`) and the rule stays silent.
72109

73110
```ts
74111
// Correct
@@ -144,7 +181,11 @@ Use `const` by default. Use `let` only when reassignment is necessary. `var` is
144181

145182
### Exported functions: `async`, explicit return types, JSDoc
146183

147-
All three are enforced (as warnings) on exported functions:
184+
All three are enforced (as warnings) on exported functions — but `async` and
185+
JSDoc only apply to the **public API surface**: files consumers can import,
186+
derived from `package.json` `exports`/`bin` (mapping `dist/` paths back to
187+
`src/`). Internal modules are exempt. Packages with no publish surface (apps,
188+
examples) are exempt entirely.
148189

149190
```ts
150191
// Correct
@@ -274,7 +315,7 @@ Builtin error constructors (`Error`, `TypeError`, `RangeError`, `ReferenceError`
274315

275316
## Tensions
276317

277-
- **Prototyping speed vs lint strictness**: During early prototyping (see [lifecycle](../lifecycle/SKILL.md)), you may want to move fast. The lint rules still apply -- write correct code from the start rather than fixing lint after the fact.
318+
- **Prototyping speed vs lint strictness**: During early prototyping (see [lifecycle](../lifecycle/SKILL.md)), you may want to move fast. The lint rules still apply -- write correct code from the start rather than fixing lint after the fact. Dead-code checks (knip unused exports/types/files) are deferred to `--strict` at PR handoff precisely so they don't fire mid-implementation.
278319
- **Opinionated defaults vs explicit config**: The lint config is intentionally strict and not configurable per-project. If a rule is wrong, change it in `oxlintrc.json` upstream.
279320

280321
## Reference

skills/lint/references/lint-rules.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,32 @@ Complete rule table for `oxlintrc.json` and custom Bombshell plugin rules.
1414
| `no-console` | warn | oxlint | Bans `console.log`; allows `console.info`, `warn`, `error`, `debug` |
1515
| `prefer-const` | error | oxlint | Use `const` when variable is never reassigned |
1616
| `no-var` | error | oxlint | No `var` declarations |
17-
| `max-params` | error | oxlint | Max 2 parameters per function |
1817
| `typescript/explicit-function-return-type` | warn | oxlint/typescript | Function declarations need return types (expressions exempt) |
1918
| `node/no-path-concat` | error | oxlint/node | No string concatenation with `__dirname`/`__filename` |
2019

20+
Deliberately disabled category defaults: `unicorn/consistent-function-scoping`, `no-underscore-dangle`.
21+
2122
## Bombshell Custom Plugin Rules
2223

2324
Defined in `rules/plugin.js`, registered as the `bombshell-dev` plugin.
2425

2526
| Rule | Severity | Description |
2627
|------|----------|-------------|
2728
| `bombshell-dev/no-generic-error` | error | No `throw new Error(...)` or other builtin error constructors. Use project-specific error classes. |
28-
| `bombshell-dev/require-export-jsdoc` | warn | Exported functions and classes must have a `/** ... */` JSDoc comment. |
29-
| `bombshell-dev/exported-function-async` | warn | Exported functions must use `async`. Adding async later is a breaking change. |
29+
| `bombshell-dev/max-params` | error | Max 2 parameters in authored signatures — use an options bag. Exempt: `override` methods, members of classes that `extends`/`implements`, inline callbacks. |
30+
| `bombshell-dev/require-export-jsdoc` | warn | Exported functions and classes must have a `/** ... */` JSDoc comment. **Public API surface only** (see below). |
31+
| `bombshell-dev/exported-function-async` | warn | Exported functions must use `async`. Adding async later is a breaking change. **Public API surface only** (see below). |
32+
33+
## Public API Surface Scoping
34+
35+
`require-export-jsdoc` and `exported-function-async` encode conventions that
36+
exist to prevent breaking changes for consumers — so they only apply to files
37+
consumers can import. `bsh lint` derives the public surface from
38+
`package.json` (`exports`, `bin`, `main`/`module`, mapping `dist/` paths back
39+
to `src/`), including conventional `packages/*/` workspace members, and scopes
40+
these rules to those files via oxlint `overrides`. Internal modules, packages
41+
without a publish surface (apps, examples), and wildcard passthrough exports
42+
(`"./*": "./dist/*"`) are exempt.
3043

3144
## oxlint Categories
3245

@@ -41,12 +54,13 @@ These apply in addition to individual rules:
4154

4255
`unicorn`, `typescript`, `oxc`, `import`, `node`, plus the custom `bombshell-dev` JS plugin.
4356

44-
## Other Tools in the Pipeline
57+
## Other Tools
4558

46-
| Tool | What It Catches |
47-
|------|----------------|
48-
| **publint** | Incorrect `package.json` exports, missing types, invalid fields |
49-
| **knip** | Unused dependencies, devDependencies, exports, types, files |
50-
| **tsgo** | TypeScript type errors (`--noEmit`) |
59+
| Tool | Where it runs | What It Catches |
60+
|------|---------------|-----------------|
61+
| **knip** | `bsh lint` | Unused dependencies/devDependencies (always); unused exports/types/files (`--strict` only) |
62+
| **tsgo** | `bsh lint` | TypeScript type errors (`--noEmit`, project mode) |
63+
| **publint** | `bsh build` (publish gate) and `bsh publint` | Incorrect `package.json` exports, missing types, invalid fields (strict mode) |
5164

52-
These tools have no configurable rules in this project. They run with defaults (publint in strict mode, knip configured in `package.json`).
65+
publint does not run in `bsh lint` — its file-existence checks need `dist/`,
66+
so it gates the build instead.

skills/migrate/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: >
1010
metadata:
1111
type: lifecycle
1212
library: "@bomb.sh/tools"
13-
library_version: "0.3.1"
13+
library_version: "0.6.0"
1414
requires:
1515
- lifecycle
1616
sources:

0 commit comments

Comments
 (0)