Skip to content

ECA support #261

@bsless

Description

@bsless

Editor Code Assistant (ECA) is an editor agnostic tool for LLM agents integration.

I have hacked together my own integration with it but official support would be nice, because I'm really enjoying the Peon sounds 😸

I also copied all the directories to .config/eca from .claude, which makes me think an editor / tool agnostic shold reside in a more generic install directory and hooks will refer to it.

Thanks

Hooks
    "hooks": {
        "peon-session-start": {
            "type": "sessionStart",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-session-end": {
            "type": "sessionEnd",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-pre-request": {
            "type": "preRequest",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                },
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/scripts/hook-handle-use.sh",
                    "timeout": 5000
                }
            ]
        },
        "peon-post-request": {
            "type": "postRequest",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-pre-tool-call": {
            "type": "preToolCall",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-post-tool-call": {
            "type": "postToolCall",
            "visible": false,
            "runOnError": true,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-chat-start": {
            "type": "chatStart",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        },
        "peon-subagent-post-request": {
            "type": "subagentPostRequest",
            "visible": false,
            "actions": [
                {
                    "type": "shell",
                    "file": "~/.config/eca/hooks/peon-ping/eca-adapter.sh",
                    "timeout": 10000
                }
            ]
        }
    },

adapter
#!/bin/bash
# ECA → peon-ping adapter
# Translates ECA's hook JSON format to the Claude Code format peon.sh expects.
set -uo pipefail

INPUT=$(cat)

# Map ECA hook_type to Claude Code hook_event_name
python3 -c "
import json, sys

data = json.loads(sys.argv[1])

hook_type = data.get('hook_type', '')
workspaces = data.get('workspaces', [])
cwd = workspaces[0] if workspaces else ''
# ECA does not provide a session_id; derive one from db_cache_path to get a
# stable per-session identifier, falling back to a constant.
db_path = data.get('db_cache_path', '')
session_id = db_path.split('/')[-2] if db_path else 'eca-default'

type_map = {
    'sessionStart':        'SessionStart',
    'sessionEnd':          'SessionEnd',
    'chatStart':           'SessionStart',
    'preRequest':          'UserPromptSubmit',
    'postRequest':         'Stop',
    'subagentPostRequest': 'Stop',
    'preToolCall':         'PermissionRequest',
    'postToolCall':        'Stop',
}

event_name = type_map.get(hook_type, hook_type)

out = {
    'hook_event_name': event_name,
    'session_id':      session_id,
    'cwd':             cwd,
}

# Forward any extra fields peon.sh might use
if 'notification_type' in data:
    out['notification_type'] = data['notification_type']
if 'permission_mode' in data:
    out['permission_mode'] = data['permission_mode']

print(json.dumps(out))
" "$INPUT" | bash /home/bsless/.config/eca/hooks/peon-ping/peon.sh

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions