fester/cli/fester.py

181 lines
3.6 KiB
Python

#!/usr/bin/env python3
import argparse
import requests
import json
import websocket
API = "http://localhost:8080/api"
WS = "ws://localhost:8080/ws"
# -----------------------------
# LIVE STREAM (IDE MODE)
# -----------------------------
def stream():
ws = websocket.WebSocket()
ws.connect(WS)
print("📡 Fester IDE stream active\n")
while True:
msg = ws.recv()
event = json.loads(msg)
if event["type"] == "pipeline":
d = event["data"]
print(f"[PIPELINE] {d['action']}{d['state']} @ {d.get('node')}")
elif event["type"] == "node":
print(f"[NODE] {event['data']}")
# -----------------------------
# PIPELINE CONTROL
# -----------------------------
def status():
r = requests.get(f"{API}/pipeline/state")
print(json.dumps(r.json(), indent=2))
def retry(action):
r = requests.post(f"{API}/pipeline/retry", json={"action": action})
print(r.json())
def force(action, node):
r = requests.post(f"{API}/pipeline/force-node", json={
"action": action,
"node": node
})
print(r.json())
def pause():
requests.post(f"{API}/pipeline/pause")
def resume():
requests.post(f"{API}/pipeline/resume")
# -----------------------------
# SESSION CONTROL (IDE FEATURE)
# -----------------------------
def sessions():
r = requests.get(f"{API}/sessions")
print(json.dumps(r.json(), indent=2))
def attach(action):
r = requests.post(f"{API}/session/attach", json={"action": action})
print(r.json())
def detach(action):
r = requests.post(f"{API}/session/detach", json={"action": action})
print(r.json())
# -----------------------------
# POLICY CONTROL (WIZARD LAYER)
# -----------------------------
def set_policy(key, value):
r = requests.post(f"{API}/policy/set", json={
"key": key,
"value": value
})
print(r.json())
def clear_policy(key):
r = requests.post(f"{API}/policy/clear", json={
"key": key
})
print(r.json())
# -----------------------------
# CLI ENTRYPOINT
# -----------------------------
def main():
parser = argparse.ArgumentParser("fester IDE CLI")
sub = parser.add_subparsers(dest="cmd")
# core
sub.add_parser("stream")
sub.add_parser("status")
sub.add_parser("sessions")
# pipeline control
r = sub.add_parser("retry")
r.add_argument("action")
f = sub.add_parser("force")
f.add_argument("action")
f.add_argument("node")
sub.add_parser("pause")
sub.add_parser("resume")
# session control
a = sub.add_parser("attach")
a.add_argument("action")
d = sub.add_parser("detach")
d.add_argument("action")
# policy control
p = sub.add_parser("policy-set")
p.add_argument("key")
p.add_argument("value")
c = sub.add_parser("policy-clear")
c.add_argument("key")
args = parser.parse_args()
# -----------------------------
# COMMAND HANDLING
# -----------------------------
if args.cmd == "stream":
stream()
elif args.cmd == "status":
status()
elif args.cmd == "sessions":
sessions()
elif args.cmd == "retry":
retry(args.action)
elif args.cmd == "force":
force(args.action, args.node)
elif args.cmd == "attach":
attach(args.action)
elif args.cmd == "detach":
detach(args.action)
elif args.cmd == "pause":
pause()
elif args.cmd == "resume":
resume()
elif args.cmd == "policy-set":
set_policy(args.key, args.value)
elif args.cmd == "policy-clear":
clear_policy(args.key)
else:
parser.print_help()
if __name__ == "__main__":
main()