Private
Public Access
0
0
Commit Graph

566 Commits

Author SHA1 Message Date
Conductor d15fdcdb05 fix(markdown): revert table to simple form with text_wrapped + add regression tests 2026-06-03 17:31:50 -04:00
ed afa2f31e11 fix(markdown): add missing table_setup_column calls in render_table
ROOT CAUSE: src/markdown_table.py:render_table was missing
imgui.table_setup_column() calls. In ImGui, columns MUST be
configured via table_setup_column before table_headers_row is called.
Without it, the table has no defined columns, causing cells to
render at overlapping Y positions. This manifested as text overlap
in the Discussion Hub's read_mode entries (e.g., 'swc2 -> gte_sw'
overlapping the line above it).

FIX: Call imgui.table_setup_column(h, TableColumnFlags_.width_stretch)
for each header BEFORE table_headers_row(). Each column now has a
defined width (stretch = fills available space) and cells render
correctly without overlap.

Tests:
- New test_markdown_table_columns.py asserts setup_column is called
  once per column and table_next_column is called for each cell.
- 16/16 broad regression pass (test_markdown_table,
  test_markdown_table_render, test_markdown_render_robust,
  test_gen_send_empty_context, test_gui_fast_render)
2026-06-03 15:27:29 -04:00
ed 801321c125 fix(gui): remove ListClipper from render_prior_session_view (variable-height items)
ROOT CAUSE: The ListClipper in render_prior_session_view was being
tripped up by the variable heights of discussion entries (huge system
prompts vs small tool results). When the first entry was very tall
(system prompt), the clipper would compute the visible range assuming
uniform item heights, leading to underflow/overflow on subsequent
items. The user saw only the first ~8 entries with massive empty
space below ('early clipping').

FIX: Replace the ListClipper with a direct for loop over
app.prior_disc_entries. With 233 entries, performance is acceptable
and each entry renders correctly. The user can still scroll the
parent imscope.child window if content overflows.

Tests:
- Updated test_prior_session_no_clipping.py to set entries on
  app_instance.controller.prior_disc_entries (the App's __getattr__
  proxies attribute reads to the controller, so the set must go to
  the controller directly).
- 28/28 broad regression pass
2026-06-03 15:18:18 -04:00
ed 96b9b00c97 fix(gui): use imscope.child for comms_scroll (was inside conditional, leaving child open)
ROOT CAUSE: render_comms_history_panel had imgui.end_child() nested INSIDE
an 'if app._scroll_comms_to_bottom:' block at line 3758. When
_scroll_comms_to_bottom was False (the common case), end_child was
NOT called, leaving the comms_scroll child window open. This caused
the imGui state to corrupt: tab_item.end_tab_item, tab_bar.end_tab_bar,
and the outer window.end all saw that the child was still open
(WithinEndChildID was set), triggering 'Must call EndChild() and not
End()!' assertion.

