---
name: type-safety-sweep
description: 'Fix TypeScript errors across a repo or the full workspace with systematic triage and minimal code changes.'
argument-hint: 'Scope, e.g. "learning_ai_flowmonk", "all backends", "common_plat packages only"'
agent: agent
---

# Type Safety Sweep Prompt

Systematically fix TypeScript errors across ByteLyst repos with minimal, safe changes.

## Context — ByteLyst TypeScript Conventions

- **Target:** ES2022, `moduleResolution: NodeNext`
- **Strict mode:** `strict: true` in all repos
- **Base config:** Extends `../../tsconfig.base.json` (from common_plat)
- **Module system:** ESM (`"type": "module"`) with `.js` extensions in imports
- **No `any`:** Use Zod inference, explicit types, or `unknown` with type guards

## Sweep Protocol

### Step 1: Run Typecheck

```bash
# Single repo
pnpm typecheck

# Workspace-wide
cd learning_ai_common_plat && pnpm typecheck
cd <product> && pnpm typecheck
```

### Step 2: Triage Errors

Categorize each error:

| Category | Fix Strategy | Risk |
|----------|-------------|------|
| **Missing `.js` extension** | Add `.js` to import path | Low |
| **Implicit `any`** | Add explicit type annotation | Low |
| **Missing property** | Add property to interface/schema | Medium |
| **Type mismatch** | Fix the value, not the type (usually) | Medium |
| **Package type conflict** | Check peer dep versions | High |
| **Structural break** | Needs design decision | High |

### Step 3: Fix by Category

#### Low-risk fixes (do first)
```typescript
// Missing .js extension
- import { foo } from './utils';
+ import { foo } from './utils.js';

// Implicit any
- function handle(req, reply) {
+ function handle(req: FastifyRequest, reply: FastifyReply) {

// Unused imports
- import { unused, used } from './types.js';
+ import { used } from './types.js';
```

#### Medium-risk fixes
```typescript
// Missing property — add to schema
const schema = z.object({
  name: z.string(),
+ description: z.string().optional(), // Was missing
});

// Type mismatch — fix the value
- const port: number = process.env.PORT; // string assigned to number
+ const port: number = Number(process.env.PORT) || 4003;
```

#### High-risk fixes (get approval first)
- Package version conflicts → document and propose solution
- Structural type breaks → explain what changed and why

### Step 4: Validate

After each batch of fixes:
```bash
pnpm typecheck  # Must pass
pnpm test        # Must still pass
pnpm build       # Must still build
```

### Step 5: Commit

Group fixes logically:
```bash
# Low-risk batch
git add .
git commit -m "fix(<scope>): resolve TypeScript errors (import extensions, explicit types)"

# Medium-risk batch
git add .
git commit -m "fix(<scope>): fix type mismatches in <modules>"

git push
```

## Common ByteLyst Type Issues

### Zod version mismatch
**Symptom:** `Type 'z.ZodString' is not assignable to type 'z.ZodString'`
**Fix:** Services must use self-contained Zod schemas in `src/lib/config.ts`, NOT import from @bytelyst/config

### Package export types
**Symptom:** `Cannot find module '@bytelyst/errors' or its corresponding type declarations`
**Fix:** Build the package first: `cd learning_ai_common_plat && pnpm build`

### Fastify request types
**Symptom:** `Property 'user' does not exist on type 'FastifyRequest'`
**Fix:** Use `getUserId(req)` from `src/lib/request-context.ts` instead of `req.user`

### Cosmos document types
**Symptom:** `Type '{ name: string }' is missing ... 'productId'`
**Fix:** Always include `productId` when creating documents

## Report Format

```markdown
## Type Safety Sweep: <Repo>

| Category | Count | Fixed | Remaining |
|----------|-------|-------|-----------|
| Import extensions | N | N | 0 |
| Implicit any | N | N | 0 |
| Type mismatches | N | N | M |
| Package conflicts | N | 0 | N |
| **Total** | **X** | **Y** | **Z** |

### Deferred Issues
- <issue>: <why deferred> (needs <decision/approval>)
```
