mirror of
https://github.com/Heretek-AI/not-zune.git
synced 2026-10-12 02:04:04 +00:00
228 lines
8.4 KiB
Python
Executable File
228 lines
8.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Not-Zune Developer MCP Server
|
|
Provides local development tools for inspecting connected Zune USB devices,
|
|
inspecting audio metadata, and auditing Zune Metro design invariants.
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
import os
|
|
import glob
|
|
import subprocess
|
|
|
|
def handle_initialize(request_id):
|
|
return {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"result": {
|
|
"protocolVersion": "2024-11-05",
|
|
"capabilities": {
|
|
"tools": {}
|
|
},
|
|
"serverInfo": {
|
|
"name": "not-zune-dev-tools",
|
|
"version": "1.0.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
def handle_list_tools(request_id):
|
|
return {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"result": {
|
|
"tools": [
|
|
{
|
|
"name": "probe_zune_devices",
|
|
"description": "Scans USB controllers for connected Microsoft Zune hardware (Zune 30, Zune 4/8/16, Zune 80/120, Zune HD).",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {},
|
|
"additionalProperties": False
|
|
}
|
|
},
|
|
{
|
|
"name": "audit_zune_design_invariants",
|
|
"description": "Scans project XAML, AXAML, and styling files to detect violations of the Zune Metro design language (e.g., non-zero CornerRadius, drop shadows).",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"directory": {
|
|
"type": "string",
|
|
"description": "Path to scan, defaults to repo root."
|
|
}
|
|
},
|
|
"additionalProperties": False
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
def probe_zune_devices():
|
|
zune_pids = {
|
|
"063e": "Microsoft Zune 30",
|
|
"0710": "Microsoft Zune 4/8/16",
|
|
"0715": "Microsoft Zune 80/120",
|
|
"0723": "Microsoft Zune HD"
|
|
}
|
|
found = []
|
|
|
|
# Check Linux /sys/bus/usb/devices
|
|
sys_usb = "/sys/bus/usb/devices"
|
|
if os.path.exists(sys_usb):
|
|
for dev in os.listdir(sys_usb):
|
|
dev_path = os.path.join(sys_usb, dev)
|
|
vendor_file = os.path.join(dev_path, "idVendor")
|
|
product_file = os.path.join(dev_path, "idProduct")
|
|
if os.path.isfile(vendor_file) and os.path.isfile(product_file):
|
|
try:
|
|
with open(vendor_file, "r") as vf:
|
|
vid = vf.read().strip().lower()
|
|
with open(product_file, "r") as pf:
|
|
pid = pf.read().strip().lower()
|
|
if vid == "045e" and pid in zune_pids:
|
|
found.append({
|
|
"model": zune_pids[pid],
|
|
"vendorId": "0x045E",
|
|
"productId": f"0x{pid.upper()}",
|
|
"devicePath": dev_path
|
|
})
|
|
except Exception:
|
|
pass
|
|
|
|
# Also attempt lsusb if available
|
|
if not found:
|
|
try:
|
|
out = subprocess.check_output(["lsusb"], text=True, stderr=subprocess.DEVNULL)
|
|
for line in out.splitlines():
|
|
if "045e:" in line.lower():
|
|
for pid, name in zune_pids.items():
|
|
if f"045e:{pid}" in line.lower():
|
|
found.append({
|
|
"model": name,
|
|
"vendorId": "0x045E",
|
|
"productId": f"0x{pid.upper()}",
|
|
"raw": line
|
|
})
|
|
except Exception:
|
|
pass
|
|
|
|
return {
|
|
"detectedDevicesCount": len(found),
|
|
"devices": found,
|
|
"message": f"Found {len(found)} connected Zune hardware device(s)." if found else "No physical Zune devices detected on USB."
|
|
}
|
|
|
|
def audit_design_invariants(target_dir=None):
|
|
if not target_dir:
|
|
target_dir = os.getcwd()
|
|
|
|
violations = []
|
|
axaml_files = glob.glob(os.path.join(target_dir, "**/*.axaml"), recursive=True) + \
|
|
glob.glob(os.path.join(target_dir, "**/*.xaml"), recursive=True)
|
|
|
|
for f in axaml_files:
|
|
try:
|
|
with open(f, "r", encoding="utf-8", errors="ignore") as fp:
|
|
for line_no, line in enumerate(fp, start=1):
|
|
# Check for non-zero CornerRadius
|
|
if "CornerRadius" in line:
|
|
# Check if non-zero
|
|
valid_zeros = [
|
|
'CornerRadius="0"',
|
|
'CornerRadius="0,0,0,0"',
|
|
'CornerRadius="{DynamicResource ZeroCornerRadius}"',
|
|
'CornerRadius="{DynamicResource ZuneCornerRadius}"',
|
|
'CornerRadius="{StaticResource ZuneCornerRadius}"',
|
|
'Value="{StaticResource ZuneCornerRadius}"',
|
|
'Value="{DynamicResource ZuneCornerRadius}"',
|
|
'>0</CornerRadius>'
|
|
]
|
|
if not any(v in line for v in valid_zeros):
|
|
violations.append({
|
|
"file": f,
|
|
"line": line_no,
|
|
"rule": "CornerRadius must be 0 (Zero rounded corners in Zune Metro design)",
|
|
"content": line.strip()
|
|
})
|
|
# Check for drop shadows
|
|
if "DropShadowEffect" in line or "BoxShadow" in line:
|
|
violations.append({
|
|
"file": f,
|
|
"line": line_no,
|
|
"rule": "Drop shadows are forbidden in Zune Metro design (Content Before Chrome)",
|
|
"content": line.strip()
|
|
})
|
|
except Exception as e:
|
|
violations.append({"file": f, "error": str(e)})
|
|
|
|
return {
|
|
"filesScanned": len(axaml_files),
|
|
"violationsCount": len(violations),
|
|
"violations": violations,
|
|
"status": "PASSED" if len(violations) == 0 else "FAILED"
|
|
}
|
|
|
|
def handle_call_tool(request_id, params):
|
|
name = params.get("name")
|
|
args = params.get("arguments", {})
|
|
|
|
if name == "probe_zune_devices":
|
|
res = probe_zune_devices()
|
|
return {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"result": {
|
|
"content": [{"type": "text", "text": json.dumps(res, indent=2)}]
|
|
}
|
|
}
|
|
elif name == "audit_zune_design_invariants":
|
|
target = args.get("directory")
|
|
res = audit_design_invariants(target)
|
|
return {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"result": {
|
|
"content": [{"type": "text", "text": json.dumps(res, indent=2)}]
|
|
}
|
|
}
|
|
else:
|
|
return {
|
|
"jsonrpc": "2.0",
|
|
"id": request_id,
|
|
"error": {"code": -32601, "message": f"Unknown tool: {name}"}
|
|
}
|
|
|
|
def main():
|
|
while True:
|
|
line = sys.stdin.readline()
|
|
if not line:
|
|
break
|
|
try:
|
|
msg = json.loads(line)
|
|
method = msg.get("method")
|
|
req_id = msg.get("id")
|
|
|
|
if method == "initialize":
|
|
resp = handle_initialize(req_id)
|
|
elif method == "notifications/initialized":
|
|
continue
|
|
elif method == "tools/list":
|
|
resp = handle_list_tools(req_id)
|
|
elif method == "tools/call":
|
|
resp = handle_call_tool(req_id, msg.get("params", {}))
|
|
else:
|
|
resp = {"jsonrpc": "2.0", "id": req_id, "error": {"code": -32601, "message": "Method not found"}}
|
|
|
|
sys.stdout.write(json.dumps(resp) + "\n")
|
|
sys.stdout.flush()
|
|
except Exception as e:
|
|
err = {"jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": str(e)}}
|
|
sys.stdout.write(json.dumps(err) + "\n")
|
|
sys.stdout.flush()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|