Skip to content

feat: add /understand-knowledge skill for personal knowledge base analysis#80

Open
Lum1104 wants to merge 19 commits intomainfrom
feat/understand-knowledge
Open

feat: add /understand-knowledge skill for personal knowledge base analysis#80
Lum1104 wants to merge 19 commits intomainfrom
feat/understand-knowledge

Conversation

@Lum1104
Copy link
Copy Markdown
Owner

@Lum1104 Lum1104 commented Apr 10, 2026

Summary

  • New /understand-knowledge skill that analyzes markdown knowledge bases (Obsidian, Logseq, Dendron, Foam, Karpathy-style LLM Wiki, Zettelkasten, or plain markdown) and produces interactive knowledge graphs
  • Extended core type system with 5 knowledge node types (article, entity, topic, claim, source) and 6 knowledge edge types (cites, contradicts, builds_on, exemplifies, categorized_under, authored_by)
  • Knowledge-aware dashboard with dedicated sidebar (KnowledgeInfo), article reading panel, knowledge edge styling, and knowledge-specific ProjectOverview stats
  • 5-agent pipeline: knowledge-scannerformat-detectorarticle-analyzerrelationship-buildergraph-reviewer
  • 7 research-backed format guides for auto-detecting and parsing different PKM formats
  • Incremental mode (--ingest) for adding new sources to an existing knowledge graph

Details

Core (packages/core)

  • types.ts: 5 new node types, 6 new edge types, KnowledgeMeta interface, kind field on KnowledgeGraph
  • schema.ts: Zod validation for knowledge types, KnowledgeMetaSchema, 30+ LLM-friendly aliases, kind preserved through validateGraph
  • 8 new tests (398 total passing)

Dashboard (packages/dashboard)

  • KnowledgeInfo.tsx: Knowledge-specific sidebar with 5 node-type-specific views (backlinks, confidence bars, frontmatter display)
  • ReadingPanel.tsx: Slide-up article reader with backlinks sidebar (45vh/70vh toggle)
  • ProjectOverview.tsx: Knowledge stats (articles/entities/topics/claims/sources), detected format badge
  • GraphView.tsx: Knowledge edge styling (dashed for cites, red for contradicts, etc.)
  • CustomNode.tsx + NodeInfo.tsx: Colors, badges, and edge labels for all knowledge types
  • store.ts: Knowledge node/edge categories, view mode, filter state
  • index.css: 5 new CSS color variables

Agents (4 new)

  • knowledge-scanner.md: Finds all .md files, detects directory signatures
  • format-detector.md: Identifies PKM format with priority-based detection
  • article-analyzer.md: Extracts nodes (article/entity/claim/source) and explicit edges per batch
  • relationship-builder.md: Discovers implicit cross-file relationships, builds topic clusters, layers, tours

Skill

  • SKILL.md: 8-phase pipeline (scan → detect → analyze → relationships → assemble → review → save → dashboard)
  • 7 format guides: Obsidian, Logseq, Dendron, Foam, Karpathy, Zettelkasten, Plain

Test plan

  • Core package builds cleanly
  • Dashboard builds cleanly
  • Skill package builds cleanly
  • 398/398 tests pass (including 8 new knowledge schema tests)
  • Run /understand-knowledge on an Obsidian vault to verify end-to-end
  • Run /understand-knowledge on a plain markdown folder
  • Verify dashboard renders knowledge graph with correct node colors and edge styles
  • Verify KnowledgeInfo sidebar shows correct content per node type
  • Verify ReadingPanel opens for article nodes
  • Test --ingest incremental mode

🤖 Generated with Claude Code

Lum1104 and others added 15 commits April 9, 2026 22:56
…se plugin

New skill that takes markdown knowledge bases (Obsidian, Logseq, Dendron, Foam,
Karpathy-style, Zettelkasten, plain) and produces interactive knowledge graphs
with typed nodes/edges, auto-format detection, and dashboard visualization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detailed step-by-step plan covering core type extensions, schema validation,
dashboard changes (CSS, store, sidebar, reading panel, edge styling, layout),
agent definitions, format guides, and skill definition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all design docs to docs/superpowers/specs/ and all implementation
plans to docs/superpowers/plans/ for consistent organization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 5 knowledge node types (article, entity, topic, claim, source),
6 knowledge edge types (cites, contradicts, builds_on, exemplifies,
categorized_under, authored_by), KnowledgeMeta interface, and
kind field on KnowledgeGraph. Update schema validation, dashboard
type maps, and filter categories for full compatibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…comments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… add knowledge schema tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ent type maps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…edge graphs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…wledge-aware ProjectOverview

