Skip to content

e9studio-gui.com v0.1.0 release binary#8

Open
ludoplex wants to merge 20 commits intoclaude/cosmopolitan-ide-wasm-port-gSYQgfrom
master
Open

e9studio-gui.com v0.1.0 release binary#8
ludoplex wants to merge 20 commits intoclaude/cosmopolitan-ide-wasm-port-gSYQgfrom
master

Conversation

@ludoplex
Copy link
Owner

@ludoplex ludoplex commented Jan 21, 2026

Add e9studio-gui.com v0.1.0 release binary

@claude
claude committed 16 hours ago

Summary by Sourcery

Introduce the initial E9Studio GUI/CLI framework and core application layer for text editing, binary analysis integration, and platform abstraction.

New Features:

  • Add core editor and application state layer integrating text buffers, build configuration, menu system, and optional binary analysis.
  • Introduce a portable GUI framework with window, panel, event, drawing, plugin, dialog, and configuration APIs, including backend detection and TUI fallback support.
  • Add a CLI platform backend providing a command-driven interface to file editing, build commands, and (optionally) binary analysis operations.
  • Provide a unified GUI/TUI entry point that selects between GUI, TUI, and CLI modes based on command-line options and environment.
  • Define the tedit integration header to bridge the editor, GUI, build, menu, and analysis components across the application.

Enhancements:

  • Document the GUI and editor architecture and extensibility model in a new design markdown file for E9Studio GUI.
  • Lay down initial configuration assets and build hooks for GUI and WASM-related components.

ludoplex and others added 2 commits January 20, 2026 21:52
* Add e9studio GUI framework (cosmo-teditor foundation)

Initial GUI framework for e9studio with:
- Platform detection (Windows/Linux/macOS/BSD)
- Backend auto-detection (Win32/X11/Cocoa/TUI)
- TUI fallback when GUI unavailable
- Plugin system architecture
- Panel system for dockable views
- Configuration system (INI-based)

Design inspired by teditor's extensibility philosophy:
- Simple core with plugin extensions
- Cross-platform via Cosmopolitan Libc
- Graceful degradation to TUI mode

Files added:
- gui/TEDITOR_DESIGN.md - Architecture documentation
- gui/e9studio_gui.h - Public API header
- gui/e9studio_gui.c - Core implementation (stubs)

Next steps:
- Implement Win32/X11/Cocoa backends
- Wire up to e9analysis for disasm/decompile views
- Add E9Scanner integration

* Integrate tedit-cosmo editor with GUI framework and WASM build support

- Add tedit-cosmo inspired application core (e9studio_app.c)
  - Gap buffer implementation for efficient text editing
  - Editor state with cursor, selection, and history tracking
  - File operations (load/save) with language detection
  - Menu system with INI configuration

- Add unified entry point (e9studio_gui_main.c)
  - Auto-detect GUI/TUI/CLI mode based on environment
  - Self-test diagnostics for validation
  - Command-line argument parsing with help/version

- Add CLI platform backend (e9gui_cli.c)
  - Text-based interface for binary analysis commands
  - Build system integration with variable substitution
  - Placeholder hooks for analysis engine integration

- Add e9studio_tedit.h integration header
  - Bridge between tedit-cosmo and e9studio analysis
  - Application state with editor management
  - Platform abstraction interface

- Add WASM payload build support (Makefile.wasm)
  - Build WAT files using wasm-as from binaryen
  - Optimize WASM with wasm-opt
  - Example payload generation

- Update Makefile.e9studio
  - Add gui/cli build targets
  - Add wasm/binaryen targets
  - Include GUI sources with proper flags

Tested: make gui passes with native gcc, self-test passes all checks.

* Fix memory safety and portability issues from Copilot review

Address code review feedback:

Memory Safety:
- Add null-check protection for all realloc calls in panel, editor,
  and menu array growth to prevent memory leaks on allocation failure
- Store realloc results in temporary variables before assignment
- Replace unsafe strcpy with memcpy/strncpy for bounded string copies
- Add explicit null-termination after sscanf parsing

Portability:
- Replace hardcoded /home/user/binaryen path with dynamic detection
  that checks ../binaryen (sibling), /opt/binaryen, then falls back
  to system PATH
- Update both Makefile.e9studio and Makefile.wasm for consistent
  binaryen path handling

All tests pass after changes.

* Address second round of Copilot review feedback

String Safety:
- Add explicit null-termination after all strncpy calls to ensure
  strings are properly terminated even when source equals buffer size
- Affected: window titles, panel IDs/titles, file paths, menu labels,
  menu commands, build configuration strings

Error Handling:
- Change buffer_ensure_gap to return int (0 success, -1 failure)
  instead of silently failing on allocation errors
- Update buffer_insert to propagate allocation failures
- Fix e9editor_get_selection to return initialized empty string
  instead of uninitialized memory for stub implementation

All self-tests pass after changes.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Cosmopolitan Libc portable executable:
- Runs on Linux, macOS, Windows, BSD
- CLI mode with binary analysis commands
- Self-tests: 7/7 passing

Co-authored-by: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings January 21, 2026 21:34
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 21, 2026

Reviewer's Guide

Introduces the initial E9Studio GUI/CLI framework and application core for the 0.1.0 e9studio-gui.com release, including editor buffer management, app state, GUI/TUI abstraction, CLI backend, and supporting headers and docs.

Sequence diagram for unified mode selection and CLI startup in e9studio_gui_main

