claude-toolkit 0.16.0 → 0.17.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/CHANGELOG.md +20 -0
- package/README.md +54 -13
- package/bin/cli.ts +75 -19
- package/package.json +6 -7
- package/src/generator.ts +64 -26
- package/src/refresh-hint.ts +95 -0
- package/bin/postinstall.mjs +0 -69
- package/docs/README.md +0 -59
- package/docs/agents/code-reviewer.md +0 -76
- package/docs/agents/github-workflow.md +0 -98
- package/docs/best-practices/capacitor/README.md +0 -64
- package/docs/best-practices/capacitor/capacitor-8.md +0 -60
- package/docs/best-practices/capacitor/capgo-setup.md +0 -151
- package/docs/best-practices/capacitor/channels-and-rollouts.md +0 -101
- package/docs/best-practices/capacitor/live-updates-ota.md +0 -75
- package/docs/best-practices/capacitor/security-encryption.md +0 -68
- package/docs/best-practices/solidjs/README.md +0 -43
- package/docs/best-practices/solidjs/anti-patterns.md +0 -166
- package/docs/best-practices/solidjs/component-patterns.md +0 -131
- package/docs/best-practices/solidjs/context-and-global-state.md +0 -131
- package/docs/best-practices/solidjs/control-flow.md +0 -124
- package/docs/best-practices/solidjs/data-fetching.md +0 -205
- package/docs/best-practices/solidjs/effects-and-lifecycle.md +0 -113
- package/docs/best-practices/solidjs/performance.md +0 -100
- package/docs/best-practices/solidjs/props-patterns.md +0 -100
- package/docs/best-practices/solidjs/reactivity-model.md +0 -104
- package/docs/best-practices/solidjs/signals-and-state.md +0 -78
- package/docs/best-practices/solidjs/stores-and-nested-state.md +0 -111
- package/docs/best-practices/solidjs/typescript-integration.md +0 -186
- package/docs/best-practices/testing/README.md +0 -84
- package/docs/best-practices/testing/playwright-e2e.md +0 -649
- package/docs/best-practices/testing/storybook-interaction.md +0 -455
- package/docs/best-practices/testing/vitest-unit.md +0 -451
- package/docs/best-practices/typescript/README.md +0 -45
- package/docs/best-practices/typescript/any-and-unknown.md +0 -73
- package/docs/best-practices/typescript/deriving-vs-decoupling.md +0 -83
- package/docs/best-practices/typescript/discriminated-unions.md +0 -75
- package/docs/best-practices/typescript/enums-alternatives.md +0 -72
- package/docs/best-practices/typescript/essential-patterns.md +0 -119
- package/docs/best-practices/typescript/generics-patterns.md +0 -105
- package/docs/best-practices/typescript/micro-opinions.md +0 -87
- package/docs/best-practices/typescript/runtime-validation.md +0 -62
- package/docs/best-practices/typescript/satisfies-operator.md +0 -100
- package/docs/best-practices/typescript/tsconfig-cheat-sheet.md +0 -160
- package/docs/best-practices/typescript/type-organization.md +0 -64
- package/docs/best-practices/typescript/type-vs-interface.md +0 -80
- package/docs/commands/code-quality.md +0 -36
- package/docs/commands/onboard.md +0 -63
- package/docs/commands/pr-review.md +0 -91
- package/docs/commands/pr-summary.md +0 -50
- package/docs/commands/proto-check.md +0 -59
- package/docs/commands/ticket.md +0 -56
- package/docs/skills/code-style.md +0 -26
- package/docs/skills/systematic-debugging.md +0 -70
- package/docs/skills/testing-patterns.md +0 -140
- package/docs/skills/typescript-conventions.md +0 -283
- package/docs/skills/verification-before-completion.md +0 -103
- package/docs/stacks/capacitor-ota.md +0 -145
- package/docs/stacks/cloudflare-d1-kv.md +0 -144
- package/docs/stacks/esnext-idioms.md +0 -25
- package/docs/stacks/i18n-typesafe.md +0 -141
- package/docs/stacks/playwright-patterns.md +0 -179
- package/docs/stacks/protobuf-contracts.md +0 -85
- package/docs/stacks/rust-wasm-patterns.md +0 -106
- package/docs/stacks/solidjs-patterns.md +0 -110
- package/docs/stacks/storybook-patterns.md +0 -177
- package/docs/stacks/vanilla-extract-patterns.md +0 -115
- package/docs/stacks/vite-vitest-patterns.md +0 -485
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Systematic Debugging
|
|
2
|
-
|
|
3
|
-
> Four-phase methodology for diagnosing and fixing bugs efficiently without guesswork. Use when investigating a bug, test failure, or unexpected behavior before proposing a fix
|
|
4
|
-
|
|
5
|
-
**Type:** Core Skill (always included)
|
|
6
|
-
**Source:** [`core/skills/ct-systematic-debugging/SKILL.md`](../core/skills/ct-systematic-debugging/SKILL.md)
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
A disciplined approach to debugging that replaces trial-and-error with structured investigation. Apply the four phases in order -- skipping phases leads to wasted time and incomplete fixes.
|
|
11
|
-
|
|
12
|
-
## Phases
|
|
13
|
-
|
|
14
|
-
### Phase 1: Observe
|
|
15
|
-
|
|
16
|
-
Reproduce the issue and gather evidence before forming any theories.
|
|
17
|
-
|
|
18
|
-
- **Reproduce reliably** -- find the minimal steps to trigger the bug
|
|
19
|
-
- **Read the actual error** -- full stack trace, error message, and relevant logs
|
|
20
|
-
- **Check recent changes** -- use `git log` and `git diff` to identify what changed
|
|
21
|
-
- **Gather context** -- note the environment, input data, user actions, and timing
|
|
22
|
-
- **Record observations** -- write down what you see, not what you think is happening
|
|
23
|
-
|
|
24
|
-
### Phase 2: Hypothesize
|
|
25
|
-
|
|
26
|
-
Form theories based on evidence, not intuition.
|
|
27
|
-
|
|
28
|
-
- **List possible causes** -- generate at least 2-3 hypotheses before investigating any
|
|
29
|
-
- **Rank by likelihood** -- what changed recently? What is the simplest explanation?
|
|
30
|
-
- **Consider the data flow** -- trace the path from input to error
|
|
31
|
-
- **Check assumptions** -- the bug is often in the code you trust most
|
|
32
|
-
|
|
33
|
-
### Phase 3: Test
|
|
34
|
-
|
|
35
|
-
Isolate variables and verify one hypothesis at a time.
|
|
36
|
-
|
|
37
|
-
- **Test one thing at a time** -- change a single variable per experiment
|
|
38
|
-
- **Use the smallest possible test** -- write a minimal reproduction
|
|
39
|
-
- **Add logging at boundaries** -- log inputs and outputs at function boundaries
|
|
40
|
-
- **Disprove hypotheses** -- design tests that would show the hypothesis is wrong
|
|
41
|
-
- **Binary search large spaces** -- bisect systematically when the problem could be anywhere
|
|
42
|
-
|
|
43
|
-
### Phase 4: Fix
|
|
44
|
-
|
|
45
|
-
Apply the minimal correct fix, then verify thoroughly.
|
|
46
|
-
|
|
47
|
-
- **Fix the root cause, not the symptom** -- if a null check prevents a crash but the value should never be null, fix the source
|
|
48
|
-
- **Make the smallest change possible** -- large fixes introduce new bugs
|
|
49
|
-
- **Verify the fix** -- run the reproduction case and confirm the bug is gone
|
|
50
|
-
- **Check for regressions** -- run the full test suite
|
|
51
|
-
- **Add a test for the bug** -- prevent the same class of bug from recurring
|
|
52
|
-
- **Document the fix** -- explain what caused the bug and why the fix is correct in the commit message
|
|
53
|
-
|
|
54
|
-
## Anti-patterns
|
|
55
|
-
|
|
56
|
-
| Anti-pattern | Description |
|
|
57
|
-
|---|---|
|
|
58
|
-
| **Shotgun debugging** | Making random changes hoping something works. Every change should be driven by a hypothesis. |
|
|
59
|
-
| **Fixing symptoms** | Adding null checks, try/catch blocks, or default values without understanding why the unexpected state occurs. |
|
|
60
|
-
| **Debugging by rewriting** | Rewriting a module because you cannot find the bug. The bug may survive the rewrite. |
|
|
61
|
-
| **Ignoring intermittent failures** | "It works now" is not a fix. Intermittent bugs are usually race conditions, state leaks, or environment dependencies. |
|
|
62
|
-
| **Assuming the bug is elsewhere** | Check your own code first. The framework or library is almost never the problem. |
|
|
63
|
-
|
|
64
|
-
## Trigger Conditions
|
|
65
|
-
|
|
66
|
-
This skill is automatically suggested when Claude detects:
|
|
67
|
-
|
|
68
|
-
- **Keywords:** `bug`, `debug`, `fix`, `error`, `issue`, `broken`, `crash`
|
|
69
|
-
- **Intent patterns:** "fix/debug/resolve the bug/error/issue"
|
|
70
|
-
- **Excludes:** "fix typo", "fix formatting", "fix lint"
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Testing Patterns
|
|
2
|
-
|
|
3
|
-
> Generic test-driven development practices and patterns applicable to any language or test framework. Use when writing tests, setting up a test suite, or deciding what to test at which layer
|
|
4
|
-
|
|
5
|
-
**Type:** Core Skill (always included)
|
|
6
|
-
**Source:** [`core/skills/ct-testing-patterns/SKILL.md`](../core/skills/ct-testing-patterns/SKILL.md)
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Principles and patterns for writing tests that catch bugs, enable refactoring, and serve as documentation. These are framework-agnostic -- adapt the syntax to your project's test runner.
|
|
11
|
-
|
|
12
|
-
## TDD Cycle: Red, Green, Refactor
|
|
13
|
-
|
|
14
|
-
1. **Red** -- Write a failing test for the desired behavior. Confirm it fails for the right reason.
|
|
15
|
-
2. **Green** -- Write the minimal code to make it pass. No optimization yet.
|
|
16
|
-
3. **Refactor** -- Clean up while keeping tests green.
|
|
17
|
-
|
|
18
|
-
Commit at each stage. The cycle keeps scope small and provides a safety net for every change.
|
|
19
|
-
|
|
20
|
-
## 3-Layer Testing Strategy
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
/ E2E \ Real browsers, full user flows
|
|
24
|
-
/----------\
|
|
25
|
-
/ Interaction \ Component sandbox, behavior, a11y
|
|
26
|
-
/----------------\
|
|
27
|
-
/ Unit \ Pure logic, signals, utilities
|
|
28
|
-
/--------------------\
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
| Layer | Target Ratio | What to Cover |
|
|
32
|
-
| ----------- | ------------ | ---------------------------------------------------------------------------- |
|
|
33
|
-
| Unit | ~70% | Business logic, utilities, data transforms, reactive primitives, error paths |
|
|
34
|
-
| Interaction | ~20% | Component variants, user interactions, accessibility, visual regression |
|
|
35
|
-
| E2E | ~10% | Critical user journeys, authentication flows, cross-page workflows |
|
|
36
|
-
|
|
37
|
-
> **Scope:** This core skill owns the layering decision below, the unit and interaction layers, and the cross-cutting E2E principles. Runner-specific E2E setup and execution live in the stack skills (e.g. `ct-playwright-patterns`) when a matching stack is installed.
|
|
38
|
-
|
|
39
|
-
### When to Use Which Layer
|
|
40
|
-
|
|
41
|
-
| Question | Layer |
|
|
42
|
-
| ------------------------------------------------- | -------------------------------------- |
|
|
43
|
-
| Does this logic need a DOM? | **Unit** if no, **Interaction** if yes |
|
|
44
|
-
| Does it involve multiple pages or navigation? | **E2E** |
|
|
45
|
-
| Am I testing a single component's visual states? | **Interaction** |
|
|
46
|
-
| Am I testing a reactive primitive (signal, memo)? | **Unit** |
|
|
47
|
-
| Does it require authentication or real network? | **E2E** |
|
|
48
|
-
| Am I testing component accessibility? | **Interaction** (axe-core) |
|
|
49
|
-
| Does it need the full server running? | **E2E** |
|
|
50
|
-
|
|
51
|
-
## Test Behavior, Not Implementation
|
|
52
|
-
|
|
53
|
-
Test _what_ code does (public interface, observable outputs), not _how_ (internal state, call counts). Implementation-coupled tests break on every refactor.
|
|
54
|
-
|
|
55
|
-
## Factory Pattern
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
function getMockUser(overrides = {}) {
|
|
59
|
-
return { id: "user-1", email: "test@example.com", name: "Test User", role: "member", ...overrides };
|
|
60
|
-
}
|
|
61
|
-
const admin = getMockUser({ role: "admin" });
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
New required fields update the factory once, not every test.
|
|
65
|
-
|
|
66
|
-
## Organization
|
|
67
|
-
|
|
68
|
-
- Co-locate tests or mirror source structure. One test file per module (`module.test.ext`).
|
|
69
|
-
- Group with `describe`, name as sentences: `it("rejects expired tokens")`.
|
|
70
|
-
|
|
71
|
-
## Shared Principles
|
|
72
|
-
|
|
73
|
-
- **Prefer role-based queries.** Use `getByRole`, `getByLabel`, `getByText` over test IDs or CSS selectors.
|
|
74
|
-
- **Never sleep.** Use framework-provided waiting mechanisms (`waitFor`, `findBy*`, web-first assertions).
|
|
75
|
-
- **One assertion focus per test.** Multiple assertions are fine if they verify facets of the same behavior.
|
|
76
|
-
- **Isolate tests.** No test should depend on another test's side effects. Reset state between tests.
|
|
77
|
-
|
|
78
|
-
## Mocking Rules
|
|
79
|
-
|
|
80
|
-
- Prefer real dependencies (in-memory DB, local server) when feasible.
|
|
81
|
-
- Mock at boundaries only (external APIs, email, payments), not internal modules.
|
|
82
|
-
- Keep mocks minimal -- only methods your code calls. Reset between tests.
|
|
83
|
-
- Verify mocks match the real API. Update when APIs change.
|
|
84
|
-
|
|
85
|
-
## Property-Based Testing
|
|
86
|
-
|
|
87
|
-
When a function has a contract ("for all valid inputs X, property Y holds"), use property-based tests to verify it across generated inputs instead of hand-picked examples:
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
// Instead of testing 3-4 specific inputs:
|
|
91
|
-
test("sort is idempotent", () => {
|
|
92
|
-
fc.assert(
|
|
93
|
-
fc.property(fc.array(fc.integer()), (arr) => {
|
|
94
|
-
const sorted = mySort(arr);
|
|
95
|
-
expect(mySort(sorted)).toEqual(sorted);
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
98
|
-
});
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Good candidates: serialization round-trips, math properties, parsers, encoding/decoding, sorting invariants.
|
|
102
|
-
|
|
103
|
-
## Bun Test Runner
|
|
104
|
-
|
|
105
|
-
Bun includes a built-in test runner. Use `bun test` for projects on the Bun runtime:
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
bun test # run all *.test.ts files
|
|
109
|
-
bun test --watch # re-run on changes
|
|
110
|
-
bun test --coverage # with code coverage
|
|
111
|
-
bun test path/to/file.test.ts # single file
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Bun supports `describe`, `it`/`test`, `expect`, lifecycle hooks, and snapshot testing out of the box with no additional dependencies.
|
|
115
|
-
|
|
116
|
-
## Test Speed
|
|
117
|
-
|
|
118
|
-
Three levers recur across common runners (Vitest, Playwright, Storybook browser mode). Stated once here; each stack skill carries the framework-specific syntax.
|
|
119
|
-
|
|
120
|
-
- **Parallelism sized to the runner.** Enable file-level parallelism (Vitest `fileParallelism`, Playwright `fullyParallel`), but cap workers to the runner's _real_ vCPUs (`"50%"` or a measured count). GitHub standard runners are 2 vCPU (private) / 4 (public); oversubscribing thrashes.
|
|
121
|
-
- **Shard across CI jobs, then merge the blob reports.** Sharding splits at the _file_ level (`--shard=i/n`), so wall-clock is gated by the slowest shard -- balance file sizes. Always emit a blob report per shard (`--reporter=blob`) and merge it (`merge-reports` / `--merge-reports`) in a dependent job, or results and coverage are fragmented and incomplete.
|
|
122
|
-
- **Skip isolation where state is clean.** Per-file environment isolation is the safe default but the biggest run-speed cost. Disable it (Vitest `isolate: false`, `pool: 'threads'`) only for side-effect-free logic suites; keep it where tests mutate globals/env/timers.
|
|
123
|
-
|
|
124
|
-
Profile before tuning, and never `sleep` to mask timing -- use the framework's auto-waiting (see Shared Principles).
|
|
125
|
-
|
|
126
|
-
Per-runner config (if the stack is installed): `ct-vite-vitest-patterns`, `ct-playwright-patterns`, `ct-storybook-patterns`.
|
|
127
|
-
|
|
128
|
-
## Anti-Patterns
|
|
129
|
-
|
|
130
|
-
1. **Testing implementation** -- Asserting internal state or call counts breaks on refactors.
|
|
131
|
-
2. **Overmocking** -- If most of the test is mock setup, you're testing mocks.
|
|
132
|
-
3. **Copy-paste tests** -- Use factories and parameterized tests.
|
|
133
|
-
4. **No assertions** -- Worse than no test. False confidence.
|
|
134
|
-
5. **Ignoring flaky tests** -- Fix or delete; never skip indefinitely.
|
|
135
|
-
6. **Happy path only** -- Error cases and boundary conditions are where bugs live.
|
|
136
|
-
|
|
137
|
-
## Trigger Conditions
|
|
138
|
-
|
|
139
|
-
- **Keywords:** `test`, `spec`, `tdd`, `mock`, `factory`
|
|
140
|
-
- **File patterns:** `**/*.test.ts`, `**/*.spec.ts`
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
# TypeScript Conventions
|
|
2
|
-
|
|
3
|
-
> Strict TypeScript patterns and compiler selection — prefer the TypeScript 7 native compiler when a project ships it. Use when writing or reviewing TypeScript, running a typecheck, adding or tightening types, or deciding between type and interface
|
|
4
|
-
|
|
5
|
-
**Type:** Core Skill (always included)
|
|
6
|
-
**Source:** [`core/skills/ct-typescript-conventions/SKILL.md`](../core/skills/ct-typescript-conventions/SKILL.md)
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Rules for writing TypeScript that leverages the type system fully. These assume strict mode is enabled and prioritize catching errors at compile time over runtime.
|
|
11
|
-
|
|
12
|
-
The skill also covers **which compiler to run**. TypeScript 7 — the Go-native port — reached GA on 2026-07-08 as `typescript@7.0.2`, with Microsoft reporting 8x–12x faster full builds. The guidance is availability-aware in the same spirit as [ct-esnext-idioms](../stacks/esnext-idioms.md): prefer TS7 where a project already has it, fall back cleanly where it doesn't, and never upgrade a project unprompted.
|
|
13
|
-
|
|
14
|
-
## Compiler Selection
|
|
15
|
-
|
|
16
|
-
### Detect before you assume
|
|
17
|
-
|
|
18
|
-
Read the **installed** version, resolved from the directory being edited (monorepo workspaces can pin different majors):
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
node -p "require('typescript/package.json').version" # major >= 7 -> TS7
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`typescript@7.0.2` whitelists `./package.json` in its `exports` map, and 5.x/6.x have no `exports` map at all, so this subpath resolves on every major.
|
|
25
|
-
|
|
26
|
-
Three detection traps:
|
|
27
|
-
|
|
28
|
-
| Trap | Why it misleads |
|
|
29
|
-
|---|---|
|
|
30
|
-
| Looking for a `tsgo` binary | TS7's only CLI binary is `tsc`. `tsgo` belonged to the pre-GA `@typescript/native-preview` package, which is frozen at a `7.0.0-dev` nightly. |
|
|
31
|
-
| Reading the `package.json` semver range | `overrides`, `resolutions`, pnpm/bun catalogs and stale lockfiles all override it — and `*`, `latest`, `>=5` all resolve to 7.x today. |
|
|
32
|
-
| Probing the API (`ts.createProgram`) | On TS7 `require("typescript")` exposes only `version` and `versionMajorMinor`, so an API probe reports a false negative. |
|
|
33
|
-
|
|
34
|
-
### When TS7 is available
|
|
35
|
-
|
|
36
|
-
Flags are unchanged from 6.x — `tsc --noEmit`, `tsc -p <path>`, `tsc -b`, `tsc --watch`. New in TS7:
|
|
37
|
-
|
|
38
|
-
| Flag | Meaning |
|
|
39
|
-
|---|---|
|
|
40
|
-
| `--checkers <n>` | Type-checking workers per project (default 4). Microsoft warns that varying it "may surface order-dependent results" — pin it in CI. |
|
|
41
|
-
| `--builders <n>` | Projects built concurrently in build mode (default 4). |
|
|
42
|
-
| `--singleThreaded` | Most deterministic setting. |
|
|
43
|
-
| `--lsp` | Language server over LSP (there is no `tsserver` binary). |
|
|
44
|
-
|
|
45
|
-
Note that watch mode is labelled a prototype at the GA tag: it rebuilds but does not incrementally recheck.
|
|
46
|
-
|
|
47
|
-
### When a tool embeds the compiler — do not switch
|
|
48
|
-
|
|
49
|
-
TypeScript 7.0 ships **no stable programmatic API**; Microsoft targets 7.1 for "a new (and different) API" with no committed date. Anything that embeds the compiler is blocked:
|
|
50
|
-
|
|
51
|
-
| Tool | Status on TS7 |
|
|
52
|
-
|---|---|
|
|
53
|
-
| `typescript-eslint` | Peer range `<6.1.0`; install fails `ERESOLVE`, and a forced install crashes during lint |
|
|
54
|
-
| `vue-tsc`, `svelte-check`, `@astrojs/check` | Crash on `ERR_PACKAGE_PATH_NOT_EXPORTED` — TS7 has no `./lib/*` export |
|
|
55
|
-
| `ts-node` | Crashes in config load |
|
|
56
|
-
| `ts-jest` | Peer range `>=4.3 <7` |
|
|
57
|
-
| `@angular/compiler-cli` | Peer range `>=6.0 <6.1` (Microsoft suggests a hybrid: TS7 at the CLI, TS6 for editor support) |
|
|
58
|
-
|
|
59
|
-
Unaffected — these carry no `typescript` dependency at all: Vite, Bun, `tsx`, Vitest, Jest, Biome.
|
|
60
|
-
|
|
61
|
-
**A type-check smoke test will not catch these failures.** typescript-eslint's breakage surfaces at `npm ci` and at lint time while `tsc --noEmit` still passes. When a blocked tool is present, install both compilers side by side rather than downgrading — this is Microsoft's documented escape hatch:
|
|
62
|
-
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"devDependencies": {
|
|
66
|
-
"@typescript/native": "npm:typescript@^7.0.2",
|
|
67
|
-
"typescript": "npm:@typescript/typescript6@^6.0.2"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
The `typescript` key must stay pointed at the 6.0 compatibility package, because blocked tools import from `typescript` by peer dependency.
|
|
73
|
-
|
|
74
|
-
### When TS7 is absent
|
|
75
|
-
|
|
76
|
-
The floor is `typescript@6.0.3` — the last 6.x release, and the bridge Microsoft designates between 5.9 and 7.0. It also sits inside every current ecosystem peer range. The readiness gate before moving a project to 7 is a clean 6.0 build with `"stableTypeOrdering": true` and no `ignoreDeprecations` set. That flag is a diagnostic aid only — Microsoft notes it can add up to 25% to type-checking time and is not meant to be left on.
|
|
77
|
-
|
|
78
|
-
### `tsconfig.json` under TS7
|
|
79
|
-
|
|
80
|
-
These are rejected outright, and `ignoreDeprecations` no longer silences them (in 6.0 they were silenceable errors; in 7.0 there is no escape hatch):
|
|
81
|
-
|
|
82
|
-
| Rejected | Replacement |
|
|
83
|
-
|---|---|
|
|
84
|
-
| `baseUrl` | project-root-relative `paths` |
|
|
85
|
-
| `outFile`, `downlevelIteration` | remove |
|
|
86
|
-
| `target: "es5"` | `"es2015"` or later |
|
|
87
|
-
| `module: "amd" \| "umd" \| "system" \| "none" \| "systemjs"` | `"esnext"`, `"preserve"`, or `"nodenext"` |
|
|
88
|
-
| `moduleResolution: "node" \| "node10" \| "classic"` | `"bundler"`, `"node16"`, or `"nodenext"` |
|
|
89
|
-
| `esModuleInterop` / `allowSyntheticDefaultImports` / `alwaysStrict` set to `false` | drop the override |
|
|
90
|
-
|
|
91
|
-
These are gone entirely — `TS5023: Unknown compiler option`: `out`, `charset`, `keyofStringsOnly`, `suppressImplicitAnyIndexErrors`, `noImplicitUseStrict`, `importsNotUsedAsValues`, `preserveValueImports`, `suppressExcessPropertyErrors`, `noStrictGenericChecks`.
|
|
92
|
-
|
|
93
|
-
Two changed defaults account for most real-world breakage:
|
|
94
|
-
|
|
95
|
-
- **`types` defaults to `[]`.** Ambient globals like `process` vanish with `TS2591`. Set it explicitly: `"types": ["node"]`, or `["bun"]` for Bun projects.
|
|
96
|
-
- **`rootDir` defaults to `./`.** With sources under `src/` and an `outDir`, emit fails `TS5011`. Set `"rootDir": "./src"`. This fires **only when the program emits** — `tsc --noEmit` stays silent, so a type-check-only CI job can stay green while the build breaks.
|
|
97
|
-
|
|
98
|
-
`strict` defaults to `true`, and `stableTypeOrdering` is on and cannot be turned off. `experimentalDecorators` and `emitDecoratorMetadata` both survive.
|
|
99
|
-
|
|
100
|
-
Project references, `--build` mode, incremental builds, declaration emit, and CommonJS emit all work.
|
|
101
|
-
|
|
102
|
-
> Reference note: `typescriptlang.org/tsconfig` has not been updated for TS7 and still documents removed options, and there is no TS 7.0 handbook release-notes page. The [GA announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) is the authoritative what's-new source.
|
|
103
|
-
|
|
104
|
-
## Key Patterns
|
|
105
|
-
|
|
106
|
-
### Strict Mode
|
|
107
|
-
|
|
108
|
-
Enable all strict checks in `tsconfig.json`:
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"compilerOptions": {
|
|
113
|
-
"strict": true,
|
|
114
|
-
"noUncheckedIndexedAccess": true,
|
|
115
|
-
"noUnusedLocals": true,
|
|
116
|
-
"noUnusedParameters": true
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Never disable strict checks for convenience.
|
|
122
|
-
|
|
123
|
-
### No `any`
|
|
124
|
-
|
|
125
|
-
Never use `any`. It disables type checking entirely.
|
|
126
|
-
|
|
127
|
-
- Use `unknown` when the type is genuinely not known, then narrow before use
|
|
128
|
-
- Use generics when the type varies but has a consistent shape
|
|
129
|
-
- Use specific types when you know the data shape
|
|
130
|
-
|
|
131
|
-
### Type vs Interface
|
|
132
|
-
|
|
133
|
-
- **Default to `type`.** It covers object shapes, unions, intersections, mapped types, and utility types.
|
|
134
|
-
- **Use `interface` only when you need `extends`** (an inheritance hierarchy or declaration merging).
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
// Default: use type for object shapes
|
|
138
|
-
type User = {
|
|
139
|
-
id: string;
|
|
140
|
-
email: string;
|
|
141
|
-
role: UserRole;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
// Unions, intersections, utilities: type
|
|
145
|
-
type UserRole = "admin" | "member" | "guest";
|
|
146
|
-
|
|
147
|
-
// interface only when you need extends
|
|
148
|
-
interface Animal {
|
|
149
|
-
name: string;
|
|
150
|
-
}
|
|
151
|
-
interface Dog extends Animal {
|
|
152
|
-
breed: string;
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### `as const` for Literal Types
|
|
157
|
-
|
|
158
|
-
Use `as const` to narrow literal values and create readonly tuples:
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
const ROLES = ["admin", "member", "guest"] as const;
|
|
162
|
-
type Role = (typeof ROLES)[number]; // "admin" | "member" | "guest"
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Exhaustive Switch with `never`
|
|
166
|
-
|
|
167
|
-
Handle every case in a switch and use `never` to catch missing branches at compile time:
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
function getPermissions(role: UserRole): string[] {
|
|
171
|
-
switch (role) {
|
|
172
|
-
case "admin":
|
|
173
|
-
return ["read", "write", "delete"];
|
|
174
|
-
case "member":
|
|
175
|
-
return ["read", "write"];
|
|
176
|
-
case "guest":
|
|
177
|
-
return ["read"];
|
|
178
|
-
default: {
|
|
179
|
-
const _exhaustive: never = role;
|
|
180
|
-
throw new Error(`Unhandled role: ${_exhaustive}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Discriminated Unions for State Modeling
|
|
187
|
-
|
|
188
|
-
Model states with different associated data as discriminated unions to make illegal states unrepresentable:
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
type AsyncState<T> =
|
|
192
|
-
| { status: "loading" }
|
|
193
|
-
| { status: "success"; data: T }
|
|
194
|
-
| { status: "error"; error: Error };
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### `satisfies` Operator
|
|
198
|
-
|
|
199
|
-
Validate a value conforms to a type while keeping the value's own narrower inferred type instead of collapsing to the annotation. Here it preserves the exact key set (`home`, `user`) rather than the index signature `Record<string, Route>`:
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
type Route = { path: string; children?: Route[] };
|
|
203
|
-
|
|
204
|
-
const routes = {
|
|
205
|
-
home: { path: "/" },
|
|
206
|
-
user: { path: "/user/:id", children: [{ path: "settings" }] },
|
|
207
|
-
} satisfies Record<string, Route>;
|
|
208
|
-
|
|
209
|
-
// routes.home and routes.user are known keys -- not `Route | undefined` from the index signature.
|
|
210
|
-
// Note: routes.home.path is `string`, NOT the literal "/", because `Route` declares `path: string`,
|
|
211
|
-
// which widens the literal. To keep a literal, target a narrower type (e.g. a union) or add `as const`.
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### `const` Type Parameters
|
|
215
|
-
|
|
216
|
-
Infer literal types from arguments without requiring callers to write `as const`:
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
function createConfig<const T extends readonly string[]>(names: T): Record<T[number], boolean> {
|
|
220
|
-
// `Object.fromEntries` is typed to return a wide `Record<string, boolean>`, so a single
|
|
221
|
-
// localized `as` at a generic helper's return boundary is acceptable here -- it keeps the
|
|
222
|
-
// public signature precise. This is the narrow exception to the "no `as` casts" anti-pattern.
|
|
223
|
-
return Object.fromEntries(names.map(n => [n, false])) as Record<T[number], boolean>;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// result: Record<"debug" | "verbose", boolean>
|
|
227
|
-
const flags = createConfig(["debug", "verbose"]);
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### Template Literal Types
|
|
231
|
-
|
|
232
|
-
Build precise string types from unions:
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
type EventName = "click" | "focus" | "blur";
|
|
236
|
-
type Handler = `on${Capitalize<EventName>}`; // "onClick" | "onFocus" | "onBlur"
|
|
237
|
-
|
|
238
|
-
type Locale = "en" | "fr" | "ja";
|
|
239
|
-
type Currency = "USD" | "EUR" | "JPY";
|
|
240
|
-
type PriceKey = `price:${Locale}:${Currency}`; // 9 valid combinations
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Generic Constraints
|
|
244
|
-
|
|
245
|
-
Use `extends` to constrain generics, documenting expectations and catching misuse:
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
|
|
249
|
-
return items.find((item) => item.id === id);
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Anti-patterns
|
|
254
|
-
|
|
255
|
-
| Anti-pattern | Description |
|
|
256
|
-
|---|---|
|
|
257
|
-
| **Type assertions (`as`)** | Tells the compiler "trust me" -- use type guards and narrowing instead. |
|
|
258
|
-
| **Non-null assertion (`!`)** | Suppresses null checks. Handle the null case explicitly. |
|
|
259
|
-
| **Enum overuse** | Prefer string literal unions. Enums generate runtime code and have surprising behavior. |
|
|
260
|
-
| **`Object`, `Function`, `{}`** | Almost never what you want. Use specific interfaces or function signatures. |
|
|
261
|
-
| **`@ts-ignore`** | Suppressing errors without tracking means the error will be forgotten. |
|
|
262
|
-
|
|
263
|
-
## Best Practices Reference
|
|
264
|
-
|
|
265
|
-
For deeper guidance on the patterns referenced above (sourced from Matt Pocock / Total TypeScript):
|
|
266
|
-
|
|
267
|
-
| Topic | Guide |
|
|
268
|
-
|---|---|
|
|
269
|
-
| Default to `type`, use `interface` for `extends` | [Type vs Interface](../best-practices/typescript/type-vs-interface.md) |
|
|
270
|
-
| Why enums are problematic, `as const` alternative | [Enums & Alternatives](../best-practices/typescript/enums-alternatives.md) |
|
|
271
|
-
| When `any` is acceptable (two exceptions) | [any & unknown](../best-practices/typescript/any-and-unknown.md) |
|
|
272
|
-
| State modeling with discriminated unions | [Discriminated Unions](../best-practices/typescript/discriminated-unions.md) |
|
|
273
|
-
| Three patterns for generics | [Generics Patterns](../best-practices/typescript/generics-patterns.md) |
|
|
274
|
-
| Recommended `tsconfig.json` settings | [TSConfig Cheat Sheet](../best-practices/typescript/tsconfig-cheat-sheet.md) |
|
|
275
|
-
| Branded types, assertion functions, type predicates | [Essential Patterns](../best-practices/typescript/essential-patterns.md) |
|
|
276
|
-
|
|
277
|
-
See the full collection: [TypeScript Best Practices](../best-practices/typescript/README.md)
|
|
278
|
-
|
|
279
|
-
## Trigger Conditions
|
|
280
|
-
|
|
281
|
-
- **Keywords:** `typescript`, `type`, `interface`, `generic`
|
|
282
|
-
- **File patterns:** `**/*.d.ts`, `**/types/**`
|
|
283
|
-
- **Intent patterns:** "define/create type/interface"
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# Verification Before Completion
|
|
2
|
-
|
|
3
|
-
> Evidence-based completion claims -- never say "done" without proof that the work is correct. Use when about to claim a task is done, fixed, or passing, or before committing or opening a PR
|
|
4
|
-
|
|
5
|
-
**Type:** Core Skill (always included)
|
|
6
|
-
**Source:** [`core/skills/ct-verification-before-completion/SKILL.md`](../core/skills/ct-verification-before-completion/SKILL.md)
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
The most common source of rework is claiming completion without verification. Every "done" claim must be backed by evidence that the code works correctly. "I wrote the code" is not evidence. "The tests pass, the types check, and here is the output" is evidence.
|
|
11
|
-
|
|
12
|
-
## Verification Checklist
|
|
13
|
-
|
|
14
|
-
### 1. Tests Pass
|
|
15
|
-
|
|
16
|
-
Run the full test suite (or related tests) and show the output. If any test fails, fix it before claiming complete.
|
|
17
|
-
|
|
18
|
-
### 2. Type Checks Pass
|
|
19
|
-
|
|
20
|
-
Run the type checker with no errors (`tsc --noEmit` or equivalent). Zero errors, zero warnings on changed files.
|
|
21
|
-
|
|
22
|
-
### 3. Linting Passes
|
|
23
|
-
|
|
24
|
-
Run the project's linter on changed files. Fix any violations introduced by your changes.
|
|
25
|
-
|
|
26
|
-
### 4. The Feature Actually Works
|
|
27
|
-
|
|
28
|
-
For user-facing changes, demonstrate the feature works with actual output -- API responses, rendered UI, CLI output:
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
$ curl -s localhost:3000/api/users/1 | jq .
|
|
32
|
-
{
|
|
33
|
-
"id": "1",
|
|
34
|
-
"name": "Alice",
|
|
35
|
-
"email": "alice@example.com"
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### 5. Edge Cases Verified
|
|
40
|
-
|
|
41
|
-
Test boundaries and unusual inputs explicitly:
|
|
42
|
-
|
|
43
|
-
- **Empty inputs** -- empty strings, empty arrays, null, undefined
|
|
44
|
-
- **Boundary values** -- zero, negative numbers, maximum values, off-by-one
|
|
45
|
-
- **Invalid inputs** -- wrong types, malformed data, missing required fields
|
|
46
|
-
- **Concurrent access** -- simultaneous requests or operations
|
|
47
|
-
- **Error paths** -- network failures, database errors, permission denied
|
|
48
|
-
|
|
49
|
-
### 6. Security Check
|
|
50
|
-
|
|
51
|
-
Before completing work that touches dependencies, inputs, or external data:
|
|
52
|
-
|
|
53
|
-
- **Dependency audit** -- Run `bun audit` or `npm audit` and resolve critical/high vulnerabilities
|
|
54
|
-
- **Input validation** -- Verify user-facing inputs are validated at system boundaries (no SQL injection, XSS, command injection)
|
|
55
|
-
- **Secret exposure** -- Confirm no secrets, API keys, or credentials in committed code or logs
|
|
56
|
-
|
|
57
|
-
### 7. Regression Check
|
|
58
|
-
|
|
59
|
-
- Run related tests, not just the tests you wrote
|
|
60
|
-
- Check integration points if you changed a shared utility, API contract, or database schema
|
|
61
|
-
- Smoke test the application if it has a running instance
|
|
62
|
-
|
|
63
|
-
## Evidence Format
|
|
64
|
-
|
|
65
|
-
When reporting completion, include concrete evidence:
|
|
66
|
-
|
|
67
|
-
```markdown
|
|
68
|
-
## Completed: User authentication endpoint
|
|
69
|
-
|
|
70
|
-
### Tests
|
|
71
|
-
- 12 tests passing (3 new, 9 existing)
|
|
72
|
-
- `npm test -- --grep "auth"` output: all green
|
|
73
|
-
|
|
74
|
-
### Type check
|
|
75
|
-
- `tsc --noEmit`: 0 errors
|
|
76
|
-
|
|
77
|
-
### Security
|
|
78
|
-
- `bun audit`: 0 vulnerabilities
|
|
79
|
-
- No secrets in committed files
|
|
80
|
-
|
|
81
|
-
### Manual verification
|
|
82
|
-
- POST /api/auth/login with valid credentials: 200 + JWT token
|
|
83
|
-
- POST /api/auth/login with wrong password: 401 + error message
|
|
84
|
-
- POST /api/auth/login with locked account: 423 + lockout message
|
|
85
|
-
|
|
86
|
-
### Edge cases verified
|
|
87
|
-
- Empty email: 400 validation error
|
|
88
|
-
- SQL injection attempt in email: properly escaped, no error
|
|
89
|
-
- Expired token refresh: 401 with clear message
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## What This Prevents
|
|
93
|
-
|
|
94
|
-
- **"It works on my machine" failures** -- evidence shows it works in a verifiable way
|
|
95
|
-
- **Phantom completions** -- tasks marked done that are actually broken
|
|
96
|
-
- **Regression blindness** -- catching breakage before it reaches review or production
|
|
97
|
-
- **Incomplete implementations** -- edge cases and error handling are verified, not assumed
|
|
98
|
-
|
|
99
|
-
## Trigger Conditions
|
|
100
|
-
|
|
101
|
-
- **Keywords:** `verify`, `check`, `confirm`, `done`, `complete`
|
|
102
|
-
- **Intent patterns:** "is it done", "verify it works"
|
|
103
|
-
- **Context patterns:** "before claiming", "make sure"
|