feat: enhance team provisioning prompts and improve dashboard interactivity

- Updated the provisioning prompts in TeamProvisioningService to include project name alongside team and lead information, enhancing clarity for non-interactive CLI sessions.
- Refactored the RepositoryCard component in DashboardView to replace button with a div for improved accessibility and keyboard navigation, allowing users to open project paths more intuitively.
- Modified ChangeReviewDialog and ContinuousScrollView components to track discard actions using a record of counters per file, improving state management during file reviews.
This commit is contained in:
iliya 2026-02-26 13:09:25 +02:00
parent 0d0786602f
commit 50efe267e4
4 changed files with 22 additions and 12 deletions

View file

@ -417,8 +417,11 @@ function buildProvisioningPrompt(request: TeamCreateRequest): string {
const leadName =
request.members.find((m) => m.role?.toLowerCase().includes('lead'))?.name || 'team-lead';
const teamCtlOps = buildTeamCtlOpsInstructions(request.teamName, leadName);
const projectName = path.basename(request.cwd);
return `You are running in a non-interactive CLI session. Do not ask questions. Do everything in a single turn.
return `Team Start [Agent Team: "${request.teamName}" | Project: "${projectName}" | Lead: "${leadName}"]
You are running in a non-interactive CLI session. Do not ask questions. Do everything in a single turn.
You are "${leadName}", the team lead.
Goal: Provision a Claude Code agent team with live teammates.
@ -494,6 +497,7 @@ function buildLaunchPrompt(
const leadName = members.find((m) => m.role?.toLowerCase().includes('lead'))?.name || 'team-lead';
const teamCtlOps = buildTeamCtlOpsInstructions(request.teamName, leadName);
const projectName = path.basename(request.cwd);
// Build per-member task snapshots to include in each teammate's spawn prompt
const memberTaskBlocks = new Map<string, string>();
@ -522,7 +526,9 @@ function buildLaunchPrompt(
})
.join('\n\n');
return `You are running in a non-interactive CLI session. Do not ask questions. Do everything in a single turn.
return `Team Start [Agent Team: "${request.teamName}" | Project: "${projectName}" | Lead: "${leadName}"]
You are running in a non-interactive CLI session. Do not ask questions. Do everything in a single turn.
You are "${leadName}", the team lead.
Goal: Reconnect with existing team "${request.teamName}" and resume pending work.

View file

@ -180,15 +180,19 @@ const RepositoryCard = ({
</div>
{/* Project path - monospace, muted, clickable to open in file manager */}
<button
type="button"
<div
role="button"
tabIndex={0}
onClick={handleOpenPath}
className="flex w-full min-w-0 items-center gap-1 truncate text-left font-mono text-[10px] text-text-muted transition-colors hover:text-text-secondary"
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') handleOpenPath(e as unknown as React.MouseEvent);
}}
className="flex w-full min-w-0 cursor-pointer items-center gap-1 truncate text-left font-mono text-[10px] text-text-muted transition-colors hover:text-text-secondary"
title={`Open in file manager: ${projectPath}`}
>
<FolderOpen className="size-3 shrink-0" />
<span className="truncate">{formattedPath}</span>
</button>
</div>
{/* Git branch / worktree info */}
{mainBranch ? (

View file

@ -80,7 +80,7 @@ export const ChangeReviewDialog = ({
const [activeFilePath, setActiveFilePath] = useState<string | null>(null);
const [autoViewed, setAutoViewed] = useState(true);
const [timelineOpen, setTimelineOpen] = useState(false);
const [discardCounter, setDiscardCounter] = useState(0);
const [discardCounters, setDiscardCounters] = useState<Record<string, number>>({});
// EditorView map for all visible file editors
const editorViewMapRef = useRef(new Map<string, EditorView>());
@ -213,7 +213,7 @@ export const ChangeReviewDialog = ({
const handleDiscardFile = useCallback(
(filePath: string) => {
discardFileEdits(filePath);
setDiscardCounter((c) => c + 1);
setDiscardCounters((prev) => ({ ...prev, [filePath]: (prev[filePath] ?? 0) + 1 }));
},
[discardFileEdits]
);
@ -544,7 +544,7 @@ export const ChangeReviewDialog = ({
collapseUnchanged={collapseUnchanged}
applying={applying}
autoViewed={autoViewed}
discardCounter={discardCounter}
discardCounters={discardCounters}
onHunkAccepted={handleHunkAccepted}
onHunkRejected={handleHunkRejected}
onFullyViewed={handleFullyViewed}

View file

@ -23,7 +23,7 @@ interface ContinuousScrollViewProps {
collapseUnchanged: boolean;
applying: boolean;
autoViewed: boolean;
discardCounter: number;
discardCounters: Record<string, number>;
onHunkAccepted: (filePath: string, hunkIndex: number) => void;
onHunkRejected: (filePath: string, hunkIndex: number) => void;
onFullyViewed: (filePath: string) => void;
@ -54,7 +54,7 @@ export const ContinuousScrollView = ({
collapseUnchanged,
applying,
autoViewed,
discardCounter,
discardCounters,
onHunkAccepted,
onHunkRejected,
onFullyViewed,
@ -198,7 +198,7 @@ export const ContinuousScrollView = ({
onFullyViewed={onFullyViewed}
onContentChanged={onContentChanged}
onEditorViewReady={handleEditorViewReady}
discardCounter={discardCounter}
discardCounter={discardCounters[filePath] ?? 0}
autoViewed={autoViewed}
isViewed={isViewed}
/>