Skip to content

Commit 85c8ad5

Browse files
committed
ref(skills): update stale skills
1 parent 7c8c389 commit 85c8ad5

File tree

2 files changed

+179
-31
lines changed

2 files changed

+179
-31
lines changed

skills/migrate/SKILL.md

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
name: migrate
33
description: >
44
Migrate existing project to bsh toolchain. Remove prettier, biome, eslint, tsup,
5-
unbuild, rollup configs and dependencies. Replace scripts with bsh equivalents.
6-
Consolidate to single @bomb.sh/tools devDependency. Migration order: check existing
7-
tools, add unimplemented commands, replace 1:1 commands, evaluate remaining, migrate
8-
one by one. Use when onboarding a project to the Bombshell ecosystem.
9-
type: lifecycle
10-
library: '@bomb.sh/tools'
11-
library_version: '0.2.8'
12-
requires:
13-
- lifecycle
14-
sources:
15-
- 'bombshell-dev/tools:skills/lifecycle/SKILL.md'
5+
unbuild, rollup, vitest configs and dependencies. Replace scripts with bsh equivalents.
6+
Adopt createMocks and createFixture from @bomb.sh/tools/test-utils. Consolidate to
7+
single @bomb.sh/tools devDependency. Migration order: inventory existing tools, add
8+
unimplemented commands, replace 1:1 commands, remove configs and deps, adopt test-utils,
9+
verify. Use when onboarding a project to the Bombshell ecosystem.
10+
metadata:
11+
type: lifecycle
12+
library: "@bomb.sh/tools"
13+
library_version: "0.3.1"
14+
requires:
15+
- lifecycle
16+
sources:
17+
- "bombshell-dev/tools:skills/lifecycle/SKILL.md"
1618
---
1719

1820
# @bomb.sh/tools — Migration Checklist
@@ -22,10 +24,13 @@ Run through each section when migrating a project to the bsh toolchain.
2224
## Step 1: Inventory Existing Tools
2325

2426
Check what the project currently uses:
27+
2528
- Build: tsup, unbuild, rollup, custom scripts, raw tsc?
2629
- Lint: eslint, biome, tslint?
2730
- Format: prettier, biome?
28-
- Test: vitest, jest, mocha?
31+
- Test: vitest, jest, mocha, node:test?
32+
- Test config: vitest.config.ts, jest.config.js, custom config?
33+
- Test mocks: manual vi.stubEnv, hand-rolled stream mocks, custom beforeAll/afterAll cleanup?
2934
- Type check: tsc directly?
3035

3136
## Step 2: Add @bomb.sh/tools
@@ -38,19 +43,21 @@ pnpm add -D @bomb.sh/tools
3843

3944
For each tool that maps directly:
4045

41-
| Old Tool | New Command | Notes |
42-
|----------|------------|-------|
43-
| vitest | pnpm run test | Likely already compatible |
44-
| prettier / biome format | pnpm run format | oxfmt replaces both |
45-
| eslint / biome lint | pnpm run lint | oxlint + publint + knip + tsgo |
46-
| tsup / unbuild / rollup | pnpm run build | tsdown with ESM defaults |
47-
| tsc --noEmit | pnpm run lint | Type checking included in lint |
46+
| Old Tool | New Command | Notes |
47+
| -------------------------------- | ------------------------------------------------ | --------------------------------- |
48+
| vitest | pnpm run test | Likely already compatible |
49+
| prettier / biome format | pnpm run format | oxfmt replaces both |
50+
| eslint / biome lint | pnpm run lint | oxlint + publint + knip + tsgo |
51+
| tsup / unbuild / rollup | pnpm run build | tsdown with ESM defaults |
52+
| tsc --noEmit | pnpm run lint | Type checking included in lint |
53+
| manual vi.stubEnv / stream mocks | `createMocks()` from `@bomb.sh/tools/test-utils` | Auto-cleanup via `onTestFinished` |
4854

4955
## Step 4: Add Unimplemented Commands
5056

5157
If the project didn't have lint or format before, add them now:
5258

