Skip to content

Mindmap/New: voice input, punctuation-blind quotes, map-only links, in-place card editing - #7

Merged
nhyiramante1 merged 10 commits into
mainfrom
claude-new/next-voice-punct
Nov 1, 2026
Merged

nhyiramante1 merged 10 commits into
mainfrom
claude-new/next-voice-punct

Conversation

@nhyiramante1

Copy link
Copy Markdown
Contributor

Summary

Changes to the tools-first Mindmap in next/. The current app in src/ is untouched.

Matching and tools

  • Punctuation is ignored in quote checks (44777ca). Dictated text has little punctuation, and the coach tends to add some when it quotes. Only letters, numbers and their order are compared now: apostrophes are dropped (don't = dont) and other punctuation counts as a space (well-known = well known). Pieces still have to start and end on whole words, so "now" doesn't match "not". Side effects, both intended: a card that differs from another only in punctuation counts as a duplicate, and a card the writer punctuates keeps its link evidence.
  • Links, nesting and near_card only use cards on the map (4e1e843). A pending card proposal is refused with a reason, at every level including L2. An accepted proposal's id is refused with the card id to use instead. Deleting a card drops the pending links and nestings that name it. A successful tool call now tells the model the proposal is pending, so it stops saying "I linked…". This reverses proposing a card and a link to it in the same turn (spec §4/§5.2 updated).

Chat

  • Voice input (f796e4f, 9fbc273). A mic button above Send uses the browser's speech recognition, adapted from src/ui/useSpeechToText.ts. Spoken words go into the message box; nothing is sent by voice alone. Typing or Send stops dictation, and late results after that are ignored. Pressing the mic right after stopping waits for the browser to end the previous session, then starts. In Firefox the button is disabled.
  • Tool calls as blocks (95fd174): a top row with the tool, its badge and Accept/Reject (or the outcome), and the full text below. A refused call's reason opens on request.

Map and draft

  • Card numbers (46225c1, f0e6ddc): cards show 1, 2, 3, the chat says "Accepted as card 3", and the coach is told to say "card 3".
  • Editing in place (f0e6ddc): a card's text is its edit box. Click into it and type; Enter or clicking away saves (one undo step), Escape reverts. Cards grow to fit their text, and you drag a card by its top row.
  • Nested cards (d8b6d75): placed below the parent's title, which shows up to three lines and fades out if there's more.
  • Resizable draft panel (46225c1, 8207a05): drag the left edge, use the arrow keys, or double-click to reset. The width is remembered in this browser. The map keeps at least 280px, and the draft gives way first when the window shrinks.

Testing

  • npm test in next/: 108/108. npx tsc --noEmit, npm run build and node scripts/verify-pages-build.mjs next pass.
  • New tests fail on the old code: the punctuation tests, the hook's late-result and restart tests, and the map-only tool tests.
  • Browser, dev server:
    • Dictation replayed through a patched recognizer: the box grows up to its cap and scrolls to the newest words, typing stops dictation, late results are ignored, no overflow at 375px.
    • Playwright at 1440×900: dragging the resizer, the arrow keys, double-click reset, the width remembered after reload, and the draft giving way at 1000/920px.
    • Card editing with real input; chat tool blocks at 1440 and 1024.

Not checked: a real microphone; Safari or Edge; touch drag and touch editing; the resizer fix (8207a05) and mic-restart fix (9fbc273) in a real browser; a live coach turn on dictated text or under the map-only rule.

Known, not changed: the card text is the coach's pieces, so punctuation the coach adds ends up on the card. That includes apostrophes that change a word ("we'll" for a spoken "well"), plus "?", "$" and emoji. The writer still accepts or rejects every card. Tightening this to treat only punctuation as spaces, and to keep comparing symbols, is a possible follow-up.

🤖 Generated with Claude Code

nhyiramante1 and others added 10 commits November 1, 2026 10:50
Dictated text has little punctuation, and the model tends to add some when
it quotes, so "nobody sees the small wins." was refused against the spoken
"nobody sees the small wins". The matching rule now compares letters,
numbers and their order only: apostrophes are dropped (don't = dont), any
other punctuation counts as a space (well-known = well known).

Every letter still has to match on word boundaries ("now" is not "not",
"ike" is not "like"), and fillers are not removed: the model quotes around
an "um" with two pieces. Side effects, both intended: a card that differs
only in punctuation is a duplicate, and a writer punctuating a card keeps
its link and nesting evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mic button above Send, using the browser's own speech recognition: the
current app's src/ui/useSpeechToText.ts copied with its tests (jsdom added
as a dev dependency for them). Spoken words go into the message box, after
whatever was already there, and the writer reads, edits and sends them like
typed text; nothing is sent by voice alone.

- While listening the button turns red, the hint says so, and the box keeps
  the newest words in view as it grows (up to 40% of the screen, then it
  scrolls).
- Typing or Send stops dictation. One change to the copied hook: after
  reset, results are ignored until the next start, because stop() still
  delivers a final result for the words heard so far, which would otherwise
  refill the box just sent, or overwrite what was just typed.
- Firefox has no speech recognition: the button is disabled with a tooltip.
- Better transcription through the backend is postponed (spec §8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Each card shows its number (c3) at the top left: the same id the coach
  sees in its state block, so "c3" in the chat is that card. An accepted
  card proposal's chat line says which card it became ("Accepted as c3").
- The draft panel's left edge can be dragged to make it wider or narrower,
  or moved with the arrow keys when it has focus; double-click resets it to
  320px. The width is remembered in this browser, apart from the session.
  The map always keeps at least 280px: dragging stops there, and if the
  window shrinks the draft gives way first (CSS min()), so nothing scrolls
  sideways. Hidden on the narrow, stacked layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nhyira, 11-01: the coach was proposing links to card proposals the writer
hadn't decided on, so the link's Accept stayed disabled and the writer was
pushed into deciding those cards later. Now:

- propose_link, propose_nest and suggest_idea's near_card accept only cards
  on the map. A pending card proposal is refused with the reason, at every
  level including L2; an accepted proposal's id is refused with the card id
  to use. The tool descriptions say so up front, so the model doesn't spend
  attempts finding out. This replaces proposing a card and a link to it in
  the same turn.
- Deleting a card drops pending links and nestings that name it (as
  rejecting a card already did), so no Accept is left that can't work.
- A successful tool call now tells the model the proposal is pending until
  the writer accepts it, so it stops saying "I linked..." for a proposal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nhyira, 11-01: the tool lines looked clustered, and since full proposal
text is shown, a long one wrapped with its "·" separator and badge on lines
of their own.

Each tool call is now a small block: a top row with the tool name, its
label and Accept/Reject (or the outcome) on the right, and the full text
underneath at any length. Pending proposals stand out (white, green edge);
decided ones fade back, with any note ("Its card was deleted.") under the
text; a refusal is one quiet row whose reason opens on request. The blocked
reason is no longer shown anywhere: since links need cards on the map, only
sessions saved before 4e1e843 can still have a link waiting on a pending
card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…umbers

Nhyira, 11-01: editing needed a double-click that sometimes didn't register
(a few pixels of movement between clicks counts as a drag) and opened a
smaller box that could close again a moment later, and long text scrolled
inside it.

- A card's text is now its edit box, styled as plain text: click anywhere in
  it and the caret goes there. Enter or clicking away saves (one undo step),
  Escape reverts, Shift+Enter is a new line. There is no separate editor to
  open, so nothing can open and close again.
- The card grows to fit its text, so nothing scrolls inside it. A parent
  card's title stays two lines over its children until it is edited.
- Cards are dragged by their top row (the number and labels).
- Card numbers show as 1, 2, 3; the chat says "Accepted as card 3", and the
  instructions tell the coach to say "card 3", not its id c3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p to three lines

A newly nested card was placed 48px into its parent, over the second line
of the parent's title, and since f0e6ddc a long title was cut off mid-line
(the old line clamp's ellipsis was lost when the text became an edit box).
A parent's title now shows up to three lines, fading out if there is more;
nested cards start 96px down, and siblings are 140px apart now that cards
grow with their text. Found while framing the presentation screenshots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After the window got narrower, the draft is drawn narrower than its saved
width (CSS min()), but dragging and the arrow keys started from the saved
width: the edge didn't follow the pointer until it had moved by the
difference, and the first ArrowRight did nothing. Both now start from the
draft's drawn width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4e1e843 added the block inside the evidence-rule block. Moved after it;
no test changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The browser ends a recognition session a moment after stop(), and start()
before then throws, so pressing the mic again quickly did nothing and
showed nothing. start() now waits for the previous session's end event and
starts then; the ending session's last results are ignored, since the
words are already in the box (the seed). Stopping while it waits cancels
the restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nhyiramante1
nhyiramante1 merged commit f1c930d into main Nov 1, 2026
2 checks passed
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.

1 participant