diff --git a/src/cli/components/InputAssist.tsx b/src/cli/components/InputAssist.tsx index 3080d9e..4ab9640 100644 --- a/src/cli/components/InputAssist.tsx +++ b/src/cli/components/InputAssist.tsx @@ -13,6 +13,7 @@ interface InputAssistProps { agentId?: string; agentName?: string | null; serverUrl?: string; + workingDirectory?: string; } /** @@ -30,6 +31,7 @@ export function InputAssist({ agentId, agentName, serverUrl, + workingDirectory, }: InputAssistProps) { const showFileAutocomplete = currentInput.includes("@"); const showCommandAutocomplete = @@ -67,6 +69,8 @@ export function InputAssist({ cursorPosition={cursorPosition} onSelect={onCommandSelect} onActiveChange={onAutocompleteActiveChange} + agentId={agentId} + workingDirectory={workingDirectory} /> diff --git a/src/cli/components/SlashCommandAutocomplete.tsx b/src/cli/components/SlashCommandAutocomplete.tsx index b649654..5552d0d 100644 --- a/src/cli/components/SlashCommandAutocomplete.tsx +++ b/src/cli/components/SlashCommandAutocomplete.tsx @@ -1,12 +1,13 @@ import { Box, Text } from "ink"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; +import { settingsManager } from "../../settings-manager"; import { commands } from "../commands/registry"; import { useAutocompleteNavigation } from "../hooks/useAutocompleteNavigation"; import { colors } from "./colors"; import type { AutocompleteProps, CommandMatch } from "./types/autocomplete"; // Compute filtered command list (excluding hidden commands) -const allCommands: CommandMatch[] = Object.entries(commands) +const _allCommands: CommandMatch[] = Object.entries(commands) .filter(([, { hidden }]) => !hidden) .map(([cmd, { desc }]) => ({ cmd, @@ -42,9 +43,42 @@ export function SlashCommandAutocomplete({ cursorPosition = currentInput.length, onSelect, onActiveChange, + agentId, + workingDirectory = process.cwd(), }: AutocompleteProps) { const [matches, setMatches] = useState([]); + // Check pin status to conditionally show/hide pin/unpin commands + const allCommands = useMemo(() => { + if (!agentId) return _allCommands; + + try { + const globalPinned = settingsManager.getGlobalPinnedAgents(); + const localPinned = + settingsManager.getLocalPinnedAgents(workingDirectory); + + const isPinnedGlobally = globalPinned.includes(agentId); + const isPinnedLocally = localPinned.includes(agentId); + const isPinnedAnywhere = isPinnedGlobally || isPinnedLocally; + const isPinnedBoth = isPinnedGlobally && isPinnedLocally; + + return _allCommands.filter((cmd) => { + // Hide /pin if agent is pinned both locally AND globally + if (cmd.cmd === "/pin" && isPinnedBoth) { + return false; + } + // Hide /unpin if agent is not pinned anywhere + if (cmd.cmd === "/unpin" && !isPinnedAnywhere) { + return false; + } + return true; + }); + } catch (_error) { + // If settings aren't loaded, just show all commands + return _allCommands; + } + }, [agentId, workingDirectory]); + const { selectedIndex } = useAutocompleteNavigation({ matches, onSelect: onSelect ? (item) => onSelect(item.cmd) : undefined, @@ -84,7 +118,7 @@ export function SlashCommandAutocomplete({ } setMatches(newMatches); - }, [currentInput, cursorPosition]); + }, [currentInput, cursorPosition, allCommands]); // Don't show if input doesn't start with "/" if (!currentInput.startsWith("/")) { diff --git a/src/cli/components/types/autocomplete.ts b/src/cli/components/types/autocomplete.ts index 625a7e4..1502884 100644 --- a/src/cli/components/types/autocomplete.ts +++ b/src/cli/components/types/autocomplete.ts @@ -14,6 +14,10 @@ export interface AutocompleteProps { onSelect?: (value: string) => void; /** Callback when autocomplete active state changes */ onActiveChange?: (isActive: boolean) => void; + /** Current agent ID for context-sensitive command filtering */ + agentId?: string; + /** Working directory for local pin status checking */ + workingDirectory?: string; } /**