5359
Update package.json scripts:
60+
5461
```json
5562
{
5663
"scripts": {
@@ -66,31 +73,82 @@ Update package.json scripts:
6673
## Step 5: Remove Old Config Files
6774

6875
Delete these if present:
76+
6977
- .prettierrc, .prettierrc.json, .prettierrc.yaml, prettier.config.js
7078
- biome.json, biome.jsonc
7179
- .eslintrc, .eslintrc.json, .eslintrc.yaml, eslint.config.js, eslint.config.mjs
7280
- rollup.config.js, rollup.config.mjs
7381
- tsup.config.ts, tsup.config.js
7482
- unbuild.config.ts, build.config.ts
83+
- vitest.config.ts, vitest.config.js, vitest.config.mjs
84+
- jest.config.js, jest.config.ts
7585

7686
## Step 6: Remove Old Dependencies
7787

7888
Remove from devDependencies:
89+
7990
- prettier, eslint, biome, @biomejs/biome
8091
- tsup, unbuild, rollup and rollup plugins
8192
- eslint plugins and configs
8293
- prettier plugins
94+
- vitest, vitest-ansi-serializer, any vitest plugins
95+
- jest, @jest/types, jest transforms and presets
8396
- Any TypeScript runners: tsx, ts-node, esbuild-register
8497

8598
## Step 7: Move Tests to Colocated Pattern
8699

87-
If tests are in __tests__/ or test/ directories, move them next to source:
88-
- __tests__/schema.test.ts → src/schema.test.ts (next to src/schema.ts)
100+
If tests are in **tests**/ or test/ directories, move them next to source:
101+
102+
- **tests**/schema.test.ts → src/schema.test.ts (next to src/schema.ts)
89103
- Use .test.ts for runtime, .test-d.ts for type-level
90104

91-
## Step 8: Verify
105+
## Step 8: Adopt Test Utilities
106+
107+
Replace manual mock setups with `createMocks` from `@bomb.sh/tools/test-utils`. It handles env stubbing, stream mocking, and auto-cleanup via `onTestFinished`.
108+
109+
**Environment mocking:**
110+
111+
```ts
112+
// Before: manual setup + cleanup
113+
import { vi, beforeEach, afterEach } from "vitest";
114+
115+
beforeEach(() => {
116+
vi.stubEnv("CI", "true");
117+
});
118+
afterEach(() => {
119+
vi.unstubAllEnvs();
120+
vi.restoreAllMocks();
121+
});
122+
123+
// After: createMocks handles it
124+
import { createMocks, type Mocks } from "@bomb.sh/tools/test-utils";
125+
126+
let mocks: Mocks;
127+
beforeEach(() => {
128+
mocks = createMocks({ env: { CI: "true" } });
129+
});
130+
```
131+
132+
**Stream mocking:**
133+
134+
```ts
135+
import { createMocks, type Mocks } from "@bomb.sh/tools/test-utils";
136+
137+
const mocks = createMocks({
138+
input: true, // MockReadable with defaults
139+
output: { columns: 120, isTTY: true }, // MockWritable
140+
env: { NO_COLOR: "1" },
141+
});
142+
// mocks.input — MockReadable (pushValue, close, isRaw, setRawMode)
143+
// mocks.output — MockWritable (buffer, resize, columns, rows)
144+
```
145+
146+
Also migrate any `createFixture` usage to import from `@bomb.sh/tools/test-utils` if currently using a local implementation.
147+
148+
## Step 9: Verify
92149

93150
Run through the full lifecycle to confirm migration:
151+
94152
```sh
95153
pnpm run test # Tests still pass
96154
pnpm run lint # No unexpected violations
@@ -111,8 +169,17 @@ pnpm run test # Final confirmation
111169
- Correct: `"lint": "bsh lint"`
112170
- Old scripts bypass the unified bsh pipeline.
113171

114-
3. **MEDIUM: Not moving tests to colocated pattern**
115-
- Wrong: Tests remain in __tests__/ directory after migration
172+
3. **HIGH: Keeping vitest.config.ts alongside bsh**
173+
- Wrong: Custom `vitest.config.ts` still exists alongside `@bomb.sh/tools`
174+
- Correct: Remove it — `bsh test` provides its own config (excludes `dist/`, enables ANSI snapshot serialization)
175+
- A project-level vitest config shadows the bsh defaults.
176+
177+
4. **MEDIUM: Manual mock cleanup instead of createMocks**
178+
- Wrong: `beforeAll`/`afterAll` with `vi.stubEnv`/`vi.unstubAllEnvs` scattered across test files
179+
- Correct: `createMocks({ env: { ... } })` — auto-cleans via `onTestFinished`
180+
181+
5. **MEDIUM: Not moving tests to colocated pattern**
182+
- Wrong: Tests remain in **tests**/ directory after migration
116183
- Correct: Tests colocated next to source files as .test.ts
117184
- Bombshell convention requires colocated tests for readability.
118185

skills/test/SKILL.md

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
---
22
name: test
33
description: >
4-
Vitest test runner with colocated .test.ts files and createFixture utility from
5-
@bomb.sh/tools/test-utils. Covers .test-d.ts type-level tests, inline fixture
6-
declarations, fixture API (root, resolve, text, json, write, isFile, isDirectory,
7-
list, cleanup). Use when writing or running tests in Bombshell projects.
4+
Vitest test runner with colocated .test.ts files and test utilities from
5+
@bomb.sh/tools/test-utils. Covers createFixture (temp directories, inline file trees,
6+
hfs API), createMocks (env stubbing, MockReadable/MockWritable streams, auto-cleanup),
7+
.test-d.ts type-level tests, and auto-loaded vitest config. Use when writing or
8+
running tests in Bombshell projects.
89
metadata:
910
type: core
1011
library: '@bomb.sh/tools'
11-
library_version: '0.2.8'
12+
library_version: '0.3.1'
1213
requires:
1314
- lifecycle
1415
sources:
1516
- 'bombshell-dev/tools:src/commands/test.ts'
16-
- 'bombshell-dev/tools:src/test-utils.ts'
17+
- 'bombshell-dev/tools:src/commands/test-utils/index.ts'
1718
---
1819

