feat(chat): align command, shell, and subtask UX (#444)
* feat: reload interface after skills operations - Adds configurable delay before interface reload after skills changes - Introduces polling to wait for application health after reload - Updates UI to show reload message when installing or modifying skills * feat: distinguish skills from commands in UI - Displays skill badge for commands that are registered skills - Prevents editing skills through command management interface - Triggers interface reload after skill operations to reflect changes * feat(chat): align command and subtask UX with opencode parity Route commands/shell via parity paths, render delegated subtasks cleanly, and surface child-session permission/question prompts in parent chat. * fix(ProjectEditDialog): improve layout consistency * fix: update task icon and session handling in ToolPart * feat(chat): add shell-mode input and collapse shell bridge output Switch leading ! to shell mode UX and fold synthetic shell bridge assistant messages into the user shell bubble with inline output actions. * fix: remove AI agent icon from file mention autocomplete * fix: remove unused icon import from file mention component
This commit is contained in:
committed by
GitHub
parent
e4a2486312
commit
85f21cb945
@@ -19,6 +19,7 @@ import {
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { RiAddLine, RiTerminalBoxLine, RiMore2Line, RiDeleteBinLine, RiFileCopyLine, RiRestartLine, RiEditLine } from '@remixicon/react';
|
||||
import { useCommandsStore, isCommandBuiltIn, type Command } from '@/stores/useCommandsStore';
|
||||
import { useSkillsStore } from '@/stores/useSkillsStore';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useDeviceInfo } from '@/lib/device';
|
||||
import { isVSCodeRuntime } from '@/lib/desktop';
|
||||
@@ -45,6 +46,7 @@ export const CommandsSidebar: React.FC<CommandsSidebarProps> = ({ onItemSelect }
|
||||
deleteCommand,
|
||||
loadCommands,
|
||||
} = useCommandsStore();
|
||||
const { skills, loadSkills } = useSkillsStore();
|
||||
|
||||
const { setSidebarOpen } = useUIStore();
|
||||
const { isMobile } = useDeviceInfo();
|
||||
@@ -53,7 +55,24 @@ export const CommandsSidebar: React.FC<CommandsSidebarProps> = ({ onItemSelect }
|
||||
|
||||
React.useEffect(() => {
|
||||
loadCommands();
|
||||
}, [loadCommands]);
|
||||
loadSkills();
|
||||
}, [loadCommands, loadSkills]);
|
||||
|
||||
const skillNames = React.useMemo(() => new Set(skills.map((skill) => skill.name)), [skills]);
|
||||
const commandOnlyItems = React.useMemo(
|
||||
() => commands.filter((command) => !skillNames.has(command.name)),
|
||||
[commands, skillNames],
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!selectedCommandName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skillNames.has(selectedCommandName)) {
|
||||
setSelectedCommand(null);
|
||||
}
|
||||
}, [selectedCommandName, setSelectedCommand, skillNames]);
|
||||
|
||||
const bgClass = isVSCode ? 'bg-background' : 'bg-sidebar';
|
||||
|
||||
@@ -203,14 +222,14 @@ export const CommandsSidebar: React.FC<CommandsSidebarProps> = ({ onItemSelect }
|
||||
setRenameDialogCommand(null);
|
||||
};
|
||||
|
||||
const builtInCommands = commands.filter(isCommandBuiltIn);
|
||||
const customCommands = commands.filter((cmd) => !isCommandBuiltIn(cmd));
|
||||
const builtInCommands = commandOnlyItems.filter(isCommandBuiltIn);
|
||||
const customCommands = commandOnlyItems.filter((cmd) => !isCommandBuiltIn(cmd));
|
||||
|
||||
return (
|
||||
<div className={cn('flex h-full flex-col', bgClass)}>
|
||||
<div className={cn('border-b px-3', isMobile ? 'mt-2 py-3' : 'py-3')}>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="typography-meta text-muted-foreground">Total {commands.length}</span>
|
||||
<span className="typography-meta text-muted-foreground">Total {commandOnlyItems.length}</span>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
@@ -224,7 +243,7 @@ export const CommandsSidebar: React.FC<CommandsSidebarProps> = ({ onItemSelect }
|
||||
</div>
|
||||
|
||||
<ScrollableOverlay outerClassName="flex-1 min-h-0" className="space-y-1 px-3 py-2">
|
||||
{commands.length === 0 ? (
|
||||
{commandOnlyItems.length === 0 ? (
|
||||
<div className="py-12 px-4 text-center text-muted-foreground">
|
||||
<RiTerminalBoxLine className="mx-auto mb-3 h-10 w-10 opacity-50" />
|
||||
<p className="typography-ui-label font-medium">No commands configured</p>
|
||||
|
||||
Reference in New Issue
Block a user