@vpxa/aikit 0.1.185 → 0.1.187
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/package.json +1 -1
- package/packages/browser/dist/index.js +1 -1
- package/scaffold/dist/definitions/skills/adr-skill.mjs +73 -155
- package/scaffold/dist/definitions/skills/aikit.mjs +291 -318
- package/scaffold/dist/definitions/skills/brainstorming.mjs +107 -242
- package/scaffold/dist/definitions/skills/browser-use.mjs +213 -1
- package/scaffold/dist/definitions/skills/c4-architecture.mjs +212 -2256
- package/scaffold/dist/definitions/skills/docs.mjs +395 -755
- package/scaffold/dist/definitions/skills/lesson-learned.mjs +61 -21
- package/scaffold/dist/definitions/skills/react.mjs +104 -137
- package/scaffold/dist/definitions/skills/requirements-clarity.mjs +55 -2
- package/scaffold/dist/definitions/skills/session-handoff.mjs +127 -177
- package/scaffold/dist/definitions/skills/typescript.mjs +16 -0
|
@@ -1298,7 +1298,7 @@ if (args.includes('--json')) {
|
|
|
1298
1298
|
}
|
|
1299
1299
|
`},{file:`SKILL.md`,content:`---
|
|
1300
1300
|
name: session-handoff
|
|
1301
|
-
description: "Creates comprehensive handoff documents for seamless AI agent session transfers. Triggered when: (1) user requests handoff/memory/context save, (2) context window approaches capacity, (3) major task milestone completed, (4) work session ending, (5) user says 'save state', 'create handoff', 'I need to pause', 'context is getting full', (6) resuming work with 'load handoff', 'resume from', 'continue where we left off'. Proactively suggests handoffs after substantial work (multiple file edits, complex debugging, architecture decisions). Solves long-running agent context exhaustion by enabling fresh agents to continue with zero ambiguity."
|
|
1301
|
+
description: "Creates comprehensive handoff documents for seamless AI agent session transfers. Triggered when: (1) user requests handoff/memory/context save, (2) context window approaches capacity (>70% pressure), (3) major task milestone completed, (4) work session ending, (5) user says 'save state', 'create handoff', 'I need to pause', 'context is getting full', (6) resuming work with 'load handoff', 'resume from', 'continue where we left off'. Proactively suggests handoffs after substantial work (multiple file edits, complex debugging, architecture decisions). Solves long-running agent context exhaustion by enabling fresh agents to continue with zero ambiguity."
|
|
1302
1302
|
metadata:
|
|
1303
1303
|
category: cross-cutting
|
|
1304
1304
|
domain: general
|
|
@@ -1309,247 +1309,197 @@ metadata:
|
|
|
1309
1309
|
relatedSkills: [lesson-learned]
|
|
1310
1310
|
---
|
|
1311
1311
|
|
|
1312
|
-
# Handoff
|
|
1312
|
+
# Session Handoff
|
|
1313
1313
|
|
|
1314
|
-
Creates
|
|
1314
|
+
Creates compact, high-signal handoffs so a fresh agent can resume work without rereading the full conversation.
|
|
1315
1315
|
|
|
1316
|
-
##
|
|
1317
|
-
|
|
1318
|
-
**Purpose:** Create handoff documents for seamless AI session transfers. Solves context exhaustion — fresh agents continue with zero ambiguity.
|
|
1319
|
-
|
|
1320
|
-
**Two modes:**
|
|
1321
|
-
- **CREATE** — Save current state when: user requests, context filling up, milestone completed, session ending
|
|
1322
|
-
- **RESUME** — Load prior state when: user says "continue", "resume", or references existing handoff
|
|
1323
|
-
|
|
1324
|
-
**Dual storage** (every handoff creates both):
|
|
1325
|
-
1. **Full file** → \`.aikit-state/handoffs/{flow-slug}/<timestamp>-<slug>.md\` (browsable, gitignored)
|
|
1326
|
-
2. **Compact entry** → \`knowledge({ action: "remember", scope: "flow", category: "session", title: "Session Handoff: <slug>" })\` (~1-2K chars, for \`withdraw\`)
|
|
1327
|
-
|
|
1328
|
-
**CREATE workflow:** Gather state → Fill template (metadata, state summary, codebase understanding, work completed, pending work, resume context) → Save dual format → Present summary
|
|
1316
|
+
## Mindset
|
|
1329
1317
|
|
|
1330
|
-
|
|
1318
|
+
Session handoffs solve the "context amnesia" problem — you have 200K tokens of accumulated understanding that will vanish. Your job is compression with zero information loss on the critical path.
|
|
1331
1319
|
|
|
1332
|
-
|
|
1320
|
+
Think of it as writing a briefing for a colleague who will take over your shift:
|
|
1321
|
+
- What's the current state? (not how we got here)
|
|
1322
|
+
- What decisions were made and WHY? (not what was considered)
|
|
1323
|
+
- What's blocked and needs action? (not what's going fine)
|
|
1324
|
+
- What will surprise them? (gotchas, non-obvious constraints)
|
|
1333
1325
|
|
|
1334
|
-
|
|
1326
|
+
The 80/20 rule applies brutally: 80% of context is irrelevant to the next step. Identify the 20% that matters and make it crystal clear.
|
|
1335
1327
|
|
|
1336
|
-
##
|
|
1337
|
-
|
|
1338
|
-
Determine which mode applies:
|
|
1328
|
+
## Quick Reference
|
|
1339
1329
|
|
|
1340
|
-
|
|
1341
|
-
-
|
|
1330
|
+
Use this skill in two modes:
|
|
1331
|
+
- **CREATE** — when user asks to save context, context pressure exceeds ~70%, a milestone lands, or the session is ending
|
|
1332
|
+
- **RESUME** — when user asks to continue prior work, load saved context, or pick up from an existing handoff
|
|
1342
1333
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1334
|
+
Every good handoff stores context in two forms:
|
|
1335
|
+
1. **Full markdown file** at \`.aikit-state/handoffs/{flow-slug}/YYYY-MM-DD-HHMMSS-[slug].md\`
|
|
1336
|
+
2. **Compact flow knowledge entry** via \`knowledge({ action: "remember", scope: "flow", category: "session", title: "Session Handoff: <slug>", content })\`
|
|
1345
1337
|
|
|
1346
|
-
|
|
1347
|
-
> "We've made significant progress. Consider creating a handoff document to preserve this context for future sessions. Say 'create handoff' when ready."
|
|
1338
|
+
On resume, start with \`knowledge({ action: "withdraw", scope: "flow", profile: "implementer", budget: 6000 })\`. Only open the full handoff file if the compact entry is insufficient.
|
|
1348
1339
|
|
|
1349
|
-
|
|
1340
|
+
## NEVER
|
|
1350
1341
|
|
|
1351
|
-
|
|
1342
|
+
- **NEVER include full file contents in handoffs** — reference file paths + what changed, not entire files. Handoffs that paste 1000 lines of code are useless because the next agent will need to re-read them anyway.
|
|
1343
|
+
- **NEVER omit the "why" behind decisions** — "chose JWT" is worthless without "chose JWT because: stateless, API consumers, no session store." The next agent WILL re-examine your decisions without the rationale.
|
|
1344
|
+
- **NEVER create a handoff without blockers/next-steps** — these are the single most important sections. Everything else provides context; these drive action.
|
|
1345
|
+
- **NEVER hand off mid-failure** without capturing: error message, what was tried, what was NOT tried yet. Incomplete failure context causes the next agent to repeat failed approaches.
|
|
1346
|
+
- **NEVER include conversation history** — handoffs summarize OUTCOMES not PROCESS. "We discussed 3 options and chose X" not "I said... user said... I said..."
|
|
1347
|
+
- **NEVER create handoffs larger than 500 words** — if it's longer, you're pasting instead of summarizing. Compress ruthlessly.
|
|
1348
|
+
- **NEVER skip the architecture context** — the next agent doesn't know the codebase. Include: key files, patterns used, critical constraints.
|
|
1352
1349
|
|
|
1353
|
-
|
|
1350
|
+
## Handoff Quality Gate
|
|
1354
1351
|
|
|
1355
|
-
|
|
1356
|
-
- Complete template with all sections
|
|
1357
|
-
- Browsable on disk but NOT committed to git
|
|
1358
|
-
- Auto-cleaned when \`.aikit-state/\` is cleared
|
|
1352
|
+
A good handoff passes the "cold start" test: could a brand-new agent, with NO prior context, pick up where you left off and produce correct output on the FIRST attempt?
|
|
1359
1353
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1354
|
+
Score your handoff (must be 4/4):
|
|
1355
|
+
- [ ] **Actionable** — next steps are specific enough to execute without interpretation
|
|
1356
|
+
- [ ] **Self-contained** — doesn't require reading the conversation to understand
|
|
1357
|
+
- [ ] **Minimal** — no content that doesn't directly serve the next agent's work
|
|
1358
|
+
- [ ] **Verified** — decisions cite evidence (file:line, test output, tool result)
|
|
1364
1359
|
|
|
1365
|
-
|
|
1360
|
+
If any criterion fails, compress further or add the missing context.
|
|
1366
1361
|
|
|
1367
1362
|
## CREATE Workflow
|
|
1368
1363
|
|
|
1369
|
-
###
|
|
1370
|
-
|
|
1371
|
-
Run the smart scaffold script to create a pre-filled handoff document:
|
|
1372
|
-
|
|
1373
|
-
\`\`\`bash
|
|
1374
|
-
node scripts/create_handoff.js [task-slug]
|
|
1375
|
-
node scripts/create_handoff.js [task-slug] --flow <flow-slug>
|
|
1376
|
-
\`\`\`
|
|
1377
|
-
|
|
1378
|
-
Example: \`node scripts/create_handoff.js implementing-user-auth\`
|
|
1364
|
+
### 1. Choose storage target
|
|
1379
1365
|
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
\`\`\`
|
|
1366
|
+
Save the full handoff at one of these locations:
|
|
1367
|
+
- Flow-scoped: \`.aikit-state/handoffs/{flow-slug}/YYYY-MM-DD-HHMMSS-[slug].md\`
|
|
1368
|
+
- Standalone: \`.aikit-state/handoffs/_standalone/YYYY-MM-DD-HHMMSS-[slug].md\`
|
|
1384
1369
|
|
|
1385
|
-
|
|
1386
|
-
- Full handoff file in \`.aikit-state/handoffs/{active-flow}/\`
|
|
1387
|
-
- Compact format string (printed to stdout for pasting into \`knowledge({ action: "remember", ... })\`)
|
|
1370
|
+
Use a slug that describes the active task, not the conversation.
|
|
1388
1371
|
|
|
1389
|
-
|
|
1390
|
-
- Uses \`--flow\` to override the active flow slug
|
|
1391
|
-
- Falls back to \`.aikit-state/handoffs/_standalone/\` when no flow is active
|
|
1392
|
-
- Pre-fills: timestamp, project path, git branch, recent commits, modified files
|
|
1393
|
-
- Adds handoff chain links if continuing from previous
|
|
1394
|
-
- Outputs file path for editing
|
|
1372
|
+
### 2. Gather only critical-path facts
|
|
1395
1373
|
|
|
1396
|
-
|
|
1374
|
+
Before writing, capture the minimum context needed for a cold start:
|
|
1375
|
+
- Current state: what is done, in progress, failing, or pending
|
|
1376
|
+
- Key files: exact paths and why they matter
|
|
1377
|
+
- Decisions: what was chosen and why
|
|
1378
|
+
- Verification: tests, checks, tool results, or specific evidence
|
|
1379
|
+
- Blockers: error text, attempted fixes, untried options
|
|
1380
|
+
- Next steps: ordered, concrete actions
|
|
1397
1381
|
|
|
1398
|
-
|
|
1382
|
+
Use AI Kit tools inline instead of external scripts:
|
|
1383
|
+
- \`stash({ action: "set", key: "handoff:<slug>:notes", value })\` for temporary compression while drafting
|
|
1384
|
+
- \`checkpoint({ action: "save", label: "handoff-<slug>", notes })\` when session state itself matters
|
|
1385
|
+
- \`knowledge({ action: "list", category: "decisions" })\` and \`search({ query })\` to pull prior decisions into the handoff when relevant
|
|
1399
1386
|
|
|
1400
|
-
|
|
1401
|
-
2. **Important Context** - Critical info the next agent MUST know
|
|
1402
|
-
3. **Immediate Next Steps** - Clear, actionable first steps
|
|
1403
|
-
4. **Decisions Made** - Choices with rationale (not just outcomes)
|
|
1387
|
+
### 3. Write the full handoff
|
|
1404
1388
|
|
|
1405
|
-
Use
|
|
1389
|
+
Use this structure:
|
|
1406
1390
|
|
|
1407
|
-
|
|
1391
|
+
\`\`\`md
|
|
1392
|
+
# Handoff: <task>
|
|
1408
1393
|
|
|
1409
|
-
|
|
1394
|
+
## Current State
|
|
1395
|
+
- Status:
|
|
1396
|
+
- Last completed step:
|
|
1397
|
+
- Current failure or pending task:
|
|
1410
1398
|
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
\`\`\`
|
|
1399
|
+
## Critical Files
|
|
1400
|
+
- path/to/file - purpose + why it matters now
|
|
1414
1401
|
|
|
1415
|
-
|
|
1416
|
-
-
|
|
1417
|
-
-
|
|
1418
|
-
- [ ] No potential secrets detected (API keys, passwords, tokens)
|
|
1419
|
-
- [ ] Referenced files exist
|
|
1420
|
-
- [ ] Quality score (0-100)
|
|
1402
|
+
## Decisions
|
|
1403
|
+
- Decision: why
|
|
1404
|
+
- Evidence: file:line | test output | tool result
|
|
1421
1405
|
|
|
1422
|
-
|
|
1406
|
+
## Next Steps
|
|
1407
|
+
1. First action
|
|
1408
|
+
2. Second action
|
|
1409
|
+
3. Third action
|
|
1423
1410
|
|
|
1424
|
-
|
|
1411
|
+
## Blockers
|
|
1412
|
+
- Blocker:
|
|
1413
|
+
- Tried:
|
|
1414
|
+
- Not tried yet:
|
|
1425
1415
|
|
|
1426
|
-
|
|
1427
|
-
-
|
|
1428
|
-
|
|
1429
|
-
- Summary of captured context
|
|
1430
|
-
- First action item for next session
|
|
1416
|
+
## Gotchas
|
|
1417
|
+
- Non-obvious constraint or pattern
|
|
1418
|
+
\`\`\`
|
|
1431
1419
|
|
|
1432
|
-
|
|
1420
|
+
Use [references/handoff-template.md](references/handoff-template.md) when you need a fuller structure, but delete sections that add no value.
|
|
1433
1421
|
|
|
1434
|
-
###
|
|
1422
|
+
### 4. Save compact flow knowledge
|
|
1435
1423
|
|
|
1436
|
-
|
|
1424
|
+
Store a compressed version for automatic resume:
|
|
1437
1425
|
|
|
1438
|
-
\`\`\`
|
|
1439
|
-
|
|
1426
|
+
\`\`\`
|
|
1427
|
+
knowledge({
|
|
1428
|
+
action: "remember",
|
|
1429
|
+
scope: "flow",
|
|
1430
|
+
category: "session",
|
|
1431
|
+
title: "Session Handoff: <slug>",
|
|
1432
|
+
content: "State: ...
|
|
1433
|
+
Decisions: ...
|
|
1434
|
+
Next: ...
|
|
1435
|
+
Blockers: ...
|
|
1436
|
+
Evidence: ..."
|
|
1437
|
+
})
|
|
1440
1438
|
\`\`\`
|
|
1441
1439
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
### Step 2: Check Staleness
|
|
1440
|
+
Target 1-2K characters. This is the resume fast-path.
|
|
1445
1441
|
|
|
1446
|
-
|
|
1442
|
+
### 5. Self-review before finalizing
|
|
1447
1443
|
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1444
|
+
Confirm all of the following:
|
|
1445
|
+
- No secrets, tokens, or raw credentials
|
|
1446
|
+
- No pasted file dumps
|
|
1447
|
+
- Every decision includes rationale
|
|
1448
|
+
- Every blocker includes attempted and untried paths
|
|
1449
|
+
- Next step #1 is immediately executable
|
|
1450
|
+
- Quality Gate score is 4/4
|
|
1451
1451
|
|
|
1452
|
-
|
|
1453
|
-
- **FRESH**: Safe to resume - minimal changes since handoff
|
|
1454
|
-
- **SLIGHTLY_STALE**: Review changes, then resume
|
|
1455
|
-
- **STALE**: Verify context carefully before resuming
|
|
1456
|
-
- **VERY_STALE**: Consider creating a fresh handoff
|
|
1452
|
+
## RESUME Workflow
|
|
1457
1453
|
|
|
1458
|
-
|
|
1459
|
-
- Time since handoff was created
|
|
1460
|
-
- Git commits since handoff
|
|
1461
|
-
- Files changed since handoff
|
|
1462
|
-
- Branch divergence
|
|
1463
|
-
- Missing referenced files
|
|
1454
|
+
### 1. Pull compact context first
|
|
1464
1455
|
|
|
1465
|
-
|
|
1456
|
+
Start with:
|
|
1466
1457
|
|
|
1467
|
-
If a flow is active, check for compact handoffs in flow knowledge:
|
|
1468
1458
|
\`\`\`
|
|
1469
1459
|
knowledge({ action: "withdraw", scope: "flow", profile: "implementer", budget: 6000 })
|
|
1470
1460
|
\`\`\`
|
|
1471
1461
|
|
|
1472
|
-
If
|
|
1462
|
+
If the entry is truncated or multiple handoffs exist, use:
|
|
1463
|
+
|
|
1473
1464
|
\`\`\`
|
|
1474
1465
|
knowledge({ action: "list", category: "session", scope: "flow" })
|
|
1475
1466
|
knowledge({ action: "read", path: "<handoff-entry>" })
|
|
1476
1467
|
\`\`\`
|
|
1477
1468
|
|
|
1478
|
-
###
|
|
1469
|
+
### 2. Load the full handoff only when needed
|
|
1479
1470
|
|
|
1480
|
-
|
|
1471
|
+
Open the markdown file in \`.aikit-state/handoffs/\` if the compact entry lacks enough detail to act safely.
|
|
1481
1472
|
|
|
1482
|
-
|
|
1473
|
+
### 3. Verify live state before coding
|
|
1483
1474
|
|
|
1484
|
-
|
|
1475
|
+
Do a fast reality check:
|
|
1476
|
+
- Does current branch still match the handoff assumptions?
|
|
1477
|
+
- Do referenced files still exist?
|
|
1478
|
+
- Have blockers already been resolved?
|
|
1479
|
+
- Do stated next steps still make sense against current diff and tests?
|
|
1485
1480
|
|
|
1486
|
-
|
|
1481
|
+
Use the checklist in [references/resume-checklist.md](references/resume-checklist.md) for the verification pass.
|
|
1487
1482
|
|
|
1488
|
-
|
|
1489
|
-
2. Check if blockers have been resolved
|
|
1490
|
-
3. Validate assumptions still hold
|
|
1491
|
-
4. Review modified files for conflicts
|
|
1492
|
-
5. Check environment state
|
|
1483
|
+
### 4. Resume from the first actionable step
|
|
1493
1484
|
|
|
1494
|
-
|
|
1485
|
+
Begin with Next Step #1. If reality differs from the handoff, update the handoff or create a successor handoff instead of silently continuing on stale assumptions.
|
|
1495
1486
|
|
|
1496
|
-
|
|
1487
|
+
## Chaining Rule
|
|
1497
1488
|
|
|
1498
|
-
|
|
1499
|
-
- "Critical Files" for important locations
|
|
1500
|
-
- "Key Patterns Discovered" for conventions to follow
|
|
1501
|
-
- "Potential Gotchas" to avoid known issues
|
|
1489
|
+
For long-running work, create a successor handoff instead of overwriting history. Each new handoff should state what it supersedes and what changed since the previous handoff.
|
|
1502
1490
|
|
|
1503
|
-
|
|
1491
|
+
## Output Expectations
|
|
1504
1492
|
|
|
1505
|
-
|
|
1506
|
-
-
|
|
1507
|
-
-
|
|
1508
|
-
-
|
|
1509
|
-
|
|
1510
|
-
## Handoff Chaining
|
|
1511
|
-
|
|
1512
|
-
For long-running projects, chain handoffs together to maintain context lineage:
|
|
1513
|
-
|
|
1514
|
-
\`\`\`
|
|
1515
|
-
handoff-1.md (initial work)
|
|
1516
|
-
↓
|
|
1517
|
-
handoff-2.md --continues-from handoff-1.md
|
|
1518
|
-
↓
|
|
1519
|
-
handoff-3.md --continues-from handoff-2.md
|
|
1520
|
-
\`\`\`
|
|
1493
|
+
When asked to create a handoff, return:
|
|
1494
|
+
- Handoff status
|
|
1495
|
+
- File path written
|
|
1496
|
+
- Key decisions captured
|
|
1497
|
+
- Top blocker or next step
|
|
1521
1498
|
|
|
1522
|
-
|
|
1523
|
-
- Links to its predecessor
|
|
1524
|
-
- Can mark older handoffs as superseded
|
|
1525
|
-
- Provides context breadcrumbs for new agents
|
|
1526
|
-
|
|
1527
|
-
When resuming from a chain, read the most recent handoff first, then reference predecessors as needed.
|
|
1528
|
-
|
|
1529
|
-
## Storage Location
|
|
1530
|
-
|
|
1531
|
-
**Primary (flow-scoped):** \`.aikit-state/handoffs/{flow-slug}/\`
|
|
1532
|
-
**Standalone fallback:** \`.aikit-state/handoffs/_standalone/\` (when no flow is active)
|
|
1533
|
-
|
|
1534
|
-
All handoffs live in \`.aikit-state/\` which is gitignored — handoffs are ephemeral context, not project history.
|
|
1535
|
-
|
|
1536
|
-
Naming convention: \`YYYY-MM-DD-HHMMSS-[slug].md\`
|
|
1537
|
-
|
|
1538
|
-
Example: \`2024-01-15-143022-implementing-auth.md\`
|
|
1499
|
+
Do not return conversation transcripts or visual dashboards.
|
|
1539
1500
|
|
|
1540
1501
|
## Resources
|
|
1541
1502
|
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
| Script | Purpose |
|
|
1545
|
-
|--------|---------|
|
|
1546
|
-
| \`create_handoff.js [slug] [--continues-from <file>] [--flow <flow-slug>]\` | Generate new handoff with smart scaffolding |
|
|
1547
|
-
| \`list_handoffs.js [path]\` | List available handoffs in a project |
|
|
1548
|
-
| \`validate_handoff.js <file>\` | Check completeness, quality, and security |
|
|
1549
|
-
| \`check_staleness.js <file>\` | Assess if handoff context is still current |
|
|
1550
|
-
|
|
1551
|
-
### references/
|
|
1552
|
-
|
|
1553
|
-
- [handoff-template.md](references/handoff-template.md) - Complete template structure with guidance
|
|
1554
|
-
- [resume-checklist.md](references/resume-checklist.md) - Verification checklist for resuming agents
|
|
1503
|
+
- [references/handoff-template.md](references/handoff-template.md) - full markdown template when a simple structure is insufficient
|
|
1504
|
+
- [references/resume-checklist.md](references/resume-checklist.md) - verification checklist before resuming from saved context
|
|
1555
1505
|
`}];export{e as default};
|
|
@@ -14,6 +14,12 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
> Comprehensive TypeScript development patterns — type system performance, compiler configuration, advanced types, type safety, async patterns, module organization, and runtime optimization. Synthesized from pproenca TypeScript rules, TypeScript 6.0 features, wshobson advanced types and modern JS patterns, and Jeffallan typescript-pro patterns.
|
|
16
16
|
|
|
17
|
+
## Mindset
|
|
18
|
+
|
|
19
|
+
Type errors are specifications, not obstacles. Every red squiggle is the compiler telling you about a contract violation BEFORE runtime. Your job is to make impossible states unrepresentable — if the type system allows an invalid value, the design is wrong.
|
|
20
|
+
|
|
21
|
+
Think in terms of: narrowing (make types more specific at each step), branding (distinguish structurally identical types by meaning), and exhaustiveness (force the compiler to verify all cases are handled).
|
|
22
|
+
|
|
17
23
|
## When to Use
|
|
18
24
|
|
|
19
25
|
**MANDATORY** for the Implementer agent on every TypeScript task. Also use when:
|
|
@@ -22,6 +28,16 @@ metadata:
|
|
|
22
28
|
- Designing type-safe APIs, libraries, or utilities
|
|
23
29
|
- Optimizing type-check performance or build times
|
|
24
30
|
|
|
31
|
+
## NEVER
|
|
32
|
+
|
|
33
|
+
- **NEVER use \`as\` to silence type errors** — it hides bugs. Use type guards, assertion functions, or fix the upstream type instead. \`as\` is only acceptable for test mocks with \`as unknown as T\` pattern.
|
|
34
|
+
- **NEVER use \`any\` in exported signatures** — it infects every consumer. Use \`unknown\` + narrowing, generics, or explicit union types. \`any\` in implementation internals is tolerable if contained.
|
|
35
|
+
- **NEVER use \`!\` (non-null assertion) without a runtime guard** — it's a lie to the compiler. If you're sure it's not null, prove it with an \`if\` check or \`?? throw\`.
|
|
36
|
+
- **NEVER mix null and undefined semantics** — pick one convention per codebase. Prefer \`undefined\` for "not set" (matches optional properties), \`null\` for "explicitly empty" (matches DOM/JSON).
|
|
37
|
+
- **NEVER export mutable state as a shared type** — use \`readonly\` modifier, \`Readonly<T>\`, or \`ReadonlyArray<T>\`. Mutable shared state causes action-at-a-distance bugs that types cannot catch.
|
|
38
|
+
- **NEVER use \`enum\` in new code** — use \`as const\` objects or string literal unions. Enums have runtime cost, tree-shaking issues, and numeric enums allow unsafe access.
|
|
39
|
+
- **NEVER ignore generic constraints** — if a function works on "any array", type it as \`T extends readonly unknown[]\`, not \`T[]\`. Constraints document intent and catch misuse at call sites.
|
|
40
|
+
|
|
25
41
|
## Type System Performance
|
|
26
42
|
|
|
27
43
|
These rules prevent slow type-checking and IDE lag:
|