From harness-claude
Generates full type safety for XState machines using the v5 setup pattern or v4 typegen. Helps with TypeScript errors on event types, guards, and actions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:xstate-typegenThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Generate full type safety for XState machines with typegen (v4) and the setup pattern (v5)
Generate full type safety for XState machines with typegen (v4) and the setup pattern (v5)
setup() to declare all types, actions, guards, actors, and delays before creating the machine.types with TypeScript as assertion for context, events, input, and output.setup() — runtime errors if missing.setup() declaration — no separate code generation step.// auth.machine.ts (v5)
import { setup, assign, fromPromise } from 'xstate';
interface AuthContext {
user: { id: string; name: string } | null;
error: string | null;
}
type AuthEvent = { type: 'LOGIN'; email: string; password: string } | { type: 'LOGOUT' };
const authMachine = setup({
types: {} as {
context: AuthContext;
events: AuthEvent;
input: { redirectUrl?: string };
},
actors: {
authenticate: fromPromise(async ({ input }: { input: { email: string; password: string } }) => {
const res = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(input),
});
if (!res.ok) throw new Error('Auth failed');
return res.json() as Promise<{ id: string; name: string }>;
}),
},
actions: {
setUser: assign({
user: (_, params: { id: string; name: string }) => params,
}),
clearUser: assign({ user: null, error: null }),
setError: assign({
error: (_, params: { message: string }) => params.message,
}),
},
guards: {
isAuthenticated: ({ context }) => context.user !== null,
},
}).createMachine({
id: 'auth',
initial: 'idle',
context: ({ input }) => ({
user: null,
error: null,
}),
states: {
idle: {
on: { LOGIN: 'authenticating' },
},
authenticating: {
invoke: {
src: 'authenticate',
input: ({ event }) => ({
email: (event as { email: string }).email,
password: (event as { password: string }).password,
}),
onDone: {
target: 'authenticated',
actions: { type: 'setUser', params: ({ event }) => event.output },
},
onError: {
target: 'error',
actions: {
type: 'setError',
params: ({ event }) => ({ message: (event.error as Error).message }),
},
},
},
},
authenticated: {
on: { LOGOUT: { target: 'idle', actions: 'clearUser' } },
},
error: {
on: { LOGIN: 'authenticating' },
},
},
});
@xstate/cli: npm install -D @xstate/cli.tsTypes: {} to the machine config to enable typegen.xstate typegen "src/**/*.machine.ts" to generate .typegen.ts files.// v4 with typegen
import { createMachine } from 'xstate';
const machine = createMachine({
tsTypes: {} as import('./auth.machine.typegen').Typegen0,
schema: {
context: {} as AuthContext,
events: {} as AuthEvent,
services: {} as { authenticate: { data: User } },
},
// ...
});
v5 setup benefits over v4 typegen:
setup() directlyfromPromise, fromCallback, etc..typegen.ts files to maintain or commitTyping event narrowing in actions: In v5, action implementations receive the full event union. Narrow when needed:
actions: {
handleLogin: ({ event }) => {
if (event.type === 'LOGIN') {
console.log(event.email); // Typed correctly
}
},
},
Common type issues:
Type 'string' is not assignable to type 'never' in transitions — usually means the event is not listed in the events typesetup() — v5 requires all referenced names to be declared upfrontcontext function returnhttps://stately.ai/docs/typescript
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeDefines statecharts with XState's createMachine for explicit states, transitions, context, and events. Useful for modeling complex UI flows and preventing illegal state transitions.
Builds, tests, and debugs event-driven state machines in Laravel using EventMachine. Activates on state machine definitions, behaviors, test assertions, parallel states, delegation, timers, and endpoints.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.