Add Nostr Feed Manager: Rust backend with Electron + React GUI
- Rust library (nostr-manager-backend) with CLI and JSON-lines IPC serve mode: profiles, publishing with per-relay reports, relays, settings, vault storage and legacy-vault migration - Electron + React + TypeScript desktop GUI using the same backend over stdio IPC - Vitest suite with a fake backend speaking the real protocol - electron-builder linux packaging; README with build and usage instructions
This commit is contained in:
commit
7e3bac345c
68 changed files with 18262 additions and 0 deletions
60
nostr_feed_manager.py
Normal file
60
nostr_feed_manager.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Path to your Rust binary (adjust if you move it)
|
||||
RUST_BINARY = "/home/avi/Projects/skills/nost-feed-manager/target/release/nostr-manager-backend"
|
||||
|
||||
class NostrFeedManager:
|
||||
"""
|
||||
A skill for Hermes to manage multiple Nostr profiles.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.vault_file = "/home/avi/Projects/skills/nost-feed-manager/profiles_vault.json"
|
||||
|
||||
def _run_rust_command(self, command: str, args: list) -> str:
|
||||
"""Executes the Rust binary."""
|
||||
# Ensure the Rust binary exists
|
||||
if not os.path.exists(RUST_BINARY):
|
||||
return f"Error: Rust binary not found at {RUST_BINARY}. Please compile it first."
|
||||
|
||||
cmd = [RUST_BINARY, command] + args
|
||||
try:
|
||||
# Set the environment variable for the Rust binary if needed
|
||||
env = os.environ.copy()
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10, env=env)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
else:
|
||||
return f"Error: {result.stderr.strip()}"
|
||||
except Exception as e:
|
||||
return f"Execution Error: {str(e)}"
|
||||
|
||||
def create_profile(self, label: str) -> str:
|
||||
"""Create a new Nostr profile."""
|
||||
return self._run_rust_command("create", [label])
|
||||
|
||||
def list_profiles(self) -> str:
|
||||
"""List all managed profiles."""
|
||||
return self._run_rust_command("list", [])
|
||||
|
||||
def switch_profile(self, npub: str) -> str:
|
||||
"""Switch the active profile context."""
|
||||
return self._run_rust_command("switch", [npub])
|
||||
|
||||
def publish_action(self, profile_npub: str, content: str, is_private: bool = False, recipient: Optional[str] = None) -> str:
|
||||
"""Publish a post or DM."""
|
||||
args = [profile_npub, content, str(is_private).lower()]
|
||||
if is_private and recipient:
|
||||
args.append(recipient)
|
||||
return self._run_rust_command("publish", args)
|
||||
|
||||
# Export the class so Hermes can import it if running as a module
|
||||
if __name__ == "__main__":
|
||||
# Simple CLI test
|
||||
manager = NostrFeedManager()
|
||||
print("Nostr Feed Manager Skill Loaded.")
|
||||
print("Usage: manager.create_profile('Name')")
|
||||
Loading…
Add table
Add a link
Reference in a new issue