181 lines
3.6 KiB
Python
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()
|