···1414 name: string;
1515};
16161717+/** Raw filesystem directory entry (name + type flags). */
1818+export type FsDirent = {
1919+ name: string;
2020+ isDirectory: boolean;
2121+ isFile: boolean;
2222+};
2323+2424+/** Recursive tree node returned by `getTree()`. */
2525+export type FileSystemTreeNode = {
2626+ id: string;
2727+ name: string;
2828+ type: 'file' | 'folder';
2929+ children?: FileSystemTreeNode[];
3030+};
3131+1732export type FileSystemProvider = {
1833 /** Stable key for React and selection state (e.g. `habitat-docs`). */
1934 id: string;
···3247 /** List entries for this source; reject on transport errors. */
3348 listFiles(): Promise<FileSystemEntry[]>;
3449 /**
5050+ * Build a recursive tree of the source's contents.
5151+ * Providers without directories return a flat list of files.
5252+ */
5353+ getTree(): Promise<FileSystemTreeNode[]>;
5454+ /**
3555 * Create a new persisted entry in this source (e.g. a new Habitat docs
3656 * record). The shell optimistically inserts it, then refreshes the listing.
3757 */
3858 createFile(): Promise<FileSystemEntry>;
5959+ /**
6060+ * Create a new directory in this source.
6161+ * Providers without directory support may throw or no-op.
6262+ */
6363+ createDirectory(name: string): Promise<FileSystemEntry>;
3964 /**
4065 * When implemented, called when a listed entry's display name changes
4166 * (e.g. habitat doc heading edits). Used to keep the sidebar in sync.
···5277 /** Live-document backend, injected at the composition root (`App.tsx`). */
5378 documents: DocumentProvider;
5479};
8080+8181+/** Low-level filesystem API used by providers that access the host disk. */
8282+export interface FilesystemApi {
8383+ readdir(dirPath: string): Promise<FsDirent[]>;
8484+ readFile(filePath: string): Promise<string>;
8585+ writeFile(filePath: string, content: string): Promise<void>;
8686+ fileExists(filePath: string): Promise<boolean>;
8787+ mkdir(dirPath: string): Promise<void>;
8888+}