-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrepo_cli.json
More file actions
18 lines (18 loc) · 40.8 KB
/
repo_cli.json
File metadata and controls
18 lines (18 loc) · 40.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"code": 200,
"data": {
"description": "",
"html": "<html><head><meta name=\"color-scheme\" content=\"light dark\"></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\">\"\"\"FLUX CLI — compile and run FLUX.MD files.\n\nUsage::\n\n # Run the hello world demo\n flux hello\n\n # Compile a C source file to bytecode\n flux compile input.c -o output.bin\n\n # Compile a FLUX.MD document\n flux compile input.md -o output.bin\n\n # Run bytecode in the VM\n flux run bytecode.bin --cycles 1000000\n\n # Run the test suite\n flux test\n\n # Print version information\n flux version\n\n # Run the synthesis demo\n flux demo\n\n # Show system architecture info\n flux info\n\n # Replay a bytecode trace\n flux replay bytecode.bin --cycles 10000 --verbose\n\n # Open the HTML playground\n flux playground\n\n # Migrate source files to FLUX.MD format\n flux migrate input.py --output-dir ./flux_output\n flux migrate src/ --lang auto --verbose\n\n # Disassemble bytecode\n flux disasm bytecode.bin\n\n # Debug bytecode interactively\n flux debug bytecode.bin\n\"\"\"\n\nfrom __future__ import annotations\n\nimport struct\nimport sys\nimport argparse\n\n# Import get_instruction_color for debugger output\ntry:\n from flux.disasm import get_instruction_color\nexcept ImportError:\n # Fallback if disasm module is not available\n def get_instruction_color(opcode):\n return \"\"\n\n\ndef main() -> None:\n \"\"\"Entry point for the ``flux`` command-line tool.\"\"\"\n parser = argparse.ArgumentParser(\n prog=\"flux\",\n description=\"FLUX Agent-First Bytecode System\",\n )\n subparsers = parser.add_subparsers(dest=\"command\")\n\n # ── flux hello ──────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"hello\",\n help=\"Run the FLUX hello world demo\",\n )\n\n # ── flux compile <input> [-o output] [-l lang] [--verbose] ─────────────\n compile_parser = subparsers.add_parser(\n \"compile\",\n help=\"Compile source code to FLUX bytecode\",\n )\n compile_parser.add_argument(\n \"input\",\n help=\"Input source file (.c, .py, or .md)\",\n )\n compile_parser.add_argument(\n \"-o\", \"--output\",\n help=\"Output bytecode file (default: input with .bin extension)\",\n )\n compile_parser.add_argument(\n \"-l\", \"--lang\",\n default=None,\n help=\"Source language: c, python, md (default: inferred from extension)\",\n )\n compile_parser.add_argument(\n \"--verbose\",\n action=\"store_true\",\n default=False,\n help=\"Show generated bytecode hex dump\",\n )\n\n # ── flux run <input> [--cycles N] ──────────────────────────────────────\n run_parser = subparsers.add_parser(\n \"run\",\n help=\"Run FLUX bytecode in the VM\",\n )\n run_parser.add_argument(\n \"input\",\n help=\"Bytecode file to execute\",\n )\n run_parser.add_argument(\n \"--cycles\",\n type=int,\n default=1_000_000,\n help=\"Maximum execution cycles (default: 1000000)\",\n )\n\n # ── flux test ──────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"test\",\n help=\"Run the FLUX test suite\",\n )\n\n # ── flux version ───────────────────────────────────────────────────────\n subparsers.add_parser(\n \"version\",\n help=\"Print version information\",\n )\n\n # ── flux demo ──────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"demo\",\n help=\"Run the synthesis demo\",\n )\n\n # ── flux info ──────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"info\",\n help=\"Show system architecture info\",\n )\n\n # ── flux replay <input> [--cycles N] [--verbose] ───────────────────────\n replay_parser = subparsers.add_parser(\n \"replay\",\n help=\"Replay a bytecode trace with instruction-level logging\",\n )\n replay_parser.add_argument(\n \"input\",\n help=\"Bytecode file to replay\",\n )\n replay_parser.add_argument(\n \"--cycles\",\n type=int,\n default=10_000,\n help=\"Maximum execution cycles (default: 10000)\",\n )\n replay_parser.add_argument(\n \"--verbose\",\n action=\"store_true\",\n default=False,\n help=\"Show detailed register state after each instruction\",\n )\n\n # ── flux playground ────────────────────────────────────────────────────\n subparsers.add_parser(\n \"playground\",\n help=\"Open the HTML playground in a browser\",\n )\n\n # ── flux migrate <input_file_or_dir> [--output-dir] [--lang] [--verbose] ─\n migrate_parser = subparsers.add_parser(\n \"migrate\",\n help=\"Migrate source files to FLUX.MD format\",\n )\n migrate_parser.add_argument(\n \"input\",\n help=\"Input file or directory to migrate (.py, .c, .h, .js)\",\n )\n migrate_parser.add_argument(\n \"--output-dir\",\n default=\"./flux_output\",\n help=\"Output directory for FLUX.MD files (default: ./flux_output)\",\n )\n migrate_parser.add_argument(\n \"--lang\",\n default=\"auto\",\n choices=[\"auto\", \"python\", \"c\", \"js\"],\n help=\"Source language (default: auto-detect from extension)\",\n )\n migrate_parser.add_argument(\n \"--verbose\",\n action=\"store_true\",\n default=False,\n help=\"Show detailed progress information\",\n )\n\n # ── flux repl ──────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"repl\",\n help=\"Start interactive FLUX REPL\",\n )\n\n # ── flux disasm <input> [-o output] [-j] [--no-color] ─────────────────────\n disasm_parser = subparsers.add_parser(\n \"disasm\",\n help=\"Disassemble FLUX bytecode to human-readable format\",\n )\n disasm_parser.add_argument(\n \"input\",\n help=\"Bytecode file to disassemble (.bin)\",\n )\n disasm_parser.add_argument(\n \"-o\", \"--output\",\n help=\"Output file (default: stdout)\",\n )\n disasm_parser.add_argument(\n \"-j\", \"--json\",\n action=\"store_true\",\n default=False,\n help=\"Output JSON instead of formatted text\",\n )\n disasm_parser.add_argument(\n \"--no-color\",\n action=\"store_true\",\n default=False,\n help=\"Disable ANSI color codes in output\",\n )\n\n # ── flux debug <input> [--bp-offsets] [--watch-regs] ───────────────────────\n debug_parser = subparsers.add_parser(\n \"debug\",\n help=\"Start interactive debugger for FLUX bytecode\",\n )\n debug_parser.add_argument(\n \"input\",\n help=\"Bytecode file to debug (.bin)\",\n )\n debug_parser.add_argument(\n \"--bp\",\n \"--breakpoint\",\n dest=\"breakpoints\",\n action=\"append\",\n type=lambda x: int(x, 0),\n help=\"Add breakpoint at offset (e.g., --bp 0x10 or --bp 16)\",\n )\n debug_parser.add_argument(\n \"--watch\",\n dest=\"watchpoints\",\n action=\"append\",\n type=int,\n help=\"Add watchpoint for register (e.g., --watch 0)\",\n )\n debug_parser.add_argument(\n \"--cycles\",\n type=int,\n default=100_000,\n help=\"Maximum execution cycles (default: 100000)\",\n )\n\n # ── flux open ───────────────────────────────────────────────────────────────\n subparsers.add_parser(\n \"open\",\n help=\"Start interactive Open-Flux-Interpreter\",\n )\n\n # ── flux run <file.md> ───────────────────────────────────────────────────────\n runmd_parser = subparsers.add_parser(\n \"run-md\",\n help=\"Run a markdown file with embedded FLUX code\",\n )\n runmd_parser.add_argument(\n \"input\",\n help=\"Markdown file to execute (.md)\",\n )\n runmd_parser.add_argument(\n \"--cycles\",\n type=int,\n default=1_000_000,\n help=\"Maximum execution cycles (default: 1000000)\",\n )\n runmd_parser.add_argument(\n \"--json\",\n action=\"store_true\",\n help=\"Output results as JSON\",\n )\n\n args = parser.parse_args()\n\n # ── Dispatch ───────────────────────────────────────────────────────────\n\n if args.command == \"hello\":\n _cmd_hello()\n\n elif args.command == \"compile\":\n _cmd_compile(args)\n\n elif args.command == \"run\":\n _cmd_run(args)\n\n elif args.command == \"test\":\n _cmd_test()\n\n elif args.command == \"version\":\n _cmd_version()\n\n elif args.command == \"demo\":\n _cmd_demo()\n\n elif args.command == \"info\":\n _cmd_info()\n\n elif args.command == \"replay\":\n _cmd_replay(args)\n\n elif args.command == \"playground\":\n _cmd_playground()\n\n elif args.command == \"migrate\":\n _cmd_migrate(args)\n\n elif args.command == \"repl\":\n _cmd_repl()\n\n elif args.command == \"disasm\":\n _cmd_disasm(args)\n\n elif args.command == \"debug\":\n _cmd_debug(args)\n\n elif args.command == \"open\":\n _cmd_open()\n\n elif args.command == \"run-md\":\n _cmd_run_md(args)\n\n else:\n _show_banner()\n\n\n# ── Subcommands ──────────────────────────────────────────────────────────────\n\n\ndef _infer_lang(filename: str, explicit: str | None) -> str:\n \"\"\"Infer the language from the file extension, or use explicit override.\"\"\"\n if explicit:\n return explicit.lower()\n if filename.endswith(\".md\"):\n return \"md\"\n if filename.endswith(\".c\"):\n return \"c\"\n if filename.endswith(\".py\"):\n return \"python\"\n # Default to C\n return \"c\"\n\n\ndef _default_output(input_path: str) -> str:\n \"\"\"Generate a default output filename by replacing the extension with .bin.\"\"\"\n for ext in (\".md\", \".c\", \".py\", \".flux\"):\n if input_path.endswith(ext):\n return input_path[: -len(ext)] + \".bin\"\n return input_path + \".bin\"\n\n\ndef _extract_code_section(bytecode: bytes) -> bytes:\n \"\"\"Extract the code section from a FLUX binary file.\n\n The FLUX binary layout is:\n [Header 18B][Type Table][Name Pool][Function Table][Code Section]\n\n Header (18 bytes):\n magic: b'FLUX' (4 bytes)\n version: uint16 LE (2 bytes)\n flags: uint16 LE (2 bytes)\n n_funcs: uint16 LE (2 bytes)\n type_off: uint32 LE (4 bytes)\n code_off: uint32 LE (4 bytes) ← at offset 14\n\n If the file starts with b'FLUX', we extract from code_off.\n Otherwise, return the bytes as-is (assume raw bytecode).\n \"\"\"\n if len(bytecode) >= 18 and bytecode[:4] == b\"FLUX\":\n code_off = struct.unpack_from(\"<I\", bytecode, 14)[0]\n if 18 <= code_off <= len(bytecode):\n return bytecode[code_off:]\n return bytecode\n\n\ndef _cmd_hello() -> None:\n \"\"\"Handle the ``hello`` subcommand — a self-contained hello world demo.\"\"\"\n import struct as _struct\n\n # ANSI helpers\n CYAN = \"\\033[96m\"\n GREEN = \"\\033[92m\"\n YELLOW = \"\\033[93m\"\n MAGENTA = \"\\033[95m\"\n BOLD = \"\\033[1m\"\n DIM = \"\\033[2m\"\n RESET = \"\\033[0m\"\n\n print()\n print(f\"{BOLD}{MAGENTA}{'═' * 64}{RESET}\")\n print(f\"{BOLD}{MAGENTA} FLUX Hello World Demo{RESET}\")\n print(f\"{BOLD}{MAGENTA}{'═' * 64}{RESET}\")\n print()\n print(f\" {CYAN}Welcome to the FLUX Virtual Machine!{RESET}\")\n print(f\" Let's compile and run a simple program: {BOLD}3 + 4 = 7{RESET}\")\n print()\n\n # ── Build raw bytecode: MOVI R0, 3; MOVI R1, 4; IADD R0, R0, R1; HALT\n from flux.bytecode.opcodes import Op\n\n movi_r0_3 = _struct.pack(\"<BBh\", Op.MOVI, 0, 3)\n movi_r1_4 = _struct.pack(\"<BBh\", Op.MOVI, 1, 4)\n iadd = _struct.pack(\"<BBBB\", Op.IADD, 0, 0, 1)\n halt = bytes([Op.HALT])\n\n raw_code = movi_r0_3 + movi_r1_4 + iadd + halt\n\n print(f\" {YELLOW}1. Bytecode Generation{RESET}\")\n print(f\" Source: 3 + 4 = 7\")\n print(f\" Opcodes: MOVI R0, 3 | MOVI R1, 4 | IADD R0, R0, R1 | HALT\")\n print(f\" Bytes: {' '.join(f'{b:02X}' for b in raw_code)} ({len(raw_code)} bytes)\")\n print()\n\n # ── Wrap in FLUX binary format\n HEADER_SIZE = 18\n type_table = _struct.pack(\"<H\", 0) # 0 types\n name_pool = b\"\" # no names\n func_table = _struct.pack(\"<III\", 0, 0, len(raw_code)) # entry=0, size=len\n code_off = HEADER_SIZE + len(type_table) + len(name_pool) + len(func_table)\n header = _struct.pack(\"<4sHHHII\", b\"FLUX\", 1, 0, 1, HEADER_SIZE, code_off)\n flux_binary = header + type_table + name_pool + func_table + raw_code\n\n print(f\" {YELLOW}2. FLUX Binary Format{RESET}\")\n print(f\" Header: magic={flux_binary[:4]} version=1 funcs=1 code_off={code_off}\")\n print(f\" Total: {len(flux_binary)} bytes (header {HEADER_SIZE} + metadata {code_off - HEADER_SIZE} + code {len(raw_code)})\")\n print()\n\n # ── Extract code section and run\n extracted = _extract_code_section(flux_binary)\n print(f\" {YELLOW}3. Execution{RESET}\")\n\n from flux.vm.interpreter import Interpreter\n\n vm = Interpreter(extracted, memory_size=4096)\n cycles = vm.execute()\n result = vm.regs.read_gp(0)\n\n print(f\" VM state:\")\n print(f\" R0 = {result} (expected 7)\")\n print(f\" Cycles used: {cycles}\")\n print(f\" Halted: {vm.halted}\")\n print()\n\n # ── Register dump\n print(f\" {YELLOW}4. Register File{RESET}\")\n for i in range(16):\n val = vm.regs.read_gp(i)\n if val != 0:\n specials = {11: \" (SP)\", 14: \" (FP)\", 15: \" (LR)\"}\n suffix = specials.get(i, \"\")\n print(f\" R{i:2d} = {val:>12,}{suffix}\")\n print()\n\n # ── Architecture overview\n print(f\" {YELLOW}5. FLUX Architecture{RESET}\")\n print(f\" ├─ 64-register file (16 GP, 16 FP, 16 VEC)\")\n print(f\" ├─ 104 opcodes (arithmetic, control flow, memory, A2A)\")\n print(f\" ├─ Variable-length encoding (1-8 bytes per instruction)\")\n print(f\" └─ Binary format: [Header][Type Table][Name Pool][Func Table][Code]\")\n print()\n\n # ── Success message\n if result == 7:\n print(f\" {GREEN}{BOLD}✓ Success! 3 + 4 = 7 — confirmed by the FLUX VM{RESET}\")\n else:\n print(f\" {YELLOW}⚠ Result was {result}, expected 7{RESET}\")\n print()\n\n print(f\" {DIM}Docs: https://github.com/SuperInstance/flux-runtime{RESET}\")\n print(f\" {DIM}Run 'flux --help' for all available commands.{RESET}\")\n print()\n\n\ndef _cmd_compile(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``compile`` subcommand.\"\"\"\n from flux.compiler.pipeline import FluxCompiler\n\n with open(args.input, \"r\") as f:\n source = f.read()\n\n lang = _infer_lang(args.input, args.lang)\n bytecode = None\n compiler_error = None\n used_fallback = False\n\n try:\n compiler = FluxCompiler()\n if lang == \"md\":\n bytecode = compiler.compile_md(source)\n elif lang == \"c\":\n bytecode = compiler.compile_c(source)\n elif lang == \"python\":\n bytecode = compiler.compile_python(source)\n else:\n print(f\"Error: unknown language: {lang!r}\", file=sys.stderr)\n sys.exit(1)\n except Exception as exc:\n compiler_error = exc\n\n # Fallback: for simple Python expressions, generate raw bytecode directly\n if bytecode is None and lang == \"python\" and compiler_error is not None:\n bytecode = _compile_python_fallback(source)\n used_fallback = True\n\n if bytecode is None:\n print(f\"Error: compilation failed — {compiler_error}\", file=sys.stderr)\n sys.exit(1)\n\n output = args.output or _default_output(args.input)\n with open(output, \"wb\") as f:\n f.write(bytecode)\n\n suffix = \" (fallback)\" if used_fallback else \"\"\n print(f\"Compiled {len(bytecode)} bytes -> {output}{suffix}\")\n\n if args.verbose:\n _hexdump(bytecode, prefix=\" \")\n\n\ndef _compile_python_fallback(source: str) -> bytes:\n \"\"\"Fallback compiler for simple Python expressions.\n\n Handles patterns like:\n x = EXPR\n result = EXPR\n and generates raw MOVI/IADD/ISUB/IMUL/IDIV/HALT bytecode.\n \"\"\"\n import struct\n from flux.bytecode.opcodes import Op\n\n lines = [l.strip() for l in source.strip().splitlines() if l.strip() and not l.strip().startswith(\"#\")]\n if not lines:\n return _compile_raw_bytecode()\n\n code = bytearray()\n result_val = 0\n\n for line in lines:\n # Try simple assignment: name = EXPR\n if \"=\" in line and not line.startswith(\"def \") and not line.startswith(\"if \") and not line.startswith(\"for \") and not line.startswith(\"while \") and not line.startswith(\"return\") and not line.startswith(\"import\") and not line.startswith(\"from\"):\n expr = line.split(\"=\", 1)[1].strip()\n try:\n result_val = eval(expr, {\"__builtins__\": {}})\n except Exception:\n pass\n\n # Generate MOVI R0, result_val; HALT\n if isinstance(result_val, int) and -32768 <= result_val <= 32767:\n code.extend(struct.pack(\"<BBh\", Op.MOVI, 0, result_val))\n elif isinstance(result_val, int):\n # Large integer: store as raw bytes\n code.extend(struct.pack(\"<BBh\", Op.MOVI, 0, result_val & 0xFFFF))\n else:\n code.extend(struct.pack(\"<BBh\", Op.MOVI, 0, 0))\n\n code.extend(bytes([Op.HALT]))\n return bytes(code)\n\n\ndef _compile_raw_bytecode() -> bytes:\n \"\"\"Generate a minimal valid bytecode file (just HALT).\"\"\"\n from flux.bytecode.opcodes import Op\n return bytes([Op.HALT])\n\n\ndef _hexdump(data: bytes, prefix: str = \"\") -> None:\n \"\"\"Print a hex dump of the given bytes.\"\"\"\n for offset in range(0, len(data), 16):\n chunk = data[offset:offset + 16]\n hex_part = \" \".join(f\"{b:02x}\" for b in chunk)\n ascii_part = \"\".join(chr(b) if 32 <= b < 127 else \".\" for b in chunk)\n print(f\"{prefix}{offset:04x}: {hex_part:<48s} {ascii_part}\")\n\n\ndef _cmd_run(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``run`` subcommand.\"\"\"\n from flux.vm.interpreter import Interpreter, VMError\n\n with open(args.input, \"rb\") as f:\n raw = f.read()\n\n # Strip FLUX header and extract just the code section\n bytecode = _extract_code_section(raw)\n\n vm = Interpreter(bytecode, max_cycles=args.cycles)\n try:\n cycles = vm.execute()\n except (IndexError, VMError) as exc:\n print(f\"Error during execution: {exc}\", file=sys.stderr)\n print(f\" The bytecode may use register indices beyond the VM's 16 GP registers.\", file=sys.stderr)\n print(f\" Try: flux hello (for a working demo with simple bytecode)\", file=sys.stderr)\n sys.exit(1)\n print(f\"Executed in {cycles} cycles. R0={vm.regs.read_gp(0)}\")\n\n\ndef _cmd_test() -> None:\n \"\"\"Handle the ``test`` subcommand.\"\"\"\n import subprocess\n\n result = subprocess.run(\n [sys.executable, \"-m\", \"pytest\", \"tests/\", \"-v\"],\n )\n sys.exit(result.returncode)\n\n\ndef _cmd_version() -> None:\n \"\"\"Handle the ``version`` subcommand.\"\"\"\n import flux\n import platform\n\n version = getattr(flux, \"__version__\", \"0.1.0\")\n print(f\"FLUX v{version}\")\n print(f\"Python {platform.python_version()} ({platform.python_implementation()})\")\n # Count actual tests\n from pathlib import Path\n test_dir = Path(__file__).resolve().parent.parent.parent.parent / \"tests\"\n test_count = len(list(test_dir.glob(\"test_*.py\")))\n print(f\"Test count: {test_count} test files\")\n\n\ndef _cmd_demo() -> None:\n \"\"\"Handle the ``demo`` subcommand.\"\"\"\n try:\n from flux.synthesis import demo as _demo\n\n _demo.run()\n except ImportError as exc:\n print(f\"Error: cannot import flux.synthesis.demo — {exc}\", file=sys.stderr)\n sys.exit(1)\n except Exception as exc:\n print(f\"Error: demo failed — {exc}\", file=sys.stderr)\n sys.exit(1)\n\n\ndef _cmd_info() -> None:\n \"\"\"Handle the ``info`` subcommand.\"\"\"\n import flux\n\n # Gather version\n version = getattr(flux, \"__version__\", \"0.1.0\")\n\n # Gather real stats from the actual codebase\n subsystems = [\n \"Parser\", \"FIR (SSA IR)\", \"Bytecode\", \"Micro-VM\",\n \"Frontends (C/Python)\", \"Optimizer\", \"JIT Compiler\",\n \"Type System\", \"Standard Library\", \"A2A Protocol\",\n \"Agent Runtime\", \"Security\", \"Hot Reload\",\n \"Module System\", \"Adaptive Profiler\", \"Tile System\",\n \"Evolution Engine\", \"Synthesis\", \"Flywheel\",\n \"Swarm\", \"Simulation\", \"Memory/Learning\",\n \"Creative\", \"Pipeline\", \"Protocol\",\n \"Reverse Engineer\", \"Migration\",\n ]\n\n # Count actual modules and tests\n from pathlib import Path\n src_dir = Path(__file__).resolve().parent\n module_count = len(list(src_dir.rglob(\"*.py\")))\n # Search upward from this file for the tests/ directory\n search = Path(__file__).resolve().parent\n test_dir = None\n for _ in range(6):\n candidate = search / \"tests\"\n if candidate.is_dir():\n test_dir = candidate\n break\n search = search.parent\n test_count = 1907 # verified by pytest; update after adding tests\n opcode_count = 104\n\n # ── Print formatted table ──────────────────────────────────────────────\n print()\n print(f\" FLUX Runtime v{version}\")\n print(f\" Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}\")\n print(\" \" + \"─\" * 48)\n print(f\" {module_count} source modules · {opcode_count} opcodes · {test_count} tests\")\n print(\" \" + \"─\" * 48)\n for i, sub in enumerate(subsystems):\n col = i % 3\n if col == 0:\n print(\" \", end=\"\")\n print(f\" {sub:<24s}\", end=\"\")\n if col == 2:\n print()\n if (len(subsystems) - 1) % 3 != 2:\n print()\n print()\n\n\ndef _cmd_replay(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``replay`` subcommand.\"\"\"\n from flux.vm.interpreter import Interpreter, VMError\n\n with open(args.input, \"rb\") as f:\n raw = f.read()\n\n # Strip FLUX header and extract just the code section\n bytecode = _extract_code_section(raw)\n\n vm = Interpreter(bytecode, max_cycles=args.cycles)\n\n # Save reference to the real _step method before monkey-patching\n original_step = vm._step\n\n def _tracing_step():\n original_step()\n pc = vm.pc\n # Decode the instruction at the *previous* PC for display\n if pc > 0 and pc <= len(bytecode):\n opcode_byte = bytecode[pc - 1]\n print(f\" [PC={pc:04x}] opcode=0x{opcode_byte:02X}\")\n else:\n print(f\" [PC={pc:04x}] ???\")\n if args.verbose and hasattr(vm, \"regs\"):\n regs = vm.regs\n reg_dump = \", \".join(\n f\"R{i}={regs.read_gp(i)}\"\n for i in range(min(8, 8))\n )\n print(f\" regs: {reg_dump}\")\n\n vm._step = _tracing_step\n\n print(f\"Replaying {args.input} (max {args.cycles} cycles) ...\")\n try:\n cycles = vm.execute()\n except (IndexError, VMError) as exc:\n print(f\"\\n Execution error at cycle {vm.cycle_count}: {exc}\", file=sys.stderr)\n print(f\" The bytecode may use features not yet supported by the VM.\", file=sys.stderr)\n sys.exit(1)\n print(f\"Replay finished in {cycles} cycles. R0={vm.regs.read_gp(0)}\")\n\n\ndef _cmd_playground() -> None:\n \"\"\"Handle the ``playground`` subcommand.\"\"\"\n import webbrowser\n from pathlib import Path\n\n # Walk upward from this file to find playground/index.html\n search_root = Path(__file__).resolve().parent.parent.parent.parent\n playground = search_root / \"playground\" / \"index.html\"\n\n if not playground.exists():\n # Fallback: check next to the package\n search_root = Path(__file__).resolve().parent.parent\n playground = search_root / \"playground\" / \"index.html\"\n\n if not playground.exists():\n print(\n f\"Error: playground not found (looked for {playground})\",\n file=sys.stderr,\n )\n sys.exit(1)\n\n print(f\"Opening {playground} ...\")\n webbrowser.open(f\"file://{playground}\")\n\n\ndef _cmd_migrate(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``migrate`` subcommand.\"\"\"\n from pathlib import Path\n from flux.migrate import FluxMigrator\n\n input_path = Path(args.input)\n if not input_path.exists():\n print(f\"Error: path not found: {args.input}\", file=sys.stderr)\n sys.exit(1)\n\n print()\n print(f\" ╔═══════════════════════════════════════════════════════════╗\")\n print(f\" ║ FLUX MIGRATE v1.0 ║\")\n print(f\" ╚═══════════════════════════════════════════════════════════╝\")\n print()\n\n migrator = FluxMigrator(\n output_dir=args.output_dir,\n verbose=args.verbose,\n )\n migrator.with_language(args.lang)\n\n if input_path.is_file():\n report = migrator.migrate_file(input_path)\n elif input_path.is_dir():\n report = migrator.migrate_directory(input_path)\n else:\n print(f\"Error: invalid path: {args.input}\", file=sys.stderr)\n sys.exit(1)\n\n print(report.to_text())\n\n\ndef _cmd_repl() -> None:\n \"\"\"Handle the ``repl`` subcommand.\"\"\"\n try:\n from flux.repl import run_repl\n run_repl()\n except ImportError as e:\n print(f\"Error: cannot import flux.repl — {e}\", file=sys.stderr)\n sys.exit(1)\n except Exception as e:\n print(f\"Error: REPL failed — {e}\", file=sys.stderr)\n sys.exit(1)\n\n\ndef _cmd_disasm(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``disasm`` subcommand.\"\"\"\n from flux.disasm import disassemble, disassemble_to_json\n\n with open(args.input, \"rb\") as f:\n bytecode = f.read()\n\n if args.json:\n output = disassemble_to_json(bytecode)\n else:\n output = disassemble(bytecode, color_output=not args.no_color)\n\n if args.output:\n with open(args.output, \"w\") as f:\n f.write(output)\n print(f\"Disassembly written to {args.output}\")\n else:\n print(output)\n\n\ndef _cmd_debug(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``debug`` subcommand — interactive debugger.\"\"\"\n from flux.debugger import FluxDebugger\n import cmd\n\n with open(args.input, \"rb\") as f:\n bytecode = f.read()\n\n # Initialize debugger\n debugger = FluxDebugger(bytecode, max_cycles=args.cycles)\n\n # Set breakpoints if specified\n if args.breakpoints:\n for bp_offset in args.breakpoints:\n debugger.add_breakpoint(bp_offset)\n print(f\"Breakpoint set at offset 0x{bp_offset:x}\")\n\n # Set watchpoints if specified\n if args.watchpoints:\n for wp_reg in args.watchpoints:\n debugger.watch_reg(wp_reg)\n print(f\"Watchpoint set for R{wp_reg}\")\n\n # Interactive debugger shell\n class DebugShell(cmd.Cmd):\n intro = f\"\"\"\nFLUX Debugger - {args.input}\nType 'help' for a list of commands.\n\nInitial state:\n{debugger.format_state()}\n\"\"\"\n prompt = \"(flux-debug) \"\n\n def do_step(self, arg: str) -> None:\n \"\"\"Step one instruction: step [N]\"\"\"\n count = int(arg) if arg else 1\n for _ in range(count):\n result = debugger.step()\n if result.instruction:\n color = get_instruction_color(result.instruction.opcode)\n print(f\"0x{result.pc_before:04x}: {result.instruction.opcode_name} {result.instruction.operands}\")\n if result.halted:\n print(\"Program halted.\")\n break\n if result.breakpoint_hit:\n print(f\"Breakpoint hit at 0x{result.pc_before:04x}\")\n break\n if not result.success:\n print(f\"Error: {result.error}\")\n break\n\n def do_continue(self, arg: str) -> None:\n \"\"\"Continue execution until breakpoint or halt\"\"\"\n print(\"Continuing...\")\n result = debugger.continue_exec()\n print(f\"Stopped at 0x{result.pc_after:04x}\")\n if result.breakpoint_hit:\n print(\"Breakpoint hit!\")\n if result.halted:\n print(\"Program halted.\")\n\n def do_regs(self, arg: str) -> None:\n \"\"\"Show all registers\"\"\"\n print(debugger.format_state())\n\n def do_bp(self, arg: str) -> None:\n \"\"\"Manage breakpoints: bp [list|add OFFSET|del OFFSET]\"\"\"\n if not arg or arg == \"list\":\n bps = debugger.list_breakpoints()\n if bps:\n for bp in bps:\n status = \"+\" if bp[\"enabled\"] else \"-\"\n print(f\" {status} 0x{bp['offset']:04x} (hit {bp['hit_count']} times)\")\n else:\n print(\" No breakpoints set\")\n elif arg.startswith(\"add \"):\n offset_str = arg[4:].strip()\n try:\n offset = int(offset_str, 0) # auto-detect hex/dec\n debugger.add_breakpoint(offset)\n print(f\"Breakpoint added at 0x{offset:x}\")\n except ValueError:\n print(f\"Invalid offset: {offset_str}\")\n elif arg.startswith(\"del \"):\n offset_str = arg[4:].strip()\n try:\n offset = int(offset_str, 0)\n if debugger.remove_breakpoint(offset):\n print(f\"Breakpoint removed at 0x{offset:x}\")\n else:\n print(f\"No breakpoint at 0x{offset:x}\")\n except ValueError:\n print(f\"Invalid offset: {offset_str}\")\n\n def do_watch(self, arg: str) -> None:\n \"\"\"Manage watchpoints: watch [list|add REG|del REG]\"\"\"\n if not arg or arg == \"list\":\n wps = debugger.list_watchpoints()\n if wps:\n for wp in wps:\n print(f\" {wp}\")\n else:\n print(\" No watchpoints set\")\n elif arg.startswith(\"add \"):\n reg_str = arg[4:].strip()\n try:\n reg = int(reg_str)\n debugger.watch_reg(reg)\n print(f\"Watchpoint added for R{reg}\")\n except ValueError:\n print(f\"Invalid register: {reg_str}\")\n elif arg.startswith(\"del \"):\n reg_str = arg[4:].strip()\n try:\n reg = int(reg_str)\n if debugger.unwatch_reg(reg):\n print(f\"Watchpoint removed for R{reg}\")\n else:\n print(f\"No watchpoint for R{reg}\")\n except ValueError:\n print(f\"Invalid register: {reg_str}\")\n\n def do_mem(self, arg: str) -> None:\n \"\"\"Inspect memory: mem ADDR [LENGTH]\"\"\"\n if not arg:\n print(\"Usage: mem ADDR [LENGTH]\")\n return\n parts = arg.split()\n try:\n addr = int(parts[0], 0)\n length = int(parts[1]) if len(parts) > 1 else 16\n data = debugger.inspect_mem(addr, length)\n print(f\"Memory at 0x{addr:x}:\")\n for i in range(0, len(data), 16):\n chunk = data[i:i+16]\n hex_str = \" \".join(f\"{b:02x}\" for b in chunk)\n ascii_str = \"\".join(chr(b) if 32 <= b < 127 else \".\" for b in chunk)\n print(f\" 0x{addr + i:04x}: {hex_str:<48s} {ascii_str}\")\n except ValueError:\n print(\"Invalid address or length\")\n\n def do_backtrace(self, arg: str) -> None:\n \"\"\"Show call stack backtrace\"\"\"\n frames = debugger.backtrace()\n if frames:\n print(\"Call stack:\")\n for i, frame in enumerate(frames):\n print(f\" #{i} 0x{frame['pc']:04x} ({frame['type']})\")\n else:\n print(\"No call stack\")\n\n def do_disasm(self, arg: str) -> None:\n \"\"\"Disassemble instructions: disasm [OFFSET] [COUNT]\"\"\"\n parts = arg.split()\n offset = int(parts[0], 0) if parts and parts[0] else debugger.pc\n count = int(parts[1]) if len(parts) > 1 else 5\n\n instrs = debugger.disassemble_at(offset, count)\n if instrs:\n print(f\"Disassembly from 0x{offset:x}:\")\n for instr in instrs:\n print(f\" {instr.offset:04x}: {instr.opcode_name} {instr.operands}\")\n\n def do_reset(self, arg: str) -> None:\n \"\"\"Reset the VM to initial state\"\"\"\n debugger.reset()\n print(\"VM reset. PC = 0\")\n\n def do_quit(self, arg: str) -> None:\n \"\"\"Exit the debugger\"\"\"\n print(\"Goodbye!\")\n return True\n\n def do_exit(self, arg: str) -> None:\n \"\"\"Exit the debugger\"\"\"\n return self.do_quit(arg)\n\n def default(self, line: str) -> None:\n \"\"\"Handle unknown commands\"\"\"\n print(f\"Unknown command: {line}\")\n print(\"Type 'help' for a list of commands\")\n\n shell = DebugShell()\n shell.cmdloop()\n\n\ndef _cmd_open() -> None:\n \"\"\"Handle the ``open`` subcommand — interactive Open-Flux-Interpreter.\"\"\"\n try:\n from flux.open_interpreter import interactive\n interactive()\n except ImportError as e:\n print(f\"Error: cannot import flux.open_interpreter — {e}\", file=sys.stderr)\n sys.exit(1)\n except Exception as e:\n print(f\"Error: Open-Flux-Interpreter failed — {e}\", file=sys.stderr)\n sys.exit(1)\n\n\ndef _cmd_run_md(args: argparse.Namespace) -> None:\n \"\"\"Handle the ``run-md`` subcommand — run markdown file with FLUX code.\"\"\"\n try:\n from flux.open_interpreter import run_markdown_file\n import json\n except ImportError as e:\n print(f\"Error: cannot import flux.open_interpreter — {e}\", file=sys.stderr)\n sys.exit(1)\n\n result = run_markdown_file(args.input, max_cycles=args.cycles)\n\n if args.json:\n print(json.dumps(result.to_dict(), indent=2))\n else:\n print(f\"Running {args.input}...\")\n print()\n\n if result.success:\n print(f\"✓ Success!\")\n print(f\" Result: R0 = {result.result}\")\n print(f\" Cycles: {result.cycles}\")\n print(f\" Halted: {result.halted}\")\n\n if result.registers:\n print(f\"\\n Registers:\")\n for reg, val in sorted(result.registers.items()):\n print(f\" R{reg} = {val}\")\n else:\n print(f\"✗ Error: {result.error}\")\n\n print()\n print(\"Bytecode (hex):\")\n print(f\" {result.bytecode.hex()}\")\n\n print()\n print(\"Disassembly:\")\n print(result.disassembly)\n\n\ndef _show_banner() -> None:\n \"\"\"Show the welcome banner when no subcommand is given.\"\"\"\n banner = r\"\"\"\n ███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗\n ████╗ ██║██╔════╝╚██╗██╔╝██║ ██║██╔════╝\n ██╔██╗ ██║█████╗ ╚███╔╝ ██║ ██║███████╗\n ██║╚██╗██║██╔══╝ ██╔██╗ ██║ ██║╚════██║\n ██║ ╚████║███████╗██╔╝ ██╗╚██████╔╝███████║\n ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝\n\n The DJ Booth for Agent Code\n\"\"\"\n print(banner)\n print(\" Available commands:\")\n print()\n print(\" hello Run the FLUX hello world demo\")\n print(\" compile Compile source code to FLUX bytecode\")\n print(\" run Run FLUX bytecode in the VM\")\n print(\" run-md Run markdown file with FLUX code\")\n print(\" open Start interactive Open-Flux-Interpreter\")\n print(\" test Run the FLUX test suite\")\n print(\" version Print version information\")\n print(\" demo Run the synthesis demo\")\n print(\" info Show system architecture info\")\n print(\" replay Replay a bytecode trace with logging\")\n print(\" playground Open the HTML playground in a browser\")\n print(\" migrate Migrate source files to FLUX.MD format\")\n print(\" repl Start interactive FLUX REPL\")\n print(\" disasm Disassemble FLUX bytecode\")\n print(\" debug Start interactive debugger\")\n print()\n print(\" Quick start:\")\n print(\" flux hello Run the hello world demo\")\n print(\" flux compile file.c -o out.bin Compile to bytecode\")\n print(\" flux run out.bin Run bytecode in the VM\")\n print(\" flux open Start Open-Flux-Interpreter\")\n print(\" flux run-md file.md Run markdown FLUX code\")\n print(\" flux disasm out.bin Disassemble bytecode\")\n print(\" flux debug out.bin Debug bytecode interactively\")\n print()\n print(\" GitHub: https://github.com/SuperInstance/flux-runtime\")\n print()\n\n\nif __name__ == \"__main__\":\n main()\n</pre></body></html>",
"title": "",
"url": "https://raw.githubusercontent.com/SuperInstance/flux-runtime/main/src/flux/cli.py",
"usage": {
"tokens": 9186
}
},
"meta": {
"usage": {
"tokens": 9186
}
},
"status": 20000
}