From fd7e389809860736e5f17865aa6352dc0337c529 Mon Sep 17 00:00:00 2001 From: dimavedenyapin Date: Sat, 18 Apr 2026 11:18:08 +0700 Subject: [PATCH] Fix Claude skill learning path in workspaces --- src/main/agent-manager.ts | 14 +++++++++----- src/mobile/pages/TaskDetailPage.tsx | 9 +++++++-- .../src/components/tasks/TaskWorkspace.tsx | 9 +++++++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/agent-manager.ts b/src/main/agent-manager.ts index 285ddc40..64b6508f 100644 --- a/src/main/agent-manager.ts +++ b/src/main/agent-manager.ts @@ -553,6 +553,15 @@ export class AgentManager extends EventEmitter { const task = this.db.getTask(taskId) const agent = this.db.getAgent(agentId) const agentConfig = agent?.config + const backendType = (agentConfig?.coding_agent as string) || CodingAgentType.OPENCODE + const isClaudeCode = backendType === CodingAgentType.CLAUDE_CODE + const skillsDir = isClaudeCode + ? join(workspaceDir, '.claude', 'skills') + : join(workspaceDir, '.agents', 'skills') + + // Ensure the backend-specific skill root exists even when no DB skills are + // pre-assigned. Learning-mode sessions can then create/update skills there. + await mkdir(skillsDir, { recursive: true }) // Resolve which skill IDs to use let skillIds: string[] | undefined @@ -572,11 +581,6 @@ export class AgentManager extends EventEmitter { // Claude Code agent: .claude/skills//SKILL.md // Other agents: .agents/skills//SKILL.md if (skills.length > 0) { - const backendType = (agentConfig?.coding_agent as string) || CodingAgentType.OPENCODE - const isClaudeCode = backendType === CodingAgentType.CLAUDE_CODE - const skillsDir = isClaudeCode - ? join(workspaceDir, '.claude', 'skills') - : join(workspaceDir, '.agents', 'skills') for (const skill of skills) { const dir = join(skillsDir, skill.name) await mkdir(dir, { recursive: true }) diff --git a/src/mobile/pages/TaskDetailPage.tsx b/src/mobile/pages/TaskDetailPage.tsx index 5d459e28..13355946 100644 --- a/src/mobile/pages/TaskDetailPage.tsx +++ b/src/mobile/pages/TaskDetailPage.tsx @@ -169,7 +169,12 @@ export function TaskDetailPage({ taskId, onNavigate }: { taskId: string; onNavig // 2. Build the same feedback prompt as desktop const commentPart = comment ? ` Comment: "${comment}".` : '' const today = new Date().toISOString().split('T')[0] - const prompt = `User rated this session ${rating}/5.${commentPart}\n\nReview the session and update skills in .agents/skills/:\n\n**For skills you used:**\nUpdate the YAML frontmatter:\n- confidence: ${rating >= 4 ? '+0.05 (was helpful)' : rating <= 2 ? '-0.10 (was wrong/outdated)' : 'no change'}\n- uses: increment by 1\n- lastUsed: ${today}\n- tags: add relevant keywords if missing\n\n**If you discovered a new reusable pattern:**\nCreate a new skill file.\n\nUpdate existing skills that were helpful or create new ones for patterns worth reusing.` + const feedbackAgent = agents.find((a) => a.id === task.agent_id) + const codingAgent = (feedbackAgent?.config as Record | undefined)?.coding_agent + const skillsDir = (codingAgent === 'claude-code' || codingAgent === 'claude_code') + ? '.claude/skills' + : '.agents/skills' + const prompt = `User rated this session ${rating}/5.${commentPart}\n\nReview the session and update skills in ${skillsDir}/:\n\n**For skills you used:**\nUpdate the YAML frontmatter:\n- confidence: ${rating >= 4 ? '+0.05 (was helpful)' : rating <= 2 ? '-0.10 (was wrong/outdated)' : 'no change'}\n- uses: increment by 1\n- lastUsed: ${today}\n- tags: add relevant keywords if missing\n\n**If you discovered a new reusable pattern:**\nCreate a new skill file.\n\nUpdate existing skills that were helpful or create new ones for patterns worth reusing.` // 3. Resume the session (or start fresh if none) and send feedback prompt try { @@ -193,7 +198,7 @@ export function TaskDetailPage({ taskId, onNavigate }: { taskId: string; onNavig // Fallback: complete the task even if learning session fails await updateTask(task.id, { status: TaskStatus.Completed }) } - }, [task, session, updateTask, initSession]) + }, [task, session, updateTask, initSession, agents]) const handleFeedbackSkip = useCallback(async () => { if (!task) return diff --git a/src/renderer/src/components/tasks/TaskWorkspace.tsx b/src/renderer/src/components/tasks/TaskWorkspace.tsx index 57877cd5..59454b56 100644 --- a/src/renderer/src/components/tasks/TaskWorkspace.tsx +++ b/src/renderer/src/components/tasks/TaskWorkspace.tsx @@ -462,9 +462,14 @@ export function TaskWorkspace({ // Build feedback prompt const commentPart = comment ? ` Comment: "${comment}".` : '' const today = new Date().toISOString().split('T')[0] + const feedbackAgent = agents.find((a) => a.id === task.agent_id) + const codingAgent = feedbackAgent?.config?.coding_agent + const skillsDir = (codingAgent === 'claude-code' || codingAgent === 'claude_code') + ? '.claude/skills' + : '.agents/skills' const prompt = `User rated this session ${rating}/5.${commentPart} -Review the session and update skills in .agents/skills/: +Review the session and update skills in ${skillsDir}/: **For skills you used:** Update the YAML frontmatter: @@ -521,7 +526,7 @@ Update existing skills that were helpful or create new ones for patterns worth r console.error('Failed to send feedback:', error) await taskApi.update(task.id, { status: TaskStatus.ReadyForReview }) } - }, [ensureChatSession, sendMessage, session.sessionId, task?.id]) + }, [agents, ensureChatSession, sendMessage, session.sessionId, task?.agent_id, task?.id]) const handleFeedbackSkip = useCallback(async () => { if (!task?.id) return