feat: add frontend customization UI and prompt picker

Add Copilot Customization section to ProjectSettingsPanel with instruction file
previews, agent profile enable/disable toggles, and prompt file listing. Add
InlinePromptPill to chat input for selecting and sending prompt files with
variable substitution. Wire rescan and agent profile IPC in App.tsx. Update
website with Copilot Customization feature card.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-28 17:40:21 +01:00
co-authored by Copilot
parent 75b9ff667a
commit dd203ddde5
5 changed files with 476 additions and 1 deletions
+13
View File
@@ -8,6 +8,7 @@ import { PlanReviewBanner } from '@renderer/components/chat/PlanReviewBanner';
import { McpAuthBanner } from '@renderer/components/chat/McpAuthBanner';
import { UserInputBanner } from '@renderer/components/chat/UserInputBanner';
import { InlineApprovalPill, InlineModelPill, InlineThinkingPill, InlineToolsPill } from '@renderer/components/chat/InlinePills';
import { InlinePromptPill } from '@renderer/components/chat/InlinePromptPill';
import { ThinkingDots } from '@renderer/components/chat/ThinkingDots';
import { getAssistantMessagePhase } from '@renderer/lib/messagePhase';
import type { ApprovalDecision } from '@shared/domain/approval';
@@ -107,6 +108,7 @@ export function ChatPane({
const isComposerDisabled = isUpdatingSessionModelConfig;
const canSubmitInput = hasComposerContent && !isComposerDisabled;
const [pendingAttachments, setPendingAttachments] = useState<ChatMessageAttachment[]>([]);
const promptFiles = useMemo(() => project.customization?.promptFiles ?? [], [project.customization?.promptFiles]);
const toolSelection = useMemo(() => resolveSessionToolingSelection(session), [session]);
const mcpServers = toolingSettings.mcpServers;
@@ -542,6 +544,17 @@ export function ChatPane({
</div>
)}
{/* Prompt files pill */}
{!isScratchpad && promptFiles.length > 0 && (
<div className="mb-2 flex items-center gap-2">
<InlinePromptPill
disabled={isComposerDisabled}
onSubmit={(content) => void onSend(content)}
promptFiles={promptFiles}
/>
</div>
)}
{/* Attachment preview */}
{pendingAttachments.length > 0 && (
<div className="flex flex-wrap gap-2 px-1 pb-2">