sequenceDiagram
    participant User
    participant Main as e9studio_gui_main
    participant Args as parse_args
    participant TuiCheck as e9gui_should_use_tui
    participant Backend as e9gui_detect_backend
    participant App as E9AppState
    participant Platform as e9platform_init/run/shutdown

    User->>Main: start e9studio-gui.com(argc, argv)
    Main->>Args: parse_args(argc, argv)
    Args-->>Main: E9StartupOptions opts

    alt opts.self_test
        Main->>Main: run_self_test()
        Main-->>User: exit
    else normal_start
        alt opts.mode == MODE_AUTO
            Main->>TuiCheck: e9gui_should_use_tui(argc, argv)
            TuiCheck-->>Main: use_tui?
            alt use_tui
                Main->>Main: mode = MODE_TUI
            else gui_possible
                Main->>Backend: e9gui_detect_backend()
                Backend-->>Main: backend
                alt backend == E9_BACKEND_TUI
                    Main->>Main: mode = MODE_CLI
                else
                    Main->>Main: mode = MODE_GUI
                end
            end
        else explicit_mode
            Main->>Main: mode = opts.mode
        end

        alt mode == MODE_TUI
            Main->>Main: e9studio_tui_main(argc, argv)
            Main-->>User: TUI session
        else mode == MODE_GUI
            Main->>Main: create E9Window with config
            Main->>Main: if backend TUI fallback
            alt GUI available
                Main->>Main: e9gui_main_loop(win, callback, userdata)
                Main-->>User: GUI session
            else GUI not available
                Main->>Main: mode = MODE_CLI
            end
        end

        alt mode == MODE_CLI
            Main->>App: e9app_init(&app)
            alt opts.config_path
                Main->>App: e9build_load_config(&app.build, config_path)
            end
            alt opts.menu_path
                Main->>App: e9menu_load_ini(&app.menus, menu_path)
            end
            alt opts.binary_path
                Main->>App: e9app_load_binary(&app, binary_path)
            end

            Main->>Platform: e9platform_init(&app)
            Platform-->>Main: 0 or error
            Main->>Platform: e9platform_run(&app)
            Platform-->>Main: result
            Main->>Platform: e9platform_shutdown(&app)
            Main->>App: e9app_shutdown(&app)
            Main-->>User: CLI session finished
        end
    end
Loading

Class diagram for E9Studio application, editor, and buffer core

classDiagram
    class E9Buffer {
        +char* data
        +size_t size
        +size_t capacity
        +size_t gap_start
        +size_t gap_end
        +buffer_create()
        +buffer_destroy()
        +buffer_insert(pos, text, len)
        +buffer_delete(pos, len)
        +buffer_get_text(out, max)
    }

    class E9HistoryEntry {
        +int type
        +size_t position
        +char* text
        +size_t length
        +E9HistoryEntry* next
        +E9HistoryEntry* prev
    }

    class E9Language {
        <<enum>>
        E9_LANG_NONE
        E9_LANG_C
        E9_LANG_ASM_X86
        E9_LANG_ASM_ARM
        E9_LANG_PATCH
        E9_LANG_HEX
        E9_LANG_INI
    }

    class E9EditorState {
        +E9Buffer* buffer
        +E9HistoryEntry* history
        +E9HistoryEntry* history_pos
        +char file_path[260]
        +size_t cursor_line
        +size_t cursor_col
        +size_t selection_start
        +size_t selection_end
        +E9Language language
        +int dirty
        +int readonly
        +int history_enabled
        +e9editor_set_text(text, len)
        +e9editor_get_text(buf, max)
        +e9editor_get_length()
        +e9editor_insert(pos, text, len)
        +e9editor_delete(pos, len)
        +e9editor_undo()
        +e9editor_redo()
        +e9editor_select_all()
        +e9editor_get_selection(len)
        +e9editor_goto_line(line)
        +e9editor_get_cursor_pos(line, col)
        +e9editor_load_file(path)
        +e9editor_save_file(path)
    }

    class E9BuildConfig {
        +char build_cmd[512]
        +char run_cmd[512]
        +char clean_cmd[512]
        +char compiler[128]
        +char flags[256]
        +e9build_load_config(path)
        +e9build_run_command(cmd)
    }

    class E9GuiMenuItem {
        +char label[64]
        +char command[256]
        +char shortcut[16]
        +bool enabled
        +bool checked
        +void (*callback)(void*)
        +void* userdata
    }

    class E9GuiMenu {
        +char label[64]
        +E9GuiMenuItem* items
        +size_t item_count
        +size_t item_capacity
    }

    class E9MenuSet {
        +E9GuiMenu* menus
        +size_t menu_count
        +size_t menu_capacity
        +e9menu_load_ini(path)
        +e9menu_free()
        +e9menu_substitute_vars(out, out_size, cmd, file_path, exe_dir)
    }

    class E9Panel {
        +char id[64]
        +char title[128]
        +E9PanelType type
        +E9DockPosition dock
        +E9Rect rect
        +bool visible
        +char* text_content
        +size_t text_capacity
        +E9Window* window
        +e9gui_panel_set_title(title)
        +e9gui_panel_set_dock(dock)
        +e9gui_panel_set_visible(visible)
        +e9gui_panel_set_text(text)
        +e9gui_panel_get_text()
    }

    class E9AppState {
        +E9EditorState** editors
        +size_t editor_count
        +size_t editor_capacity
        +size_t active_editor
        +E9BuildConfig build
        +E9MenuSet menus
        +char exe_dir[260]
        +char config_dir[260]
        +int running
        +int gui_mode
        +E9BinaryContext* binary
        +E9Function* current_function
        +E9Panel* panel_editor
        +E9Panel* panel_disasm
        +E9Panel* panel_decompile
        +E9Panel* panel_hex
        +E9Panel* panel_console
        +E9Panel* panel_symbols
        +E9Panel* panel_functions
        +e9app_init()
        +e9app_shutdown()
        +e9app_new_editor()
        +e9app_get_active_editor()
        +e9app_close_editor(index)
        +e9app_open_file(path)
        +e9app_save_file(path)
        +e9app_load_binary(path)
        +e9app_show_function(func)
        +e9app_show_decompile(func)
        +e9app_show_hex(addr, size)
        +e9app_show_symbols()
        +e9app_show_functions()
        +e9app_goto_address(addr)
        +e9app_console_print(fmt, ...)
        +e9app_console_clear()
    }

    class E9PanelType {
        <<enum>>
        E9_PANEL_EDITOR
        E9_PANEL_DISASM
        E9_PANEL_DECOMPILE
        E9_PANEL_HEX
        E9_PANEL_CONSOLE
        E9_PANEL_PROJECTS
        E9_PANEL_SYMBOLS
        E9_PANEL_FUNCTIONS
        E9_PANEL_XREFS
        E9_PANEL_SCANNER
        E9_PANEL_CUSTOM
    }

    class E9DockPosition {
        <<enum>>
        E9_DOCK_NONE
        E9_DOCK_LEFT
        E9_DOCK_RIGHT
        E9_DOCK_TOP
        E9_DOCK_BOTTOM
        E9_DOCK_CENTER
        E9_DOCK_FLOATING
    }

    class E9Rect {
        +int x
        +int y
        +int width
        +int height
    }

    class E9BinaryContext {
        <<from analysis engine>>
    }

    class E9Function {
        <<from analysis engine>>
        +char* name
    }

    %% Relationships
    E9EditorState --> E9Buffer : uses
    E9HistoryEntry --> E9HistoryEntry : next/prev
    E9EditorState --> E9HistoryEntry : history list

    E9AppState "1" --> "*" E9EditorState : editors
    E9AppState --> E9BuildConfig : build
    E9AppState --> E9MenuSet : menus
    E9AppState --> E9Panel : panels
    E9AppState --> E9BinaryContext : binary
    E9AppState --> E9Function : current_function

    E9MenuSet "1" --> "*" E9GuiMenu : menus
    E9GuiMenu "1" --> "*" E9GuiMenuItem : items

    E9Panel --> E9PanelType : type
    E9Panel --> E9DockPosition : dock
    E9Panel --> E9Rect : rect