- Use graphKind-aware layout direction for knowledge graphs (TB)
- Add KNOWLEDGE_EDGE_STYLES map with distinct visual styles for knowledge edge types (cites, contradicts, builds_on, etc.)
- Show knowledge-specific stats (articles, entities, topics, claims, sources) and format badge in ProjectOverview
- Hide Languages/Frameworks sections for knowledge graphs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r, and relationship-builder agents

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pipeline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arsing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dbc17d6399

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

service: "infra", resource: "infra", pipeline: "infra",
table: "data", endpoint: "data", schema: "data",
domain: "domain", flow: "domain", step: "domain",
article: "knowledge", entity: "knowledge", topic: "knowledge", claim: "knowledge", source: "knowledge",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add knowledge node types to layer visibility whitelist

This adds knowledge node categories here, but useLayerDetailTopology still gates rendering through an allVisibleTypes set that only contains code/domain node names; the subsequent if (!allVisibleTypes.has(n.type)) return false filter drops article/entity/topic/claim/source nodes entirely. In a kind: "knowledge" graph, drilling into a layer can therefore render an empty layer topology even though nodes exist.

Useful? React with 👍 / 👎.

interacts_with: "cross_domain",
// Knowledge aliases
references: "cites",
cited_by: "cites",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Drop cited_by alias unless direction is reversed

Aliasing cited_by to cites rewrites only the type string and keeps source/target unchanged, so an extracted edge like A cited_by B becomes A cites B, which inverts the relationship semantics. This can silently corrupt knowledge graphs generated from natural-language edge labels, especially because no direction correction is applied during normalization.

Useful? React with 👍 / 👎.


