diff --git a/pi_wake_agent.skill.json b/pi_wake_agent.skill.json new file mode 100644 index 00000000..9345a4b9 --- /dev/null +++ b/pi_wake_agent.skill.json @@ -0,0 +1,51 @@ +{ + "name": "pi_wake_agent", + "description": "Multi-agent wake-up timer with self-cron/daemon/succession modes. Sends doorbell injections via zellij and durable messages via h5i bus.", + "parameters": { + "type": "object", + "properties": { + "mode": { + "type": "string", + "enum": ["install", "once", "daemon", "succession", "run", "remove", "list", "status", "validate"], + "description": "Operation mode" + }, + "interval": { + "type": "string", + "pattern": "^\\d+[hms]$", + "default": "1h", + "description": "Interval duration. Formats: 30m, 1h, 90m, 2h, 10s" + }, + "session": { + "type": "array", + "items": { "type": "string" }, + "description": "Zellij session name(s). Repeatable." + }, + "sessions": { + "type": "string", + "description": "Comma-separated list of sessions" + }, + "message": { + "type": "string", + "default": "Operator says CONTINUE. pi_nvnemo here, saying hi!", + "description": "Wake message sent to agent(s)" + }, + "count": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Number of runs for succession mode" + }, + "dry_run": { + "type": "boolean", + "default": false, + "description": "Show what would be done without executing" + }, + "debug": { + "type": "boolean", + "default": false, + "description": "Enable debug logging" + } + }, + "required": ["mode"] + } +} diff --git a/pi_wake_agent.skill.yaml b/pi_wake_agent.skill.yaml new file mode 100644 index 00000000..9935c7af --- /dev/null +++ b/pi_wake_agent.skill.yaml @@ -0,0 +1,242 @@ +# pi_wake_agent Skill Definition +# Universal Agent Skill Format (YAML) +# Compatible with: Anthropic, LangChain, OpenAI Functions, Custom Agents + +skill: + name: "pi_wake_agent" + version: "1.1.0" + description: | + Multi-agent wake-up timer with self-cron/daemon/succession modes. + Sends doorbell injections via zellij and durable messages via h5i bus. + Designed for the DOLPHIN fleet (pi_nvnemo, cmd, mimo, codex, etc.). + + author: "pi_nvnemo" + repository: "https://github.com/dolphinng5/pi_wake_agent" + branch: "tools/pi_wake_agent" + license: "MIT" + + # ─── Installation ───────────────────────────────────────────────────── + installation: + method: "script" + path: "/mnt/dolphinng5_predict/pi_wake_agent.py" + requirements: + - python >= 3.8 + - zellij (for terminal injections) + - h5i (for bus messaging, optional) + test_command: "python3 -m pytest test_pi_wake_agent.py -v" + + # ─── Capabilities ───────────────────────────────────────────────────── + capabilities: + - name: "install_cron" + description: "Install recurring wake-up timer via system cron" + modes: ["install"] + - name: "once" + description: "One-shot wake after interval (no cron)" + modes: ["once"] + - name: "daemon" + description: "Long-lived process, no cron needed" + modes: ["daemon"] + - name: "succession" + description: "Run N times at interval, then self-clean (remove cron)" + modes: ["succession"] + - name: "run_wake" + description: "Internal: execute wake action (called by cron)" + modes: ["run"] + - name: "remove_cron" + description: "Remove cron timer entry" + modes: ["remove"] + - name: "list_cron" + description: "List active cron timers" + modes: ["list"] + - name: "status" + description: "Show cron + one-shot timer status" + modes: ["status"] + - name: "validate_sessions" + description: "Validate zellij sessions exist" + modes: ["validate"] + + # ─── Parameters ─────────────────────────────────────────────────────── + parameters: + mode: + type: "string" + enum: ["install", "once", "daemon", "succession", "run", "run", "remove", "list", "status", "validate"] + required: true + default: "install" + description: "Operation mode" + + interval: + type: "string" + pattern: "^\\d+[hms]$" + default: "1h" + description: "Interval duration. Formats: 30m, 1h, 90m, 2h, 10s" + examples: ["1h", "30m", "90m", "2h", "10s"] + + session: + type: "array" + items: + type: "string" + description: "Zellij session name(s). Repeatable flag." + examples: [["cc_UV_dev0_Fb"], ["cc_UV_dev0_Fb", "cc_UV_dev1_48"]] + + sessions: + type: "string" + description: "Comma-separated list of sessions (alternative to --session)" + examples: ["cc_UV_dev0_Fb,cc_UV_dev1_48"] + + message: + type: "string" + default: "Operator says CONTINUE. pi_nvnemo here, saying hi!" + description: "Wake message sent to agent(s)" + + count: + type: "integer" + minimum: 1 + default: 1 + description: "Number of runs for succession mode" + + dry_run: + type: "boolean" + default: false + description: "Show what would be done without executing" + + debug: + type: "boolean" + default: false + description: "Enable debug logging" + + json: + type: "boolean" + default: false + description: "Output JSON for machine parsing" + + config: + type: "string" + description: "Path to config file (JSON/YAML)" + + # ─── Returns ────────────────────────────────────────────────────────── + returns: + type: "object" + properties: + exit_code: + type: "integer" + description: "0 = success, non-zero = error" + cron_entry: + type: "string" + description: "Installed cron line (for install mode)" + log_file: + type: "string" + value: "/tmp/pi_wake_agent.log" + message_sent: + type: "boolean" + description: "Whether wake message was sent" + + # ─── Side Effects ───────────────────────────────────────────────────── + side_effects: + - "Modifies system crontab (install/remove modes)" + - "Injects text into zellij sessions (zellij write-chars)" + - "Sends h5i bus message to Fable (fire-and-forget)" + - "Writes to /tmp/pi_wake_agent.log (rotated at 10MB)" + - "Creates PID files in /tmp/pi_wake_agent_*.pid (once mode)" + + # ─── h5i Bus Protocol ───────────────────────────────────────────────── + bus_protocol: + agent_id: "pi_nvnemo" + target: "Fable" + message_format: "[pi_nvnemo via zellij] {message} Run: h5i-bus msg inbox" + keypresses: 5 + keypress_delay_ms: 1000 + bus_message: "{message} (timer wakeup)" + timeout_ms: 5000 + fire_and_forget: true + silently_ignore_failures: true + + # ─── Zellij Integration ─────────────────────────────────────────────── + zellij: + command_check: "zellij list-sessions" + injection_method: "zellij --session {session} action write-chars" + enter_keypress: "zellij --session {session} action write 13" + ansi_strip: true + session_exists_check: true + + # ─── Cron Format ────────────────────────────────────────────────────── + cron: + comment_format: "pi_wake_agent:{sessions}:{interval}" + session_delimiter: "," + command_template: "cd /mnt/dolphinng5_predict && export H5I_AGENT=pi_nvnemo && /mnt/dolphinng5_predict/pi_wake_agent.py --run --sessions '{sessions}' --msg '{message}'" + + # ─── Logging ────────────────────────────────────────────────────────── + logging: + file: "/tmp/pi_wake_agent.log" + rotation_mb: 10 + max_files: 5 + format: "[YYYY-MM-DD HH:MM:SS] [LEVEL] message" + levels: ["DEBUG", "INFO", "WARN", "ERROR"] + + # ─── Examples ───────────────────────────────────────────────────────── + examples: + - name: "Recurring 1-hour wake for one session" + command: "pi_wake_agent.py --install --interval 1h --session cc_UV_dev0_Fb" + - name: "Multi-session 30-minute wake" + command: 'pi_wake_agent.py --install --interval 30m --sessions "cc_UV_dev0_Fb,cc_UV_dev1_48" --msg "Wake up!"' + - name: "One-shot in 2 hours" + command: 'pi_wake_agent.py --once --interval 2h --session cc_UV_dev0_Fb --msg "Time\'s up!"' + - name: "Run 3 times at 1-hour intervals, then self-clean" + command: 'pi_wake_agent.py --succession --count 3 --interval 1h --session cc_UV_dev0_Fb --msg "Scheduled wake"' + - name: "Daemon mode (long-lived process, no cron)" + command: 'pi_wake_agent.py --daemon --interval 1h --session cc_UV_dev0_Fb' + - name: "Remove timer" + command: 'pi_wake_agent.py --remove --session cc_UV_dev0_Fb --interval 1h' + - name: "List / status" + command: "pi_wake_agent.py --list" + command: "pi_wake_agent.py --status" + - name: "Validate sessions exist" + command: 'pi_wake_agent.py --validate --session cc_UV_dev0_Fb' + - name: "Dry run (show what would happen)" + command: 'pi_wake_agent.py --install --interval 1h --session test --msg "test" --dry-run' + + # ─── Error Handling ─────────────────────────────────────────────────── + error_handling: + - condition: "missing_session" + action: "return_error" + message: "--session or --sessions required" + exit_code: 1 + - condition: "invalid_interval" + action: "return_error" + message: "Invalid interval format. Use like 1h, 30m, 90m, 2h" + exit_code: 1 + - condition: "invalid_count" + action: "return_error" + message: "--count must be >= 1 for succession mode" + exit_code: 1 + - condition: "cron_failure" + action: "log_warning_continue" + description: "Cron install/remove logs warning but continues" + - condition: "zellij_not_found" + action: "log_warning_continue" + description: "Session injection fails silently, bus message still sent" + - condition: "h5i_timeout" + action: "silent_ignore" + description: "h5i bus message failures are silently ignored (fire-and-forget)" + + # ─── Testing ────────────────────────────────────────────────────────── + testing: + test_file: "test_pi_wake_agent.py" + test_count: 38 + coverage: + - unit_interval_parsing + - unit_cron_comments + - unit_session_parsing + - integration_install_remove_list + - integration_once_short + - integration_succession_short + - edge_cases_invalid_intervals + - edge_cases_missing_sessions + - edge_cases_invalid_counts + run_command: "python3 -m pytest test_pi_wake_agent.py -v" + + # ─── Metadata ───────────────────────────────────────────────────────── + metadata: + created: "2026-07-08" + updated: "2026-07-08" + maintainer: "pi_nvnemo" + tags: ["wake-timer", "cron", "zellij", "h5i", "multi-agent", "doorbell", "self-cleaning"]