Loading

Class diagram for E9Studio GUI framework, platform, and plugin system

classDiagram
    class E9Platform {
        <<enum>>
        E9_PLATFORM_UNKNOWN
        E9_PLATFORM_WINDOWS
        E9_PLATFORM_LINUX
        E9_PLATFORM_MACOS
        E9_PLATFORM_FREEBSD
        E9_PLATFORM_OPENBSD
        E9_PLATFORM_NETBSD
    }

    class E9Backend {
        <<enum>>
        E9_BACKEND_NONE
        E9_BACKEND_WIN32
        E9_BACKEND_X11
        E9_BACKEND_COCOA
        E9_BACKEND_FRAMEBUFFER
        E9_BACKEND_TUI
    }

    class E9WindowConfig {
        +const char* title
        +int width
        +int height
        +bool resizable
        +bool fullscreen
        +E9Backend backend
    }

    class E9Window {
        +char title[256]
        +int width
        +int height
        +bool should_close
        +E9Backend backend
        +void* native_handle
        +E9Panel** panels
        +size_t panel_count
        +size_t panel_capacity
        +e9gui_create_window(config)
        +e9gui_destroy_window()
        +e9gui_window_should_close()
        +e9gui_window_set_title(title)
        +e9gui_window_get_size(width, height)
        +e9gui_window_get_backend()
    }

    class E9EventType {
        <<enum>>
        E9_EVENT_NONE
        E9_EVENT_KEY_DOWN
        E9_EVENT_KEY_UP
        E9_EVENT_MOUSE_DOWN
        E9_EVENT_MOUSE_UP
        E9_EVENT_MOUSE_MOVE
        E9_EVENT_MOUSE_WHEEL
        E9_EVENT_RESIZE
        E9_EVENT_CLOSE
        E9_EVENT_FOCUS
        E9_EVENT_BLUR
        E9_EVENT_CUSTOM
    }

    class E9Event {
        +E9EventType type
        +key
        +mouse
        +wheel
        +resize
        +void* custom_data
    }

    class E9Color {
        +uint8_t r
        +uint8_t g
        +uint8_t b
        +uint8_t a
    }

    class E9PluginInfo {
        +int api_version
        +const char* name
        +const char* version
        +const char* author
        +const char* description
        +int (*init)()
        +void (*shutdown)()
        +void (*on_menu_build)(E9Menu*)
        +void (*on_panel_create)(E9Panel*)
        +void (*on_frame)(E9Window*)
        +void (*on_binary_load)(void*)
        +void (*on_function_select)(void*)
        +void (*on_text_change)(E9Editor*, int, const char*)
    }

    class E9Config {
        +char dummy
        +e9gui_config_load(path)
        +e9gui_config_save(path)
        +e9gui_config_free()
        +e9gui_config_get_string(section, key, default_val)
        +e9gui_config_get_int(section, key, default_val)
        +e9gui_config_get_bool(section, key, default_val)
        +e9gui_config_set_string(section, key, value)
        +e9gui_config_set_int(section, key, value)
        +e9gui_config_set_bool(section, key, value)
    }

    class E9GuiFrameworkAPI {
        +e9gui_get_platform()
        +e9gui_detect_backend()
        +e9gui_platform_name(platform)
        +e9gui_backend_name(backend)
        +e9gui_version()
        +e9gui_get_error()
        +e9gui_clear_error()
        +e9gui_should_use_tui(argc, argv)
        +e9gui_poll_event(win, event)
        +e9gui_begin_frame(win)
        +e9gui_end_frame(win)
        +e9gui_main_loop(win, callback, userdata)
        +e9gui_set_color(win, color)
        +e9gui_draw_rect(win, rect, filled)
        +e9gui_draw_line(win, p1, p2)
        +e9gui_draw_text(win, x, y, text)
        +e9gui_set_font(win, name, size)
        +e9gui_get_text_size(win, text, width, height)
        +e9gui_create_menu(label)
        +e9gui_menu_add_item(menu, label, shortcut)
        +e9gui_menu_add_submenu(menu, label)
        +e9gui_menu_add_separator(menu)
        +e9gui_menuitem_set_callback(item, callback, userdata)
        +e9gui_menuitem_set_enabled(item, enabled)
        +e9gui_menuitem_set_checked(item, checked)
        +e9gui_register_plugin(plugin)
        +e9gui_load_plugin_file(path)
        +e9gui_unload_plugin(name)
        +e9gui_get_plugin(name)
        +e9gui_file_dialog(win, flags, filter, default_path)
        +e9gui_message_box(win, title, message, type)
    }

    class E9studio_gui_main_entry {
        +e9studio_gui_main(argc, argv)
    }

    %% Relationships
    E9Window --> E9WindowConfig : created_from
    E9Window "1" --> "*" E9Panel : panels
    E9Window --> E9Backend : backend

    E9GuiFrameworkAPI ..> E9Window : uses
    E9GuiFrameworkAPI ..> E9Panel : uses
    E9GuiFrameworkAPI ..> E9Config : uses
    E9GuiFrameworkAPI ..> E9PluginInfo : manages

    E9studio_gui_main_entry ..> E9GuiFrameworkAPI : calls
    E9studio_gui_main_entry ..> E9platform_API : selects_mode

    class E9platform_API {
        +e9platform_init(E9AppState*)
        +e9platform_run(E9AppState*)
        +e9platform_shutdown(E9AppState*)
        +e9platform_open_file_dialog(path, max, filter)
        +e9platform_save_file_dialog(path, max, filter)
        +e9platform_folder_dialog(path, max, title)
        +e9platform_message_box(title, msg, type)
        +e9platform_clipboard_set(text)
        +e9platform_clipboard_get()
        +e9platform_open_url(url)
        +e9platform_run_external(cmd)
    }

    E9platform_API ..> E9AppState : operates_on
    E9platform_API ..> E9EditorState : via_app
