Archived
feat: expose prompt helper to workspace panels
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@jmfederico/pi-web": patch
|
||||
---
|
||||
|
||||
Expose the plugin prompt editor helper in workspace panel contexts so panel interactions can insert text into the current prompt.
|
||||
+4
-3
@@ -467,7 +467,7 @@ Notes:
|
||||
|
||||
### Prompt editor API
|
||||
|
||||
The `prompt` helper on `PluginRuntimeContext` provides stable access to the chat prompt editor:
|
||||
The `prompt` helper on `PluginRuntimeContext` and `WorkspacePanelContext` provides stable access to the chat prompt editor:
|
||||
|
||||
| Method | Description |
|
||||
| --- | --- |
|
||||
@@ -486,7 +486,7 @@ const text = context.prompt.getText();
|
||||
const selection = context.prompt.getSelection(); // { start, end, text } | null
|
||||
```
|
||||
|
||||
Use `focusPrompt()` on `PluginRuntimeContext` to move focus to the prompt editor.
|
||||
Use `focusPrompt()` on `PluginRuntimeContext` to move focus to the prompt editor. Workspace panels can call `context.prompt.insertText()` from explicit user interactions such as button clicks; panel contexts target the currently selected session's mounted prompt editor.
|
||||
|
||||
#### Keyboard shortcuts
|
||||
|
||||
@@ -549,6 +549,7 @@ interface WorkspacePanelContext {
|
||||
deleteFile(path: string): Promise<DeleteWorkspaceFileResponse>;
|
||||
moveFile(fromPath: string, toPath: string, options?: MoveWorkspaceFileOptions): Promise<MoveWorkspaceFileResponse>;
|
||||
};
|
||||
prompt: PluginPromptEditor;
|
||||
terminal: {
|
||||
open(options?: { terminalId?: string }): void;
|
||||
runCommand(input: {
|
||||
@@ -566,7 +567,7 @@ interface WorkspacePanelContext {
|
||||
|
||||
`icon` is optional and is used in the compact mobile tab bar. Prefer an SVG rendered with the `svg` helper from `PluginActivationContext`; use `currentColor` so PI WEB themes can style it. If `icon` is omitted, mobile tabs fall back to initials from the panel title, or to the full title when initials collide.
|
||||
|
||||
`machine`, `workspace`, `files`, `terminal`, and `host` are documented as stable for panel callbacks. The `files` helper supports `readFile`, `writeFile`, `deleteFile`, and `moveFile` — see [Reading workspace files](#reading-workspace-files) and [Writing workspace files](#writing-workspace-files). Use `terminal.open()` to switch to the built-in terminal panel; pass `{ terminalId }` to deep-link to a specific terminal. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate panel callbacks such as `badge`, `visible`, or `render`.
|
||||
`machine`, `workspace`, `files`, `prompt`, `terminal`, and `host` are documented as stable for panel callbacks. The `files` helper supports `readFile`, `writeFile`, `deleteFile`, and `moveFile` — see [Reading workspace files](#reading-workspace-files) and [Writing workspace files](#writing-workspace-files). The `prompt` helper supports panel interactions that insert workspace context into the current prompt — see [Prompt editor API](#prompt-editor-api). Use `terminal.open()` to switch to the built-in terminal panel; pass `{ terminalId }` to deep-link to a specific terminal. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate panel callbacks such as `badge`, `visible`, or `render`.
|
||||
|
||||
For compatibility, PI WEB still provides the old `context.openTerminal()` workspace-panel helper at runtime. It is deprecated, intentionally omitted from the public TypeScript declarations, and planned for removal in v2. Existing JavaScript plugins keep working, while typed plugins should migrate to `context.terminal.open()`.
|
||||
|
||||
|
||||
@@ -1250,6 +1250,7 @@ export class PiWebApp extends LitElement {
|
||||
workspace,
|
||||
state: this.state,
|
||||
files: this.createWorkspaceFiles(workspace, machineId),
|
||||
prompt: this.createPromptEditor(),
|
||||
terminal: {
|
||||
open: (options) => { void this.openRuntimeTerminal(machineId, workspace, options); },
|
||||
runCommand: (input) => terminalCommandRuns.runCommand({ ...input, workspace }),
|
||||
|
||||
@@ -89,6 +89,37 @@ describe("PluginRegistry", () => {
|
||||
expect(registry.getWorkspacePanels()[0]?.icon).toBeDefined();
|
||||
});
|
||||
|
||||
it("exposes the prompt helper to workspace panel callbacks", () => {
|
||||
const registry = new PluginRegistry();
|
||||
registry.register({
|
||||
id: "example",
|
||||
plugin: {
|
||||
apiVersion: 1,
|
||||
name: "Example",
|
||||
activate: () => ({
|
||||
contributions: {
|
||||
workspacePanels: [
|
||||
{
|
||||
id: "workspace.prompt",
|
||||
title: "Prompt",
|
||||
render: (context) => {
|
||||
context.prompt.insertText("@docs/example.md");
|
||||
return html`<p>Prompt</p>`;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
const insertText = vi.fn();
|
||||
const context = createWorkspacePanelContext("local", { insertText, getText: vi.fn(() => ""), getSelection: vi.fn(() => null) });
|
||||
|
||||
registry.getWorkspacePanels()[0]?.render(context);
|
||||
|
||||
expect(insertText).toHaveBeenCalledWith("@docs/example.md");
|
||||
});
|
||||
|
||||
it("rejects duplicate ids within the same namespace", () => {
|
||||
const registry = new PluginRegistry();
|
||||
|
||||
@@ -561,13 +592,14 @@ function createWorkspaceLabelContext(machineId: string, workspace = testWorkspac
|
||||
};
|
||||
}
|
||||
|
||||
function createWorkspacePanelContext(machineId: string): WorkspacePanelContext {
|
||||
function createWorkspacePanelContext(machineId: string, prompt: WorkspacePanelContext["prompt"] = { insertText: vi.fn(), getText: vi.fn(() => ""), getSelection: vi.fn(() => null) }): WorkspacePanelContext {
|
||||
const workspace = testWorkspace();
|
||||
return {
|
||||
machine: { id: machineId, name: machineId, kind: machineId === "local" ? "local" : "remote" },
|
||||
workspace,
|
||||
state: { ...initialAppState(), selectedMachine: testMachine(machineId) },
|
||||
files: { readFile: vi.fn(), writeFile: vi.fn(), deleteFile: vi.fn(), moveFile: vi.fn() },
|
||||
prompt,
|
||||
terminal: { open: vi.fn(), runCommand: vi.fn() },
|
||||
host: { requestRender: vi.fn() },
|
||||
fileTree: [],
|
||||
|
||||
@@ -138,6 +138,7 @@ export interface QualifiedPluginAction extends AppAction {
|
||||
}
|
||||
|
||||
export interface WorkspacePanelContext extends WorkspaceContext {
|
||||
prompt: PluginPromptEditor;
|
||||
terminal: WorkspacePanelTerminal;
|
||||
/**
|
||||
* @deprecated Runtime-only compatibility alias for pre-v2 plugins. Use `terminal.open()` instead.
|
||||
|
||||
@@ -168,6 +168,7 @@ export interface WorkspacePanelTerminal {
|
||||
}
|
||||
|
||||
export interface WorkspacePanelContext extends WorkspaceContext {
|
||||
prompt: PluginPromptEditor;
|
||||
terminal: WorkspacePanelTerminal;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user