diff --git a/skills/kugetsu-helpers/SKILL.md b/skills/kugetsu-helpers/SKILL.md deleted file mode 100644 index 899f7d1..0000000 --- a/skills/kugetsu-helpers/SKILL.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: kugetsu-helpers -description: Helper tools for Hermes to interact with kugetsu. Provides routing, delegation, and status functions. -license: MIT -compatibility: Requires Hermes agent, kugetsu CLI, opencode sessions. -metadata: - author: shoko - version: "1.0" ---- - -# kugetsu-helpers - Hermes Tools for Kugetsu - -Provides tools/functions for Hermes to route messages and delegate to the PM Agent. - -## Overview - -This skill enables Hermes (as Chat Agent) to interact with kugetsu-managed opencode sessions. - -## Tools - -### kugetsu_get_pm_session - -Gets the PM Agent session ID from kugetsu index. - -```bash -kugetsu_get_pm_session -``` - -**Returns:** PM agent session ID string, or empty if not initialized - -**Example:** -``` -PM_SESSION=$(kugetsu_get_pm_session) -echo "PM Agent: $PM_SESSION" -``` - -### kugetsu_delegate_to_pm - -Delegates a task to the PM Agent via opencode. - -```bash -kugetsu_delegate_to_pm "" -``` - -**Arguments:** -- `task message`: The task to delegate (e.g., "fix issue #5") - -**Returns:** PM Agent response (may be multi-line) - -**Example:** -``` -kugetsu_delegate_to_pm "User wants to fix issue #5 in github.com/shoko/kugetsu" -``` - -### kugetsu_check_status - -Checks kugetsu initialization status. - -```bash -kugetsu_check_status -``` - -**Returns:** Status string indicating: -- "ok" - kugetsu initialized, PM agent running -- "kugetsu_not_initialized" - Run kugetsu init first -- "pm_agent_missing" - PM agent not found - -### kugetsu_list_sessions - -Lists all kugetsu-managed sessions. - -```bash -kugetsu_list_sessions -``` - -**Returns:** Formatted list of sessions - -### kugetsu_create_dev_session - -Creates a Dev Agent session for an issue. - -```bash -kugetsu_create_dev_session "" "" -``` - -**Arguments:** -- `issue-ref`: Issue reference (e.g., "github.com/shoko/kugetsu#5") -- `task`: Task description for the dev agent - -**Returns:** Session creation status - -## Implementation - -These tools are implemented as shell functions that Hermes can call via `terminal()`. - -### Direct Implementation (Recommended) - -Add to Hermes SOUL.md as custom tools: - -``` -You have access to kugetsu via terminal commands: - -- kugetsu_get_pm_session: Get PM agent session ID -- kugetsu_delegate_to_pm : Delegate to PM agent -- kugetsu_check_status: Check kugetsu status -``` - -### Tool Definition Format - -Hermes tools should call these functions via terminal(): - -```python -{ - "name": "kugetsu_delegate", - "description": "Delegate a task to the PM Agent", - "parameters": { - "type": "object", - "properties": { - "task": { - "type": "string", - "description": "Task to delegate to PM Agent" - } - }, - "required": ["task"] - } -} -``` - -## Usage in Hermes - -### SOUL.md Integration - -Add to your SOUL.md: - -``` -You can interact with kugetsu to route tasks: - -1. Get PM agent session: terminal(command="kugetsu_get_pm_session") -2. Delegate to PM: terminal(command="kugetsu_delegate_to_pm 'fix issue #5'") -3. Check status: terminal(command="kugetsu_check_status") -``` - -### Routing Logic - -``` -User message → Hermes - │ - ├─ Small talk → respond directly - │ - └─ Task request → terminal(kugetsu_delegate_to_pm "") - │ - └─ PM Agent response → relay to user -``` - -## Error Handling - -| Error | Cause | Resolution | -|-------|-------|------------| -| "kugetsu not initialized" | Run `kugetsu init` | Inform user | -| "pm_agent_missing" | PM agent not created | Run `kugetsu init` | -| "session not found" | opencode session expired | May need reinit | - -## Files - -- `scripts/kugetsu-helpers.sh` - Shell implementations -- `SKILL.md` - This documentation \ No newline at end of file diff --git a/skills/kugetsu-helpers/scripts/kugetsu-helpers b/skills/kugetsu-helpers/scripts/kugetsu-helpers deleted file mode 100755 index 9d02eb8..0000000 --- a/skills/kugetsu-helpers/scripts/kugetsu-helpers +++ /dev/null @@ -1,202 +0,0 @@ -#!/bin/bash -# kugetsu-helpers - Shell functions for Hermes to interact with kugetsu -# -# These functions provide tools for routing and delegation to PM Agent. - -set -euo pipefail - -KUGETSU_DIR="${KUGETSU_DIR:-$HOME/.kugetsu}" -INDEX_FILE="$KUGETSU_DIR/index.json" - -kugetsu_get_pm_session() { - if [ ! -f "$INDEX_FILE" ]; then - echo "" - return - fi - - python3 -c "import json; print(json.load(open('$INDEX_FILE')).get('pm_agent', ''))" 2>/dev/null || echo "" -} - -kugetsu_check_status() { - if [ ! -f "$INDEX_FILE" ]; then - echo "kugetsu_not_initialized" - return - fi - - if ! grep -q '"pm_agent"' "$INDEX_FILE"; then - echo "pm_agent_missing" - return - fi - - PM_AGENT=$(kugetsu_get_pm_session) - if [ -z "$PM_AGENT" ] || [ "$PM_AGENT" = "null" ] || [ "$PM_AGENT" = "None" ]; then - echo "pm_agent_missing" - return - fi - - echo "ok" -} - -kugetsu_delegate_to_pm() { - local task="${1:-}" - - if [ -z "$task" ]; then - echo "Error: task is required" - return 1 - fi - - local pm_session=$(kugetsu_get_pm_session) - if [ -z "$pm_session" ] || [ "$pm_session" = "null" ] || [ "$pm_session" = "None" ]; then - echo "Error: PM agent session not found. Run 'kugetsu init' first." - return 1 - fi - - opencode run --continue --session "$pm_session" "$task" 2>&1 -} - -kugetsu_list_sessions() { - if command -v kugetsu &> /dev/null; then - kugetsu list 2>&1 - else - echo "kugetsu command not found" - return 1 - fi -} - -kugetsu_create_dev_session() { - local issue_ref="${1:-}" - local task="${2:-}" - - if [ -z "$issue_ref" ] || [ -z "$task" ]; then - echo "Error: issue_ref and task are required" - return 1 - fi - - if ! command -v kugetsu &> /dev/null; then - echo "Error: kugetsu command not found" - return 1 - fi - - kugetsu start "$issue_ref" "$task" 2>&1 -} - -kugetsu_continue_dev_session() { - local issue_ref="${1:-}" - local update="${2:-}" - - if [ -z "$issue_ref" ] || [ -z "$update" ]; then - echo "Error: issue_ref and update are required" - return 1 - fi - - if ! command -v kugetsu &> /dev/null; then - echo "Error: kugetsu command not found" - return 1 - fi - - kugetsu continue "$issue_ref" "$update" 2>&1 -} - -kugetsu_fix_pm_permissions() { - local pm_session=$(kugetsu_get_pm_session) - if [ -z "$pm_session" ] || [ "$pm_session" = "null" ] || [ "$pm_session" = "None" ]; then - echo "Error: PM agent session not found" - return 1 - fi - - python3 << PYEOF -import sqlite3 -import json -import os - -db_path = os.path.expanduser("~/.local/share/opencode/opencode.db") -conn = sqlite3.connect(db_path) -cursor = conn.cursor() - -# Get current permission for PM session -session_id = "$pm_session" -cursor.execute("SELECT id, permission FROM session WHERE id = ?", (session_id,)) -row = cursor.fetchone() - -if not row: - print(f"Error: Session {session_id} not found") - exit(1) - -perms = json.loads(row[1]) if row[1] else [] -patterns = [p['pattern'] for p in perms] - -# Add missing patterns for /tmp/kugetsu -needed = ['/tmp/kugetsu', '/tmp/kugetsu/*', '/tmp/kugetsu/**'] -added = [] - -for pattern in needed: - if pattern not in patterns: - perms.append({"permission": "external_directory", "pattern": pattern, "action": "allow"}) - added.append(pattern) - -if added: - new_perms = json.dumps(perms) - cursor.execute("UPDATE session SET permission = ? WHERE id = ?", (new_perms, session_id)) - conn.commit() - print(f"Added permissions: {', '.join(added)}") -else: - print("All required permissions already exist") -PYEOF -} - -# Main entry point for CLI usage -main() { - local command="${1:-}" - shift || true - - case "$command" in - get-pm-session) - kugetsu_get_pm_session - ;; - check-status) - kugetsu_check_status - ;; - delegate-to-pm) - kugetsu_delegate_to_pm "$@" - ;; - list-sessions) - kugetsu_list_sessions - ;; - create-dev-session) - kugetsu_create_dev_session "$@" - ;; - continue-dev-session) - kugetsu_continue_dev_session "$@" - ;; - fix-permissions) - kugetsu_fix_pm_permissions - ;; - help|--help|-h) - cat << 'EOF' -kugetsu-helpers - Hermes tools for kugetsu - -Commands: - get-pm-session Get PM agent session ID - check-status Check kugetsu initialization status - delegate-to-pm Delegate task to PM agent - list-sessions List all kugetsu sessions - create-dev-session Create dev agent session - continue-dev-session Continue dev agent session - fix-permissions Fix opencode permission for /tmp/kugetsu access - -Usage in Hermes: - terminal(command="~/.local/bin/kugetsu-helper delegate-to-pm 'fix issue #5'", timeout=120) - -Note: If PM agent has permission issues accessing /tmp/kugetsu, run: - kugetsu-helper fix-permissions -EOF - ;; - *) - echo "Error: Unknown command '$command'" - echo "Run 'kugetsu-helpers help' for usage" - return 1 - ;; - esac -} - -main "$@" \ No newline at end of file diff --git a/skills/kugetsu-helpers/tests/test-kugetsu-helpers.sh b/skills/kugetsu-helpers/tests/test-kugetsu-helpers.sh deleted file mode 100644 index d4705a9..0000000 --- a/skills/kugetsu-helpers/tests/test-kugetsu-helpers.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/bash -# kugetsu-helpers test suite -# Tests the shell helper functions for Hermes/Chat Agent integration -# -# Run with: bash skills/kugetsu-helpers/tests/test-kugetsu-helpers.sh - -set -euo pipefail - -KUGETSU_HELPERS="./skills/kugetsu-helpers/scripts/kugetsu-helpers" -TEST_PM_SESSION_ID="ses_test_pm_789" -TEST_ISSUE_REF="github.com/shoko/kugetsu#14" -PASS=0 -FAIL=0 - -cleanup() { - rm -rf ~/.kugetsu/sessions/* ~/.kugetsu/index.json 2>/dev/null || true -} - -setup_mock_index_uninitialized() { - cleanup -} - -setup_mock_index_no_pm_agent() { - mkdir -p ~/.kugetsu/sessions - cat > ~/.kugetsu/index.json << EOF -{ - "base": "ses_base_123", - "pm_agent": null, - "issues": {} -} -EOF -} - -setup_mock_index_with_pm_agent() { - mkdir -p ~/.kugetsu/sessions - cat > ~/.kugetsu/index.json << EOF -{ - "base": "ses_base_123", - "pm_agent": "$TEST_PM_SESSION_ID", - "issues": {} -} -EOF - cat > ~/.kugetsu/sessions/pm-agent.json << EOF -{"type": "pm_agent", "opencode_session_id": "$TEST_PM_SESSION_ID", "created_at": "2026-03-30T18:00:00+02:00", "state": "idle"} -EOF -} - -pass() { - echo "PASS: $1" - PASS=$((PASS + 1)) -} - -fail() { - echo "FAIL: $1" - FAIL=$((FAIL + 1)) -} - -cleanup - -echo "=== kugetsu-helpers Test Suite ===" -echo "" - -# Test 1: check-status when not initialized -echo "--- Test: check-status (not initialized) ---" -setup_mock_index_uninitialized -OUTPUT=$($KUGETSU_HELPERS check-status 2>&1 || true) -if [ "$OUTPUT" = "kugetsu_not_initialized" ]; then - pass "check-status returns kugetsu_not_initialized when no index.json" -else - fail "check-status not initialized: got '$OUTPUT', expected 'kugetsu_not_initialized'" -fi -echo "" - -# Test 2: check-status when pm_agent field is missing -echo "--- Test: check-status (missing pm_agent field) ---" -setup_mock_index_no_pm_agent -OUTPUT=$($KUGETSU_HELPERS check-status 2>&1 || true) -if [ "$OUTPUT" = "pm_agent_missing" ]; then - pass "check-status returns pm_agent_missing when field is null" -else - fail "check-status missing pm_agent: got '$OUTPUT', expected 'pm_agent_missing'" -fi -echo "" - -# Test 3: check-status when PM agent exists -echo "--- Test: check-status (PM agent exists) ---" -setup_mock_index_with_pm_agent -OUTPUT=$($KUGETSU_HELPERS check-status 2>&1 || true) -if [ "$OUTPUT" = "ok" ]; then - pass "check-status returns ok when PM agent exists" -else - fail "check-status ok: got '$OUTPUT', expected 'ok'" -fi -echo "" - -# Test 4: get-pm-session returns session ID when exists -echo "--- Test: get-pm-session (exists) ---" -setup_mock_index_with_pm_agent -OUTPUT=$($KUGETSU_HELPERS get-pm-session 2>&1 || true) -if [ "$OUTPUT" = "$TEST_PM_SESSION_ID" ]; then - pass "get-pm-session returns correct session ID" -else - fail "get-pm-session: got '$OUTPUT', expected '$TEST_PM_SESSION_ID'" -fi -echo "" - -# Test 5: get-pm-session returns empty when not initialized -echo "--- Test: get-pm-session (not initialized) ---" -setup_mock_index_uninitialized -OUTPUT=$($KUGETSU_HELPERS get-pm-session 2>&1 || true) -if [ -z "$OUTPUT" ]; then - pass "get-pm-session returns empty when not initialized" -else - fail "get-pm-session not initialized: got '$OUTPUT', expected ''" -fi -echo "" - -# Test 6: delegate-to-pm fails without task argument -echo "--- Test: delegate-to-pm (no task) ---" -setup_mock_index_with_pm_agent -OUTPUT=$($KUGETSU_HELPERS delegate-to-pm 2>&1 || true) -if echo "$OUTPUT" | grep -q "Error: task is required"; then - pass "delegate-to-pm fails without task" -else - fail "delegate-to-pm no task: got '$OUTPUT', expected error about task required" -fi -echo "" - -# Test 7: delegate-to-pm fails when PM agent missing -echo "--- Test: delegate-to-pm (PM agent missing) ---" -setup_mock_index_uninitialized -OUTPUT=$($KUGETSU_HELPERS delegate-to-pm "test task" 2>&1 || true) -if echo "$OUTPUT" | grep -q "Error: PM agent session not found"; then - pass "delegate-to-pm fails when PM agent not found" -else - fail "delegate-to-pm missing PM: got '$OUTPUT', expected error" -fi -echo "" - -# Test 8: list-sessions when kugetsu not installed -echo "--- Test: list-sessions (kugetsu not installed) ---" -cleanup -TMPDIR=$(mktemp -d) -KUGETSU_BAK="" -if command -v kugetsu &> /dev/null; then - KUGETSU_PATH=$(command -v kugetsu) - KUGETSU_BAK="${TMPDIR}/kugetsu.bak" - mv "$KUGETSU_PATH" "$KUGETSU_BAK" -fi -OUTPUT=$($KUGETSU_HELPERS list-sessions 2>&1 || true) -if [ -n "$KUGETSU_BAK" ]; then - mv "$KUGETSU_BAK" "$KUGETSU_PATH" -fi -rmdir "$TMPDIR" 2>/dev/null || true -if echo "$OUTPUT" | grep -q "kugetsu command not found"; then - pass "list-sessions fails gracefully when kugetsu not found" -else - fail "list-sessions no kugetsu: got '$OUTPUT', expected error" -fi -echo "" - -# Test 9: help command works -echo "--- Test: help command ---" -OUTPUT=$($KUGETSU_HELPERS help 2>&1 || true) -if echo "$OUTPUT" | grep -q "delegate-to-pm"; then - pass "help shows delegate-to-pm command" -else - fail "help: output missing delegate-to-pm" -fi -echo "" - -# Test 10: unknown command fails gracefully -echo "--- Test: unknown command ---" -OUTPUT=$($KUGETSU_HELPERS unknown-cmd 2>&1 || true) -if echo "$OUTPUT" | grep -q "Error: Unknown command"; then - pass "unknown command fails gracefully" -else - fail "unknown command: got '$OUTPUT', expected error" -fi -echo "" - -# Test 11: check-status handles malformed JSON gracefully -echo "--- Test: check-status (malformed JSON) ---" -mkdir -p ~/.kugetsu/sessions -echo "not valid json" > ~/.kugetsu/index.json -OUTPUT=$($KUGETSU_HELPERS check-status 2>&1 || true) -if [ "$OUTPUT" = "pm_agent_missing" ]; then - pass "check-status handles malformed JSON gracefully" -else - fail "check-status malformed JSON: got '$OUTPUT', expected 'pm_agent_missing'" -fi -echo "" - -# Cleanup -cleanup - -echo "" -echo "=== Test Summary ===" -echo "Passed: $PASS" -echo "Failed: $FAIL" -echo "" - -if [ $FAIL -eq 0 ]; then - echo "All tests passed!" - exit 0 -else - echo "Some tests failed." - exit 1 -fi \ No newline at end of file