Mindmap main - #569
Merged
Merged
Conversation
Standalone prototype app under prototype-uist/ with React UI, API client, and Vite build config.
- handleSend: protect the suggest box from being overwritten by a new placement prime when it holds user-typed text or an active suggestion; allow newest auto-prime to replace a prior auto-prime (lastPrimedTextRef). - Preserve both guardrail and placement notices on the same turn. - Document the iterative LLM-assisted evaluation in docs/evaluation-log.md (test catalog, open items J1/K3, UIST framing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Pin the word bank; scroll only the region below it (pending, placement, rejected) in one bank-scroll-area. Resolves K3 card clipping without scrolling the whole pane. - Add a chat banner when a placement suggestion is awaiting review. - Make the "Suggest placement from the bank" header sticky within the scroll area. - Condense the topbar to give the working panes more room. - Emphasize status-bar notices (flash on change + active styling). - Update evaluation log: J1 and K3 now PASS; record post-Phase-A UX backlog. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase B (expand-before-place + box authoring):
- Abandon signal (placementIntent) clears placement state on a stop/pivot.
- Expand-before-place: coach can ask to expand a thin snippet (chat + box-side
hint); approving the re-said item auto-primes it (scoped to placement flow).
- Box is an authoring surface: box-typed text becomes a user-origin approved
bank item, then inserts through the unchanged exact-match guardrail.
- Keep/remove placed reference (tri-state: keep/remove/ask) with persistence.
- Placement insertion now follows the coach's focus region; suggestion card
shows the resolved anchor.
Insertion routing fix (document.ts findParagraphRangeForAnchor):
- Previously only recognized blank-line ("\n\n") paragraph separators, and a
single global separator broke mixed drafts (single-newline body + a blank
line before Works Cited), causing inserts to append before Works Cited and
duplicate. Now uses the next single "\n" boundary. Covered by 2 regression
tests. Exact-match insertion guardrail unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ve dead radios
- document.ts: match the separator at the insertion boundary instead of a global
guess (fixes blank-line accumulation; avoids the mixed-draft L5 failure)
- types/document/App: new into_paragraph insert mode ("Insert seamless") placing
exact bank text continuing the anchored paragraph; reuses the exact-match
guardrail, joining space kept outside the verbatim span (AI authors nothing)
- App.tsx: remove the dead editor-mode radios + unused targetKind/placeholderTarget
- document.test.ts: spacing + seamless regression tests (22 passing)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A writing-thinking tool where the user authors every idea and the AI only questions, mirrors the user's own words, and captures confirmed structure. Enforcement in code, calibration in config. - Headless loop: capture -> segment -> deterministic signal detection -> readiness gate -> mirror validation -> per-chunk user confirmation. - Question mode with deepen/organize intent + settle/narrow/challenge stance. - Draft panel with question anchoring; concept-map canvas (xyflow) with nesting-as-embedding, user-drawn connections, delete/undo. - Think<->Map slider biases mirror pacing only; grounding gates never move. - carryForwardIntent: AI-detected commitment lets a single grounded idea mirror sooner, fenced by validation + confirmation (idea-only, this-turn, source-spanned). suppressionReason diagnostics surfaced in Debug. 74 tests passing; tsc + build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…or dedup
- Phase 2/3 map commands: nest_card/connect_cards with exact + near-match
reference resolution ("did you mean X?"), declarative/referential blocklist.
- Connection UX: optional relationship wording, side/corner handles preserved,
draggable endpoints, deletable connections, label on/off toggle.
- Mirror dedup: drop claims already placed on the map (normalized-exact);
downgrade to a question with an `already_on_map` suppression reason when all
claims are already settled structure, preventing duplicate cards.
- Nest-intent prompt nudge so first-person "I want X under Y" routes to a
command, not a mirror.
- DESIGN.md + airtightness-report.md updated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gpt-5.4 occasionally returns invalid JSON (unescaped double quotes inside a string value when it quotes the user's wording), which hard-broke the confirm-continuation flow with a red parse error. chatJSON now retries once with a strict reminder before failing, the continuation-focus and output-format prompts steer the model away from raw double quotes (use #ref/paraphrase), and api.test.ts pins the retry with the exact failure shape. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A complete direct command with no uncertainty now returns "Done. What would you like to do next?" regardless of the LLM's chosen mode, instead of a reflective probe or (via a lastAiText self-match) the mirror-suppressed repeat question. Consolidated the two command-precedence branches, stopped pre-setting lastAiText before finish(), and exempted command hand-backs from the anti-repeat guard so back-to-back commands stay clean. Regression test added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-clean now lays each connected component out top-down with dagre (clean rank flow, minimal crossings) and packs components left-to-right with row wrapping, so unconnected cards spread across the canvas instead of stacking in one column. Card placement is now a shared, rectangle-overlap-aware nextRootPosition used by every add path (blank card, reflection, command), so a new card never overlaps an existing one; the + New card button zooms out to reveal the free slot when the canvas is cluttered. Adds @dagrejs/dagre (prototype-mindmap only) and a non-overlap placement test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cards the current coach turn names by #ref are now highlighted on the canvas (amber ring, applied like the drop-target class). The draft anchor highlight persists until the user clicks inside the draft to dismiss it — clicks elsewhere never clear it — and a new anchored coach turn re-shows the highlight and opens the draft if it was minimized. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The organize-focus note was interpolated twice in the system prompt; keep one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`uist` named the conference deadline the prototype was built for, not what it is. The README calls it the "User-Owned Words Writing Coach": the AI coaches and extracts candidate wording from the user's own messages, and the word bank's guardrail is what stops novel AI prose reaching the draft. Updates the package name, the sibling reference in prototype-mindmap's README, and the quickstart path. The evaluation log keeps the original directory name alongside the new one — it is a dated research record, so the name it was written under is provenance rather than staleness. Also stops tracking the prototype's build output. Three `dist/` artifacts had been committed with the original prototype; prototype-mindmap tracks none, and vendoring is the last moment to drop them before they are baked into main's history. Adds a `.gitignore` mirroring prototype-mindmap's, minus its mindmap-specific `eval/runs/`. Co-Authored-By: Claude <noreply@anthropic.com>
…ndary Item 7 slice 2 plus the root error boundary (item 9). The launcher integration made the persistence split necessary rather than merely tidy: PlatformBootstrap has to ask "is there real saved work?" before mounting App, which meant the boot layer imported storage helpers from the 4,600-line component it renders. session-persistence.ts now owns the persisted shape, the storage key, and load/write/summarize/clear. The migrations that transform loaded data into live stores stay in App.tsx — they operate on the running stores, not on storage. AppErrorBoundary sits above the ready branch in PlatformBootstrap. Map.tsx guards the canvas; nothing sat above App, so any render throw blanked the page. It deliberately does not clear storage: a render crash must leave the saved mindmap as intact as a token expiry does. Its fallback uses plain strings because the locale provider lives inside the boundary. Behaviour-neutral. 355 Vitest (3 new), typecheck, eval typecheck, build green. Co-Authored-By: Claude <noreply@anthropic.com>
…one 401s Three prod-readiness fixes to the launcher gate, all fail-closed: - `VITE_REQUIRE_LAUNCH=false` is now ignored when PROD. The override exists for dev servers and Playwright; honouring it in a production build let one stray deploy env var ship an ungated bundle with no runtime signal. - `VITE_BACKEND_URL` is required under PROD and throws at module load. The old localhost fallback would have pointed every user browser at their own machine. - `providerRuntime` is now supplied even when `session` is null, so standalone 401s reach a blocking screen instead of leaking a raw "Backend 401" chat banner. Standalone maps to `launch_required`, not `token_expired` — nothing expired, there was never a token. The backend-URL guard is duplicated in `api.ts` rather than imported from `platform-session.ts` to keep provider code environment-neutral for the Node eval runner. Co-Authored-By: Claude <noreply@anthropic.com>
A failed turn left its optimistic user message in `msgs`. That is not cosmetic: `msgs` is persisted, and `buildConversationHistory` rebuilds the provider transcript from it, so every later request replayed a dangling user turn the coach had never answered — for the life of the saved mindmap. Retrying stacked a second copy beside the first. Drop the bubble and restore the text to the composer instead. Not auto-resent: after a 401 the relaunch can be minutes later, by which point the message is often stale, and resending spends a real call the user never re-confirmed. The coach-only turn's catch is unchanged — it has no user message to roll back. Co-Authored-By: Claude <noreply@anthropic.com>
The choice screen is the first thing a returning user sees, and it was two undifferentiated bordered boxes. - Pins the timestamp to the bottom of both cards with a two-row grid, so a document name that wraps no longer leaves the pair looking ragged. - Adds a focus-visible ring. The old rule styled `:hover` only, so keyboard users got the UA default outline against a tinted background. - Gives "continue" a quiet accent. Starting new silently discards the saved mindmap, so the accent marks the recoverable path rather than shouting about the destructive one — an explicit warning would need a new i18n string. - Tabular figures so the two times align, plus hover/active depth that `prefers-reduced-motion` opts out of. No string changes: every visible label is an i18n key, so rewording would leave `zh` untranslated until a paid regeneration. Co-Authored-By: Claude <noreply@anthropic.com>
Feat/mindmap tool integration
Replace the Tools registry assertion with a behavioral one. The old test restated the registry literal (tier === 'lab', enabled === undefined); the replacement goes through pagesByTier, the same selector the navbar uses, so it asserts that Tools is reachable from the Labs menu without a flag rather than that two fields hold two values. Verified non-vacuous: adding an enabled predicate that returns false fails it. Document why reserveBrowserLaunch opens the popup synchronously instead of using an <a href>: the URL carries a grant id that does not exist until an async round trip completes, the synchronous open is what detects a blocked popup before the document is read and transmitted, and pre-minting a grant to fill an href starts its ~2 minute TTL before the writer clicks. Co-Authored-By: Claude <noreply@anthropic.com>
`tsconfig.tsbuildinfo` is incremental-compile state, not source. It is already listed in `prototype-word-bank/.gitignore`, but the file was committed before the ignore rule could take effect, and .gitignore does not apply to already-tracked paths. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the mindmap prototype to the Writing Tools repository as a standalone, client-side writing environment.
The prototype helps writers externalize ideas into an editable map while keeping AI contributions visible, reviewable, and subordinate to the writer’s decisions. This PR establishes the application itself; authenticated launch from Writing Tools is added separately in the stacked integration PR.
What this adds
prototype-mindmap/.Telemetry decision
Server-side telemetry was considered, but its current value does not justify the added privacy, consent, and backend complexity. For now, the audit ledger remains local in IndexedDB. Server telemetry can be designed later as a separate feature if a concrete research need emerges.
Scope boundaries
This PR does not:
Verification
Stack
This is PR 1 of 2.
The follow-up PR targets
mindmap-mainand adds the authenticated Writing Tools launcher integration.