- Re-export NODE_WIDTH/NODE_HEIGHT from utils/layout.ts as the
fallback dimensions in elk-layout.ts. Coupling them with the dagre/
force defaults prevents silent drift during the migration.
- Declare optional x/y on ElkChild so downstream consumers (Tasks 9-12)
see the position contract in the type. Comment notes ELK sets them
on output but they're absent on input.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Length-prefix the inter-container bucket key to eliminate collision
risk when container ids contain the separator (e.g. folder names with
spaces). Adds a regression test.
- Rename AggregatedContainerEdge.types -> edgeTypes for symmetry with
the existing LayerEdgeAggregation.edgeTypes field.
- Drop the as-cast in the test helper by giving it the real EdgeType
literal type and a complete object shape.
- Reword the JSDoc to match what the function actually does (silently
drop unmapped endpoints; callers needing strict can pre-filter).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- louvain.ts: rewrite the misleading "disconnected nodes get -1" comment
(the library actually assigns unique ids; the reassignment loop is a
defensive net for future API drift).
- containers.test.ts: add tags:[] to the test node helper for shape
fidelity; replace the vacuously-true "every is community" assertion
with one that actually fails if the community fallback regresses.
- containers.ts: collapse the two-pass groupByFolder into a single
branching loop; guard Cluster A-Z naming so it doesn't wrap into
punctuation past 26 communities.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task 2 implementation surfaced inconsistencies between the spec/plan
and the actual codebase:
- The real type exports are GraphNode / GraphEdge, not KnowledgeGraph*
- Folder grouping uses bucket count (folders + rooted) not just folder
count, with threshold < 2 instead of < 3
- Concentration threshold is > 70% (was > 60%) so 2/3 distributions
stay in folder mode
- Single-child suppression is gated by layer total ≥ 3 to avoid
emptying tiny layers
- Removed the "layer < 8 → flat" rule; the algorithm is now uniform
and small layers fall through naturally via single-child suppression
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review flagged that without it as a direct dep, TypeScript would
fail to resolve types like Attributes/NodeKey from transitive
graphology-types when later tasks import them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Design doc for replacing dagre with ELK across structural views, plus
folder/community-based containers and lazy two-stage layout for the
layer-detail view to fix horizontal sprawl at 50+ nodes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #108 ships a new user-visible feature (in-dashboard source code viewer
with Files tab + double-click navigation), so it warrants a minor bump
across all 5 version-tracked files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Double-clicking a file in the Files tab previously only opened the source
viewer; the graph stayed wherever it was. Now also calls navigateToNode
first (drills into the layer + selects the node), then re-opens the code
viewer so the source panel stays visible.
Order matters: navigateToNodeInLayer resets codeViewerOpen, so the
openCodeViewer call has to come after.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two issues from review of #108:
1. Sidebar exclusivity regression — replacing the entire sidebar with the
CodeViewer when codeViewerOpen hid NodeInfo / LearnPanel / ProjectOverview
while reading source. Same pattern that was rejected in #50. Restore the
slide-up bottom overlay (per CLAUDE.md), keep sidebar tabs always visible,
and revert the <aside> overflow-hidden change so long content can scroll.
2. Cross-graph mismatch (Codex P1) — FileExplorer always builds its tree from
the structural graph and emits structural node IDs, but CodeViewer resolved
IDs against the domain graph in domain mode, yielding "No file selected".
Fall back to the structural graph when the active graph misses, so the
Files tab works regardless of viewMode.
Also update CLAUDE.md to describe the Files tab + modal expand behavior so
future Claude sessions don't re-introduce the slide-up regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hook echo commands referenced \${PLUGIN_DIR}, which Claude Code does not
inject into hook commands. The documented variable is \${CLAUDE_PLUGIN_ROOT}
(used elsewhere in skills/understand/SKILL.md and friends). Also switched
the surrounding single quotes to double quotes so the variable actually
expands at runtime instead of being passed literally.
Without this fix, the auto-update hook silently sent Claude a non-existent
file path, so the knowledge graph never incrementally updated even when
autoUpdate: true was configured.
Builds on the direction identified in #96; closes#96.
Co-Authored-By: xiaolai <lixiaolai@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The homepage Hero component referenced `/images/hero.png`, but the
actual asset shipped at `homepage/public/images/hero.jpg`. As a result,
https://understand-anything.com/images/hero.png returned HTTP 404 and
the hero background failed to load.
修复:把 homepage/src/components/Hero.astro:7 的 /images/hero.png 改成
/images/hero.jpg,与仓库中实际存在的 homepage/public/images/hero.jpg
对齐,消除站点首页的 404。
Repro:
curl -sI https://understand-anything.com/images/hero.png
# HTTP/2 404
Root cause:
homepage/src/components/Hero.astro:7
<img src="/images/hero.png" ... /> # file does not exist
homepage/public/images/
hero.jpg (182179 bytes) # actual file shipped
Fix:
Single-line: .png -> .jpg in Hero.astro:7. Asset already published,
no binary changes needed. After Pages rebuild, /images/hero.jpg
resolves with HTTP 200.
Bumps all five version-carrying manifests to 2.3.2, bringing
.copilot-plugin/plugin.json back in sync (was stuck at 2.2.0), and
updates CLAUDE.md to reflect the true set of files that must move
together: the nested understand-anything-plugin/.claude-plugin/plugin.json
and .copilot-plugin/plugin.json were missing, and marketplace.json was
incorrectly listed (its plugins[] entry does not support a version field).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a collapsed "Subscribe to release updates" disclosure below the
Hero CTA row. Default state preserves the existing dark-luxury layout;
clicking expands the Substack embed iframe in place. Uses native
<details> to avoid runtime JS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Silent pass on re.error hid invalid .gitignore patterns from users,
making it impossible to diagnose unexpected file-exclusion behavior.
Now logs a warning to stderr so users can see which patterns were
skipped and why.
Co-Authored-By: Claude Code <noreply@anthropic.com>
echo interprets escape sequences and flags (e.g. -e, -n) in some
shells, which can corrupt or truncate the hook event JSON before it
reaches grep. printf '%s' passes the value as a plain string with
no interpretation, eliminating any risk of mishandled special chars.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Split the single 770 kB dashboard bundle into named vendor chunks and
lazy-load optional views so the initial JS payload is smaller and stays
under Vite's 500 kB warning threshold.
- vite manualChunks: react-vendor, xyflow, graph-layout, markdown
- React.lazy for CodeViewer, LearnPanel, PathFinderModal, KeyboardShortcutsHelp
- PathFinderModal now only mounts while open (was always mounted)
Before: index 769.80 kB (gzip 235.12 kB), chunks-too-large warning.
After: index 205 kB + split vendor/lazy chunks, warning gone.
Fixes#86
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the /Understand-Anything subpath and retargets the site at the
apex custom domain served through GitHub Pages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lockfile was missing entries for tree-sitter language parsers
(c-sharp, cpp, go, java, php, python, ruby, rust) that were already
declared in packages/core/package.json.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>