install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/xstate-machine-definition" ~/.claude/skills/intense-visions-harness-engineering-xstate-machine-definition && rm -rf "$T"
manifest:
agents/skills/claude-code/xstate-machine-definition/SKILL.mdsource content
XState Machine Definition
Define statecharts with createMachine for explicit states, transitions, context, and events
When to Use
- Modeling complex UI flows with multiple states (forms, wizards, authentication)
- Replacing boolean flag soup (
) with named statesisLoading && !isError && isSubmitted - Building workflows where illegal state transitions must be prevented
- Any feature where a state diagram would clarify the logic
Instructions
- Define the machine in a
file. Keep it separate from UI components..machine.ts - Start with the types: define
(extended state data) andContext
(a discriminated union of all possible events).Events - Use
withcreateMachine
,id
,initial
, andcontext
. Each state hasstates
for transitions.on - Name states as nouns or adjectives (
,idle
,loading
), not verbs.error - Name events as past-tense descriptions of what happened (
,SUBMITTED
,LOADED
) or imperative commands (ERRORED
,SUBMIT
).RETRY - Use
for the destination state. Omittarget
for self-transitions that only run actions.target - Keep machines pure — no side effects in the machine definition itself. Use actions and services for effects.
// auth.machine.ts import { createMachine, assign } from 'xstate'; interface AuthContext { user: { id: string; name: string } | null; error: string | null; retries: number; } type AuthEvent = | { type: 'LOGIN'; email: string; password: string } | { type: 'LOGOUT' } | { type: 'RETRY' } | { type: 'done.invoke.authenticate'; data: { id: string; name: string } } | { type: 'error.platform.authenticate'; data: Error }; const authMachine = createMachine<AuthContext, AuthEvent>({ id: 'auth', initial: 'idle', context: { user: null, error: null, retries: 0, }, states: { idle: { on: { LOGIN: 'authenticating', }, }, authenticating: { invoke: { id: 'authenticate', src: 'authenticateUser', onDone: { target: 'authenticated', actions: assign({ user: (_, event) => event.data, error: null }), }, onError: { target: 'error', actions: assign({ error: (_, event) => event.data.message, retries: (ctx) => ctx.retries + 1, }), }, }, }, authenticated: { on: { LOGOUT: { target: 'idle', actions: assign({ user: null }), }, }, }, error: { on: { RETRY: { target: 'authenticating', guard: 'canRetry', }, LOGIN: 'authenticating', }, }, }, }); export { authMachine };
Details
Context vs state: "State" in XState means the finite state node (idle, loading, error). "Context" is the extended state — arbitrary data that travels with the machine. Use finite states for mode/phase, context for data.
XState v5 changes: If using XState v5, the API shifts to
setup().createMachine() with a different structure:
import { setup, assign } from 'xstate'; const machine = setup({ types: {} as { context: AuthContext; events: AuthEvent; }, guards: { canRetry: ({ context }) => context.retries < 3 }, actions: { clearUser: assign({ user: null }) }, }).createMachine({ id: 'auth', initial: 'idle', context: { user: null, error: null, retries: 0 }, states: { /* ... */ }, });
State node types:
— leaf node, no child states (default)atomic
— has child states (nested)compound
— all child states active simultaneouslyparallel
— terminal state, triggersfinal
in the parentonDone
— remembers the last active child statehistory
Design principles:
- Every event should be handled in every state, even if the handler is a no-op. Unhandled events are silently ignored, which can mask bugs.
- Draw the state diagram first, code second. XState machines are visual — use Stately.ai or the VS Code extension.
- Prefer fewer top-level states with nested substates over many flat states.
Source
https://stately.ai/docs/machines
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.