Skip to content

Repository files navigation

kaying-filetree

CI npm License: MIT

English · 简体中文

A file tree + code preview Web Component built for custom AI agent interfaces, fully benchmarked against the right-side file preview panel in ChatGPT Codex.

Designed around the agent workflow: present a browsable project structure on one side and rich file previews on the other, so your agent can show, explain, and let users inspect code, configs, images, and more — directly inside the conversation.

Live Demo

kaying-filetree screenshot

Built for agents

  • Codex-style side panel — draggable split view with the file tree on the right and the preview on the left, just like ChatGPT Codex.
  • Agent-native interactions — copy selection, add to agent, Google search, plus an extensible context menu for custom agent actions.
  • No framework lock-in — standard Web Component with Shadow DOM; drops into React, Vue, Svelte, Angular, or vanilla HTML.
  • Rich file preview — syntax highlighting via Shiki, line numbers, breadcrumbs, image preview, and file metadata.
  • Rendered markdown — Markdown files are rendered to a styled preview (headings, tables, blockquotes, code blocks highlighted with Shiki) with a one-click Preview / Source toggle.
  • Production-grade tree — virtual scrolling, search/filter, keyboard navigation, 50+ file-type icons, and Git status indicators.
  • Theme aware — light, dark, or system mode via --trees-* CSS variables.

Installation

npm install @kayingai/kaying-filetree
# or
pnpm add @kayingai/kaying-filetree
# or
yarn add @kayingai/kaying-filetree

Quick Start

Vanilla HTML

<script type="module">
  import '@kayingai/kaying-filetree';
</script>

<agent-file-explorer
  id="explorer"
  theme="dark"
  shiki-theme="github-dark"
  style="width: 100%; height: 100vh;"
></agent-file-explorer>

<script type="module">
  const explorer = document.getElementById('explorer');

  explorer.tree = {
    id: 'root',
    name: 'project',
    path: '/project',
    isDirectory: true,
    children: [
      {
        id: 'src/index.ts',
        name: 'index.ts',
        path: '/project/src/index.ts',
        isDirectory: false,
      },
    ],
  };

  explorer.addEventListener('agent-file-open', (e) => {
    const { path, node } = e.detail;
    // load file content from your backend / filesystem
    const content = `// content of ${node.name}`;
    explorer.setFileContent(node.name, content, null, path, content.length);
  });
</script>

React

import '@kayingai/kaying-filetree';
import { useRef, useEffect } from 'react';

function FileExplorer({ tree }) {
  const ref = useRef(null);

  useEffect(() => {
    if (!ref.current) return;
    ref.current.tree = tree;
    ref.current.addEventListener('agent-file-open', (e) => {
      const { node, path } = e.detail;
      // load content
      ref.current.setFileContent(node.name, '// content', null, path, 10);
    });
  }, [tree]);

  return (
    <agent-file-explorer
      ref={ref}
      theme="dark"
      shiki-theme="github-dark"
      style={{ width: '100%', height: '100vh' }}
    />
  );
}

Custom agent panel

For an agent-facing panel, the project tree can remain the source of truth for the current location while the preview header only shows the selected filename:

explorer.showBreadcrumb = false;
explorer.autoOpenFirstFile = true;
explorer.tree = projectTree;

explorer.addEventListener('agent-file-open', async (event) => {
  const { node, path } = event.detail;
  const content = await loadFileFromAgentBackend(path);
  explorer.setFileContent(node.name, content, null, path, content.length);
});

// Or run initialization after the tree has finished rendering.
explorer.addEventListener('agent-file-tree-ready', () => {
  console.log('file tree is ready');
});

Set autoOpenFirstFile = true when a project is first detected: the component waits for the file tree to finish rendering, expands directories, and emits agent-file-open for the first file. Consumers do not need to coordinate render frames or access Shadow DOM. openFirstFile() remains available for manual use.

To open a specific file when the component mounts (e.g. resume a previous session, or deep-link to a path), set initialFilePath together with tree:

explorer.tree = projectTree;
explorer.initialFilePath = '/project/README.md'; // auto-selects README.md

The component expands every parent directory, scrolls the file into view, and emits agent-file-open for it — no manual coordination required. Use explorer.openFile(path) to jump to another file at any time.

API

<agent-file-explorer>

Property Type Default Description
tree FileNode | null null Root node of the file tree.
theme 'light' | 'dark' | 'system' 'dark' Color theme.
shikiTheme string 'github-dark' Shiki highlighting theme.
splitRatio number 0.5 Initial ratio of the left (preview) panel.
virtualized boolean true Enable virtual scrolling.
showGitStatus boolean true Show Git status dots.
showBreadcrumb boolean true Show the preview path breadcrumb.
extraContextMenuActions ContextMenuAction[] [] Custom actions for the preview context menu.
autoOpenFirstFile boolean false Expand the tree and select the first file after the tree is ready.
initialFilePath string | null null Path (or node ID) to preselect when the tree is ready. Auto-expands parent directories and fires agent-file-open.
Callback Type Description
onTreeReady (detail: { tree: FileNode }) => void Called after the file tree finishes rendering.
Method Description
setFileContent(filename, content, imageUrl?, path?, size?) Display a file in the preview panel.
expandAll() Expand all directories.
collapseAll() Collapse all directories.
openFirstFile() Expand the tree and request the first file to open.
openFile(path) Select the file at path (or node ID): expands its ancestors and fires agent-file-open.
Event Detail Description
agent-file-open { node: FileNode, path: string } Fired when a file is selected.
agent-file-tree-ready { tree: FileNode } Fired after the file tree finishes rendering.
agent-add-to-context { text: string, filename: string } Fired from the context menu "Add to agent".

<agent-file-tree>

Can be used standalone for just the file tree.

<agent-file-preview>

Can be used standalone for just the code preview.

Property Type Description
filename string File name for language detection.
content string File text content.
imageUrl string | null URL for image preview.
filePath string Full path for breadcrumb.
showBreadcrumb boolean Whether to show the path breadcrumb.
fileSize number | null File size in bytes.
extraContextMenuActions ContextMenuAction[] Custom context-menu actions.

By default Markdown files render in the preview panel. Use the 预览/源码 toggle in the header to switch between the rendered view and the raw syntax-highlighted source.

Themes

The component uses --trees-* CSS custom properties. Override them on the host element to customize:

agent-file-explorer {
  --trees-bg: #0d1117;
  --trees-fg: #c9d1d9;
  --trees-accent: #58a6ff;
}

Development

# install dependencies
npm install

# start dev server
npm run dev

# type check
npm run typecheck

# build
npm run build

Contributing

Contributions are welcome! Please open an issue or submit a pull request. Make sure npm run typecheck and npm run build pass before submitting.

License

MIT © Kaying Studio

About

A file tree + code preview Web Component built for custom AI agent interfaces, fully benchmarked against the right-side file preview panel in ChatGPT Codex.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages