From 90a66ee94ba54166325aeda0e3143657e2a12bc5 Mon Sep 17 00:00:00 2001
From: Kian Jones <11655409+kianjones9@users.noreply.github.com>
Date: Tue, 16 Dec 2025 14:29:39 -0500
Subject: [PATCH] feat: hide pin and unpin based on existing pinning
configuration (#236)
---
src/cli/components/InputAssist.tsx | 4 ++
src/cli/components/InputRich.tsx | 2 +
.../components/SlashCommandAutocomplete.tsx | 40 +++++++++++++++++--
src/cli/components/types/autocomplete.ts | 4 ++
4 files changed, 47 insertions(+), 3 deletions(-)
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;
}
/**