const graph = {
version: typeof fixed.version === "string" ? fixed.version : "1.0.0",
kind: fixed.kind as "codebase" | "knowledge" | undefined,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate graph kind instead of type-asserting input

validateGraph now copies fixed.kind via a TypeScript cast without runtime validation, so invalid strings can pass through as data.kind. Since the dashboard switches behavior on graph.kind === "knowledge", malformed values silently disable knowledge-specific UI instead of being rejected or corrected.

Useful? React with 👍 / 👎.

@Lum1104
Copy link
Copy Markdown
Owner Author

Lum1104 commented Apr 11, 2026

Code review

Reviewed by five expert personas: Anthropic Claude Code Plugin Architect, OpenAI Codex Senior Reviewer, Obsidian Core Team Engineer, Anthropic API Platform Engineer, and Senior Knowledge Graph Researcher. Found 7 issues:

  1. cited_by alias silently inverts edge direction -- cited_by: "cites" rewrites only the type string without swapping source/target, so A cited_by B becomes A cites B (opposite meaning). The codebase already warns about this exact pattern: "implemented_by" is intentionally NOT aliased to "implements" -- it inverts edge direction (see commit fd0df15). Same applies to sourced_from: "cites".

references: "cites",
cited_by: "cites",
sourced_from: "cites",

// Note: "implemented_by" is intentionally NOT aliased to "implements" —
// it inverts edge direction (see commit fd0df15). The LLM should use
// "implements" with correct source/target instead.

  1. allVisibleTypes missing knowledge node types -- The 5 knowledge types (article, entity, topic, claim, source) are added to NODE_TYPE_TO_CATEGORY but not to the allVisibleTypes whitelist in useLayerDetailTopology(). The filter at line 275 (if (!allVisibleTypes.has(n.type)) return false) will silently drop all knowledge nodes in layer detail view.

const subFileTypes = new Set(["function", "class"]);
const allVisibleTypes = new Set([
"file", "module", "concept",
"config", "document", "service", "table",
"endpoint", "pipeline", "schema", "resource",
"domain", "flow", "step",
"function", "class",
]);
let filteredGraphNodes = graph.nodes.filter((n) => {
if (!expandedLayerNodeIds.has(n.id)) return false;
if (!allVisibleTypes.has(n.type)) return false;
if (persona === "non-technical" && subFileTypes.has(n.type)) return false;

  1. Agent edge output uses wrong field names -- article-analyzer.md and relationship-builder.md instruct the LLM to output edgeType and label, but GraphEdge requires type and description. The normalize-graph code reads raw.type, so agent-produced edges will have undefined type fields.

- `source` (string): Source node ID
- `target` (string): Target node ID
- `edgeType` (string): One of `related`, `categorized_under`, `cites`, `authored_by`, `contains`
- `label` (string): Human-readable label (e.g., `"links to"`, `"cites"`, `"authored by"`)
- `weight` (number): As specified in the table above

  1. Agent uses invalid "trivial" complexity value -- article-analyzer.md instructs LLMs to produce complexity: "trivial" for short articles. The schema only allows z.enum(["simple", "moderate", "complex"]) and "trivial" is not in the complexity alias map. Nodes will fail validation.

| `tags` | Array of tags extracted from frontmatter `tags` field, inline `#tag` syntax, or empty array |
| `complexity` | `trivial` if < 20 lines, `simple` if 20-100, `moderate` if 101-300, `complex` if > 300 |
| `knowledgeMeta` | `{ nodeType: "article" }` |

  1. Agent layer output missing required description field -- relationship-builder.md layer JSON example (line 88-93) omits the description field required by LayerSchema. Layers will fail Zod validation and be silently dropped.

```json
{
"id": "layer-<topic-name>",
"name": "<Topic Name>",
"nodeIds": ["article:...", "entity:...", "claim:..."]
}

  1. paper aliased to entity instead of source -- In PKM/academic contexts, a paper is a citable source. Other aliases (reference, citation, bibliography) correctly map to "source", but paper maps to "entity", which will misclassify papers alongside people/organizations.

tool: "entity",
paper: "entity",
organization: "entity",
org: "entity",

  1. strokeDasharray guard breaks knowledge edge selection highlighting -- The guard at line 500 skips selection styling for any edge with strokeDasharray. Three knowledge edge types (cites, authored_by, exemplifies) use strokeDasharray in KNOWLEDGE_EDGE_STYLES, so they will never receive selection highlighting or fade-out dimming.

const isSelectedEdge = edge.source === selectedNodeId || edge.target === selectedNodeId;
// Don't restyle diff-impacted or portal edges
if ((edge.style as Record<string, unknown>)?.strokeDasharray) return edge;
if (isSelectedEdge) {
return { ...edge, animated: true, style: { stroke: "rgba(212,165,116,0.8)", strokeWidth: 2.5 }, labelStyle: { fill: "#d4a574", fontSize: 11, fontWeight: 600 } };
}

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

Lum1104 and others added 3 commits April 11, 2026 15:20
…d kind validation

Remove cited_by/sourced_from aliases that silently invert edge semantics
without swapping source/target. Reclassify paper from entity to source
to match other academic aliases (reference, citation, bibliography).
Replace bare type-assertion of graph.kind with runtime validation that
rejects invalid values and logs an auto-corrected issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dge selection guard

Add article/entity/topic/claim/source to allVisibleTypes so knowledge
nodes are not silently dropped in layer detail view. Replace the
strokeDasharray guard with a portal-specific check so knowledge edges
using dashed strokes still receive selection highlighting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nd TourStep types

Rename edgeType→type and label→description to match GraphEdgeSchema.
Replace invalid trivial complexity with simple. Add required description
field to layer examples and required complexity to entity/claim/source/
topic node specs. Fix tour step format to use order + nodeIds array
instead of singular nodeId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Lum1104
Copy link
Copy Markdown
Owner Author

Lum1104 commented Apr 11, 2026

@codex review this

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f4878f3e18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +318 to +319
{selectedNodeId && graph?.kind === "knowledge" && <KnowledgeInfo />}
{selectedNodeId && graph?.kind !== "knowledge" && <NodeInfo />}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use active view to choose the node details sidebar

When a node is selected, this branch renders KnowledgeInfo solely from graph.kind === "knowledge", but KnowledgeInfo resolves nodes from graph only. In the domain view (when domainGraph is present), selected IDs come from the domain graph, so the sidebar can’t resolve the node and shows an empty state instead of details. This breaks node inspection for that view; the sidebar selection should also account for viewMode.

Useful? React with 👍 / 👎.

Comment on lines +352 to +354
.filter((e) => e.type === "categorized_under" && e.target === node.id)
.map((e) => graph?.nodes.find((n) => n.id === e.source))
.filter((n): n is GraphNode => n !== undefined);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Filter topic members to article nodes

The Articles section for topic nodes currently includes every categorized_under source node without validating its type. Because categorized_under can connect non-article nodes too, this view can count and display entities/other types as articles, which makes the sidebar labels and counts inaccurate. Restrict this list to n.type === "article" (or relabel it to a generic membership list).

Useful? React with 👍 / 👎.

…ode, filter topic articles

- KnowledgeInfo now resolves nodes from activeGraph (respecting viewMode/
  domainGraph) instead of graph directly, fixing empty sidebar in domain view
- setGraph sets viewMode to "knowledge" when graph.kind is "knowledge"
- Topic "Articles" section filters to type === "article" only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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