perf: faster plugin updates, half-size first bundle, images from the chat attach on Windows
- Chat view: an attached image's path is pasted on its own after the text (promptForPane). claude turns a paste that is only an image path into [Image #n], but left a Windows path inside a paste of text as a plain path. Other files and @-mentions stay in the text as before. - Plugin bootstrap: depsHash covers only what npm installs (no release version), so a version bump no longer reinstalls runtime deps; the client's installed tree is kept while its manifests are unchanged (no npm ci per update); the user-side build runs vite only (tsc -b cost ~25 s / ~900 MB); clientBuild is recorded only after a build that did not fail, so a failed one is retried; npm output goes to runtime/npm-install.log. - Server: a port held by another program ends with a clear message and exit 1 instead of an uncaught 'error' stack trace. - Client: the onboarding wizard is lazy and rendered only before onboarding; usePrefersReducedMotion moved to hooks/ so PetSettings no longer pulls the Sagi chat/pane stack into the entry chunk (884 KB -> 431 KB, gzip 268 -> 133 KB).
This commit is contained in:
@@ -14,6 +14,9 @@
|
||||
* terminal moves the unsent prompt across (`takeRunInput` reads the TUI's
|
||||
* input box off the screen and empties it; the chat's draft is pasted back
|
||||
* without Enter), so the half-typed text is never left behind on the other side.
|
||||
* Attached images' paths go after the text, each in a paste of its own: `claude`
|
||||
* turns a paste that is only an image's path into `[Image #n]`, but left a
|
||||
* Windows path (`C:\…\drops\…png`) inside a paste of text as a plain path.
|
||||
* The Chat view also answers a menu the CLI asks with (`parsePaneMenu` reads
|
||||
* it off the screen; `chooseRunOption`/`answerRunMenu` press its digit, the
|
||||
* arrows and Enter, or type into its "Type something" row).
|
||||
@@ -24,7 +27,8 @@
|
||||
export type PaneScreen = { rows: string[]; cols: number };
|
||||
|
||||
interface Pane {
|
||||
paste: (text: string, submit?: boolean) => void;
|
||||
/** `files`: image paths pasted after `text`, one paste each. */
|
||||
paste: (text: string, submit?: boolean, files?: string[]) => void;
|
||||
visible: () => boolean;
|
||||
key?: (data: string) => void;
|
||||
/** `menuOnly`: null at once unless a row could be a menu's cursor row. */
|
||||
@@ -62,19 +66,19 @@ function ofLane(runId: string, laneId: number): boolean {
|
||||
|
||||
/** Pastes `text` into the pane of `runId` when it is mounted and on screen;
|
||||
* false otherwise (not mounted yet, or hidden). */
|
||||
export function pasteToRun(runId: string, text: string): boolean {
|
||||
export function pasteToRun(runId: string, text: string, files: string[] = []): boolean {
|
||||
const p = panes.get(runId);
|
||||
if (!p?.visible()) return false;
|
||||
p.paste(text);
|
||||
p.paste(text, false, files);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Sends `text` as a message to the pane of `runId`: a paste, then Enter.
|
||||
* False when the pane is not mounted or not attached. */
|
||||
export function submitToRun(runId: string, text: string): boolean {
|
||||
export function submitToRun(runId: string, text: string, files: string[] = []): boolean {
|
||||
const p = panes.get(runId);
|
||||
if (!p?.visible()) return false;
|
||||
p.paste(text, true);
|
||||
p.paste(text, true, files);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user