-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Add built-in slash commands #6793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import { describe, it, expect } from "vitest" | ||
| import { getBuiltInCommands, getBuiltInCommand, getBuiltInCommandNames } from "../built-in-commands" | ||
|
|
||
| describe("Built-in Commands", () => { | ||
| describe("getBuiltInCommands", () => { | ||
| it("should return all built-in commands", async () => { | ||
| const commands = await getBuiltInCommands() | ||
|
|
||
| expect(commands).toHaveLength(1) | ||
| expect(commands.map((cmd) => cmd.name)).toEqual(expect.arrayContaining(["init"])) | ||
|
|
||
| // Verify all commands have required properties | ||
| commands.forEach((command) => { | ||
| expect(command.name).toBeDefined() | ||
| expect(typeof command.name).toBe("string") | ||
| expect(command.content).toBeDefined() | ||
| expect(typeof command.content).toBe("string") | ||
| expect(command.source).toBe("built-in") | ||
| expect(command.filePath).toMatch(/^<built-in:.+>$/) | ||
| expect(command.description).toBeDefined() | ||
| expect(typeof command.description).toBe("string") | ||
| }) | ||
| }) | ||
|
|
||
| it("should return commands with proper content", async () => { | ||
| const commands = await getBuiltInCommands() | ||
|
|
||
| const initCommand = commands.find((cmd) => cmd.name === "init") | ||
| expect(initCommand).toBeDefined() | ||
| expect(initCommand!.content).toContain("AGENTS.md") | ||
| expect(initCommand!.content).toContain(".roo/rules-") | ||
| expect(initCommand!.description).toBe("Initialize a project with recommended rules and configuration") | ||
| }) | ||
| }) | ||
|
|
||
| describe("getBuiltInCommand", () => { | ||
| it("should return specific built-in command by name", async () => { | ||
| const initCommand = await getBuiltInCommand("init") | ||
|
|
||
| expect(initCommand).toBeDefined() | ||
| expect(initCommand!.name).toBe("init") | ||
| expect(initCommand!.source).toBe("built-in") | ||
| expect(initCommand!.filePath).toBe("<built-in:init>") | ||
| expect(initCommand!.content).toContain("AGENTS.md") | ||
| expect(initCommand!.description).toBe("Initialize a project with recommended rules and configuration") | ||
| }) | ||
|
|
||
| it("should return undefined for non-existent command", async () => { | ||
| const nonExistentCommand = await getBuiltInCommand("non-existent") | ||
| expect(nonExistentCommand).toBeUndefined() | ||
| }) | ||
|
|
||
| it("should handle empty string command name", async () => { | ||
| const emptyCommand = await getBuiltInCommand("") | ||
| expect(emptyCommand).toBeUndefined() | ||
| }) | ||
| }) | ||
|
|
||
| describe("getBuiltInCommandNames", () => { | ||
| it("should return all built-in command names", async () => { | ||
| const names = await getBuiltInCommandNames() | ||
|
|
||
| expect(names).toHaveLength(1) | ||
| expect(names).toEqual(expect.arrayContaining(["init"])) | ||
| // Order doesn't matter since it's based on filesystem order | ||
| expect(names.sort()).toEqual(["init"]) | ||
| }) | ||
|
|
||
| it("should return array of strings", async () => { | ||
| const names = await getBuiltInCommandNames() | ||
|
|
||
| names.forEach((name) => { | ||
| expect(typeof name).toBe("string") | ||
| expect(name.length).toBeGreaterThan(0) | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| describe("Command Content Validation", () => { | ||
| it("init command should have comprehensive content", async () => { | ||
| const command = await getBuiltInCommand("init") | ||
| const content = command!.content | ||
|
|
||
| // Should contain key sections | ||
| expect(content).toContain("Please analyze this codebase") | ||
| expect(content).toContain("Build/lint/test commands") | ||
| expect(content).toContain("Code style guidelines") | ||
| expect(content).toContain("mode-specific rule directories") | ||
| expect(content).toContain("refer to the system prompt") | ||
|
|
||
| // Should mention important concepts | ||
| expect(content).toContain("AGENTS.md") | ||
| expect(content).toContain(".roo/rules-") | ||
| expect(content).toContain("four core modes") | ||
| expect(content).toContain("mode-specific AGENTS.md files") | ||
| }) | ||
| }) | ||
| }) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| import { Command } from "./commands" | ||
|
|
||
| interface BuiltInCommandDefinition { | ||
| name: string | ||
| description: string | ||
| argumentHint?: string | ||
| content: string | ||
| } | ||
|
|
||
| const BUILT_IN_COMMANDS: Record<string, BuiltInCommandDefinition> = { | ||
| init: { | ||
| name: "init", | ||
| description: "Initialize a project with recommended rules and configuration", | ||
| content: `Please analyze this codebase and create an AGENTS.md file containing: | ||
| 1. Build/lint/test commands - especially for running a single test | ||
| 2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc. | ||
|
|
||
| Usage notes: | ||
| - The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long. | ||
| - If there's already an AGENTS.md, improve it. | ||
| - If there are Claude Code rules (in CLAUDE.md), Cursor rules (in .cursor/rules/ or .cursorrules), or Copilot rules (in .github/copilot-instructions.md), make sure to include them. | ||
| - Be sure to prefix the file with the following text: | ||
|
|
||
| # AGENTS.md | ||
|
|
||
| This file provides guidance to agents when working with code in this repository. | ||
|
|
||
| Additionally, please: | ||
| 1. **Create mode-specific rule directories** - Create directory structures for the four core modes: \`.roo/rules-code/\`, \`.roo/rules-ask/\`, \`.roo/rules-architect/\`, and \`.roo/rules-debug/\` | ||
| 2. **Create mode-specific AGENTS.md files** - Within each of these four mode directories, research and then create an AGENTS.md file with rules specific to that mode's purpose and capabilities. These rules should provide additive context and not just repeat the mode definitions. Only include rules that you have high confidence are accurate, valuable, and non-obvious. | ||
|
|
||
| **For the complete list of available modes with detailed descriptions, refer to the system prompt.** The system prompt contains comprehensive information about each mode's purpose, when to use it, and its specific capabilities. | ||
|
|
||
| Example structure with specific instructions: | ||
|
|
||
| \\\`\\\`\\\` | ||
| AGENTS.md # General project guidance | ||
| .roo/ | ||
| ├── rules-code/ | ||
| │ └── AGENTS.md # Code mode specific instructions | ||
| ├── rules-debug/ | ||
| │ └── AGENTS.md # Debug mode specific instructions | ||
| ├── rules-ask/ | ||
| │ └── AGENTS.md # Ask mode specific instructions | ||
| └── rules-architect/ | ||
| └── AGENTS.md # Architect mode specific instructions | ||
| \\\`\\\`\\\` | ||
|
|
||
| **Example project-specific instructions:** | ||
|
|
||
| **\`.roo/rules-code/AGENTS.md\`** - Project-specific coding rules: | ||
| \\\`\\\`\\\` | ||
| # Project Coding Rules | ||
|
|
||
| - All API calls must use the retry mechanism in src/api/providers/utils/ | ||
| - UI components should use Tailwind CSS classes, not inline styles | ||
| - New providers must implement the Provider interface in packages/types/src/ | ||
| - Database queries must use the query builder in packages/evals/src/db/queries/ | ||
| - Always use safeWriteJson() from src/utils/ instead of JSON.stringify for file writes | ||
| - Test coverage required for all new features in src/ and webview-ui/ | ||
| \\\`\\\`\\\` | ||
|
|
||
| **\`.roo/rules-debug/AGENTS.md\`** - Project-specific debugging approaches: | ||
| \\\`\\\`\\\` | ||
| # Project Debug Rules | ||
|
|
||
| - Check VSCode extension logs in the Debug Console | ||
| - For webview issues, inspect the webview dev tools via Command Palette | ||
| - Provider issues: check src/api/providers/__tests__/ for similar test patterns | ||
| - Database issues: run migrations in packages/evals/src/db/migrations/ | ||
| - IPC communication issues: review packages/ipc/src/ message patterns | ||
| - Always reproduce in both development and production extension builds | ||
| \\\`\\\`\\\` | ||
|
|
||
| **\`.roo/rules-ask/AGENTS.md\`** - Project-specific explanation context: | ||
| \\\`\\\`\\\` | ||
| # Project Documentation Rules | ||
|
|
||
| - Reference the monorepo structure: src/ (VSCode extension), apps/ (web apps), packages/ (shared) | ||
| - Explain provider patterns by referencing existing ones in src/api/providers/ | ||
| - For UI questions, reference webview-ui/ React components and their patterns | ||
| - Point to package.json scripts for build/test commands | ||
| - Reference locales/ for i18n patterns when discussing translations | ||
| - Always mention the VSCode webview architecture when discussing UI | ||
| \\\`\\\`\\\` | ||
|
|
||
| **\`.roo/rules-architect/AGENTS.md\`** - Project-specific architectural considerations: | ||
| \\\`\\\`\\\` | ||
| # Project Architecture Rules | ||
|
|
||
| - New features must work within VSCode extension + webview architecture | ||
| - Provider implementations must be stateless and cacheable | ||
| - UI state management uses React hooks, not external state libraries | ||
| - Database schema changes require migrations in packages/evals/src/db/migrations/ | ||
| - New packages must follow the existing monorepo structure in packages/ | ||
| - API changes must maintain backward compatibility with existing provider contracts | ||
| \\\`\\\`\\\` | ||
|
|
||
| This structure provides both general project guidance and specialized instructions for the four core modes' specific domains and workflows. | ||
| `, | ||
| }, | ||
| } | ||
|
|
||
| /** | ||
| * Get all built-in commands as Command objects | ||
| */ | ||
| export async function getBuiltInCommands(): Promise<Command[]> { | ||
| return Object.values(BUILT_IN_COMMANDS).map((cmd) => ({ | ||
| name: cmd.name, | ||
| content: cmd.content, | ||
| source: "built-in" as const, | ||
| filePath: `<built-in:${cmd.name}>`, | ||
| description: cmd.description, | ||
| argumentHint: cmd.argumentHint, | ||
| })) | ||
| } | ||
|
|
||
| /** | ||
| * Get a specific built-in command by name | ||
| */ | ||
| export async function getBuiltInCommand(name: string): Promise<Command | undefined> { | ||
| const cmd = BUILT_IN_COMMANDS[name] | ||
| if (!cmd) return undefined | ||
|
|
||
| return { | ||
| name: cmd.name, | ||
| content: cmd.content, | ||
| source: "built-in" as const, | ||
| filePath: `<built-in:${name}>`, | ||
| description: cmd.description, | ||
| argumentHint: cmd.argumentHint, | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Get names of all built-in commands | ||
| */ | ||
| export async function getBuiltInCommandNames(): Promise<string[]> { | ||
| return Object.keys(BUILT_IN_COMMANDS) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests will fail because they expect content that doesn't exist in the actual command files. The test expectations don't match the current 'TBD' placeholders. Should these tests be marked as pending/skipped until the actual content is implemented?