-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Add a built-in /init slash command #7381
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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") | ||
| }) | ||
| }) | ||
| }) | ||
| 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[]> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding JSDoc comments to these exported functions to help future developers understand how to add new built-in commands and what each function does. |
||
| 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> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While the current implementation is simple, consider adding error handling for future built-in commands that might need validation or async operations. Could we make these functions more robust? |
||
| 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) | ||
| } | ||
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.
The test coverage is good for basic functionality. Consider adding tests for edge cases like: