Skip to content
Agent Orchestration
Hook

Hooks

What xenitv1-maestro runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
xenitv1-maestro
22912 skills1 agent1 command7 hooks
+1

Claude Code

> /plugin marketplace add xenitv1/claude-code-maestro
> /plugin install maestro@maestro-marketplace

What fires, and when

SessionStart

Fires once when a session begins, and again after a context compaction. It is where a plugin sets up its environment, or restores state the compaction dropped.

  • node "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js"

PreCompact

  • Matches*node "${CLAUDE_PLUGIN_ROOT}/hooks/pre-compact.js"node "${CLAUDE_PLUGIN_ROOT}/hooks/brain-sync.js"

SubagentStop

  • echo {}

Stop

  • node "${CLAUDE_PLUGIN_ROOT}/hooks/stop.js"node "${CLAUDE_PLUGIN_ROOT}/hooks/brain-sync.js"

PostToolUse

  • Matches*node "${CLAUDE_PLUGIN_ROOT}/hooks/brain-sync.js"

PostToolUseFailure

  • Matches*node "${CLAUDE_PLUGIN_ROOT}/hooks/brain-sync.js"

UserPromptSubmit

Fires before Claude sees each prompt you send. A plugin can use it to inject context, so the same instruction reaches the model every turn instead of only at session start.

  • node "${CLAUDE_PLUGIN_ROOT}/hooks/brain-sync.js"
Read hooks/hooks.json

In the plugin's words

How xenitv1-maestro describes its own hook set.

Maestro plugin hooks for AI memory (LTM) and Ralph Wiggum persistence

Where it lives

  • hooks/brain-sync.jsRunsGitHub
    Read the script
    #!/usr/bin/env node
    /**
     * Brain Sync Hook - Auto-Memory System
     * Runs after every tool use, extracts AI memory to brain.jsonl
     * 
     * @event PostToolUse
     */
    
    const fs = require('fs');
    const path = require('path');
    const {
      findProjectRoot,
      getMaestroDir,
      getClaudeProjectsDir,
      normalizeProjectPath,
      ensureMaestroDir,
      loadState,
      saveState,
      isReadOnlyTool,
      logDebug,
      cleanAnsi,
      getTimestamp,
      readStdin,
      outputJson
    } = require('./lib/utils');
    
    const {
      readPreservedBrain,
      writeBrain,
      dedupe
    } = require('./lib/brain');
    
    const LOG_PREFIX = '[BRAIN-SYNC]';
    
    // Maximum file size to read (50MB) - for full read
    // Files larger than this will use streaming
    const MAX_JSONL_SIZE = 50 * 1024 * 1024;
    const STREAMING_THRESHOLD = 50 * 1024 * 1024; // Use streaming for files > 50MB
    
    /**
     * Detect active Claude CLI session from cwd.
     */
    function getActiveSession(projectRoot) {
      logDebug(LOG_PREFIX, `Project root: ${projectRoot}`);
    
      try {
        // STALE CONTEXT GUARD: Detect if project is empty
        // Only check if it's a directory (might be a newly created empty folder)
        if (fs.existsSync(projectRoot) && fs.lstatSync(projectRoot).isDirectory()) {
          const rootEntries = fs.readdirSync(projectRoot);
          const hasProjectFiles = rootEntries.some(e => !['.git', '.maestro', '.claude'].includes(e));
          if (!hasProjectFiles) {
            logDebug(LOG_PREFIX, 'Project directory empty (except meta) - treated as FRESH START. Skipping legacy session recovery.');
            return { sessionId: null, mainJsonl: null, subagentDir: null };
          }
        }
    
        const claudeProjectsDir = getClaudeProjectsDir();
        if (!fs.existsSync(claudeProjectsDir)) {
          return { sessionId: null, mainJsonl: null, subagentDir: null };
        }
    
        // Normalize project path for matching
        const cwdNormalized = normalizeProjectPath(projectRoot);
        let projectDir = null;
    
        // Find matching project directory (case-insensitive for Windows compatibility)
        const entries = fs.readdirSync(claudeProjectsDir);
        // 1. Try exact match first
        for (const entry of entries) {
          if (entry.toLowerCase() === cwdNormalized.toLowerCase()) {
            projectDir = path.join(claudeProjectsDir, entry);
            break;
          }
        }
    
        // 2. Try prefix match if exact match fails (case-insensitive)
        if (!projectDir) {
          for (const entry of entries) {
            const entryLower = entry.toLowerCase();
            const cwdLower = cwdNormalized.toLowerCase();
            if (cwdLower && (entryLower.startsWith(cwdLower) || cwdLower.startsWith(entryLower))) {
              projectDir = path.join(claudeProjectsDir, entry);
              break;
            }
          }
        }
    
        if (!projectDir) {
          return { sessionId: null, mainJsonl: null, subagentDir: null };
        }
    
        // Try to find session from .jsonl files
        const jsonlFiles = fs.readdirSync(projectDir)
          .filter(f => f.endsWith('.jsonl'))
          .map(f => ({
            name: f,
            path: path.join(projectDir, f),
            mtime: fs.statSync(path.join(projectDir, f)).mtimeMs
          }))
          .sort((a, b) => b.mtime - a.mtime);
    
        if (jsonlFiles.length > 0) {
          const latestJsonl = jsonlFiles[0];
          const sessionId = latestJsonl.name.replace('.jsonl', '');
          const mainJsonl = latestJsonl.path;
          const subagentDir = path.join(projectDir, sessionId, 'subagents');
    
          logDebug(LOG_PREFIX, `Session: ${sessionId}`);
          return { sessionId, mainJsonl, subagentDir };
        }
    
        // Fallback: read sessions-index.json
        const indexFile = path.join(projectDir, 'sessions-index.json');
        if (fs.existsSync(indexFile)) {
          const indexData = JSON.parse(fs.readFileSync(indexFile, 'utf-8'));
          const sessions = indexData.entries || [];
    
          if (sessions.length > 0) {
            // Get most recent session
            const latestSession = sessions.sort((a, b) =>
              (b.fileMtime || 0) - (a.fileMtime || 0)
            )[0];
    
            const sessionId = latestSession.sessionId;
            const subagentDir = path.join(projectDir, sessionId, 'subagents');
            const mainJsonl = path.join(projectDir, `${sessionId}.jsonl`);
    
            logDebug(LOG_PREFIX, `Session (from index): ${sessionId}`);
            return { sessionId, mainJsonl, subagentDir };
          }
        }
    
        return { sessionId: null, mainJsonl: null, subagentDir: null };
    
      } catch (err) {
        logDebug(LOG_PREFIX, `Session detection error: ${err.message}`);
        return { sessionId: null, mainJsonl: null, subagentDir: null };
      }
    }
    
    /**
     * Read JSONL file incrementally using offset tracking.
     */
    function readJsonlIncremental(filePath, sessionId, callback) {
      const syncState = loadState('sync', findProjectRoot()) || {};
      const fileKey = `${sessionId}:${path.basename(filePath)}`;
      const startOffset = syncState[fileKey] || 0;
    
      const stats = fs.statSync(filePath);
      if (stats.size < startOffset) {
        // File was rotated or cleared
        logDebug(LOG_PREFIX, `File ${fileKey} shrunk, resetting offset`);
      }
    
      const currentStart = stats.size < startOffset ? 0 : startOffset;
    
      if (currentStart >= stats.size) {
        logDebug(LOG_PREFIX, `No new content in ${fileKey}`);
        return Promise.resolve();
      }
    
      logDebug(LOG_PREFIX, `Reading ${fileKey} from offset ${currentStart}`);
    
      // Open file for reading
      const fd = fs.openSync(filePath, 'r');
      const bufferSize = 64 * 1024;
      const buffer = Buffer.alloc(bufferSize);
      let bytesRead;
      let leftover = '';
      let currentOffset = currentStart;
    
      while ((bytesRead = fs.readSync(fd, buffer, 0, bufferSize, currentOffset)) > 0) {
        currentOffset += bytesRead;
        const chunk = leftover + buffer.toString('utf-8', 0, bytesRead);
        const lines = chunk.split('\n');
        leftover = lines.pop(); // Last line might be incomplete
    
        for (const line of lines) {
          if (line.trim()) {
            try {
              callback(JSON.parse(line));
            } catch (err) { /* Skip invalid */ }
          }
        }
      }
    
      fs.closeSync(fd);
    
      // Save new offset
      syncState[fileKey] = currentOffset;
      s
  • hooks/pre-compact.jsRunsGitHub
    Read the script
    #!/usr/bin/env node
    /**
     * Pre-Compact Hook - Compact Summary Capture
     * Captures compact summaries before/after manual /compact command
     * and persists them to brain.jsonl for cross-session memory.
     *
     * @event PreCompact
     * @matcher manual - Triggered by /compact command
     */
    
    const fs = require('fs');
    const path = require('path');
    
    const {
      findProjectRoot,
      getMaestroDir,
      ensureMaestroDir,
      getClaudeProjectsDir,
      normalizeProjectPath,
      loadState,
      saveState,
      logDebug,
      readStdin,
      outputJson
    } = require('./lib/utils');
    
    const {
      readBrain,
      writeBrain,
      appendToBrain,
      extractLastSummary,
      writeCompactToBrain
    } = require('./lib/brain');
    
    const LOG_PREFIX = '[PRE-COMPACT]';
    
    /**
     * Find the current active session transcript.
     */
    function getCurrentTranscript() {
      try {
        const claudeProjectsDir = getClaudeProjectsDir();
        if (!fs.existsSync(claudeProjectsDir)) {
          return null;
        }
    
        const projectRoot = findProjectRoot();
        const cwdNormalized = normalizeProjectPath(projectRoot);
        let projectDir = null;
    
        // Find matching project directory (case-insensitive for Windows compatibility)
        const entries = fs.readdirSync(claudeProjectsDir);
        for (const entry of entries) {
          if (entry.toLowerCase() === cwdNormalized.toLowerCase()) {
            projectDir = path.join(claudeProjectsDir, entry);
            break;
          }
        }
    
        // Prefix match fallback (case-insensitive)
        if (!projectDir) {
          for (const entry of entries) {
            const entryLower = entry.toLowerCase();
            const cwdLower = cwdNormalized.toLowerCase();
            if (cwdLower && (entryLower.startsWith(cwdLower) || cwdLower.startsWith(entryLower))) {
              projectDir = path.join(claudeProjectsDir, entry);
              break;
            }
          }
        }
    
        if (!projectDir) {
          return null;
        }
    
        // Find most recent JSONL file
        const jsonlFiles = fs.readdirSync(projectDir)
          .filter(f => f.endsWith('.jsonl'))
          .map(f => ({
            name: f,
            path: path.join(projectDir, f),
            mtime: fs.statSync(path.join(projectDir, f)).mtimeMs
          }))
          .sort((a, b) => b.mtime - a.mtime);
    
        if (jsonlFiles.length > 0) {
          return jsonlFiles[0].path;
        }
    
        return null;
      } catch (err) {
        logDebug(LOG_PREFIX, `Error finding transcript: ${err.message}`);
        return null;
      }
    }
    
    
    /**
     * Main hook entry point.
     */
    async function main() {
      const projectRoot = findProjectRoot();
    
      logDebug(LOG_PREFIX, '='.repeat(60));
      logDebug(LOG_PREFIX, 'PRE-COMPACT HOOK TRIGGERED');
      logDebug(LOG_PREFIX, `Project Root: ${projectRoot}`);
    
      try {
        // Read hook input
        const hookInput = await readStdin();
        logDebug(LOG_PREFIX, `Hook input: trigger=${hookInput.trigger}, custom_instructions=${hookInput.custom_instructions ? 'yes' : 'no'}`);
    
        // Only process manual compacts
        if (hookInput.trigger !== 'manual') {
          outputJson({});
          return;
        }
    
        // Get current transcript
        const transcriptPath = hookInput.transcript_path || getCurrentTranscript();
        logDebug(LOG_PREFIX, `Current transcript: ${transcriptPath ? path.basename(transcriptPath) : 'none'}`);
    
        if (!transcriptPath) {
          outputJson({});
          return;
        }
    
        // Extract last summary from transcript
        const summary = extractLastSummary(transcriptPath);
        logDebug(LOG_PREFIX, `Summary found: ${summary ? 'yes (' + summary.length + ' chars)' : 'no'}`);
    
        if (summary) {
          // Write to brain.jsonl
          writeCompactToBrain(summary, projectRoot);
    
          // Also save to state for reference if needed
          saveState('last-compact', {
            summary: summary.substring(0, 5000),
            timestamp: Date.now(),
            trigger: 'manual'
          }, projectRoot);
    
          // Output context for the new session
          outputJson({
            type: 'compact_capture',
            hookSpecificOutput: {
              hookEventName: 'PreCompact',
              additionalContext: `
    ✅ Current summary captured and saved to brain.jsonl.
    Note: Compaction will now continue and a new summary will be generated.
    `
            }
          });
    
          logDebug(LOG_PREFIX, 'Pre-compact hook completed successfully');
        } else {
          // It's normal to not find a summary in PreCompact because it hasn't been generated yet for this compaction.
          // But we output OK anyway.
          outputJson({});
          logDebug(LOG_PREFIX, 'No pre-existing compact summary found in current transcript.');
        }
    
      } catch (err) {
        logDebug(LOG_PREFIX, `Hook error: ${err.message}`);
        logDebug(LOG_PREFIX, `Stack: ${err.stack}`);
        outputJson({});
      }
    }
    
    main();
    
  • hooks/session-start.jsRunsGitHub
    Read the script
    #!/usr/bin/env node
    /**
     * Session Start Hook for Maestro Plugin
     * Reads brain.jsonl and project context when a new session begins.
     * Analyzes package.json for tech stack info and stores in LTM.
     * 
     * @event SessionStart
     */
    
    const fs = require('fs');
    const path = require('path');
    const {
      findProjectRoot,
      getMaestroDir,
      ensureMaestroDir,
      readFileSafe,
      getFileHash,
      readStdin,
      logDebug,
      outputJson
    } = require('./lib/utils');
    
    const {
      formatBrainForContext,
      writeTechToBrain,
      extractLastSummary,
      writeCompactToBrain
    } = require('./lib/brain');
    
    const LOG_PREFIX = '[SESSION-START]';
    
    // Framework detection patterns
    const FRAMEWORK_PATTERNS = {
      'next.js': { deps: ['next'], files: ['next.config.js', 'next.config.mjs', 'next.config.ts'] },
      'react': { deps: ['react', 'react-dom'], files: [] },
      'vue': { deps: ['vue'], files: ['vue.config.js', 'nuxt.config.js'] },
      'nuxt': { deps: ['nuxt'], files: ['nuxt.config.js', 'nuxt.config.ts'] },
      'angular': { deps: ['@angular/core'], files: ['angular.json'] },
      'svelte': { deps: ['svelte'], files: ['svelte.config.js'] },
      'express': { deps: ['express'], files: [] },
      'fastify': { deps: ['fastify'], files: [] },
      'nestjs': { deps: ['@nestjs/core'], files: ['nest-cli.json'] },
      'electron': { deps: ['electron'], files: [] },
      'tauri': { deps: ['@tauri-apps/api'], files: ['tauri.conf.json'] },
      'astro': { deps: ['astro'], files: ['astro.config.mjs'] },
      'remix': { deps: ['@remix-run/react'], files: ['remix.config.js'] },
      'gatsby': { deps: ['gatsby'], files: ['gatsby-config.js'] }
    };
    
    // Important dependencies to track
    const IMPORTANT_DEPS = {
      // State management
      'zustand': 'State (Zustand)',
      'redux': 'State (Redux)',
      'recoil': 'State (Recoil)',
      'jotai': 'State (Jotai)',
      'mobx': 'State (MobX)',
      '@tanstack/react-query': 'Data Fetching (React Query)',
      'swr': 'Data Fetching (SWR)',
    
      // Styling
      'tailwindcss': 'Styling (Tailwind)',
      'styled-components': 'Styling (Styled Components)',
      '@emotion/react': 'Styling (Emotion)',
      'sass': 'Styling (SASS)',
      '@mui/material': 'UI (Material UI)',
      '@chakra-ui/react': 'UI (Chakra)',
      'antd': 'UI (Ant Design)',
      'shadcn-ui': 'UI (shadcn)',
    
      // Database
      'prisma': 'ORM (Prisma)',
      '@prisma/client': 'ORM (Prisma)',
      'drizzle-orm': 'ORM (Drizzle)',
      'typeorm': 'ORM (TypeORM)',
      'mongoose': 'ODM (Mongoose)',
      'sequelize': 'ORM (Sequelize)',
    
      // Auth
      'next-auth': 'Auth (NextAuth)',
      '@clerk/nextjs': 'Auth (Clerk)',
      '@supabase/supabase-js': 'Backend (Supabase)',
      'firebase': 'Backend (Firebase)',
    
      // Testing
      'jest': 'Testing (Jest)',
      'vitest': 'Testing (Vitest)',
      '@testing-library/react': 'Testing (RTL)',
      'playwright': 'E2E (Playwright)',
      'cypress': 'E2E (Cypress)',
    
      // Build tools
      'vite': 'Build (Vite)',
      'webpack': 'Build (Webpack)',
      'esbuild': 'Build (esbuild)',
      'turbo': 'Monorepo (Turborepo)',
    
      // Utilities
      'zod': 'Validation (Zod)',
      'yup': 'Validation (Yup)',
      'axios': 'HTTP (Axios)',
      'date-fns': 'Dates (date-fns)',
      'dayjs': 'Dates (Day.js)',
      'lodash': 'Utils (Lodash)',
      'framer-motion': 'Animation (Framer)'
    };
    
    /**
     * Check if tech stack needs re-analysis (package.json changed).
     */
    function shouldReanalyzeTech(projectRoot) {
      const pkgPath = path.join(projectRoot, 'package.json');
      const hashFile = path.join(getMaestroDir(projectRoot), '.tech_hash');
    
      const currentHash = getFileHash(pkgPath);
      if (!currentHash) {
        return false; // No package.json
      }
    
      if (fs.existsSync(hashFile)) {
        try {
          const storedHash = fs.readFileSync(hashFile, 'utf-8').trim();
          if (storedHash === currentHash) {
            return false; // No change
          }
        } catch (err) {
          // Continue with reanalysis
        }
      }
    
      return true;
    }
    
    /**
     * Save current package.json hash.
     */
    function saveTechHash(projectRoot) {
      const pkgPath = path.join(projectRoot, 'package.json');
      const hashFile = path.join(ensureMaestroDir(projectRoot), '.tech_hash');
    
      const hash = getFileHash(pkgPath);
      if (hash) {
        try {
          fs.writeFileSync(hashFile, hash, 'utf-8');
        } catch (err) {
          logDebug(LOG_PREFIX, `Error saving tech hash: ${err.message}`);
        }
      }
    }
    
    /**
     * Analyze package.json and extract tech stack info.
     */
    function analyzePackageJson(projectRoot) {
      const pkgPath = path.join(projectRoot, 'package.json');
    
      if (!fs.existsSync(pkgPath)) {
        logDebug(LOG_PREFIX, 'No package.json found');
        return null;
      }
    
      try {
        const pkgContent = fs.readFileSync(pkgPath, 'utf-8');
        const pkg = JSON.parse(pkgContent);
    
        const result = {
          name: pkg.name || 'unknown',
          version: pkg.version || '0.0.0',
          description: pkg.description || '',
          frameworks: [],
          frameworkVersions: {},
          keyDeps: [],
          devTools: [],
          scripts: {},
          nodeVersion: null,
          packageManager: null,
          type: pkg.type || 'commonjs'
        };
    
        // Combine all dependencies
        const allDeps = {
          ...pkg.dependencies,
          ...pkg.devDependencies
        };
    
        // Detect frameworks
        for (const [framework, patterns] of Object.entries(FRAMEWORK_PATTERNS)) {
          // Check dependencies
          for (const dep of patterns.deps) {
            if (allDeps[dep]) {
              if (!result.frameworks.includes(framework)) {
                result.frameworks.push(framework);
              }
              // Capture version
              const version = allDeps[dep].replace(/[\^~>=<]/g, '');
              result.frameworkVersions[dep] = version;
              break;
            }
          }
    
          // Check config files
          for (const cfgFile of patterns.files) {
            if (fs.existsSync(path.join(projectRoot, cfgFile))) {
              if (!result.frameworks.includes(framework)) {
                result.frameworks.push(framework);
              }
              break;
            }
          }
        }
    
        // Always capture React version if present
        if (allDeps['react'] && !result.frameworkVersions['react']) {
          result.frameworkVersions['react'] = allDeps['reac
  • hooks/stop.jsRunsGitHub
    Read the script
    #!/usr/bin/env node
    /**
     * Stop Hook for Maestro Plugin (Ralph Wiggum Controller)
     * Controls whether Claude can exit or must continue iterating.
     *
     * @event Stop, SubagentStop
     */
    
    const {
      findProjectRoot,
      logDebug,
      readStdin,
      outputJson
    } = require('./lib/utils');
    
    const Ralph = require('./lib/ralph');
    
    const LOG_PREFIX = '[STOP]';
    
    /**
     * Main hook entry point.
     */
    async function main() {
      const projectRoot = findProjectRoot();
    
      logDebug(LOG_PREFIX, '='.repeat(60));
      logDebug(LOG_PREFIX, 'STOP HOOK TRIGGERED');
    
      try {
        const hookInput = await readStdin();
        const inputData = JSON.stringify(hookInput);
    
        // Check if this is a SubagentStop event
        const hookEvent = hookInput.hookEventName || '';
        const isSubagentStop = hookEvent === 'SubagentStop' ||
          inputData.toLowerCase().includes('subagent');
    
        if (isSubagentStop) {
          logDebug(LOG_PREFIX, 'SUBAGENT STOP detected - allowing subagent to complete');
          outputJson({});
          process.exit(0);
          return;
        }
    
        // Check Ralph Wiggum iteration state
        const decision = Ralph.getBlockDecision();
    
        if (!decision.block) {
          // Allow exit
          logDebug(LOG_PREFIX, `Exit allowed: ${decision.reason}`);
    
          // Cleanup if completed
          if (decision.completed) {
            logDebug(LOG_PREFIX, 'Ralph Wiggum completed - cleaning up state');
            Ralph.clearState();
          }
    
          outputJson({});
          process.exit(0);
          return;
        }
    
        // Block exit - Ralph wants more iterations
        logDebug(LOG_PREFIX, `Exit BLOCKED: ${decision.reason} (${decision.current}/${decision.max})`);
    
        // Build continuation message
        const continuationMessage = `
    🔄 RALPH WIGGUM 2.0: ELITE PERSISTENCE ACTIVE
    
    ## 📊 Iteration Status
    **Progress:** ${decision.current} / ${decision.max}
    
    ## ⚠️ TASK COMPLETION BLOCKED
    
    Ralph Wiggum requires more iterations to ensure quality standards are met.
    
    ### Next Steps:
    1. Continue testing and fixing issues
    2. Run tests again to verify fixes
    3. Check verification matrix coverage
    4. Ensure all critical tests pass
    
    The task will remain blocked until:
    - All tests pass OR
    - Maximum iterations reached OR
    - Manual completion signal received
    
    ---
    
    **To manually complete:** Create .maestro/ralph.complete file
    **To stop early:** Delete .maestro/ralph.active file
    `;
    
        // Block the exit with continuation prompt
        outputJson({
          block: true,
          message: continuationMessage.trim(),
          iteration: decision.current,
          maxIterations: decision.max
        });
    
        process.exit(0);
    
      } catch (err) {
        logDebug(LOG_PREFIX, `Error: ${err.message}`);
        outputJson({});
      }
    }
    
    main();
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@xenitv1
Ships withxenitv1-maestro

Elite-tier orchestration framework for Claude Code CLI. Supercharges AI development through specialized agents, modular skills, intelligent hooks, and persistent memory systems. Author: xenitV1 • X/Twitter Philosophy: "Why over How.

22912 skills1 agent1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
229
Star history of xenitv1/claude-code-maestro on GitHub, a chart by star-history.com

More plugins that ship hooks.

oh-my-claudecode
Plugin

oh-my-claudecode

Splits a complex task across several specialized Claude Code agents working in parallel, then keeps going until the result is checked. You describe what you want in plain language instead of memorizing commands.

48 skills+440k
@yeachan-heo@yeachan-heo
Install Plugin
ouroboros
Plugin

ouroboros

Turns a rough feature idea into a written spec through guided questions, then has the agent build it and checks the result against that spec. Instead of hand-checking whether the work is finished, you get an automatic evaluation gate that runs in your coding agent.

25 skills+36.3k
@q00@q00
Install Plugin
stellarlinkco-myclaude
Plugin

stellarlinkco-myclaude

A plugin that runs coding tasks through multiple AI backends (Codex, Claude, Gemini, OpenCode) with a structured development workflow, parallel execution, browser automation and multi-session task checkpointing.

11 skills+32.7k
@stellarlinkco@stellarlinkco
Install Plugin
harmonist
Plugin

harmonist

Coordinates AI agents with mechanical protocol enforcement, a workflow gate, memory validation and a session hook. Includes a catalog of specialist agents and has no runtime dependencies.

199 agents+12.3k
@gammalabtechnologies@gammalabtechnologies
Install Plugin
bernstein
Plugin

bernstein

Bernstein is a Claude Code plugin for orchestrating AI agents. It adds skills to list and inspect agents, review and approve tasks, create tasks, track costs and budgets, and show alerts for failed or stalled work.

26 skills+41.3k
@sipyourdrink-ltd@sipyourdrink-ltd
Install Plugin
fablize
Plugin

fablize

A Claude Code plugin that enforces finishing multi-step tasks with evidence and verification at each stage. It works as a procedure for Opus or any Claude model, not as chance.

1 skill+2894
@fivetaku@fivetaku
Install Plugin
hello2cc
Plugin

hello2cc

Adjusts how third-party models behave inside Claude Code so they run closer to a native Opus session, covering subagent lifecycle, session hooks and tool interception. It does not replace your gateway, provider mapping or account setup.

1 agent11 hooks689
@hellowind777@hellowind777
Install Plugin
ww-w-ai-bkit-claude-code
Plugin

ww-w-ai-bkit-claude-co…

Runs a PDCA workflow with phase gating, spec checks, and delegation to sub-agents for planning, QA, and deployment. Fires at session start and on prompts, edits, task creation, and phase transitions.

44 skills+3606
@ww-w-ai@ww-w-ai
Install Plugin

Questions about the hooks in xenitv1-maestro.

Which coding agents can use the hooks in xenitv1-maestro?
The hooks in xenitv1-maestro install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.