50 Commits
Author SHA1 Message Date
Martin Vogel e30dd59fde fix: match architecture handtest identifiers literally
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-22 00:51:41 +02:00
Martin Vogel 8c4747666c fix: preserve literal input and static asset boundaries
Escape project names before building hand-test patterns, compare transport
identifiers as literal tokens, preserve boundaries when extracting prose
and XML facts, and require canonical containment for smoke static assets.
Add regression coverage for metacharacters, dollar identifiers, markup
joining, traversal, symlinks, and malformed URL encoding.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-21 23:12:06 +02:00
Martin Vogel cf41bdc6d6 Secure Lens history reads and verify shipped browser dependencies
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-11 18:12:30 +02:00
Martin Vogel fa05e114f2 Tidy Lens documentation and remove development artifacts
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-11 18:12:05 +02:00
Martin Vogel b0b0ffdef8 Polish CBM Lens Beta branding and architecture navigation
Rename the reading workspace to CBM Lens Beta, distinguish Beta with an amber badge, and keep build diagnostics out of the header. Put architecture history beside the active context and record meaningful exploration steps.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-11 15:56:10 +02:00
Martin Vogel 7cfc1b8771 Fix integration regressions in agent handover and graph scope
Preserve unfinished model operations across repeated project switches, retain truncated graph metadata for file and folder scopes, and give each browser hand test a fresh profile directory without deleting existing data.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-10-07 23:39:29 +02:00
Bernhard Jackiewicz 234e0f2329 Merge third round: chat wording, counts with units, render limit sentence, dropped sentence reason, token note, unknown names, German answers, Architecture card
Both chat branches touched the same places. The grounded answer keeps the
lines read from the code and takes the reason of a dropped sentence; the
divider says "Back to" for a returning topic and "New topic" in the
language of the turn otherwise; examples follow the kind of the selection
and the hint offers no model. The new tests of the behaviour branch now
expect the reworded texts, and the German follow up answer quotes the
prompt like the other German hints.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 15:59:04 +02:00
Bernhard Jackiewicz 77639095e2 fix(ui): smooth the German chat wording and fit examples to the kind
"Frage zum Beispiel:" now reads "Du kannst zum Beispiel fragen:", and the
uncertain answers offer a choice instead of an order ("Du kannst dir die
Liste ... anzeigen lassen oder das Modell fragen.", "You can show the
list ... or ask the model."). A misspelled name is compared with the
selection by name: "JSONBAg entspricht nicht dem Namen der Auswahl
(JSONBAgg)". The definer uses article and pronoun of each kind ("die
Schnittstelle, die", "der Ordner, der") and the English plural is right
("the classes"). Examples for a prompt without a question fit the kind:
a class gets what it is, who uses it and, when it has INHERITS edges,
what it inherits from; a file or folder gets what it contains. The K16
hand test expects the new name sentence.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:47:04 +02:00
Bernhard Jackiewicz a5f3df2099 fix(ui): keep German answers German and name the Galaxy controls
German answers showed "(Method, ...)" and "Ausgewählt: JSONBAgg (Class)".
Kinds are now written in the language of the answer (Methode, Klasse,
Datei, Funktion, Modul, Schnittstelle and the other kinds of the index),
while the prompt stays English. The topic divider follows the language of
the turn it heads, with a German text beside the English one. When a side
or a layer is missing, the answer names the controls as Galaxy labels
them: "Incoming", "Outgoing", "Both directions" and "Expand +1". The K17
hand test expects the German divider above its German question.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:44:12 +02:00
Bernhard Jackiewicz 94ac1219dc fix(ui): say why the model sentence was left out
The note said the sentence "named something the evidence does not show"
also when it was dropped for a claim word such as "output" or "Array"
that the source does not show. explanationSentence now returns the reason
with the drop, the claim word or the unknown name as the sentence wrote
it, and the notes say what was claimed or named and what it was checked
against, in English and German. The K12 hand test accepts the named form.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:38:36 +02:00
Bernhard Jackiewicz c395bd57bb fix(ui): say "Back to" and send a returned topic's own earlier turns
Coming back to a file or selection that already had turns showed "New
topic: <same file>. Earlier messages are not sent with these questions."
and sent none of them, so "Und was noch?" got "Ja, und noch." The divider
now reads "Back to: X. Earlier messages about it are sent again." (German
"Zurück zu: X. ..." for a German question), and the request carries the
earlier turns of that topic again. Turns of other topics still stay out.

A short follow-up right after a change of topic ("und", "mehr", "und was
noch?", "and?", "more") has no turn of its topic to follow. It is now
answered without the model: earlier messages were about another topic and
are not sent, please ask the full question, with the example questions of
a prompt that asks nothing.

The chat check for K17 now expects the return to send the file's own
earlier question and to say "Zurück zu".

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:38:27 +02:00
Bernhard Jackiewicz a2fe87127d fix(ui): head a listed answer with the callers it lists
"Callers of JSONBAgg ... 23 incoming relationships from 12 symbols" was
followed by 11 callers. The heading now counts what it lists, "11 callers
(CALLS) of JSONBAgg in the loaded graph.", and gives all incoming
relationships apart ("All incoming: 23 relationships from 12 symbols.").
What a selection calls is a full sentence in both languages, the German
list of other types is headed "Andere", and a side that cannot be listed
says why in a full sentence. The K16 hand test expects the new heading.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:35:38 +02:00
Bernhard Jackiewicz 9d6e69fd97 fix(ui): write relationship counts with their units
"Incoming relationships: 23 from 12 symbols" and "2 zu 2 Symbolen" read
like a score. The summary lines now say "Incoming: 23 relationships from
12 symbols" and "Eingehend: 23 Beziehungen von 12 Symbolen", and the empty,
not loaded and cut sides use the same labels. The prompt and the Source
block head each edge type as "CALLS (11):" instead of "CALLS from 11:",
which the model repeated as a sentence. The K7 hand test and the call
feedback acceptance check expect the new wording.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:32:13 +02:00
Bernhard Jackiewicz 789b18d171 Merge second hand test fixes: chat facts, listed answers, name check, language, grounded general questions, empty prompts, configuration files, output limit (K32 to K39)
Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:00:51 +02:00
Bernhard Jackiewicz 6002e391fe Merge second hand test fixes: Architecture navigation, Recent menus, Refresh feedback, Behavior start list, workspace in the address (K40 to K44)
Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 14:00:51 +02:00
Bernhard Jackiewicz 63e2f40469 test(ui): expect file questions answered from the file in the chat check (C7)
Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 13:59:11 +02:00
Bernhard Jackiewicz 3d51f86d43 fix(ui): make the Expand +1 warning true and show it at once
At two layers of JSONBAgg the tooltip said "Likely past the render
limit", then that growing like the last layer adds about 402 nodes (90
plus 402 stays far below 5,000), and that loading stops at the render
limit of 5,000 nodes, while the layer then ended at 5,548 nodes.

- The warning names the limit and the number behind it: the 9,031 calls
  the index counts at the 75 edge nodes, with the loaded count. The
  growth estimate only stands where it is the larger number.
- The limit sentence says what loading does: it stops after the first
  request that takes the layer past the node or edge limit, so the layer
  can end above it, is marked partial, and the scene draws up to the
  limit. The partial status and the blocked Expand say the same. The
  Explore mini-Galaxy loads without limits and the hint claims none.
- The text moves from a native title (shown after the browser's delay)
  to the Galaxy's own tooltip: at once on hover and keyboard focus, below
  the button, also in its compact +1 form, closed on leave, blur and
  Escape, with aria-describedby.
- Expand is blocked with aria-disabled instead of disabled, so pointer
  and keyboard still reach the reason why it is blocked.

handtest-fixes-galaxy.mjs K8 reads the text from data-hint and matches
the new wording.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 13:43:06 +02:00
Bernhard Jackiewicz 57090cbd2e fix(ui): let tooltips ignore fields of closed menus
Hint protected every input and select of the page, also those inside a
closed <details>. Their content is not drawn, but the browser still gives
it a box, so the closed Path to and Edge types menus of the Galaxy
toolbar pushed the Expand +1 tooltip from its place below the button
into the page header.

Only drawn elements are protected now: checkVisibility where the browser
has it, and the content of a closed <details> (other than its summary)
everywhere. The readability probe applies the same rule.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 13:43:06 +02:00
Bernhard Jackiewicz 397b5dc68d fix(ui): put Architecture Back and Forward first, as in Galaxy, and close Recent menus (A1, A2)
Architecture showed bare arrows at the right end of its subtab row while
Galaxy has "← Back", "Forward →" and "▾" at the start of its toolbar.
The controls now come first in the row with Galaxy's words and tooltips;
the row measures itself with the shared toolbar fit and shows the glyphs
alone once the tabs would scroll.

The Recent menus of both workspaces stayed open over the content. One
shared hook (graph/use-dismissible-menu.ts) closes them on a press, wheel
or focus outside, on Escape (which no longer reaches the page), on a chosen
entry and whenever the place changes.

The K27 browser check counts an in-view "← Back" outside the shared
history group only, since the shared one now carries the same words.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 13:24:00 +02:00
Bernhard Jackiewicz 1d4c4ad125 test(ui): run the acceptance and architecture checks without a window
Both opened a visible browser window that took the foreground. Like the
Galaxy and chat checks they now run headless; --headed shows the window.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 13:02:04 +02:00
Bernhard Jackiewicz ea8c623c5d test(ui): measure the typed-then-Back window inside the page (K27)
Date.now() around click() also counted Playwright's own wait for the
button and exceeded 600 ms under load, so the check measured the case
after the pause. The page now records the last input and the click that
reaches the button.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 05:24:23 +02:00
Bernhard Jackiewicz 04255f6fb0 Merge completeness fixes: chat, agent and in-page project switch gaps (K1, K7, K12, K16, K24) 2026-10-04 04:42:09 +02:00
Bernhard Jackiewicz b824b34206 test(ui): browser checks for the K24 switch situations and the YAML facts
A switch with the chat closed, with an answer running, while the old
project still loads, and a log line written after it; YAML lists of
mappings in the file facts; the opened-area card counting the parts the
view counts. The check that deletes the cached model and downloads it
again during a switch runs only with --with-download.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 04:06:45 +02:00
Bernhard Jackiewicz b864f93371 test(ui): browser checks for the Galaxy completeness gaps (K2, K3, K5, K12, K13)
tools/handtest-fixes-galaxy.mjs now runs headless (Chromium channel, so
WebGL draws on the GPU; --headed shows the window) and adds:

- K5: at two layers around JSONBAgg no node the first incoming column calls
  or defines (index truth via query_graph) stands in an incoming column
  unless it also leads into one; outer outgoing nodes come from the first
  outgoing column; the band below holds every mixed node, its heading counts
  them and overlaps no name; every edge label carries a type and an arrow;
  one layer has no band; Aggregate at two layers (651 nodes) keeps the names
  of the root and its 34 direct neighbours with a visible note; call_command
  (554 direct neighbours) keeps its own name and its 11 callees.
- K12: in Explore with .github/workflows/new_contributor_pr.yml open, the
  mini-Galaxy has no overlapping label rects in the DOM with the chat closed
  and open, and every root in view keeps its name.
- K13: "Lines 42 to 65 · end of file" and 65 as the last drawn line.
- K2: "← Back" and "Forward →" at the full level, the arrows alone at the
  compact level, tooltips unchanged.
- K3: at the full level the root name is never squeezed below its text.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 00:40:23 +02:00
Bernhard Jackiewicz 90de5135be test(ui): acceptance G7 also measures the toolbar with the chat open (K3)
K3 asked for the acceptance check G7 to cover the open chat as well; it
measured only with the chat closed at 1600 px, where the toolbar never
wrapped. G7 now measures the scoped Galaxy toolbar with the chat closed and
then open at 1600 px (bar about 1170 px), counts rows by the centres of the
toolbar's own items, and passes only when both measurements are one row
without overflow. The chat is closed again for the checks that follow.
A small vitest guard reads the G7 section and keeps both measurements in it.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 00:38:34 +02:00
Bernhard Jackiewicz 1a60ba8352 test(ui): browser checks for the in-page project switch and the chat gaps (K24, K16, K12, K7, K1)
Extends the chat stream script of the hand test (tools/handtest-fixes-
chat.mjs) with the points the completeness check of 2026-10-04 found
open:

- K24: django-demo with the agent active, a selection and a listed
  answer, then cbm and django-demo through the project switcher, then
  Back and Forward. Each leg measures that the page did not reload, no
  model worker was created and nothing was prepared again, the lamp
  reads "Agent active" at 0, 250, 1000 and 3000 ms, the workspace stays,
  the chat shows the new project's history, and no request sent once
  the address named the new project names the old one. After each
  switcher leg all twelve views (Explore, Galaxy, Architecture Overview,
  Entry points, Service map, Endpoints, Hotspots, System structure,
  Behavior, ADR, Coverage, System logs) carry no marker of the old
  project and are compared with a fresh page load of the new one. The
  auto-load tooltip is read too.
- K16: three word orders with "wo" are listed, four misspelled names are
  offered for the selection with the right wording; none reaches the
  model.
- K12: the workflow's automatic card is facts only and offers "Ask the
  model"; asking marks the model text as generated; tox.ini,
  pyproject.toml and README.rst show facts only without a model call.
- K7: the django area opened with nothing selected lists its lines,
  languages, parts, hotspot findings and connections.
- K1: an automatic explanation cut at 32 output tokens names both
  limits.

The browser runs headless unless --headed is given; ANGLE on Metal gives
it the GPU with shader-f16 the local model needs.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-04 00:33:33 +02:00
Bernhard Jackiewicz 80dd23d5a3 Merge hand-test fix: Architecture back and forward on the shared history (K27) 2026-10-03 23:04:45 +02:00
Bernhard Jackiewicz e617e70e4b test(ui): browser check for Architecture cameras, call chain and typed filter (K27)
The K27 browser run now also checks that System structure and Behavior show
no Back of their own, that Plan or 3D in System structure and Behavior is a
step Back restores, that the Behavior path and the operation on the call
chain come back after Back and Forward, and that text typed in the Routes
filter survives an immediate Back. Screenshots reset every scrolled
container so each one shows the subtabs and the history controls.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 23:02:58 +02:00
Bernhard Jackiewicz d354983e84 test(ui): browser check for Architecture back and forward (K27)
tools/handtest-fixes-k27.mjs drives the hand-test flow on django-demo in a
headless browser: Overview, open django, Routes, Endpoints, open the /edit
route group, System structure, expand a group, Behavior, start handle in
loaddata.py, follow a call. It then goes back step by step to the start and
forward again, checking at every step the subtab, location trail, route
perspective and filter, system focus and expanded groups, Behavior start
and the Back and Forward tooltips. It also checks Alt+Left and Alt+Right
(and that they do nothing while typing in the filter), a jump from Recent,
that a new navigation after Back drops Forward, that Alt+Left in Galaxy
leaves the Architecture history alone, and that switching to cbm starts a
fresh history. Every step writes a screenshot and index.md.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 22:25:26 +02:00
Bernhard Jackiewicz 844d4129c1 test(ui): accept grounded explanations and wait for route evidence
The automatic explanation now lists the indexed facts itself and sends
the model only the source (K7, K14): check the card facts against the
index and the source in the prompt instead of caller names in the prompt.
Endpoints are measured after the route evidence is read.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 21:46:35 +02:00
Bernhard Jackiewicz 5282faa7f9 Merge hand-test fixes: local agent grounding, context and lifecycle (K1-K24) 2026-10-03 21:17:58 +02:00
Bernhard Jackiewicz 5d13cec18f Merge hand-test fixes: galaxy history, layers, toolbar, hierarchy and details (K2-K13) 2026-10-03 21:17:58 +02:00
Bernhard Jackiewicz 4cf470b8e6 test(ui): browser checks for the review findings on the chat items
The chat checks now also go back to the workflow file after Galaxy and
assert that its earlier answer is not resent (K17), list callers with
automatic explanations off and ask the model with the source (K14),
read the German suggestion buttons and the direction of "Does this
class call super?" (K16), assert the counted workflow facts and the job
count (K12) and the callee names in the Behavior facts (K7).

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 21:03:10 +02:00
Bernhard Jackiewicz 76fb819f7b fix(ui): keep names in a two-layer Galaxy hierarchy and tidy its edge labels
Review of the hand-test fixes, K5. Above 60 nodes the hierarchy of a
scope drew no names (JSONBAgg at two layers, 90 nodes) but 80 edge
labels on the first 80 pairs. Names now stand up to 150 nodes; above
that neither names nor edge labels, and the hint says how to get them
back. Every line at the root keeps its label; further out a fan from
or into one node carries one label with its count. A label shows only
while the names read on screen (at the fitted two-layer view they are
about 5 px), only on lines in view, and never over a name: a label
without a free place is left out, the line colour still tells its type.

The Playwright script checks these review findings too.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 20:58:49 +02:00
Bernhard Jackiewicz 067e5ca7da test(ui): check the review fixes of the hand test in a browser
The browser check now also measures what the review found: blue pixels
of the Behavior call lines and the Service map call key (K19-lines),
folder names and neighbour chips while the pointer sweeps over every
chip in Hotspots and Overview (K20-hover), and whether the same error
text from two places reaches the log twice in full while a count keeps
its place (K26-identity). K25 now selects Behavior after the project
switch, so it no longer depends on a profile that remembered it, and
slow architecture reads of django-demo get a longer wait.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 20:30:32 +02:00
Bernhard Jackiewicz 8079aff668 fix(tools): skip the style gate's committed report when it writes elsewhere
The gate does not read its own report, which quotes every finding and every
documented exception. With --out outside the repository it still read the
committed verification/w6/stylegate.json, an earlier run of itself, and
failed on 57 quotes of the documented exceptions, on this branch as on its
base. Both paths are now its own reports.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 20:07:53 +02:00
Bernhard Jackiewicz b838e200e2 test(ui): browser checks for the chat items of the hand test
One Playwright check per item K1, K4, K7, K10, K11, K12, K14, K15, K16,
K17 and K24: each drives the flow of the correction plan against a
running server with the real local model, measures DOM text and boxes,
the messages sent to the model worker, the model's raw answers, model
downloads and the agent lamp, and writes screenshots with an index per
item. It prints PASS or FAIL with the measured values.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 20:01:41 +02:00
Bernhard Jackiewicz 86af069f76 fix(ui): lay out the Galaxy scope hierarchy left, centre and right
Hand test K5. With both directions and all edge types the hierarchy
put incoming and outgoing neighbours of every type into one column to
the right of the root, sorted by name, cut long names, labelled no
edge and claimed "one column per call depth". Path to and Call order
were missing in this view.

The scope hierarchy now places incoming relationships on the left, the
root in the middle and outgoing ones on the right; deeper layers keep
the side of the neighbour that led to them. A column orders by that
neighbour, calls before other types and calls by call-site line.
Columns stand as far apart as their names are wide, so names keep
their full length (up to about forty characters). Each node pair
carries its edge types at the line ("CALLS · TESTS"), placed clear of
the names. The hint and the legend describe this picture per trace
direction, and Path to and Call order work here too, highlighting the
hierarchy's own nodes.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 19:46:59 +02:00
Bernhard Jackiewicz 1ed66ce3e2 fix(ui): frame a shown Galaxy path and keep its edge labels off node names
Hand test K6. When the target of "Path to" lay close to the root, the
target's name covered the CALLS label and the camera did not move.

A newly shown path (not a step through it) now flies the camera onto
its nodes: the view direction stays, the camera steps in or out until
the path fills about half of the area beside the step list, with a
margin for names. All nodes of the path carry their name in the path
layer instead of the scene's name sprites, and each edge label slides
along its edge, then aside, until it touches no name and no other
label. Measured in the browser for JSONBAgg: zero overlaps for a one
hop and a two hop path, root and target 595 px apart (before: overlap
and an unmoved camera).

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 19:33:18 +02:00
Bernhard Jackiewicz 0e957965a6 test(ui): check the Architecture and log fixes of the hand test in a browser
tools/handtest-fixes-architecture.mjs drives the hand-test flows of
K18 to K23, K25 and K26 against a running UI, measures each finding in
the page (label rects and their overlaps, canvas colours from the
screenshot, counters, the posted ui-log entries) and prints PASS or
FAIL with the values, with screenshots after 0 ms, 250 ms, 1 s and 3 s.
Label and camera checks also run in the hand-test window (1494x728,
chat open). The script answers POST /api/ui-log and keeps beacons in
the page, so its sessions never reach the daemon log.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 19:25:12 +02:00
Bernhard Jackiewicz 495e27a38d fix(ui): show the loaded scope's relationships in Galaxy selection details
Hand test K13. For JSONBAgg the panel showed only "Outgoing
relationships · 2" while the toolbar and the chat counted 23 incoming
ones. The panel read the repository map snapshot, which is capped at
20,000 nodes by file path, so the tests under tests/ were missing, and
it kept only the map relations, so TESTS and DEFINES never counted.

In Galaxy the panel now receives the loaded scope and counts every
indexed relationship type, by direction and type ("Incoming
relationships · 23 (CALLS 11 · TESTS 11 · DEFINES 1)"). It says where
the relationships come from and when the scope is still loading,
partial, traced in one direction or for some types only. A symbol in
the scope but behind the snapshot cap is a valid selection there.

"Next lines" disabled at line 66 of general.py was correct: the file
has 65 lines and the Module range ends at 66. The pager now says
"end of file" and the disabled button names the last line.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 19:17:50 +02:00
Bernhard Jackiewicz cbeed8bdc1 fix(ui): keep the scoped Galaxy toolbar to one row with the chat open
Hand test K3. With the chat open the Galaxy column is about 1170 px at
a 1600 px window, and the scoped toolbar broke into two rows; Expand,
Path to and Call order moved down. Acceptance G7 had measured it with
the chat closed only.

The row no longer wraps in a scope. The root name is now the button
that opens its source; Open source, the render limits, the connection
groups and the note on nodes outside the limits moved into a compact
menu. The visible word Trace is gone (the select keeps its accessible
name), Recent became a glyph, and the search field, the root name and
long status texts shrink with their full text in the tooltip. A
partial layer now leads with "Partial:", so a narrow row never cuts
the warning. Measured in the browser: 49 px and one row in seven
states, chat open and closed (before: 88 px, two rows).

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 19:10:39 +02:00
Bernhard Jackiewicz a436eacf43 fix(ui): load deep Galaxy layers in large pages, show progress, allow cancel
Hand test K8. Expanding JSONBAgg to three layers ran for minutes: the
server re-executes a query for every continuation page and returns only
about 30 rows of scope columns per page under its default output
budget, so one layer became more than 500 sequential calls.

The scope loader now asks for pages of up to 5000 rows. Layer three of
JSONBAgg finishes in about 8 s with 11 calls. While a layer loads, the
toolbar names it with the nodes and edges loaded so far, the canvas
says the picture is a partial preview, and the minus button cancels
the load and returns at once to the previous, complete layer. A layer
that grows past the render limits stops there, is marked partial with
the limit in its tooltip and is never the base of a further layer.
The Expand tooltip states the frontier and the growth of the last
layer, without promising a count.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 18:56:34 +02:00
Bernhard Jackiewicz 80b8f7965f feat(ui): add Galaxy back and forward and keep the scope on empty clicks
Hand test K2 and K9. A click on a node made it the new root with no way
back, and a click just beside a node threw away scope, layers and path.

A bounded history (25 entries, consecutive duplicates merged, forward
branch dropped on a new navigation, no pushState) now records root,
depth, direction, edge types, open path and view. Back and Forward sit
in the scoped toolbar with tooltips naming the target, Alt+Left and
Alt+Right work outside fields, and a Recent list jumps to the last 8
roots. All graph is an entry of its own.

An empty-canvas click inside a scope now only clears the path
highlight. The scope is left only through All graph, Escape or Back.
The concept is in docs/development/pr-2068-galaxy-history.md; the
model in graph/navigation-history.ts is meant for K27 as well.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-03 18:47:55 +02:00
Bernhard Jackiewicz e4bb705d05 test(ui): accept the call-feedback fixes with measured browser checks
One check per plan item, measured in the running page instead of
described: canvas identity and fit count across selection and Expand,
camera movement under the wheel, root marker position, toolbar height,
path and call-order stepping, element under the Send button, the prompt
sent to the browser model, the caller list against query_graph, cached
explanations, Overview labels inside a large area, System structure,
Behavior starts and grouped endpoints. Movements are also cut into
frame strips from a recorded video.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-02 20:52:05 +02:00
Bernhard Jackiewicz 016861e0e5 chore(ui): clear the style gate hits outside the chat surfaces
npm run check:style failed on the PR head. This removes the hits that do
not belong to the chat and header work:

- the six long dashes in the ADR preview fixtures become colons;
- the projects menu entry, the coverage selection label and the "Open
  ADR" button take their text from the message catalog again, with the
  wording unchanged;
- the README names the bundled hook by its installation section instead
  of by product name;
- the configuration reference keeps the installer's exact environment
  variable through a narrow exemption in the operational client rule,
  limited to that one variable in that one file, with tests showing that
  any other mention or an authorship claim there still fails.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-02 19:17:24 +02:00
Bernhard Jackiewicz 92224c4463 docs(ui): reproduce the review call feedback and plan the fixes
Reproduce every point from the 2 October review call in a real browser
against a Django 5.2.7 index and this repository as control, and record
the plan with measured causes, priorities and open decisions.

The capture script splits each interaction into numbered screenshots
with a visible cursor ring and records canvas identity, camera and the
prompt sent to the browser model, so resets, zoom direction and chat
evidence are measurable rather than described. Only 17 downscaled
images are committed; the full series stays local.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-10-02 18:19:23 +02:00
Bernhard Jackiewicz 4372d9fada feat(ui): integrate repository evidence and change analysis on one daemon
Add source-backed repository navigation, selection context and a shared change
analysis workspace for symbols, working-tree changes and Git comparisons.
Persist agent events and project logs through the existing daemon with SQLite
schema 4, bounded polling, retention and restart-safe deduplication.

Repair compact RPC decoding, path-search races, source pagination and identity,
large map responses, live error propagation and explicit local diagnosis flows.
Include the real-repository browser runners and focused regression coverage.

Validation: 2473 frontend tests, 203 acceptance checks, production build,
style/promise gates, 5 reference-boundary checks and 7 local hook tests pass.
The complete repository-map browser flow also passes after daemon restart.
Global C lint and cross-platform release validation remain open and are
recorded in the accompanying handoff report.

Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
2026-09-10 00:08:19 +02:00
Martin Vogel c8661d7fb1 feat(ui): projects panel keeps indexing, ADR editing and server views in the browser
The previous graph-ui let a reader index a repository from the browser,
delete an index, edit the project's decision record and look at the
server's log and processes. CodeAtlasWeb is read-only by design and sent
all of that to the command line, which for a fresh install means a page
that says "nothing indexed" with no way forward. This adds a [p]rojects
panel (alt+p) in Bernhard's idiom so nothing users have today is cut.

What it does, and how it says so:

- Projects on this server: the list from list_projects over /rpc, with
  root path and counts when the server sends them ("counts not sent"
  when it does not), open (reloads with ?project=), check
  (GET /api/project-health as a sentence), reindex (POST /api/index with
  the root the server reported; no root, no button, a sentence instead)
  and delete (DELETE /api/project) as a two-step question in place.
- Index a repository: path and name (suggested from the last segment),
  a folder browser over GET /api/browse, the index button only once
  both fields are there, the acknowledgement of POST /api/index, and
  the job table from GET /api/index-status polled every 1.5 s while a
  job runs; the list reloads exactly when a job finishes.
- Decision record: GET/POST /api/adr for the open project, with
  "busy" told apart from "refused" by the 423 status.
- This server: GET /api/processes and the GET /api/logs tail.

Every block names its source route, a number the server did not send is
shown as not sent, and no control is on the screen that cannot act
(his promise-scan and style gates stay green; the panel is in the
hardcoded-string scan's file list).

Wiring: AtlasApi grows the routes above with a method-aware request;
the catalog gets a projects section, the menu entry, the help panel
entry and the help wording about what this window can ask the server
to do; WIRED_MENU_SHORTCUTS gains 'p' and the help table picks it up
structurally; the no-project status line points at alt+p.

index.html gets an inline SVG favicon so a fresh page stops logging a
404 for /favicon.ico.

Verified: 2073 vitest tests pass (49 new: model readers, the API
routes with a recording fetch, the panel in jsdom); in the embedded
build against a live server, POST /api/index returned 202, the job
table was polled to "done" and the list refreshed with the new project.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-05 20:36:10 +02:00
Martin VogelandBernhard Jackiewicz 67e39d16c0 feat(ui): replace graph-ui with CodeAtlasWeb by Bernhard Jackiewicz
Imports the CodeAtlasWeb companion frontend verbatim from
BernhardJackiewicz/CodeAtlasWeb at commit
1825f9c850ac794066e02606012508b9d393c6aa as the new graph-ui and removes
the previous React frontend.

This is Bernhard Jackiewicz's work, contributed with his agreement and
squashed here from his development history (41 commits, cycles W0
through W15). The maintainer only relocates it: every product decision,
line of code and test below graph-ui/ is his. The seven galaxy files
that originate in this repository's previous graph-ui, and the pinned
3D libraries, are listed in graph-ui/THIRD_PARTY.md.

What it is: a local reading IDE on the CBM read surface. A read-only
Monaco source reader, a semantic twin that follows the caret, entry,
bug-hunt, change-scope and flow reading modes, deterministic
source-cited explanations with an optional local-model wording pass
(llama-server sidecar, off unless the reader starts one; no model or
binary ships), a persistent galaxy with focus following in both
directions, a live-agent overlay fed by a loopback bridge, explicit
air-gap, provenance and index-limit messaging, and an offline
acceptance and browser verification harness.

It consumes POST /rpc (the read-only tool allowlist), GET /api/layout,
and the atlas routes /api/tree, /api/trace, /api/flows and /api/flow,
plus the real ingest_traces store for observed calls; all of these are
on feat/atlas-r1 (#1860), which this change stacks on.

Not imported: CLAUDE.md (an agent-instruction file, which stays
local-only in this repository), and the recorded proof artifacts under
graph-ui/verification/, which follow in a separate commit so they can
be reviewed and dropped on their own.

Build wiring, the dev-proxy port contract, the CSP allowance for the
sidecar and bridge ports, and the control surfaces the previous
frontend had (project indexing, ADR editor, logs) follow in separate
maintainer commits.

Design and tracking: #1964.

Co-authored-by: Bernhard Jackiewicz <bj@techport.io>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-05 20:05:43 +02:00