дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
feat(plugins): tidy the unreleased 1.3 API before it freezes (#2079)
- workspace.symbols becomes the project method project.symbols(query, limit), like find-files; the Rust SDK's Project::symbols is unchanged, components built against the previous main need a rebuild. - The open-log-tab web message names its arguments args, as pty-spawn and the services process-log do; baseArgs is refused with log-error rather than ignored. - Document the hover, semantic-tokens and diagnostics provider exports and their worlds.
Цей коміт міститься в:
1 джерело
32a778d28d
коміт
ec171c3188
86 files changed
+177
-111
No files matched your search
@@ -19,7 +19,7 @@ const plugin = { id: "probe", enabled: true, capabilities: [{ id: "process:bash"
|
||||
const spec = {
|
||||
program: "bash",
|
||||
title: "Probe logs",
|
||||
baseArgs: ["--noprofile", "--norc"],
|
||||
args: ["--noprofile", "--norc"],
|
||||
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
|
||||
};
|
||||
let stopActions: () => void;
|
||||
@@ -76,9 +76,10 @@ describe("plugin streaming log tabs", () => {
|
||||
{ program: "sh" },
|
||||
{ program: "/bin/bash" },
|
||||
{ program: " bash" },
|
||||
{ baseArgs: [123] },
|
||||
{ baseArgs: ["\0"] },
|
||||
{ baseArgs: ["x".repeat(4097)] },
|
||||
{ args: [123] },
|
||||
{ args: ["\0"] },
|
||||
{ args: ["x".repeat(4097)] },
|
||||
{ baseArgs: ["--verbose"] },
|
||||
{ cwd: "/" },
|
||||
{ env: { PATH: "/tmp" } },
|
||||
{ title: "x".repeat(257) },
|
||||
@@ -102,7 +103,7 @@ describe("plugin streaming log tabs", () => {
|
||||
const f = setup();
|
||||
expect(webPtyBackend).toHaveBeenCalledWith("probe", "logs");
|
||||
expect(f.backend.spawn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ program: "bash", env: {}, args: spec.baseArgs }),
|
||||
expect.objectContaining({ program: "bash", env: {}, args: spec.args }),
|
||||
expect.any(Function),
|
||||
);
|
||||
expect(f.view().state.facet(EditorState.readOnly)).toBe(true);
|
||||
@@ -128,7 +129,7 @@ describe("plugin streaming log tabs", () => {
|
||||
fireEvent.click(screen.getByRole("switch", { name: "Verbose" }));
|
||||
await waitFor(() => expect(f.backend.kill).toHaveBeenCalledWith(42));
|
||||
expect(f.backend.spawn).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({ args: [...spec.baseArgs, "-v"] }),
|
||||
expect.objectContaining({ args: [...spec.args, "-v"] }),
|
||||
expect.any(Function),
|
||||
);
|
||||
vi.mocked(f.backend.kill).mockClear();
|
||||
|
||||
@@ -277,7 +277,7 @@ describe("WebView", () => {
|
||||
title: "App Logs",
|
||||
key: "shared",
|
||||
program: "tail",
|
||||
baseArgs: ["-f", "app.log"],
|
||||
args: ["-f", "app.log"],
|
||||
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
|
||||
};
|
||||
|
||||
@@ -308,7 +308,7 @@ describe("WebView", () => {
|
||||
pluginId: "acme.draw",
|
||||
title: "App Logs",
|
||||
program: "tail",
|
||||
baseArgs: ["-f", "app.log"],
|
||||
args: ["-f", "app.log"],
|
||||
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -395,7 +395,7 @@ function PluginLogEditorBody({ input, data }: { input: EditorInput; data: Plugin
|
||||
op: "pty-spawn",
|
||||
sessionId: "log",
|
||||
program: data.program,
|
||||
args: [...data.baseArgs, ...data.toggles.filter((t) => on.has(t.id)).flatMap((t) => t.args)],
|
||||
args: [...data.args, ...data.toggles.filter((t) => on.has(t.id)).flatMap((t) => t.args)],
|
||||
cols: 240,
|
||||
rows: 40,
|
||||
}),
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface PluginLogEditorData {
|
||||
key?: string;
|
||||
title: string;
|
||||
program: string;
|
||||
baseArgs: string[];
|
||||
args: string[];
|
||||
toggles: PluginLogToggleSpec[];
|
||||
}
|
||||
|
||||
@@ -25,27 +25,28 @@ const args = (v: unknown): v is string[] =>
|
||||
/** Reject malformed requests instead of silently running a different command. */
|
||||
export function logTabData(pluginId: string, view: string, value: object, length: number): PluginLogEditorData {
|
||||
const m = value as Record<string, unknown>;
|
||||
const { program, baseArgs = [], toggles = [], key, title = program } = m;
|
||||
const { program, args: command = [], toggles = [], key, title = program } = m;
|
||||
if (
|
||||
length > 2 << 20 ||
|
||||
!text(program, 256) ||
|
||||
program.trim() !== program ||
|
||||
!text(title, 256) ||
|
||||
(key !== undefined && !text(key, 128)) ||
|
||||
!args(baseArgs) ||
|
||||
!args(command) ||
|
||||
!Array.isArray(toggles) ||
|
||||
toggles.length > 32 ||
|
||||
toggles.some((t) => !t || !text(t.id, 64) || !text(t.label, 128) || !args(t.args)) ||
|
||||
new Set(toggles.map((t) => t.id)).size !== toggles.length ||
|
||||
baseArgs.length + toggles.reduce((n, t) => n + t.args.length, 0) > 256 ||
|
||||
command.length + toggles.reduce((n, t) => n + t.args.length, 0) > 256 ||
|
||||
"cwd" in m ||
|
||||
"env" in m
|
||||
"env" in m ||
|
||||
"baseArgs" in m
|
||||
)
|
||||
throw new Error(tx("Invalid log stream configuration"));
|
||||
const plugin = usePlugins.getState().plugins.find((p) => p.id === pluginId);
|
||||
if (!plugin?.enabled || !plugin.capabilities.some((c) => c.id === `process:${program}` && c.granted))
|
||||
throw new Error(tx`Cannot start PTY: process:${program} capability not granted.`);
|
||||
return { pluginId, view, key: key as string | undefined, title, program, baseArgs, toggles };
|
||||
return { pluginId, view, key: key as string | undefined, title, program, args: command, toggles };
|
||||
}
|
||||
|
||||
/** Bound both line count and text size, including output with no newlines. */
|
||||
|
||||
Reference in new issue
Заблокувати користувача