feat(coding-agent): make scoped models and tree filter shortcuts configurable (#3343)
- Add app.models.{save,enableAll,clearAll,toggleProvider,reorderUp,reorderDown}
- Add app.tree.filter.{default,noTools,userOnly,labeledOnly,all,cycleForward,cycleBackward}
- Migrate scoped-models-selector cancel to tui.select.cancel
- Prefer reserved actions on key collision in extension shortcut conflict check
This commit is contained in:
@@ -180,6 +180,29 @@ describe("ExtensionRunner", () => {
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("blocks shortcuts when reserved key is also bound to non-reserved actions", async () => {
|
||||
const extCode = `
|
||||
export default function(pi) {
|
||||
pi.registerShortcut("ctrl+p", {
|
||||
description: "Conflicts with shared reserved default",
|
||||
handler: async () => {},
|
||||
});
|
||||
}
|
||||
`;
|
||||
fs.writeFileSync(path.join(extensionsDir, "shared-reserved.ts"), extCode);
|
||||
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
|
||||
const result = await discoverAndLoadExtensions([], tempDir, tempDir);
|
||||
const runner = new ExtensionRunner(result.extensions, result.runtime, tempDir, sessionManager, modelRegistry);
|
||||
const shortcuts = runner.getShortcuts(defaultKeybindings);
|
||||
|
||||
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("conflicts with built-in"));
|
||||
expect(shortcuts.has("ctrl+p")).toBe(false);
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("blocks shortcuts when reserved action has multiple keys", async () => {
|
||||
const extCode = `
|
||||
export default function(pi) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { TUI } from "@mariozechner/pi-tui";
|
||||
import { setKeybindings, type TUI } from "@mariozechner/pi-tui";
|
||||
import stripAnsi from "strip-ansi";
|
||||
import { afterEach, beforeAll, describe, expect, it } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import { KeybindingsManager } from "../../../src/core/keybindings.js";
|
||||
import { ModelSelectorComponent } from "../../../src/modes/interactive/components/model-selector.js";
|
||||
import { ScopedModelsSelectorComponent } from "../../../src/modes/interactive/components/scoped-models-selector.js";
|
||||
import { initTheme } from "../../../src/modes/interactive/theme/theme.js";
|
||||
@@ -23,6 +24,11 @@ describe("issue #3217 scoped model ordering", () => {
|
||||
initTheme("dark");
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Ensure test isolation: keybindings are a global singleton
|
||||
setKeybindings(new KeybindingsManager());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
while (harnesses.length > 0) {
|
||||
harnesses.pop()?.cleanup();
|
||||
|
||||
Reference in New Issue
Block a user