Loading

File-Level Changes

Change Details Files
Implement core editor buffer, editor state, application state, build/menu systems, and analysis integration hooks.
  • Add gap-buffer implementation for text storage including insert/delete and serialization helpers.
  • Define E9EditorState and E9AppState structures with creation/destruction, file load/save, and multi-editor/tab management.
  • Wire in optional binary analysis integration guarded by E9STUDIO_WITH_ANALYSIS, including helpers to load binaries and show disasm/decompile/hex/symbols/functions.
  • Provide build configuration loading and command execution helpers wrapping system().
  • Provide INI-based menu loading, menu freeing, and command variable substitution ({e},{n},{b},{p}).
  • Add various file and string utility helpers for reading/writing entire files.
src/e9studio/gui/e9studio_app.c
src/e9studio/gui/e9studio_tedit.h
Introduce a portable GUI abstraction layer with backend detection, panels, events, plugins, dialogs, and configuration stubs.
  • Define platform and backend enums and runtime detection logic, including SSH and DISPLAY-based TUI fallback heuristics.
  • Implement E9Window and E9Panel abstractions with panel creation, docking, text storage, and window lifecycle management.
  • Provide a minimal event loop and frame callbacks with backend-specific stubs for Win32/X11/Cocoa and a TUI backend marker.
  • Add immediate-mode drawing API stubs (rect/line/text/font) and text measurement placeholder.
  • Implement a simple plugin registry with API version checking and lifecycle hooks, as well as stub dynamic loader and lookup routines.
  • Add stub dialog and configuration APIs (file dialog, message box, INI-like config accessors).
  • Expose GUI API surface in a new public header for use by the rest of the application and plugins.
src/e9studio/gui/e9studio_gui.c
src/e9studio/gui/e9studio_gui.h
Add a CLI platform backend that drives the E9AppState via a command-oriented REPL for file, analysis, editor, and build operations.
  • Implement a global CLI loop with status line, prompt, and command parsing (help/version/file/analysis/editor/build/menu/quit).
  • Provide concrete command handlers for binary analysis operations when E9STUDIO_WITH_ANALYSIS is enabled, with stubbed fallbacks otherwise.
  • Integrate build commands using the app’s build config and menu variable substitution, and shell out via system().
  • Implement platform interface functions (init/run/shutdown, dialogs, message boxes, clipboard/url/external-run stubs) used by e9studio_tedit.
  • Add a string trim helper used by INI/menu parsing and CLI input handling.
src/e9studio/gui/platform/e9gui_cli.c
Create unified GUI/TUI entrypoint that selects start mode (GUI, TUI, or CLI), parses CLI options, and provides a self-test harness.
  • Add argument parser supporting mode selection flags, config/menu/script paths, binary argument, and a self-test option.
  • Implement platform-aware usage and version printers including backend/platform info and environment variable documentation.
  • Provide a self-test routine covering platform/backend detection, editor creation, buffer operations, language detection, and app init/shutdown.
  • Implement e9studio_gui_main() that chooses between TUI (e9studio_tui_main), GUI window creation, or CLI mode based on options and environment.
  • Optionally expose main() when built as standalone via E9STUDIO_GUI_STANDALONE.
src/e9studio/gui/e9studio_gui_main.c
Document the GUI design and add placeholder config/menu and wasm build files for future expansion.
  • Add TEDITOR_DESIGN.md describing high-level GUI architecture, panel types, plugin interface, platform abstraction, and roadmap.
  • Introduce placeholder menuini.txt under gui/config and a wasm Makefile stub to support future WASM builds and menu configuration.
