scripts/vendor.sh clones upstream, rewrites @/ imports to relative paths, and applies scripts/apply-host.py. web/host.ts is ours and gets placed into the vendored tree, because upstream declined it. a script rather than a .patch, and that is not a preference. between cfde698 and 5c83ac6 — one day — upstream changed an import line, re-indented the component from 6 spaces to 8, and added an editAccess guard. a context diff fails on all three, none of which concern us. so every anchor matches structure with flexible whitespace and re-indents to whatever it finds, and a missing anchor stops the run loudly. all three prompt-export paths are wired, which is what upstream said a complete version needs. the other two clipboard writes are ShareMenu's share-link and ask-an-AI blurb, and the reason they are excluded is written down so the count does not read as the same oversight twice. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext } from "react";
|
|
import type { Doc } from "./tokens";
|
|
|
|
/**
|
|
* Hooks for an application that embeds the editor.
|
|
*
|
|
* The editor keeps its own state and its own UI; a host only needs to say where the document is kept
|
|
* and where the prompt goes. Every field is optional and every default is what the standalone app
|
|
* already did — localStorage for the document, the clipboard for the prompt — so an editor rendered
|
|
* without a provider behaves exactly as before.
|
|
*
|
|
* ```tsx
|
|
* <HostProvider value={{ loadDoc, saveDoc, onExport: (text) => sendToAgent(text) }}>
|
|
* <Canvas />
|
|
* </HostProvider>
|
|
* ```
|
|
*/
|
|
export type HostAdapter = {
|
|
/** Return the saved document, or null for a fresh one. Omit to read localStorage. */
|
|
loadDoc?: () => Partial<Doc> | null;
|
|
/** Persist the document. Omit to write localStorage. Called on every change, so debounce if remote. */
|
|
saveDoc?: (doc: Partial<Doc>) => void;
|
|
|
|
/** Editor chrome — panel widths, favourites. Separate from the document because it is not the work. */
|
|
loadUi?: () => unknown | null;
|
|
saveUi?: (ui: unknown) => void;
|
|
|
|
/**
|
|
* Where the generated prompt goes.
|
|
*
|
|
* Return `true` to say the host has handled it and the editor should not also write the clipboard;
|
|
* anything else and the clipboard write still happens. That default matters — a host that only
|
|
* wants to observe the export does not have to reimplement copying.
|
|
*/
|
|
onExport?: (prompt: string, doc: Doc) => boolean | void;
|
|
};
|
|
|
|
const EMPTY: HostAdapter = {};
|
|
|
|
export const HostContext = createContext<HostAdapter>(EMPTY);
|
|
|
|
export const HostProvider = HostContext.Provider;
|
|
|
|
export const useHost = (): HostAdapter => useContext(HostContext);
|