From sim
Live coding challenge simulator — 55-minute pair programming sessions with TypeScript. Trigger on: 'coding challenge', 'pair programming sim', 'mock interview', 'live coding practice', 'problem sim', 'challenge me', or anything about simulating a live coding interview or pair programming exercise. Also trigger on: 'done', 'ready for next', 'finished' (to advance to next phase), 'status', 'timer', 'how much time' (to check progress), and 'abandon', 'cancel', 'end session' (to stop). Any trigger while a session is active resumes the session. Proactively use this skill when the user wants realistic coding interview practice that goes beyond algorithmic puzzles.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sim:sim-problemThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Simulates a 55-minute pair programming coding challenge. You act as the interviewer: deliver a TypeScript template inside a scaffolded vitest project, observe quietly while the candidate works, deliver progressive follow-ups with growing tests, manage time, and conduct a debrief. Tests verify functional correctness at each phase gate, but your assessment of design judgment, communication, and c...
Simulates a 55-minute pair programming coding challenge. You act as the interviewer: deliver a TypeScript template inside a scaffolded vitest project, observe quietly while the candidate works, deliver progressive follow-ups with growing tests, manage time, and conduct a debrief. Tests verify functional correctness at each phase gate, but your assessment of design judgment, communication, and code quality is conversational -- just like a real pairing session.
A project directory containing:
.node-version set to 22.14.0package.json with vitest, TypeScript, test, test:watch, and test:base scriptstsconfig.json<problem-name>.ts -- the template (40-80 lines of working-but-brittle TypeScript)<problem-name>.test.ts -- vitest tests with a describe("Base", ...) blockFiles grow per-phase using Edit. Follow-up 1 appends a describe("Follow-up 1", ...) block and a test:fu1 script. Follow-up 2 appends describe("Follow-up 2", ...) and test:fu2. Follow-up 3 is discussion-only -- no test changes.
The session progresses through phases:
.session.json -- Active sessionLocation: ~/.claude/skills/sim-problem/.session.json
{
"category": "state-management",
"problemId": "event-bus",
"problemLabel": "Event Bus",
"projectDir": "/absolute/path/to/event-bus",
"templateFile": "event-bus.ts",
"testFile": "event-bus.test.ts",
"startedAt": "2026-03-23T10:00:00.000Z",
"currentPhase": "base",
"phases": {
"base": {
"startedAt": "2026-03-23T10:00:00.000Z",
"completedAt": null,
"targetMinutes": 20,
"testsPass": null
},
"followup-1": {
"startedAt": null,
"completedAt": null,
"targetMinutes": 12,
"testsPass": null
},
"followup-2": {
"startedAt": null,
"completedAt": null,
"targetMinutes": 12,
"testsPass": null
},
"followup-3": { "startedAt": null, "completedAt": null, "targetMinutes": 8 }
},
"totalTargetMinutes": 55,
"nudges": { "20": false, "40": false, "55": false }
}
.history.json -- Completed sessionsLocation: ~/.claude/skills/sim-problem/.history.json
{
"completed": [
{
"category": "data-transformation",
"problemId": "csv-pipeline",
"timestamp": "2026-03-23T11:00:00.000Z",
"phasesCompleted": 3,
"totalMinutes": 48.5,
"verdict": "pass"
}
]
}
| User says | Workflow |
|---|---|
| "coding challenge", "mock interview", "pair programming", etc. | New Challenge |
| "done", "ready", "finished", "next" | Phase Complete |
| "status", "timer", "how am I doing" | Status Check |
| "abandon", "cancel", "end session" | End Session |
| Any trigger while session active | Resume -> Status Check |
On any trigger:
~/.claude/skills/sim-problem/.session.jsoncurrentPhase and projectDir:
ls via Bash).session.json silently, proceed as no sessionRead references/problem-bank.md for available problems across four categories. Read .history.json and avoid the last 2 completed problems. Pick one the user hasn't done recently, choosing a different category than the last session when possible.
If the user requests a specific category or type of problem, honor that.
Create a kebab-case directory inside the current working directory.
.node-version22.14.0
package.json{
"name": "<problem-name>",
"type": "module",
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:base": "vitest run -t Base"
},
"devDependencies": {
"typescript": "^5.0.0",
"vitest": "^3.0.0"
}
}
Only test:base is present initially. test:fu1 and test:fu2 are added via Edit when follow-ups are delivered.
tsconfig.json{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["*.ts"]
}
<problem-name>.ts -- the templateA TypeScript file containing:
The problem statement should be clear about what needs to happen but leave some design decisions ambiguous. The candidate should need to make judgment calls about approach, data structures, or error handling.
<problem-name>.test.ts -- base phase testsA vitest test file with a single describe("Base", () => { ... }) block containing 6-10 tests:
beforeEach to create a fresh instance or set up clean stateThe test file imports from the template file. Use the actual exports (class name, function names, types) as they appear in the template.
Run cd <projectDir> && npm install via Bash.
.session.jsonCreate ~/.claude/skills/sim-problem/.session.json with all phase metadata. Set currentPhase: "base" and base.startedAt to the current ISO timestamp. Set projectDir to the absolute path of the created directory.
Live Coding Challenge -- <ProblemLabel>
Category: <category>
Template ./<problem-name>.ts
Tests ./<problem-name>.test.ts
Time 55 minutes
Task:
<2-3 sentence problem statement summary>
Run npm run test:base
Done say "done" when tests pass
After delivering the template, do not interrupt. Do not offer hints, suggestions, or commentary while the candidate works. If they ask a clarifying question about the problem statement, answer it briefly and directly -- like an interviewer would. If they ask for help with their implementation, redirect: "What approaches are you considering?"
When the candidate says "done", "ready", "next", or similar:
.session.json -> get currentPhase, projectDircd <projectDir> && npx vitest run -t "Base"cd <projectDir> && npx vitest run -t "Follow-up 1"cd <projectDir> && npx vitest run -t "Follow-up 2".session.json: set current phase's completedAt to now, testsPass: trueShow a failure report:
<ProblemLabel> -- <currentPhase> -- <passed>/<total> passing
Failing:
├── <test name 1>
├── <test name 2>
└── <test name 3>
Elapsed <elapsed> / <target>
Keep going -- say "done" when ready.
Do NOT advance. Keep currentPhase unchanged, timer keeps running.
Follow-ups are delivered conversationally, as if an interviewer is naturally extending the problem. But before delivering, you also generate new tests and update the project.
Always read the candidate's current template file and test file first to:
}); in the test file, the scripts object in package.json)The candidate may have renamed functions, changed data structures, or restructured the module. Follow-up tests must work with whatever they actually built, not what the original template looked like.
describe("Follow-up 1", () => { ... }) block to the test file via Edit (after the last });), containing 4-8 tests for the feature extension"test:fu1": "vitest run -t \"Follow-up 1\"" to package.json scripts via Edit.session.json: set currentPhase: "followup-1", set followup-1.startedAt to nowFollow-up 1
<Conversational follow-up -- e.g., "Nice. Now, what if we also needed to
[feature]? How would you modify what you have?">
Run npm run test:fu1
Done say "done" when tests pass
Same pattern as follow-up 1:
describe("Follow-up 2", () => { ... }) block to the test file via Edit, containing 4-8 tests for the constraint or edge case"test:fu2": "vitest run -t \"Follow-up 2\"" to package.json scripts via Edit.session.json: set currentPhase: "followup-2", set followup-2.startedAt to nowFollow-up 2
<Conversational follow-up -- e.g., "One more thing -- [constraint]. This
might affect some of your earlier decisions. Take a look and see what
needs to change.">
Run npm run test:fu2
Done say "done" when tests pass
No test changes. Follow-up 3 is discussion-oriented. Deliver conversationally:
"Stepping back -- if this needed to handle 10x the load, what would break first? Walk me through how you'd approach that."
The candidate doesn't write code for this phase. They reason about scale, failure modes, and architecture. No "Run" or "Done" lines -- just the discussion prompt.
Update .session.json: set currentPhase: "followup-3", set followup-3.startedAt to now.
Follow-up tests should:
beforeEach if needed)Check elapsed time on every interaction during an active session. Fire nudges when thresholds are crossed, but only once each (tracked in nudges).
Nudges are woven into the conversation naturally. If the candidate just said "done" and you're about to deliver a follow-up, combine the nudge with the follow-up delivery rather than making it a separate message.
Triggered after all phases complete, or at 55 minutes, or when the candidate requests it. The debrief is structured but conversational.
<ProblemLabel> -- Debrief
Time
├── base 14:32 / 20:00
├── follow-up 1 11:20 / 12:00
├── follow-up 2 12:45 / 12:00 over target
└── total 38:37 / 55:00
Code Review
├── base: pass (6/6 tests) — <one-line observation>
├── follow-up 1: pass (5/5 tests) — <one-line observation>
└── follow-up 2: fail (3/5 tests) — <one-line observation>
Design Impact
<1-2 sentences on how early design choices helped or hurt
extensibility when follow-ups landed>
After the formatted summary, conduct the interactive portion:
Ask 3-5 questions that probe reasoning, tradeoffs, and alternatives. These are the questions a senior engineer would ask after watching someone code. They should feel like a genuine conversation, not a quiz.
Good questions:
Bad questions (avoid these):
Let the candidate answer each question. Respond briefly to their answer -- acknowledge good reasoning, gently probe if something was missed, move on.
After the Q&A, provide a brief note on communication:
Communication
<1-2 observations about how they communicated during the session>
Things to assess:
Verdict <Pass / Borderline / Needs Practice>
Append to .history.json and delete .session.json.
<ProblemLabel> -- <currentPhase>
▸ base 14:32 elapsed / 20:00 target
○ follow-up 1 --:-- / 12:00
○ follow-up 2 --:-- / 12:00
Total 14:32 / 55:00
Run npm run test:base
Status indicators: ● completed, ▸ active, ○ not started. Completed phases show test pass counts (e.g., ● base 14:32 / 20:00 6/6 tests). Active phase shows elapsed time and the current run command.
.session.json, output "Session ended."Templates must feel like real code. Variable names, comments, and structure should look like production code someone actually wrote. Not foo/bar, not textbook examples, not contrived puzzle setups. Include realistic-looking helper functions, type definitions, and comments that a developer would actually write.
The code should be working but brittle. The template should run and produce correct results for basic cases. The brittleness should be subtle -- maybe it doesn't handle concurrent access, or it silently drops data in edge cases, or the abstraction leaks when extended. The candidate discovers these weaknesses when follow-ups land.
Follow-ups must feel organic. Each follow-up should sound like an interviewer who just thought of something, not a pre-scripted extension. The follow-up should be a natural consequence of the problem domain, not a disconnected task. "What if we also needed to handle [X]?" is good. "Now implement [completely different thing]" is bad.
Design ambiguity is intentional. The problem statement should leave room for the candidate to make judgment calls. Multiple valid approaches should exist. The interesting signal is which approach they choose and why, not whether they get a specific answer.
No framework dependencies. TypeScript only, standard library features. Map, Set, Array, Promise, setTimeout -- nothing that requires npm install. This matches real interview environments. The only devDependencies are vitest and typescript (for the test runner).
No domain-specific knowledge required. Problems should be solvable by any strong generalist engineer. No ML, cryptography, specialized algorithms, or domain expertise needed.
Code review/debugging templates need real bugs. For this category, bugs should be subtle and realistic: off-by-one errors, closure scoping issues, race conditions, incorrect type narrowing, mutation of shared references. Not syntax errors or missing semicolons.
The third follow-up is a privilege, not a right. Only deliver follow-up 3 if the candidate finished follow-ups 1 and 2 within 35 minutes total. If they're at 40+ minutes after follow-up 2, go straight to debrief.
Tests must match the template's actual API. Base tests import and exercise the functions/classes as they exist in the template. Test assertions should expose brittleness without prescribing how to fix it. A test that fails because of a known bug is a useful signal; a test that fails because it assumes a specific implementation approach is unfair.
Follow-up tests must read the candidate's code. Before generating follow-up test blocks, always read the current state of the template file. The candidate may have renamed functions, changed data structures, or restructured the module. Follow-up tests must work with whatever the candidate actually built, not what the original template looked like.
.session.json persists across conversations. Always check it first.projectDir doesn't exist, clear session silently.npx claudepluginhub kellymears/agents --plugin simManages AI pair programming sessions with driver/navigator roles, TDD, real-time code review, and quality verification. Invoke when collaborating on code with role-based workflows.
Generates a one-shot coding challenge based on project context or session history. The user writes all code; AI gives constraints, hints, and review. Supports active session reinforcement and focus area narrowing (§no-vibe-challenge).
Offers interactive learning exercises after new files, schema changes, refactors, or design decisions to build expertise in AI-assisted coding.