mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 17:00:59 +00:00
feat(coding-agent): surface extension shortcut conflicts
This commit is contained in:
parent
72de8f26a1
commit
3a57f1259b
2 changed files with 38 additions and 3 deletions
|
|
@ -6,6 +6,7 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
|||
import type { ImageContent, Model } from "@mariozechner/pi-ai";
|
||||
import type { KeyId } from "@mariozechner/pi-tui";
|
||||
import { type Theme, theme } from "../../modes/interactive/theme/theme.js";
|
||||
import type { ResourceDiagnostic } from "../diagnostics.js";
|
||||
import type { KeyAction, KeybindingsConfig } from "../keybindings.js";
|
||||
import type { ModelRegistry } from "../model-registry.js";
|
||||
import type { SessionManager } from "../session-manager.js";
|
||||
|
|
@ -162,6 +163,7 @@ export class ExtensionRunner {
|
|||
private forkHandler: ForkHandler = async () => ({ cancelled: false });
|
||||
private navigateTreeHandler: NavigateTreeHandler = async () => ({ cancelled: false });
|
||||
private shutdownHandler: ShutdownHandler = () => {};
|
||||
private shortcutDiagnostics: ResourceDiagnostic[] = [];
|
||||
|
||||
constructor(
|
||||
extensions: Extension[],
|
||||
|
|
@ -275,30 +277,42 @@ export class ExtensionRunner {
|
|||
}
|
||||
|
||||
getShortcuts(effectiveKeybindings: Required<KeybindingsConfig>): Map<KeyId, ExtensionShortcut> {
|
||||
this.shortcutDiagnostics = [];
|
||||
const builtinKeybindings = buildBuiltinKeybindings(effectiveKeybindings);
|
||||
const extensionShortcuts = new Map<KeyId, ExtensionShortcut>();
|
||||
|
||||
const addDiagnostic = (message: string, extensionPath: string) => {
|
||||
this.shortcutDiagnostics.push({ type: "warning", message, path: extensionPath });
|
||||
if (!this.hasUI()) {
|
||||
console.warn(message);
|
||||
}
|
||||
};
|
||||
|
||||
for (const ext of this.extensions) {
|
||||
for (const [key, shortcut] of ext.shortcuts) {
|
||||
const normalizedKey = key.toLowerCase() as KeyId;
|
||||
|
||||
const builtInKeybinding = builtinKeybindings[normalizedKey];
|
||||
if (builtInKeybinding?.restrictOverride === true) {
|
||||
console.warn(
|
||||
addDiagnostic(
|
||||
`Extension shortcut '${key}' from ${shortcut.extensionPath} conflicts with built-in shortcut. Skipping.`,
|
||||
shortcut.extensionPath,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (builtInKeybinding?.restrictOverride === false) {
|
||||
console.warn(
|
||||
addDiagnostic(
|
||||
`Extension shortcut conflict: '${key}' is built-in shortcut for ${builtInKeybinding.action} and ${shortcut.extensionPath}. Using ${shortcut.extensionPath}.`,
|
||||
shortcut.extensionPath,
|
||||
);
|
||||
}
|
||||
|
||||
const existingExtensionShortcut = extensionShortcuts.get(normalizedKey);
|
||||
if (existingExtensionShortcut) {
|
||||
console.warn(
|
||||
addDiagnostic(
|
||||
`Extension shortcut conflict: '${key}' registered by both ${existingExtensionShortcut.extensionPath} and ${shortcut.extensionPath}. Using ${shortcut.extensionPath}.`,
|
||||
shortcut.extensionPath,
|
||||
);
|
||||
}
|
||||
extensionShortcuts.set(normalizedKey, shortcut);
|
||||
|
|
@ -307,6 +321,10 @@ export class ExtensionRunner {
|
|||
return extensionShortcuts;
|
||||
}
|
||||
|
||||
getShortcutDiagnostics(): ResourceDiagnostic[] {
|
||||
return this.shortcutDiagnostics;
|
||||
}
|
||||
|
||||
onError(listener: ExtensionErrorListener): () => void {
|
||||
this.errorListeners.add(listener);
|
||||
return () => this.errorListeners.delete(listener);
|
||||
|
|
|
|||
|
|
@ -932,6 +932,23 @@ export class InteractiveMode {
|
|||
this.chatContainer.addChild(new Spacer(1));
|
||||
}
|
||||
|
||||
const extensionDiagnostics: ResourceDiagnostic[] = [];
|
||||
const extensionErrors = this.session.resourceLoader.getExtensions().errors;
|
||||
if (extensionErrors.length > 0) {
|
||||
for (const error of extensionErrors) {
|
||||
extensionDiagnostics.push({ type: "error", message: error.error, path: error.path });
|
||||
}
|
||||
}
|
||||
|
||||
const shortcutDiagnostics = this.session.extensionRunner?.getShortcutDiagnostics() ?? [];
|
||||
extensionDiagnostics.push(...shortcutDiagnostics);
|
||||
|
||||
if (extensionDiagnostics.length > 0) {
|
||||
const warningLines = this.formatDiagnostics(extensionDiagnostics, metadata);
|
||||
this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Extension issues]")}\n${warningLines}`, 0, 0));
|
||||
this.chatContainer.addChild(new Spacer(1));
|
||||
}
|
||||
|
||||
// Show loaded themes (excluding built-in)
|
||||
const loadedThemes = this.session.resourceLoader.getThemes().themes;
|
||||
const customThemes = loadedThemes.filter((t) => t.sourcePath);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue