feat(workspace): topic clustering and generated TOC/SKILL docs - #28
Merged
Conversation
…Z8RGR06XBSG9CH4TEWYJY) The last open item, and the only one that adds product surface rather than repairing something. Flagged before building: its own ticket called it a deferred go/no-go, and the approved plan scoped it out. The goal said all 24, so it is built — the concern is on the record, not in the way. Synthesize reads every note, summarizes each, clusters them by topic, and writes TOC.md and SKILL.md back into the workspace. This connects the last three orphans. TopicRefiner, TOCGenerator and SkillGenerator were written months ago, tested, and completely unreachable — nothing imported them, and they called Bun.spawn so they could not have run in either shipped mode regardless. The client-bundle guard now walks 23 modules instead of 19, and passes: that increment is the proof they are genuinely reachable and genuinely browser-safe, not merely edited. Filesystem access is injected rather than imported, so the orchestration is testable without a real workspace and the same code serves both runtimes. Three things it deliberately does NOT do: - Read its own output. TOC.md and SKILL.md are excluded from the input, or a second run would summarize the index it wrote on the first and the topic labels would drift toward describing the index rather than the notes. - Process an unbounded workspace. One LLM round trip per note means an unbounded bill and a very long wait; capped at 40. - Truncate silently. When it skips notes it says so — a silent cap reads as "covered everything" when it did not. Tested at both levels: six unit tests against an in-memory workspace with the LLM stubbed in code, and two E2E specs that stub only the /api/llm network boundary so everything above it is real. The second E2E asserts the failure path, because a synthesis that dies quietly is worse than one that refuses. The status region needed an accessible name: two role="status" elements now exist (save state and this), and the spec could not address either.
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.
The last open item — and the only one that adds product surface rather than repairing something.
Flagged before building: its own ticket calls it a deferred go/no-go, and the approved plan scoped it out. The goal said all 24, so it is built. The concern is on the record, not in the way.
What it does
Synthesize reads every note, summarizes each, clusters them by topic, and writes
TOC.mdandSKILL.mdback into the workspace.This connects the last three orphans.
TopicRefiner,TOCGeneratorandSkillGeneratorwere written months ago, tested, and completely unreachable — nothing imported them, and they calledBun.spawnso they could not have run in either shipped mode regardless.The client-bundle guard now walks 23 modules instead of 19 and passes. That increment is the proof they are genuinely reachable and genuinely browser-safe, not merely edited.
Three things it deliberately does not do
Testing
Six unit tests against an in-memory workspace (LLM stubbed in code) and two E2E specs that stub only the
/api/llmnetwork boundary, so everything above it is real. The second asserts the failure path: a synthesis that dies quietly is worse than one that refuses.🤖 Generated with Claude Code
https://claude.ai/code/session_01TYuTJt2hh7k8mg8FXCKrw1