1920
# Test
2021

21-
Vitest test runner with colocated test files and a filesystem fixture utility.
22+
Vitest test runner with colocated test files, filesystem fixtures, and mock utilities.
2223

2324
## Setup
2425

26+
`bsh test` auto-loads its own vitest config — no `vitest.config.ts` needed in your project. The bundled config excludes `dist/`, sets `FORCE_COLOR=1`, and registers `vitest-ansi-serializer` for snapshot tests with ANSI output.
27+
2528
Run the full test suite:
2629

2730
```sh
@@ -136,6 +139,59 @@ The `symlink` helper creates a symbolic link:
136139
}
137140
```
138141

142+
### createMocks
143+
144+
Creates a mock test environment with streams and env vars. Cleanup is automatic via `onTestFinished` — no `beforeAll`/`afterAll` needed.
145+
146+
```ts
147+
import { describe, it, expect, beforeEach } from "vitest";
148+
import { createMocks, type Mocks } from "@bomb.sh/tools/test-utils";
149+
150+
describe("my-cli", () => {
151+
let mocks: Mocks;
152+
beforeEach(() => {
153+
mocks = createMocks({
154+
input: true, // MockReadable with defaults
155+
output: { columns: 120, isTTY: true }, // MockWritable
156+
env: { CI: "true", NO_COLOR: "1" },
157+
});
158+
});
159+
160+
it("writes output", () => {
161+
render(mocks.input, mocks.output);
162+
expect(mocks.output.buffer.join("")).toContain("hello");
163+
});
164+
});
165+
```
166+
167+
#### createMocks Options
168+
169+
| Option | Type | Description |
170+
|--------|------|-------------|
171+
| `env` | `Record<string, string \| undefined>` | Environment variables to stub for the test duration |
172+
| `input` | `true \| { isTTY?: boolean }` | Create a `MockReadable`. Pass `true` for defaults |
173+
| `output` | `true \| { columns?: number; rows?: number; isTTY?: boolean }` | Create a `MockWritable`. Defaults: 80×20, non-TTY |
174+
175+
#### MockReadable
176+
177+
| Member | Type | Description |
178+
|--------|------|-------------|
179+
| `isTTY` | `boolean` | Whether the stream is a TTY |
180+
| `isRaw` | `boolean` | Whether raw mode is enabled |
181+
| `setRawMode()` | `() => void` | Enable raw mode |
182+
| `pushValue(val)` | `(val: unknown) => void` | Push a value to the readable buffer |
183+
| `close()` | `() => void` | Signal end of stream |
184+
185+
#### MockWritable
186+
187+
| Member | Type | Description |
188+
|--------|------|-------------|
189+
| `buffer` | `string[]` | All written chunks as strings |
190+
| `isTTY` | `boolean` | Whether the stream is a TTY |
191+
| `columns` | `number` | Terminal width (default 80) |
192+
| `rows` | `number` | Terminal height (default 20) |
193+
| `resize(columns, rows)` | `(columns: number, rows: number) => void` | Resize and emit `"resize"` event |
194+
139195
### Type-Level Tests
140196

141197
Files ending in `.test-d.ts` run compile-time type assertions using `expectTypeOf` from vitest. No runtime code executes — these tests verify that types resolve correctly.
@@ -249,6 +305,31 @@ it("produces valid output from config", async () => {
249305
});
250306
```
251307

308+
### HIGH: Adding a vitest.config.ts
309+
310+
`bsh test` provides its own config. A project-level `vitest.config.ts` shadows the bsh defaults (ANSI serialization, dist exclusion, FORCE_COLOR).
311+
312+
```
313+
# Wrong
314+
vitest.config.ts exists in project root
315+
316+
# Correct
317+
No vitest config — bsh handles it
318+
```
319+
320+
### HIGH: Manual env/mock cleanup instead of createMocks
321+
322+
Use `createMocks` instead of manual `vi.stubEnv`/`vi.unstubAllEnvs` patterns. It auto-cleans via `onTestFinished`.
323+
324+
```ts
325+
// Wrong — manual lifecycle
326+
beforeEach(() => { vi.stubEnv("CI", "true"); });
327+
afterEach(() => { vi.unstubAllEnvs(); vi.restoreAllMocks(); });
328+
329+
// Correct
330+
beforeEach(() => { mocks = createMocks({ env: { CI: "true" } }); });
331+
```
332+
252333
### HIGH: Running vitest directly
253334

254335
Always use `pnpm run test`. The `bsh test` wrapper configures vitest correctly.

0 commit comments

Comments
 (0)