# How to Extend Lum1104/Understand-Anything Functionality: Core, Dashboard, and CLI

> Learn to extend Lum1104/Understand-Anything functionality by adding extractors agents dashboard utilities and CLI commands without altering unrelated packages.

- Repository: [Yuxiang Lin/Understand-Anything](https://github.com/Lum1104/Understand-Anything)
- Tags: how-to-guide
- Published: 2026-06-07

---

**You can extend Lum1104/Understand-Anything functionality by adding language extractors to the core plugin system, registering new analysis agents in the graph pipeline, surfacing data in the dashboard utilities, and exposing commands through skill wrappers—without touching unrelated packages.**

The `Lum1104/Understand-Anything` repository is a modular TypeScript monorepo that isolates its static-analysis engine, interactive UI, and CLI skill definitions into separate workspaces. Because each layer communicates through strict interfaces, you can safely extend Lum1104/Understand-Anything functionality without destabilizing existing code. Below is a complete walkthrough of the primary extension points, with exact source files and working code examples.

## Add a New Language Extractor to the Core

The `@understand-anything/core` package defines a plugin system for language-specific extractors. Every extractor implements the `BaseExtractor` interface located in [`packages/core/src/plugins/extractors/base-extractor.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/extractors/base-extractor.ts), and the pipeline discovers them through the registry at [`packages/core/src/plugins/registry.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/registry.ts).

### Implement the BaseExtractor Interface

Create a new file in `packages/core/src/plugins/extractors/` that extends the base class and implements the `extract` method using Tree-sitter parsing:

```ts
// packages/core/src/plugins/extractors/my-language-extractor.ts
import { BaseExtractor } from './base-extractor';
import { Language } from '../../languages/types';

export class MyLanguageExtractor extends BaseExtractor {
  static language: Language = 'myLang';

  async extract(source: string) {
    // Use web-tree-sitter to parse the file and return nodes
    const tree = await this.parser.parse(source);
    // …extract functions, classes, imports, etc.
    return this.formatResult(tree);
  }
}

```

### Register the Extractor in the Plugin Registry

Add the new extractor to the barrel export so the `project-scanner` → `file-analyzer` → `architecture-analyzer` pipeline can discover it automatically:

```ts
// packages/core/src/plugins/extractors/index.ts
export * from './typescript-extractor';
export * from './rust-extractor';
export * from './my-language-extractor';   // ← add your extractor here

```

Because [`packages/core/src/plugins/registry.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/registry.ts) consumes this index, no additional wiring is required once the export is present.

## Add a New Analysis Agent to the Pipeline

Analysis agents are TypeScript classes that implement a `run(context)` method and are invoked from command entry points such as [`understand-anything-plugin/src/understand-chat.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/understand-anything-plugin/src/understand-chat.ts) and [`src/diff-analyzer.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/src/diff-analyzer.ts). You can introduce a new analysis step—such as a dependency-risk analyzer—without altering existing agents.

### Create a New Analyzer Class

Place the new agent in `packages/core/src/analyzer/`. It should expose a `run` method that mutates or enriches the `KnowledgeGraph`:

```ts
// packages/core/src/analyzer/risk-analyzer.ts
export class RiskAnalyzer {
  async run(graph: KnowledgeGraph) {
    // Walk the graph, compute risk scores, add `risk` property to nodes
    for (const node of graph.nodes) {
      node.risk = this.computeRisk(node);
    }
    return graph;
  }

  private computeRisk(node: Node): number {
    // simple heuristic: high-fan-out + external imports = higher risk
    const external = node.imports?.filter(i => i.isExternal).length ?? 0;
    return node.outEdges?.length * external;
  }
}

```

### Hook the Agent into GraphBuilder

The `GraphBuilder` orchestrator at [`packages/core/src/analyzer/graph-builder.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/analyzer/graph-builder.ts) runs agents sequentially. Import your analyzer and append it to the build sequence:

```ts
// packages/core/src/analyzer/graph-builder.ts
import { RiskAnalyzer } from './risk-analyzer';

export class GraphBuilder {
  async build(...args: any[]) {
    // existing agents…
    await new ArchitectureAnalyzer().run(graph);
    await new TourBuilder().run(graph);

    // 👇 new step
    await new RiskAnalyzer().run(graph);
    return graph;
  }
}

```

Export the new analyzer from [`packages/core/src/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/index.ts) if other packages need to import it directly.

## Expose New Data in the Dashboard

The dashboard consumes only the browser-safe export sub-paths from core (`./search`, `./types`, `./schema`). Because the knowledge graph is serialized to [`.understand-anything/knowledge-graph.json`](https://github.com/Lum1104/Understand-Anything/blob/main/.understand-anything/knowledge-graph.json), new fields like `risk` are already available in the UI payload without any core changes.

### Style Nodes Using Dashboard Utilities

To visualize the new data, add a utility in [`packages/dashboard/src/utils/layerStats.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/dashboard/src/utils/layerStats.ts) or create a new component in `packages/dashboard/src/components/`:

```ts
// packages/dashboard/src/utils/layerStats.ts
export function getRiskColor(risk: number): string {
  if (risk > 50) return '#d9534f';   // red
  if (risk > 20) return '#f0ad4e';   // orange
  return '#5cb85c';                  // green
}

```

Then reference the helper when rendering graph nodes:

```tsx
// packages/dashboard/src/components/GraphNode.tsx
const color = getRiskColor(node.risk ?? 0);
return <circle fill={color} />;

```

## Add a New CLI Skill Command

Skills are thin wrappers that expose agents as `/understand-<name>` CLI commands. To surface a new feature such as `/understand-risk`:

### Build a Skill Wrapper

Add a new file in `src/` that imports the core analyzer and runs it:

```ts
// src/risk-builder.ts
import { RiskAnalyzer } from '@understand-anything/core/analyzer/risk-analyzer';
import { GraphBuilder } from '@understand-anything/core/analyzer/graph-builder';

export async function runRisk(context: any) {
  const graph = await GraphBuilder.build(context);
  await new RiskAnalyzer().run(graph);
  console.log('Risk analysis completed.');
}

```

### Register the Command Entry Point

Export the wrapper from [`src/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/src/index.ts) so the CLI can discover and mount the command:

```ts
// src/index.ts
export * from './risk-builder';   // ← expose the command

```

After rebuilding and reinstalling the plugin, users can invoke `/understand-risk` from any supported platform.

## Test Your Extensions with Vitest

All core functionality is covered by tests under `packages/core/src/__tests__/`. Add a unit test for every new extractor or agent:

```ts
// packages/core/src/__tests__/risk-analyzer.test.ts
import { RiskAnalyzer } from '../analyzer/risk-analyzer';
import { mockGraph } from './mocks';

test('risk scores are computed', async () => {
  const graph = mockGraph();
  await new RiskAnalyzer().run(graph);
  expect(graph.nodes[0].risk).toBeGreaterThan(0);
});

```

Run the suite scoped to the core package:

```bash
pnpm --filter @understand-anything/core test

```

After tests pass, build the core package:

```bash
pnpm --filter @understand-anything/core build

```

Reinstall the plugin to activate the new functionality.

## Summary

- **Language extractors** must implement `BaseExtractor` in `packages/core/src/plugins/extractors/` and be exported from [`packages/core/src/plugins/extractors/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/extractors/index.ts) to be picked up by the registry at [`packages/core/src/plugins/registry.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/registry.ts).
- **Analysis agents** are classes with a `run` method that you place in `packages/core/src/analyzer/` and invoke from [`packages/core/src/analyzer/graph-builder.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/analyzer/graph-builder.ts).
- **Dashboard visualizations** consume the existing JSON payload; add styling logic in [`packages/dashboard/src/utils/layerStats.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/dashboard/src/utils/layerStats.ts) or new components in `src/components/`.
- **CLI commands** are added by creating a skill wrapper in `src/` and exporting it from [`src/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/src/index.ts).
- **Tests** live in `packages/core/src/__tests__/` and are executed with `pnpm --filter @understand-anything/core test`.

## Frequently Asked Questions

### How do I register a new language extractor so the scanner finds it automatically?

Export the extractor class from [`packages/core/src/plugins/extractors/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/extractors/index.ts). The plugin registry at [`packages/core/src/plugins/registry.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/plugins/registry.ts) discovers all registered extractors through that barrel file, so no manual list update is needed beyond the export.

### Can I add a new analysis step without modifying existing agents?

Yes. Create a new analyzer class in `packages/core/src/analyzer/`, implement its `run` method, then import and invoke it inside [`packages/core/src/analyzer/graph-builder.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/analyzer/graph-builder.ts) after the existing steps. Existing analyzers such as `ArchitectureAnalyzer` and `TourBuilder` remain untouched.

### Does the dashboard require core changes to display new graph properties?

No. The dashboard reads from [`.understand-anything/knowledge-graph.json`](https://github.com/Lum1104/Understand-Anything/blob/main/.understand-anything/knowledge-graph.json), so any property you attach to graph nodes in the core pipeline is already available in the UI. You only need to update dashboard utilities such as [`packages/dashboard/src/utils/layerStats.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/dashboard/src/utils/layerStats.ts) to style or format the new data.

### How do I expose a new feature as a CLI command?

Wrap the core logic in a TypeScript file under `src/` (for example, [`src/risk-builder.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/src/risk-builder.ts)), then re-export it from [`src/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/src/index.ts). The skill system surfaces any exported wrapper as a `/understand-<name>` command automatically.