Add repository-declared diff file categories - #155
Merged
Merged
Conversation
Add the bounded category model and validation, an owned TreemonConfig reader, and focused schema tests.
…tion Implemented bounded glob matching, depth-first classification, stable grouping, and focused tests.
…y responses Carry category paths and categorization state through diff summary responses, with endpoint coverage.
…mary request Resolve repository configuration from each diff request and add coverage for linked worktrees, configuration edits, and unknown worktrees.
Render configured category hierarchies with counts, fallback states, warnings, and DiffViewer coverage.
…egory toggles Compute category disclosure defaults, preserve page-instance toggles, and add end-to-end coverage.
Add the embedded diff configure action, shared invalid-warning action, routing request, and E2E coverage.
…ction Integrate nested category disclosure with file selection, patch cancellation, and visible-row keyboard navigation, with E2E coverage and spec updates.
… handling in DiffCategories Collapse repeated stars and add literal and fixed-depth matcher fast paths with regression coverage and spec documentation.
…ategories validation Reject oversized sibling arrays before duplicate-name validation, enforce trimmed category names at 100 characters, and document and test both bounds.
…e validator's constants Expose the schema constants internally and add a viewer template contract test plus the spec note.
Add DiffSummaryTarget to keep summary comparison context and categorization paired through the request handler.
…on resumes a session Clarify that configure routing starts or queues a session when needed and align the viewer comment with startup terminology.
…lf-hosted asset files Move the diff viewer stylesheet and script into embedded self-hosted assets, serve them with revalidation policies, and update documentation and tests.
Remove the completed DiffTemplate asset extraction from the remaining WorktreeDiff refactoring idea.
…iffEndpointTests.fs Extract shared diff-endpoint scaffolding and categorization test modules into dedicated files, registering them before DiffEndpointTests.fs.
…erTests.fs Extract shared viewer harness code and category-specific E2E tests into focused test files.
…ndpointTests Simplify fixture default insertion and document the locally owned JsonNode mutation.
…ion withRepository helper
…lper in DiffViewerTests Add DiffViewerHarness.RouteSummaries, replace duplicated route callbacks, and document verification coverage.
…tion Drop the unnecessary summary request counter and wait from the late patch response category test.
Exercise the real path end to end: a temp Git repo, a repository-root .treemon.json, WorktreeDiffApi.liveService with real git subprocesses, a Kestrel canvas host on a free loopback port, and a real Chromium page. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a5c0840d-68c2-4631-8efa-3747509be31a
The action posted a fire-and-forget canvas message: no feedback, re-clickable, and the new grouping only appeared if the user pressed Refresh. The control now disables itself and shows a spinner while the request is outstanding, shared by its toolbar and warning copies. Completion is resolved by watching the repository's categorization rather than the agent, since an agent can end its turn without writing anything: diff-categorization serves the categorization alone, reading and validating .treemon.json with no Git call, so polling costs a file read instead of a diff. A revision derived from the validated outline detects a rewrite that leaves the status configured, which a status alone cannot, while ignoring reformatting. One serializer produces the block for both the summary and the new route. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a5c0840d-68c2-4631-8efa-3747509be31a
…the CLI Add the tm categories command, diff-category report API, coverage helpers, tests, and documentation.
Clarify that existing diff behavior is unchanged and document tracked-file enumeration.
…r and self-verification Clarify category display ordering, require tm categories verification, update the spec decision, and pin the prompt behavior in tests.
Flatten category chains before rendering, preserve collapse state, and document and test the behavior.
Aggregate changed-line totals across category subtrees, render them on category headers, and cover the behavior with focused tests.
0101
enabled auto-merge (squash)
July 29, 2026 10:20
0101
disabled auto-merge
July 29, 2026 10:21
There was a problem hiding this comment.
Pull request overview
Adds repository-defined categories to organize worktree diffs while preserving flat-list behavior when unconfigured.
Changes:
- Adds validated nested category configuration, glob matching, reporting API, and CLI command.
- Adds categorized viewer rendering, disclosure state, and agent-assisted configuration.
- Extracts viewer assets and adds broad unit/E2E coverage and documentation.
Show a summary per file
| File | Description |
|---|---|
src/Server/DiffCategories.fs |
Validates, matches, orders, and reports categories. |
src/Server/TreemonConfig.fs |
Reads category configuration. |
src/Server/WorktreeDiffApi.fs |
Classifies summaries and exposes categorization. |
src/Server/WorktreeDiff.fs |
Enumerates tracked files. |
src/Server/WorktreeApi.fs |
Builds category coverage reports. |
src/Server/RefreshScheduler.fs |
Resolves owning repositories. |
src/Server/CanvasDocServer.fs |
Routes category-aware diff requests. |
src/Server/DiffAssets.fs |
Serves extracted viewer assets. |
src/Server/DiffTemplate.html |
Becomes the viewer shell. |
src/Server/Assets/diff/viewer.js |
Implements category UI and configuration flow. |
src/Server/Assets/diff/viewer.css |
Styles categories and warnings. |
src/Server/Server.fsproj |
Registers sources and embedded assets. |
src/Shared/Types.fs |
Adds category wire/report types. |
src/Shared/WorktreeApi.fs |
Adds the report API operation. |
src/Cli/Program.fs |
Adds tm categories. |
src/Tests/Tests.fsproj |
Registers new test modules. |
src/Tests/DiffCategoriesTests.fs |
Tests validation, matching, and coverage. |
src/Tests/DiffCategoryTests.fs |
Tests category viewer behavior. |
src/Tests/DiffCategoryEndToEndTests.fs |
Tests the live repository/viewer path. |
src/Tests/DiffEndpointCategorizationTests.fs |
Tests category endpoint integration. |
src/Tests/DiffEndpointTestHelpers.fs |
Shares endpoint fixtures. |
src/Tests/DiffEndpointTests.fs |
Updates endpoint serialization coverage. |
src/Tests/DiffViewerTestHarness.fs |
Shares viewer routing fixtures. |
src/Tests/DiffViewerTests.fs |
Updates viewer and asset tests. |
src/Tests/CliTests.fs |
Tests category report formatting. |
src/Tests/CanvasDocServerTests.fs |
Tests owning-repository resolution. |
src/Tests/CreateWorktreeTests.fs |
Updates API stubs. |
README.md |
Documents the CLI command. |
docs/spec/diff-file-categories.md |
Specifies category behavior and architecture. |
docs/spec/worktree-diff-viewer.md |
Integrates categories into viewer behavior. |
docs/spec/worktree-monitor.md |
Documents repository-level configuration. |
docs/spec/future/code-improvements.md |
Updates the remaining refactoring item. |
Review details
- Files reviewed: 32/32 changed files
- Comments generated: 4
- Review effort level: Medium
Bound the total pattern text a repository may declare, so a valid configuration cannot make one summary's classification cost minutes: 10,000 patterns against the 1,000-file cap measured 405 s, and 5,000 pattern characters holds the same worst case to 1.2 s. Length-prefix names and patterns in the categorization revision, so a name or pattern containing the punctuation between them cannot make two different outlines encode alike and hide a rewrite from the poller. Require a viewer instance and an empty query on diff-categorization, which the endpoint contract already stated for all three routes. Capture the configure wait's baseline revision before dispatching the request rather than on the first poll, so a configuration written within the poll interval is still seen as a change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 40e14c86-fbe3-41f9-836b-4bce07eb7c9a
0101
added a commit
that referenced
this pull request
Jul 29, 2026
Treemon's mechanical sync conflicted and aborted; resolved by hand. main added repository-declared diff categories (#155) and consolidated the dashboard font sizes (#156) while this branch moved the scheduler state slice into SchedulerState and reshaped worktreeApi's dependencies, so the two collided on five files: - WorktreeApi: kept both sides - main's diffCategoryReport helper and this branch's WorktreeApiDependencies record. The record already carries AutoSyncStore, which main's positional signature did not have. - CanvasDocServer: took main's resolveDiffTarget (it replaces the older getDiffComparisonContext) and retyped it to SchedulerState.StateMsg, dropping the stale duplicate resolver body this branch still had. - DiffEndpointTests: took main's deletion - those helpers now live in the new DiffEndpointTestHelpers.fs. This branch's only edits there were the module rename, which is reapplied below. - CanvasDocServerTests: kept main's new repoId binding with this branch's SchedulerState.createAgent. - worktree-monitor.md: kept this branch's GitWorktree/GitBranchSync rows and took main's TreemonConfig row, which now names the diffCategories read. main's new files still referenced RefreshScheduler for the state members this branch moved, so DiffEndpointTestHelpers.fs, DiffCategoryEndToEndTests.fs and one WorktreeApi call site were repointed at SchedulerState. Server, client and tests build clean; fast suite 1878 passed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80f775f5-e421-45b9-acac-d4f981b3f691
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.
Problem
A large branch diff opens in the worktree diff viewer as one flat accordion of files. There is no way for a repository to say which files matter most, so a reviewer scrolls a mixed list of production code, tests, docs, and instruction files with no architectural shape and no cue about where the substance of a change lives.
Changes
Adds an optional, repository-declared categorization of changed files. Everything is additive — a repository without configuration keeps today's flat list.
Configuration (
src/Server/DiffCategories.fs,src/Server/TreemonConfig.fs)diffCategoriesarray in the repo-root.treemon.json, shared by every linked worktree alongsidebaseBranch/upstreamRemote.nameplus exactly one ofpatterns(leaf) orchildren(branch). Validation enforces sibling-name uniqueness, max depth 4, at most 200 nodes, 50 patterns per leaf, and name/pattern length bounds, and reserves the top-level nameOther.Missing,Invalid, orConfigured.Invalidrenders the flat list plus a bounded, non-blocking warning that never leaks a path, raw JSON, or exception text.Matching
?,*within a segment,**across segments — matched ordinally against the whole repo-relative path. Repository text is never compiled as a regex.a***borsrc/**/**costs pattern length times input length. Literal and fixed-depth patterns short-circuit to an ordinal comparison.Othergroup.Presentation (
src/Server/Assets/diff/viewer.js,viewer.css)aria-expanded, a subtree file count, and aggregated+X/−Yline stats rendered like a file row's own stats.Parent > Child, at any depth.Configure action (
src/Server/CanvasDocServer.fs,src/Server/WorktreeDiffApi.fs)configure-diff-categoriesmessage through the SystemView canvas transport to the worktree's agent session, reusing existing routing, waiting, and delivery-error banners. Not rendered in a standalone diff tab or without a transport.diff.htmlstays byte-identical across repositories. A unit test pins its stated depth bound and reserved name toDiffCategories.maxDepthandDiffCategories.reservedTopLevelNameso prose and validator cannot drift.CLI (
src/Cli/Program.fs)tm categories [path]reports every declared leaf as its full path with the number of tracked files that classify into it, flags leaves matching zero files, and reports the unmatched count.MissingandInvalidexit non-zero so it works as a check; category names are stripped of control characters before printing.Refactors carried along
DiffTemplate.htmlshrinks from ~1,400 lines to a shell by extracting its CSS and JS into self-hosted assets served throughDiffAssets.DiffSummaryTarget, so a context and categorization from two repositories are not representable.DiffEndpointTests.fsandDiffViewerTests.fsinto shared helper modules.Docs
docs/spec/diff-file-categories.md; updates toworktree-diff-viewer.md,worktree-monitor.md,future/code-improvements.md, andREADME.md.Tests
dotnet test src/Tests/Tests.fsproj --filter "Category=Fast"— 1808 passed, 0 failed (3m31s).New coverage:
DiffCategoriesTests.fs(schema, bounds, glob matcher),DiffCategoryTests.fs(viewer rendering, disclosure, flattening, line stats),DiffCategoryEndToEndTests.fs,DiffEndpointCategorizationTests.fs, andtm categoriescases inCliTests.fs.