checkpoint: track complete

This commit is contained in:
2026-03-18 18:39:54 -04:00
parent 0474df5958
commit 8ee8862ae8
7 changed files with 194 additions and 117 deletions

View File

@@ -23,7 +23,7 @@ active = "C:/projects/gencpp/gencpp_sloppy.toml"
separate_message_panel = false separate_message_panel = false
separate_response_panel = false separate_response_panel = false
separate_tool_calls_panel = false separate_tool_calls_panel = false
bg_shader_enabled = true bg_shader_enabled = false
crt_filter_enabled = false crt_filter_enabled = false
separate_task_dag = false separate_task_dag = false
separate_usage_analytics = false separate_usage_analytics = false
@@ -51,7 +51,7 @@ separate_external_tools = false
"Discussion Hub" = true "Discussion Hub" = true
"Operations Hub" = true "Operations Hub" = true
Message = false Message = false
Response = false Response = true
"Tool Calls" = false "Tool Calls" = false
Theme = true Theme = true
"Log Management" = false "Log Management" = false

View File

@@ -44,18 +44,18 @@ Collapsed=0
DockId=0x00000001,0 DockId=0x00000001,0
[Window][Message] [Window][Message]
Pos=661,1426 Pos=711,694
Size=716,455 Size=716,455
Collapsed=0 Collapsed=0
[Window][Response] [Window][Response]
Pos=2258,1377 Pos=1946,1000
Size=1102,575 Size=1339,785
Collapsed=0 Collapsed=0
[Window][Tool Calls] [Window][Tool Calls]
Pos=520,1144 Pos=1028,1668
Size=663,232 Size=1397,340
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
@@ -74,8 +74,8 @@ Collapsed=0
DockId=0xAFC85805,2 DockId=0xAFC85805,2
[Window][Theme] [Window][Theme]
Pos=0,1423 Pos=0,1010
Size=579,737 Size=828,999
Collapsed=0 Collapsed=0
DockId=0x00000002,2 DockId=0x00000002,2
@@ -85,14 +85,14 @@ Size=900,700
Collapsed=0 Collapsed=0
[Window][Diagnostics] [Window][Diagnostics]
Pos=1649,24 Pos=2177,26
Size=580,1284 Size=1162,1777
Collapsed=0 Collapsed=0
DockId=0x00000010,2 DockId=0x00000010,0
[Window][Context Hub] [Window][Context Hub]
Pos=0,1423 Pos=0,1010
Size=579,737 Size=828,999
Collapsed=0 Collapsed=0
DockId=0x00000002,1 DockId=0x00000002,1
@@ -103,26 +103,26 @@ Collapsed=0
DockId=0x0000000D,0 DockId=0x0000000D,0
[Window][Discussion Hub] [Window][Discussion Hub]
Pos=2230,26 Pos=1768,26
Size=1610,2134 Size=1263,1983
Collapsed=0 Collapsed=0
DockId=0x00000013,0 DockId=0x00000013,0
[Window][Operations Hub] [Window][Operations Hub]
Pos=581,26 Pos=830,26
Size=1647,2134 Size=936,1983
Collapsed=0 Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
[Window][Files & Media] [Window][Files & Media]
Pos=0,1423 Pos=0,1010
Size=579,737 Size=828,999
Collapsed=0 Collapsed=0
DockId=0x00000002,0 DockId=0x00000002,0
[Window][AI Settings] [Window][AI Settings]
Pos=0,26 Pos=0,26
Size=579,1395 Size=828,982
Collapsed=0 Collapsed=0
DockId=0x00000001,0 DockId=0x00000001,0
@@ -175,8 +175,8 @@ Size=381,329
Collapsed=0 Collapsed=0
[Window][Last Script Output] [Window][Last Script Output]
Pos=927,1365 Pos=2567,1006
Size=800,562 Size=746,548
Collapsed=0 Collapsed=0
[Window][Text Viewer - Log Entry #1 (request)] [Window][Text Viewer - Log Entry #1 (request)]
@@ -190,7 +190,7 @@ Size=1005,366
Collapsed=0 Collapsed=0
[Window][Text Viewer - Entry #11] [Window][Text Viewer - Entry #11]
Pos=60,60 Pos=1010,564
Size=1529,925 Size=1529,925
Collapsed=0 Collapsed=0
@@ -225,8 +225,8 @@ Size=900,700
Collapsed=0 Collapsed=0
[Window][Text Viewer - system] [Window][Text Viewer - system]
Pos=377,705 Pos=901,1502
Size=900,340 Size=876,536
Collapsed=0 Collapsed=0
[Window][Text Viewer - Entry #15] [Window][Text Viewer - Entry #15]
@@ -240,8 +240,8 @@ Size=900,700
Collapsed=0 Collapsed=0
[Window][Text Viewer - tool_calls] [Window][Text Viewer - tool_calls]
Pos=60,60 Pos=1106,942
Size=900,700 Size=831,482
Collapsed=0 Collapsed=0
[Window][Text Viewer - Tool Script #1] [Window][Text Viewer - Tool Script #1]
@@ -285,7 +285,7 @@ Size=900,700
Collapsed=0 Collapsed=0
[Window][Text Viewer - Tool Call #1 Details] [Window][Text Viewer - Tool Call #1 Details]
Pos=165,1081 Pos=963,716
Size=727,725 Size=727,725
Collapsed=0 Collapsed=0
@@ -330,8 +330,8 @@ Size=967,499
Collapsed=0 Collapsed=0
[Window][Usage Analytics] [Window][Usage Analytics]
Pos=1739,1107 Pos=2678,26
Size=586,269 Size=1162,2134
Collapsed=0 Collapsed=0
DockId=0x0000000F,0 DockId=0x0000000F,0
@@ -366,7 +366,7 @@ Size=900,700
Collapsed=0 Collapsed=0
[Window][Text Viewer - Entry #4] [Window][Text Viewer - Entry #4]
Pos=1247,1182 Pos=1165,782
Size=900,700 Size=900,700
Collapsed=0 Collapsed=0
@@ -376,13 +376,28 @@ Size=1593,1240
Collapsed=0 Collapsed=0
[Window][Text Viewer - Entry #5] [Window][Text Viewer - Entry #5]
Pos=60,60 Pos=989,778
Size=900,700 Size=1366,1032
Collapsed=0 Collapsed=0
[Window][Shader Editor] [Window][Shader Editor]
Pos=457,710 Pos=457,710
Size=493,252 Size=573,280
Collapsed=0
[Window][Text Viewer - list_directory]
Pos=1376,796
Size=882,656
Collapsed=0
[Window][Text Viewer - Last Output]
Pos=60,60
Size=900,700
Collapsed=0
[Window][Text Viewer - Entry #2]
Pos=1518,488
Size=900,700
Collapsed=0 Collapsed=0
[Table][0xFB6E3870,4] [Table][0xFB6E3870,4]
@@ -416,11 +431,11 @@ Column 3 Width=20
Column 4 Weight=1.0000 Column 4 Weight=1.0000
[Table][0x2A6000B6,4] [Table][0x2A6000B6,4]
RefScale=16 RefScale=18
Column 0 Width=48 Column 0 Width=54
Column 1 Width=68 Column 1 Width=76
Column 2 Weight=1.0000 Column 2 Weight=1.0000
Column 3 Width=120 Column 3 Width=274
[Table][0x8BCC69C7,6] [Table][0x8BCC69C7,6]
RefScale=13 RefScale=13
@@ -432,18 +447,18 @@ Column 4 Weight=1.0000
Column 5 Width=50 Column 5 Width=50
[Table][0x3751446B,4] [Table][0x3751446B,4]
RefScale=16 RefScale=18
Column 0 Width=48 Column 0 Width=54
Column 1 Width=72 Column 1 Width=81
Column 2 Weight=1.0000 Column 2 Weight=1.0000
Column 3 Width=120 Column 3 Width=135
[Table][0x2C515046,4] [Table][0x2C515046,4]
RefScale=16 RefScale=18
Column 0 Width=48 Column 0 Width=54
Column 1 Weight=1.0000 Column 1 Weight=1.0000
Column 2 Width=118 Column 2 Width=132
Column 3 Width=48 Column 3 Width=54
[Table][0xD99F45C5,4] [Table][0xD99F45C5,4]
Column 0 Sort=0v Column 0 Sort=0v
@@ -464,9 +479,9 @@ Column 1 Width=100
Column 2 Weight=1.0000 Column 2 Weight=1.0000
[Table][0xA02D8C87,3] [Table][0xA02D8C87,3]
RefScale=16 RefScale=18
Column 0 Width=180 Column 0 Width=202
Column 1 Width=120 Column 1 Width=135
Column 2 Weight=1.0000 Column 2 Weight=1.0000
[Table][0xD0277E63,2] [Table][0xD0277E63,2]
@@ -480,13 +495,13 @@ Column 0 Width=150
Column 1 Weight=1.0000 Column 1 Weight=1.0000
[Table][0x8D8494AB,2] [Table][0x8D8494AB,2]
RefScale=16 RefScale=18
Column 0 Width=132 Column 0 Width=148
Column 1 Weight=1.0000 Column 1 Weight=1.0000
[Table][0x2C261E6E,2] [Table][0x2C261E6E,2]
RefScale=16 RefScale=18
Column 0 Width=99 Column 0 Width=111
Column 1 Weight=1.0000 Column 1 Weight=1.0000
[Table][0x9CB1E6FD,2] [Table][0x9CB1E6FD,2]
@@ -498,20 +513,20 @@ Column 1 Weight=1.0000
DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y
DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A
DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02 DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02
DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,26 Size=3840,2134 Split=X DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,26 Size=3031,1983 Split=X
DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=3358,1183 Split=X DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2175,1183 Split=X
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2 DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2
DockNode ID=0x00000007 Parent=0x0000000B SizeRef=579,858 Split=Y Selected=0x8CA2375C DockNode ID=0x00000007 Parent=0x0000000B SizeRef=828,858 Split=Y Selected=0x8CA2375C
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=824,525 CentralNode=1 Selected=0x7BD57D6A DockNode ID=0x00000001 Parent=0x00000007 SizeRef=824,1056 CentralNode=1 Selected=0x7BD57D6A
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=824,737 Selected=0x8CA2375C DockNode ID=0x00000002 Parent=0x00000007 SizeRef=824,999 Selected=0xF4139CA2
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=3259,858 Split=X Selected=0x418C7449 DockNode ID=0x0000000E Parent=0x0000000B SizeRef=2201,858 Split=X Selected=0x418C7449
DockNode ID=0x00000012 Parent=0x0000000E SizeRef=1647,402 Split=Y Selected=0x418C7449 DockNode ID=0x00000012 Parent=0x0000000E SizeRef=936,402 Split=Y Selected=0x418C7449
DockNode ID=0x00000005 Parent=0x00000012 SizeRef=876,1749 Selected=0x418C7449 DockNode ID=0x00000005 Parent=0x00000012 SizeRef=876,1749 Selected=0x418C7449
DockNode ID=0x00000006 Parent=0x00000012 SizeRef=876,362 Selected=0x1D56B311 DockNode ID=0x00000006 Parent=0x00000012 SizeRef=876,362 Selected=0x1D56B311
DockNode ID=0x00000013 Parent=0x0000000E SizeRef=1610,402 Selected=0x6F2B5B04 DockNode ID=0x00000013 Parent=0x0000000E SizeRef=1263,402 Selected=0x6F2B5B04
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6 DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6
DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=480,1183 Split=Y Selected=0x3AEC3498 DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=1162,1183 Split=Y Selected=0x3AEC3498
DockNode ID=0x00000010 Parent=0x00000004 SizeRef=1199,1689 Selected=0x2C0206CE DockNode ID=0x00000010 Parent=0x00000004 SizeRef=1199,1689 Selected=0xB4CBF21A
DockNode ID=0x00000011 Parent=0x00000004 SizeRef=1199,420 Split=X Selected=0xDEB547B6 DockNode ID=0x00000011 Parent=0x00000004 SizeRef=1199,420 Split=X Selected=0xDEB547B6
DockNode ID=0x0000000C Parent=0x00000011 SizeRef=916,380 Selected=0x655BC6E9 DockNode ID=0x0000000C Parent=0x00000011 SizeRef=916,380 Selected=0x655BC6E9
DockNode ID=0x0000000F Parent=0x00000011 SizeRef=281,380 Selected=0xDEB547B6 DockNode ID=0x0000000F Parent=0x00000011 SizeRef=281,380 Selected=0xDEB547B6

View File

@@ -3096,3 +3096,26 @@ PROMPT:
role: tool role: tool
Here are the results: {"content": "done"} Here are the results: {"content": "done"}
------------------ ------------------
--- MOCK INVOKED ---
ARGS: ['tests/mock_gemini_cli.py']
PROMPT:
PATH: Epic Initialization — please produce tracks
------------------
--- MOCK INVOKED ---
ARGS: ['tests/mock_gemini_cli.py']
PROMPT:
Please generate the implementation tickets for this track.
------------------
--- MOCK INVOKED ---
ARGS: ['tests/mock_gemini_cli.py']
PROMPT:
Please read test.txt
You are assigned to Ticket T1.
Task Description: do something
------------------
--- MOCK INVOKED ---
ARGS: ['tests/mock_gemini_cli.py']
PROMPT:
role: tool
Here are the results: {"content": "done"}
------------------

View File

@@ -9,5 +9,5 @@ active = "main"
[discussions.main] [discussions.main]
git_commit = "" git_commit = ""
last_updated = "2026-03-12T20:34:43" last_updated = "2026-03-14T09:29:30"
history = [] history = []

View File

@@ -253,7 +253,7 @@ class HookHandler(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
files = _get_app_attr(app, "files", []) files = _get_app_attr(app, "files", [])
screenshots = _get_app_attr(app, "screenshots", []) screenshots = _get_app_attr(app, "screenshots", [])
self.wfile.write(json.dumps({"files": files, "screenshots": screenshots}).encode("utf-8")) self.wfile.write(json.dumps({"files": _serialize_for_api(files), "screenshots": _serialize_for_api(screenshots)}).encode("utf-8"))
elif self.path == "/api/metrics/financial": elif self.path == "/api/metrics/financial":
self.send_response(200) self.send_response(200)
self.send_header("Content-Type", "application/json") self.send_header("Content-Type", "application/json")

View File

@@ -26,6 +26,7 @@ from src import log_pruner
from src import models from src import models
from src import app_controller from src import app_controller
from src import mcp_client from src import mcp_client
from src import aggregate
from src import markdown_helper from src import markdown_helper
from src import bg_shader from src import bg_shader
from src import thinking_parser from src import thinking_parser
@@ -236,6 +237,7 @@ class App:
self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8}
self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8}
self.ui_new_context_preset_name = "" self.ui_new_context_preset_name = ""
self._focus_md_cache: dict[str, str] = {}
"""UI-level wrapper for approving a pending tool execution ask.""" """UI-level wrapper for approving a pending tool execution ask."""
self._handle_approve_ask() self._handle_approve_ask()
@@ -773,21 +775,6 @@ class App:
if self.show_windows.get("Operations Hub", False): if self.show_windows.get("Operations Hub", False):
exp, opened = imgui.begin("Operations Hub", self.show_windows["Operations Hub"]) exp, opened = imgui.begin("Operations Hub", self.show_windows["Operations Hub"])
self.show_windows["Operations Hub"] = bool(opened) self.show_windows["Operations Hub"] = bool(opened)
if exp:
imgui.text("Focus Agent:")
imgui.same_line()
focus_label = self.ui_focus_agent or "All"
if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview):
if imgui.selectable("All", self.ui_focus_agent is None)[0]:
self.ui_focus_agent = None
for tier in ["Tier 2", "Tier 3", "Tier 4"]:
if imgui.selectable(tier, self.ui_focus_agent == tier)[0]:
self.ui_focus_agent = tier
imgui.end_combo()
imgui.same_line()
if self.ui_focus_agent:
if imgui.button("x##clear_focus"):
self.ui_focus_agent = None
if exp: if exp:
imgui.push_style_var(imgui.StyleVar_.item_spacing, imgui.ImVec2(10, 4)) imgui.push_style_var(imgui.StyleVar_.item_spacing, imgui.ImVec2(10, 4))
ch1, self.ui_separate_tool_calls_panel = imgui.checkbox("Pop Out Tool Calls", self.ui_separate_tool_calls_panel) ch1, self.ui_separate_tool_calls_panel = imgui.checkbox("Pop Out Tool Calls", self.ui_separate_tool_calls_panel)
@@ -2105,10 +2092,31 @@ class App:
if exp: if exp:
if imgui.begin_tab_bar('session_hub_tabs'): if imgui.begin_tab_bar('session_hub_tabs'):
if imgui.begin_tab_item('Aggregate MD')[0]: if imgui.begin_tab_item('Aggregate MD')[0]:
display_md = self.last_aggregate_markdown
if self.ui_focus_agent:
tier_usage = self.mma_tier_usage.get(self.ui_focus_agent)
if tier_usage:
persona_name = tier_usage.get("persona")
if persona_name:
persona = self.controller.personas.get(persona_name)
if persona and persona.context_preset:
cp_name = persona.context_preset
if cp_name in self._focus_md_cache:
display_md = self._focus_md_cache[cp_name]
else:
# Generate focused aggregate
flat = src.project_manager.flat_config(self.controller.project, self.active_discussion)
cp = self.controller.project.get('context_presets', {}).get(cp_name)
if cp:
flat["files"]["paths"] = cp.get("files", [])
flat["screenshots"]["paths"] = cp.get("screenshots", [])
full_md, _, _ = src.aggregate.run(flat)
self._focus_md_cache[cp_name] = full_md
display_md = full_md
if imgui.button("Copy"): if imgui.button("Copy"):
imgui.set_clipboard_text(self.last_aggregate_markdown) imgui.set_clipboard_text(display_md)
imgui.begin_child("last_agg_md", imgui.ImVec2(0, 0), True) imgui.begin_child("last_agg_md", imgui.ImVec2(0, 0), True)
markdown_helper.render(self.last_aggregate_markdown, context_id="session_hub_agg") markdown_helper.render(display_md, context_id="session_hub_agg")
imgui.end_child() imgui.end_child()
imgui.end_tab_item() imgui.end_tab_item()
if imgui.begin_tab_item('System Prompt')[0]: if imgui.begin_tab_item('System Prompt')[0]:
@@ -2404,12 +2412,24 @@ def hello():
self.ui_disc_new_role_input = "" self.ui_disc_new_role_input = ""
imgui.separator() imgui.separator()
imgui.begin_child("disc_scroll", imgui.ImVec2(0, 0), False) imgui.begin_child("disc_scroll", imgui.ImVec2(0, 0), False)
# Filter entries based on focused agent persona
display_entries = self.disc_entries
if self.ui_focus_agent:
tier_usage = self.mma_tier_usage.get(self.ui_focus_agent)
if tier_usage:
persona_name = tier_usage.get("persona")
if persona_name:
# Show User messages and the focused agent's responses
display_entries = [e for e in self.disc_entries if e.get("role") == persona_name or e.get("role") == "User"]
clipper = imgui.ListClipper() clipper = imgui.ListClipper()
clipper.begin(len(self.disc_entries)) clipper.begin(len(display_entries))
while clipper.step(): while clipper.step():
for i in range(clipper.display_start, clipper.display_end): for i in range(clipper.display_start, clipper.display_end):
entry = self.disc_entries[i] entry = display_entries[i]
imgui.push_id(str(i)) # Use the index in the original list for ID if possible, but here i is index in display_entries
imgui.push_id(f"disc_{i}")
collapsed = entry.get("collapsed", False) collapsed = entry.get("collapsed", False)
read_mode = entry.get("read_mode", False) read_mode = entry.get("read_mode", False)
if imgui.button("+" if collapsed else "-"): if imgui.button("+" if collapsed else "-"):
@@ -3435,6 +3455,24 @@ def hello():
def _render_mma_dashboard(self) -> None: def _render_mma_dashboard(self) -> None:
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_mma_dashboard") if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_mma_dashboard")
# Focus Agent dropdown
imgui.text("Focus Agent:")
imgui.same_line()
focus_label = self.ui_focus_agent or "All"
if imgui.begin_combo("##focus_agent", focus_label, imgui.ComboFlags_.width_fit_preview):
if imgui.selectable("All", self.ui_focus_agent is None)[0]:
self.ui_focus_agent = None
for tier in ["Tier 2", "Tier 3", "Tier 4"]:
if imgui.selectable(tier, self.ui_focus_agent == tier)[0]:
self.ui_focus_agent = tier
imgui.end_combo()
imgui.same_line()
if self.ui_focus_agent:
if imgui.button("x##clear_focus"):
self.ui_focus_agent = None
imgui.separator()
is_nerv = theme.is_nerv_active() is_nerv = theme.is_nerv_active()
if self.is_viewing_prior_session: if self.is_viewing_prior_session:
c = vec4(255, 200, 100) c = vec4(255, 200, 100)

View File

@@ -244,6 +244,7 @@ def flat_config(proj: dict[str, Any], disc_name: Optional[str] = None, track_id:
"output": proj.get("output", {}), "output": proj.get("output", {}),
"files": proj.get("files", {}), "files": proj.get("files", {}),
"screenshots": proj.get("screenshots", {}), "screenshots": proj.get("screenshots", {}),
"context_presets": proj.get("context_presets", {}),
"discussion": { "discussion": {
"roles": disc_sec.get("roles", []), "roles": disc_sec.get("roles", []),
"history": history, "history": history,