Commit Graph
10 Commits
Author SHA1 Message Date
amosblomqvist 9eb30edb40 Plan-graph refinement round 6 (owner): grayed arrows, static glow, glow-sized frame pad
- Arrows into not-yet-visited nodes are grayed out like the nodes
  (stroke-border line + a fill-border copy of the arrowhead); the
  in-chat block stays all-white.
- The yellow glow is static — the pulse is gone (owner).
- Smaller blur: stdDeviation 7 → 5, glow rect margin 10 → 8.
- The glow clipped at the frame on narrow graphs: its visible reach
  (GLOW_MARGIN + 3·GLOW_BLUR = 23 units) far exceeded GRAPH_PAD (8).
  Surfaces that show the glow now pad by GLOW_REACH — the popup's
  viewBox AND its fit box both use POPUP_PAD = GLOW_REACH, so the blur
  never clips; the monochrome in-chat block stays tight at GRAPH_PAD.
2026-09-14 07:06:25 +03:00
amosblomqvist 43ada6ce23 Plan-graph refinement round 5 (owner): the owner's arrowhead lands
arrowhead_1.svg (the CM/MJX long-arrow head) baked in — transform chain
collapsed to a clean scale 0.2 + y-flip: viewBox 0 0 50.2 104, tip at
(50.2, 52), notch mouth at x 27.2, tail opening 9.6 tall (≈10 at the
owner's full height 104).

Sizing per the owner's spec: line width stays 1.5; head height 16 makes
the mouth opening tuck the line flush (the LaTeX proportion). markerUnits
userSpaceOnUse, refX at the mouth (27.2) so the line terminates at the
notch — never at the narrow tip, where it would show through. Edges
shorten by the tip overhang (≈3.54 units) so the head's tip lands
exactly on the target node's border.
2026-09-14 06:59:38 +03:00
amosblomqvist 739a6aed56 Plan-graph refinement round 4 (owner): the simple white look + no entrance fly-in
Look (rectangular, white language — owner spec):
- Boxes: no corner rounding (rx dropped everywhere).
- Visited: fill-none, white stroke, white text. Upcoming: today's gray
  (fill-card, border stroke, muted text) — kept per owner. Current:
  white stroke/text + a faint yellow highlight — a blurred yellow fill
  (feGaussianBlur) that bleeds out over the node's edges, still breathing.
- Edges + interim arrowhead: white (marker swaps to the owner's SVG when
  it lands: right-pointing, solid fill, tight viewBox, tip at right edge).
- The IN-CHAT plan block renders monochrome — every node white, no
  status language, no glow; the popup/plan-window show the progression.

Popup entrance fix: the transition from round 3 animated the first fit
(graph flew in from the top-left zoom:1 state). The transition now stays
off until the first fit has been applied — the popup paints settled.
2026-09-14 06:55:10 +03:00
amosblomqvist b92237fd56 Plan-graph refinement round 3 (owner): higher zoom ceiling + eased zooming
- ZOOM_MAX 2× → 4×: node titles reach ~50px rendered, comfortable for
  close reading. Single tunable constant.
- Smooth zoom: a 180ms ease-out CSS transition on the transform wrapper —
  CSS retargets from the current computed value, so chained wheel ticks
  and the fit/button zooms all glide instead of snapping. Disabled while
  dragging (per-frame pans must not rubber-band). panning is React state
  toggled at drag start/end.
2026-09-14 06:30:05 +03:00
amosblomqvist 6464b34a79 Plan-graph refinement round 2 (owner): the popup fits, centers, and never clips
Root cause of the popup's fit/center failure: PlanDiagram rendered
w-full inside the popup's shrink-to-fit absolute wrapper — the svg
resolved to the popup's width regardless of its viewBox extent, so the
transform math (1 svg unit = 1 px at zoom 1) was off and the 'fit floor'
neither fitted nor centered.

- naturalSize: the popup's diagram renders at the viewBox width in px,
  so fit/pan/zoom math holds.
- The popup's fit box is now the PADDED ink box (GRAPH_PAD all around):
  centered strokes and the glow halo never clip at the frame edge.
- fitZoomFor lost its 0.15 artificial floor — for wide graphs it sat
  ABOVE the true fit and broke 'fully zoomed out = the whole graph
  visible, whichever axis binds' (owner's rule). The fit itself is the
  floor; a 0.02 epsilon only guards degenerate viewports.
2026-09-14 06:26:55 +03:00
amosblomqvist fdeacc42f5 Plan-graph refinement round 1 (owner): chat-font zoom cap + stroke-safe padding
In-chat full plan block:
- TEXT_CAP_SCALE (16.5/12.5): node text renders at text-xs in svg units;
  the block now carries maxWidth = extent × cap + mx-auto, so it still
  fills the column whenever the column is narrower than the cap, but
  never scales node text past the chat prose size (--lh-prose-size).
- GRAPH_PAD (8 svg units) around the full-extent viewBox: centered
  strokes (half outside the geometry) and the −4 glow halo were clipping
  at the frame edges — the padded origin (-8,-8) keeps all ink visible.
  Only the full-extent render pads; the plan window's override viewport
  and the popup's fit margins are untouched.
Test pins updated: mx-auto + max-width:232.32px + viewBox='-8 -8 176 152'.
2026-09-14 06:22:26 +03:00
amosblomqvist 3360181e41 Wave-5 reskin batch 5: normalize stray pixel text sizes onto the declared ladder
--text-xxs (10px) joins the ladder; every component-level text-[9|10|11px]
literal in owned components now pulls from the ladder (graph-view.tsx and
home.tsx untouched — graph stream). Cosmetic pins updated where touched.
2026-09-12 23:48:27 +03:00
amosblomqvist 41d6ae531c feat: the plan window — the plan's ambient, live, auto-moving presence
The successor of the injected plan blocks (docs/probe-teach-split.md §6):
always on once a tree exists, a zoomed-in window (2:1, ~2¼ node widths)
centered on the CURRENT node, re-centering by pure derivation as tagged
checks move the lesson — statuses derive live from the transcript on
every render (derivePlanStatuses), glow on current, fallback focus on
the lesson's first node, click opens the existing full-DAG popup.
Bottom-left, mirroring the activity dock's bottom-right; hidden on
narrow viewports; the learner's visual polish pass comes later.

PlanDiagram gains a viewBoxOverride (exported); latestTree exported.
Tests: viewBox centering/clamping (pure) + render (hidden pre-plan,
windowed viewBox, glowing current, starting fallback).
2026-09-11 21:21:43 +03:00
amosblomqvist 5653c77a29 feat: probe/teach agent split — explicit phase markers, position-only plan map
Diagnosis (2026-09-11 user testing, minimal-effort GLM): sessions stuck on
'plan' forever. Two causes: (1) the three-phase view read the stored tree's
currentNodeId, which nothing ever writes post author-once (2026-09-03) — a
structural dead seam; (2) the teacher stochastically left quiz.nodeId
untagged, and done-by-quiz-result semantics would have falsely completed
nodes anyway.

The redesign (docs/probe-teach-split.md) abolishes derived occupancy in
favor of explicit events:

- Two agents over one transcript: createProberAgent (quiz without a
  nodeId field, ask, probe_done) and createTeacherAgent (full toolset,
  plan_init onward). The chat-handler construction branch keys on a
  probe_done part in the transcript. MODELS.prober added.
- probe_done: server-side seam tool — carries the learner assessment
  (strands + free-form edge read), refuses while a question is open or
  the probe is already concluded, and queues a handoff steer through the
  generalized wake pipeline (steers now dedupe by id, not jobId; job
  finalization only for job steers). The teacher auto-wakes and authors
  the plan; the learner sees the assessment via the probe-done card.
- phases: probe ends at a concluded probe_done, plan ends at a
  successful plan_init — strictly sequential, no skipping, no legacy
  compatibility (data wiped at the pivot per doctrine).
- Plan map = position, not completion: derivePlanStatuses reads only
  tagged quiz CALLS (state/outcome feed nothing); current = latest
  tagged node with consecutive duplicates collapsed, visited = earlier
  distinct stays (a revisit stays in both — current wins at render).
  PlanTree is structure-only; currentNodeId/doneNodeIds and the dead
  mutation helpers are gone. No fallback current.
- Prompts split per agent (prompts/prober/, prompts/teacher/ over the
  trimmed shared base); graph-context injection removed entirely
  (shelved, docs/probe-teach-split.md §5); knowledge-graph context no
  longer reaches either agent.
- Plan blocks are full-only snapshots at plan_init (neighborhood
  machinery retired; the persistent DAG window is the future UI wave);
  usage capture unchanged.

Gates: tsc clean, 294/294 tests (phases/plan-tree/plan-blocks/question-
tools rewritten to the new semantics; probe-done + handoff-wake tests
added), lint, build. Live GLM smoke PASS: prober concluded with an honest
assessment, teacher auto-woke, authored a 10-node plan with the block
attached, then tagged checks on slope-instinct → secant derived current/
visited exactly as designed; grading honest both ways (driver off-by-one
proved a wrong answer grades false).
2026-09-11 06:44:20 +03:00
amosblomqvist bb369a077b Plan blocks in chat: full DAG borderless in the flow, fragment + glow, live popup (wave-4 item 3)
- components/plan-block.tsx: hand-built SVG (user decision) — deterministic
  layered layout (Kahn topo + longest-path depth, rows centered, authoring
  tie-break), bezier edges, the retired panel's status color language.
- PlanBlock renders data-plan-block parts AS CARRIED (frozen snapshots,
  never re-derived): kind full = borderless, viewBox = layout extent so
  nodes hug the column edges, natural height; kind neighborhood = own
  small labeled 'Plan fragment' container with the current node glowing
  (pulsing primary halo).
- PlanPopup: full-screen overlay with the LIVE plan — latest tree from the
  transcript, statuses derived at click time via derivePlanStatuses
  (contracts/plan.ts). Esc / backdrop / X close; drag pan, wheel
  zoom-to-cursor, zoom buttons; fit-floor semantics harvested from the
  retired tree panel (zoom floor = the fit, pan locks at it).
- chat.tsx: data-plan-block case in the part switch + popup mount.
- src/core/ui-message.ts: TeacherUIDataParts gains "plan-block": PlanBlockData
  (additive, type-only — lane touch flagged to master).
- tests/render-plan-block.test.tsx: pure layout (layering, centering,
  dangling-edge tolerance), wrap, frozen-snapshot render, live derivation.
2026-09-11 03:26:56 +03:00