mpsuesser

Effect Claudecode — Development skill for Claude Code

Development community

Effect v4 bindings for Claude Code's plugin primitives — hooks, skills, settings, MCP servers, frontmatter.

How to install Effect Claudecode

This entry records only its repository, not the path inside it, so there is no exact command to give. Open mpsuesser/effect-claudecode and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

What Effect Claudecode does

Effect v4 bindings for Claude Code's plugin primitives — hooks, skills, settings, MCP servers, frontmatter.

Alternatives in Development

README

effect-claudecode

Write [Claude Code](https://code.claude.com) plugins — hooks, skills, subagents, commands, MCP servers — with [Effect v4](https://effect.website).

Install

npm install effect-claudecode effect@4.0.0-beta.80 @effect/platform-node-shared@4.0.0-beta.80
bun add effect-claudecode effect@4.0.0-beta.80 @effect/platform-node-shared@4.0.0-beta.80

Before / After

A vanilla Claude Code hook that rewrites `npm test` to `bun run test`:

// hooks/rewrite-test.js — vanilla Node.js
let data = '';
process.stdin.on('data', (chunk) => (data += chunk));
process.stdin.on('end', () => {
  const input = JSON.parse(data);
  const command = input.tool_input?.command ?? '';
  const output = command.startsWith('npm test')
    ? { continue: true, hookSpecificOutput: {
        hookEventName: 'PreToolUse',
        updatedInput: { command: command.replace('npm test', 'bun run test') },
        permissionDecision: 'allow',
        permissionDecisionReason: 'This workspace runs tests through Bun.'
      }}
    : { continue: true };
  process.stdout.write(JSON.stringify(output));
  process.exit(0);
});

The same hook with effect-claudecode:

import * as Effect from 'effect/Effect';
import * as Str from 'effect/String';
import { Hook } from 'effect-claudecode';

const hook = Hook.PreToolUse.onTool({
  toolName: 'Bash',
  handler: ({ tool }) =>
    Effect.succeed(
      Str.startsWith('npm test')(tool.command)
        ? Hook.PreToolUse.allowWithUpdatedInput(
            { command: Str.replace('npm test', 'bun run test')(tool.command) },
            'This workspace runs tests through Bun.'
          )
        : Hook.PreToolUse.allow()
    )
});

Hook.runMain(hook);

Typed tool payloads, decision constructors, correct exit-code semantics — no stdin plumbing, no manual JSON, no `process.exit`.

What You Can Build

Detect when Claude is stuck in a loop

Every Claude Code user has watched Claude read the same file three times in a