src/e9studio/gui/TEDITOR_DESIGN.md
src/e9studio/gui/config/menuini.txt
src/e9studio/wasm/Makefile.wasm

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 5 issues, and left some high level feedback:

  • Several editor operations ignore allocation failures from the gap buffer helpers: for example, e9editor_set_text, e9editor_insert, and e9editor_load_file call buffer_insert() without checking its -1 error return, which can leave the editor in a partially updated or inconsistent state; consider propagating errors and failing the operation cleanly when allocation fails.
  • In e9menu_substitute_vars, the {p} (project directory) expansion computes len as 1 when no path separator is found, which will copy the first character of the file path instead of using the current directory; you likely intended to fall back to . when there is no directory component, so the no-separator case should set len to 0 and hit the . branch.
  • Also in e9menu_substitute_vars, when encountering an unknown {...} sequence, the code writes a literal '{' to out but does not advance p, which will cause an infinite loop on that character; you should increment p in this branch (and possibly copy the rest of the sequence literally) to avoid getting stuck.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several editor operations ignore allocation failures from the gap buffer helpers: for example, `e9editor_set_text`, `e9editor_insert`, and `e9editor_load_file` call `buffer_insert()` without checking its `-1` error return, which can leave the editor in a partially updated or inconsistent state; consider propagating errors and failing the operation cleanly when allocation fails.
- In `e9menu_substitute_vars`, the `{p}` (project directory) expansion computes `len` as `1` when no path separator is found, which will copy the first character of the file path instead of using the current directory; you likely intended to fall back to `.` when there is no directory component, so the no-separator case should set `len` to `0` and hit the `.` branch.
- Also in `e9menu_substitute_vars`, when encountering an unknown `{...}` sequence, the code writes a literal `'{'` to `out` but does not advance `p`, which will cause an infinite loop on that character; you should increment `p` in this branch (and possibly copy the rest of the sequence literally) to avoid getting stuck.

## Individual Comments

### Comment 1
<location> `src/e9studio/gui/e9studio_app.c:214-215` </location>
<code_context>
+    ed->buffer->gap_end = ed->buffer->capacity;
+    ed->buffer->size = 0;
+
+    /* Insert new text */
+    buffer_insert(ed->buffer, 0, text, len);
+    ed->dirty = 0;
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Handle allocation failure from buffer_insert in e9editor_set_text.

buffer_insert() returns -1 on allocation failure, but e9editor_set_text() ignores this and still marks the editor as clean. This can leave the buffer empty, the editor not dirty, and OOM errors silent. Please check the return value, propagate an error, and keep the previous buffer contents on failure instead of always returning 0.
</issue_to_address>

