diff --git a/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.client.test.tsx b/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.client.test.tsx index 8b919a038..0a1c9d392 100644 --- a/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.client.test.tsx +++ b/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.client.test.tsx @@ -51,6 +51,9 @@ describe('CommandSearch', () => { fireEvent.change(screen.getByPlaceholderText('Search commands...'), { target: { value: 'implement-changes' }, }); + expect( + screen.getByText('Implement, test, and deliver a repository change'), + ).toBeInTheDocument(); fireEvent.click(screen.getByText('/implement-changes')); expect(onSelectCommand).toHaveBeenCalledWith('/implement-changes'); @@ -90,4 +93,21 @@ describe('CommandSearch', () => { expect(screen.getByText('/goal')).toBeInTheDocument(); }); + + it('finds packaged workflows by their purpose', () => { + render( + {}} + onSelectCommand={() => {}} + />, + ); + + fireEvent.change(screen.getByPlaceholderText('Search commands...'), { + target: { value: 'dependency upgrades' }, + }); + + expect(screen.getByText('/update-dependencies')).toBeInTheDocument(); + expect(screen.queryByText('/implement-changes')).not.toBeInTheDocument(); + }); }); diff --git a/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.tsx b/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.tsx index 3de66ef74..117375894 100644 --- a/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.tsx +++ b/apps/web/src/app/(sandbox)/task/[taskId]/CommandSearch.tsx @@ -22,15 +22,71 @@ interface CommandSearchProps { interface SlashCommand { name: string; - description?: string; + description: string; } +const PACKAGED_SKILL_DESCRIPTIONS: Record< + (typeof PACKAGED_SKILL_INVOCATIONS)[number], + string +> = { + 'address-pr-feedback': + 'Address unresolved review threads on the current pull request', + 'agent-browser': 'Navigate, test, or automate a website or web application', + 'capture-visual-proof': + 'Capture screenshots or video evidence for a product change', + 'ci-failure-triage': + 'Investigate and fix the latest default-branch CI failure', + 'create-draft-pr': 'Commit changes and open or update a draft pull request', + 'create-pr': 'Commit changes and open or update a ready pull request', + 'debug-reported-bug': 'Reproduce a reported bug and trace its root cause', + 'dependabot-triage': + 'Review Dependabot alerts and launch safe dependency fixes', + 'codeql-triage': 'Review CodeQL alerts and launch focused security fixes', + doctor: 'Check an environment by running a real task journey', + 'issue-fixer': 'Investigate an issue and post a concrete implementation plan', + 'environment-setup': 'Configure and verify a Roomote task environment', + 'explain-repo-code': + 'Explain repository behavior or architecture without editing files', + 'feature-demo': 'Record a polished browser demo of a product feature', + 'fix-pr': 'Implement requested fixes from pull request feedback', + 'github-management': + 'Manage repository labels, milestones, and GitHub projects', + 'explore-and-act': 'Investigate evidence or act in connected systems', + 'implement-repo-change': 'Legacy alias for implementing repository changes', + 'implement-changes': 'Implement, test, and deliver a repository change', + 'merge-resolution-review': 'Review a completed merge-conflict resolution', + 'merge-resolver': 'Resolve merge conflicts in the current workspace', + 'plan-repo-implementation': + 'Create an implementation plan without changing files', + push: 'Commit and push changes without opening a pull request', + 'push-branch': 'Legacy alias for committing and pushing a branch', + 'resolve-github-pr-merge-conflicts': + 'Merge the base branch and resolve pull request conflicts', + 'review-and-fix': 'Review current changes and fix the issues found', + 'review-code': 'Review current changes without modifying them', + 'sentry-triage': 'Inspect Sentry issues and recommend focused follow-up work', + simplify: 'Simplify recent code changes without changing behavior', + 'update-dependencies': 'Find and apply safe dependency upgrades', + zero: 'Find an external capability when Roomote cannot do the task directly', + 'code-quality-auditor': + 'Audit recent pull requests for code quality follow-up work', + 'fix-sentry-error': 'Investigate and remediate a specific Sentry issue', + 'refactor-code': 'Survey the codebase and plan high-leverage refactors', + 'security-auditor': 'Audit recent pull requests for concrete security issues', + 'triage-better-stack': + 'Scan Better Stack telemetry for operational follow-up work', + 'triage-sentry': 'Scan Sentry for errors and regressions worth fixing', +}; + const AVAILABLE_COMMANDS: SlashCommand[] = [ { name: '/goal', description: 'Keep working toward an objective across multiple turns', }, - ...PACKAGED_SKILL_INVOCATIONS.map((name) => ({ name: `/${name}` })), + ...PACKAGED_SKILL_INVOCATIONS.map((name) => ({ + name: `/${name}`, + description: PACKAGED_SKILL_DESCRIPTIONS[name], + })), ]; export const CommandSearch = ({ @@ -50,7 +106,7 @@ export const CommandSearch = ({ return AVAILABLE_COMMANDS.filter( (command) => command.name.toLowerCase().includes(normalizedQuery) || - command.description?.toLowerCase().includes(normalizedQuery), + command.description.toLowerCase().includes(normalizedQuery), ); }, [query]); @@ -106,11 +162,9 @@ export const CommandSearch = ({ {command.name} - {command.description && ( - - {command.description} - - )} + + {command.description} + ))