FIX: Convert the entire comms_scroll block to imscope.child (which uses
Python's with statement for exception-safe end_child). The scroll-to-bottom
logic is now correctly nested INSIDE the with block, and there's no
manual end_child to forget.

Tests:
- Updated test_comms_scroll_no_clipping.py to check imscope.child
  instead of begin_child
- 28/28 broad regression pass
2026-06-03 14:53:05 -04:00
ed 070c159f11 fix(gui): use imscope.child in render_heavy_text for exception safety
ROOT CAUSE: render_heavy_text (called per comms panel entry) had
manual begin_child/end_child pairs. If anything inside the child
(especially markdown_helper.render) raised, end_child was skipped.
The child window was left open, corrupting the imGui state. The
corruption cascaded through tab_item.end_tab_item -> tab_bar.end_tab_bar
-> window.end, triggering 'Must call EndChild() and not End()!' assertion.

FIX: Convert the inner begin_child/end_child pair to imscope.child so
the end_child is automatically called by Python's with statement, even
on exception. Also convert prior_scroll to imscope.child for consistency.

TESTS:
- Existing test_comms_no_extraneous_pop.py: push/pop balance check
- Updated test_prior_session_no_clipping.py to match new imscope.child
  signature
- 28/28 broad regression pass
2026-06-03 14:38:26 -04:00
ed 228359679d fix(gui): remove orphan pop_style_color in render_comms_history_panel
ROOT CAUSE: In a previous fix (df7bda6e 'explicit child size for
comms_scroll and prior_scroll'), the code that pushed a child_bg style
color at the start of render_comms_history_panel was removed when the
section was rewritten to use imgui.get_content_region_avail() for
explicit child sizing. However, the matching pop_style_color at the end
of the function (guarded by 'if app.is_viewing_prior_session') was left
in place.

RESULT: When viewing a prior session, the imscope.style_color in
_gui_func pushes 1 color at the start of the frame, then the orphaned
pop in render_comms_history_panel decrements the imGui style counter
by 1, then _gui_func's imscope __exit__ tries to pop again — triggering
IM_ASSERT 'PopStyleColor() too many times!'.

This caused a cascade of imGui state corruption on every frame after
loading a prior session log, manifesting as 'too many times' assertions
on the next frame and 'Must call EndChild() and not End()' once the
style stack underflowed.

FIX: Remove the orphan pop_style_color at gui_2.py:3761. No matching
push exists, so the pop is unconditionally wrong.

TESTS:
- New test_comms_no_extraneous_pop.py asserts push/pop balance in
  render_comms_history_panel when is_viewing_prior_session is True
- 43/43 broad regression pass
2026-06-03 14:25:59 -04:00
ed 2e5e985d6d fix(gui): use imscope context manager for prior session tint in _gui_func
Convert manual push_style_color / pop_style_color in _gui_func to use the
imscope context manager so the pop is exception-safe via Python's with
statement. Manual push/pop can desync if render_main_interface raises
mid-render, causing 'PopStyleColor() too many times!' imGui assertion
on subsequent frames.

The try/except around render_main_interface was already there but the
pop was outside it, so the pop count could exceed the push count when
an exception short-circuited the render.
2026-06-03 14:08:01 -04:00
ed df7bda6e0d fix(gui): explicit child size for comms_scroll and prior_scroll prevents early clipping
ROOT CAUSE: When child windows used ImVec2(0, 0) for auto-fill, the
child's reported height was unstable inside tab items (especially when
the parent tab was inside a tab_bar inside a window). Result: the
scrollable child rendered with a fixed smaller height, showing only the
first half of the content, with empty space below.

FIX: Use imgui.get_content_region_avail() to compute explicit dimensions
and pass them to begin_child. Now the child fills the full available area
inside the tab content.

- render_comms_history_panel: avail.x, avail.y
- render_prior_session_view: same, plus added entry count indicator next
  to the Exit Prior Session button ({N} entries) for at-a-glance info

Tests:
- test_comms_scroll_no_clipping.py: verifies comms_scroll child uses
  explicit (non-zero) size
- test_prior_session_no_clipping.py: same for prior_scroll child
- test_log_management_first_open.py: minor cleanup
- 42/42 broad regression pass
2026-06-03 13:47:08 -04:00
ed 91fe07f72a fix(markdown): rewrite render() to walk lines (no text replacement)
ROOT CAUSE: src/markdown_helper.py:render() used a 'mask text with placeholders
then re.split' approach that failed when AI responses contained CRLF or when
the same table content appeared twice. The replace() either didn't match
(CRLF mismatch) or only replaced the first occurrence, leaving the second
table as raw markdown for imgui_md to render badly. Result: the same table
appeared twice (bad rendering via imgui_md, good rendering via my new code).

FIX: rewrite render() to walk lines directly. Per-line, decide whether to
buffer for imgui_md, skip into a table renderer, or accumulate into a
code-block renderer. No text replacement needed.

- src/markdown_helper.py: new render() walks lines, handles code fences
  and table intervals inline via lookup dicts.
- src/gui_2.py: render_log_management now calls load_registry() on the
  newly-created LogRegistry when _log_registry was None. Previously the
  initial construction populated an empty table, AND the 'Refresh Registry'
  button was inside the else branch, so users had no way to load data.
  User re-indented the surrounding block during debugging.

Tests:
- test_markdown_render_robust.py: 2 tests (CRLF text, duplicate content)
- test_log_management_first_open.py: 1 test (registry populated on open)
40/40 broad regression pass.
2026-06-03 13:14:49 -04:00
ed 9396154779 fix(gui): Gen+Send and MD Only with empty context no-op silently
ROOT CAUSE: 3 mismatched names in the empty-context warning path:

1. _handle_generate_send set self.show_empty_context_warning_modal = True
   but render_empty_context_modal checks self.show_empty_context_modal.
   The modal never opened.

2. _handle_generate_send / _handle_md_only never set
   self._pending_generation_action, so the modal's 'Proceed Anyway'
   button always saw None and dispatched nothing.

3. After Proceed Anyway, _pending_generation_action was never reset,
   so subsequent empty-context calls would dispatch the wrong action.

FIX:
- gui_2.py:494,501: show_empty_context_warning_modal -> show_empty_context_modal
- gui_2.py:494,501: set _pending_generation_action before showing modal
- gui_2.py:5385: reset _pending_generation_action = None after dispatch

Tests: tests/test_gen_send_empty_context.py (5 cases) covers all 4 dispatch
paths (generate/md_only x proceed/skip) plus the happy path with context.

37/37 regression pass. No new ImGui scope errors (2 pre-existing unrelated).
2026-06-03 12:41:13 -04:00
ed 55eb923bd9 feat(files-media): group files by directory + add 'Add Directory' button
- render_files_and_media now wraps the per-file loop in directory groups
  via aggregate.group_files_by_dir + imscope.tree_node_ex (mirrors the
  Context Composition visual style at gui_2.py:3114)
- New 'Add Directory' button next to 'Add Files to Inventory':
  uses filedialog.askdirectory() + os.walk to bulk-import a folder tree
- Button IDs (i, add_f_{i}, rem_f_{i}) preserve global uniqueness via
  file_indices map (regression-safe across the directory wrap)
- Test uses mock button=False, mock filedialog.askopenfilenames/askdirectory
  to avoid opening a real Tk dialog during test run
2026-06-03 12:24:51 -04:00
ed 375e30e427 feat(vendor-state): add pure aggregator with stable metric keys 2026-06-03 11:31:29 -04:00
ed 8fac9c34c9 fix(log): Refresh Registry button now calls load_registry() on the live instance
ROOT CAUSE: gui_2.py:1675 re-instantiated LogRegistry() which opens the TOML
but never called .load_registry() so the table stayed empty.

FIX: in-place load_registry() on the existing instance — preserves in-memory
state (any pending update_session_metadata call) and matches the user's intent
of 'refresh from disk'.
2026-06-03 11:28:36 -04:00
ed d0b06575c7 fix(gui): widen Keep Pairs input (80->140) and switch to drag_int
- src/gui_2.py:3829 set_next_item_width 80 -> 140, input_int -> drag_int
- Tests adapted to mock drag_int alongside input_int (5 test files)
2026-06-03 11:27:04 -04:00
ed f72e72c92c feat(markdown): implement table rendering with imgui.begin_table 2026-06-03 11:08:58 -04:00
ed 44f631c9a5 test(markdown): add GFM table parser failing tests 2026-06-03 10:59:57 -04:00
ed df96c6a4ed test(docker): add Docker Desktop auto-start and detection 2026-06-03 08:33:10 -04:00
ed 7708b76286 test(docker): add opt-in build and container-run tests 2026-06-03 08:25:37 -04:00
ed b306f8f609 test(clean-install): use correct endpoint /api/gui/mma_status (not /api/mma_status) 2026-06-03 00:52:08 -04:00
ed d171c18717 test(clean-install): add opt-in clone-and-verify pytest test 2026-06-03 00:30:00 -04:00
ed a280706ce4 feat(palette): comprehensive command library (32 commands, up from 11)
Added commands focused on ergonomics and mouse-free operation:

View (window toggles, 12 new): toggle_text_viewer, toggle_diagnostics, toggle_usage_analytics, toggle_context_preview, toggle_tier1_strategy, toggle_tier2_tech_lead, toggle_tier3_workers, toggle_tier4_qa, toggle_external_tools, toggle_shader_editor, toggle_undo_redo_history, toggle_command_palette

Layout (3 new): show_all_panels, hide_all_panels, save_workspace_profile, show_workspace_manager

Theme (1 new): cycle_theme (Dark -> Light -> NERV cycle)

Tools (2 new): undo, redo

Project (1 new): save_all (flush to project + config + global config)

Help (1 new): show_command_palette_help (opens docs/Readme.md in Text Viewer)

Refactored: extracted _toggle_window and _toggle_attr helpers to reduce duplication and make commands safer (no-op if state is missing).

Reset session now also clears comms and tool logs (matches the menu item behavior).

Added 7 new unit tests for the expanded command library.
2026-06-02 22:54:52 -04:00
ed d7449ae417 feat(palette): add Up/Down arrow navigation and Enter key selection
- Process arrow keys BEFORE input_text so the input field does not consume them
- Up/Down arrow keys navigate the result list (clamped to bounds)
- Enter and KeypadEnter execute the currently selected command
- Refactored _close_palette and _execute helpers (action call is now wrapped in try/except via _execute)
- Added 3 new tests: close helper resets state, execute runs and catches exceptions, top_n is meaningful for navigation
2026-06-02 22:41:59 -04:00
ed 436f4cfdfc test(palette): add live_gui integration tests via toggle custom_callback 2026-06-02 22:03:33 -04:00
ed 57d0329951 feat(palette): define 11 core commands in commands.py 2026-06-02 21:44:31 -04:00
ed 63b67be5b1 feat(palette): add fuzzy_match with subsequence matching and scoring 2026-06-02 21:42:01 -04:00
ed 7646fc14a2 test(arch-boundary): migrate whitelist test to tmp_path; fix indentation 2026-06-02 21:34:56 -04:00
ed 8f6f47d46b fix(gui): Final monolithic stabilization pass
- Restore monolithic architecture in gui_2.py to fix test breakages and circular imports.
- Update Text Viewer stable ID to '###Text_Viewer_Unified' to definitively fix docking conflicts.
- Refactor discussion entry renderer to force full-width horizontal expansion for Markdown.
- Fully restore theme_2.py definitions (palettes, fonts, scale) while retaining role-tint logic.
- Robustify ImGui ID stack in imgui_scopes.py to prevent access violations.
- Verify all fixes with the comprehensive unit and visual test suite.
2026-06-02 17:30:46 -04:00
ed ad98475a2e fix(gui): Definitive monolithic restoration and UI stabilization
- Restore all rendering logic to gui_2.py to maintain monolithic architecture and test compatibility.
- Fix horizontal squashing of Markdown tables by ensuring full panel width in entry groups.
- Resolve Text Viewer docking conflicts by standardizing on a stable window ID ('###Text_Viewer_Unified').
- Fix theme initialization by restoring missing load/save functions in theme_2.py.
- Prevent ImGui access violations by ensuring ID stack always receives strings in imgui_scopes.py.
- Successfully verified all UI regressions with a passing unit test suite.
2026-06-02 16:17:32 -04:00
ed df6aa1f455 fix(gui): Resolve Text Viewer docking conflict with unified ID
- Update Text Viewer window ID to '###Text_Viewer_Unified'.
- Ensures ImGui treats the window as a single stable entity across title changes.
- Prevents docking loop glitches.
2026-06-02 15:45:07 -04:00
ed 4d8e949720 fix(gui): Force newline in discussion entries to prevent squashed layout
- Insert imgui.new_line() before rendering discussion content.
- Ensures the Markdown renderer inherits the full horizontal width of the panel.
- Definitively fixes vertical squashing of tables and long text blocks.
2026-06-02 15:42:04 -04:00
ed c4811f00c1 fix(gui): Final Phase 7 stabilization and polish
- Resolve ImportError by correctly prefixing 'src' in modular renderers.
- Fix ImGui access violation by ensuring push_id always receives string IDs.
- Restore visible role-based background tints using layered rendering (channels).
- Definitively fix horizontal Markdown table widths by forcing group expansion.
- Centralize color management in theme_2.py and ui_shared.py.
- Standardize Files & Media inventory layout and remove legacy controls.
- Update test mocks to support modular UI and theme-driven styling.
2026-06-02 13:27:38 -04:00
ed 964b5c5aa4 test: Fix assertions after GUI state unification
- Update test_gui_symbol_navigation.py and test_gui_text_viewer.py to assert against show_windows['Text Viewer'] instead of the deprecated show_text_viewer attribute.
- Increase synchronization wait time in test_visual_sim_gui_ux.py to ensure the GUI loop accurately reflects the mocked MMA status.
2026-06-02 02:20:07 -04:00
ed 34a7f00cb3 test: Add extensive coverage for discussion metrics and compression
- Add tests/test_discussion_compression.py to verify AI sub-agent compression logic across Gemini, Anthropic, DeepSeek, and Gemini CLI providers.
- Add tests/test_discussion_metrics.py to verify AppController correctly extracts and accumulates token usage (input/output/cache) and logs token history.
2026-06-02 01:42:41 -04:00
ed b3b9baf91f test: Implement comprehensive workspace isolation to protect user projects
- Add isolate_workspace autouse fixture in conftest.py.
- Monkeypatch SLOP_CONFIG and preset paths to point to a temporary test directory.
- Update test_history_management.py to use dynamic paths.get_config_path().
- Prevents tests from accidentally reading or modifying the active project.toml or config.toml.
2026-06-02 01:27:32 -04:00
ed 8f5565ed04 chore(conductor): Mark track 'fix_imgui_keys_down_20260601' as complete 2026-06-01 17:56:24 -04:00
ed e2305ff49a Antigravity is dog shit. 2026-05-20 07:51:58 -04:00
ed 22f3b9f33a Progress on context composition 2026-05-17 06:43:19 -04:00
ed e770515328 fix(ctx): Remove erroneous recursive call to render_text_viewer_window 2026-05-16 17:58:19 -04:00
ed c7f5b6801f test(ctx): Add integration test for Preview button with real FileItems 2026-05-16 17:55:23 -04:00
ed 9ea20d01e4 feat(ctx): Fix Preview button sync and Text Viewer render loop 2026-05-16 16:58:28 -04:00
ed ec13757097 minimax: absolute dog shit edits 2026-05-16 15:59:40 -04:00
ed bf5b426c24 gemini quota exhausted: fixing regressions in test suite 2026-05-16 14:45:06 -04:00
ed 49082e5036 stuff left over from context composition presets track (still regressions) 2026-05-16 14:32:38 -04:00
ed fcc8822612 docs(conductor): Synchronize docs for track 'Context Composition Presets' 2026-05-16 12:36:20 -04:00
ed c52e4612ae fix(tests): Update tests and HotReloader to accommodate gui_2 refactoring 2026-05-16 11:22:41 -04:00
ed e3d84bc4da feat(presets): Implement ContextPresetManager and integrate with AppController 2026-05-16 11:04:38 -04:00
ed 8467cdd525 feat(models): Implement ContextPreset and ContextFileEntry 2026-05-16 05:05:22 -04:00
ed eadc4d62d2 test(hot-reload): Fix integration tests for gutted OOP architecture 2026-05-16 04:37:01 -04:00
ed 1ddde58161 dumbass bot 2026-05-16 03:38:15 -04:00
ed 671654ddda feat(hot-reload): Add trigger integration for hot reload system
- Task 1.1: Added _hot_reload_error state to App.__init__
- Task 1.2: Added _trigger_hot_reload() method to App
- Task 1.3: Added Ctrl+Alt+R keyboard capture in _gui_func()
- Task 1.4: Registered src.gui_2 with HotReloader in App.__init__
- Task 1.5: Added Hot Reload button in _render_mma_global_controls
- Tests: Added test_hot_reload_integration.py with 13 passing tests
2026-05-16 03:19:53 -04:00