### Comment 2
<location> `src/e9studio/gui/e9studio_app.c:279` </location>
<code_context>
+{
+    if (!ed || !ed->buffer || !text || len == 0) return;
+
+    buffer_insert(ed->buffer, pos, text, len);
+    ed->dirty = 1;
+
</code_context>

<issue_to_address>
**issue:** e9editor_insert should propagate buffer_insert allocation failures.

Here, buffer_insert()’s return value is ignored, so an allocation failure would silently drop the edit while still marking the buffer dirty and potentially affecting history. Please check the return code and either avoid updating editor state on failure or propagate an error so the caller can handle it.
</issue_to_address>

### Comment 3
<location> `src/e9studio/gui/e9studio_app.c:813-818` </location>
<code_context>
+                    }
+                }
+                p += 2;
+            } else if (*p == 'p' && p[1] == '}') {
+                /* {p} = project directory (same as file dir) */
+                if (file_path) {
+                    const char *last = strrchr(file_path, '/');
+                    if (!last) last = strrchr(file_path, '\\');
+                    size_t len = last ? (size_t)(last - file_path) : 1;
+                    if (out_pos + len < out_size - 1) {
+                        if (len > 0) {
</code_context>

<issue_to_address>
**issue:** Project directory substitution {p} does not behave correctly for paths without a separator.

For paths without '/' or '\\', `last` stays NULL and `len` becomes 1, so only the first character of `file_path` is copied (e.g., `"file.c"``"f"`). The `else` branch that writes `'.'` is never used because `len` is never 0. Please adjust this logic so separator-less paths produce a sensible project directory (e.g., `"./"` or the full path) instead of a single truncated character.
</issue_to_address>

### Comment 4
<location> `src/e9studio/gui/platform/e9gui_cli.c:205-206` </location>
<code_context>
+        return;
+    }
+
+    /* Try as hex address first */
+    uint64_t addr = strtoull(arg, NULL, 16);
+    if (addr != 0) {
+        /* TODO: Disassemble at address */
</code_context>

<issue_to_address>
**suggestion (bug_risk):** cmd_disasm cannot disassemble address 0x0 and conflates invalid addresses with zero.

Because `strtoull()` is called with a `NULL` end pointer, any result of 0 is treated as "not an address" and the code falls back to treating the argument as a function name. This both forbids disassembly at address 0x0 and makes invalid strings like "zz" indistinguishable from 0x0. Use `strtoull(arg, &endptr, 16)` and verify that `endptr > arg` (at least one hex digit consumed) so you can accept address 0 while rejecting invalid numeric input.
</issue_to_address>

### Comment 5
<location> `src/e9studio/gui/e9studio_app.c:889-893` </location>
<code_context>
+    return 0;
+}
+
+int e9build_run_command(const char *cmd)
+{
+    if (!cmd) return -1;
+    return system(cmd);
+}
+
</code_context>

<issue_to_address>
**🚨 suggestion (security):** Consider constraining or documenting the security implications of system() in e9build_run_command.

e9build_run_command() forwards cmd directly to system(), so any substituted paths or config/menu-derived values become part of a shell command. If those inputs are ever user- or externally-controlled, this is a command injection risk. Either clearly document that only trusted input is allowed, or sanitize/switch to a non-shell execution model (e.g., exec with an argv array).

```suggestion
/*
 * Executes a build command via the system shell.
 *
 * SECURITY NOTE:
 *   `cmd` MUST be constructed only from trusted data (no user- or externally-
 *   controlled input) because it is passed directly to system(3). Callers are
 *   responsible for ensuring that any substituted paths, configuration values,
 *   or menu-derived strings cannot be used for command injection.
 */
int e9build_run_command(const char *cmd)
{
    if (!cmd) return -1;
    return system(cmd);
}
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +214 to +215
/* Insert new text */
buffer_insert(ed->buffer, 0, text, len);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Handle allocation failure from buffer_insert in e9editor_set_text.

buffer_insert() returns -1 on allocation failure, but e9editor_set_text() ignores this and still marks the editor as clean. This can leave the buffer empty, the editor not dirty, and OOM errors silent. Please check the return value, propagate an error, and keep the previous buffer contents on failure instead of always returning 0.

{
if (!ed || !ed->buffer || !text || len == 0) return;

buffer_insert(ed->buffer, pos, text, len);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: e9editor_insert should propagate buffer_insert allocation failures.

Here, buffer_insert()’s return value is ignored, so an allocation failure would silently drop the edit while still marking the buffer dirty and potentially affecting history. Please check the return code and either avoid updating editor state on failure or propagate an error so the caller can handle it.

Comment on lines +813 to +818
} else if (*p == 'p' && p[1] == '}') {
/* {p} = project directory (same as file dir) */
if (file_path) {
const char *last = strrchr(file_path, '/');
if (!last) last = strrchr(file_path, '\\');
size_t len = last ? (size_t)(last - file_path) : 1;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Project directory substitution {p} does not behave correctly for paths without a separator.

For paths without '/' or '\', last stays NULL and len becomes 1, so only the first character of file_path is copied (e.g., "file.c""f"). The else branch that writes '.' is never used because len is never 0. Please adjust this logic so separator-less paths produce a sensible project directory (e.g., "./" or the full path) instead of a single truncated character.

Comment on lines +205 to +206
/* Try as hex address first */
uint64_t addr = strtoull(arg, NULL, 16);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): cmd_disasm cannot disassemble address 0x0 and conflates invalid addresses with zero.

Because strtoull() is called with a NULL end pointer, any result of 0 is treated as "not an address" and the code falls back to treating the argument as a function name. This both forbids disassembly at address 0x0 and makes invalid strings like "zz" indistinguishable from 0x0. Use strtoull(arg, &endptr, 16) and verify that endptr > arg (at least one hex digit consumed) so you can accept address 0 while rejecting invalid numeric input.

Comment on lines +889 to +893
int e9build_run_command(const char *cmd)
{
if (!cmd) return -1;
return system(cmd);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 suggestion (security): Consider constraining or documenting the security implications of system() in e9build_run_command.

e9build_run_command() forwards cmd directly to system(), so any substituted paths or config/menu-derived values become part of a shell command. If those inputs are ever user- or externally-controlled, this is a command injection risk. Either clearly document that only trusted input is allowed, or sanitize/switch to a non-shell execution model (e.g., exec with an argv array).

Suggested change
int e9build_run_command(const char *cmd)
{
if (!cmd) return -1;
return system(cmd);
}
/*
* Executes a build command via the system shell.
*
* SECURITY NOTE:
* `cmd` MUST be constructed only from trusted data (no user- or externally-
* controlled input) because it is passed directly to system(3). Callers are
* responsible for ensuring that any substituted paths, configuration values,
* or menu-derived strings cannot be used for command injection.
*/
int e9build_run_command(const char *cmd)
{
if (!cmd) return -1;
return system(cmd);
}

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a GUI framework for E9Studio (v0.1.0) inspired by tedit-cosmo's extensibility philosophy. The implementation adds a command-line interface with platform abstraction, supporting CLI mode as the primary interface with TUI fallback when GUI backends are unavailable.

Changes:

  • Added GUI framework with platform abstraction layer supporting Windows, Linux, macOS, and BSD
  • Implemented CLI mode with binary analysis commands (disassembly, hex dump, symbols, etc.)
  • Added WASM payload build system with Binaryen integration for extensibility
  • Integrated text editor functionality with gap buffer implementation and language detection

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Makefile.e9studio Added GUI and WASM build targets, binaryen integration, and updated help text
src/e9studio/wasm/Makefile.wasm New WASM payload build system for e9studio with Binaryen optimization support
src/e9studio/gui/e9studio_gui.h GUI framework API with platform detection, panel system, and plugin architecture
src/e9studio/gui/e9studio_gui.c GUI framework implementation with stub backends and TUI fallback
src/e9studio/gui/e9studio_tedit.h Editor integration layer between tedit-cosmo and e9studio analysis engine
src/e9studio/gui/e9studio_app.c Application core with editor management, build system, and analysis integration
src/e9studio/gui/e9studio_gui_main.c Main entry point with mode selection (TUI/GUI/CLI) and self-test functionality
src/e9studio/gui/platform/e9gui_cli.c CLI platform backend with command handling and stub platform implementations
src/e9studio/gui/config/menuini.txt INI-based menu configuration for extensibility
src/e9studio/gui/TEDITOR_DESIGN.md Architecture documentation describing design philosophy and implementation phases
releases/e9studio-gui.com Compiled binary release (ELF executable)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


uint64_t addr = 0;
size_t size = 256;

Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing input validation for the 'arg' parameter. The sscanf call attempts to parse 'args' but doesn't check if 'args' is NULL or empty before parsing. If the function is called with NULL or an invalid pointer, this will lead to undefined behavior. Add a check to validate the input parameter before using it.

Suggested change
if (!args || !args[0]) {
printf("Usage: hex <address> [size]\n");
return;
}

Copilot uses AI. Check for mistakes.
ed->buffer->size = 0;

/* Insert new text */
buffer_insert(ed->buffer, 0, text, len);
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer_insert function can fail due to allocation failure, but the return value is not checked at the call sites. This could lead to silent data loss when insertions fail. The call in e9editor_set_text at line 215 and e9editor_insert at line 279 should check the return value and handle allocation failures appropriately.

Suggested change
buffer_insert(ed->buffer, 0, text, len);
if (buffer_insert(ed->buffer, 0, text, len) != 0) {
/* Insertion failed (likely due to allocation failure) */
return -1;
}

Copilot uses AI. Check for mistakes.
{
if (!ed || !ed->buffer || !text || len == 0) return;

buffer_insert(ed->buffer, pos, text, len);
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer_insert function can fail due to allocation failure, but the return value is not checked. This could lead to silent data loss when insertions fail. Check the return value and handle allocation failures appropriately, either by propagating the error or notifying the user.

Suggested change
buffer_insert(ed->buffer, pos, text, len);
int rc = buffer_insert(ed->buffer, pos, text, len);
if (rc != 0) {
fprintf(stderr, "e9editor_insert: buffer_insert failed (code %d)\n", rc);
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines +206 to +211
uint64_t addr = strtoull(arg, NULL, 16);
if (addr != 0) {
/* TODO: Disassemble at address */
printf("Disassembly at 0x%llx:\n", (unsigned long long)addr);
e9analysis_disasm_at(g_app->binary, addr, 32);
} else {
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sscanf call does not validate the parsed address value properly. When strtoull returns 0, it could indicate either a successful parse of "0" or a parsing error. The code at lines 206-211 treats any non-zero value as a valid address and zero as an invalid address, but this logic is incorrect since address 0x0 is a valid address. Consider checking errno or the endptr parameter from strtoull to properly distinguish between parsing errors and valid zero addresses.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,279 @@
# E9Studio GUI (cosmo-teditor)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in comment: "cosmo-teditor" should be "tedit-cosmo" to match the terminology used elsewhere in the codebase (as seen in line 5 and throughout other files).

Suggested change
# E9Studio GUI (cosmo-teditor)
# E9Studio GUI (tedit-cosmo)

Copilot uses AI. Check for mistakes.
ludoplex pushed a commit that referenced this pull request Jan 23, 2026
- Handle buffer_insert allocation failures in e9editor_set_text/insert
- Change e9editor_insert signature from void to int for error propagation
- Fix {p} project directory substitution for paths without separator
- Fix cmd_disasm to properly handle address 0x0 vs parse errors
- Add NULL validation in cmd_hex before sscanf
- Validate empty command strings in e9build_run_command
- Add security note for e9build_run_command about trusted input
- Fix typo: cosmo-teditor -> tedit-cosmo in TEDITOR_DESIGN.md
mx-agent and others added 18 commits February 28, 2026 17:59
APE (Actually Portable Executable) patching:
- e9ape.c/h: Parse and patch polyglot APE binaries
- Handles MZ/PE + ELF + shell script + ZipOS layers
- Preserves polyglot validity across all formats

WASM/Binaryen integration:
- e9binaryen.c/h: Binaryen-based WASM optimization
- Integration with ludoplex-binaryen fork

Analysis enhancements:
- e9analysis.c/h: Extended analysis for APE format detection
- e9patch.h: APE-aware patching API

BDD specs:
- ape_detection.feature: APE format detection scenarios
- ape_patching.feature: Polyglot patching scenarios
- zipos_access.feature: ZipOS filesystem scenarios

Schema specs:
- e9ape.schema: APE data structures
- e9ape.sm: APE patching state machine

Ring: 0 (pure C, cosmocc compatible)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RE analysis of hello.ape (cosmocc output) revealed:
- APE has NO x86-64 ELF header embedded
- Shell script bootstrap handles Linux execution
- PE sections are the ground truth for code layout
- ARM64 ELF exists at 0x3C000 (not x86-64)
- file_offset often equals RVA in APE

Changes:
- e9ape.schema: Updated with correct APE structure from RE
- e9ape.c: Rewrote to use PE sections for patching
  - e9_ape_rva_to_offset(): Primary address translation
  - e9_ape_patch_offset(): Direct file offset patching
  - e9_ape_patch_rva(): RVA-based patching
  - e9_ape_patch(): Legacy VA compat (maps to PE)
- e9ape.h: Updated API to reflect PE-centric approach

Analysis method:
- Built hello.ape with cosmocc
- Examined with od, readelf, objdump
- Parsed PE/ZIP structures with python
- Documented findings in schema comments

Ring: 0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…patching

Add live reload integration layer that connects:
- File watcher (inotify) to detect C source changes
- cosmocc recompilation for incremental builds
- Binaryen object diffing to generate patches
- APE patching via PE-based APIs (no x86-64 ELF assumption!)
- Instruction cache flush for safe code replacement

New files:
- specs/e9livereload.schema: Protocol spec (cosmicringforge style)
- src/e9patch/e9livereload.h: Public API for live reload
- src/e9patch/e9livereload.c: Integration implementation

Updated:
- e9studio.c: Use e9livereload for file watching and hot-patching
- Makefile.e9studio: Add APE and livereload sources to build
- AGENTS.md: Document live reload workflow

This enables viewing C source code changes in real-time by updating
the running APE binary in place, leveraging cosmicringforge spec-driven
workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add spec-driven artifacts generated by cosmicringforge workflow:

- gen/domain/e9livereload_types.{h,c}: C types with init/validate
  - Generated by schemagen 2.0.0 from specs/e9livereload.schema
  - Provides E9LiveReloadConfig, E9PatchState, E9PendingPatch, etc.

- specs/features/e9livereload.feature: BDD test scenarios
  - 21 Gherkin scenarios covering full live reload workflow
  - File watching, compilation, diffing, patching, icache flush
  - Self-patching, statistics, error handling

This follows the cosmicringforge workflow:
  Edit spec → make regen → make verify → commit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove reference to shell_start (not in public E9_APEInfo struct)
- Use E9_ZipOSEntry from header instead of internal ZipOSEntry typedef
- Fix function signatures to match header declarations

These errors were correctly caught by CI - tests working as designed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Required for va_list, va_start, va_end used in set_error().

CI correctly caught this linker error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Test files for demonstrating the live reload workflow:
- target.c: Simple program to patch
- test_livereload.c: Full live reload driver with WAMR
- test_simple.c: Minimal test without WAMR dependency
- Makefile: Build both native and APE versions

Workflow: File Watch -> cosmocc Recompile -> Binaryen Diff -> APE Patch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses cosmicringforge generated types from livereload.schema.
Implements full hot-patching workflow:
- File watch via inotify
- Recompilation via cosmocc
- Function byte extraction via objdump
- Memory patching via ptrace
- ICache flush for x86-64 and aarch64

Usage: sudo ./livereload <PID> [source_file]

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Platform backends:
- Linux (native): inotify for efficient event-driven watching
- macOS/BSD (native): kqueue for event-driven watching
- APE/Windows/other: stat-based polling (universal fallback)

For APE builds:
- Uses _COSMO_SOURCE for ptrace() and IsLinux()/IsBsd() runtime detection
- Polling fallback for file watching (most portable)
- Works on all platforms APE supports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove inotify/kqueue backends. stat() polling works everywhere and
100ms latency is imperceptible for a dev tool where recompilation
takes way longer anyway.

-216 lines of platform-specific code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace ptrace with portable backends:
- Linux: process_vm_readv/writev (no stop required!)
- Windows: ReadProcessMemory/WriteProcessMemory
- Self-patching: mprotect + direct memory access

Benefits:
- No root needed for same-user processes on Linux
- Target process doesn't stop during patching
- Works on all platforms APE supports

Generated types from: specs/domain/procmem.schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- e9procmem.h now uses X-macro pattern for constants:
  - MEMACCESS_XMACRO for read/write/execute flags
  - PROCMEM_OS_XMACRO for OS detection
  - PROCMEM_ARCH_XMACRO for architecture
  - PROCMEM_STATUS_XMACRO for status codes
  - Added procmem_*_str() functions via X-macro expansion

- livereload.c fixes:
  - Mark get_function_info as __attribute__((unused)) (WAMR pending)
  - Increase buffer sizes to fix truncation warnings

Ring 0 composability: specs → X-macros → constants + strings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- docs/ARCHITECTURE.md: Component architecture and data flow diagrams
- docs/IR_PATCHING.md: IR-based patching strategies for lower latency
  - TinyCC integration (Ring 0, ~30-50ms vs current ~200-500ms)
  - Binaryen IR diffing approach
  - Incremental AST compilation using Lemon/lexgen
- specs/behavior/livereload.sm: Live reload session state machine
- specs/behavior/patch.sm: Individual patch lifecycle state machine
- AGENTS.md: Updated with architecture docs and state machine refs

These documents serve as LLM reference for AI assistants working
on the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete spec-driven IR patching using CosmicRingForge generators:

SPECS (Ring 0 SSOT):
- specs/domain/c11_ast.schema: AST node types (40+ node kinds)
  - FunctionDef, TypeSpec, Statements, Expressions
  - ASTDiff, FuncChange for diff results
  - C version abstraction (C89-C23, base: C11/Cosmopolitan)

- specs/parsing/c11_tokens.def: Token X-macros
  - C11_KEYWORDS, C11_OPERATORS, C11_PUNCTUATION
  - C11_TOKEN_KINDS for categorization
  - Expandable via defgen to enum + string tables

- specs/parsing/c11.lex: Lexer specification
  - Full C11 lexer rules for lexgen
  - Multi-state: INITIAL, IN_COMMENT, IN_STRING, IN_CHAR
  - Escape sequence handling

- specs/parsing/c11.grammar: Lemon LALR(1) grammar
  - Function-focused subset of C11
  - AST construction actions
  - Content hashing for diff

- specs/behavior/ast_diff.sm: Diff state machine
  - INIT -> PARSE_OLD -> PARSE_NEW -> HASH_FUNCS -> COMPARE -> DONE
  - Detects ADDED, MODIFIED, REMOVED functions

- specs/behavior/ir_compile.sm: Selective compile state machine
  - Only compiles changed functions
  - Generates stubs for unchanged
  - Optional TinyCC fast path

DOCS:
- docs/IR_PATCHING.md: Full Ring 0/1/2 composability documentation
  - 4-8x latency reduction (~30-80ms vs ~200-500ms)
  - C version abstraction strategy
  - Data flow diagrams
  - Build integration

All specs use CosmicRingForge generators (schemagen, defgen,
lexgen, lemon, smgen) - fully Ring 0 dogfooded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add MANDATORY upstream reading section to AGENTS.md
- Add tool compatibility table (TinyCC banned, Binaryen OK via ludoplex)
- Update IR_PATCHING.md with ludoplex/binaryen as Ring 1
- Remove TinyCC from latency comparison (incompatible with Cosmopolitan)
- Update file map to reflect actual directory structure

Contains errors: narrowed focus to Ring 0, needs Ring 1/2 coverage fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TinyCC produces "Invalid relocation entry" errors when linking with
cosmopolitan.a. This is a fundamental incompatibility.

Changes:
- ir_compile.sm: Remove USE_TCC option, replace with ccache guard
- ape-anatomy-analysis.md: Replace TinyCC with binaryen.wasm, add warning
- ARCHITECTURE.md: Update options list with Ring 0 AST as recommended
- build-e9studio.yml: Replace tcc.wasm with binaryen.wasm

Use Ring 0 AST-based parsing (Lemon + lexgen) or cosmocc for compilation.
Use ludoplex/binaryen for WASM IR diffing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parent repo renamed from ludoplex/cosmicringforge to ludoplex/cosmo-bde

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants