diff --git a/packages/diffs/README.md b/packages/diffs/README.md index bc3717423..7126b5b50 100644 --- a/packages/diffs/README.md +++ b/packages/diffs/README.md @@ -36,6 +36,9 @@ Install the agent skill for this package with the npx skills add pierrecomputer/pierre --skill diffs ``` +The published package also includes the same skill at `skills/diffs/`, so +installing `@pierre/diffs` version-locks the agent instructions with the API. + ## Development We use pnpm for workspace package management and Bun for tests. diff --git a/packages/diffs/package.json b/packages/diffs/package.json index 4fa825486..3204e9c34 100644 --- a/packages/diffs/package.json +++ b/packages/diffs/package.json @@ -5,7 +5,8 @@ "files": [ "dist", "LICENSE.md", - "README.md" + "README.md", + "skills" ], "type": "module", "sideEffects": [ diff --git a/packages/diffs/skills/diffs/SKILL.md b/packages/diffs/skills/diffs/SKILL.md new file mode 100644 index 000000000..25ba00509 --- /dev/null +++ b/packages/diffs/skills/diffs/SKILL.md @@ -0,0 +1,48 @@ +--- +name: diffs +description: + Use when an app uses @pierre/diffs to render or edit code files, diffs, + patches, merge conflicts, or CodeView review surfaces, including React, + vanilla JavaScript, SSR, workers, annotations, selection, and custom Shiki + languages or themes. +--- + +# `@pierre/diffs` + +Use `@pierre/diffs` to render syntax-highlighted files and diffs. Use its +optional editor, SSR, and worker entries for those capabilities. + +## Install + +```bash +pnpm add @pierre/diffs +``` + +Install `react` and `react-dom` when the app uses the React entry. + +## Select an API reference + +| Surface | Reference | +| ------------------------------------------------------------ | ------------------------------------------------------ | +| Root components, parsing, and file extension APIs | [Core API](references/api-core.md) | +| Languages, themes, highlighter state, and streams | [Highlighting API](references/api-highlighting.md) | +| Renderers, managers, DOM helpers, comparisons, and constants | [Low-level rendering API](references/api-rendering.md) | +| Shared data, option, render, selection, and editor types | [Shared types](references/api-types.md) | +| `@pierre/diffs/react` | [React API](references/api-react.md) | +| `@pierre/diffs/edit` | [Editor API](references/api-editor.md) | +| `@pierre/diffs/ssr` | [SSR API](references/api-ssr.md) | +| `@pierre/diffs/worker` and worker scripts | [Worker API](references/api-worker.md) | + +## Select a recipe + +| Task | Recipe | +| ----------------------------------- | ------------------------------------------------------------------------ | +| Render a file or diff in React | [Render with React](references/recipe-react.md) | +| Render a file or diff without React | [Render with vanilla JavaScript](references/recipe-vanilla.md) | +| Build a virtualized review surface | [Use CodeView](references/recipe-code-view.md) | +| Edit a React surface or CodeView | [Edit with React](references/recipe-edit-react.md) | +| Edit a vanilla surface or CodeView | [Edit with vanilla JavaScript](references/recipe-edit-vanilla.md) | +| Preload markup on the server | [Use SSR](references/recipe-ssr.md) | +| Highlight through a worker pool | [Use workers](references/recipe-workers.md) | +| Add line annotations and selection | [Add annotations and selection](references/recipe-annotations.md) | +| Register a Shiki language or theme | [Register custom highlighting](references/recipe-custom-highlighting.md) | diff --git a/packages/diffs/skills/diffs/references/api-core.md b/packages/diffs/skills/diffs/references/api-core.md new file mode 100644 index 000000000..22b012862 --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-core.md @@ -0,0 +1,186 @@ +# Core API + +This reference covers components, parsing, merge conflicts, and file extension +APIs from `@pierre/diffs`. + +## Contents + +- [File components](#file-components) +- [Virtualized components](#virtualized-components) +- [`File` members](#file-members) +- [`FileDiff` members](#filediff-members) +- [`CodeView` members](#codeview-members) +- [Parsing and patch APIs](#parsing-and-patch-apis) +- [Merge conflict APIs](#merge-conflict-apis) +- [Annotation APIs](#annotation-apis) +- [File extension APIs](#file-extension-apis) + +## File components + +| Export | Kind | Purpose | +| --------------------------------------- | -------- | ------------------------------------------------------------- | +| `File` | Class | Renders one syntax-highlighted file. | +| `FileOptions` | Type | Configures file display, interaction, slots, and callbacks. | +| `FileRenderProps` | Type | Defines file input and a render target. | +| `FileHydrateProps` | Type | Defines file input and preloaded markup for hydration. | +| `FileDiff` | Class | Renders a file diff from files or parsed metadata. | +| `FileDiffOptions` | Type | Configures diff display, interaction, slots, and callbacks. | +| `FileDiffRenderBaseProps` | Type | Defines shared diff render input. | +| `FileDiffRenderProps` | Type | Adds files or parsed metadata to diff render input. | +| `FileDiffHydrationProps` | Type | Defines diff input and preloaded markup for hydration. | +| `FileDiffType` | Type | Identifies a standard or unresolved diff instance. | +| `UnresolvedFile` | Class | Renders one file with merge conflict controls. | +| `UnresolvedFileOptions` | Type | Configures merge conflict display and callbacks. | +| `UnresolvedFileRenderProps` | Type | Defines merge conflict render input. | +| `UnresolvedFileHydrationProps` | Type | Defines merge conflict input for hydration. | +| `MergeConflictActionsTypeOption` | Type | Selects no actions, default actions, or a custom renderer. | +| `RenderMergeConflictActions` | Type | Defines a vanilla conflict action renderer. | +| `getUnresolvedDiffHunksRendererOptions` | Function | Converts unresolved-file options to hunk renderer options. | +| `CodeView` | Class | Renders a virtualized list of files and diffs. | +| `CodeViewOptions` | Type | Configures list layout, items, slots, selection, and editing. | +| `CodeViewLineSelection` | Type | Associates a selected range with one item ID. | +| `CodeViewRenderedFileItem` | Type | Describes one mounted file item. | +| `CodeViewRenderedDiffItem` | Type | Describes one mounted diff item. | +| `CodeViewRenderedItem` | Type | Represents a mounted file or diff item. | +| `CodeViewCoordinator` | Type | Coordinates React slots with the vanilla list. | +| `CodeViewSlotSnapshot` | Type | Describes mounted items and list header or footer hosts. | +| `CodeViewScrollListener` | Type | Receives list scroll changes. | +| `CODE_VIEW_FILE_OPTION_KEYS` | Value | Lists file options that `CodeView` passes to an item. | +| `CODE_VIEW_DIFF_OPTION_KEYS` | Value | Lists diff options that `CodeView` passes to an item. | + +## Virtualized components + +| Export | Kind | Purpose | +| -------------------------------------------------- | ----- | ----------------------------------------------------------- | +| `Virtualizer` | Class | Tracks a simple viewport and connected render instances. | +| `VirtualizerConfig` | Type | Configures overscroll, observation margin, and resize logs. | +| `VirtualizedFile` | Class | Adds simple viewport behavior to `File`. | +| `VirtualizedFileDiff` | Class | Adds simple viewport behavior to `FileDiff`. | +| `VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL` | Value | Sets the line interval for virtual diff layout checkpoints. | + +## `File` members + +| Member | Purpose | +| --------------------------------------------- | ---------------------------------------------------- | +| `new File(options?, workerManager?)` | Creates one file renderer. | +| `render(props)` | Renders file contents. | +| `hydrate(props)` | Attaches to preloaded file markup. | +| `rerender()` | Renders the current file again. | +| `setOptions(options)` | Replaces file options. | +| `setThemeType(themeType)` | Selects system, light, or dark theme mode. | +| `onThemeChange()` | Applies a changed theme. | +| `setLineAnnotations(annotations)` | Replaces file annotations. | +| `setSelectedLines(range, options?)` | Replaces the selected line range. | +| `setEditorActiveLine(line, options?)` | Marks the editor's active line. | +| `getHoveredLine()` | Gets the current hovered line. | +| `getOrCreateLineCache(file?)` | Gets cached source lines. | +| `attachEditor(editor)` | Attaches an editor and returns a detach function. | +| `applyDocumentChange(document, annotations?)` | Applies an editor document update. | +| `updateRenderCache(tokens, themeType)` | Updates highlighted token cache entries. | +| `primeHighlightCache()` | Preloads the highlighted file result. | +| `renderPlaceholder(height)` | Renders a fixed-height placeholder. | +| `virtualizedSetup()` | Prepares the instance for a virtualizer. | +| `flushManagers()` | Applies deferred interaction and size manager state. | +| `cleanUp(recycle?)` | Releases rendered resources. | + +## `FileDiff` members + +`FileDiff` supports the shared `File` update, selection, annotation, editor, +hydration, placeholder, and cleanup members with diff data. + +| Member | Purpose | +| -------------------------------------------- | ------------------------------------------------ | +| `new FileDiff(options?, workerManager?)` | Creates one diff renderer. | +| `render(props)` | Parses or renders diff input. | +| `hydrate(props)` | Attaches to preloaded diff markup. | +| `rerender()` | Renders the current diff again. | +| `setOptions(options)` | Replaces diff options. | +| `getLineIndex(line, side?)` | Maps a displayed line to row and column indexes. | +| `handleExpandHunk(index, direction, count?)` | Handles a hunk expansion request. | +| `expandHunk(index, direction, count?)` | Expands hidden context around one hunk. | +| `completeEditSession()` | Recomputes diff metadata after an edit session. | +| `isLineRenderable(line)` | Tests whether an additions line is visible. | +| `getNearestRenderableLine(line, direction)` | Finds a visible additions line. | +| `revealLine(line)` | Expands context to show an additions line. | +| `primeHighlightCache(diff?)` | Preloads the highlighted diff result. | + +## `CodeView` members + +| Member | Purpose | +| ---------------------------------------- | -------------------------------------------- | +| `new CodeView(options?, workerManager?)` | Creates one virtualized list. | +| `setup(root)` | Attaches the list to its scroll root. | +| `setItems(items)` | Replaces all items. | +| `addItem(item)` | Appends one item. | +| `addItems(items)` | Appends several items. | +| `getItem(id)` | Gets one item by ID. | +| `updateItem(item)` | Replaces one item by ID. | +| `updateItemId(oldId, newId)` | Changes one item ID. | +| `getEditor(id)` | Gets the active editor for an item. | +| `scrollTo(target)` | Scrolls to a position, item, line, or range. | +| `setSelectedLines(selection, options?)` | Sets the selected item and range. | +| `getSelectedLines()` | Gets the selected item and range. | +| `clearSelectedLines(options?)` | Clears the selected lines. | +| `setOptions(options)` | Replaces list options. | +| `onThemeChange()` | Applies a changed theme to list items. | +| `render(immediate?)` | Schedules or performs a render. | +| `getWindowSpecs()` | Gets the current virtual window. | +| `getContainerElement()` | Gets the scroll content element. | +| `getHeaderElement()` | Gets the list header host. | +| `getFooterElement()` | Gets the list footer host. | +| `getRenderedItems()` | Gets mounted items. | +| `setSlotCoordinator(coordinator?)` | Sets the external slot coordinator. | +| `getSlotSnapshot(coordinator)` | Gets the coordinator's mounted slot state. | +| `subscribeToScroll(listener)` | Subscribes to scroll changes. | +| `getLocalTopForInstance(instance)` | Gets an instance offset inside the list. | +| `getTopForItem(id)` | Gets an item offset inside the list. | +| `instanceChanged(instance, layoutDirty)` | Reports a render instance change. | +| `reset()` | Clears items and render state. | +| `cleanUp()` | Releases list resources. | + +## Parsing and patch APIs + +| Export | Purpose | +| ---------------------------- | ----------------------------------------------------- | +| `parseDiffFromFile` | Creates `FileDiffMetadata` from old and new files. | +| `parsePatchFiles` | Parses a patch string into file diff metadata. | +| `processPatch` | Parses one patch section. | +| `processFile` | Converts one parsed patch file to `FileDiffMetadata`. | +| `getSingularPatch` | Selects one file patch from a patch string. | +| `trimPatchContext` | Limits unchanged context in patch text. | +| `hydratePartialDiff` | Adds loaded file contents to partial diff metadata. | +| `cloneFileDiffMetadata` | Creates a structural copy of diff metadata. | +| `cleanLastNewline` | Normalizes the final newline for diff input. | +| `getLineEndingType` | Detects a file's line-ending sequence. | +| `getTotalLineCountFromHunks` | Counts rendered rows across hunks. | +| `parseLineType` | Parses one patch line marker and content. | +| `ParsedLine` | Describes the result from `parseLineType`. | + +## Merge conflict APIs + +| Export | Purpose | +| ---------------------- | --------------------------------------------------------------- | +| `resolveConflict` | Applies one current, incoming, or combined conflict resolution. | +| `resolveRegion` | Resolves one parsed merge conflict region. | +| `diffAcceptRejectHunk` | Applies accept or reject behavior to one change hunk. | + +## Annotation APIs + +| Export | Purpose | +| ---------------------------- | ---------------------------------------------------------- | +| `isFileAnnotation` | Tests whether one annotation targets a file line. | +| `isDiffAnnotation` | Tests whether one annotation targets a diff side and line. | +| `isFileAnnotationCollection` | Tests whether an array contains file annotations. | +| `isDiffAnnotationCollection` | Tests whether an array contains diff annotations. | + +## File extension APIs + +| Export | Purpose | +| ---------------------------- | ------------------------------------------------ | +| `getFiletypeFromFileName` | Infers a language from a file name. | +| `setCustomExtension` | Maps one file name or extension to a language. | +| `replaceCustomExtensions` | Replaces all custom mappings. | +| `getCustomExtensionsMap` | Gets a copy of custom mappings. | +| `getCustomExtensionsVersion` | Gets the mapping revision. | +| `EXTENSION_TO_FILE_FORMAT` | Maps built-in extensions and names to languages. | +| `setLanguageOverride` | Assigns a language to parsed diff files. | diff --git a/packages/diffs/skills/diffs/references/api-editor.md b/packages/diffs/skills/diffs/references/api-editor.md new file mode 100644 index 000000000..671d1195d --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-editor.md @@ -0,0 +1,95 @@ +# Editor API + +This reference lists every export from `@pierre/diffs/edit` and every public +member of its classes. + +## Exports + +| Export | Kind | Purpose | +| --------------------- | ----- | --------------------------------------------------------- | +| `Editor` | Class | Adds text editing to a `File` or `FileDiff` instance. | +| `EditorChange` | Type | Describes one normalized editor change. | +| `EditorChangeEvent` | Type | Provides normalized edits and current document state. | +| `EditorOptions` | Type | Configures history, state, selections, and callbacks. | +| `TextDocument` | Class | Stores text, positions, edits, search, and undo history. | +| `TextDocumentChange` | Type | Describes the lines and characters changed by an edit. | +| `IStateStorage` | Type | Defines asynchronous or synchronous editor state storage. | +| `PersistStateStorage` | Type | Selects memory, IndexedDB, or custom state storage. | +| `Position` | Type | Identifies a zero-based line and character. | +| `Range` | Type | Identifies a start and end position. | +| `TextEdit` | Type | Replaces one range with new text. | + +## `EditorOptions` fields + +| Field | Purpose | +| ------------------------ | -------------------------------------------------------- | +| `historyMaxEntries` | Limits the undo stack. | +| `persistState` | Keeps editor state for each file cache key. | +| `persistStateStorage` | Selects the state store. | +| `roundedSelection` | Controls rounded selection corners. | +| `matchBrackets` | Controls matching-bracket highlights. | +| `autoSurround` | Controls quote and bracket insertion around a selection. | +| `languageCommentConfig` | Overrides comment tokens by language. | +| `enabledSelectionAction` | Enables the selection action surface. | +| `clipboard` | Supplies a text clipboard reader. | +| `renderSelectionAction` | Produces the selection action element. | +| `onAttach` | Receives the editor and attached surface. | +| `onChange` | Receives file state, annotations, and a change event. | +| `onFocus` | Runs after the editor gains focus. | +| `onBlur` | Runs after the editor loses focus. | + +## `Editor` members + +| Member | Purpose | +| ----------------------------------- | --------------------------------------------------------- | +| `new Editor(options?)` | Creates one editor. | +| `edit(instance)` | Attaches to a file or diff and returns a detach function. | +| `setOptions(options)` | Replaces editor options. | +| `applyEdits(edits, updateHistory?)` | Applies programmatic text edits. | +| `canUndo` | Reports whether undo has an entry. | +| `canRedo` | Reports whether redo has an entry. | +| `undo()` | Reverts the latest edit. | +| `redo()` | Reapplies the latest reverted edit. | +| `getFile()` | Gets the current file contents. | +| `getText()` | Gets the current text. | +| `getState()` | Gets selections and view state. | +| `setState(state)` | Sets selections and view state. | +| `setSelections(selections)` | Sets directed selection ranges. | +| `setMarkers(markers)` | Sets diagnostic markers. | +| `focus(options?)` | Focuses the editor. | +| `blur()` | Removes editor focus. | +| `cleanUp(recycle?)` | Releases editor resources. | + +## `TextDocument` members + +| Member | Purpose | +| ---------------------------------------------------- | ----------------------------------------------------- | +| `new TextDocument(uri, text, languageId?, version?)` | Creates a text document. | +| `uri` | Gets the document identifier. | +| `languageId` | Gets the language identifier. | +| `version` | Gets the document version. | +| `lineCount` | Gets the line count. | +| `eol` | Gets the line-ending sequence. | +| `canUndo` | Reports whether undo has an entry. | +| `canRedo` | Reports whether redo has an entry. | +| `positionAt(offset)` | Converts an offset to a position. | +| `positionsAt(offsets)` | Converts several offsets to positions. | +| `offsetAt(position)` | Converts a position to an offset. | +| `getText(range?)` | Gets all text or one range. | +| `getLineText(line, includeLineBreak?)` | Gets one line. | +| `normalizeEol(text)` | Converts text to the document line ending. | +| `getLineLength(line, includeLineBreak?)` | Gets one line length. | +| `charAt(offsetOrPosition)` | Gets one character. | +| `getTextSlice(start, end)` | Gets text between two offsets. | +| `findNextNonOverlappingSubstring(needle, occupied)` | Finds an unused substring range. | +| `search(params)` | Finds text ranges. | +| `applyEdits(edits, ...)` | Resolves and applies position-based edits. | +| `resolveEdits(edits)` | Converts position-based edits to offset edits. | +| `applyResolvedEdits(edits, ...)` | Applies offset-based edits. | +| `setLastUndoSelectionsAfter(selections)` | Associates selections with the latest history entry. | +| `setLastUndoLineAnnotations(before, after)` | Associates annotations with the latest history entry. | +| `undo()` | Reverts one document history entry. | +| `redo()` | Reapplies one document history entry. | +| `normalizePosition(position)` | Clamps a position to the document. | + +`IStateStorage` has `get(cacheKey)` and `set(cacheKey, state)` methods. diff --git a/packages/diffs/skills/diffs/references/api-highlighting.md b/packages/diffs/skills/diffs/references/api-highlighting.md new file mode 100644 index 000000000..861d8884f --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-highlighting.md @@ -0,0 +1,113 @@ +# Highlighting API + +This reference lists every language, theme, shared highlighter, and stream +export from `@pierre/diffs`. + +## Contents + +- [Shiki passthrough APIs](#shiki-passthrough-apis) +- [Language APIs](#language-apis) +- [Theme APIs](#theme-apis) +- [Shared highlighter APIs](#shared-highlighter-apis) +- [Render APIs](#render-apis) +- [Stream APIs](#stream-apis) + +## Shiki passthrough APIs + +| Export | Kind | Purpose | +| ------------------------- | -------- | ------------------------------------------------ | +| `codeToHtml` | Function | Re-exports Shiki's complete code-to-HTML helper. | +| `createCSSVariablesTheme` | Function | Re-exports Shiki's CSS variable theme factory. | + +## Language APIs + +| Export | Kind | Purpose | +| ------------------------------ | -------- | --------------------------------------------------------- | +| `registerCustomLanguage` | Function | Registers a lazy language and optional file mappings. | +| `resolveLanguage` | Function | Loads and caches one language registration. | +| `resolveLanguages` | Function | Loads and caches several language registrations. | +| `getResolvedOrResolveLanguage` | Function | Returns one cached language or starts its load. | +| `getResolvedLanguages` | Function | Gets cached registrations for the supplied languages. | +| `hasResolvedLanguages` | Function | Tests whether language registrations are cached. | +| `attachResolvedLanguages` | Function | Adds resolved registrations to a highlighter. | +| `areLanguagesAttached` | Function | Tests whether a highlighter has the supplied languages. | +| `cleanUpResolvedLanguages` | Function | Clears language resolution state. | +| `RegisteredCustomLanguages` | Map | Stores registered custom language loaders. | +| `ResolvedLanguages` | Map | Stores resolved language registrations. | +| `ResolvingLanguages` | Map | Stores active language load promises. | +| `AttachedLanguages` | Set | Stores language names attached to the shared highlighter. | + +## Theme APIs + +| Export | Kind | Purpose | +| -------------------------------- | -------- | ------------------------------------------------------ | +| `registerCustomTheme` | Function | Registers a lazy Shiki theme loader. | +| `CustomThemeLoader` | Type | Defines a raw or resolved Shiki theme loader. | +| `registerCustomCSSVariableTheme` | Function | Registers a theme that reads CSS variables. | +| `resolveTheme` | Function | Loads and caches one theme. | +| `resolveThemes` | Function | Loads and caches several themes. | +| `getResolvedOrResolveTheme` | Function | Returns one cached theme or starts its load. | +| `getResolvedThemes` | Function | Gets cached themes by name. | +| `hasResolvedThemes` | Function | Tests whether themes are cached. | +| `attachResolvedThemes` | Function | Adds resolved themes to a highlighter. | +| `areThemesAttached` | Function | Tests whether a highlighter has the supplied themes. | +| `cleanUpResolvedThemes` | Function | Clears theme resolution state. | +| `AttachedThemes` | Set | Stores theme names attached to the shared highlighter. | + +## Shared highlighter APIs + +| Export | Purpose | +| --------------------------- | ----------------------------------------------------------------- | +| `getSharedHighlighter` | Gets or creates the shared highlighter for themes and languages. | +| `preloadHighlighter` | Loads the shared highlighter before a render. | +| `getHighlighterIfLoaded` | Gets the shared highlighter after load. | +| `isHighlighterLoaded` | Tests a highlighter cache value for a loaded instance. | +| `isHighlighterLoading` | Tests a highlighter cache value for an active promise. | +| `isHighlighterNull` | Tests a highlighter cache value for an empty state. | +| `disposeHighlighter` | Disposes and clears the shared highlighter. | +| `getHighlighterOptions` | Converts one language and component options to highlighter input. | +| `getHighlighterThemeStyles` | Creates theme CSS from a loaded highlighter. | +| `getThemes` | Converts one theme or light/dark pair to a name list. | +| `isWorkerContext` | Tests whether code runs in a worker global scope. | + +## Render APIs + +| Export | Purpose | +| ---------------------------- | ------------------------------------------------------- | +| `renderFileWithHighlighter` | Creates a highlighted file syntax tree. | +| `renderDiffWithHighlighter` | Creates highlighted deletion and addition syntax trees. | +| `createTransformerWithState` | Creates Shiki transformers with shared render state. | + +## Stream APIs + +| Export | Kind | Purpose | +| ----------------------------------- | ----- | ------------------------------------------------------------- | +| `FileStream` | Class | Renders a readable code stream as highlighted rows. | +| `FileStreamOptions` | Type | Configures stream language, theme, start line, and callbacks. | +| `CodeToTokenTransformStream` | Class | Converts code chunks to themed or recall tokens. | +| `CodeToTokenTransformStreamOptions` | Type | Configures stream tokenization and recall tokens. | +| `ShikiStreamTokenizer` | Class | Tracks stable and unstable tokens across code chunks. | +| `ShikiStreamTokenizerOptions` | Type | Supplies Shiki token options and a highlighter. | +| `ShikiStreamTokenizerEnqueueResult` | Type | Returns recalled, stable, and unstable tokens for one chunk. | +| `RecallToken` | Type | Requests removal of prior unstable tokens. | + +## `FileStream` members + +| Member | Purpose | +| -------------------------- | ------------------------------------------ | +| `new FileStream(options?)` | Creates a stream renderer. | +| `setup(source, wrapper)` | Connects a readable code stream to a host. | +| `setThemeType(themeType)` | Selects system, light, or dark theme mode. | +| `cleanUp()` | Aborts the stream and releases resources. | + +## `ShikiStreamTokenizer` members + +| Member | Purpose | +| ----------------------------------- | ------------------------------------ | +| `new ShikiStreamTokenizer(options)` | Creates a stateful tokenizer. | +| `enqueue(chunk)` | Tokenizes one code chunk. | +| `close()` | Finalizes and returns stable tokens. | +| `clear()` | Clears accumulated token state. | +| `clone()` | Copies current tokenizer state. | + +`CodeToTokenTransformStream` exposes its `tokenizer` and `options` values. diff --git a/packages/diffs/skills/diffs/references/api-react.md b/packages/diffs/skills/diffs/references/api-react.md new file mode 100644 index 000000000..96e6bf76e --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-react.md @@ -0,0 +1,63 @@ +# React API + +This reference lists the React-specific exports from `@pierre/diffs/react`. The +entry also re-exports every type in [Shared types](api-types.md). + +## Components and hooks + +| Export | Kind | Purpose | +| --------------------------- | --------- | --------------------------------------------------------- | +| `File` | Component | Renders one code file. | +| `FileDiff` | Component | Renders pre-parsed diff metadata. | +| `MultiFileDiff` | Component | Parses and renders an old and new file pair. | +| `PatchDiff` | Component | Parses and renders one unified patch string. | +| `UnresolvedFile` | Component | Renders and resolves merge conflicts in one file. | +| `CodeView` | Component | Renders a virtualized list of files and diffs. | +| `Virtualizer` | Component | Provides simple viewport virtualization. | +| `useVirtualizer` | Hook | Gets the nearest simple `Virtualizer` instance. | +| `EditProvider` | Component | Supplies an editor factory. | +| `useCreateEditor` | Hook | Gets the nearest editor factory. | +| `WorkerPoolContextProvider` | Component | Creates and supplies a worker pool. | +| `useWorkerPool` | Hook | Gets the nearest worker pool. | +| `useFileInstance` | Hook | Creates and manages a vanilla `File` instance. | +| `useFileDiffInstance` | Hook | Creates and manages a vanilla `FileDiff` instance. | +| `useStableCallback` | Hook | Returns a stable callback that reads the latest function. | + +## Component and provider types + +| Export | Purpose | +| ----------------------------------- | ----------------------------------------------------------------- | +| `FileProps` | Defines props for `File`. | +| `FileOptions` | Defines vanilla file options and the React `options` prop. | +| `FileDiffProps` | Defines props for `FileDiff`. | +| `MultiFileDiffProps` | Defines props for `MultiFileDiff`. | +| `PatchDiffProps` | Defines props for `PatchDiff`. | +| `UnresolvedFileProps` | Defines props for `UnresolvedFile`. | +| `UnresolvedFileReactOptions` | Defines merge-conflict options for React. | +| `DiffBasePropsReact` | Defines props shared by React diff components. | +| `CodeViewProps` | Defines controlled or uncontrolled `CodeView` props. | +| `ControlledCodeViewProps` | Defines `CodeView` props with `items`. | +| `UncontrolledCodeViewProps` | Defines `CodeView` props with `initialItems`. | +| `CodeViewReactOptions` | Defines the React-safe `CodeView` option set. | +| `CodeViewHandle` | Defines imperative list, selection, scroll, and editor controls. | +| `CreateEditor` | Defines the editor factory. | +| `EditProviderProps` | Defines the `EditProvider` factory prop. | +| `MergeConflictActionsTypeOption` | Selects no actions, default actions, or a custom action renderer. | +| `RenderMergeConflictActionContext` | Supplies conflict resolution to a custom action renderer. | +| `RenderMergeConflictActions` | Defines a custom conflict action renderer. | +| `WorkerInitializationRenderOptions` | Defines initial worker languages and render options. | +| `WorkerPoolOptions` | Defines the worker factory, pool size, and cache size. | + +## Contexts and render helpers + +| Export | Kind | Purpose | +| ------------------------- | -------- | ------------------------------------------------------ | +| `EditContext` | Context | Holds the editor factory. | +| `WorkerPoolContext` | Context | Holds the worker pool. | +| `VirtualizerContext` | Context | Holds the simple virtualizer. | +| `GutterUtilitySlotStyles` | Value | Supplies style keys for gutter utility slots. | +| `MergeConflictSlotStyles` | Value | Supplies style keys for merge conflict slots. | +| `noopRender` | Function | Returns no React output for an optional render slot. | +| `renderDiffChildren` | Function | Builds React portals for diff slots. | +| `renderFileChildren` | Function | Builds React portals for file slots. | +| `templateRender` | Function | Renders React content through a managed template slot. | diff --git a/packages/diffs/skills/diffs/references/api-rendering.md b/packages/diffs/skills/diffs/references/api-rendering.md new file mode 100644 index 000000000..5e9de9707 --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-rendering.md @@ -0,0 +1,183 @@ +# Low-level rendering API + +This reference lists the renderer, manager, DOM helper, comparison, and constant +exports from `@pierre/diffs`. + +## Contents + +- [Renderers](#renderers) +- [Interaction manager](#interaction-manager) +- [Size, scroll, and render managers](#size-scroll-and-render-managers) +- [Comparison helpers](#comparison-helpers) +- [Syntax tree and DOM helpers](#syntax-tree-and-dom-helpers) +- [Layout and CSS helpers](#layout-and-css-helpers) +- [Constants](#constants) + +## Renderers + +| Export | Kind | Purpose | +| -------------------------------------- | ----- | ------------------------------------------------------- | +| `FileRenderer` | Class | Converts one file to highlighted HAST, CSS, and HTML. | +| `FileRendererOptions` | Type | Adds header mode to base code options. | +| `FileRenderResult` | Type | Holds file HAST, CSS, row counts, and buffers. | +| `DiffHunksRenderer` | Class | Converts diff hunks to highlighted column HAST and CSS. | +| `DiffHunksRendererOptions` | Type | Configures one hunk renderer. | +| `DiffHunksRendererOptionsWithDefaults` | Type | Describes resolved hunk renderer options. | +| `HunksRenderResult` | Type | Holds rendered diff columns, metadata, and row count. | +| `RenderedLineContext` | Type | Supplies line state to a line decoration. | +| `LineDecoration` | Type | Defines a custom line wrapper and injected rows. | +| `InjectedRow` | Type | Defines one row inserted around a unified line. | +| `SplitInjectedRow` | Type | Defines one row inserted around a split line. | +| `UnifiedInjectedRowPlacement` | Type | Selects placement before or after a unified row. | +| `SplitInjectedRowPlacement` | Type | Selects side and placement for a split row. | +| `UnifiedLineDecorationProps` | Type | Supplies one unified row to a decoration. | +| `SplitLineDecorationProps` | Type | Supplies paired split rows to a decoration. | + +## Interaction manager + +| Export | Kind | Purpose | +| ------------------------------- | -------- | ------------------------------------------------------------------------ | +| `InteractionManager` | Class | Handles hover, token, gutter, and line selection events. | +| `InteractionManagerMode` | Type | Selects file or diff interaction data. | +| `InteractionManagerBaseOptions` | Type | Defines interaction callbacks and enabled features. | +| `InteractionManagerOptions` | Type | Adds required DOM access to base interaction options. | +| `GetHoveredLineResult` | Type | Describes the current hovered file or diff line. | +| `GetLineIndexUtility` | Type | Maps a logical line to row and column indexes. | +| `OnLineClickProps` | Type | Describes a file line click. | +| `OnLineEnterLeaveProps` | Type | Describes file line pointer entry or exit. | +| `OnDiffLineClickProps` | Type | Describes a diff line click. | +| `OnDiffLineEnterLeaveProps` | Type | Describes diff line pointer entry or exit. | +| `OnTokenEventProps` | Type | Selects file or diff token event data. | +| `SelectionWriteOptions` | Type | Configures callback emission, the active side, and line-only highlights. | +| `MergeConflictActionTarget` | Type | Describes a merge conflict action element. | +| `LogTypes` | Type | Selects interaction log categories. | +| `pluckInteractionOptions` | Function | Selects interaction fields from component options. | + +## Size, scroll, and render managers + +| Export | Kind | Purpose | +| --------------------------------- | -------- | ------------------------------------------------------------- | +| `ResizeManager` | Class | Measures rows, annotations, and column CSS values. | +| `ResizeManagerColumnVariableMode` | Type | Selects column variable measurement or application. | +| `ResizeManagerSetupOptions` | Type | Configures annotation and column measurement. | +| `ScrollSyncManager` | Class | Synchronizes additions and deletions column scroll positions. | +| `queueRender` | Function | Adds a callback to the shared animation render queue. | +| `dequeueRender` | Function | Removes a callback from the shared render queue. | +| `clearRenderQueue` | Function | Removes all callbacks from the shared render queue. | + +## Comparison helpers + +| Export | Purpose | +| ----------------------------- | ------------------------------------------------- | +| `areDiffLineAnnotationsEqual` | Compares two diff annotation arrays. | +| `areLineAnnotationsEqual` | Compares two file annotation arrays. | +| `areDiffRenderOptionsEqual` | Compares resolved diff render options. | +| `areFileRenderOptionsEqual` | Compares resolved file render options. | +| `areDiffTargetsEqual` | Compares two diff interaction targets. | +| `areFilesEqual` | Compares two file inputs. | +| `areHunkDataEqual` | Compares two hunk data objects. | +| `areObjectsEqual` | Performs the package's shallow object comparison. | +| `areOptionsEqual` | Compares component option objects. | +| `arePrePropertiesEqual` | Compares calculated `pre` properties. | +| `areRenderRangesEqual` | Compares two render ranges. | +| `areSelectionsEqual` | Compares editor selection arrays. | +| `areThemesEqual` | Compares theme names or light/dark pairs. | +| `areVirtualWindowSpecsEqual` | Compares two virtual window descriptions. | +| `areWorkerStatsEqual` | Compares two worker statistics objects. | + +## Syntax tree and DOM helpers + +| Export | Kind | Purpose | +| -------------------------------- | -------- | ---------------------------------------------------------- | +| `createAnnotationElement` | Function | Creates a HAST annotation row from an annotation span. | +| `createAnnotationWrapperNode` | Function | Creates a DOM host for an annotation slot. | +| `createDiffSpanDecoration` | Function | Creates one Shiki inline diff decoration. | +| `pushOrJoinSpan` | Function | Adds or joins one inline diff span. | +| `createEmptyRowBuffer` | Function | Creates an empty virtual row buffer. | +| `createFileHeaderElement` | Function | Creates a file or diff header HAST element. | +| `CreateFileHeaderElementProps` | Type | Defines header source, mode, and sticky state. | +| `createGutterGap` | Function | Creates a gutter gap HAST element. | +| `createGutterItem` | Function | Creates a gutter item HAST element. | +| `createGutterWrapper` | Function | Creates a gutter wrapper HAST element. | +| `createGutterUtilityElement` | Function | Creates a gutter utility HAST element. | +| `createGutterUtilityContentNode` | Function | Creates a gutter utility DOM content host. | +| `createHastElement` | Function | Creates a typed HAST element. | +| `createIconElement` | Function | Creates a sprite icon HAST element. | +| `createTextNodeElement` | Function | Creates a HAST text node. | +| `createNoNewlineElement` | Function | Creates the missing-final-newline HAST element. | +| `createPreElement` | Function | Creates the outer HAST `pre` element. | +| `createPreWrapperProperties` | Function | Creates HAST properties for a `pre` wrapper. | +| `createRowNodes` | Function | Creates DOM row and content elements for one line. | +| `createSeparator` | Function | Creates a hunk separator HAST element. | +| `createSpanFromToken` | Function | Creates a HAST span from one highlighted token. | +| `createStyleElement` | Function | Creates a DOM style element with an attribute marker. | +| `createThemeStyleElement` | Function | Creates a marked theme style element. | +| `createUnsafeCSSStyleNode` | Function | Creates a marked custom CSS style element. | +| `findCodeElement` | Function | Finds the code element in a HAST tree. | +| `getLineNodes` | Function | Gets rendered line nodes from a HAST root. | +| `getOrCreateCodeNode` | Function | Reuses or creates a code column DOM node. | +| `getLineAnnotationName` | Function | Creates the slot name for a line annotation. | +| `getHunkSeparatorSlotName` | Function | Creates the slot name for a hunk separator. | +| `getIconForType` | Function | Maps a file change type to a sprite icon. | +| `processLine` | Function | Applies line render state to one HAST line. | +| `setPreNodeProperties` | Function | Applies resolved render properties to a DOM `pre` element. | +| `prerenderHTMLIfNecessary` | Function | Adds preloaded HTML to an empty host element. | + +## Layout and CSS helpers + +| Export | Purpose | +| -------------------------------- | ------------------------------------------------------------- | +| `createWindowFromScrollPosition` | Calculates a virtual window from scroll measurements. | +| `isDefaultRenderRange` | Tests whether a render range covers the default full range. | +| `prefersReducedMotion` | Reads the reduced-motion media preference. | +| `formatCSSVariablePrefix` | Creates the global or token CSS variable prefix. | +| `wrapCoreCSS` | Places core CSS in its cascade layer. | +| `wrapThemeCSS` | Places theme CSS in its layer and mode selector. | +| `wrapUnsafeCSS` | Places custom CSS in its cascade layer. | +| `patchScrollbarGutterSize` | Updates the measured scrollbar gutter in theme CSS. | +| `detachString` | Copies a retained substring to an independent backing string. | +| `releaseStringDetachBuffer` | Resets the reusable string copy buffer. | +| `SVGSpriteSheet` | Contains the SVG symbols used by rendered controls. | +| `SVGSpriteNames` | Names a symbol in `SVGSpriteSheet`. | + +## Constants + +| Export | Purpose | +| ------------------------------------------ | ----------------------------------------------------- | +| `DEFAULT_THEMES` | Provides the default light and dark theme names. | +| `DEFAULT_TOKENIZE_MAX_LENGTH` | Provides the default total tokenization limit. | +| `DEFAULT_COLLAPSED_CONTEXT_THRESHOLD` | Provides the default hidden-context threshold. | +| `DEFAULT_EXPANDED_REGION` | Provides the default hunk expansion state. | +| `DEFAULT_RENDER_RANGE` | Provides the full render range. | +| `EMPTY_RENDER_RANGE` | Provides an empty render range. | +| `DEFAULT_VIRTUAL_FILE_METRICS` | Provides estimated file header and line heights. | +| `DEFAULT_CODE_VIEW_FILE_METRICS` | Provides list item height estimates. | +| `DEFAULT_CODE_VIEW_LAYOUT` | Provides an empty list layout. | +| `DEFAULT_SMOOTH_SCROLL_SETTINGS` | Provides the default smooth scroll settings. | +| `DIFFS_TAG_NAME` | Provides the `diffs-container` custom element name. | +| `CORE_CSS_ATTRIBUTE` | Provides the core style marker attribute. | +| `THEME_CSS_ATTRIBUTE` | Provides the theme style marker attribute. | +| `UNSAFE_CSS_ATTRIBUTE` | Provides the custom style marker attribute. | +| `DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE` | Provides the scrollbar measurement attribute. | +| `DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY` | Provides the measured scrollbar CSS property. | +| `CODE_VIEW_HEADER_ATTRIBUTE` | Provides the list header host attribute. | +| `CODE_VIEW_FOOTER_ATTRIBUTE` | Provides the list footer host attribute. | +| `CUSTOM_HEADER_SLOT_ID` | Provides the custom header slot ID. | +| `HEADER_PREFIX_SLOT_ID` | Provides the header prefix slot ID. | +| `HEADER_FILENAME_SUFFIX_SLOT_ID` | Provides the filename suffix slot ID. | +| `HEADER_METADATA_SLOT_ID` | Provides the header metadata slot ID. | +| `HUNK_HEADER` | Provides the patch hunk header marker. | +| `FILE_CONTEXT_BLOB` | Matches a patch hunk boundary. | +| `INDEX_LINE_METADATA` | Provides the patch index metadata marker. | +| `COMMIT_METADATA_SPLIT` | Provides the commit metadata separator expression. | +| `FILENAME_HEADER_REGEX` | Matches a standard patch file header. | +| `FILENAME_HEADER_REGEX_GIT` | Matches a Git patch file header. | +| `GIT_DIFF_FILE_BREAK_REGEX` | Matches a Git patch file boundary. | +| `UNIFIED_DIFF_FILE_BREAK_REGEX` | Matches a unified patch file boundary. | +| `ALTERNATE_FILE_NAMES_GIT` | Matches alternate file names in a Git patch header. | +| `MERGE_CONFLICT_START_MARKER_REGEX` | Matches a conflict start marker. | +| `MERGE_CONFLICT_BASE_MARKER_REGEX` | Matches a conflict base marker. | +| `MERGE_CONFLICT_SEPARATOR_MARKER_REGEX` | Matches a conflict separator marker. | +| `MERGE_CONFLICT_END_MARKER_REGEX` | Matches a conflict end marker. | +| `SPLIT_WITH_NEWLINES` | Splits text while it preserves newline tokens. | +| `DIFFS_DEVELOPMENT_BUILD` | Reports whether the package uses a development build. | diff --git a/packages/diffs/skills/diffs/references/api-ssr.md b/packages/diffs/skills/diffs/references/api-ssr.md new file mode 100644 index 000000000..6f5b7e61f --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-ssr.md @@ -0,0 +1,35 @@ +# SSR API + +This reference lists the SSR-specific exports from `@pierre/diffs/ssr`. The +entry also re-exports every type in [Shared types](api-types.md). + +## Functions + +| Export | Purpose | +| --------------------------- | ------------------------------------------------------------- | +| `preloadFile` | Renders one file and returns props with `prerenderedHTML`. | +| `preloadFileDiff` | Renders pre-parsed diff metadata and returns component props. | +| `preloadMultiFileDiff` | Parses and renders an old and new file pair. | +| `preloadPatchDiff` | Parses and renders one patch for `PatchDiff`. | +| `preloadPatchFile` | Parses a multi-file patch and returns one result per file. | +| `preloadUnresolvedFile` | Renders one merge-conflict file and returns component props. | +| `preloadDiffHTML` | Renders a diff directly to an HTML string. | +| `preloadUnresolvedFileHTML` | Renders a merge-conflict file directly to an HTML string. | +| `renderHTML` | Serializes rendered HAST elements to HTML. | + +## Types + +| Export | Purpose | +| ------------------------------ | -------------------------------------------------------- | +| `PreloadFileOptions` | Defines input for `preloadFile`. | +| `PreloadedFileResult` | Adds `prerenderedHTML` to file input. | +| `PreloadDiffOptions` | Defines parsed or file-pair input for `preloadDiffHTML`. | +| `PreloadFileDiffOptions` | Defines input for `preloadFileDiff`. | +| `PreloadFileDiffResult` | Adds `prerenderedHTML` to parsed diff input. | +| `PreloadMultiFileDiffOptions` | Defines input for `preloadMultiFileDiff`. | +| `PreloadMultiFileDiffResult` | Adds `prerenderedHTML` to file-pair input. | +| `PreloadPatchDiffOptions` | Defines input for `preloadPatchDiff`. | +| `PreloadPatchDiffResult` | Adds `prerenderedHTML` to patch input. | +| `PreloadPatchFileOptions` | Defines input for `preloadPatchFile`. | +| `PreloadUnresolvedFileOptions` | Defines input for `preloadUnresolvedFile`. | +| `PreloadUnresolvedFileResult` | Adds `prerenderedHTML` to merge-conflict input. | diff --git a/packages/diffs/skills/diffs/references/api-types.md b/packages/diffs/skills/diffs/references/api-types.md new file mode 100644 index 000000000..deed8152d --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-types.md @@ -0,0 +1,176 @@ +# Shared types + +This reference lists every export from the shared `@pierre/diffs` type module. +The root, React, and SSR entries re-export these types. + +## Contents + +- [Files and patches](#files-and-patches) +- [Themes and options](#themes-and-options) +- [Annotations and selection](#annotations-and-selection) +- [`CodeView` types](#codeview-types) +- [Lines, hunks, and render state](#lines-hunks-and-render-state) +- [Render results and virtualization](#render-results-and-virtualization) +- [Component and editor contracts](#component-and-editor-contracts) +- [Shiki and diff types](#shiki-and-diff-types) + +## Files and patches + +| Export | Purpose | +| ------------------------------- | ----------------------------------------------------------------- | +| `FileContents` | Describes a file name, text, language, header, and cache key. | +| `DiffFileInput` | Accepts an old and new file for changes, additions, or deletions. | +| `MaybeDiffFileInput` | Accepts a file pair or no file input. | +| `FileDiffContentsLoader` | Loads complete files for partial diff metadata. | +| `FileDiffLoadedChangedFiles` | Returns both files for a loaded changed diff. | +| `FileDiffLoadedPureRenamedFile` | Returns the new file for a loaded pure rename. | +| `FileDiffLoadedFiles` | Represents either loaded-file result. | +| `ChangeTypes` | Names changed, renamed, added, or deleted file states. | +| `ParsedPatch` | Holds patch metadata and parsed files. | +| `ContextContent` | Describes one unchanged hunk block. | +| `ChangeContent` | Describes one additions and deletions block. | +| `Hunk` | Describes one parsed patch hunk. | +| `FileDiffMetadata` | Holds parsed file names, lines, hunks, and change metadata. | +| `MergeConflictMarkerRowType` | Names a merge conflict marker row. | +| `MergeConflictMarkerRow` | Describes one marker row and its source line. | +| `MergeConflictRegion` | Describes one parsed merge conflict region. | +| `MergeConflictResolution` | Selects current, incoming, or both conflict contents. | +| `MergeConflictActionPayload` | Describes one conflict action and region. | +| `ProcessFileConflictData` | Holds state while patch parsing processes conflicts. | +| `ConflictResolverTypes` | Names current, incoming, or both conflict choices. | + +## Themes and options + +| Export | Purpose | +| ------------------------------------ | ------------------------------------------------------------ | +| `SupportedLanguages` | Accepts a bundled, text, ANSI, or custom language name. | +| `HighlighterTypes` | Selects the JavaScript or WebAssembly Shiki engine. | +| `HighlightedToken` | Stores a character index, foreground, and token text. | +| `DiffsThemeNames` | Accepts a bundled or custom theme name. | +| `ThemesType` | Maps light and dark schemes to theme names. | +| `ThemeTypes` | Selects system, light, or dark mode. | +| `DiffsHighlighter` | Defines the package's configured Shiki highlighter. | +| `BaseCodeOptions` | Configures themes, wrapping, headers, tokenization, and CSS. | +| `BaseDiffOptions` | Adds layout, indicators, context, and line diff options. | +| `BaseDiffOptionsWithDefaults` | Describes required diff options after defaults apply. | +| `DiffIndicators` | Selects classic, bar, or hidden diff indicators. | +| `HunkSeparators` | Selects the hunk separator presentation. | +| `LineDiffTypes` | Selects word, alternate word, character, or no inline diff. | +| `FileHeaderRenderMode` | Selects a default or custom file header. | +| `CustomPreProperties` | Defines custom properties for the rendered `pre` element. | +| `PrePropertiesConfig` | Describes calculated `pre` element properties. | +| `ExtensionFormatMap` | Maps file names or extensions to languages. | +| `RenderHeaderPrefixCallback` | Produces prefix content for a diff header. | +| `RenderHeaderFilenameSuffixCallback` | Produces filename suffix content for a diff header. | +| `RenderHeaderMetadataCallback` | Produces metadata content for a diff header. | +| `RenderFileMetadata` | Produces header content for a file. | +| `PostRenderPhase` | Names mount, update, or unmount callback phases. | + +## Annotations and selection + +| Export | Purpose | +| ------------------------- | ------------------------------------------------------------ | +| `AnnotationSide` | Selects deletions or additions for an annotation. | +| `LineAnnotation` | Associates metadata with one file line. | +| `DiffLineAnnotation` | Associates metadata with one side and line. | +| `AnnotationLineMap` | Groups diff annotations by line number. | +| `SelectedLineRange` | Describes a selected start and end across diff sides. | +| `SelectionSide` | Selects deletions or additions for a selection. | +| `SelectionPoint` | Describes one line and optional side. | +| `SelectionDirection` | Describes backward, neutral, or forward selection direction. | +| `EditorActiveLineOptions` | Configures reveal behavior for an editor active line. | + +## `CodeView` types + +| Export | Purpose | +| ------------------------------ | -------------------------------------------------------- | +| `CodeViewFileItem` | Describes one file item in a virtualized list. | +| `CodeViewDiffItem` | Describes one diff item in a virtualized list. | +| `CodeViewItem` | Represents a file or diff list item. | +| `CodeViewCreateEditorOptions` | Adds an item ID to editor creation options. | +| `CodeViewScrollBehavior` | Selects instant, smooth, or automatic smooth scroll. | +| `CodeViewScrollTarget` | Represents any supported list scroll target. | +| `CodeViewPositionScrollTarget` | Scrolls to an absolute list position. | +| `CodeViewLineScrollTarget` | Scrolls to one item line. | +| `CodeViewRangeScrollTarget` | Scrolls to one item line range. | +| `CodeViewItemScrollTarget` | Scrolls to one item boundary. | +| `NumericScrollLineAnchor` | Describes a numeric position inside a line. | +| `CodeViewLayout` | Stores item offsets, heights, and total list height. | +| `PendingCodeViewLayoutReset` | Describes a deferred list layout reset. | +| `SmoothScrollSettings` | Configures duration and distance for smooth list scroll. | + +## Lines, hunks, and render state + +| Export | Purpose | +| ---------------------------- | --------------------------------------------------------------- | +| `HunkLineType` | Names context, expanded, addition, deletion, or metadata lines. | +| `HunkData` | Describes one hunk's render indexes and line ranges. | +| `HunkExpansionRegion` | Describes expanded context above and below a hunk. | +| `ExpansionDirections` | Selects up, down, or both expansion directions. | +| `DiffAcceptRejectHunkType` | Selects accept, reject, or both hunk controls. | +| `DiffAcceptRejectHunkConfig` | Configures hunk accept and reject behavior. | +| `GapSpan` | Describes an empty row span. | +| `AnnotationSpan` | Describes an annotation row span. | +| `LineSpans` | Represents a gap or annotation span. | +| `LineTypes` | Names rendered context and change line classes. | +| `LineInfo` | Describes a rendered line number, side, and type. | +| `CodeColumnType` | Selects unified, additions, or deletions columns. | +| `LineEventBaseProps` | Supplies a file line to an interaction callback. | +| `DiffLineEventBaseProps` | Supplies a diff line and side to an interaction callback. | +| `TokenEventBase` | Supplies a token and source event. | +| `DiffTokenEventBaseProps` | Adds diff side data to a token event. | +| `ObservedAnnotationNodes` | Stores DOM nodes for observed annotations. | +| `ObservedGridNodes` | Stores DOM nodes for observed grid columns. | +| `SharedRenderState` | Holds shared token transformer render state. | +| `StickySpecs` | Describes sticky header position and height. | + +## Render results and virtualization + +| Export | Purpose | +| --------------------------- | ------------------------------------------------------- | +| `RenderFileOptions` | Defines the resolved options for a highlighted file. | +| `RenderDiffOptions` | Defines the resolved options for a highlighted diff. | +| `ForceFilePlainTextOptions` | Selects a plain-text file range. | +| `ForceDiffPlainTextOptions` | Selects a plain-text diff range and hunk state. | +| `ThemedFileResult` | Holds the highlighted file syntax tree and line count. | +| `ThemedDiffResult` | Holds highlighted additions and deletions syntax trees. | +| `RenderDiffFilesResult` | Holds the resolved old and new file inputs. | +| `RenderFileResult` | Holds file output and the options that produced it. | +| `RenderDiffResult` | Holds diff output and the options that produced it. | +| `RenderedFileASTCache` | Stores one cached file syntax tree by theme. | +| `RenderedDiffASTCache` | Stores one cached diff syntax tree by theme. | +| `AppliedThemeStyleCache` | Stores applied light and dark theme CSS. | +| `RenderRange` | Describes a start row, row count, and buffer sizes. | +| `RenderWindow` | Describes first and last rows in a render window. | +| `VirtualWindowSpecs` | Describes viewport position, height, and row window. | +| `VirtualFileMetrics` | Describes estimated header and line heights. | + +## Component and editor contracts + +| Export | Purpose | +| ------------------------ | ----------------------------------------------------------- | +| `DiffsComponentOptions` | Defines shared options for a render component. | +| `DiffsBaseComponent` | Defines the common file and diff component methods. | +| `DiffsEditableComponent` | Adds editor attachment and document updates to a component. | +| `EditableInstance` | Selects an editable file or diff instance. | +| `DiffsEditor` | Defines the editor interface that render components use. | +| `DiffsTextDocument` | Defines the text document interface that components use. | +| `Position` | Identifies a zero-based line and character. | +| `Range` | Identifies start and end positions. | +| `TextEdit` | Replaces one range with new text. | +| `EditorSelection` | Adds direction to a range. | +| `EditorState` | Holds editor selections and view state. | + +## Shiki and diff types + +| Export | Purpose | +| -------------------------------- | ----------------------------------------------- | +| `BundledLanguage` | Names a language bundled by Shiki. | +| `CodeToHastOptions` | Configures Shiki code-to-HAST output. | +| `DecorationItem` | Describes a Shiki source decoration. | +| `LanguageRegistration` | Describes a Shiki language grammar. | +| `ShikiTransformer` | Defines a Shiki syntax tree transformer. | +| `ThemeRegistration` | Describes a raw Shiki theme. | +| `ThemeRegistrationResolved` | Describes a normalized Shiki theme. | +| `ThemedToken` | Describes one Shiki token with its theme style. | +| `CreatePatchOptionsNonabortable` | Configures the underlying patch algorithm. | diff --git a/packages/diffs/skills/diffs/references/api-worker.md b/packages/diffs/skills/diffs/references/api-worker.md new file mode 100644 index 000000000..cb204dac6 --- /dev/null +++ b/packages/diffs/skills/diffs/references/api-worker.md @@ -0,0 +1,91 @@ +# Worker API + +This reference lists every export from `@pierre/diffs/worker`, every public +`WorkerPoolManager` member, and both worker script entries. + +## Runtime exports + +| Export | Kind | Purpose | +| -------------------------------- | -------- | ----------------------------------------------------- | +| `WorkerPoolManager` | Class | Runs file and diff highlighting across a worker pool. | +| `getOrCreateWorkerPoolSingleton` | Function | Gets or creates the module-wide worker pool. | +| `terminateWorkerPoolSingleton` | Function | Terminates and clears the module-wide worker pool. | + +## `WorkerPoolManager` members + +| Member | Purpose | +| -------------------------------------------------------------- | ------------------------------------------------- | +| `new WorkerPoolManager(options, renderOptions)` | Creates a worker pool. | +| `initialize(languages?)` | Starts workers and loads languages. | +| `isInitialized()` | Reports whether initialization finished. | +| `isWorkingPool()` | Reports whether workers can accept work. | +| `setRenderOptions(options)` | Updates theme and render settings in each worker. | +| `getFileRenderOptions()` | Gets active file render options. | +| `getDiffRenderOptions()` | Gets active diff render options. | +| `highlightFileAST(instance, file)` | Queues a highlighted file result for an instance. | +| `highlightDiffAST(instance, diff)` | Queues a highlighted diff result for an instance. | +| `primeFileHighlightCache(file)` | Preloads one highlighted file result. | +| `primeDiffHighlightCache(diff)` | Preloads one highlighted diff result. | +| `getFileResultCache(file)` | Gets one cached file result. | +| `getDiffResultCache(diff)` | Gets one cached diff result. | +| `getPlainFileAST(file, start, total, lines?)` | Gets a plain-text file result. | +| `getPlainDiffAST(diff, start, total, expansions?, threshold?)` | Gets a plain-text diff result. | +| `inspectCaches()` | Gets both result caches. | +| `evictFileFromCache(cacheKey)` | Removes one file cache entry. | +| `evictDiffFromCache(cacheKey)` | Removes one diff cache entry. | +| `subscribeToThemeChanges(instance)` | Subscribes a render instance to theme changes. | +| `unsubscribeToThemeChanges(instance)` | Removes a theme subscription. | +| `subscribeToStatChanges(callback)` | Subscribes to worker statistics. | +| `cleanUpTasks(instance)` | Removes queued and active tasks for an instance. | +| `getStats()` | Gets worker and cache statistics. | +| `terminate()` | Stops workers and clears pool resources. | + +## Configuration and state types + +| Export | Purpose | +| ----------------------------------- | ----------------------------------------------------------------- | +| `SetupWorkerPoolProps` | Combines pool and highlighter options for the singleton. | +| `WorkerPoolOptions` | Defines the worker factory, pool size, and cache size. | +| `WorkerInitializationRenderOptions` | Defines initial languages, theme, highlighter, and diff settings. | +| `WorkerRenderingOptions` | Defines the complete worker render settings. | +| `WorkerStats` | Describes pool state, work counts, subscribers, and cache sizes. | +| `WorkerRequestId` | Identifies one worker request. | +| `ResolvedLanguage` | Holds a resolved language registration. | +| `FileRendererInstance` | Defines callbacks for a file render consumer. | +| `DiffRendererInstance` | Defines callbacks for a diff render consumer. | + +## Request and response types + +| Export | Purpose | +| ------------------------------- | ------------------------------------------------------- | +| `WorkerRequest` | Represents any request sent to a worker. | +| `InitializeWorkerRequest` | Starts a worker with themes, languages, and options. | +| `SetRenderOptionsWorkerRequest` | Updates render options and themes. | +| `RenderFileRequest` | Requests one file render. | +| `RenderDiffRequest` | Requests one diff render. | +| `SubmitRequest` | Represents a file or diff request before ID assignment. | +| `WorkerResponse` | Represents any worker response. | +| `InitializeSuccessResponse` | Confirms worker initialization. | +| `RegisterThemeSuccessResponse` | Confirms a render-option and theme update. | +| `RenderSuccessResponse` | Represents a successful file or diff render. | +| `RenderFileSuccessResponse` | Returns one file render result. | +| `RenderDiffSuccessResponse` | Returns one diff render result. | +| `RenderErrorResponse` | Returns a serialized worker error. | + +## Task types + +| Export | Purpose | +| ---------------------------- | ------------------------------------------------- | +| `AllWorkerTasks` | Represents any manager task. | +| `InitializeWorkerTask` | Tracks one initialization request. | +| `SetRenderOptionsWorkerTask` | Tracks one render-option update. | +| `RenderFileTask` | Tracks one file render request and its consumers. | +| `RenderDiffTask` | Tracks one diff render request and its consumers. | +| `RenderTaskCallbacks` | Resolves or rejects one render task consumer. | + +## Worker script entries + +| Import | Purpose | +| ----------------------------------------- | ---------------------------------------------------------- | +| `@pierre/diffs/worker/worker.js` | Supplies the module worker that uses package dependencies. | +| `@pierre/diffs/worker/worker-portable.js` | Supplies a bundled module worker. | diff --git a/packages/diffs/skills/diffs/references/recipe-annotations.md b/packages/diffs/skills/diffs/references/recipe-annotations.md new file mode 100644 index 000000000..7707e93f3 --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-annotations.md @@ -0,0 +1,32 @@ +# Recipe: add line annotations and selection + +Pass annotation data and a renderer to the surface: + +```tsx +import type { DiffLineAnnotation } from '@pierre/diffs/react'; +import { MultiFileDiff } from '@pierre/diffs/react'; + +const annotations: DiffLineAnnotation<{ message: string }>[] = [ + { + side: 'additions', + lineNumber: 8, + metadata: { message: 'Review this line.' }, + }, +]; + +

{annotation.metadata.message}

} + options={{ + enableLineSelection: true, + onLineSelectionEnd(range) { + saveSelection(range); + }, + }} +/>; +``` + +Use `LineAnnotation` for a single file. Use `DiffLineAnnotation` for a diff. +Control the active selection with the `selectedLines` prop. diff --git a/packages/diffs/skills/diffs/references/recipe-code-view.md b/packages/diffs/skills/diffs/references/recipe-code-view.md new file mode 100644 index 000000000..36d818c0a --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-code-view.md @@ -0,0 +1,213 @@ +# Recipe: build a `CodeView` + +Use `CodeView` when one scroll region contains many files, diffs, or both. It +manages item virtualization, sticky headers, list-wide selection, and item or +line scroll targets. + +## Contents + +- [Select item ownership](#select-item-ownership) +- [Define items](#define-items) +- [Use controlled React state](#use-controlled-react-state) +- [Use imperative ownership](#use-imperative-ownership) +- [Enable item edit mode](#enable-item-edit-mode) + +## Select item ownership + +| Host and data flow | Input | Update API | +| ------------------------------------------- | ----------------- | ------------------------------------ | +| React owns the complete list | `items` | Publish a new `items` array. | +| React hosts a large or append-only list | `initialItems` | Use the `CodeViewHandle` methods. | +| Vanilla JavaScript owns the viewer instance | `setItems(items)` | Use the `CodeView` instance methods. | + +Keep one ownership mode for the life of a mounted React viewer. Use controlled +state when item data already belongs to React. Use imperative ownership for a +large or streamed list. + +## Define items + +Give each item a stable and unique `id`. Use a `file` item for `FileContents`. +Use a `diff` item for `FileDiffMetadata`. + +Increment `version` when an existing item changes its contents, annotations, +collapsed state, or edit state. `CodeView` uses the ID and version to select the +item that it must update. + +## Use controlled React state + +```tsx +import { + parseDiffFromFile, + type CodeViewItem, + type CodeViewLineSelection, +} from '@pierre/diffs'; +import { CodeView, type CodeViewHandle } from '@pierre/diffs/react'; +import { useRef, useState } from 'react'; + +const oldFile = { + name: 'src/value.ts', + contents: 'export const value = 1;', +}; +const newFile = { + name: 'src/value.ts', + contents: 'export const value = 2;', +}; +const codeViewStyle = { height: 600, overflow: 'auto' } as const; +const codeViewOptions = { + theme: { light: 'pierre-light', dark: 'pierre-dark' }, + stickyHeaders: true, + enableLineSelection: true, + layout: { paddingTop: 16, paddingBottom: 16, gap: 12 }, +} as const; + +export function ReviewSurface() { + const viewerRef = useRef | null>(null); + const [selection, setSelection] = useState( + null + ); + const [items, setItems] = useState(() => [ + { + id: 'diff:src/value.ts', + type: 'diff', + fileDiff: parseDiffFromFile(oldFile, newFile), + version: 0, + }, + { + id: 'file:README.md', + type: 'file', + file: { name: 'README.md', contents: '# Review notes' }, + version: 0, + }, + ]); + + function toggleDiff() { + setItems((current) => + current.map((item) => + item.id === 'diff:src/value.ts' + ? { + ...item, + collapsed: !item.collapsed, + version: (item.version ?? 0) + 1, + } + : item + ) + ); + } + + return ( + <> + + + + + ); +} +``` + +## Use imperative ownership + +In React, pass `initialItems` and keep `items` unset. Use the component ref to +call `addItems`, `getItem`, `updateItem`, `updateItemId`, or `scrollTo`. + +In vanilla JavaScript, configure and populate the instance directly: + +```ts +import { CodeView, parseDiffFromFile } from '@pierre/diffs'; + +const root = document.querySelector('#review'); +if (root == null) throw new Error('Missing review host'); + +const oldFile = { + name: 'src/value.ts', + contents: 'export const value = 1;', +}; +const newFile = { + name: 'src/value.ts', + contents: 'export const value = 2;', +}; + +const viewer = new CodeView({ + theme: { light: 'pierre-light', dark: 'pierre-dark' }, + stickyHeaders: true, + enableLineSelection: true, + onSelectedLinesChange(selection) { + console.log('selected lines', selection); + }, +}); + +root.style.height = '600px'; +root.style.overflow = 'auto'; +viewer.setup(root); +viewer.setItems([ + { + id: 'diff:src/value.ts', + type: 'diff', + fileDiff: parseDiffFromFile(oldFile, newFile), + version: 0, + }, +]); + +viewer.addItems([ + { + id: 'file:README.md', + type: 'file', + file: { name: 'README.md', contents: '# Review notes' }, + version: 0, + }, +]); +viewer.scrollTo({ + type: 'item', + id: 'diff:src/value.ts', + align: 'start', +}); + +const item = viewer.getItem('diff:src/value.ts'); +if (item != null) { + viewer.updateItem({ + ...item, + collapsed: true, + version: (item.version ?? 0) + 1, + }); +} + +export function removeReviewSurface() { + viewer.cleanUp(); +} +``` + +## Enable item edit mode + +In React, wrap `CodeView` in `EditProvider`. In vanilla JavaScript, pass +`createEditor` in `CodeViewOptions`. Set `edit: true` on each editable item and +increment its version. + +Use `onItemEditChange` for live contents and annotation changes. Use +`onItemEditComplete` to write the final contents into the item, disable edit +mode, assign a fresh `cacheKey`, and increment `version`. Use `getEditor(id)` +for editor commands such as undo, redo, markers, or programmatic edits. + +Read [Edit with React](recipe-edit-react.md) or +[Edit with vanilla JavaScript](recipe-edit-vanilla.md) for the complete editor +lifecycle. diff --git a/packages/diffs/skills/diffs/references/recipe-custom-highlighting.md b/packages/diffs/skills/diffs/references/recipe-custom-highlighting.md new file mode 100644 index 000000000..22efc967f --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-custom-highlighting.md @@ -0,0 +1,19 @@ +# Recipe: register custom highlighting + +Register a language or theme before the first surface uses it: + +```ts +import { registerCustomLanguage, registerCustomTheme } from '@pierre/diffs'; + +registerCustomLanguage( + 'my-language', + () => import('./my-language.tmLanguage.json'), + ['myext'] +); + +registerCustomTheme('my-theme', () => import('./my-theme.json')); +``` + +Set `file.lang` to the custom language name. Set `options.theme` to the custom +theme name. Use `registerCustomCSSVariableTheme` when CSS variables supply the +theme colors. diff --git a/packages/diffs/skills/diffs/references/recipe-edit-react.md b/packages/diffs/skills/diffs/references/recipe-edit-react.md new file mode 100644 index 000000000..c51e57dab --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-edit-react.md @@ -0,0 +1,130 @@ +# Recipe: edit with React + +Mount one stable `EditProvider` above the editable surfaces. The provider +supplies an editor factory. Each active surface or `CodeView` item owns a +separate editor instance, cached by `editorOptions` object identity — an edit +session restarting with the same options object reuses its editor, and +simultaneously editable surfaces need distinct options objects. + +To share one editor across surfaces, pass the same `editorOptions` object to +each of them: the cache then hands every surface the same instance. Instance +state — such as `persistState` records and their default `inMemory` storage — +survives surface remounts, so per-file selections and scroll positions restore +across file switches. Share an options object only where one surface is editable +at a time; simultaneously editable surfaces need distinct options objects. + +## Contents + +- [Edit a standalone file or diff](#edit-a-standalone-file-or-diff) +- [Keep annotations synchronized](#keep-annotations-synchronized) +- [Edit CodeView items](#edit-codeview-items) + +## Edit a standalone file or diff + +Set `edit` on `File`, `FileDiff`, `MultiFileDiff`, or `PatchDiff`. Pass editor +behavior through `editOptions`. + +```tsx +import type { FileContents, FileDiffOptions } from '@pierre/diffs'; +import { Editor, type EditorOptions } from '@pierre/diffs/edit'; +import { EditProvider, MultiFileDiff, Virtualizer } from '@pierre/diffs/react'; +import { useMemo, useRef, useState } from 'react'; + +const oldFile: FileContents = { + name: 'src/value.ts', + contents: 'export const value = 1;', +}; +const initialNewFile: FileContents = { + name: 'src/value.ts', + contents: 'export const value = 2;', +}; +const diffOptions: FileDiffOptions = { + theme: { light: 'pierre-light', dark: 'pierre-dark' }, + diffStyle: 'split', +}; + +function createEditor(options: EditorOptions) { + return new Editor(options); +} + +export function EditableDiff() { + const [edit, setEdit] = useState(false); + const [newFile, setNewFile] = useState(initialNewFile); + const draftRef = useRef(newFile); + const editorRef = useRef | null>(null); + const editOptions = useMemo>( + () => ({ + onAttach(editor) { + editorRef.current = editor; + }, + onChange(file) { + draftRef.current = file; + saveDraft(file); + }, + }), + [] + ); + + function toggleEdit() { + if (edit) setNewFile(draftRef.current); + setEdit((value) => !value); + } + + return ( + + + + + + + + ); +} +``` + +Mount the provider near the application root when many surfaces use edit mode. +Keep `createEditor` and `editOptions` stable. Use `onAttach` when controls need +`undo`, `redo`, `applyEdits`, selections, markers, focus, or other editor APIs. + +## Keep annotations synchronized + +The `onChange` callback can supply the complete current annotation collection. +Replace the application collection when the callback supplies a different array. +Use `isFileAnnotationCollection` or `isDiffAnnotationCollection` to narrow its +type. + +Publish a changed React annotation array inside `flushSync`. This keeps its +coordinates aligned with the edited contents before paint. Store annotation UI +state by a stable metadata ID instead of a line number. + +## Edit `CodeView` items + +Wrap `CodeView` in the same `EditProvider`. Set `edit: true` on an item and +increment its `version`. Pass shared creation options through the `CodeView` +`editOptions` prop. + +Use `onItemEditChange` for live contents and annotation changes. Use +`onItemEditComplete` to commit the final `file` or rebuild the `fileDiff`. In +the same item update, set `edit: false`, assign a fresh `cacheKey`, and +increment `version`. + +Use the `CodeViewHandle.getEditor(id)` method for imperative editor commands. +The item editor keeps its document and history when virtualization removes the +item from the rendered window. + +When a worker pool highlights an editable surface, set +`useTokenTransformer: true` in the worker `highlighterOptions`. diff --git a/packages/diffs/skills/diffs/references/recipe-edit-vanilla.md b/packages/diffs/skills/diffs/references/recipe-edit-vanilla.md new file mode 100644 index 000000000..0876349f6 --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-edit-vanilla.md @@ -0,0 +1,163 @@ +# Recipe: edit with vanilla JavaScript + +Render a standalone surface first. Then attach one `Editor` to it. Use one +editor for each surface that can be edited at the same time. + +## Contents + +- [Edit a standalone diff](#edit-a-standalone-diff) +- [Edit CodeView items](#edit-codeview-items) + +## Edit a standalone diff + +```ts +import { + FileDiff, + isDiffAnnotationCollection, + type DiffLineAnnotation, + type FileContents, +} from '@pierre/diffs'; +import { Editor } from '@pierre/diffs/edit'; + +interface ThreadMetadata { + id: string; +} + +const hostElement = document.querySelector('#diff'); +if (hostElement == null) throw new Error('Missing diff host'); +const host: HTMLElement = hostElement; + +const oldFile: FileContents = { + name: 'src/value.ts', + contents: 'export const value = 1;', +}; +let newFile: FileContents = { + name: 'src/value.ts', + contents: 'export const value = 2;', +}; +let annotations: DiffLineAnnotation[] = [ + { + side: 'additions', + lineNumber: 1, + metadata: { id: 'value-review' }, + }, +]; + +const view = new FileDiff({ + theme: { light: 'pierre-light', dark: 'pierre-dark' }, + renderAnnotation(annotation) { + const element = document.createElement('p'); + element.textContent = 'Thread ' + annotation.metadata.id; + return element; + }, +}); + +function render() { + view.render({ + fileContainer: host, + oldFile, + newFile, + lineAnnotations: annotations, + }); +} + +render(); + +const editor = new Editor({ + onChange(file, nextAnnotations) { + newFile = { ...newFile, contents: file.contents }; + saveDraft(newFile); + + if ( + nextAnnotations != null && + isDiffAnnotationCollection(nextAnnotations) && + nextAnnotations !== annotations + ) { + annotations = nextAnnotations; + queueMicrotask(render); + } + }, +}); + +const detach = editor.edit(view); + +export function stopEditing() { + detach(); +} + +export function removeSurface() { + editor.cleanUp(); + view.cleanUp(); +} +``` + +The annotation array from `onChange` is the complete current collection. Save it +before a later render can apply old coordinates. Use stable metadata IDs for +application state that belongs to an annotation. + +Use `VirtualizedFile` or `VirtualizedFileDiff` with a `Virtualizer` for a large +standalone surface. Load `@pierre/diffs/edit` with `import()` when edit mode is +optional and the initial bundle must omit the editor. + +## Edit `CodeView` items + +Pass a factory through `CodeViewOptions.createEditor`: + +```ts +import { CodeView } from '@pierre/diffs'; +import { Editor } from '@pierre/diffs/edit'; + +export function mountEditableCodeView(root: HTMLElement) { + const viewer = new CodeView({ + createEditor(options) { + return new Editor(options); + }, + onItemEditChange(item, file, nextAnnotations) { + saveItemDraft(item.id, file, nextAnnotations); + }, + onItemEditComplete(item, file) { + const current = viewer.getItem(item.id); + if (current?.type !== 'file') return; + + const version = (current.version ?? 0) + 1; + viewer.updateItem({ + ...current, + edit: false, + version, + file: { + ...file, + cacheKey: current.id + ':v' + version, + }, + }); + }, + }); + + viewer.setup(root); + viewer.setItems([ + { + id: 'file:src/value.ts', + type: 'file', + file: { + name: 'src/value.ts', + contents: 'export const value = 1;', + }, + edit: true, + version: 0, + }, + ]); + + return viewer; +} +``` + +Set `edit: true` on an item and increment its `version`. In +`onItemEditComplete`, write the final contents into that item, set +`edit: false`, assign a fresh `cacheKey`, and increment `version` again. +`CodeView` creates and removes the item editors. + +Call `viewer.getEditor(id)` for `undo`, `redo`, `applyEdits`, selections, +markers, focus, or other editor commands. Call `viewer.cleanUp()` when the host +removes the viewer. + +When a worker pool highlights an editable surface, set +`useTokenTransformer: true` in the worker `highlighterOptions`. diff --git a/packages/diffs/skills/diffs/references/recipe-react.md b/packages/diffs/skills/diffs/references/recipe-react.md new file mode 100644 index 000000000..f1048230f --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-react.md @@ -0,0 +1,37 @@ +# Recipe: render with React + +## Select a surface + +| Input or layout | Component | +| ------------------------------------------- | ---------------- | +| One `FileContents` object | `File` | +| Old and new `FileContents` objects | `MultiFileDiff` | +| Existing `FileDiffMetadata` | `FileDiff` | +| One unified patch string | `PatchDiff` | +| One file with merge conflicts | `UnresolvedFile` | +| One scroll region with many files and diffs | `CodeView` | + +Use `MultiFileDiff` when the app has old and new file contents: + +```tsx +import { MultiFileDiff } from '@pierre/diffs/react'; + +; +``` + +Pass source data, annotations, and slot renderers as component props. Pass +display, theme, interaction, and highlighting settings through `options`. + +Keep file objects and option objects stable when their values do not change. +Wrap a large standalone surface in `Virtualizer`. Use `CodeView` when one scroll +region contains a list of files or diffs. + +Use the matching preload function from `@pierre/diffs/ssr` when the server must +render the initial highlighted markup. diff --git a/packages/diffs/skills/diffs/references/recipe-ssr.md b/packages/diffs/skills/diffs/references/recipe-ssr.md new file mode 100644 index 000000000..6899453e3 --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-ssr.md @@ -0,0 +1,20 @@ +# Recipe: preload a diff on the server + +Create props on the server and pass the result to the matching React component: + +```tsx +import { preloadMultiFileDiff } from '@pierre/diffs/ssr'; +import { MultiFileDiff } from '@pierre/diffs/react'; + +const preloaded = await preloadMultiFileDiff({ + oldFile: { name: 'src/value.ts', contents: oldSource }, + newFile: { name: 'src/value.ts', contents: newSource }, + options: { theme: 'pierre-dark', diffStyle: 'split' }, +}); + +; +``` + +Select the preload function that matches the client component. Use +`preloadDiffHTML` or `preloadUnresolvedFileHTML` when the host needs an HTML +string only. diff --git a/packages/diffs/skills/diffs/references/recipe-vanilla.md b/packages/diffs/skills/diffs/references/recipe-vanilla.md new file mode 100644 index 000000000..ebb8841b1 --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-vanilla.md @@ -0,0 +1,41 @@ +# Recipe: render with vanilla JavaScript + +## Select a surface + +| Input or layout | Class | +| ------------------------------------------- | --------------------- | +| One `FileContents` object | `File` | +| Existing or parsed `FileDiffMetadata` | `FileDiff` | +| One file with merge conflicts | `UnresolvedFile` | +| One large file | `VirtualizedFile` | +| One large diff | `VirtualizedFileDiff` | +| One scroll region with many files and diffs | `CodeView` | + +Parse the files, create the view, and render it into a host: + +```ts +import { FileDiff, parseDiffFromFile } from '@pierre/diffs'; + +const host = document.querySelector('#diff'); +if (host == null) throw new Error('Missing diff host'); + +const fileDiff = parseDiffFromFile( + { name: 'src/value.ts', contents: oldSource }, + { name: 'src/value.ts', contents: newSource } +); + +const view = new FileDiff({ + diffStyle: 'split', + theme: 'pierre-dark', +}); + +view.render({ fileContainer: host, fileDiff }); +``` + +Keep the class instance while the host remains mounted. Call `render` again when +the source data changes. Call `setOptions`, `setThemeType`, +`setLineAnnotations`, or `setSelectedLines` for targeted updates. + +Use a `Virtualizer` with `VirtualizedFile` or `VirtualizedFileDiff` for one +large surface. Use `CodeView` for a list that shares one scroll region. Call +`cleanUp()` when the host removes the surface. diff --git a/packages/diffs/skills/diffs/references/recipe-workers.md b/packages/diffs/skills/diffs/references/recipe-workers.md new file mode 100644 index 000000000..fbe7cc6f8 --- /dev/null +++ b/packages/diffs/skills/diffs/references/recipe-workers.md @@ -0,0 +1,28 @@ +# Recipe: use a worker pool + +Wrap React diff surfaces in one provider: + +```tsx +import { WorkerPoolContextProvider } from '@pierre/diffs/react'; + + + new Worker(new URL('@pierre/diffs/worker/worker.js', import.meta.url), { + type: 'module', + }), + }} + highlighterOptions={{ + langs: ['typescript', 'tsx'], + theme: { light: 'pierre-light', dark: 'pierre-dark' }, + }} +> + {children} +; +``` + +For vanilla JavaScript, call `getOrCreateWorkerPoolSingleton` and pass the +result as the second constructor argument to a render class. Call +`terminateWorkerPoolSingleton()` when the application tears down the shared +pool. diff --git a/packages/diffs/test/published-skill.test.ts b/packages/diffs/test/published-skill.test.ts new file mode 100644 index 000000000..cd8446965 --- /dev/null +++ b/packages/diffs/test/published-skill.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, test } from 'bun:test'; +import { existsSync, readdirSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const packageRoot = join(import.meta.dir, '..'); + +describe('published agent skill', () => { + // Skills ship inside the npm tarball so consumers get version-locked + // agent instructions without a separate GitHub install. + test('package files include the skills directory with SKILL.md', () => { + const pkg = JSON.parse( + readFileSync(join(packageRoot, 'package.json'), 'utf8') + ) as { files: string[] }; + expect(pkg.files).toContain('skills'); + + const skillDir = join(packageRoot, 'skills', 'diffs'); + expect(existsSync(join(skillDir, 'SKILL.md'))).toBe(true); + expect( + readdirSync(join(skillDir, 'references')).some((name) => + name.endsWith('.md') + ) + ).toBe(true); + }); +}); diff --git a/packages/trees/PUBLISHING.md b/packages/trees/PUBLISHING.md index 1829319de..7551b420b 100644 --- a/packages/trees/PUBLISHING.md +++ b/packages/trees/PUBLISHING.md @@ -58,6 +58,7 @@ The script will: `*.tsbuildinfo` files. 6. Run `pnpm publish --dry-run` against the final tarball, print the `package.json` diff and final tarball listing, then stop without uploading. + The listing should include `skills/trees/SKILL.md` and the skill references. Inspect the diff. It should delete the `@pierre/path-store` dependency and the release-only scripts that are meaningless inside the packed artifact. diff --git a/packages/trees/README.md b/packages/trees/README.md index bbd70c544..7925b7ab8 100644 --- a/packages/trees/README.md +++ b/packages/trees/README.md @@ -28,6 +28,9 @@ Install the agent skill for this package with the npx skills add pierrecomputer/pierre --skill trees ``` +The published package also includes the same skill at `skills/trees/`, so +installing `@pierre/trees` version-locks the agent instructions with the API. + ## Vanilla usage ```ts diff --git a/packages/trees/package.json b/packages/trees/package.json index c2ac160d9..f44b4a729 100644 --- a/packages/trees/package.json +++ b/packages/trees/package.json @@ -6,7 +6,8 @@ "dist", "LICENSE.md", "NOTICE.md", - "README.md" + "README.md", + "skills" ], "type": "module", "sideEffects": [ diff --git a/packages/trees/skills/trees/SKILL.md b/packages/trees/skills/trees/SKILL.md new file mode 100644 index 000000000..d3cc23fb7 --- /dev/null +++ b/packages/trees/skills/trees/SKILL.md @@ -0,0 +1,39 @@ +--- +name: trees +description: + Use when an app uses @pierre/trees to render or control a file tree, including + React, vanilla JavaScript, SSR, web components, selection, search, rename, + drag and drop, icons, git status, and themes. +--- + +# `@pierre/trees` + +Use `@pierre/trees` for an interactive file tree. Public state and callbacks use +path strings. + +## Install + +```bash +pnpm add @pierre/trees +``` + +Install `react` and `react-dom` when the app uses the React entry. + +## Select an API reference + +| Entry | Reference | +| ------------------------------ | ------------------------------------------------------ | +| `@pierre/trees` | [Core API](references/api-core.md) | +| `@pierre/trees/react` | [React API](references/api-react.md) | +| `@pierre/trees/ssr` | [SSR API](references/api-ssr.md) | +| `@pierre/trees/web-components` | [Web components API](references/api-web-components.md) | + +## Select a recipe + +| Task | Recipe | +| ------------------------------------------------------- | ------------------------------------------------------ | +| Render and update a tree in React | [Use React](references/recipe-react.md) | +| Render and update a tree without React | [Use vanilla JavaScript](references/recipe-vanilla.md) | +| Preload a tree on the server | [Use SSR](references/recipe-ssr.md) | +| Apply a resolved Shiki or VS Code theme | [Apply a theme](references/recipe-theme.md) | +| Configure search, rename, drag and drop, and git status | [Add interactions](references/recipe-interactions.md) | diff --git a/packages/trees/skills/trees/references/api-core.md b/packages/trees/skills/trees/references/api-core.md new file mode 100644 index 000000000..22727767e --- /dev/null +++ b/packages/trees/skills/trees/references/api-core.md @@ -0,0 +1,173 @@ +# Core API + +This reference lists every export from `@pierre/trees` and every public +`FileTree` member. + +## Contents + +- [Runtime values](#runtime-values) +- [`FileTree` members](#filetree-members) +- [Configuration and state types](#configuration-and-state-types) +- [Mutation types](#mutation-types) +- [Interaction types](#interaction-types) +- [Presentation types](#presentation-types) +- [Constants](#constants) + +## Runtime values + +| Export | Kind | Purpose | +| ------------------------------- | -------- | ----------------------------------------------------------------- | +| `FileTree` | Class | Owns the tree model, renders it, and exposes path-based controls. | +| `prepareFileTreeInput` | Function | Prepares and optionally sorts a path list for reuse. | +| `preparePresortedFileTreeInput` | Function | Prepares a path list that already has final order. | +| `preloadFileTree` | Function | Creates server-rendered tree markup and hydration data. | +| `serializeFileTreeSsrPayload` | Function | Joins an SSR payload into one host markup string. | +| `themeToTreeStyles` | Function | Maps a resolved theme to tree host CSS properties. | +| `getBuiltInSpriteSheet` | Function | Gets the SVG sprite for a built-in icon set. | +| `createFileTreeIconResolver` | Function | Creates an icon resolver from an icon configuration. | + +## `FileTree` members + +| Member | Purpose | +| -------------------------------- | ----------------------------------------------------------- | +| `new FileTree(options)` | Creates a model from paths or prepared input. | +| `FileTree.LoadedCustomComponent` | Reports whether the file-tree custom element module loaded. | +| `render(props)` | Mounts the tree into a wrapper or host element. | +| `hydrate(props)` | Attaches the model to preloaded host markup. | +| `unmount()` | Removes the mounted view and keeps the model. | +| `cleanUp()` | Removes the view and destroys model resources. | +| `getFileTreeContainer()` | Gets the mounted host element. | +| `getItem(path)` | Gets a path handle or `null`. | +| `getFocusedItem()` | Gets the focused item handle or `null`. | +| `getFocusedPath()` | Gets the focused path or `null`. | +| `getSelectedPaths()` | Gets the selected paths. | +| `getComposition()` | Gets the current header and context-menu configuration. | +| `getItemHeight()` | Gets the resolved row height. | +| `getDensityFactor()` | Gets the resolved density factor. | +| `subscribe(listener)` | Subscribes to model changes. | +| `focusPath(path)` | Focuses a path. | +| `focusNearestPath(path)` | Focuses and returns the nearest available path. | +| `scrollToPath(path, options?)` | Scrolls a path into view. | +| `add(path)` | Adds one path. | +| `remove(path, options?)` | Removes one path. | +| `move(from, to, options?)` | Moves one path. | +| `batch(operations)` | Applies several path mutations together. | +| `resetPaths(paths, options?)` | Replaces the full path set. | +| `onMutation(type, handler)` | Subscribes to mutation events. | +| `setSearch(value)` | Sets or clears the search query. | +| `openSearch(initialValue?)` | Opens the search session. | +| `closeSearch()` | Closes the search session. | +| `isSearchOpen()` | Tests whether search is open. | +| `getSearchValue()` | Gets the search query. | +| `getSearchMatchingPaths()` | Gets paths that match the query. | +| `focusNextSearchMatch()` | Focuses the next search match. | +| `focusPreviousSearchMatch()` | Focuses the previous search match. | +| `startRenaming(path?, options?)` | Starts inline rename and reports whether it started. | +| `setGitStatus(status?)` | Replaces all git status entries. | +| `applyGitStatusPatch(patch)` | Applies a partial git status update. | +| `setIcons(icons?)` | Replaces the icon configuration. | +| `setComposition(composition?)` | Replaces header and context-menu configuration. | + +## Configuration and state types + +| Export | Purpose | +| -------------------------- | --------------------------------------------------------------- | +| `FileTreeOptions` | Defines input, behavior, rendering, and presentation options. | +| `FileTreePreparedInput` | Holds a reusable prepared path list. | +| `FileTreeInitialExpansion` | Selects closed, open, or depth-based initial expansion. | +| `FileTreeSortComparator` | Compares two path entries. | +| `FileTreeSortEntry` | Describes one path for a sort comparator. | +| `FileTreeRenderOptions` | Configures row height, row count, overscan, and sticky folders. | +| `FileTreeRenderProps` | Selects the wrapper or existing host for `render`. | +| `FileTreeHydrationProps` | Selects the host for `hydrate`. | +| `FileTreeVisibleRow` | Describes one visible tree row. | +| `FileTreeItemHandle` | Represents a file or directory item. | +| `FileTreeFileHandle` | Controls one file item. | +| `FileTreeDirectoryHandle` | Controls one directory item and its expansion. | +| `FileTreeListener` | Defines a model subscription callback. | +| `FileTreeSsrPayload` | Holds the host and shadow markup for server output. | + +## Mutation types + +| Export | Purpose | +| ----------------------------------- | -------------------------------------------------------------- | +| `FileTreeMutationHandle` | Defines the public path mutation methods. | +| `FileTreeBatchOperation` | Describes one add, remove, or move in a batch. | +| `FileTreeCollisionStrategy` | Selects error, replace, or skip behavior for a move collision. | +| `FileTreeMoveOptions` | Configures move collision behavior. | +| `FileTreeRemoveOptions` | Configures recursive removal. | +| `FileTreeResetOptions` | Configures a path reset and optional prepared input. | +| `FileTreeResetPreparedOptions` | Configures a reset that uses prepared input. | +| `FileTreeMutationEvent` | Represents any mutation event. | +| `FileTreeMutationSemanticEvent` | Represents an add, remove, move, or reset event. | +| `FileTreeMutationEventType` | Names a mutation operation. | +| `FileTreeMutationEventForType` | Selects the event shape for an operation name. | +| `FileTreeMutationEventInvalidation` | Describes the state invalidation from a mutation. | +| `FileTreeAddEvent` | Describes one add result. | +| `FileTreeRemoveEvent` | Describes one remove result. | +| `FileTreeMoveEvent` | Describes one move result. | +| `FileTreeResetEvent` | Describes one reset result. | +| `FileTreeBatchEvent` | Describes one batch result. | + +## Interaction types + +| Export | Purpose | +| --------------------------------- | -------------------------------------------------- | +| `FileTreeSelectionChangeListener` | Receives the selected path list. | +| `FileTreeSearchChangeListener` | Receives the current search query. | +| `FileTreeSearchSessionHandle` | Defines search session methods. | +| `FileTreeSearchMode` | Selects how nonmatching rows appear. | +| `FileTreeSearchBlurBehavior` | Selects search behavior after focus leaves. | +| `FileTreeScrollOffset` | Selects top, center, or nearest scroll alignment. | +| `FileTreeScrollToPathOptions` | Configures focus and alignment for `scrollToPath`. | +| `FileTreeDragAndDropConfig` | Configures drag rules and completion callbacks. | +| `FileTreeDropTarget` | Describes the current drop target. | +| `FileTreeDropContext` | Describes dragged paths and their target. | +| `FileTreeDropResult` | Describes the completed move or batch operation. | +| `FileTreeRenamingConfig` | Configures rename rules and callbacks. | +| `FileTreeRenamingItem` | Describes the item offered to a rename rule. | +| `FileTreeRenameEvent` | Describes a completed rename. | + +## Presentation types + +| Export | Purpose | +| ---------------------------------- | ----------------------------------------------------------- | +| `FileTreeCompositionOptions` | Configures header and context-menu composition. | +| `FileTreeHeaderCompositionOptions` | Supplies header HTML or a header renderer. | +| `ContextMenuItem` | Describes the file or directory for a context menu. | +| `ContextMenuOpenContext` | Supplies menu position, close, and focus controls. | +| `ContextMenuAnchorRect` | Describes the menu anchor rectangle. | +| `ContextMenuTriggerMode` | Selects right-click, button, or both triggers. | +| `ContextMenuButtonVisibility` | Selects when the row menu button appears. | +| `FileTreeRowDecoration` | Describes text or icon content in the decoration lane. | +| `FileTreeRowDecorationContext` | Supplies the item and visible row to a decoration renderer. | +| `FileTreeRowDecorationRenderer` | Produces one row decoration. | +| `GitStatus` | Names a supported git status. | +| `GitStatusEntry` | Assigns a git status to one path. | +| `FileTreeGitStatusPatch` | Adds, changes, or removes git status entries. | +| `FileTreeBuiltInIconSet` | Names a built-in icon set. | +| `FileTreeIconConfig` | Configures built-in and custom icon rules. | +| `FileTreeIcons` | Accepts an icon set name or icon configuration. | +| `RemappedIcon` | Names or defines a replacement SVG symbol. | +| `FileTreeDensity` | Accepts a density keyword or numeric factor. | +| `FileTreeDensityKeyword` | Names compact, default, or relaxed density. | +| `FileTreeDensityPreset` | Holds a density factor and row height. | +| `TreeThemeInput` | Defines the resolved theme accepted by `themeToTreeStyles`. | +| `TreeThemeStyles` | Maps tree CSS property names to values. | + +## Constants + +| Export | Purpose | +| ---------------------------------------------- | --------------------------------------------------------------- | +| `FILE_TREE_TAG_NAME` | Provides the `file-tree-container` element name. | +| `FILE_TREE_STYLE_ATTRIBUTE` | Provides the core style marker attribute. | +| `FILE_TREE_UNSAFE_CSS_ATTRIBUTE` | Provides the custom style marker attribute. | +| `FILE_TREE_SCROLLBAR_MEASURE_ATTRIBUTE` | Provides the scrollbar measurement attribute. | +| `FILE_TREE_SCROLLBAR_GUTTER_STYLE_ATTRIBUTE` | Provides the measured scrollbar style attribute. | +| `FILE_TREE_SCROLLBAR_GUTTER_MEASURED_PROPERTY` | Provides the measured scrollbar CSS property. | +| `FILE_TREE_DEFAULT_ITEM_HEIGHT` | Provides the default row height. | +| `FILE_TREE_DENSITY_PRESETS` | Maps each density keyword to its preset. | +| `FLATTENED_PREFIX` | Provides the identifier prefix for a flattened directory chain. | +| `HEADER_SLOT_NAME` | Provides the header slot name. | +| `CONTEXT_MENU_SLOT_NAME` | Provides the context-menu slot name. | +| `CONTEXT_MENU_TRIGGER_TYPE` | Provides the context-menu trigger type. | diff --git a/packages/trees/skills/trees/references/api-react.md b/packages/trees/skills/trees/references/api-react.md new file mode 100644 index 000000000..39ba73da3 --- /dev/null +++ b/packages/trees/skills/trees/references/api-react.md @@ -0,0 +1,27 @@ +# React API + +This reference lists every export from `@pierre/trees/react`. + +| Export | Kind | Purpose | +| -------------------------- | --------- | ---------------------------------------------------------------------- | +| `FileTree` | Component | Mounts a `FileTree` model in a React host element. | +| `FileTreeProps` | Type | Defines the model, header, context menu, preload data, and host props. | +| `FileTreePreloadedData` | Type | Selects the `id` and `shadowHtml` fields for hydration. | +| `useFileTree` | Hook | Creates one stable `FileTree` model. | +| `UseFileTreeResult` | Type | Holds the model returned by `useFileTree`. | +| `useFileTreeSelection` | Hook | Returns the selected path list and updates with the model. | +| `useFileTreeSearch` | Hook | Returns search state and search actions. | +| `FileTreeSearchState` | Type | Defines the search snapshot and actions. | +| `useFileTreeSelector` | Hook | Subscribes to a selected part of model state. | +| `FileTreeSelector` | Type | Selects a value from a model. | +| `FileTreeSelectorEquality` | Type | Compares two selected values. | + +`FileTreeProps` extends React host attributes except `children`. Its specific +fields are: + +| Field | Purpose | +| ------------------- | --------------------------------------------------- | +| `model` | Supplies the required `FileTree` model. | +| `header` | Supplies React content for the header slot. | +| `renderContextMenu` | Produces React content for the active context menu. | +| `preloadedData` | Supplies server markup for hydration. | diff --git a/packages/trees/skills/trees/references/api-ssr.md b/packages/trees/skills/trees/references/api-ssr.md new file mode 100644 index 000000000..3ef00b4c3 --- /dev/null +++ b/packages/trees/skills/trees/references/api-ssr.md @@ -0,0 +1,12 @@ +# SSR API + +This reference lists every export from `@pierre/trees/ssr`. + +| Export | Kind | Purpose | +| ----------------------------- | -------- | --------------------------------------------------------------- | +| `preloadFileTree` | Function | Renders a tree to a `FileTreeSsrPayload`. | +| `serializeFileTreeSsrPayload` | Function | Creates declarative or DOM-inserted host markup from a payload. | +| `FileTreeSsrPayload` | Type | Holds the host start, shadow HTML, host end, and stable ID. | + +`preloadFileTree` and `serializeFileTreeSsrPayload` are also available from +`@pierre/trees`. diff --git a/packages/trees/skills/trees/references/api-web-components.md b/packages/trees/skills/trees/references/api-web-components.md new file mode 100644 index 000000000..b03a9635b --- /dev/null +++ b/packages/trees/skills/trees/references/api-web-components.md @@ -0,0 +1,11 @@ +# Web components API + +Import `@pierre/trees/web-components` to register the `file-tree-container` +custom element. The entry exports these APIs: + +| Export | Kind | Purpose | +| --------------------------- | -------- | ------------------------------------------------------------------------- | +| `FileTreeContainerLoaded` | Value | Confirms that the registration module ran. | +| `adoptDeclarativeShadowDom` | Function | Copies a declarative template into an empty shadow root. | +| `ensureFileTreeStyles` | Function | Installs the core tree stylesheet in a shadow root. | +| `prepareFileTreeShadowRoot` | Function | Adopts server markup, installs styles, and measures the scrollbar gutter. | diff --git a/packages/trees/skills/trees/references/recipe-interactions.md b/packages/trees/skills/trees/references/recipe-interactions.md new file mode 100644 index 000000000..b96d98af4 --- /dev/null +++ b/packages/trees/skills/trees/references/recipe-interactions.md @@ -0,0 +1,30 @@ +# Recipe: add file tree interactions + +Enable only the interactions that the product exposes: + +```ts +const tree = new FileTree({ + paths, + search: true, + renaming: { + onRename(event) { + renamePath(event.sourcePath, event.destinationPath); + }, + }, + dragAndDrop: { + canDrop({ target }) { + return target.kind === 'directory'; + }, + onDropComplete(event) { + saveMove(event); + }, + }, + gitStatus, +}); +``` + +Use `openSearch()` to open search from an application command. Use +`startRenaming(path)` to start rename from a menu. Use `setGitStatus()` or +`applyGitStatusPatch()` after repository state changes. + +Directory input paths end with `/`. File input paths do not end with `/`. diff --git a/packages/trees/skills/trees/references/recipe-react.md b/packages/trees/skills/trees/references/recipe-react.md new file mode 100644 index 000000000..393c78e22 --- /dev/null +++ b/packages/trees/skills/trees/references/recipe-react.md @@ -0,0 +1,22 @@ +# Recipe: use a file tree in React + +Create the model once and pass it to the component: + +```tsx +'use client'; + +import { FileTree, useFileTree } from '@pierre/trees/react'; + +export function ProjectFiles({ paths }: { paths: readonly string[] }) { + const { model } = useFileTree({ + paths, + initialExpansion: 'open', + search: true, + }); + + return ; +} +``` + +Call model methods for updates after model creation. For example, call +`model.resetPaths(paths)` after the source path list changes. diff --git a/packages/trees/skills/trees/references/recipe-ssr.md b/packages/trees/skills/trees/references/recipe-ssr.md new file mode 100644 index 000000000..9b225804f --- /dev/null +++ b/packages/trees/skills/trees/references/recipe-ssr.md @@ -0,0 +1,31 @@ +# Recipe: preload a file tree on the server + +Create one payload and pass it to the React tree: + +```tsx +import { preloadFileTree } from '@pierre/trees/ssr'; +import { FileTree, useFileTree } from '@pierre/trees/react'; + +const options = { + id: 'project-files', + paths: ['README.md', 'src/', 'src/index.ts'], + initialExpansion: 'open' as const, + initialVisibleRowCount: 8, +}; + +const preloadedData = preloadFileTree(options); + +export function ProjectFiles() { + const { model } = useFileTree(options); + return ( + + ); +} +``` + +For a direct HTML response, call `serializeFileTreeSsrPayload(payload)`. Pass +`dom` as the second argument when a DOM API inserts the complete markup string. diff --git a/packages/trees/skills/trees/references/recipe-theme.md b/packages/trees/skills/trees/references/recipe-theme.md new file mode 100644 index 000000000..b7d90fbc5 --- /dev/null +++ b/packages/trees/skills/trees/references/recipe-theme.md @@ -0,0 +1,18 @@ +# Recipe: apply a resolved theme + +Convert one resolved Shiki or VS Code theme to host styles: + +```tsx +import { themeToTreeStyles } from '@pierre/trees'; +import { FileTree } from '@pierre/trees/react'; + +const treeStyle = { + height: 320, + ...themeToTreeStyles(resolvedTheme), +}; + +; +``` + +Recalculate the styles when the resolved theme changes. Set tree override CSS +properties on the same host style when the product needs a local color choice. diff --git a/packages/trees/skills/trees/references/recipe-vanilla.md b/packages/trees/skills/trees/references/recipe-vanilla.md new file mode 100644 index 000000000..ea258f439 --- /dev/null +++ b/packages/trees/skills/trees/references/recipe-vanilla.md @@ -0,0 +1,23 @@ +# Recipe: use a file tree in vanilla JavaScript + +Create the model and mount it in an element with a height: + +```ts +import { FileTree } from '@pierre/trees'; + +const mount = document.querySelector('#files'); +if (mount == null) throw new Error('Missing file tree mount'); + +mount.style.height = '320px'; + +const tree = new FileTree({ + paths: ['README.md', 'src/', 'src/index.ts'], + initialExpansion: 'open', + search: true, +}); + +tree.render({ containerWrapper: mount }); +``` + +Use `add`, `remove`, `move`, or `resetPaths` to update paths. Call `cleanUp()` +when the host removes the tree. diff --git a/packages/trees/test/published-skill.test.ts b/packages/trees/test/published-skill.test.ts new file mode 100644 index 000000000..a3e2e43e5 --- /dev/null +++ b/packages/trees/test/published-skill.test.ts @@ -0,0 +1,24 @@ +import { describe, expect, test } from 'bun:test'; +import { existsSync, readdirSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const packageRoot = join(import.meta.dir, '..'); + +describe('published agent skill', () => { + // Skills ship inside the npm tarball so consumers get version-locked + // agent instructions without a separate GitHub install. + test('package files include the skills directory with SKILL.md', () => { + const pkg = JSON.parse( + readFileSync(join(packageRoot, 'package.json'), 'utf8') + ) as { files: string[] }; + expect(pkg.files).toContain('skills'); + + const skillDir = join(packageRoot, 'skills', 'trees'); + expect(existsSync(join(skillDir, 'SKILL.md'))).toBe(true); + expect( + readdirSync(join(skillDir, 'references')).some((name) => + name.endsWith('.md') + ) + ).toBe(true); + }); +}); diff --git a/skills/INDEX.md b/skills/INDEX.md index a84aa54b8..91428ef2b 100644 --- a/skills/INDEX.md +++ b/skills/INDEX.md @@ -16,3 +16,8 @@ the task. `@pierre/theme` supplies theme objects. `@pierre/theming` selects, resolves, and maps those objects. `@pierre/diffs` and `@pierre/trees` render code and file trees with the selected theme. + +The `diffs` and `trees` skill directories are owned by those published packages +(`packages/diffs/skills/diffs`, `packages/trees/skills/trees`) so they ship on +npm. The paths in this folder are convenience symlinks for +`npx skills add pierrecomputer/pierre`. diff --git a/skills/diffs/SKILL.md b/skills/diffs/SKILL.md deleted file mode 100644 index 25ba00509..000000000 --- a/skills/diffs/SKILL.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: diffs -description: - Use when an app uses @pierre/diffs to render or edit code files, diffs, - patches, merge conflicts, or CodeView review surfaces, including React, - vanilla JavaScript, SSR, workers, annotations, selection, and custom Shiki - languages or themes. ---- - -# `@pierre/diffs` - -Use `@pierre/diffs` to render syntax-highlighted files and diffs. Use its -optional editor, SSR, and worker entries for those capabilities. - -## Install - -```bash -pnpm add @pierre/diffs -``` - -Install `react` and `react-dom` when the app uses the React entry. - -## Select an API reference - -| Surface | Reference | -| ------------------------------------------------------------ | ------------------------------------------------------ | -| Root components, parsing, and file extension APIs | [Core API](references/api-core.md) | -| Languages, themes, highlighter state, and streams | [Highlighting API](references/api-highlighting.md) | -| Renderers, managers, DOM helpers, comparisons, and constants | [Low-level rendering API](references/api-rendering.md) | -| Shared data, option, render, selection, and editor types | [Shared types](references/api-types.md) | -| `@pierre/diffs/react` | [React API](references/api-react.md) | -| `@pierre/diffs/edit` | [Editor API](references/api-editor.md) | -| `@pierre/diffs/ssr` | [SSR API](references/api-ssr.md) | -| `@pierre/diffs/worker` and worker scripts | [Worker API](references/api-worker.md) | - -## Select a recipe - -| Task | Recipe | -| ----------------------------------- | ------------------------------------------------------------------------ | -| Render a file or diff in React | [Render with React](references/recipe-react.md) | -| Render a file or diff without React | [Render with vanilla JavaScript](references/recipe-vanilla.md) | -| Build a virtualized review surface | [Use CodeView](references/recipe-code-view.md) | -| Edit a React surface or CodeView | [Edit with React](references/recipe-edit-react.md) | -| Edit a vanilla surface or CodeView | [Edit with vanilla JavaScript](references/recipe-edit-vanilla.md) | -| Preload markup on the server | [Use SSR](references/recipe-ssr.md) | -| Highlight through a worker pool | [Use workers](references/recipe-workers.md) | -| Add line annotations and selection | [Add annotations and selection](references/recipe-annotations.md) | -| Register a Shiki language or theme | [Register custom highlighting](references/recipe-custom-highlighting.md) | diff --git a/skills/diffs/SKILL.md b/skills/diffs/SKILL.md new file mode 120000 index 000000000..409159b6c --- /dev/null +++ b/skills/diffs/SKILL.md @@ -0,0 +1 @@ +../../packages/diffs/skills/diffs/SKILL.md \ No newline at end of file diff --git a/skills/diffs/references/api-core.md b/skills/diffs/references/api-core.md deleted file mode 100644 index 22b012862..000000000 --- a/skills/diffs/references/api-core.md +++ /dev/null @@ -1,186 +0,0 @@ -# Core API - -This reference covers components, parsing, merge conflicts, and file extension -APIs from `@pierre/diffs`. - -## Contents - -- [File components](#file-components) -- [Virtualized components](#virtualized-components) -- [`File` members](#file-members) -- [`FileDiff` members](#filediff-members) -- [`CodeView` members](#codeview-members) -- [Parsing and patch APIs](#parsing-and-patch-apis) -- [Merge conflict APIs](#merge-conflict-apis) -- [Annotation APIs](#annotation-apis) -- [File extension APIs](#file-extension-apis) - -## File components - -| Export | Kind | Purpose | -| --------------------------------------- | -------- | ------------------------------------------------------------- | -| `File` | Class | Renders one syntax-highlighted file. | -| `FileOptions` | Type | Configures file display, interaction, slots, and callbacks. | -| `FileRenderProps` | Type | Defines file input and a render target. | -| `FileHydrateProps` | Type | Defines file input and preloaded markup for hydration. | -| `FileDiff` | Class | Renders a file diff from files or parsed metadata. | -| `FileDiffOptions` | Type | Configures diff display, interaction, slots, and callbacks. | -| `FileDiffRenderBaseProps` | Type | Defines shared diff render input. | -| `FileDiffRenderProps` | Type | Adds files or parsed metadata to diff render input. | -| `FileDiffHydrationProps` | Type | Defines diff input and preloaded markup for hydration. | -| `FileDiffType` | Type | Identifies a standard or unresolved diff instance. | -| `UnresolvedFile` | Class | Renders one file with merge conflict controls. | -| `UnresolvedFileOptions` | Type | Configures merge conflict display and callbacks. | -| `UnresolvedFileRenderProps` | Type | Defines merge conflict render input. | -| `UnresolvedFileHydrationProps` | Type | Defines merge conflict input for hydration. | -| `MergeConflictActionsTypeOption` | Type | Selects no actions, default actions, or a custom renderer. | -| `RenderMergeConflictActions` | Type | Defines a vanilla conflict action renderer. | -| `getUnresolvedDiffHunksRendererOptions` | Function | Converts unresolved-file options to hunk renderer options. | -| `CodeView` | Class | Renders a virtualized list of files and diffs. | -| `CodeViewOptions` | Type | Configures list layout, items, slots, selection, and editing. | -| `CodeViewLineSelection` | Type | Associates a selected range with one item ID. | -| `CodeViewRenderedFileItem` | Type | Describes one mounted file item. | -| `CodeViewRenderedDiffItem` | Type | Describes one mounted diff item. | -| `CodeViewRenderedItem` | Type | Represents a mounted file or diff item. | -| `CodeViewCoordinator` | Type | Coordinates React slots with the vanilla list. | -| `CodeViewSlotSnapshot` | Type | Describes mounted items and list header or footer hosts. | -| `CodeViewScrollListener` | Type | Receives list scroll changes. | -| `CODE_VIEW_FILE_OPTION_KEYS` | Value | Lists file options that `CodeView` passes to an item. | -| `CODE_VIEW_DIFF_OPTION_KEYS` | Value | Lists diff options that `CodeView` passes to an item. | - -## Virtualized components - -| Export | Kind | Purpose | -| -------------------------------------------------- | ----- | ----------------------------------------------------------- | -| `Virtualizer` | Class | Tracks a simple viewport and connected render instances. | -| `VirtualizerConfig` | Type | Configures overscroll, observation margin, and resize logs. | -| `VirtualizedFile` | Class | Adds simple viewport behavior to `File`. | -| `VirtualizedFileDiff` | Class | Adds simple viewport behavior to `FileDiff`. | -| `VIRTUALIZED_FILE_DIFF_LAYOUT_CHECKPOINT_INTERVAL` | Value | Sets the line interval for virtual diff layout checkpoints. | - -## `File` members - -| Member | Purpose | -| --------------------------------------------- | ---------------------------------------------------- | -| `new File(options?, workerManager?)` | Creates one file renderer. | -| `render(props)` | Renders file contents. | -| `hydrate(props)` | Attaches to preloaded file markup. | -| `rerender()` | Renders the current file again. | -| `setOptions(options)` | Replaces file options. | -| `setThemeType(themeType)` | Selects system, light, or dark theme mode. | -| `onThemeChange()` | Applies a changed theme. | -| `setLineAnnotations(annotations)` | Replaces file annotations. | -| `setSelectedLines(range, options?)` | Replaces the selected line range. | -| `setEditorActiveLine(line, options?)` | Marks the editor's active line. | -| `getHoveredLine()` | Gets the current hovered line. | -| `getOrCreateLineCache(file?)` | Gets cached source lines. | -| `attachEditor(editor)` | Attaches an editor and returns a detach function. | -| `applyDocumentChange(document, annotations?)` | Applies an editor document update. | -| `updateRenderCache(tokens, themeType)` | Updates highlighted token cache entries. | -| `primeHighlightCache()` | Preloads the highlighted file result. | -| `renderPlaceholder(height)` | Renders a fixed-height placeholder. | -| `virtualizedSetup()` | Prepares the instance for a virtualizer. | -| `flushManagers()` | Applies deferred interaction and size manager state. | -| `cleanUp(recycle?)` | Releases rendered resources. | - -## `FileDiff` members - -`FileDiff` supports the shared `File` update, selection, annotation, editor, -hydration, placeholder, and cleanup members with diff data. - -| Member | Purpose | -| -------------------------------------------- | ------------------------------------------------ | -| `new FileDiff(options?, workerManager?)` | Creates one diff renderer. | -| `render(props)` | Parses or renders diff input. | -| `hydrate(props)` | Attaches to preloaded diff markup. | -| `rerender()` | Renders the current diff again. | -| `setOptions(options)` | Replaces diff options. | -| `getLineIndex(line, side?)` | Maps a displayed line to row and column indexes. | -| `handleExpandHunk(index, direction, count?)` | Handles a hunk expansion request. | -| `expandHunk(index, direction, count?)` | Expands hidden context around one hunk. | -| `completeEditSession()` | Recomputes diff metadata after an edit session. | -| `isLineRenderable(line)` | Tests whether an additions line is visible. | -| `getNearestRenderableLine(line, direction)` | Finds a visible additions line. | -| `revealLine(line)` | Expands context to show an additions line. | -| `primeHighlightCache(diff?)` | Preloads the highlighted diff result. | - -## `CodeView` members - -| Member | Purpose | -| ---------------------------------------- | -------------------------------------------- | -| `new CodeView(options?, workerManager?)` | Creates one virtualized list. | -| `setup(root)` | Attaches the list to its scroll root. | -| `setItems(items)` | Replaces all items. | -| `addItem(item)` | Appends one item. | -| `addItems(items)` | Appends several items. | -| `getItem(id)` | Gets one item by ID. | -| `updateItem(item)` | Replaces one item by ID. | -| `updateItemId(oldId, newId)` | Changes one item ID. | -| `getEditor(id)` | Gets the active editor for an item. | -| `scrollTo(target)` | Scrolls to a position, item, line, or range. | -| `setSelectedLines(selection, options?)` | Sets the selected item and range. | -| `getSelectedLines()` | Gets the selected item and range. | -| `clearSelectedLines(options?)` | Clears the selected lines. | -| `setOptions(options)` | Replaces list options. | -| `onThemeChange()` | Applies a changed theme to list items. | -| `render(immediate?)` | Schedules or performs a render. | -| `getWindowSpecs()` | Gets the current virtual window. | -| `getContainerElement()` | Gets the scroll content element. | -| `getHeaderElement()` | Gets the list header host. | -| `getFooterElement()` | Gets the list footer host. | -| `getRenderedItems()` | Gets mounted items. | -| `setSlotCoordinator(coordinator?)` | Sets the external slot coordinator. | -| `getSlotSnapshot(coordinator)` | Gets the coordinator's mounted slot state. | -| `subscribeToScroll(listener)` | Subscribes to scroll changes. | -| `getLocalTopForInstance(instance)` | Gets an instance offset inside the list. | -| `getTopForItem(id)` | Gets an item offset inside the list. | -| `instanceChanged(instance, layoutDirty)` | Reports a render instance change. | -| `reset()` | Clears items and render state. | -| `cleanUp()` | Releases list resources. | - -## Parsing and patch APIs - -| Export | Purpose | -| ---------------------------- | ----------------------------------------------------- | -| `parseDiffFromFile` | Creates `FileDiffMetadata` from old and new files. | -| `parsePatchFiles` | Parses a patch string into file diff metadata. | -| `processPatch` | Parses one patch section. | -| `processFile` | Converts one parsed patch file to `FileDiffMetadata`. | -| `getSingularPatch` | Selects one file patch from a patch string. | -| `trimPatchContext` | Limits unchanged context in patch text. | -| `hydratePartialDiff` | Adds loaded file contents to partial diff metadata. | -| `cloneFileDiffMetadata` | Creates a structural copy of diff metadata. | -| `cleanLastNewline` | Normalizes the final newline for diff input. | -| `getLineEndingType` | Detects a file's line-ending sequence. | -| `getTotalLineCountFromHunks` | Counts rendered rows across hunks. | -| `parseLineType` | Parses one patch line marker and content. | -| `ParsedLine` | Describes the result from `parseLineType`. | - -## Merge conflict APIs - -| Export | Purpose | -| ---------------------- | --------------------------------------------------------------- | -| `resolveConflict` | Applies one current, incoming, or combined conflict resolution. | -| `resolveRegion` | Resolves one parsed merge conflict region. | -| `diffAcceptRejectHunk` | Applies accept or reject behavior to one change hunk. | - -## Annotation APIs - -| Export | Purpose | -| ---------------------------- | ---------------------------------------------------------- | -| `isFileAnnotation` | Tests whether one annotation targets a file line. | -| `isDiffAnnotation` | Tests whether one annotation targets a diff side and line. | -| `isFileAnnotationCollection` | Tests whether an array contains file annotations. | -| `isDiffAnnotationCollection` | Tests whether an array contains diff annotations. | - -## File extension APIs - -| Export | Purpose | -| ---------------------------- | ------------------------------------------------ | -| `getFiletypeFromFileName` | Infers a language from a file name. | -| `setCustomExtension` | Maps one file name or extension to a language. | -| `replaceCustomExtensions` | Replaces all custom mappings. | -| `getCustomExtensionsMap` | Gets a copy of custom mappings. | -| `getCustomExtensionsVersion` | Gets the mapping revision. | -| `EXTENSION_TO_FILE_FORMAT` | Maps built-in extensions and names to languages. | -| `setLanguageOverride` | Assigns a language to parsed diff files. | diff --git a/skills/diffs/references/api-core.md b/skills/diffs/references/api-core.md new file mode 120000 index 000000000..718c3ee04 --- /dev/null +++ b/skills/diffs/references/api-core.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-core.md \ No newline at end of file diff --git a/skills/diffs/references/api-editor.md b/skills/diffs/references/api-editor.md deleted file mode 100644 index 671d1195d..000000000 --- a/skills/diffs/references/api-editor.md +++ /dev/null @@ -1,95 +0,0 @@ -# Editor API - -This reference lists every export from `@pierre/diffs/edit` and every public -member of its classes. - -## Exports - -| Export | Kind | Purpose | -| --------------------- | ----- | --------------------------------------------------------- | -| `Editor` | Class | Adds text editing to a `File` or `FileDiff` instance. | -| `EditorChange` | Type | Describes one normalized editor change. | -| `EditorChangeEvent` | Type | Provides normalized edits and current document state. | -| `EditorOptions` | Type | Configures history, state, selections, and callbacks. | -| `TextDocument` | Class | Stores text, positions, edits, search, and undo history. | -| `TextDocumentChange` | Type | Describes the lines and characters changed by an edit. | -| `IStateStorage` | Type | Defines asynchronous or synchronous editor state storage. | -| `PersistStateStorage` | Type | Selects memory, IndexedDB, or custom state storage. | -| `Position` | Type | Identifies a zero-based line and character. | -| `Range` | Type | Identifies a start and end position. | -| `TextEdit` | Type | Replaces one range with new text. | - -## `EditorOptions` fields - -| Field | Purpose | -| ------------------------ | -------------------------------------------------------- | -| `historyMaxEntries` | Limits the undo stack. | -| `persistState` | Keeps editor state for each file cache key. | -| `persistStateStorage` | Selects the state store. | -| `roundedSelection` | Controls rounded selection corners. | -| `matchBrackets` | Controls matching-bracket highlights. | -| `autoSurround` | Controls quote and bracket insertion around a selection. | -| `languageCommentConfig` | Overrides comment tokens by language. | -| `enabledSelectionAction` | Enables the selection action surface. | -| `clipboard` | Supplies a text clipboard reader. | -| `renderSelectionAction` | Produces the selection action element. | -| `onAttach` | Receives the editor and attached surface. | -| `onChange` | Receives file state, annotations, and a change event. | -| `onFocus` | Runs after the editor gains focus. | -| `onBlur` | Runs after the editor loses focus. | - -## `Editor` members - -| Member | Purpose | -| ----------------------------------- | --------------------------------------------------------- | -| `new Editor(options?)` | Creates one editor. | -| `edit(instance)` | Attaches to a file or diff and returns a detach function. | -| `setOptions(options)` | Replaces editor options. | -| `applyEdits(edits, updateHistory?)` | Applies programmatic text edits. | -| `canUndo` | Reports whether undo has an entry. | -| `canRedo` | Reports whether redo has an entry. | -| `undo()` | Reverts the latest edit. | -| `redo()` | Reapplies the latest reverted edit. | -| `getFile()` | Gets the current file contents. | -| `getText()` | Gets the current text. | -| `getState()` | Gets selections and view state. | -| `setState(state)` | Sets selections and view state. | -| `setSelections(selections)` | Sets directed selection ranges. | -| `setMarkers(markers)` | Sets diagnostic markers. | -| `focus(options?)` | Focuses the editor. | -| `blur()` | Removes editor focus. | -| `cleanUp(recycle?)` | Releases editor resources. | - -## `TextDocument` members - -| Member | Purpose | -| ---------------------------------------------------- | ----------------------------------------------------- | -| `new TextDocument(uri, text, languageId?, version?)` | Creates a text document. | -| `uri` | Gets the document identifier. | -| `languageId` | Gets the language identifier. | -| `version` | Gets the document version. | -| `lineCount` | Gets the line count. | -| `eol` | Gets the line-ending sequence. | -| `canUndo` | Reports whether undo has an entry. | -| `canRedo` | Reports whether redo has an entry. | -| `positionAt(offset)` | Converts an offset to a position. | -| `positionsAt(offsets)` | Converts several offsets to positions. | -| `offsetAt(position)` | Converts a position to an offset. | -| `getText(range?)` | Gets all text or one range. | -| `getLineText(line, includeLineBreak?)` | Gets one line. | -| `normalizeEol(text)` | Converts text to the document line ending. | -| `getLineLength(line, includeLineBreak?)` | Gets one line length. | -| `charAt(offsetOrPosition)` | Gets one character. | -| `getTextSlice(start, end)` | Gets text between two offsets. | -| `findNextNonOverlappingSubstring(needle, occupied)` | Finds an unused substring range. | -| `search(params)` | Finds text ranges. | -| `applyEdits(edits, ...)` | Resolves and applies position-based edits. | -| `resolveEdits(edits)` | Converts position-based edits to offset edits. | -| `applyResolvedEdits(edits, ...)` | Applies offset-based edits. | -| `setLastUndoSelectionsAfter(selections)` | Associates selections with the latest history entry. | -| `setLastUndoLineAnnotations(before, after)` | Associates annotations with the latest history entry. | -| `undo()` | Reverts one document history entry. | -| `redo()` | Reapplies one document history entry. | -| `normalizePosition(position)` | Clamps a position to the document. | - -`IStateStorage` has `get(cacheKey)` and `set(cacheKey, state)` methods. diff --git a/skills/diffs/references/api-editor.md b/skills/diffs/references/api-editor.md new file mode 120000 index 000000000..b48858fe8 --- /dev/null +++ b/skills/diffs/references/api-editor.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-editor.md \ No newline at end of file diff --git a/skills/diffs/references/api-highlighting.md b/skills/diffs/references/api-highlighting.md deleted file mode 100644 index 861d8884f..000000000 --- a/skills/diffs/references/api-highlighting.md +++ /dev/null @@ -1,113 +0,0 @@ -# Highlighting API - -This reference lists every language, theme, shared highlighter, and stream -export from `@pierre/diffs`. - -## Contents - -- [Shiki passthrough APIs](#shiki-passthrough-apis) -- [Language APIs](#language-apis) -- [Theme APIs](#theme-apis) -- [Shared highlighter APIs](#shared-highlighter-apis) -- [Render APIs](#render-apis) -- [Stream APIs](#stream-apis) - -## Shiki passthrough APIs - -| Export | Kind | Purpose | -| ------------------------- | -------- | ------------------------------------------------ | -| `codeToHtml` | Function | Re-exports Shiki's complete code-to-HTML helper. | -| `createCSSVariablesTheme` | Function | Re-exports Shiki's CSS variable theme factory. | - -## Language APIs - -| Export | Kind | Purpose | -| ------------------------------ | -------- | --------------------------------------------------------- | -| `registerCustomLanguage` | Function | Registers a lazy language and optional file mappings. | -| `resolveLanguage` | Function | Loads and caches one language registration. | -| `resolveLanguages` | Function | Loads and caches several language registrations. | -| `getResolvedOrResolveLanguage` | Function | Returns one cached language or starts its load. | -| `getResolvedLanguages` | Function | Gets cached registrations for the supplied languages. | -| `hasResolvedLanguages` | Function | Tests whether language registrations are cached. | -| `attachResolvedLanguages` | Function | Adds resolved registrations to a highlighter. | -| `areLanguagesAttached` | Function | Tests whether a highlighter has the supplied languages. | -| `cleanUpResolvedLanguages` | Function | Clears language resolution state. | -| `RegisteredCustomLanguages` | Map | Stores registered custom language loaders. | -| `ResolvedLanguages` | Map | Stores resolved language registrations. | -| `ResolvingLanguages` | Map | Stores active language load promises. | -| `AttachedLanguages` | Set | Stores language names attached to the shared highlighter. | - -## Theme APIs - -| Export | Kind | Purpose | -| -------------------------------- | -------- | ------------------------------------------------------ | -| `registerCustomTheme` | Function | Registers a lazy Shiki theme loader. | -| `CustomThemeLoader` | Type | Defines a raw or resolved Shiki theme loader. | -| `registerCustomCSSVariableTheme` | Function | Registers a theme that reads CSS variables. | -| `resolveTheme` | Function | Loads and caches one theme. | -| `resolveThemes` | Function | Loads and caches several themes. | -| `getResolvedOrResolveTheme` | Function | Returns one cached theme or starts its load. | -| `getResolvedThemes` | Function | Gets cached themes by name. | -| `hasResolvedThemes` | Function | Tests whether themes are cached. | -| `attachResolvedThemes` | Function | Adds resolved themes to a highlighter. | -| `areThemesAttached` | Function | Tests whether a highlighter has the supplied themes. | -| `cleanUpResolvedThemes` | Function | Clears theme resolution state. | -| `AttachedThemes` | Set | Stores theme names attached to the shared highlighter. | - -## Shared highlighter APIs - -| Export | Purpose | -| --------------------------- | ----------------------------------------------------------------- | -| `getSharedHighlighter` | Gets or creates the shared highlighter for themes and languages. | -| `preloadHighlighter` | Loads the shared highlighter before a render. | -| `getHighlighterIfLoaded` | Gets the shared highlighter after load. | -| `isHighlighterLoaded` | Tests a highlighter cache value for a loaded instance. | -| `isHighlighterLoading` | Tests a highlighter cache value for an active promise. | -| `isHighlighterNull` | Tests a highlighter cache value for an empty state. | -| `disposeHighlighter` | Disposes and clears the shared highlighter. | -| `getHighlighterOptions` | Converts one language and component options to highlighter input. | -| `getHighlighterThemeStyles` | Creates theme CSS from a loaded highlighter. | -| `getThemes` | Converts one theme or light/dark pair to a name list. | -| `isWorkerContext` | Tests whether code runs in a worker global scope. | - -## Render APIs - -| Export | Purpose | -| ---------------------------- | ------------------------------------------------------- | -| `renderFileWithHighlighter` | Creates a highlighted file syntax tree. | -| `renderDiffWithHighlighter` | Creates highlighted deletion and addition syntax trees. | -| `createTransformerWithState` | Creates Shiki transformers with shared render state. | - -## Stream APIs - -| Export | Kind | Purpose | -| ----------------------------------- | ----- | ------------------------------------------------------------- | -| `FileStream` | Class | Renders a readable code stream as highlighted rows. | -| `FileStreamOptions` | Type | Configures stream language, theme, start line, and callbacks. | -| `CodeToTokenTransformStream` | Class | Converts code chunks to themed or recall tokens. | -| `CodeToTokenTransformStreamOptions` | Type | Configures stream tokenization and recall tokens. | -| `ShikiStreamTokenizer` | Class | Tracks stable and unstable tokens across code chunks. | -| `ShikiStreamTokenizerOptions` | Type | Supplies Shiki token options and a highlighter. | -| `ShikiStreamTokenizerEnqueueResult` | Type | Returns recalled, stable, and unstable tokens for one chunk. | -| `RecallToken` | Type | Requests removal of prior unstable tokens. | - -## `FileStream` members - -| Member | Purpose | -| -------------------------- | ------------------------------------------ | -| `new FileStream(options?)` | Creates a stream renderer. | -| `setup(source, wrapper)` | Connects a readable code stream to a host. | -| `setThemeType(themeType)` | Selects system, light, or dark theme mode. | -| `cleanUp()` | Aborts the stream and releases resources. | - -## `ShikiStreamTokenizer` members - -| Member | Purpose | -| ----------------------------------- | ------------------------------------ | -| `new ShikiStreamTokenizer(options)` | Creates a stateful tokenizer. | -| `enqueue(chunk)` | Tokenizes one code chunk. | -| `close()` | Finalizes and returns stable tokens. | -| `clear()` | Clears accumulated token state. | -| `clone()` | Copies current tokenizer state. | - -`CodeToTokenTransformStream` exposes its `tokenizer` and `options` values. diff --git a/skills/diffs/references/api-highlighting.md b/skills/diffs/references/api-highlighting.md new file mode 120000 index 000000000..a03fa2a16 --- /dev/null +++ b/skills/diffs/references/api-highlighting.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-highlighting.md \ No newline at end of file diff --git a/skills/diffs/references/api-react.md b/skills/diffs/references/api-react.md deleted file mode 100644 index 96e6bf76e..000000000 --- a/skills/diffs/references/api-react.md +++ /dev/null @@ -1,63 +0,0 @@ -# React API - -This reference lists the React-specific exports from `@pierre/diffs/react`. The -entry also re-exports every type in [Shared types](api-types.md). - -## Components and hooks - -| Export | Kind | Purpose | -| --------------------------- | --------- | --------------------------------------------------------- | -| `File` | Component | Renders one code file. | -| `FileDiff` | Component | Renders pre-parsed diff metadata. | -| `MultiFileDiff` | Component | Parses and renders an old and new file pair. | -| `PatchDiff` | Component | Parses and renders one unified patch string. | -| `UnresolvedFile` | Component | Renders and resolves merge conflicts in one file. | -| `CodeView` | Component | Renders a virtualized list of files and diffs. | -| `Virtualizer` | Component | Provides simple viewport virtualization. | -| `useVirtualizer` | Hook | Gets the nearest simple `Virtualizer` instance. | -| `EditProvider` | Component | Supplies an editor factory. | -| `useCreateEditor` | Hook | Gets the nearest editor factory. | -| `WorkerPoolContextProvider` | Component | Creates and supplies a worker pool. | -| `useWorkerPool` | Hook | Gets the nearest worker pool. | -| `useFileInstance` | Hook | Creates and manages a vanilla `File` instance. | -| `useFileDiffInstance` | Hook | Creates and manages a vanilla `FileDiff` instance. | -| `useStableCallback` | Hook | Returns a stable callback that reads the latest function. | - -## Component and provider types - -| Export | Purpose | -| ----------------------------------- | ----------------------------------------------------------------- | -| `FileProps` | Defines props for `File`. | -| `FileOptions` | Defines vanilla file options and the React `options` prop. | -| `FileDiffProps` | Defines props for `FileDiff`. | -| `MultiFileDiffProps` | Defines props for `MultiFileDiff`. | -| `PatchDiffProps` | Defines props for `PatchDiff`. | -| `UnresolvedFileProps` | Defines props for `UnresolvedFile`. | -| `UnresolvedFileReactOptions` | Defines merge-conflict options for React. | -| `DiffBasePropsReact` | Defines props shared by React diff components. | -| `CodeViewProps` | Defines controlled or uncontrolled `CodeView` props. | -| `ControlledCodeViewProps` | Defines `CodeView` props with `items`. | -| `UncontrolledCodeViewProps` | Defines `CodeView` props with `initialItems`. | -| `CodeViewReactOptions` | Defines the React-safe `CodeView` option set. | -| `CodeViewHandle` | Defines imperative list, selection, scroll, and editor controls. | -| `CreateEditor` | Defines the editor factory. | -| `EditProviderProps` | Defines the `EditProvider` factory prop. | -| `MergeConflictActionsTypeOption` | Selects no actions, default actions, or a custom action renderer. | -| `RenderMergeConflictActionContext` | Supplies conflict resolution to a custom action renderer. | -| `RenderMergeConflictActions` | Defines a custom conflict action renderer. | -| `WorkerInitializationRenderOptions` | Defines initial worker languages and render options. | -| `WorkerPoolOptions` | Defines the worker factory, pool size, and cache size. | - -## Contexts and render helpers - -| Export | Kind | Purpose | -| ------------------------- | -------- | ------------------------------------------------------ | -| `EditContext` | Context | Holds the editor factory. | -| `WorkerPoolContext` | Context | Holds the worker pool. | -| `VirtualizerContext` | Context | Holds the simple virtualizer. | -| `GutterUtilitySlotStyles` | Value | Supplies style keys for gutter utility slots. | -| `MergeConflictSlotStyles` | Value | Supplies style keys for merge conflict slots. | -| `noopRender` | Function | Returns no React output for an optional render slot. | -| `renderDiffChildren` | Function | Builds React portals for diff slots. | -| `renderFileChildren` | Function | Builds React portals for file slots. | -| `templateRender` | Function | Renders React content through a managed template slot. | diff --git a/skills/diffs/references/api-react.md b/skills/diffs/references/api-react.md new file mode 120000 index 000000000..231cc1ee6 --- /dev/null +++ b/skills/diffs/references/api-react.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-react.md \ No newline at end of file diff --git a/skills/diffs/references/api-rendering.md b/skills/diffs/references/api-rendering.md deleted file mode 100644 index 5e9de9707..000000000 --- a/skills/diffs/references/api-rendering.md +++ /dev/null @@ -1,183 +0,0 @@ -# Low-level rendering API - -This reference lists the renderer, manager, DOM helper, comparison, and constant -exports from `@pierre/diffs`. - -## Contents - -- [Renderers](#renderers) -- [Interaction manager](#interaction-manager) -- [Size, scroll, and render managers](#size-scroll-and-render-managers) -- [Comparison helpers](#comparison-helpers) -- [Syntax tree and DOM helpers](#syntax-tree-and-dom-helpers) -- [Layout and CSS helpers](#layout-and-css-helpers) -- [Constants](#constants) - -## Renderers - -| Export | Kind | Purpose | -| -------------------------------------- | ----- | ------------------------------------------------------- | -| `FileRenderer` | Class | Converts one file to highlighted HAST, CSS, and HTML. | -| `FileRendererOptions` | Type | Adds header mode to base code options. | -| `FileRenderResult` | Type | Holds file HAST, CSS, row counts, and buffers. | -| `DiffHunksRenderer` | Class | Converts diff hunks to highlighted column HAST and CSS. | -| `DiffHunksRendererOptions` | Type | Configures one hunk renderer. | -| `DiffHunksRendererOptionsWithDefaults` | Type | Describes resolved hunk renderer options. | -| `HunksRenderResult` | Type | Holds rendered diff columns, metadata, and row count. | -| `RenderedLineContext` | Type | Supplies line state to a line decoration. | -| `LineDecoration` | Type | Defines a custom line wrapper and injected rows. | -| `InjectedRow` | Type | Defines one row inserted around a unified line. | -| `SplitInjectedRow` | Type | Defines one row inserted around a split line. | -| `UnifiedInjectedRowPlacement` | Type | Selects placement before or after a unified row. | -| `SplitInjectedRowPlacement` | Type | Selects side and placement for a split row. | -| `UnifiedLineDecorationProps` | Type | Supplies one unified row to a decoration. | -| `SplitLineDecorationProps` | Type | Supplies paired split rows to a decoration. | - -## Interaction manager - -| Export | Kind | Purpose | -| ------------------------------- | -------- | ------------------------------------------------------------------------ | -| `InteractionManager` | Class | Handles hover, token, gutter, and line selection events. | -| `InteractionManagerMode` | Type | Selects file or diff interaction data. | -| `InteractionManagerBaseOptions` | Type | Defines interaction callbacks and enabled features. | -| `InteractionManagerOptions` | Type | Adds required DOM access to base interaction options. | -| `GetHoveredLineResult` | Type | Describes the current hovered file or diff line. | -| `GetLineIndexUtility` | Type | Maps a logical line to row and column indexes. | -| `OnLineClickProps` | Type | Describes a file line click. | -| `OnLineEnterLeaveProps` | Type | Describes file line pointer entry or exit. | -| `OnDiffLineClickProps` | Type | Describes a diff line click. | -| `OnDiffLineEnterLeaveProps` | Type | Describes diff line pointer entry or exit. | -| `OnTokenEventProps` | Type | Selects file or diff token event data. | -| `SelectionWriteOptions` | Type | Configures callback emission, the active side, and line-only highlights. | -| `MergeConflictActionTarget` | Type | Describes a merge conflict action element. | -| `LogTypes` | Type | Selects interaction log categories. | -| `pluckInteractionOptions` | Function | Selects interaction fields from component options. | - -## Size, scroll, and render managers - -| Export | Kind | Purpose | -| --------------------------------- | -------- | ------------------------------------------------------------- | -| `ResizeManager` | Class | Measures rows, annotations, and column CSS values. | -| `ResizeManagerColumnVariableMode` | Type | Selects column variable measurement or application. | -| `ResizeManagerSetupOptions` | Type | Configures annotation and column measurement. | -| `ScrollSyncManager` | Class | Synchronizes additions and deletions column scroll positions. | -| `queueRender` | Function | Adds a callback to the shared animation render queue. | -| `dequeueRender` | Function | Removes a callback from the shared render queue. | -| `clearRenderQueue` | Function | Removes all callbacks from the shared render queue. | - -## Comparison helpers - -| Export | Purpose | -| ----------------------------- | ------------------------------------------------- | -| `areDiffLineAnnotationsEqual` | Compares two diff annotation arrays. | -| `areLineAnnotationsEqual` | Compares two file annotation arrays. | -| `areDiffRenderOptionsEqual` | Compares resolved diff render options. | -| `areFileRenderOptionsEqual` | Compares resolved file render options. | -| `areDiffTargetsEqual` | Compares two diff interaction targets. | -| `areFilesEqual` | Compares two file inputs. | -| `areHunkDataEqual` | Compares two hunk data objects. | -| `areObjectsEqual` | Performs the package's shallow object comparison. | -| `areOptionsEqual` | Compares component option objects. | -| `arePrePropertiesEqual` | Compares calculated `pre` properties. | -| `areRenderRangesEqual` | Compares two render ranges. | -| `areSelectionsEqual` | Compares editor selection arrays. | -| `areThemesEqual` | Compares theme names or light/dark pairs. | -| `areVirtualWindowSpecsEqual` | Compares two virtual window descriptions. | -| `areWorkerStatsEqual` | Compares two worker statistics objects. | - -## Syntax tree and DOM helpers - -| Export | Kind | Purpose | -| -------------------------------- | -------- | ---------------------------------------------------------- | -| `createAnnotationElement` | Function | Creates a HAST annotation row from an annotation span. | -| `createAnnotationWrapperNode` | Function | Creates a DOM host for an annotation slot. | -| `createDiffSpanDecoration` | Function | Creates one Shiki inline diff decoration. | -| `pushOrJoinSpan` | Function | Adds or joins one inline diff span. | -| `createEmptyRowBuffer` | Function | Creates an empty virtual row buffer. | -| `createFileHeaderElement` | Function | Creates a file or diff header HAST element. | -| `CreateFileHeaderElementProps` | Type | Defines header source, mode, and sticky state. | -| `createGutterGap` | Function | Creates a gutter gap HAST element. | -| `createGutterItem` | Function | Creates a gutter item HAST element. | -| `createGutterWrapper` | Function | Creates a gutter wrapper HAST element. | -| `createGutterUtilityElement` | Function | Creates a gutter utility HAST element. | -| `createGutterUtilityContentNode` | Function | Creates a gutter utility DOM content host. | -| `createHastElement` | Function | Creates a typed HAST element. | -| `createIconElement` | Function | Creates a sprite icon HAST element. | -| `createTextNodeElement` | Function | Creates a HAST text node. | -| `createNoNewlineElement` | Function | Creates the missing-final-newline HAST element. | -| `createPreElement` | Function | Creates the outer HAST `pre` element. | -| `createPreWrapperProperties` | Function | Creates HAST properties for a `pre` wrapper. | -| `createRowNodes` | Function | Creates DOM row and content elements for one line. | -| `createSeparator` | Function | Creates a hunk separator HAST element. | -| `createSpanFromToken` | Function | Creates a HAST span from one highlighted token. | -| `createStyleElement` | Function | Creates a DOM style element with an attribute marker. | -| `createThemeStyleElement` | Function | Creates a marked theme style element. | -| `createUnsafeCSSStyleNode` | Function | Creates a marked custom CSS style element. | -| `findCodeElement` | Function | Finds the code element in a HAST tree. | -| `getLineNodes` | Function | Gets rendered line nodes from a HAST root. | -| `getOrCreateCodeNode` | Function | Reuses or creates a code column DOM node. | -| `getLineAnnotationName` | Function | Creates the slot name for a line annotation. | -| `getHunkSeparatorSlotName` | Function | Creates the slot name for a hunk separator. | -| `getIconForType` | Function | Maps a file change type to a sprite icon. | -| `processLine` | Function | Applies line render state to one HAST line. | -| `setPreNodeProperties` | Function | Applies resolved render properties to a DOM `pre` element. | -| `prerenderHTMLIfNecessary` | Function | Adds preloaded HTML to an empty host element. | - -## Layout and CSS helpers - -| Export | Purpose | -| -------------------------------- | ------------------------------------------------------------- | -| `createWindowFromScrollPosition` | Calculates a virtual window from scroll measurements. | -| `isDefaultRenderRange` | Tests whether a render range covers the default full range. | -| `prefersReducedMotion` | Reads the reduced-motion media preference. | -| `formatCSSVariablePrefix` | Creates the global or token CSS variable prefix. | -| `wrapCoreCSS` | Places core CSS in its cascade layer. | -| `wrapThemeCSS` | Places theme CSS in its layer and mode selector. | -| `wrapUnsafeCSS` | Places custom CSS in its cascade layer. | -| `patchScrollbarGutterSize` | Updates the measured scrollbar gutter in theme CSS. | -| `detachString` | Copies a retained substring to an independent backing string. | -| `releaseStringDetachBuffer` | Resets the reusable string copy buffer. | -| `SVGSpriteSheet` | Contains the SVG symbols used by rendered controls. | -| `SVGSpriteNames` | Names a symbol in `SVGSpriteSheet`. | - -## Constants - -| Export | Purpose | -| ------------------------------------------ | ----------------------------------------------------- | -| `DEFAULT_THEMES` | Provides the default light and dark theme names. | -| `DEFAULT_TOKENIZE_MAX_LENGTH` | Provides the default total tokenization limit. | -| `DEFAULT_COLLAPSED_CONTEXT_THRESHOLD` | Provides the default hidden-context threshold. | -| `DEFAULT_EXPANDED_REGION` | Provides the default hunk expansion state. | -| `DEFAULT_RENDER_RANGE` | Provides the full render range. | -| `EMPTY_RENDER_RANGE` | Provides an empty render range. | -| `DEFAULT_VIRTUAL_FILE_METRICS` | Provides estimated file header and line heights. | -| `DEFAULT_CODE_VIEW_FILE_METRICS` | Provides list item height estimates. | -| `DEFAULT_CODE_VIEW_LAYOUT` | Provides an empty list layout. | -| `DEFAULT_SMOOTH_SCROLL_SETTINGS` | Provides the default smooth scroll settings. | -| `DIFFS_TAG_NAME` | Provides the `diffs-container` custom element name. | -| `CORE_CSS_ATTRIBUTE` | Provides the core style marker attribute. | -| `THEME_CSS_ATTRIBUTE` | Provides the theme style marker attribute. | -| `UNSAFE_CSS_ATTRIBUTE` | Provides the custom style marker attribute. | -| `DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE` | Provides the scrollbar measurement attribute. | -| `DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY` | Provides the measured scrollbar CSS property. | -| `CODE_VIEW_HEADER_ATTRIBUTE` | Provides the list header host attribute. | -| `CODE_VIEW_FOOTER_ATTRIBUTE` | Provides the list footer host attribute. | -| `CUSTOM_HEADER_SLOT_ID` | Provides the custom header slot ID. | -| `HEADER_PREFIX_SLOT_ID` | Provides the header prefix slot ID. | -| `HEADER_FILENAME_SUFFIX_SLOT_ID` | Provides the filename suffix slot ID. | -| `HEADER_METADATA_SLOT_ID` | Provides the header metadata slot ID. | -| `HUNK_HEADER` | Provides the patch hunk header marker. | -| `FILE_CONTEXT_BLOB` | Matches a patch hunk boundary. | -| `INDEX_LINE_METADATA` | Provides the patch index metadata marker. | -| `COMMIT_METADATA_SPLIT` | Provides the commit metadata separator expression. | -| `FILENAME_HEADER_REGEX` | Matches a standard patch file header. | -| `FILENAME_HEADER_REGEX_GIT` | Matches a Git patch file header. | -| `GIT_DIFF_FILE_BREAK_REGEX` | Matches a Git patch file boundary. | -| `UNIFIED_DIFF_FILE_BREAK_REGEX` | Matches a unified patch file boundary. | -| `ALTERNATE_FILE_NAMES_GIT` | Matches alternate file names in a Git patch header. | -| `MERGE_CONFLICT_START_MARKER_REGEX` | Matches a conflict start marker. | -| `MERGE_CONFLICT_BASE_MARKER_REGEX` | Matches a conflict base marker. | -| `MERGE_CONFLICT_SEPARATOR_MARKER_REGEX` | Matches a conflict separator marker. | -| `MERGE_CONFLICT_END_MARKER_REGEX` | Matches a conflict end marker. | -| `SPLIT_WITH_NEWLINES` | Splits text while it preserves newline tokens. | -| `DIFFS_DEVELOPMENT_BUILD` | Reports whether the package uses a development build. | diff --git a/skills/diffs/references/api-rendering.md b/skills/diffs/references/api-rendering.md new file mode 120000 index 000000000..cebb62a7d --- /dev/null +++ b/skills/diffs/references/api-rendering.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-rendering.md \ No newline at end of file diff --git a/skills/diffs/references/api-ssr.md b/skills/diffs/references/api-ssr.md deleted file mode 100644 index 6f5b7e61f..000000000 --- a/skills/diffs/references/api-ssr.md +++ /dev/null @@ -1,35 +0,0 @@ -# SSR API - -This reference lists the SSR-specific exports from `@pierre/diffs/ssr`. The -entry also re-exports every type in [Shared types](api-types.md). - -## Functions - -| Export | Purpose | -| --------------------------- | ------------------------------------------------------------- | -| `preloadFile` | Renders one file and returns props with `prerenderedHTML`. | -| `preloadFileDiff` | Renders pre-parsed diff metadata and returns component props. | -| `preloadMultiFileDiff` | Parses and renders an old and new file pair. | -| `preloadPatchDiff` | Parses and renders one patch for `PatchDiff`. | -| `preloadPatchFile` | Parses a multi-file patch and returns one result per file. | -| `preloadUnresolvedFile` | Renders one merge-conflict file and returns component props. | -| `preloadDiffHTML` | Renders a diff directly to an HTML string. | -| `preloadUnresolvedFileHTML` | Renders a merge-conflict file directly to an HTML string. | -| `renderHTML` | Serializes rendered HAST elements to HTML. | - -## Types - -| Export | Purpose | -| ------------------------------ | -------------------------------------------------------- | -| `PreloadFileOptions` | Defines input for `preloadFile`. | -| `PreloadedFileResult` | Adds `prerenderedHTML` to file input. | -| `PreloadDiffOptions` | Defines parsed or file-pair input for `preloadDiffHTML`. | -| `PreloadFileDiffOptions` | Defines input for `preloadFileDiff`. | -| `PreloadFileDiffResult` | Adds `prerenderedHTML` to parsed diff input. | -| `PreloadMultiFileDiffOptions` | Defines input for `preloadMultiFileDiff`. | -| `PreloadMultiFileDiffResult` | Adds `prerenderedHTML` to file-pair input. | -| `PreloadPatchDiffOptions` | Defines input for `preloadPatchDiff`. | -| `PreloadPatchDiffResult` | Adds `prerenderedHTML` to patch input. | -| `PreloadPatchFileOptions` | Defines input for `preloadPatchFile`. | -| `PreloadUnresolvedFileOptions` | Defines input for `preloadUnresolvedFile`. | -| `PreloadUnresolvedFileResult` | Adds `prerenderedHTML` to merge-conflict input. | diff --git a/skills/diffs/references/api-ssr.md b/skills/diffs/references/api-ssr.md new file mode 120000 index 000000000..aad99c700 --- /dev/null +++ b/skills/diffs/references/api-ssr.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-ssr.md \ No newline at end of file diff --git a/skills/diffs/references/api-types.md b/skills/diffs/references/api-types.md deleted file mode 100644 index deed8152d..000000000 --- a/skills/diffs/references/api-types.md +++ /dev/null @@ -1,176 +0,0 @@ -# Shared types - -This reference lists every export from the shared `@pierre/diffs` type module. -The root, React, and SSR entries re-export these types. - -## Contents - -- [Files and patches](#files-and-patches) -- [Themes and options](#themes-and-options) -- [Annotations and selection](#annotations-and-selection) -- [`CodeView` types](#codeview-types) -- [Lines, hunks, and render state](#lines-hunks-and-render-state) -- [Render results and virtualization](#render-results-and-virtualization) -- [Component and editor contracts](#component-and-editor-contracts) -- [Shiki and diff types](#shiki-and-diff-types) - -## Files and patches - -| Export | Purpose | -| ------------------------------- | ----------------------------------------------------------------- | -| `FileContents` | Describes a file name, text, language, header, and cache key. | -| `DiffFileInput` | Accepts an old and new file for changes, additions, or deletions. | -| `MaybeDiffFileInput` | Accepts a file pair or no file input. | -| `FileDiffContentsLoader` | Loads complete files for partial diff metadata. | -| `FileDiffLoadedChangedFiles` | Returns both files for a loaded changed diff. | -| `FileDiffLoadedPureRenamedFile` | Returns the new file for a loaded pure rename. | -| `FileDiffLoadedFiles` | Represents either loaded-file result. | -| `ChangeTypes` | Names changed, renamed, added, or deleted file states. | -| `ParsedPatch` | Holds patch metadata and parsed files. | -| `ContextContent` | Describes one unchanged hunk block. | -| `ChangeContent` | Describes one additions and deletions block. | -| `Hunk` | Describes one parsed patch hunk. | -| `FileDiffMetadata` | Holds parsed file names, lines, hunks, and change metadata. | -| `MergeConflictMarkerRowType` | Names a merge conflict marker row. | -| `MergeConflictMarkerRow` | Describes one marker row and its source line. | -| `MergeConflictRegion` | Describes one parsed merge conflict region. | -| `MergeConflictResolution` | Selects current, incoming, or both conflict contents. | -| `MergeConflictActionPayload` | Describes one conflict action and region. | -| `ProcessFileConflictData` | Holds state while patch parsing processes conflicts. | -| `ConflictResolverTypes` | Names current, incoming, or both conflict choices. | - -## Themes and options - -| Export | Purpose | -| ------------------------------------ | ------------------------------------------------------------ | -| `SupportedLanguages` | Accepts a bundled, text, ANSI, or custom language name. | -| `HighlighterTypes` | Selects the JavaScript or WebAssembly Shiki engine. | -| `HighlightedToken` | Stores a character index, foreground, and token text. | -| `DiffsThemeNames` | Accepts a bundled or custom theme name. | -| `ThemesType` | Maps light and dark schemes to theme names. | -| `ThemeTypes` | Selects system, light, or dark mode. | -| `DiffsHighlighter` | Defines the package's configured Shiki highlighter. | -| `BaseCodeOptions` | Configures themes, wrapping, headers, tokenization, and CSS. | -| `BaseDiffOptions` | Adds layout, indicators, context, and line diff options. | -| `BaseDiffOptionsWithDefaults` | Describes required diff options after defaults apply. | -| `DiffIndicators` | Selects classic, bar, or hidden diff indicators. | -| `HunkSeparators` | Selects the hunk separator presentation. | -| `LineDiffTypes` | Selects word, alternate word, character, or no inline diff. | -| `FileHeaderRenderMode` | Selects a default or custom file header. | -| `CustomPreProperties` | Defines custom properties for the rendered `pre` element. | -| `PrePropertiesConfig` | Describes calculated `pre` element properties. | -| `ExtensionFormatMap` | Maps file names or extensions to languages. | -| `RenderHeaderPrefixCallback` | Produces prefix content for a diff header. | -| `RenderHeaderFilenameSuffixCallback` | Produces filename suffix content for a diff header. | -| `RenderHeaderMetadataCallback` | Produces metadata content for a diff header. | -| `RenderFileMetadata` | Produces header content for a file. | -| `PostRenderPhase` | Names mount, update, or unmount callback phases. | - -## Annotations and selection - -| Export | Purpose | -| ------------------------- | ------------------------------------------------------------ | -| `AnnotationSide` | Selects deletions or additions for an annotation. | -| `LineAnnotation` | Associates metadata with one file line. | -| `DiffLineAnnotation` | Associates metadata with one side and line. | -| `AnnotationLineMap` | Groups diff annotations by line number. | -| `SelectedLineRange` | Describes a selected start and end across diff sides. | -| `SelectionSide` | Selects deletions or additions for a selection. | -| `SelectionPoint` | Describes one line and optional side. | -| `SelectionDirection` | Describes backward, neutral, or forward selection direction. | -| `EditorActiveLineOptions` | Configures reveal behavior for an editor active line. | - -## `CodeView` types - -| Export | Purpose | -| ------------------------------ | -------------------------------------------------------- | -| `CodeViewFileItem` | Describes one file item in a virtualized list. | -| `CodeViewDiffItem` | Describes one diff item in a virtualized list. | -| `CodeViewItem` | Represents a file or diff list item. | -| `CodeViewCreateEditorOptions` | Adds an item ID to editor creation options. | -| `CodeViewScrollBehavior` | Selects instant, smooth, or automatic smooth scroll. | -| `CodeViewScrollTarget` | Represents any supported list scroll target. | -| `CodeViewPositionScrollTarget` | Scrolls to an absolute list position. | -| `CodeViewLineScrollTarget` | Scrolls to one item line. | -| `CodeViewRangeScrollTarget` | Scrolls to one item line range. | -| `CodeViewItemScrollTarget` | Scrolls to one item boundary. | -| `NumericScrollLineAnchor` | Describes a numeric position inside a line. | -| `CodeViewLayout` | Stores item offsets, heights, and total list height. | -| `PendingCodeViewLayoutReset` | Describes a deferred list layout reset. | -| `SmoothScrollSettings` | Configures duration and distance for smooth list scroll. | - -## Lines, hunks, and render state - -| Export | Purpose | -| ---------------------------- | --------------------------------------------------------------- | -| `HunkLineType` | Names context, expanded, addition, deletion, or metadata lines. | -| `HunkData` | Describes one hunk's render indexes and line ranges. | -| `HunkExpansionRegion` | Describes expanded context above and below a hunk. | -| `ExpansionDirections` | Selects up, down, or both expansion directions. | -| `DiffAcceptRejectHunkType` | Selects accept, reject, or both hunk controls. | -| `DiffAcceptRejectHunkConfig` | Configures hunk accept and reject behavior. | -| `GapSpan` | Describes an empty row span. | -| `AnnotationSpan` | Describes an annotation row span. | -| `LineSpans` | Represents a gap or annotation span. | -| `LineTypes` | Names rendered context and change line classes. | -| `LineInfo` | Describes a rendered line number, side, and type. | -| `CodeColumnType` | Selects unified, additions, or deletions columns. | -| `LineEventBaseProps` | Supplies a file line to an interaction callback. | -| `DiffLineEventBaseProps` | Supplies a diff line and side to an interaction callback. | -| `TokenEventBase` | Supplies a token and source event. | -| `DiffTokenEventBaseProps` | Adds diff side data to a token event. | -| `ObservedAnnotationNodes` | Stores DOM nodes for observed annotations. | -| `ObservedGridNodes` | Stores DOM nodes for observed grid columns. | -| `SharedRenderState` | Holds shared token transformer render state. | -| `StickySpecs` | Describes sticky header position and height. | - -## Render results and virtualization - -| Export | Purpose | -| --------------------------- | ------------------------------------------------------- | -| `RenderFileOptions` | Defines the resolved options for a highlighted file. | -| `RenderDiffOptions` | Defines the resolved options for a highlighted diff. | -| `ForceFilePlainTextOptions` | Selects a plain-text file range. | -| `ForceDiffPlainTextOptions` | Selects a plain-text diff range and hunk state. | -| `ThemedFileResult` | Holds the highlighted file syntax tree and line count. | -| `ThemedDiffResult` | Holds highlighted additions and deletions syntax trees. | -| `RenderDiffFilesResult` | Holds the resolved old and new file inputs. | -| `RenderFileResult` | Holds file output and the options that produced it. | -| `RenderDiffResult` | Holds diff output and the options that produced it. | -| `RenderedFileASTCache` | Stores one cached file syntax tree by theme. | -| `RenderedDiffASTCache` | Stores one cached diff syntax tree by theme. | -| `AppliedThemeStyleCache` | Stores applied light and dark theme CSS. | -| `RenderRange` | Describes a start row, row count, and buffer sizes. | -| `RenderWindow` | Describes first and last rows in a render window. | -| `VirtualWindowSpecs` | Describes viewport position, height, and row window. | -| `VirtualFileMetrics` | Describes estimated header and line heights. | - -## Component and editor contracts - -| Export | Purpose | -| ------------------------ | ----------------------------------------------------------- | -| `DiffsComponentOptions` | Defines shared options for a render component. | -| `DiffsBaseComponent` | Defines the common file and diff component methods. | -| `DiffsEditableComponent` | Adds editor attachment and document updates to a component. | -| `EditableInstance` | Selects an editable file or diff instance. | -| `DiffsEditor` | Defines the editor interface that render components use. | -| `DiffsTextDocument` | Defines the text document interface that components use. | -| `Position` | Identifies a zero-based line and character. | -| `Range` | Identifies start and end positions. | -| `TextEdit` | Replaces one range with new text. | -| `EditorSelection` | Adds direction to a range. | -| `EditorState` | Holds editor selections and view state. | - -## Shiki and diff types - -| Export | Purpose | -| -------------------------------- | ----------------------------------------------- | -| `BundledLanguage` | Names a language bundled by Shiki. | -| `CodeToHastOptions` | Configures Shiki code-to-HAST output. | -| `DecorationItem` | Describes a Shiki source decoration. | -| `LanguageRegistration` | Describes a Shiki language grammar. | -| `ShikiTransformer` | Defines a Shiki syntax tree transformer. | -| `ThemeRegistration` | Describes a raw Shiki theme. | -| `ThemeRegistrationResolved` | Describes a normalized Shiki theme. | -| `ThemedToken` | Describes one Shiki token with its theme style. | -| `CreatePatchOptionsNonabortable` | Configures the underlying patch algorithm. | diff --git a/skills/diffs/references/api-types.md b/skills/diffs/references/api-types.md new file mode 120000 index 000000000..776bfd788 --- /dev/null +++ b/skills/diffs/references/api-types.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-types.md \ No newline at end of file diff --git a/skills/diffs/references/api-worker.md b/skills/diffs/references/api-worker.md deleted file mode 100644 index cb204dac6..000000000 --- a/skills/diffs/references/api-worker.md +++ /dev/null @@ -1,91 +0,0 @@ -# Worker API - -This reference lists every export from `@pierre/diffs/worker`, every public -`WorkerPoolManager` member, and both worker script entries. - -## Runtime exports - -| Export | Kind | Purpose | -| -------------------------------- | -------- | ----------------------------------------------------- | -| `WorkerPoolManager` | Class | Runs file and diff highlighting across a worker pool. | -| `getOrCreateWorkerPoolSingleton` | Function | Gets or creates the module-wide worker pool. | -| `terminateWorkerPoolSingleton` | Function | Terminates and clears the module-wide worker pool. | - -## `WorkerPoolManager` members - -| Member | Purpose | -| -------------------------------------------------------------- | ------------------------------------------------- | -| `new WorkerPoolManager(options, renderOptions)` | Creates a worker pool. | -| `initialize(languages?)` | Starts workers and loads languages. | -| `isInitialized()` | Reports whether initialization finished. | -| `isWorkingPool()` | Reports whether workers can accept work. | -| `setRenderOptions(options)` | Updates theme and render settings in each worker. | -| `getFileRenderOptions()` | Gets active file render options. | -| `getDiffRenderOptions()` | Gets active diff render options. | -| `highlightFileAST(instance, file)` | Queues a highlighted file result for an instance. | -| `highlightDiffAST(instance, diff)` | Queues a highlighted diff result for an instance. | -| `primeFileHighlightCache(file)` | Preloads one highlighted file result. | -| `primeDiffHighlightCache(diff)` | Preloads one highlighted diff result. | -| `getFileResultCache(file)` | Gets one cached file result. | -| `getDiffResultCache(diff)` | Gets one cached diff result. | -| `getPlainFileAST(file, start, total, lines?)` | Gets a plain-text file result. | -| `getPlainDiffAST(diff, start, total, expansions?, threshold?)` | Gets a plain-text diff result. | -| `inspectCaches()` | Gets both result caches. | -| `evictFileFromCache(cacheKey)` | Removes one file cache entry. | -| `evictDiffFromCache(cacheKey)` | Removes one diff cache entry. | -| `subscribeToThemeChanges(instance)` | Subscribes a render instance to theme changes. | -| `unsubscribeToThemeChanges(instance)` | Removes a theme subscription. | -| `subscribeToStatChanges(callback)` | Subscribes to worker statistics. | -| `cleanUpTasks(instance)` | Removes queued and active tasks for an instance. | -| `getStats()` | Gets worker and cache statistics. | -| `terminate()` | Stops workers and clears pool resources. | - -## Configuration and state types - -| Export | Purpose | -| ----------------------------------- | ----------------------------------------------------------------- | -| `SetupWorkerPoolProps` | Combines pool and highlighter options for the singleton. | -| `WorkerPoolOptions` | Defines the worker factory, pool size, and cache size. | -| `WorkerInitializationRenderOptions` | Defines initial languages, theme, highlighter, and diff settings. | -| `WorkerRenderingOptions` | Defines the complete worker render settings. | -| `WorkerStats` | Describes pool state, work counts, subscribers, and cache sizes. | -| `WorkerRequestId` | Identifies one worker request. | -| `ResolvedLanguage` | Holds a resolved language registration. | -| `FileRendererInstance` | Defines callbacks for a file render consumer. | -| `DiffRendererInstance` | Defines callbacks for a diff render consumer. | - -## Request and response types - -| Export | Purpose | -| ------------------------------- | ------------------------------------------------------- | -| `WorkerRequest` | Represents any request sent to a worker. | -| `InitializeWorkerRequest` | Starts a worker with themes, languages, and options. | -| `SetRenderOptionsWorkerRequest` | Updates render options and themes. | -| `RenderFileRequest` | Requests one file render. | -| `RenderDiffRequest` | Requests one diff render. | -| `SubmitRequest` | Represents a file or diff request before ID assignment. | -| `WorkerResponse` | Represents any worker response. | -| `InitializeSuccessResponse` | Confirms worker initialization. | -| `RegisterThemeSuccessResponse` | Confirms a render-option and theme update. | -| `RenderSuccessResponse` | Represents a successful file or diff render. | -| `RenderFileSuccessResponse` | Returns one file render result. | -| `RenderDiffSuccessResponse` | Returns one diff render result. | -| `RenderErrorResponse` | Returns a serialized worker error. | - -## Task types - -| Export | Purpose | -| ---------------------------- | ------------------------------------------------- | -| `AllWorkerTasks` | Represents any manager task. | -| `InitializeWorkerTask` | Tracks one initialization request. | -| `SetRenderOptionsWorkerTask` | Tracks one render-option update. | -| `RenderFileTask` | Tracks one file render request and its consumers. | -| `RenderDiffTask` | Tracks one diff render request and its consumers. | -| `RenderTaskCallbacks` | Resolves or rejects one render task consumer. | - -## Worker script entries - -| Import | Purpose | -| ----------------------------------------- | ---------------------------------------------------------- | -| `@pierre/diffs/worker/worker.js` | Supplies the module worker that uses package dependencies. | -| `@pierre/diffs/worker/worker-portable.js` | Supplies a bundled module worker. | diff --git a/skills/diffs/references/api-worker.md b/skills/diffs/references/api-worker.md new file mode 120000 index 000000000..d77eb0813 --- /dev/null +++ b/skills/diffs/references/api-worker.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/api-worker.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-annotations.md b/skills/diffs/references/recipe-annotations.md deleted file mode 100644 index 7707e93f3..000000000 --- a/skills/diffs/references/recipe-annotations.md +++ /dev/null @@ -1,32 +0,0 @@ -# Recipe: add line annotations and selection - -Pass annotation data and a renderer to the surface: - -```tsx -import type { DiffLineAnnotation } from '@pierre/diffs/react'; -import { MultiFileDiff } from '@pierre/diffs/react'; - -const annotations: DiffLineAnnotation<{ message: string }>[] = [ - { - side: 'additions', - lineNumber: 8, - metadata: { message: 'Review this line.' }, - }, -]; - -

{annotation.metadata.message}

} - options={{ - enableLineSelection: true, - onLineSelectionEnd(range) { - saveSelection(range); - }, - }} -/>; -``` - -Use `LineAnnotation` for a single file. Use `DiffLineAnnotation` for a diff. -Control the active selection with the `selectedLines` prop. diff --git a/skills/diffs/references/recipe-annotations.md b/skills/diffs/references/recipe-annotations.md new file mode 120000 index 000000000..59fe7fd6c --- /dev/null +++ b/skills/diffs/references/recipe-annotations.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-annotations.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-code-view.md b/skills/diffs/references/recipe-code-view.md deleted file mode 100644 index 36d818c0a..000000000 --- a/skills/diffs/references/recipe-code-view.md +++ /dev/null @@ -1,213 +0,0 @@ -# Recipe: build a `CodeView` - -Use `CodeView` when one scroll region contains many files, diffs, or both. It -manages item virtualization, sticky headers, list-wide selection, and item or -line scroll targets. - -## Contents - -- [Select item ownership](#select-item-ownership) -- [Define items](#define-items) -- [Use controlled React state](#use-controlled-react-state) -- [Use imperative ownership](#use-imperative-ownership) -- [Enable item edit mode](#enable-item-edit-mode) - -## Select item ownership - -| Host and data flow | Input | Update API | -| ------------------------------------------- | ----------------- | ------------------------------------ | -| React owns the complete list | `items` | Publish a new `items` array. | -| React hosts a large or append-only list | `initialItems` | Use the `CodeViewHandle` methods. | -| Vanilla JavaScript owns the viewer instance | `setItems(items)` | Use the `CodeView` instance methods. | - -Keep one ownership mode for the life of a mounted React viewer. Use controlled -state when item data already belongs to React. Use imperative ownership for a -large or streamed list. - -## Define items - -Give each item a stable and unique `id`. Use a `file` item for `FileContents`. -Use a `diff` item for `FileDiffMetadata`. - -Increment `version` when an existing item changes its contents, annotations, -collapsed state, or edit state. `CodeView` uses the ID and version to select the -item that it must update. - -## Use controlled React state - -```tsx -import { - parseDiffFromFile, - type CodeViewItem, - type CodeViewLineSelection, -} from '@pierre/diffs'; -import { CodeView, type CodeViewHandle } from '@pierre/diffs/react'; -import { useRef, useState } from 'react'; - -const oldFile = { - name: 'src/value.ts', - contents: 'export const value = 1;', -}; -const newFile = { - name: 'src/value.ts', - contents: 'export const value = 2;', -}; -const codeViewStyle = { height: 600, overflow: 'auto' } as const; -const codeViewOptions = { - theme: { light: 'pierre-light', dark: 'pierre-dark' }, - stickyHeaders: true, - enableLineSelection: true, - layout: { paddingTop: 16, paddingBottom: 16, gap: 12 }, -} as const; - -export function ReviewSurface() { - const viewerRef = useRef | null>(null); - const [selection, setSelection] = useState( - null - ); - const [items, setItems] = useState(() => [ - { - id: 'diff:src/value.ts', - type: 'diff', - fileDiff: parseDiffFromFile(oldFile, newFile), - version: 0, - }, - { - id: 'file:README.md', - type: 'file', - file: { name: 'README.md', contents: '# Review notes' }, - version: 0, - }, - ]); - - function toggleDiff() { - setItems((current) => - current.map((item) => - item.id === 'diff:src/value.ts' - ? { - ...item, - collapsed: !item.collapsed, - version: (item.version ?? 0) + 1, - } - : item - ) - ); - } - - return ( - <> - - - - - ); -} -``` - -## Use imperative ownership - -In React, pass `initialItems` and keep `items` unset. Use the component ref to -call `addItems`, `getItem`, `updateItem`, `updateItemId`, or `scrollTo`. - -In vanilla JavaScript, configure and populate the instance directly: - -```ts -import { CodeView, parseDiffFromFile } from '@pierre/diffs'; - -const root = document.querySelector('#review'); -if (root == null) throw new Error('Missing review host'); - -const oldFile = { - name: 'src/value.ts', - contents: 'export const value = 1;', -}; -const newFile = { - name: 'src/value.ts', - contents: 'export const value = 2;', -}; - -const viewer = new CodeView({ - theme: { light: 'pierre-light', dark: 'pierre-dark' }, - stickyHeaders: true, - enableLineSelection: true, - onSelectedLinesChange(selection) { - console.log('selected lines', selection); - }, -}); - -root.style.height = '600px'; -root.style.overflow = 'auto'; -viewer.setup(root); -viewer.setItems([ - { - id: 'diff:src/value.ts', - type: 'diff', - fileDiff: parseDiffFromFile(oldFile, newFile), - version: 0, - }, -]); - -viewer.addItems([ - { - id: 'file:README.md', - type: 'file', - file: { name: 'README.md', contents: '# Review notes' }, - version: 0, - }, -]); -viewer.scrollTo({ - type: 'item', - id: 'diff:src/value.ts', - align: 'start', -}); - -const item = viewer.getItem('diff:src/value.ts'); -if (item != null) { - viewer.updateItem({ - ...item, - collapsed: true, - version: (item.version ?? 0) + 1, - }); -} - -export function removeReviewSurface() { - viewer.cleanUp(); -} -``` - -## Enable item edit mode - -In React, wrap `CodeView` in `EditProvider`. In vanilla JavaScript, pass -`createEditor` in `CodeViewOptions`. Set `edit: true` on each editable item and -increment its version. - -Use `onItemEditChange` for live contents and annotation changes. Use -`onItemEditComplete` to write the final contents into the item, disable edit -mode, assign a fresh `cacheKey`, and increment `version`. Use `getEditor(id)` -for editor commands such as undo, redo, markers, or programmatic edits. - -Read [Edit with React](recipe-edit-react.md) or -[Edit with vanilla JavaScript](recipe-edit-vanilla.md) for the complete editor -lifecycle. diff --git a/skills/diffs/references/recipe-code-view.md b/skills/diffs/references/recipe-code-view.md new file mode 120000 index 000000000..cdfa35a1f --- /dev/null +++ b/skills/diffs/references/recipe-code-view.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-code-view.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-custom-highlighting.md b/skills/diffs/references/recipe-custom-highlighting.md deleted file mode 100644 index 22efc967f..000000000 --- a/skills/diffs/references/recipe-custom-highlighting.md +++ /dev/null @@ -1,19 +0,0 @@ -# Recipe: register custom highlighting - -Register a language or theme before the first surface uses it: - -```ts -import { registerCustomLanguage, registerCustomTheme } from '@pierre/diffs'; - -registerCustomLanguage( - 'my-language', - () => import('./my-language.tmLanguage.json'), - ['myext'] -); - -registerCustomTheme('my-theme', () => import('./my-theme.json')); -``` - -Set `file.lang` to the custom language name. Set `options.theme` to the custom -theme name. Use `registerCustomCSSVariableTheme` when CSS variables supply the -theme colors. diff --git a/skills/diffs/references/recipe-custom-highlighting.md b/skills/diffs/references/recipe-custom-highlighting.md new file mode 120000 index 000000000..94553cb2d --- /dev/null +++ b/skills/diffs/references/recipe-custom-highlighting.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-custom-highlighting.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-edit-react.md b/skills/diffs/references/recipe-edit-react.md deleted file mode 100644 index c51e57dab..000000000 --- a/skills/diffs/references/recipe-edit-react.md +++ /dev/null @@ -1,130 +0,0 @@ -# Recipe: edit with React - -Mount one stable `EditProvider` above the editable surfaces. The provider -supplies an editor factory. Each active surface or `CodeView` item owns a -separate editor instance, cached by `editorOptions` object identity — an edit -session restarting with the same options object reuses its editor, and -simultaneously editable surfaces need distinct options objects. - -To share one editor across surfaces, pass the same `editorOptions` object to -each of them: the cache then hands every surface the same instance. Instance -state — such as `persistState` records and their default `inMemory` storage — -survives surface remounts, so per-file selections and scroll positions restore -across file switches. Share an options object only where one surface is editable -at a time; simultaneously editable surfaces need distinct options objects. - -## Contents - -- [Edit a standalone file or diff](#edit-a-standalone-file-or-diff) -- [Keep annotations synchronized](#keep-annotations-synchronized) -- [Edit CodeView items](#edit-codeview-items) - -## Edit a standalone file or diff - -Set `edit` on `File`, `FileDiff`, `MultiFileDiff`, or `PatchDiff`. Pass editor -behavior through `editOptions`. - -```tsx -import type { FileContents, FileDiffOptions } from '@pierre/diffs'; -import { Editor, type EditorOptions } from '@pierre/diffs/edit'; -import { EditProvider, MultiFileDiff, Virtualizer } from '@pierre/diffs/react'; -import { useMemo, useRef, useState } from 'react'; - -const oldFile: FileContents = { - name: 'src/value.ts', - contents: 'export const value = 1;', -}; -const initialNewFile: FileContents = { - name: 'src/value.ts', - contents: 'export const value = 2;', -}; -const diffOptions: FileDiffOptions = { - theme: { light: 'pierre-light', dark: 'pierre-dark' }, - diffStyle: 'split', -}; - -function createEditor(options: EditorOptions) { - return new Editor(options); -} - -export function EditableDiff() { - const [edit, setEdit] = useState(false); - const [newFile, setNewFile] = useState(initialNewFile); - const draftRef = useRef(newFile); - const editorRef = useRef | null>(null); - const editOptions = useMemo>( - () => ({ - onAttach(editor) { - editorRef.current = editor; - }, - onChange(file) { - draftRef.current = file; - saveDraft(file); - }, - }), - [] - ); - - function toggleEdit() { - if (edit) setNewFile(draftRef.current); - setEdit((value) => !value); - } - - return ( - - - - - - - - ); -} -``` - -Mount the provider near the application root when many surfaces use edit mode. -Keep `createEditor` and `editOptions` stable. Use `onAttach` when controls need -`undo`, `redo`, `applyEdits`, selections, markers, focus, or other editor APIs. - -## Keep annotations synchronized - -The `onChange` callback can supply the complete current annotation collection. -Replace the application collection when the callback supplies a different array. -Use `isFileAnnotationCollection` or `isDiffAnnotationCollection` to narrow its -type. - -Publish a changed React annotation array inside `flushSync`. This keeps its -coordinates aligned with the edited contents before paint. Store annotation UI -state by a stable metadata ID instead of a line number. - -## Edit `CodeView` items - -Wrap `CodeView` in the same `EditProvider`. Set `edit: true` on an item and -increment its `version`. Pass shared creation options through the `CodeView` -`editOptions` prop. - -Use `onItemEditChange` for live contents and annotation changes. Use -`onItemEditComplete` to commit the final `file` or rebuild the `fileDiff`. In -the same item update, set `edit: false`, assign a fresh `cacheKey`, and -increment `version`. - -Use the `CodeViewHandle.getEditor(id)` method for imperative editor commands. -The item editor keeps its document and history when virtualization removes the -item from the rendered window. - -When a worker pool highlights an editable surface, set -`useTokenTransformer: true` in the worker `highlighterOptions`. diff --git a/skills/diffs/references/recipe-edit-react.md b/skills/diffs/references/recipe-edit-react.md new file mode 120000 index 000000000..1f85b095b --- /dev/null +++ b/skills/diffs/references/recipe-edit-react.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-edit-react.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-edit-vanilla.md b/skills/diffs/references/recipe-edit-vanilla.md deleted file mode 100644 index 0876349f6..000000000 --- a/skills/diffs/references/recipe-edit-vanilla.md +++ /dev/null @@ -1,163 +0,0 @@ -# Recipe: edit with vanilla JavaScript - -Render a standalone surface first. Then attach one `Editor` to it. Use one -editor for each surface that can be edited at the same time. - -## Contents - -- [Edit a standalone diff](#edit-a-standalone-diff) -- [Edit CodeView items](#edit-codeview-items) - -## Edit a standalone diff - -```ts -import { - FileDiff, - isDiffAnnotationCollection, - type DiffLineAnnotation, - type FileContents, -} from '@pierre/diffs'; -import { Editor } from '@pierre/diffs/edit'; - -interface ThreadMetadata { - id: string; -} - -const hostElement = document.querySelector('#diff'); -if (hostElement == null) throw new Error('Missing diff host'); -const host: HTMLElement = hostElement; - -const oldFile: FileContents = { - name: 'src/value.ts', - contents: 'export const value = 1;', -}; -let newFile: FileContents = { - name: 'src/value.ts', - contents: 'export const value = 2;', -}; -let annotations: DiffLineAnnotation[] = [ - { - side: 'additions', - lineNumber: 1, - metadata: { id: 'value-review' }, - }, -]; - -const view = new FileDiff({ - theme: { light: 'pierre-light', dark: 'pierre-dark' }, - renderAnnotation(annotation) { - const element = document.createElement('p'); - element.textContent = 'Thread ' + annotation.metadata.id; - return element; - }, -}); - -function render() { - view.render({ - fileContainer: host, - oldFile, - newFile, - lineAnnotations: annotations, - }); -} - -render(); - -const editor = new Editor({ - onChange(file, nextAnnotations) { - newFile = { ...newFile, contents: file.contents }; - saveDraft(newFile); - - if ( - nextAnnotations != null && - isDiffAnnotationCollection(nextAnnotations) && - nextAnnotations !== annotations - ) { - annotations = nextAnnotations; - queueMicrotask(render); - } - }, -}); - -const detach = editor.edit(view); - -export function stopEditing() { - detach(); -} - -export function removeSurface() { - editor.cleanUp(); - view.cleanUp(); -} -``` - -The annotation array from `onChange` is the complete current collection. Save it -before a later render can apply old coordinates. Use stable metadata IDs for -application state that belongs to an annotation. - -Use `VirtualizedFile` or `VirtualizedFileDiff` with a `Virtualizer` for a large -standalone surface. Load `@pierre/diffs/edit` with `import()` when edit mode is -optional and the initial bundle must omit the editor. - -## Edit `CodeView` items - -Pass a factory through `CodeViewOptions.createEditor`: - -```ts -import { CodeView } from '@pierre/diffs'; -import { Editor } from '@pierre/diffs/edit'; - -export function mountEditableCodeView(root: HTMLElement) { - const viewer = new CodeView({ - createEditor(options) { - return new Editor(options); - }, - onItemEditChange(item, file, nextAnnotations) { - saveItemDraft(item.id, file, nextAnnotations); - }, - onItemEditComplete(item, file) { - const current = viewer.getItem(item.id); - if (current?.type !== 'file') return; - - const version = (current.version ?? 0) + 1; - viewer.updateItem({ - ...current, - edit: false, - version, - file: { - ...file, - cacheKey: current.id + ':v' + version, - }, - }); - }, - }); - - viewer.setup(root); - viewer.setItems([ - { - id: 'file:src/value.ts', - type: 'file', - file: { - name: 'src/value.ts', - contents: 'export const value = 1;', - }, - edit: true, - version: 0, - }, - ]); - - return viewer; -} -``` - -Set `edit: true` on an item and increment its `version`. In -`onItemEditComplete`, write the final contents into that item, set -`edit: false`, assign a fresh `cacheKey`, and increment `version` again. -`CodeView` creates and removes the item editors. - -Call `viewer.getEditor(id)` for `undo`, `redo`, `applyEdits`, selections, -markers, focus, or other editor commands. Call `viewer.cleanUp()` when the host -removes the viewer. - -When a worker pool highlights an editable surface, set -`useTokenTransformer: true` in the worker `highlighterOptions`. diff --git a/skills/diffs/references/recipe-edit-vanilla.md b/skills/diffs/references/recipe-edit-vanilla.md new file mode 120000 index 000000000..a3e25a558 --- /dev/null +++ b/skills/diffs/references/recipe-edit-vanilla.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-edit-vanilla.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-react.md b/skills/diffs/references/recipe-react.md deleted file mode 100644 index f1048230f..000000000 --- a/skills/diffs/references/recipe-react.md +++ /dev/null @@ -1,37 +0,0 @@ -# Recipe: render with React - -## Select a surface - -| Input or layout | Component | -| ------------------------------------------- | ---------------- | -| One `FileContents` object | `File` | -| Old and new `FileContents` objects | `MultiFileDiff` | -| Existing `FileDiffMetadata` | `FileDiff` | -| One unified patch string | `PatchDiff` | -| One file with merge conflicts | `UnresolvedFile` | -| One scroll region with many files and diffs | `CodeView` | - -Use `MultiFileDiff` when the app has old and new file contents: - -```tsx -import { MultiFileDiff } from '@pierre/diffs/react'; - -; -``` - -Pass source data, annotations, and slot renderers as component props. Pass -display, theme, interaction, and highlighting settings through `options`. - -Keep file objects and option objects stable when their values do not change. -Wrap a large standalone surface in `Virtualizer`. Use `CodeView` when one scroll -region contains a list of files or diffs. - -Use the matching preload function from `@pierre/diffs/ssr` when the server must -render the initial highlighted markup. diff --git a/skills/diffs/references/recipe-react.md b/skills/diffs/references/recipe-react.md new file mode 120000 index 000000000..4e86bf8ce --- /dev/null +++ b/skills/diffs/references/recipe-react.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-react.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-ssr.md b/skills/diffs/references/recipe-ssr.md deleted file mode 100644 index 6899453e3..000000000 --- a/skills/diffs/references/recipe-ssr.md +++ /dev/null @@ -1,20 +0,0 @@ -# Recipe: preload a diff on the server - -Create props on the server and pass the result to the matching React component: - -```tsx -import { preloadMultiFileDiff } from '@pierre/diffs/ssr'; -import { MultiFileDiff } from '@pierre/diffs/react'; - -const preloaded = await preloadMultiFileDiff({ - oldFile: { name: 'src/value.ts', contents: oldSource }, - newFile: { name: 'src/value.ts', contents: newSource }, - options: { theme: 'pierre-dark', diffStyle: 'split' }, -}); - -; -``` - -Select the preload function that matches the client component. Use -`preloadDiffHTML` or `preloadUnresolvedFileHTML` when the host needs an HTML -string only. diff --git a/skills/diffs/references/recipe-ssr.md b/skills/diffs/references/recipe-ssr.md new file mode 120000 index 000000000..0694b7195 --- /dev/null +++ b/skills/diffs/references/recipe-ssr.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-ssr.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-vanilla.md b/skills/diffs/references/recipe-vanilla.md deleted file mode 100644 index ebb8841b1..000000000 --- a/skills/diffs/references/recipe-vanilla.md +++ /dev/null @@ -1,41 +0,0 @@ -# Recipe: render with vanilla JavaScript - -## Select a surface - -| Input or layout | Class | -| ------------------------------------------- | --------------------- | -| One `FileContents` object | `File` | -| Existing or parsed `FileDiffMetadata` | `FileDiff` | -| One file with merge conflicts | `UnresolvedFile` | -| One large file | `VirtualizedFile` | -| One large diff | `VirtualizedFileDiff` | -| One scroll region with many files and diffs | `CodeView` | - -Parse the files, create the view, and render it into a host: - -```ts -import { FileDiff, parseDiffFromFile } from '@pierre/diffs'; - -const host = document.querySelector('#diff'); -if (host == null) throw new Error('Missing diff host'); - -const fileDiff = parseDiffFromFile( - { name: 'src/value.ts', contents: oldSource }, - { name: 'src/value.ts', contents: newSource } -); - -const view = new FileDiff({ - diffStyle: 'split', - theme: 'pierre-dark', -}); - -view.render({ fileContainer: host, fileDiff }); -``` - -Keep the class instance while the host remains mounted. Call `render` again when -the source data changes. Call `setOptions`, `setThemeType`, -`setLineAnnotations`, or `setSelectedLines` for targeted updates. - -Use a `Virtualizer` with `VirtualizedFile` or `VirtualizedFileDiff` for one -large surface. Use `CodeView` for a list that shares one scroll region. Call -`cleanUp()` when the host removes the surface. diff --git a/skills/diffs/references/recipe-vanilla.md b/skills/diffs/references/recipe-vanilla.md new file mode 120000 index 000000000..ac5223ff5 --- /dev/null +++ b/skills/diffs/references/recipe-vanilla.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-vanilla.md \ No newline at end of file diff --git a/skills/diffs/references/recipe-workers.md b/skills/diffs/references/recipe-workers.md deleted file mode 100644 index fbe7cc6f8..000000000 --- a/skills/diffs/references/recipe-workers.md +++ /dev/null @@ -1,28 +0,0 @@ -# Recipe: use a worker pool - -Wrap React diff surfaces in one provider: - -```tsx -import { WorkerPoolContextProvider } from '@pierre/diffs/react'; - - - new Worker(new URL('@pierre/diffs/worker/worker.js', import.meta.url), { - type: 'module', - }), - }} - highlighterOptions={{ - langs: ['typescript', 'tsx'], - theme: { light: 'pierre-light', dark: 'pierre-dark' }, - }} -> - {children} -; -``` - -For vanilla JavaScript, call `getOrCreateWorkerPoolSingleton` and pass the -result as the second constructor argument to a render class. Call -`terminateWorkerPoolSingleton()` when the application tears down the shared -pool. diff --git a/skills/diffs/references/recipe-workers.md b/skills/diffs/references/recipe-workers.md new file mode 120000 index 000000000..f4d59e310 --- /dev/null +++ b/skills/diffs/references/recipe-workers.md @@ -0,0 +1 @@ +../../../packages/diffs/skills/diffs/references/recipe-workers.md \ No newline at end of file diff --git a/skills/trees/SKILL.md b/skills/trees/SKILL.md deleted file mode 100644 index d3cc23fb7..000000000 --- a/skills/trees/SKILL.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: trees -description: - Use when an app uses @pierre/trees to render or control a file tree, including - React, vanilla JavaScript, SSR, web components, selection, search, rename, - drag and drop, icons, git status, and themes. ---- - -# `@pierre/trees` - -Use `@pierre/trees` for an interactive file tree. Public state and callbacks use -path strings. - -## Install - -```bash -pnpm add @pierre/trees -``` - -Install `react` and `react-dom` when the app uses the React entry. - -## Select an API reference - -| Entry | Reference | -| ------------------------------ | ------------------------------------------------------ | -| `@pierre/trees` | [Core API](references/api-core.md) | -| `@pierre/trees/react` | [React API](references/api-react.md) | -| `@pierre/trees/ssr` | [SSR API](references/api-ssr.md) | -| `@pierre/trees/web-components` | [Web components API](references/api-web-components.md) | - -## Select a recipe - -| Task | Recipe | -| ------------------------------------------------------- | ------------------------------------------------------ | -| Render and update a tree in React | [Use React](references/recipe-react.md) | -| Render and update a tree without React | [Use vanilla JavaScript](references/recipe-vanilla.md) | -| Preload a tree on the server | [Use SSR](references/recipe-ssr.md) | -| Apply a resolved Shiki or VS Code theme | [Apply a theme](references/recipe-theme.md) | -| Configure search, rename, drag and drop, and git status | [Add interactions](references/recipe-interactions.md) | diff --git a/skills/trees/SKILL.md b/skills/trees/SKILL.md new file mode 120000 index 000000000..77d1b4809 --- /dev/null +++ b/skills/trees/SKILL.md @@ -0,0 +1 @@ +../../packages/trees/skills/trees/SKILL.md \ No newline at end of file diff --git a/skills/trees/references/api-core.md b/skills/trees/references/api-core.md deleted file mode 100644 index 22727767e..000000000 --- a/skills/trees/references/api-core.md +++ /dev/null @@ -1,173 +0,0 @@ -# Core API - -This reference lists every export from `@pierre/trees` and every public -`FileTree` member. - -## Contents - -- [Runtime values](#runtime-values) -- [`FileTree` members](#filetree-members) -- [Configuration and state types](#configuration-and-state-types) -- [Mutation types](#mutation-types) -- [Interaction types](#interaction-types) -- [Presentation types](#presentation-types) -- [Constants](#constants) - -## Runtime values - -| Export | Kind | Purpose | -| ------------------------------- | -------- | ----------------------------------------------------------------- | -| `FileTree` | Class | Owns the tree model, renders it, and exposes path-based controls. | -| `prepareFileTreeInput` | Function | Prepares and optionally sorts a path list for reuse. | -| `preparePresortedFileTreeInput` | Function | Prepares a path list that already has final order. | -| `preloadFileTree` | Function | Creates server-rendered tree markup and hydration data. | -| `serializeFileTreeSsrPayload` | Function | Joins an SSR payload into one host markup string. | -| `themeToTreeStyles` | Function | Maps a resolved theme to tree host CSS properties. | -| `getBuiltInSpriteSheet` | Function | Gets the SVG sprite for a built-in icon set. | -| `createFileTreeIconResolver` | Function | Creates an icon resolver from an icon configuration. | - -## `FileTree` members - -| Member | Purpose | -| -------------------------------- | ----------------------------------------------------------- | -| `new FileTree(options)` | Creates a model from paths or prepared input. | -| `FileTree.LoadedCustomComponent` | Reports whether the file-tree custom element module loaded. | -| `render(props)` | Mounts the tree into a wrapper or host element. | -| `hydrate(props)` | Attaches the model to preloaded host markup. | -| `unmount()` | Removes the mounted view and keeps the model. | -| `cleanUp()` | Removes the view and destroys model resources. | -| `getFileTreeContainer()` | Gets the mounted host element. | -| `getItem(path)` | Gets a path handle or `null`. | -| `getFocusedItem()` | Gets the focused item handle or `null`. | -| `getFocusedPath()` | Gets the focused path or `null`. | -| `getSelectedPaths()` | Gets the selected paths. | -| `getComposition()` | Gets the current header and context-menu configuration. | -| `getItemHeight()` | Gets the resolved row height. | -| `getDensityFactor()` | Gets the resolved density factor. | -| `subscribe(listener)` | Subscribes to model changes. | -| `focusPath(path)` | Focuses a path. | -| `focusNearestPath(path)` | Focuses and returns the nearest available path. | -| `scrollToPath(path, options?)` | Scrolls a path into view. | -| `add(path)` | Adds one path. | -| `remove(path, options?)` | Removes one path. | -| `move(from, to, options?)` | Moves one path. | -| `batch(operations)` | Applies several path mutations together. | -| `resetPaths(paths, options?)` | Replaces the full path set. | -| `onMutation(type, handler)` | Subscribes to mutation events. | -| `setSearch(value)` | Sets or clears the search query. | -| `openSearch(initialValue?)` | Opens the search session. | -| `closeSearch()` | Closes the search session. | -| `isSearchOpen()` | Tests whether search is open. | -| `getSearchValue()` | Gets the search query. | -| `getSearchMatchingPaths()` | Gets paths that match the query. | -| `focusNextSearchMatch()` | Focuses the next search match. | -| `focusPreviousSearchMatch()` | Focuses the previous search match. | -| `startRenaming(path?, options?)` | Starts inline rename and reports whether it started. | -| `setGitStatus(status?)` | Replaces all git status entries. | -| `applyGitStatusPatch(patch)` | Applies a partial git status update. | -| `setIcons(icons?)` | Replaces the icon configuration. | -| `setComposition(composition?)` | Replaces header and context-menu configuration. | - -## Configuration and state types - -| Export | Purpose | -| -------------------------- | --------------------------------------------------------------- | -| `FileTreeOptions` | Defines input, behavior, rendering, and presentation options. | -| `FileTreePreparedInput` | Holds a reusable prepared path list. | -| `FileTreeInitialExpansion` | Selects closed, open, or depth-based initial expansion. | -| `FileTreeSortComparator` | Compares two path entries. | -| `FileTreeSortEntry` | Describes one path for a sort comparator. | -| `FileTreeRenderOptions` | Configures row height, row count, overscan, and sticky folders. | -| `FileTreeRenderProps` | Selects the wrapper or existing host for `render`. | -| `FileTreeHydrationProps` | Selects the host for `hydrate`. | -| `FileTreeVisibleRow` | Describes one visible tree row. | -| `FileTreeItemHandle` | Represents a file or directory item. | -| `FileTreeFileHandle` | Controls one file item. | -| `FileTreeDirectoryHandle` | Controls one directory item and its expansion. | -| `FileTreeListener` | Defines a model subscription callback. | -| `FileTreeSsrPayload` | Holds the host and shadow markup for server output. | - -## Mutation types - -| Export | Purpose | -| ----------------------------------- | -------------------------------------------------------------- | -| `FileTreeMutationHandle` | Defines the public path mutation methods. | -| `FileTreeBatchOperation` | Describes one add, remove, or move in a batch. | -| `FileTreeCollisionStrategy` | Selects error, replace, or skip behavior for a move collision. | -| `FileTreeMoveOptions` | Configures move collision behavior. | -| `FileTreeRemoveOptions` | Configures recursive removal. | -| `FileTreeResetOptions` | Configures a path reset and optional prepared input. | -| `FileTreeResetPreparedOptions` | Configures a reset that uses prepared input. | -| `FileTreeMutationEvent` | Represents any mutation event. | -| `FileTreeMutationSemanticEvent` | Represents an add, remove, move, or reset event. | -| `FileTreeMutationEventType` | Names a mutation operation. | -| `FileTreeMutationEventForType` | Selects the event shape for an operation name. | -| `FileTreeMutationEventInvalidation` | Describes the state invalidation from a mutation. | -| `FileTreeAddEvent` | Describes one add result. | -| `FileTreeRemoveEvent` | Describes one remove result. | -| `FileTreeMoveEvent` | Describes one move result. | -| `FileTreeResetEvent` | Describes one reset result. | -| `FileTreeBatchEvent` | Describes one batch result. | - -## Interaction types - -| Export | Purpose | -| --------------------------------- | -------------------------------------------------- | -| `FileTreeSelectionChangeListener` | Receives the selected path list. | -| `FileTreeSearchChangeListener` | Receives the current search query. | -| `FileTreeSearchSessionHandle` | Defines search session methods. | -| `FileTreeSearchMode` | Selects how nonmatching rows appear. | -| `FileTreeSearchBlurBehavior` | Selects search behavior after focus leaves. | -| `FileTreeScrollOffset` | Selects top, center, or nearest scroll alignment. | -| `FileTreeScrollToPathOptions` | Configures focus and alignment for `scrollToPath`. | -| `FileTreeDragAndDropConfig` | Configures drag rules and completion callbacks. | -| `FileTreeDropTarget` | Describes the current drop target. | -| `FileTreeDropContext` | Describes dragged paths and their target. | -| `FileTreeDropResult` | Describes the completed move or batch operation. | -| `FileTreeRenamingConfig` | Configures rename rules and callbacks. | -| `FileTreeRenamingItem` | Describes the item offered to a rename rule. | -| `FileTreeRenameEvent` | Describes a completed rename. | - -## Presentation types - -| Export | Purpose | -| ---------------------------------- | ----------------------------------------------------------- | -| `FileTreeCompositionOptions` | Configures header and context-menu composition. | -| `FileTreeHeaderCompositionOptions` | Supplies header HTML or a header renderer. | -| `ContextMenuItem` | Describes the file or directory for a context menu. | -| `ContextMenuOpenContext` | Supplies menu position, close, and focus controls. | -| `ContextMenuAnchorRect` | Describes the menu anchor rectangle. | -| `ContextMenuTriggerMode` | Selects right-click, button, or both triggers. | -| `ContextMenuButtonVisibility` | Selects when the row menu button appears. | -| `FileTreeRowDecoration` | Describes text or icon content in the decoration lane. | -| `FileTreeRowDecorationContext` | Supplies the item and visible row to a decoration renderer. | -| `FileTreeRowDecorationRenderer` | Produces one row decoration. | -| `GitStatus` | Names a supported git status. | -| `GitStatusEntry` | Assigns a git status to one path. | -| `FileTreeGitStatusPatch` | Adds, changes, or removes git status entries. | -| `FileTreeBuiltInIconSet` | Names a built-in icon set. | -| `FileTreeIconConfig` | Configures built-in and custom icon rules. | -| `FileTreeIcons` | Accepts an icon set name or icon configuration. | -| `RemappedIcon` | Names or defines a replacement SVG symbol. | -| `FileTreeDensity` | Accepts a density keyword or numeric factor. | -| `FileTreeDensityKeyword` | Names compact, default, or relaxed density. | -| `FileTreeDensityPreset` | Holds a density factor and row height. | -| `TreeThemeInput` | Defines the resolved theme accepted by `themeToTreeStyles`. | -| `TreeThemeStyles` | Maps tree CSS property names to values. | - -## Constants - -| Export | Purpose | -| ---------------------------------------------- | --------------------------------------------------------------- | -| `FILE_TREE_TAG_NAME` | Provides the `file-tree-container` element name. | -| `FILE_TREE_STYLE_ATTRIBUTE` | Provides the core style marker attribute. | -| `FILE_TREE_UNSAFE_CSS_ATTRIBUTE` | Provides the custom style marker attribute. | -| `FILE_TREE_SCROLLBAR_MEASURE_ATTRIBUTE` | Provides the scrollbar measurement attribute. | -| `FILE_TREE_SCROLLBAR_GUTTER_STYLE_ATTRIBUTE` | Provides the measured scrollbar style attribute. | -| `FILE_TREE_SCROLLBAR_GUTTER_MEASURED_PROPERTY` | Provides the measured scrollbar CSS property. | -| `FILE_TREE_DEFAULT_ITEM_HEIGHT` | Provides the default row height. | -| `FILE_TREE_DENSITY_PRESETS` | Maps each density keyword to its preset. | -| `FLATTENED_PREFIX` | Provides the identifier prefix for a flattened directory chain. | -| `HEADER_SLOT_NAME` | Provides the header slot name. | -| `CONTEXT_MENU_SLOT_NAME` | Provides the context-menu slot name. | -| `CONTEXT_MENU_TRIGGER_TYPE` | Provides the context-menu trigger type. | diff --git a/skills/trees/references/api-core.md b/skills/trees/references/api-core.md new file mode 120000 index 000000000..2b6380ad2 --- /dev/null +++ b/skills/trees/references/api-core.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/api-core.md \ No newline at end of file diff --git a/skills/trees/references/api-react.md b/skills/trees/references/api-react.md deleted file mode 100644 index 39ba73da3..000000000 --- a/skills/trees/references/api-react.md +++ /dev/null @@ -1,27 +0,0 @@ -# React API - -This reference lists every export from `@pierre/trees/react`. - -| Export | Kind | Purpose | -| -------------------------- | --------- | ---------------------------------------------------------------------- | -| `FileTree` | Component | Mounts a `FileTree` model in a React host element. | -| `FileTreeProps` | Type | Defines the model, header, context menu, preload data, and host props. | -| `FileTreePreloadedData` | Type | Selects the `id` and `shadowHtml` fields for hydration. | -| `useFileTree` | Hook | Creates one stable `FileTree` model. | -| `UseFileTreeResult` | Type | Holds the model returned by `useFileTree`. | -| `useFileTreeSelection` | Hook | Returns the selected path list and updates with the model. | -| `useFileTreeSearch` | Hook | Returns search state and search actions. | -| `FileTreeSearchState` | Type | Defines the search snapshot and actions. | -| `useFileTreeSelector` | Hook | Subscribes to a selected part of model state. | -| `FileTreeSelector` | Type | Selects a value from a model. | -| `FileTreeSelectorEquality` | Type | Compares two selected values. | - -`FileTreeProps` extends React host attributes except `children`. Its specific -fields are: - -| Field | Purpose | -| ------------------- | --------------------------------------------------- | -| `model` | Supplies the required `FileTree` model. | -| `header` | Supplies React content for the header slot. | -| `renderContextMenu` | Produces React content for the active context menu. | -| `preloadedData` | Supplies server markup for hydration. | diff --git a/skills/trees/references/api-react.md b/skills/trees/references/api-react.md new file mode 120000 index 000000000..5ba088412 --- /dev/null +++ b/skills/trees/references/api-react.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/api-react.md \ No newline at end of file diff --git a/skills/trees/references/api-ssr.md b/skills/trees/references/api-ssr.md deleted file mode 100644 index 3ef00b4c3..000000000 --- a/skills/trees/references/api-ssr.md +++ /dev/null @@ -1,12 +0,0 @@ -# SSR API - -This reference lists every export from `@pierre/trees/ssr`. - -| Export | Kind | Purpose | -| ----------------------------- | -------- | --------------------------------------------------------------- | -| `preloadFileTree` | Function | Renders a tree to a `FileTreeSsrPayload`. | -| `serializeFileTreeSsrPayload` | Function | Creates declarative or DOM-inserted host markup from a payload. | -| `FileTreeSsrPayload` | Type | Holds the host start, shadow HTML, host end, and stable ID. | - -`preloadFileTree` and `serializeFileTreeSsrPayload` are also available from -`@pierre/trees`. diff --git a/skills/trees/references/api-ssr.md b/skills/trees/references/api-ssr.md new file mode 120000 index 000000000..116546f00 --- /dev/null +++ b/skills/trees/references/api-ssr.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/api-ssr.md \ No newline at end of file diff --git a/skills/trees/references/api-web-components.md b/skills/trees/references/api-web-components.md deleted file mode 100644 index b03a9635b..000000000 --- a/skills/trees/references/api-web-components.md +++ /dev/null @@ -1,11 +0,0 @@ -# Web components API - -Import `@pierre/trees/web-components` to register the `file-tree-container` -custom element. The entry exports these APIs: - -| Export | Kind | Purpose | -| --------------------------- | -------- | ------------------------------------------------------------------------- | -| `FileTreeContainerLoaded` | Value | Confirms that the registration module ran. | -| `adoptDeclarativeShadowDom` | Function | Copies a declarative template into an empty shadow root. | -| `ensureFileTreeStyles` | Function | Installs the core tree stylesheet in a shadow root. | -| `prepareFileTreeShadowRoot` | Function | Adopts server markup, installs styles, and measures the scrollbar gutter. | diff --git a/skills/trees/references/api-web-components.md b/skills/trees/references/api-web-components.md new file mode 120000 index 000000000..f795e7fee --- /dev/null +++ b/skills/trees/references/api-web-components.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/api-web-components.md \ No newline at end of file diff --git a/skills/trees/references/recipe-interactions.md b/skills/trees/references/recipe-interactions.md deleted file mode 100644 index b96d98af4..000000000 --- a/skills/trees/references/recipe-interactions.md +++ /dev/null @@ -1,30 +0,0 @@ -# Recipe: add file tree interactions - -Enable only the interactions that the product exposes: - -```ts -const tree = new FileTree({ - paths, - search: true, - renaming: { - onRename(event) { - renamePath(event.sourcePath, event.destinationPath); - }, - }, - dragAndDrop: { - canDrop({ target }) { - return target.kind === 'directory'; - }, - onDropComplete(event) { - saveMove(event); - }, - }, - gitStatus, -}); -``` - -Use `openSearch()` to open search from an application command. Use -`startRenaming(path)` to start rename from a menu. Use `setGitStatus()` or -`applyGitStatusPatch()` after repository state changes. - -Directory input paths end with `/`. File input paths do not end with `/`. diff --git a/skills/trees/references/recipe-interactions.md b/skills/trees/references/recipe-interactions.md new file mode 120000 index 000000000..9731ffcd1 --- /dev/null +++ b/skills/trees/references/recipe-interactions.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/recipe-interactions.md \ No newline at end of file diff --git a/skills/trees/references/recipe-react.md b/skills/trees/references/recipe-react.md deleted file mode 100644 index 393c78e22..000000000 --- a/skills/trees/references/recipe-react.md +++ /dev/null @@ -1,22 +0,0 @@ -# Recipe: use a file tree in React - -Create the model once and pass it to the component: - -```tsx -'use client'; - -import { FileTree, useFileTree } from '@pierre/trees/react'; - -export function ProjectFiles({ paths }: { paths: readonly string[] }) { - const { model } = useFileTree({ - paths, - initialExpansion: 'open', - search: true, - }); - - return ; -} -``` - -Call model methods for updates after model creation. For example, call -`model.resetPaths(paths)` after the source path list changes. diff --git a/skills/trees/references/recipe-react.md b/skills/trees/references/recipe-react.md new file mode 120000 index 000000000..6ada97c77 --- /dev/null +++ b/skills/trees/references/recipe-react.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/recipe-react.md \ No newline at end of file diff --git a/skills/trees/references/recipe-ssr.md b/skills/trees/references/recipe-ssr.md deleted file mode 100644 index 9b225804f..000000000 --- a/skills/trees/references/recipe-ssr.md +++ /dev/null @@ -1,31 +0,0 @@ -# Recipe: preload a file tree on the server - -Create one payload and pass it to the React tree: - -```tsx -import { preloadFileTree } from '@pierre/trees/ssr'; -import { FileTree, useFileTree } from '@pierre/trees/react'; - -const options = { - id: 'project-files', - paths: ['README.md', 'src/', 'src/index.ts'], - initialExpansion: 'open' as const, - initialVisibleRowCount: 8, -}; - -const preloadedData = preloadFileTree(options); - -export function ProjectFiles() { - const { model } = useFileTree(options); - return ( - - ); -} -``` - -For a direct HTML response, call `serializeFileTreeSsrPayload(payload)`. Pass -`dom` as the second argument when a DOM API inserts the complete markup string. diff --git a/skills/trees/references/recipe-ssr.md b/skills/trees/references/recipe-ssr.md new file mode 120000 index 000000000..3a2c444f7 --- /dev/null +++ b/skills/trees/references/recipe-ssr.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/recipe-ssr.md \ No newline at end of file diff --git a/skills/trees/references/recipe-theme.md b/skills/trees/references/recipe-theme.md deleted file mode 100644 index b7d90fbc5..000000000 --- a/skills/trees/references/recipe-theme.md +++ /dev/null @@ -1,18 +0,0 @@ -# Recipe: apply a resolved theme - -Convert one resolved Shiki or VS Code theme to host styles: - -```tsx -import { themeToTreeStyles } from '@pierre/trees'; -import { FileTree } from '@pierre/trees/react'; - -const treeStyle = { - height: 320, - ...themeToTreeStyles(resolvedTheme), -}; - -; -``` - -Recalculate the styles when the resolved theme changes. Set tree override CSS -properties on the same host style when the product needs a local color choice. diff --git a/skills/trees/references/recipe-theme.md b/skills/trees/references/recipe-theme.md new file mode 120000 index 000000000..e3c826445 --- /dev/null +++ b/skills/trees/references/recipe-theme.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/recipe-theme.md \ No newline at end of file diff --git a/skills/trees/references/recipe-vanilla.md b/skills/trees/references/recipe-vanilla.md deleted file mode 100644 index ea258f439..000000000 --- a/skills/trees/references/recipe-vanilla.md +++ /dev/null @@ -1,23 +0,0 @@ -# Recipe: use a file tree in vanilla JavaScript - -Create the model and mount it in an element with a height: - -```ts -import { FileTree } from '@pierre/trees'; - -const mount = document.querySelector('#files'); -if (mount == null) throw new Error('Missing file tree mount'); - -mount.style.height = '320px'; - -const tree = new FileTree({ - paths: ['README.md', 'src/', 'src/index.ts'], - initialExpansion: 'open', - search: true, -}); - -tree.render({ containerWrapper: mount }); -``` - -Use `add`, `remove`, `move`, or `resetPaths` to update paths. Call `cleanUp()` -when the host removes the tree. diff --git a/skills/trees/references/recipe-vanilla.md b/skills/trees/references/recipe-vanilla.md new file mode 120000 index 000000000..507425414 --- /dev/null +++ b/skills/trees/references/recipe-vanilla.md @@ -0,0 +1 @@ +../../../packages/trees/skills/trees/references/recipe-vanilla.md \ No newline at end of file