# zidane-ui/files/headless

Import: `import { … } from 'zidane-ui/files/headless'`. Source: [ui/src/files/headless/index.ts](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/index.ts).

## Functions

### `createMemoryFilesLayout`

Function.

A layout that lasts as long as the store: for an app that keeps none.

```ts
function createMemoryFilesLayout(initial?: Partial<FilesLayout>): FilesLayoutStore
```

**Parameters**

- `initial?` (`Partial<FilesLayout>`, default `{}`): Where it starts.

**Returns** `FilesLayoutStore`

Source: [ui/src/files/headless/view.ts:66](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L66)

### `createStorageEditorPrefs`

Function.

Editor preferences kept in a `Storage` under one key, read on first use and validated with [`parseEditor`](https://zidane.si/docs/reference/ui-files-headless.md#parseEditor).
Every storage call is guarded: a storage that throws reads as empty and drops writes.

Another window's change (Settings in the main window, the session's panels in a window of their own) is
adopted and announced. Otherwise the files open here keep the old mode, and the next write from here puts it back.

```ts
function createStorageEditorPrefs(options: StorageEditorPrefsOptions): EditorPrefs
```

**Parameters**

- `options` (`StorageEditorPrefsOptions`): The storage and the key.

**Returns** `EditorPrefs`

Source: [ui/src/files/headless/editor-prefs.ts:181](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L181)

### `droppedImportItems`

Function.

A drop as import items (`importEntries`, `zidane/chat/pure`): dropped
folders walked through their entries, files read when their turn comes.

```ts
function droppedImportItems(items: readonly DroppedItem[]): Promise<EntryImportItem[]>
```

**Parameters**

- `items` (`readonly DroppedItem[]`): What the drop held ([`droppedItems`](https://zidane.si/docs/reference/ui-files-headless.md#droppedItems)).

**Returns** `Promise<EntryImportItem[]>`

Source: [ui/src/files/headless/entries.ts:75](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L75)

### `droppedItems`

Function.

What a drop holds, taken now: a `DataTransfer`'s items are gone once the
drop event returns, so its files and their entries are read here.

```ts
function droppedItems(data: DataTransfer): DroppedItem[]
```

**Parameters**

- `data` (`DataTransfer`): The drop's data.

**Returns** `DroppedItem[]`

Source: [ui/src/files/headless/entries.ts:27](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L27)

### `entryRefusalText`

Function.

What a refusal says, in the files labels.

```ts
function entryRefusalText(
  reason: EntryRefusal,
  labels: { filesAddToChat: string; filesAddToPrompt: string; filesAddWhatToChat: (what: string) => string; filesAfter: string; filesAllFiles: string; filesBefore: string; filesBinary: string; filesBlankLines: string; filesCancel: string; filesChangedOnly: string; filesCheckedBy: (ran: readonly string[], failed: readonly string[]) => string; filesCheckFailed: (tools: readonly string[]) => string; filesChecking: string; filesClearSearch: string; filesCloseSearch: string; filesCloseSearchHint: string; filesCommentOn: (what: string) => string; filesCommentPlaceholder: string; filesCopy: string; filesCopyPath: string; filesCopyRelativePath: string; filesCopyWhat: (what: string) => string; filesCut: string; filesDelete: string; filesDeleteConfirm: string; filesDeletePermanent: string; filesDeleteTitle: (name: string, count: number) => string; filesDeleteToTrash: string; filesDiffSource: string; filesDiffsToolbar: string; filesDismiss: string; filesDropHere: string; filesDuplicate: string; filesEmptyFolder: string; filesEntryDenied: string; filesEntryExists: string; filesEntryInvalid: string; filesEntryMissing: string; filesEntryTooLarge: string; filesFileNames: string; filesFindInDiff: string; filesFindInDiffs: string; filesGoToDefinition: string; filesHideFileList: string; filesHideIgnored: string; filesHideTree: string; filesImageSize: (name: string, width: number, height: number) => string; filesLanguageServer: string; filesLineHits: (count: number, more: boolean, files: number) => string; filesMatchCase: string; filesMatchingLines: string; filesMatchLine: (path: string, line: number, text: string) => string; filesMediaFailed: (name: string) => string; filesMoreLines: (count: number) => string; filesMoveToTrash: string; filesNameHits: (count: number, more: boolean) => string; filesNewFile: string; filesNewFolder: string; filesNoChanged: string; filesNoChangesHint: string; filesNoChangesYet: string; filesNoChat: string; filesNoFolder: string; filesNoResults: string; filesNotFound: string; filesNoTool: string; filesNoWorkingTree: string; filesOpenEditor: string; filesOpenFiles: string; filesOpenFolderInEditor: string; filesOpenInEditor: string; filesPaste: string; filesPickFile: string; filesPlainView: string; filesRefresh: string; filesRename: string; filesRevealFinder: string; filesRevealInFinder: string; filesSearchFiles: string; filesSearchInChanges: string; filesSearchInFiles: string; filesSearching: string; filesSearchNamesOnly: string; filesSelectedLines: string; filesSelection: string; filesSessionNoFolder: string; filesShowChanges: string; filesShowChangesLarge: string; filesShowFileList: string; filesShowIgnored: string; filesShowTree: string; filesSourceSession: string; filesSourceWorking: string; filesSplit: string; filesToAdd: string; filesTooLarge: (kb: number) => string; filesTruncated: (shown: number, total: number, atLeast: boolean) => string; filesWorkingTreeClean: string; filesWrap: string },
): string
```

**Parameters**

- `reason` (`EntryRefusal`): Why the host refused the action.
- `labels` (`{ filesAddToChat: string; filesAddToPrompt: string; filesAddWhatToChat: (what: string) => string; filesAfter: string; filesAllFiles: string; filesBefore: string; filesBinary: string; filesBlankLines: string; filesCancel: string; filesChangedOnly: string; filesCheckedBy: (ran: readonly string[], failed: readonly string[]) => string; filesCheckFailed: (tools: readonly string[]) => string; filesChecking: string; filesClearSearch: string; filesCloseSearch: string; filesCloseSearchHint: string; filesCommentOn: (what: string) => string; filesCommentPlaceholder: string; filesCopy: string; filesCopyPath: string; filesCopyRelativePath: string; filesCopyWhat: (what: string) => string; filesCut: string; filesDelete: string; filesDeleteConfirm: string; filesDeletePermanent: string; filesDeleteTitle: (name: string, count: number) => string; filesDeleteToTrash: string; filesDiffSource: string; filesDiffsToolbar: string; filesDismiss: string; filesDropHere: string; filesDuplicate: string; filesEmptyFolder: string; filesEntryDenied: string; filesEntryExists: string; filesEntryInvalid: string; filesEntryMissing: string; filesEntryTooLarge: string; filesFileNames: string; filesFindInDiff: string; filesFindInDiffs: string; filesGoToDefinition: string; filesHideFileList: string; filesHideIgnored: string; filesHideTree: string; filesImageSize: (name: string, width: number, height: number) => string; filesLanguageServer: string; filesLineHits: (count: number, more: boolean, files: number) => string; filesMatchCase: string; filesMatchingLines: string; filesMatchLine: (path: string, line: number, text: string) => string; filesMediaFailed: (name: string) => string; filesMoreLines: (count: number) => string; filesMoveToTrash: string; filesNameHits: (count: number, more: boolean) => string; filesNewFile: string; filesNewFolder: string; filesNoChanged: string; filesNoChangesHint: string; filesNoChangesYet: string; filesNoChat: string; filesNoFolder: string; filesNoResults: string; filesNotFound: string; filesNoTool: string; filesNoWorkingTree: string; filesOpenEditor: string; filesOpenFiles: string; filesOpenFolderInEditor: string; filesOpenInEditor: string; filesPaste: string; filesPickFile: string; filesPlainView: string; filesRefresh: string; filesRename: string; filesRevealFinder: string; filesRevealInFinder: string; filesSearchFiles: string; filesSearchInChanges: string; filesSearchInFiles: string; filesSearching: string; filesSearchNamesOnly: string; filesSelectedLines: string; filesSelection: string; filesSessionNoFolder: string; filesShowChanges: string; filesShowChangesLarge: string; filesShowFileList: string; filesShowIgnored: string; filesShowTree: string; filesSourceSession: string; filesSourceWorking: string; filesSplit: string; filesToAdd: string; filesTooLarge: (kb: number) => string; filesTruncated: (shown: number, total: number, atLeast: boolean) => string; filesWorkingTreeClean: string; filesWrap: string }`): The files labels to read the text from.

**Returns** `string`

Source: [ui/src/files/headless/entries.ts:149](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L149)

### `filesRootOf`

Function.

The scope's folder for file views: the session's workspace URI when its files are elsewhere, else its `cwd`.

```ts
function filesRootOf(scope: FilesScope): string
```

**Parameters**

- `scope` (`FilesScope`): The view's scope.

**Returns** `string`

Source: [ui/src/files/headless/view.ts:14](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L14)

### `filesScopeKey`

Function.

The scope's identity: the session when bound, else `draft:<id>` or `project:<root>`.

```ts
function filesScopeKey(scope: FilesScope): string
```

**Parameters**

- `scope` (`FilesScope`): The view's scope.

**Returns** `string`

Source: [ui/src/files/headless/view.ts:23](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L23)

### `hasDroppedFiles`

Function.

Whether a drag carries files from outside the page (the file manager).

```ts
function hasDroppedFiles(data: DataTransfer | null | undefined): boolean
```

**Parameters**

- `data` (`DataTransfer | null | undefined`): The drag event's `dataTransfer`.

**Returns** `boolean`

Source: [ui/src/files/headless/entries.ts:17](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L17)

### `inFolder`

Function.

`name` in folder `dir`.

```ts
function inFolder(dir: string, name: string): string
```

**Parameters**

- `dir` (`string`): The folder (`''`: the root).
- `name` (`string`): The entry's name.

**Returns** `string`

Source: [ui/src/files/headless/entries.ts:128](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L128)

### `isUnder`

Function.

Whether `path` is `root` or inside it.

```ts
function isUnder(path: string, root: string): boolean
```

**Parameters**

- `path` (`string`): A path relative to the folder.
- `root` (`string`): The folder to test against.

**Returns** `boolean`

Source: [ui/src/files/headless/entries.ts:86](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L86)

### `matchRanges`

Function.

Every occurrence of `query` in `text`, as UTF-16 offsets.

```ts
function matchRanges(
  text: string,
  query: string,
  opts: TextMatchOptions,
): { end: number; start: number }[]
```

**Parameters**

- `text` (`string`): The text to search.
- `query` (`string`): What to find (empty: nothing).
- `opts` (`TextMatchOptions`): Whether case matters.

**Returns** `{ end: number; start: number }[]`

Source: [ui/src/files/headless/search.ts:14](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/search.ts#L14)

### `mediaTypeOfPath`

Function.

The media a path names, by its extension; `null` for everything else.

```ts
function mediaTypeOfPath(path: string): MediaType | null
```

**Parameters**

- `path` (`string`): A file path.

**Returns** `MediaType | null`

Source: [ui/src/files/headless/media.ts:36](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/media.ts#L36)

### `movedPath`

Function.

Where `path` is once `from` moved to `to` (itself, or inside a moved
folder); `null` when the move does not touch it.

```ts
function movedPath(path: string, from: string, to: string): string | null
```

**Parameters**

- `path` (`string`): A path relative to the folder.
- `from` (`string`): The moved entry.
- `to` (`string`): Where it went.

**Returns** `string | null`

Source: [ui/src/files/headless/entries.ts:98](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L98)

### `nameOf`

Function.

The last segment of `path`.

```ts
function nameOf(path: string): string
```

**Parameters**

- `path` (`string`): A path relative to the folder.

**Returns** `string`

Source: [ui/src/files/headless/entries.ts:118](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L118)

### `parentOf`

Function.

The folder holding `path` (`''`: the root).

```ts
function parentOf(path: string): string
```

**Parameters**

- `path` (`string`): A path relative to the folder.

**Returns** `string`

Source: [ui/src/files/headless/entries.ts:108](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L108)

### `parseEditor`

Function.

Stored preferences, validated: unknown or broken fields fall back to the defaults, numbers are clamped.
`undefined` when `raw` is not a JSON object.

```ts
function parseEditor(raw: string): EditorState | undefined
```

**Parameters**

- `raw` (`string`): The stored JSON.

**Returns** `EditorState | undefined`

Source: [ui/src/files/headless/editor-prefs.ts:91](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L91)

### `steppedIndex`

Function.

The next index when stepping `direction` through `length` items from `current` (-1: none), wrapping; -1 when
there are none.

```ts
function steppedIndex(current: number, length: number, direction: -1 | 1): number
```

**Parameters**

- `current` (`number`): The current index, or -1.
- `length` (`number`): How many items.
- `direction` (`-1 | 1`): `1` next, `-1` previous.

**Returns** `number`

Source: [ui/src/files/headless/view.ts:110](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L110)

### `topLevelPaths`

Function.

The paths to act on when several are picked: a path inside another picked
folder goes with it, so it is left out.

```ts
function topLevelPaths(paths: readonly string[]): string[]
```

**Parameters**

- `paths` (`readonly string[]`): The picked paths.

**Returns** `string[]`

Source: [ui/src/files/headless/entries.ts:138](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L138)

## Constants

### `DEFAULT_EDITOR`

Constant.

The preferences before any change.

```ts
const DEFAULT_EDITOR: EditorState
```

Source: [ui/src/files/headless/editor-prefs.ts:64](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L64)

### `DEFAULT_FILES_LABELS`

Constant.

The default English strings of the Files and Diffs tabs. Override any of them through `FilesProvider`.

```ts
const DEFAULT_FILES_LABELS: { filesAddToChat: string; filesAddToPrompt: string; filesAddWhatToChat: (what: string) => string; filesAfter: string; filesAllFiles: string; filesBefore: string; filesBinary: string; filesBlankLines: string; filesCancel: string; filesChangedOnly: string; filesCheckedBy: (ran: readonly string[], failed: readonly string[]) => string; filesCheckFailed: (tools: readonly string[]) => string; filesChecking: string; filesClearSearch: string; filesCloseSearch: string; filesCloseSearchHint: string; filesCommentOn: (what: string) => string; filesCommentPlaceholder: string; filesCopy: string; filesCopyPath: string; filesCopyRelativePath: string; filesCopyWhat: (what: string) => string; filesCut: string; filesDelete: string; filesDeleteConfirm: string; filesDeletePermanent: string; filesDeleteTitle: (name: string, count: number) => string; filesDeleteToTrash: string; filesDiffSource: string; filesDiffsToolbar: string; filesDismiss: string; filesDropHere: string; filesDuplicate: string; filesEmptyFolder: string; filesEntryDenied: string; filesEntryExists: string; filesEntryInvalid: string; filesEntryMissing: string; filesEntryTooLarge: string; filesFileNames: string; filesFindInDiff: string; filesFindInDiffs: string; filesGoToDefinition: string; filesHideFileList: string; filesHideIgnored: string; filesHideTree: string; filesImageSize: (name: string, width: number, height: number) => string; filesLanguageServer: string; filesLineHits: (count: number, more: boolean, files: number) => string; filesMatchCase: string; filesMatchingLines: string; filesMatchLine: (path: string, line: number, text: string) => string; filesMediaFailed: (name: string) => string; filesMoreLines: (count: number) => string; filesMoveToTrash: string; filesNameHits: (count: number, more: boolean) => string; filesNewFile: string; filesNewFolder: string; filesNoChanged: string; filesNoChangesHint: string; filesNoChangesYet: string; filesNoChat: string; filesNoFolder: string; filesNoResults: string; filesNotFound: string; filesNoTool: string; filesNoWorkingTree: string; filesOpenEditor: string; filesOpenFiles: string; filesOpenFolderInEditor: string; filesOpenInEditor: string; filesPaste: string; filesPickFile: string; filesPlainView: string; filesRefresh: string; filesRename: string; filesRevealFinder: string; filesRevealInFinder: string; filesSearchFiles: string; filesSearchInChanges: string; filesSearchInFiles: string; filesSearching: string; filesSearchNamesOnly: string; filesSelectedLines: string; filesSelection: string; filesSessionNoFolder: string; filesShowChanges: string; filesShowChangesLarge: string; filesShowFileList: string; filesShowIgnored: string; filesShowTree: string; filesSourceSession: string; filesSourceWorking: string; filesSplit: string; filesToAdd: string; filesTooLarge: (kb: number) => string; filesTruncated: (shown: number, total: number, atLeast: boolean) => string; filesWorkingTreeClean: string; filesWrap: string }
```

Source: [ui/src/files/headless/labels.ts:10](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/labels.ts#L10)

### `DEFAULT_FILES_LAYOUT`

Constant.

A fresh scope's layout.

```ts
const DEFAULT_FILES_LAYOUT: FilesLayout
```

Source: [ui/src/files/headless/view.ts:46](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L46)

### `DIAGNOSTICS_TIMEOUT`

Constant.

The per-tool diagnostics timeout, in seconds.

```ts
const DIAGNOSTICS_TIMEOUT: { max: number; min: number; step: number }
```

Source: [ui/src/files/headless/editor-prefs.ts:61](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L61)

### `EDITOR_STORAGE_KEY`

Constant.

The key the preferences live under.

```ts
const EDITOR_STORAGE_KEY = 'zg:editor:v1'
```

Source: [ui/src/files/headless/editor-prefs.ts:10](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L10)

### `LSP_IDLE`

Constant.

The language servers' idle shutdown, in minutes.

```ts
const LSP_IDLE: { max: number; min: number; step: number }
```

Source: [ui/src/files/headless/editor-prefs.ts:58](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L58)

## Interfaces

### `ContentMatch`

Interface.

One matching line of a search in files.

```ts
interface ContentMatch
```

**Properties**

- `line` (`number`): 1-based.
- `path` (`string`): Relative to the folder.
- `ranges` (`{ end: number; start: number }[]`): The matches in it, as UTF-16 offsets.
- `text` (`string`): The line.

Source: [ui/src/files/headless/host.ts:89](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L89)

### `ContentSearchOptions`

Interface.

Options of `FilesHost.search`.

```ts
interface ContentSearchOptions extends TextMatchOptions
```

**Properties**

- `caseSensitive` (`boolean`, from `TextMatchOptions`): Match case.
- `searchId` (`string`): A later search with the same id cancels this one (one per search box).

Source: [ui/src/files/headless/host.ts:113](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L113)

### `ContentSearchResult`

Interface.

A search in files.

```ts
interface ContentSearchResult
```

**Properties**

- `capped` (`boolean`): Stopped at the cap: there are more.
- `engine` (`'none' | 'rg' | 'git' | 'walk'`): What ran: ripgrep, `git grep`, a walk of the files, or nothing (empty query, superseded).
- `matches` (`ContentMatch[]`): The matching lines.
- `unsupported?` (`'sandbox'`): File contents can't be searched here (a sandboxed session); names still can.

Source: [ui/src/files/headless/host.ts:101](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L101)

### `Diagnostic`

Interface.

One finding from a project tool or a language server, positions 1-based like editors show them.

```ts
interface Diagnostic
```

**Properties**

- `code?` (`string`): Rule / error code (`TS2322`, `no-unused-vars`).
- `column` (`number`): 1-based column.
- `endColumn?` (`number`): Last column.
- `endLine?` (`number`): Last line.
- `line` (`number`): 1-based line.
- `message` (`string`): What it says.
- `path` (`string`): Relative to the folder.
- `severity` (`DiagnosticSeverity`): How bad.
- `source` (`string`): Tool id (`tsc`, `eslint`, …).

Source: [ui/src/files/headless/host.ts:139](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L139)

### `DiagnosticsResult`

Interface.

A diagnostics run.

```ts
interface DiagnosticsResult
```

**Properties**

- `diagnostics` (`Diagnostic[]`): The findings.
- `failed` (`{ id: string; reason: string }[]`): Tools that failed or timed out, with a short reason.
- `ran` (`string[]`): Tools that ran (ids), for the "checked by" line.

Source: [ui/src/files/headless/host.ts:161](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L161)

### `DiagnosticsRunOptions`

Interface.

Options of `FilesDiagnostics.run`.

```ts
interface DiagnosticsRunOptions
```

**Properties**

- `disabled` (`string[]`): Tool ids switched off.
- `lsp` (`boolean`): The files are open in a language server, which reports what the project-wide checks would: skip those.
- `signal?` (`AbortSignal`): Aborted when the caller no longer reads the answer (the file moved on, the view went): the backend may stop the run.
- `timeoutMs` (`number`): Per-command timeout.

Source: [ui/src/files/headless/host.ts:171](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L171)

### `DroppedItem`

Interface.

One thing dropped from outside the page, taken while the drop lasts (a `DataTransfer` is emptied after it).

```ts
interface DroppedItem
```

**Properties**

- `entry` (`FileSystemEntry | null`): Its entry, to walk a dropped folder (`webkitGetAsEntry`); `null` when the platform gives none.
- `file` (`File`): The dropped file (a dropped folder too, where the platform hands folders as files).

Source: [ui/src/files/headless/host.ts:328](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L328)

### `EditorPrefs`

Interface.

The stored preferences: read with `get`, follow with `subscribe`, change with `set`.

```ts
interface EditorPrefs extends Readable<EditorState>
```

**Properties**

- `get` (`() => EditorState`, from `Readable`): Returns the current value.
- `reset` (`() => void`): Back to [`DEFAULT_EDITOR`](https://zidane.si/docs/reference/ui-files-headless.md#DEFAULT_EDITOR).
- `set` (`(update: Partial<EditorState>) => void`): Merges `update` into the preferences, stores them and tells subscribers. Equal preferences change nothing.
- `subscribe` (`(onChange: () => void) => () => void`, from `Readable`): Registers a listener called after the value changes. Returns a function that removes the listener.

Source: [ui/src/files/headless/editor-prefs.ts:140](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L140)

### `EditorState`

Interface.

The editor preferences.

```ts
interface EditorState
```

**Properties**

- `autoSurround` (`AutoSurround`): How a typed bracket or quote wraps the selection.
- `diagnostics` (`DiagnosticsMode`): `tools`: run the project's own linters/typecheckers on viewed files.
- `diagnosticsDisabled` (`readonly string[]`): Tool ids the user switched off.
- `diagnosticsRun` (`DiagnosticsRun`): When to run: on open (and after every change on disk) or only after our own saves.
- `diagnosticsTimeoutS` (`number`): Per-tool timeout in seconds.
- `editing` (`boolean`): Files opened in the panel are editable (⌘S saves).
- `lspCompletion` (`boolean`): Suggest completions from the server while typing.
- `lspHover` (`boolean`): Show type/documentation hovers from the server.
- `lspIdleMin` (`number`): Language servers: shut down after this many idle minutes.
- `lspOverrides` (`Readonly<Record<string, string>>`): Command overrides by server id (`bin arg…`).
- `matchBrackets` (`boolean`): Highlight the bracket matching the one at the caret.
- `roundedSelection` (`boolean`): Round the selection's corners.
- `saveOn` (`SaveOn`): When an edited file saves.
- `tabSize` (`2 | 4`): Indentation width.
- `version` (`1`): The record's version.
- `wordWrap` (`boolean`): Wrap long lines.

Source: [ui/src/files/headless/editor-prefs.ts:22](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L22)

### `EntryClipboard`

Interface.

Rows cut or copied in the tree, waiting for a paste.

```ts
interface EntryClipboard
```

**Properties**

- `cwd` (`string`): The folder they come from.
- `mode` (`'copy' | 'cut'`): `cut`: a paste moves them; `copy`: a paste copies them.
- `paths` (`readonly string[]`): Their paths, relative to it.

Source: [ui/src/files/headless/entries.ts:165](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/entries.ts#L165)

### `FilesChatTarget`

Interface.

The chat a view adds to: the composer receiving the view's scope.

```ts
interface FilesChatTarget
```

**Properties**

- `attach` (`(name: string, text: string) => void`): Attaches a text (a snippet, a review comment, a finding) to the composer under `name`.
- `mention` (`(path: string) => void`): Mentions a path (relative to the folder) in the composer.

Source: [ui/src/files/headless/view.ts:85](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L85)

### `FilesDiagnostics`

Interface.

The project's own linters and typecheckers.

```ts
interface FilesDiagnostics
```

**Properties**

- `invalidate` (`(cwd: string) => Promise<void>`): Drops the cached results for the folder (the next run checks again).
- `run` (`(cwd: string, paths: string[], options: DiagnosticsRunOptions) => Promise<DiagnosticsResult>`): Runs the tools on `paths` (cached by the backend until the files move).

Source: [ui/src/files/headless/host.ts:183](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L183)

### `FilesEntries`

Interface.

Entry actions on a folder's files: what the tree's new file and folder,
rename, move, copy, delete and drops from outside run. Paths are relative
to the folder, never `..` or absolute. Nothing is overwritten: a create,
move or rename onto a taken name is refused (`exists`); a copy or an
import takes the next free name (`a copy.ts`). A refusal resolves; it
does not throw.

```ts
interface FilesEntries
```

**Properties**

- `copy` (`(cwd: string, from: string, toDir: string) => Promise<EntryResult>`): Copies `from` into folder `toDir` (`''`: the root) under its name, or the next free one.
- `create` (`(cwd: string, path: string, kind: 'dir' | 'file') => Promise<EntryResult>`): Creates a file (empty) or a folder at `path`, making the folders on the way.
- `importFiles` (`(cwd: string, dir: string, items: readonly DroppedItem[]) => Promise<EntryImportResult>`): Brings what was dropped from outside the page into folder `dir`, each top-level item under a free name.
- `move` (`(cwd: string, from: string, to: string) => Promise<EntryResult>`): Moves (renames) `from` to `to`, making the folders on the way.
- `removal` (`(cwd: string) => FilesRemoval`): Where `remove` sends `cwd`'s entries: the confirmation says so.
- `remove` (`(cwd: string, path: string) => Promise<EntryResult>`): Removes `path` (a folder whole), where `removal` says.

Source: [ui/src/files/headless/host.ts:346](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L346)

### `FilesHost`

Interface.

The files host. Every member is optional.

```ts
interface FilesHost
```

**Properties**

- `diagnostics?` (`FilesDiagnostics`): Project-tool diagnostics. Absent: no findings, no chip.
- `editorPrefs?` (`EditorPrefs`): The editor preferences. Absent: the defaults, unchangeable.
- `entries?` (`FilesEntries`): Creates, moves, copies, removes and imports entries. Absent: the tree only browses.
- `lsp?` (`FilesLsp`): Language servers. Absent: the `lsp` diagnostics mode runs project tools only.
- `system?` (`FilesSystem`): Opening paths in other apps. Absent: no "Open in editor" / "Reveal" actions.
- `gitStatus?` (`(cwd: string) => Promise<GitStatusEntry[]>`): The folder's git status. Absent: no changed marks, no "changed only".
- `list?` (`(cwd: string, options?: { dir?: string; showIgnored?: boolean }) => Promise<WorkspaceListing>`): The folder's entries (files, and empty folders). `dir`: only what is under that folder (relative to `cwd`, the
  paths still relative to `cwd`), how an ignored folder opens. Rejects when the folder can't be read.
- `mediaUrl?` (`(source: MediaSource) => string`): The address a media file plays from. Absent: media files show as binary.
- `read?` (`(cwd: string, path: string) => Promise<WorkspaceFile | null>`): A file, or `null` when it is gone (moved, deleted, outside the folder).
- `search?` (`(cwd: string, query: string, options: ContentSearchOptions) => Promise<ContentSearchResult>`): Searches the folder's file contents. Absent: search in files matches names only.
- `watch?` (`(scope: FilesScope, onChange: (why: FolderChange) => void) => () => void`): Calls `onChange` when files of the scope's folder may have moved (a tool result from a session working there,
  the repository moving), raw: callers settle bursts. Returns the unsubscribe. Absent: views refresh by hand.
- `workingTreeDiff?` (`(cwd: string, options?: { context?: number; path?: string }) => Promise<string>`): The working tree against HEAD as a unified patch (untracked files included), the whole folder or one
  `path`, with `context` lines (`Infinity`: the whole file). Absent: no working-tree diffs.
- `write?` (`(cwd: string, path: string, contents: string, expectedMtimeMs: number) => Promise<WorkspaceWriteResult>`): Writes a file, refused when its version moved past `expectedMtimeMs`. Absent: files are read-only.

Source: [ui/src/files/headless/host.ts:362](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L362)

### `FilesKeyScope`

Interface.

What next/previous/close/find keys do inside a tab (the app routes them by focus).

```ts
interface FilesKeyScope
```

**Properties**

- `close` (`() => boolean`): Closes one thing inside the tab. False when nothing is left to close.
- `find?` (`(mode: 'files' | 'file') => boolean`): `file`: find in the file or diff on screen; `files`: search across files. False when there is nothing to search.
- `step` (`(direction: -1 | 1) => boolean`): `1` next, `-1` previous. Returns false when there was nothing to move to.

Source: [ui/src/files/headless/view.ts:93](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L93)

### `FilesLayout`

Interface.

What the Files tab keeps per scope.

```ts
interface FilesLayout
```

**Properties**

- `filesActive` (`string | null`): The active file.
- `filesChangedOnly` (`boolean`): The tree lists changed files only.
- `filesOpen` (`readonly string[]`): The open files, in tab order.
- `filesShowIgnored` (`boolean`): Gitignored files are listed.
- `filesTreeOpen` (`boolean`): The tree is shown.
- `filesTreeWidth` (`number | null`): The tree's width (`null`: the default).

Source: [ui/src/files/headless/view.ts:30](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L30)

### `FilesLayoutStore`

Interface.

Where a scope's layout lives: read with `get`, follow with `subscribe`, change with `update`.

```ts
interface FilesLayoutStore extends Readable<FilesLayout>
```

**Properties**

- `get` (`() => FilesLayout`, from `Readable`): Returns the current value.
- `subscribe` (`(onChange: () => void) => () => void`, from `Readable`): Registers a listener called after the value changes. Returns a function that removes the listener.
- `update` (`(patch: Partial<FilesLayout>) => void`): Merges `patch` into the layout.

Source: [ui/src/files/headless/view.ts:56](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/view.ts#L56)

### `FilesLsp`

Interface.

Language servers: live findings while typing, hovers, completion and go to definition.

```ts
interface FilesLsp
```

**Properties**

- `close` (`(cwd: string, path: string) => Promise<void>`): Closes the document.
- `completion` (`(cwd: string, path: string, text: string, changes: LspTextChange[] | undefined, line: number, column: number, trigger?: string) => Promise<LspCompletionList>`): Completion at a 1-based position, sending the document's pending change with it.
- `configure` (`(options: { idleMs: number; overrides: Record<string, string> }) => Promise<void>`): The idle timeout and the per-server command overrides (the editor preferences).
- `definition` (`(cwd: string, path: string, line: number, column: number) => Promise<LspDefinition[]>`): Where the symbol at a 1-based position is defined (several places for an overload; empty: nowhere known).
- `hover` (`(cwd: string, path: string, line: number, column: number) => Promise<LspHover>`): The hover at a 1-based position.
- `onDiagnostics` (`(listener: (cwd: string, path: string, diagnostics: Diagnostic[]) => void) => () => void`): Findings the server pushes for an open document. Returns the unsubscribe.
- `open` (`(cwd: string, path: string, text: string, changes?: LspTextChange[]) => Promise<Diagnostic[]>`): Opens the document (or sends a change: `changes` incremental, else the full text); resolves to the findings known now.
- `resolveCompletion` (`(cwd: string, path: string, id: number, index: number) => Promise<LspCompletionDetail | null>`): The rest of item `index` of answer `id`.

Source: [ui/src/files/headless/host.ts:275](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L275)

### `FilesScope`

Interface.

What a view works from: a folder, optionally bound to a session (or the new-chat draft).

```ts
interface FilesScope
```

**Properties**

- `cwd` (`string`): Where things open.
- `draft?` (`string`): The new-chat draft's id.
- `root` (`string`): The project root.
- `session?` (`string`): Bound to this session.
- `workspace?` (`string`): Where a bound session's files live when they are not on this machine (`zidane-env://…`).

Source: [ui/src/files/headless/host.ts:119](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L119)

### `FilesSystem`

Interface.

What the platform does with a path outside the page.

```ts
interface FilesSystem
```

**Properties**

- `isLocal` (`(cwd: string) => boolean`): Whether files of `cwd` are on this machine (not a sandbox's or a server's): only those can be opened elsewhere.
- `openPath` (`(path: string, at?: { column?: number; line: number }) => Promise<boolean>`): Opens an absolute path in the default editor, at `at` (1-based) when the editor takes a position. Resolves false when it could not.
- `revealPath` (`(path: string) => Promise<boolean>`): Shows an absolute path in the file manager. Resolves false when it could not.

Source: [ui/src/files/headless/host.ts:303](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L303)

### `GitStatusEntry`

Interface.

One path's git status.

```ts
interface GitStatusEntry
```

**Properties**

- `path` (`string`): Relative to the folder.
- `status` (`'added' | 'deleted' | 'ignored' | 'modified' | 'renamed' | 'untracked'`): What changed.

Source: [ui/src/files/headless/host.ts:75](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L75)

### `LspCompletionDetail`

Interface.

The rest of a completion item, fetched when it is selected or accepted.

```ts
interface LspCompletionDetail
```

**Properties**

- `additionalEdits?` (`{ newText: string; range: LspRange }[]`): Edits elsewhere in the file applied with the item (an auto-import).
- `detail?` (`string`): The item's detail.
- `documentation?` (`string`): Its documentation (Markdown).

Source: [ui/src/files/headless/host.ts:265](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L265)

### `LspCompletionItem`

Interface.

One completion candidate, ready to insert.

```ts
interface LspCompletionItem
```

**Properties**

- `cursor?` (`{ end: number; start: number }`): Where the caret lands inside `insertText`, as offsets; absent: its end.
- `detail?` (`string`): Shown after the label (signature, type, module).
- `filterText?` (`string`): What typing filters on (defaults to `label`).
- `insertText` (`string`): Text that replaces `range` (snippet syntax already flattened).
- `kind?` (`string`): LSP kind as a word (`function`, `field`, `module`, …).
- `label` (`string`): What the menu shows.
- `preselect?` (`boolean`): Selected first.
- `range?` (`LspRange`): 0-based range the item replaces; absent: the word before the caret.
- `sortText?` (`string`): Sort key.

Source: [ui/src/files/headless/host.ts:231](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L231)

### `LspCompletionList`

Interface.

A completion answer; `id` names it for `FilesLsp.resolveCompletion`.

```ts
interface LspCompletionList
```

**Properties**

- `busy?` (`string`): What the server is still doing.
- `id` (`number`): The answer's id.
- `incomplete` (`boolean`): Typing on must ask again instead of filtering these.
- `items` (`LspCompletionItem[]`): The candidates.

Source: [ui/src/files/headless/host.ts:253](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L253)

### `LspDefinition`

Interface.

A definition target, and the symbol it was asked from when the server says.

```ts
interface LspDefinition extends LspLocation
```

**Properties**

- `column` (`number`, from `LspLocation`): 1-based column.
- `line` (`number`, from `LspLocation`): 1-based line.
- `origin?` (`{ column: number; endColumn: number; endLine: number; line: number }`): The symbol in the asking file, 1-based, `endColumn` exclusive: what Cmd-hover underlines.
- `path` (`string`, from `LspLocation`): Relative to the folder.

Source: [ui/src/files/headless/host.ts:201](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L201)

### `LspHover`

Interface.

A hover answer; `busy` says why `text` may be missing (the server is still loading the project).

```ts
interface LspHover
```

**Properties**

- `busy?` (`string`): What the server is still doing.
- `text` (`string | null`): The hover text (Markdown).

Source: [ui/src/files/headless/host.ts:223](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L223)

### `LspLocation`

Interface.

A position in a file, 1-based.

```ts
interface LspLocation
```

**Properties**

- `column` (`number`): 1-based column.
- `line` (`number`): 1-based line.
- `path` (`string`): Relative to the folder.

Source: [ui/src/files/headless/host.ts:191](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L191)

### `LspRange`

Interface.

0-based LSP range.

```ts
interface LspRange
```

**Properties**

- `end` (`{ character: number; line: number }`): End.
- `start` (`{ character: number; line: number }`): Start.

Source: [ui/src/files/headless/host.ts:207](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L207)

### `LspTextChange`

Interface.

One incremental document change, LSP shape (0-based positions in the document before the change).

```ts
interface LspTextChange
```

**Properties**

- `range` (`LspRange`): What it replaces.
- `text` (`string`): The new text.

Source: [ui/src/files/headless/host.ts:215](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L215)

### `MediaType`

Interface.

A file the page shows as media, with its MIME type.

```ts
interface MediaType
```

**Properties**

- `kind` (`MediaKind`): How it is shown.
- `mime` (`string`): Its MIME type.

Source: [ui/src/files/headless/host.ts:43](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L43)

### `StorageEditorPrefsOptions`

Interface.

Options of [`createStorageEditorPrefs`](https://zidane.si/docs/reference/ui-files-headless.md#createStorageEditorPrefs).

```ts
interface StorageEditorPrefsOptions
```

**Properties**

- `key?` (`string`): The key. Default: [`EDITOR_STORAGE_KEY`](https://zidane.si/docs/reference/ui-files-headless.md#EDITOR_STORAGE_KEY).
- `storage` (`EditorPrefsStorage`): Where the preferences live.
- `watch?` (`(key: string, onChange: () => void) => () => void`): Calls `onChange` when another window changed the stored preferences; returns the unsubscribe. Default: the
  `storage` event of `window`, when there is one.

Source: [ui/src/files/headless/editor-prefs.ts:151](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L151)

### `TextMatchOptions`

Interface.

How text matches.

```ts
interface TextMatchOptions
```

**Properties**

- `caseSensitive` (`boolean`): Match case.

Source: [ui/src/files/headless/host.ts:83](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L83)

### `WorkspaceEntry`

Interface.

One entry of a folder listing.

```ts
interface WorkspaceEntry
```

**Properties**

- `ignored?` (`boolean`): Gitignored (only present when listed with `showIgnored`). An ignored folder is one node: list it with `dir` to open it.
- `kind` (`'dir' | 'file'`): A file or a folder.
- `path` (`string`): Relative to the folder; directories end with `/` (only listed when empty).

Source: [ui/src/files/headless/host.ts:22](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L22)

### `WorkspaceFile`

Interface.

A file as read.

```ts
interface WorkspaceFile
```

**Properties**

- `binary` (`boolean`): Not text.
- `contents` (`string`): The text (empty for a binary or media file).
- `media?` (`MediaType`): A binary the page plays (an image, a video, audio), shown through `FilesHost.mediaUrl`.
- `mtimeMs` (`number`): Version at read (a modification time, or any number that changes with the bytes); `write` refuses when it moved.
- `path` (`string`): Relative to the folder.
- `size` (`number`): Size in bytes.
- `truncated` (`boolean`): Too large: `contents` is cut.

Source: [ui/src/files/headless/host.ts:51](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L51)

### `WorkspaceListing`

Interface.

A folder's listing: its entries, and whether the host cut it at its cap.

```ts
interface WorkspaceListing
```

**Properties**

- `entries` (`WorkspaceEntry[]`): The entries.
- `truncated?` (`{ atLeast?: boolean; shown: number; total: number }`): Set when the listing was cut: how many it holds and how many there are (`atLeast`: more than that).

Source: [ui/src/files/headless/host.ts:32](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L32)

## Types

### `AutoSurround`

Type.

How the editor wraps a selection when a bracket or quote is typed.

```ts
type AutoSurround = 'default' | 'never' | 'brackets' | 'quotes'
```

Source: [ui/src/files/headless/editor-prefs.ts:13](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L13)

### `DiagnosticSeverity`

Type.

The severity of a finding.

```ts
type DiagnosticSeverity = 'error' | 'warning' | 'info' | 'hint'
```

Source: [ui/src/files/headless/host.ts:136](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L136)

### `DiagnosticsMode`

Type.

`lsp` = project tools plus language servers (live while typing, hovers).

```ts
type DiagnosticsMode = 'off' | 'tools' | 'lsp'
```

Source: [ui/src/files/headless/editor-prefs.ts:17](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L17)

### `DiagnosticsRun`

Type.

When project tools run: on open (and after every change on disk) or only after the editor's own saves.

```ts
type DiagnosticsRun = 'open' | 'save'
```

Source: [ui/src/files/headless/editor-prefs.ts:19](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L19)

### `EditorPrefsStorage`

Type.

The `Storage` calls the editor preferences make (`localStorage` or a double).

```ts
type EditorPrefsStorage = Pick<Storage, 'getItem' | 'setItem'>
```

Source: [ui/src/files/headless/editor-prefs.ts:148](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L148)

### `FilesEntryRefusal`

Type.

Why an entry action was refused: a taken name, a source gone, an invalid name, no access, over the import limits.

```ts
type FilesEntryRefusal = EntryRefusal
```

Source: [ui/src/files/headless/host.ts:319](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L319)

### `FilesEntryResult`

Type.

What an entry action did: the path it ended at, or why it was refused (`message`: the backend's own words).

```ts
type FilesEntryResult = EntryResult
```

Source: [ui/src/files/headless/host.ts:322](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L322)

### `FilesImportResult`

Type.

What an import did: the top-level paths it made, and why it stopped when it did.

```ts
type FilesImportResult = EntryImportResult
```

Source: [ui/src/files/headless/host.ts:325](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L325)

### `FilesLabels`

Type.

The shape of the files label dictionary. Some values are functions that build a string.

```ts
type FilesLabels = typeof DEFAULT_FILES_LABELS
```

Source: [ui/src/files/headless/labels.ts:125](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/labels.ts#L125)

### `FilesRemoval`

Type.

How a folder's removals end: in the system trash (recoverable), or gone for good.

```ts
type FilesRemoval = 'trash' | 'permanent'
```

Source: [ui/src/files/headless/host.ts:336](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L336)

### `FolderChange`

Type.

Why a folder may have changed: a tool result in it, or the repository moving.

```ts
type FolderChange = 'tool-result' | 'git'
```

Source: [ui/src/files/headless/host.ts:133](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L133)

### `MediaKind`

Type.

The media kinds a browser plays on its own.

```ts
type MediaKind = 'image' | 'video' | 'audio' | 'pdf'
```

Source: [ui/src/files/headless/host.ts:40](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L40)

### `MediaSource`

Type.

A media file's address: as it is now, or one side of a working-tree change.

```ts
type MediaSource =
  | { cwd: string; kind: 'file'; path: string; version: number }
  | { cwd: string; kind: 'diff'; path: string; side: 'old' | 'new'; version?: string }
```

Source: [ui/src/files/headless/host.ts:313](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L313)

### `SaveOn`

Type.

When an edited file saves: on ⌘S only, or when the editor loses focus too.

```ts
type SaveOn = 'manual' | 'blur'
```

Source: [ui/src/files/headless/editor-prefs.ts:15](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/editor-prefs.ts#L15)

### `WorkspaceWriteResult`

Type.

What a guarded write did.

```ts
type WorkspaceWriteResult =
  | { mtimeMs: number; ok: true }
  | { ok: false; reason: 'changed' | 'missing' | 'denied' }
```

Source: [ui/src/files/headless/host.ts:69](https://github.com/Tahul/zidane/blob/main/ui/src/files/headless/host.ts#L69)
