[READ-ONLY] Mirror of https://github.com/bombshell-dev/tools. Internal CLI to standardize tooling across all Bombshell projects
0

Configure Feed

Select the types of activity you want to include in your feed.

ref(skills): update stale skills

Nate Moore (Mar 26, 2026, 9:38 PM EDT) 85c8ad55 7c8c389f

+179 -31
+91 -24
skills/migrate/SKILL.md
··· 2 2 name: migrate 3 3 description: > 4 4 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" 16 18 --- 17 19 18 20 # @bomb.sh/tools — Migration Checklist ··· 22 24 ## Step 1: Inventory Existing Tools 23 25 24 26 Check what the project currently uses: 27 + 25 28 - Build: tsup, unbuild, rollup, custom scripts, raw tsc? 26 29 - Lint: eslint, biome, tslint? 27 30 - 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? 29 34 - Type check: tsc directly? 30 35 31 36 ## Step 2: Add @bomb.sh/tools ··· 38 43 39 44 For each tool that maps directly: 40 45 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` | 48 54 49 55 ## Step 4: Add Unimplemented Commands 50 56 51 57 If the project didn't have lint or format before, add them now: 52 58 53 59 Update package.json scripts: 60 + 54 61 ```json 55 62 { 56 63 "scripts": { ··· 66 73 ## Step 5: Remove Old Config Files 67 74 68 75 Delete these if present: 76 + 69 77 - .prettierrc, .prettierrc.json, .prettierrc.yaml, prettier.config.js 70 78 - biome.json, biome.jsonc 71 79 - .eslintrc, .eslintrc.json, .eslintrc.yaml, eslint.config.js, eslint.config.mjs 72 80 - rollup.config.js, rollup.config.mjs 73 81 - tsup.config.ts, tsup.config.js 74 82 - unbuild.config.ts, build.config.ts 83 + - vitest.config.ts, vitest.config.js, vitest.config.mjs 84 + - jest.config.js, jest.config.ts 75 85 76 86 ## Step 6: Remove Old Dependencies 77 87 78 88 Remove from devDependencies: 89 + 79 90 - prettier, eslint, biome, @biomejs/biome 80 91 - tsup, unbuild, rollup and rollup plugins 81 92 - eslint plugins and configs 82 93 - prettier plugins 94 + - vitest, vitest-ansi-serializer, any vitest plugins 95 + - jest, @jest/types, jest transforms and presets 83 96 - Any TypeScript runners: tsx, ts-node, esbuild-register 84 97 85 98 ## Step 7: Move Tests to Colocated Pattern 86 99 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) 89 103 - Use .test.ts for runtime, .test-d.ts for type-level 90 104 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 92 149 93 150 Run through the full lifecycle to confirm migration: 151 + 94 152 ```sh 95 153 pnpm run test # Tests still pass 96 154 pnpm run lint # No unexpected violations ··· 111 169 - Correct: `"lint": "bsh lint"` 112 170 - Old scripts bypass the unified bsh pipeline. 113 171 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 116 183 - Correct: Tests colocated next to source files as .test.ts 117 184 - Bombshell convention requires colocated tests for readability. 118 185
+88 -7
skills/test/SKILL.md
··· 1 1 --- 2 2 name: test 3 3 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. 8 9 metadata: 9 10 type: core 10 11 library: '@bomb.sh/tools' 11 - library_version: '0.2.8' 12 + library_version: '0.3.1' 12 13 requires: 13 14 - lifecycle 14 15 sources: 15 16 - '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' 17 18 --- 18 19 19 20 # Test 20 21 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. 22 23 23 24 ## Setup 25 + 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. 24 27 25 28 Run the full test suite: 26 29 ··· 136 139 } 137 140 ``` 138 141 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 + 139 195 ### Type-Level Tests 140 196 141 197 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. ··· 247 303 const result = await processConfig(fixture.root); 248 304 expect(result.entry).toBe("src/index.ts"); 249 305 }); 306 + ``` 307 + 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" } }); }); 250 331 ``` 251 332 252 333 ### HIGH: Running vitest directly