Compare commits

..

2 commits

Author SHA1 Message Date
Matt Rubens
1d70f95ae8
Update CHANGELOG.md 2025-09-05 00:05:53 -04:00
github-actions[bot]
a7fbccfab9 changeset version bump 2025-09-05 04:01:30 +00:00
2997 changed files with 138819 additions and 238848 deletions

View file

@ -1,9 +1,9 @@
const getReleaseLine = async (changeset) => {
const lines = changeset.summary
const [firstLine] = changeset.summary
.split("\n")
.map((l) => l.trim())
.filter(Boolean)
return lines.map((line) => (line.startsWith("- ") ? line : `- ${line}`)).join("\n")
return `- ${firstLine}`
}
const getDependencyReleaseLine = async () => {

View file

@ -7,5 +7,5 @@
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@roo-code/cli"]
"ignore": []
}

View file

@ -1,15 +0,0 @@
---
"roo-cline": minor
---
- Remove: Roo Code Cloud and eval infrastructure from the extension, CLI, workflows, and package surfaces so the release is focused on the standalone extension (PR #12328 by @mrubens)
- Remove: All telemetry collection and analytics plumbing across the extension, website, shared types, provider flows, and related tests (PR #12324 by @mrubens)
- Remove: MDM and organization membership enforcement, including host wiring, webview state, user-facing messages, and locale strings (PR #12323 by @mrubens)
- Remove: The MCP marketplace, marketplace services, webview marketplace UI, package contributions, and related localized copy (PR #12326 by @mrubens)
- Update: Extension-facing support, diagnostics, and announcement content for the final Roo Code release, including GitHub help paths and links to Roomote, ZooCode, and Cline (PR #12341 by @brunobergher)
- Add: A cleaned docs app with GitHub Pages deployment support (PR #12344 by @brunobergher)
- Fix: Configure the docs GitHub Pages base URL so deployed assets and canonical paths load correctly under the repository Pages path (PR #12370 by @mrubens)
- Update: Point docs links in the root README, localized READMEs, and web app copy to the current GitHub Pages docs URL (PR #12371 by @mrubens)
- Remove: Stale `roocode.github.io` docs references, including the old CNAME and outdated docs README and robots.txt URLs (PR #12372 by @mrubens)
- Update: The website to focus almost entirely on the Roo Code extension and remove cloud, team, enterprise, provider, pricing, Slack, and Linear product pages (PR #12180 by @brunobergher)
- Remove: Contributor, community, social channel, and tutorial references from README files, docs, website copy, issue templates, and workflows (PR #12347 by @brunobergher)

View file

@ -76,18 +76,14 @@ src/node_modules
!pnpm-workspace.yaml
!scripts/bootstrap.mjs
!apps/web-evals/
!apps/cli/
!src/
!webview-ui/
!packages/evals/.docker/entrypoints/runner.sh
!packages/build/
!packages/config-eslint/
!packages/config-typescript/
!packages/core/
!packages/evals/
!packages/ipc/
!packages/telemetry/
!packages/types/
!packages/vscode-shim/
!packages/cloud/
!locales/

2
.github/CODEOWNERS vendored
View file

@ -1,2 +1,2 @@
# These owners will be the default owners for everything in the repo
* @mrubens @cte @jr @hannesrudolph @daniel-lxs
* @mrubens @cte @jr

View file

@ -1,66 +1,12 @@
name: Bug Report
description: Report a broken behavior in plain language with a minimal reproduction
description: Clearly report a bug with detailed repro steps
labels: ["bug"]
title: "[BUG] "
body:
- type: markdown
attributes:
value: |
Thank you for your report! Please search existing issues first:
https://github.com/RooCodeInc/Roo-Code/issues
- type: textarea
id: problem
attributes:
label: Problem (one or two sentences)
description: Describe what went wrong in plain language.
placeholder: 'Example: "Expected the task to start, but nothing happened and no message appeared."'
validations:
required: true
- type: textarea
id: context
attributes:
label: Context (who is affected and when)
description: Who sees this and in what situation? Keep it non-technical.
placeholder: 'Example: "Happens to new users when starting a run from the New Run page with dark theme enabled."'
validations:
required: true
- type: textarea
id: steps
attributes:
label: Reproduction steps
description: Provide clear, numbered steps so we can reproduce.
placeholder: |
1) Environment/setup (OS, extension version, relevant settings)
2) Exact actions (clicks, inputs, commands)
3) What you observed after each step
validations:
required: true
- type: input
id: expected
attributes:
label: Expected result
placeholder: e.g., "The task starts and shows progress."
validations:
required: true
- type: input
id: actual
attributes:
label: Actual result
placeholder: e.g., "The button appears disabled and no progress is shown."
validations:
required: true
- type: textarea
id: variations
attributes:
label: Variations tried (optional)
description: Different browsers, devices, providers, or settings you tried.
placeholder: e.g., "Tried Chrome/Firefox, disabling dark theme, switching providers."
**Thanks for your report!** Please check existing issues first:
👉 https://github.com/RooCodeInc/Roo-Code/issues
- type: input
id: version
@ -73,17 +19,19 @@ body:
- type: dropdown
id: provider
attributes:
label: API Provider (optional)
label: API Provider
options:
- Anthropic
- Amazon Bedrock
- AWS Bedrock
- Chutes AI
- DeepSeek
- Featherless AI
- Fireworks AI
- Glama
- Google Gemini
- Google Vertex AI
- Groq
- Human Relay Provider
- LiteLLM
- LM Studio
- Mistral AI
@ -97,23 +45,57 @@ body:
- VS Code Language Model API
- xAI (Grok)
- Not Applicable / Other
validations:
required: true
- type: input
id: model
attributes:
label: Model Used (optional)
label: Model Used
description: Exact model name (e.g., Claude 3.7 Sonnet). Use N/A if irrelevant.
validations:
required: true
- type: textarea
id: roo-code-tasks
attributes:
label: Roo Code Task Links (optional)
description: If you have any publicly shared Roo Code task links that demonstrate the issue, paste them here.
label: Roo Code Task Links (Optional)
description: |
If you have any publicly shared task links that demonstrate the issue, please paste them here.
This helps maintainers understand the context.
Example: https://app.roocode.com/share/task-id
placeholder: Paste your Roo Code share links here, one per line
- type: textarea
id: steps
attributes:
label: 🔁 Steps to Reproduce
description: |
Help us see what you saw. Give clear, numbered steps:
1. Setup (OS, extension version, settings)
2. Exact actions (clicks, input, files, commands)
3. What happened after each step
Think like you're writing a recipe. Without this, we can't reproduce the issue.
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: 💥 Outcome Summary
description: |
Recap what went wrong in one or two lines.
Example: "Expected code to run, but got an empty response and no error."
placeholder: Expected ___, but got ___.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant logs or errors (optional)
description: Paste relevant output or errors. Use triple backticks (```) for formatting.
label: 📄 Relevant Logs or Errors (Optional)
description: Paste API logs, terminal output, or errors here. Use triple backticks (```) for code formatting.
render: shell

View file

@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Feature Request
url: https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests
about: Share and vote on feature requests for Roo Code
- name: Leave a Review
url: https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline&ssr=false#review-details
about: Enjoying Roo Code? Leave a review here!

View file

@ -1,47 +1,71 @@
name: Enhancement Request
description: Propose an improvement in plain language focused on user benefit
labels: ["enhancement"]
title: "[ENHANCEMENT] "
name: Detailed Feature Proposal
description: Report a specific problem that needs solving in Roo Code
labels: ["proposal", "enhancement"]
body:
- type: markdown
attributes:
value: |
Thank you for helping improve Roo Code!
Please focus on the problem and the desired behavior in plain language.
**Thank you for submitting a feature request for Roo Code!**
This template helps you describe problems that need solving. Focus on the problem - the Roo team will work to design solutions unless you want to contribute the implementation yourself.
**Quality over speed:** We prefer detailed, clear problem descriptions over quick ones. Vague requests often get closed or require multiple rounds of clarification, which wastes everyone's time.
**Before submitting:**
- Search existing [Issues](https://github.com/RooCodeInc/Roo-Code/issues) and [Discussions](https://github.com/RooCodeInc/Roo-Code/discussions) to avoid duplicates
- For general ideas, use [GitHub Discussions](https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests) instead of this template.
- type: markdown
attributes:
value: |
## ❌ Common mistakes that lead to request rejection:
- **Vague problem descriptions:** "UI is bad" -> Should be: "Submit button is invisible on dark theme"
- **Missing user impact:** "This would be cool" -> Should explain who benefits and how
- **No specific context:** Describe exactly when and how the problem occurs
- type: textarea
id: problem
id: problem-description
attributes:
label: Problem (one or two sentences)
description: What problem are users facing?
placeholder: e.g., "Users often click Copy Run by mistake and duplicate runs unintentionally."
label: What specific problem does this solve?
description: |
**Be concrete and detailed.** Explain the problem from a user's perspective.
✅ **Good examples (specific, clear impact):**
- "When running large tasks, users wait 5+ minutes because tasks execute sequentially instead of in parallel, blocking productivity"
- "AI can only read one file per request, forcing users to make multiple requests for multi-file projects, increasing wait time from 30s to 5+ minutes"
- "Dark theme users can't see the submit button because it uses white text on light grey background"
❌ **Poor examples (vague, unclear impact):**
- "The UI looks weird" -> What specifically looks weird? On which screen? What's the impact?
- "System prompt is not good" -> What's wrong with it? What behaviour does it cause? What should it do instead?
- "Performance could be better" -> Where? How slow is it currently? What's the user impact?
**Your problem description should answer:**
- Who is affected? (all users, specific user types, etc.)
- When does this happen? (specific scenarios/steps)
- What's the current behaviour vs expected behaviour?
- What's the impact? (time wasted, errors caused, etc.)
placeholder: Be specific about the problem, who it affects, and the impact. Avoid generic statements like "it's slow" or "it's confusing."
validations:
required: true
- type: textarea
id: context
attributes:
label: Context (who is affected and when)
description: Who encounters this and in what situation?
placeholder: e.g., "Happens when browsing the Runs list; most visible for new users."
validations:
required: true
- type: textarea
id: desired
id: additional-context
attributes:
label: Desired behavior (conceptual, not technical)
description: Describe what should happen in simple terms.
placeholder: e.g., "Ask for confirmation before copying a run."
validations:
required: true
label: Additional context (optional)
description: Mockups, screenshots, links, user quotes, or other relevant information that supports your proposal.
- type: textarea
id: constraints
id: roo-code-tasks
attributes:
label: Constraints / preferences (optional)
description: Any considerations like performance, accessibility, or UX expectations.
placeholder: e.g., "Keep it quick and unobtrusive; keyboard accessible."
label: Roo Code Task Links (Optional)
description: |
If you used Roo Code to explore this feature request or develop solutions, share the public task links here.
This helps maintainers understand the context and any exploration you've done.
Example: https://app.roocode.com/share/task-id
placeholder: Paste your Roo Code share links here, one per line
- type: checkboxes
id: checklist
@ -50,42 +74,128 @@ body:
options:
- label: I've searched existing Issues and Discussions for duplicates
required: true
- label: This describes a specific problem with clear context and impact
- label: This describes a specific problem with clear impact and context
required: true
- type: textarea
id: roo-code-tasks
attributes:
label: Roo Code Task Links (optional)
description: If you explored this with Roo Code, share public task links for context.
placeholder: Paste your Roo Code share links here, one per line
- type: markdown
attributes:
value: |
---
Optional: You can stop here if you're just proposing the improvement.
## 🛠️ **Optional: Contributing & Technical Analysis**
**🎯 Just reporting a problem?** You can click "Submit new issue" right now! The sections below are only needed if you want to contribute a solution via pull request.
**⚠️ Only continue if you want to:**
- Propose a specific solution design
- Implement the feature yourself via pull request
- Provide technical analysis to help with implementation
**For contributors who continue:**
- A maintainer (especially @hannesrudolph) will review this proposal. **Do not start implementation until approved and assigned.** We're a small team with limited resources, so every code addition needs careful consideration. We're always happy to receive clear, actionable proposals though!
- Join [Discord](https://discord.gg/roocode) and DM **Hannes Rudolph** (`hrudolph`) for guidance on implementation
- Check our [Roadmap](https://github.com/orgs/RooCodeInc/projects/1/views/1?query=sort%3Aupdated-desc+is%3Aopen&filterQuery=is%3Aissue%2Copen%2Cclosed+label%3A%22feature+request%22+status%3A%22Issue+%5BUnassigned%5D%22%2C%22Issue+%5BIn+Progress%5D%22) to see open feature requests ready to be implemented or currently being worked on
- type: textarea
id: acceptance-criteria
- type: checkboxes
id: willingness-to-contribute
attributes:
label: Acceptance criteria (optional)
description: Define what “working” looks like with specific, testable outcomes.
placeholder: |
Given [context]
When [user action]
Then [expected result]
And [additional expectations]
But [what should NOT happen]
label: Interested in implementing this?
description: |
**Important:** If you check "Yes" below, the technical sections become REQUIRED.
We need detailed technical analysis from contributors to ensure quality implementation.
options:
- label: Yes, I'd like to help implement this feature
required: false
- type: checkboxes
id: implementation-approval
attributes:
label: Implementation requirements
options:
- label: I understand this needs approval before implementation begins
required: false
- type: textarea
id: proposed-solution
attributes:
label: Proposed approach (optional)
description: If you have an idea, describe it briefly in plain language.
label: How should this be solved? (REQUIRED if contributing, optional otherwise)
description: |
**If you want to implement this feature, this section is REQUIRED.**
**Describe your solution in detail.** Explain not just what to build, but how it should work.
✅ **Good examples:**
- "Add parallel task execution: Allow up to 3 tasks to run simultaneously with a queue system for additional tasks. Show progress for each active task in the UI."
- "Enable multi-file AI processing: Modify the request handler to accept multiple files in a single request and process them together, reducing round trips."
- "Fix button contrast: Change submit button to use primary colour on dark theme (white text on blue background) instead of current grey."
❌ **Poor examples:**
- "Make it faster" -> How? What specific changes?
- "Improve the UI" -> Which part? What specific improvements?
- "Fix the prompt" -> What should the new prompt do differently?
**Your solution should explain:**
- What exactly will change?
- How will users interact with it?
- What will the new behaviour look like?
placeholder: Describe the specific changes and how they will work. Include user interaction details if relevant.
- type: textarea
id: risks
id: acceptance-criteria
attributes:
label: Trade-offs / risks (optional)
description: Potential downsides or alternatives considered.
label: How will we know it works? (Acceptance Criteria - REQUIRED if contributing, optional otherwise)
description: |
**If you want to implement this feature, this section is REQUIRED.**
**This is crucial - don't skip it.** Define what "working" looks like with specific, testable criteria.
**Format suggestion:**
```
Given [context/situation]
When [user action]
Then [expected result]
And [additional expectations]
But [what should NOT happen]
```
**Example:**
```
Given I have 5 large tasks to run
When I start all of them
Then they execute in parallel (max 3 at once, can be configured)
And I see progress for each active task
And queued tasks show "waiting" status
But the UI doesn't freeze or become unresponsive
```
placeholder: |
Define specific, testable criteria. What should users be able to do? What should happen? What should NOT happen?
Use the Given/When/Then format above or your own clear structure.
- type: textarea
id: technical-considerations
attributes:
label: Technical considerations (REQUIRED if contributing, optional otherwise)
description: |
**If you want to implement this feature, this section is REQUIRED.**
Share technical insights that could help planning:
- Implementation approach or architecture changes
- Performance implications
- Compatibility concerns
- Systems that might be affected
- Potential blockers you can foresee
placeholder: e.g., "Will need to refactor task manager", "Could impact memory usage on large files", "Requires a large portion of code to be rewritten"
- type: textarea
id: trade-offs-and-risks
attributes:
label: Trade-offs and risks (REQUIRED if contributing, optional otherwise)
description: |
**If you want to implement this feature, this section is REQUIRED.**
What could go wrong or what alternatives did you consider?
- Alternative approaches and why you chose this one
- Potential negative impacts (performance, UX, etc.)
- Breaking changes or migration concerns
- Edge cases that need careful handling
placeholder: 'e.g., "Alternative: use library X but it is 500KB larger", "Risk: might slow older devices", "Breaking: changes API response format"'

75
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,75 @@
<!--
Thank you for contributing to Roo Code!
Before submitting your PR, please ensure:
- It's linked to an approved GitHub Issue.
- You've reviewed our [Contributing Guidelines](../CONTRIBUTING.md).
-->
### Related GitHub Issue
<!-- Every PR MUST be linked to an approved issue. -->
Closes: # <!-- Replace with the issue number, e.g., Closes: #123 -->
### Roo Code Task Context (Optional)
<!--
If you used Roo Code to help create this PR, you can share public task links here.
This helps reviewers understand your development process and provides additional context.
Example: https://app.roocode.com/share/task-id
-->
### Description
<!--
Briefly summarize the changes in this PR and how they address the linked issue.
The issue should cover the "what" and "why"; this section should focus on:
- The "how": key implementation details, design choices, or trade-offs made.
- Anything specific reviewers should pay attention to in this PR.
-->
### Test Procedure
<!--
Detail the steps to test your changes. This helps reviewers verify your work.
- How did you test this specific implementation? (e.g., unit tests, manual testing steps)
- How can reviewers reproduce your tests or verify the fix/feature?
- Include relevant testing environment details if applicable.
-->
### Pre-Submission Checklist
<!-- Go through this checklist before marking your PR as ready for review. -->
- [ ] **Issue Linked**: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
- [ ] **Scope**: My changes are focused on the linked issue (one major feature/fix per PR).
- [ ] **Self-Review**: I have performed a thorough self-review of my code.
- [ ] **Testing**: New and/or updated tests have been added to cover my changes (if applicable).
- [ ] **Documentation Impact**: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
- [ ] **Contribution Guidelines**: I have read and agree to the [Contributor Guidelines](/CONTRIBUTING.md).
### Screenshots / Videos
<!--
For UI changes, please provide before-and-after screenshots or a short video of the *actual results*.
This greatly helps in understanding the visual impact of your changes.
-->
### Documentation Updates
<!--
Does this PR necessitate updates to user-facing documentation?
- [ ] No documentation updates are required.
- [ ] Yes, documentation updates are required. (Please describe what needs to be updated or link to a PR in the docs repository).
-->
### Additional Notes
<!-- Add any other context, questions, or information for reviewers here. -->
### Get in Touch
<!--
Please provide your Discord username for reviewers or maintainers to reach you if they have questions about your PR
-->

View file

@ -1,394 +0,0 @@
name: CLI Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.1.0). Leave empty to use package.json version.'
required: false
type: string
dry_run:
description: 'Dry run (build and test but do not create release).'
required: false
type: boolean
default: false
jobs:
# Build CLI for each platform.
build:
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
platform: darwin-arm64
runs-on: macos-latest
- os: ubuntu-latest
platform: linux-x64
runs-on: ubuntu-latest
- os: ubuntu-24.04-arm
platform: linux-arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
- name: Get version
id: version
run: |
if [ -n "${{ inputs.version }}" ]; then
VERSION="${{ inputs.version }}"
else
VERSION=$(node -p "require('./apps/cli/package.json').version")
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=cli-v$VERSION" >> $GITHUB_OUTPUT
echo "Using version: $VERSION"
- name: Build extension bundle
run: pnpm bundle
- name: Build CLI
run: pnpm --filter @roo-code/cli build
- name: Create release tarball
id: tarball
env:
VERSION: ${{ steps.version.outputs.version }}
PLATFORM: ${{ matrix.platform }}
run: |
RELEASE_DIR="roo-cli-${PLATFORM}"
TARBALL="roo-cli-${PLATFORM}.tar.gz"
# Clean up any previous build.
rm -rf "$RELEASE_DIR"
rm -f "$TARBALL"
# Create directory structure.
mkdir -p "$RELEASE_DIR/bin"
mkdir -p "$RELEASE_DIR/lib"
mkdir -p "$RELEASE_DIR/extension"
# Copy CLI dist files.
echo "Copying CLI files..."
cp -r apps/cli/dist/* "$RELEASE_DIR/lib/"
# Create package.json for npm install.
echo "Creating package.json..."
node -e "
const pkg = require('./apps/cli/package.json');
const newPkg = {
name: '@roo-code/cli',
version: '$VERSION',
type: 'module',
dependencies: {
'@inkjs/ui': pkg.dependencies['@inkjs/ui'],
'@trpc/client': pkg.dependencies['@trpc/client'],
'commander': pkg.dependencies.commander,
'fuzzysort': pkg.dependencies.fuzzysort,
'ink': pkg.dependencies.ink,
'p-wait-for': pkg.dependencies['p-wait-for'],
'react': pkg.dependencies.react,
'superjson': pkg.dependencies.superjson,
'zustand': pkg.dependencies.zustand
}
};
console.log(JSON.stringify(newPkg, null, 2));
" > "$RELEASE_DIR/package.json"
# Copy extension bundle.
echo "Copying extension bundle..."
cp -r src/dist/* "$RELEASE_DIR/extension/"
# Add package.json to extension directory for CommonJS.
echo '{"type": "commonjs"}' > "$RELEASE_DIR/extension/package.json"
# Find and copy ripgrep binary.
echo "Looking for ripgrep binary..."
RIPGREP_PATH=$(find node_modules -path "*/@vscode/ripgrep/bin/rg" -type f 2>/dev/null | head -1)
if [ -n "$RIPGREP_PATH" ] && [ -f "$RIPGREP_PATH" ]; then
echo "Found ripgrep at: $RIPGREP_PATH"
mkdir -p "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin"
cp "$RIPGREP_PATH" "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin/"
chmod +x "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin/rg"
mkdir -p "$RELEASE_DIR/bin"
cp "$RIPGREP_PATH" "$RELEASE_DIR/bin/"
chmod +x "$RELEASE_DIR/bin/rg"
else
echo "Warning: ripgrep binary not found"
fi
# Create the wrapper script
echo "Creating wrapper script..."
printf '%s\n' '#!/usr/bin/env node' \
'' \
"import { fileURLToPath } from 'url';" \
"import { dirname, join } from 'path';" \
'' \
'const __filename = fileURLToPath(import.meta.url);' \
'const __dirname = dirname(__filename);' \
'' \
'// Set environment variables for the CLI' \
"process.env.ROO_CLI_ROOT = join(__dirname, '..');" \
"process.env.ROO_EXTENSION_PATH = join(__dirname, '..', 'extension');" \
"process.env.ROO_RIPGREP_PATH = join(__dirname, 'rg');" \
'' \
'// Import and run the actual CLI' \
"await import(join(__dirname, '..', 'lib', 'index.js'));" \
> "$RELEASE_DIR/bin/roo"
chmod +x "$RELEASE_DIR/bin/roo"
# Create empty .env file.
touch "$RELEASE_DIR/.env"
# Create tarball.
echo "Creating tarball..."
tar -czvf "$TARBALL" "$RELEASE_DIR"
# Clean up release directory.
rm -rf "$RELEASE_DIR"
# Create checksum.
if command -v sha256sum &> /dev/null; then
sha256sum "$TARBALL" > "${TARBALL}.sha256"
elif command -v shasum &> /dev/null; then
shasum -a 256 "$TARBALL" > "${TARBALL}.sha256"
fi
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
echo "Created: $TARBALL"
ls -la "$TARBALL"
- name: Verify tarball
env:
PLATFORM: ${{ matrix.platform }}
run: |
TARBALL="roo-cli-${PLATFORM}.tar.gz"
# Create temp directory for verification.
VERIFY_DIR=$(mktemp -d)
# Extract and verify structure.
tar -xzf "$TARBALL" -C "$VERIFY_DIR"
echo "Verifying tarball contents..."
ls -la "$VERIFY_DIR/roo-cli-${PLATFORM}/"
# Check required files exist.
test -f "$VERIFY_DIR/roo-cli-${PLATFORM}/bin/roo" || { echo "Missing bin/roo"; exit 1; }
test -f "$VERIFY_DIR/roo-cli-${PLATFORM}/lib/index.js" || { echo "Missing lib/index.js"; exit 1; }
test -f "$VERIFY_DIR/roo-cli-${PLATFORM}/package.json" || { echo "Missing package.json"; exit 1; }
test -d "$VERIFY_DIR/roo-cli-${PLATFORM}/extension" || { echo "Missing extension directory"; exit 1; }
echo "Tarball verification passed!"
# Cleanup.
rm -rf "$VERIFY_DIR"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cli-${{ matrix.platform }}
path: |
roo-cli-${{ matrix.platform }}.tar.gz
roo-cli-${{ matrix.platform }}.tar.gz.sha256
retention-days: 7
# Create GitHub release with all platform artifacts.
release:
needs: build
runs-on: ubuntu-latest
if: ${{ !inputs.dry_run }}
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get version
id: version
run: |
if [ -n "${{ inputs.version }}" ]; then
VERSION="${{ inputs.version }}"
else
VERSION=$(node -p "require('./apps/cli/package.json').version")
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=cli-v$VERSION" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release files
run: |
mkdir -p release
find artifacts -name "*.tar.gz" -exec cp {} release/ \;
find artifacts -name "*.sha256" -exec cp {} release/ \;
ls -la release/
- name: Extract changelog
id: changelog
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
CHANGELOG_FILE="apps/cli/CHANGELOG.md"
if [ -f "$CHANGELOG_FILE" ]; then
# Extract content between version headers.
CONTENT=$(awk -v version="$VERSION" '
BEGIN { found = 0; content = ""; target = "[" version "]" }
/^## \[/ {
if (found) { exit }
if (index($0, target) > 0) { found = 1; next }
}
found { content = content $0 "\n" }
END { print content }
' "$CHANGELOG_FILE")
if [ -n "$CONTENT" ]; then
echo "Found changelog content"
echo "content<<EOF" >> $GITHUB_OUTPUT
echo "$CONTENT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo "No changelog content found for version $VERSION"
echo "content=" >> $GITHUB_OUTPUT
fi
else
echo "No changelog file found"
echo "content=" >> $GITHUB_OUTPUT
fi
- name: Generate checksums summary
id: checksums
run: |
echo "checksums<<EOF" >> $GITHUB_OUTPUT
cat release/*.sha256 >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Check for existing release
id: check_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.version.outputs.tag }}
run: |
if gh release view "$TAG" &> /dev/null; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Delete existing release
if: steps.check_release.outputs.exists == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.version.outputs.tag }}
run: |
echo "Deleting existing release $TAG..."
gh release delete "$TAG" --yes || true
git push origin ":refs/tags/$TAG" || true
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
TAG: ${{ steps.version.outputs.tag }}
CHANGELOG_CONTENT: ${{ steps.changelog.outputs.content }}
CHECKSUMS: ${{ steps.checksums.outputs.checksums }}
run: |
NOTES_FILE=$(mktemp)
if [ -n "$CHANGELOG_CONTENT" ]; then
echo "## What's New" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "$CHANGELOG_CONTENT" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
fi
echo "## Installation" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo '```bash' >> "$NOTES_FILE"
echo "curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "Or install a specific version:" >> "$NOTES_FILE"
echo '```bash' >> "$NOTES_FILE"
echo "ROO_VERSION=$VERSION curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "## Requirements" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "- Node.js 20 or higher" >> "$NOTES_FILE"
echo "- macOS Apple Silicon (M1/M2/M3/M4), Linux x64, or Linux ARM64" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "## Usage" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo '```bash' >> "$NOTES_FILE"
echo "# Run a task" >> "$NOTES_FILE"
echo 'roo "What is this project?"' >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "# See all options" >> "$NOTES_FILE"
echo "roo --help" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "## Platform Support" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "This release includes binaries for:" >> "$NOTES_FILE"
echo '- `roo-cli-darwin-arm64.tar.gz` - macOS Apple Silicon (M1/M2/M3)' >> "$NOTES_FILE"
echo '- `roo-cli-linux-x64.tar.gz` - Linux x64' >> "$NOTES_FILE"
echo '- `roo-cli-linux-arm64.tar.gz` - Linux ARM64' >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "## Checksums" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
echo "$CHECKSUMS" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
gh release create "$TAG" \
--title "Roo Code CLI v$VERSION" \
--notes-file "$NOTES_FILE" \
--prerelease \
release/*
rm -f "$NOTES_FILE"
echo "Release created: https://github.com/${{ github.repository }}/releases/tag/$TAG"
# Summary job for dry runs
summary:
needs: build
runs-on: ubuntu-latest
if: ${{ inputs.dry_run }}
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Show build summary
run: |
echo "## Dry Run Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The following artifacts were built:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
find artifacts -name "*.tar.gz" | while read f; do
SIZE=$(ls -lh "$f" | awk '{print $5}')
echo "- $(basename $f) ($SIZE)" >> $GITHUB_STEP_SUMMARY
done
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Checksums" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
cat artifacts/*/*.sha256 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

View file

@ -58,3 +58,34 @@ jobs:
uses: ./.github/actions/setup-node-pnpm
- name: Run unit tests
run: pnpm test
check-openrouter-api-key:
runs-on: ubuntu-latest
outputs:
exists: ${{ steps.openrouter-api-key-check.outputs.defined }}
steps:
- name: Check if OpenRouter API key exists
id: openrouter-api-key-check
shell: bash
run: |
if [ "${{ secrets.OPENROUTER_API_KEY }}" != '' ]; then
echo "defined=true" >> $GITHUB_OUTPUT;
else
echo "defined=false" >> $GITHUB_OUTPUT;
fi
integration-test:
runs-on: ubuntu-latest
needs: [check-openrouter-api-key]
if: needs.check-openrouter-api-key.outputs.exists == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
- name: Create .env.local file
working-directory: apps/vscode-e2e
run: echo "OPENROUTER_API_KEY=${{ secrets.OPENROUTER_API_KEY }}" > .env.local
- name: Run integration tests
working-directory: apps/vscode-e2e
run: xvfb-run -a pnpm test:ci

View file

@ -1,55 +0,0 @@
name: Deploy docs to GitHub Pages
on:
push:
branches:
- main
paths:
- "apps/docs/**"
- ".github/workflows/docs-pages.yml"
- ".github/actions/setup-node-pnpm/**"
- "package.json"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
workflow_dispatch:
concurrency:
group: docs-pages
cancel-in-progress: true
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
with:
install-args: "--frozen-lockfile"
- name: Run type check
run: pnpm --filter @roo-code/docs check-types
- name: Run lint
run: pnpm --filter @roo-code/docs lint
- name: Build docs
run: pnpm --filter @roo-code/docs build
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: apps/docs/build
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

74
.github/workflows/evals.yml vendored Normal file
View file

@ -0,0 +1,74 @@
name: Evals
on:
pull_request:
types: [labeled]
workflow_dispatch:
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
jobs:
evals:
# Run if triggered manually or if PR has 'evals' label.
if: github.event_name == 'workflow_dispatch' || contains(github.event.label.name, 'evals')
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 45
defaults:
run:
working-directory: packages/evals
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Create environment
run: |
cat > .env.local << EOF
OPENROUTER_API_KEY=${{ secrets.OPENROUTER_API_KEY || 'test-key-for-build' }}
EOF
cat > .env.development << EOF
NODE_ENV=development
DATABASE_URL=postgresql://postgres:password@db:5432/evals_development
REDIS_URL=redis://redis:6379
HOST_EXECUTION_METHOD=docker
EOF
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
file: packages/evals/Dockerfile.runner
tags: evals-runner:latest
cache-from: type=gha
cache-to: type=gha,mode=max
push: false
load: true
- name: Tag image
run: docker tag evals-runner:latest evals-runner
- name: Start containers
run: |
docker compose up -d db redis
timeout 60 bash -c 'until docker compose exec -T db pg_isready -U postgres; do sleep 2; done'
timeout 60 bash -c 'until docker compose exec -T redis redis-cli ping | grep -q PONG; do sleep 2; done'
docker compose run --rm runner sh -c 'nc -z db 5432 && echo "✓ Runner -> Database connection successful"'
docker compose run --rm runner sh -c 'nc -z redis 6379 && echo "✓ Runner -> Redis connection successful"'
docker compose run --rm runner docker ps
- name: Run database migrations
run: docker compose run --rm runner pnpm --filter @roo-code/evals db:migrate
- name: Run evals
run: docker compose run --rm runner pnpm --filter @roo-code/evals cli --ci
- name: Cleanup
if: always()
run: docker compose down -v --remove-orphans

View file

@ -0,0 +1,46 @@
name: Update Contributors
on:
push:
branches:
- main
workflow_dispatch:
jobs:
update-contributors:
runs-on: ubuntu-latest
permissions:
contents: write # Needed for pushing changes.
pull-requests: write # Needed for creating PRs.
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
- name: Disable Husky
run: |
echo "HUSKY=0" >> $GITHUB_ENV
git config --global core.hooksPath /dev/null
- name: Update contributors and format
run: |
pnpm update-contributors
npx prettier --write README.md locales/*/README.md
if git diff --quiet; then echo "changes=false" >> $GITHUB_OUTPUT; else echo "changes=true" >> $GITHUB_OUTPUT; fi
id: check-changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Pull Request
if: steps.check-changes.outputs.changes == 'true'
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "docs: update contributors list [skip ci]"
committer: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
branch: update-contributors
delete-branch: true
title: "Update contributors list"
body: |
Automated update of contributors list and related files
This PR was created automatically by a GitHub Action workflow and includes all changed files.
base: main

46
.github/workflows/website-deploy.yml vendored Normal file
View file

@ -0,0 +1,46 @@
name: Deploy roocode.com
on:
push:
branches:
- main
paths:
- 'apps/web-roo-code/**'
workflow_dispatch:
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
check-secrets:
runs-on: ubuntu-latest
outputs:
has-vercel-token: ${{ steps.check.outputs.has-vercel-token }}
steps:
- name: Check if VERCEL_TOKEN exists
id: check
run: |
if [ -n "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "has-vercel-token=true" >> $GITHUB_OUTPUT
else
echo "has-vercel-token=false" >> $GITHUB_OUTPUT
fi
deploy:
runs-on: ubuntu-latest
needs: check-secrets
if: ${{ needs.check-secrets.outputs.has-vercel-token == 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
- name: Install Vercel CLI
run: npm install --global vercel@canary
- name: Pull Vercel Environment Information
run: npx vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: npx vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: npx vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

84
.github/workflows/website-preview.yml vendored Normal file
View file

@ -0,0 +1,84 @@
name: Preview roocode.com
on:
push:
branches-ignore:
- main
paths:
- "apps/web-roo-code/**"
pull_request:
paths:
- "apps/web-roo-code/**"
workflow_dispatch:
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
check-secrets:
runs-on: ubuntu-latest
outputs:
has-vercel-token: ${{ steps.check.outputs.has-vercel-token }}
steps:
- name: Check if VERCEL_TOKEN exists
id: check
run: |
if [ -n "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "has-vercel-token=true" >> $GITHUB_OUTPUT
else
echo "has-vercel-token=false" >> $GITHUB_OUTPUT
fi
preview:
runs-on: ubuntu-latest
needs: check-secrets
if: ${{ needs.check-secrets.outputs.has-vercel-token == 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js and pnpm
uses: ./.github/actions/setup-node-pnpm
- name: Install Vercel CLI
run: npm install --global vercel@canary
- name: Pull Vercel Environment Information
run: npx vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: npx vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
id: deploy
run: |
DEPLOYMENT_URL=$(npx vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "deployment_url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
echo "Preview deployed to: $DEPLOYMENT_URL"
- name: Comment PR with preview link
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const deploymentUrl = '${{ steps.deploy.outputs.deployment_url }}';
const commentIdentifier = '<!-- roo-preview-comment -->';
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existingComment = comments.find(comment =>
comment.body.includes(commentIdentifier)
);
if (existingComment) {
return;
}
const comment = commentIdentifier + '\n🚀 **Preview deployed!**\n\nYour changes have been deployed to Vercel:\n\n**Preview URL:** ' + deploymentUrl + '\n\nThis preview will be updated automatically when you push new commits to this PR.';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});

6
.gitignore vendored
View file

@ -18,7 +18,6 @@ bin/
# Local prompts and rules
/local-prompts
AGENTS.local.md
# Test environment
.test_env
@ -50,8 +49,3 @@ logs
# Qdrant
qdrant_storage/
# Architect plans
plans/
roo-cli-*.tar.gz*

View file

@ -18,19 +18,6 @@ fi
$pnpm_cmd run check-types
# Use dotenvx to securely load .env.local and run commands that depend on it
if [ -f ".env.local" ]; then
# Check if RUN_TESTS_ON_PUSH is set to true and run tests with dotenvx
if npx dotenvx get RUN_TESTS_ON_PUSH -f .env.local 2>/dev/null | grep -q "^true$"; then
npx dotenvx run -f .env.local -- $pnpm_cmd run test
fi
else
# Fallback: run tests if RUN_TESTS_ON_PUSH is set in regular environment
if [ "$RUN_TESTS_ON_PUSH" = "true" ]; then
$pnpm_cmd run test
fi
fi
# Check for new changesets.
NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ')
echo "Changeset files: $NEW_CHANGESETS"

View file

@ -1,86 +0,0 @@
---
description: "Prepare a new release of the Roo Code CLI"
argument-hint: "[version-description]"
mode: code
---
1. Identify changes since the last CLI release:
- Get the last CLI release tag: `gh release list --limit 10 | grep "cli-v"`
- View changes since last release: `git log cli-v<last-version>..HEAD -- apps/cli --oneline`
- Or for uncommitted changes: `git diff --stat -- apps/cli`
2. Review and summarize the changes to determine an appropriate changelog entry. Group changes by type:
- **Added**: New features
- **Changed**: Changes to existing functionality
- **Fixed**: Bug fixes
- **Removed**: Removed features
- **Tests**: New or updated tests
3. Bump the version in `apps/cli/package.json`:
- Increment the patch version (e.g., 0.0.43 → 0.0.44) for bug fixes and minor changes
- Increment the minor version (e.g., 0.0.43 → 0.1.0) for new features
- Increment the major version (e.g., 0.0.43 → 1.0.0) for breaking changes
4. Update `apps/cli/CHANGELOG.md` with a new entry:
- Add a new section at the top (below the header) following this format:
```markdown
## [X.Y.Z] - YYYY-MM-DD
### Added
- Description of new features
### Changed
- Description of changes
### Fixed
- Description of bug fixes
```
- Use the current date in YYYY-MM-DD format
- Include links to relevant source files where helpful
- Describe changes from the user's perspective
5. Create a release branch and commit the changes:
```bash
# Ensure you're on main and up to date
git checkout main
git pull origin main
# Create a new branch for the release
git checkout -b cli-release-v<version>
# Commit the version bump and changelog update
git add apps/cli/package.json apps/cli/CHANGELOG.md
git commit -m "chore(cli): prepare release v<version>"
# Push the branch to origin
git push -u origin cli-release-v<version>
```
6. Create a pull request for the release:
```bash
gh pr create --title "chore(cli): prepare release v<version>" \
--body "## CLI Release v<version>
This PR prepares the CLI release v<version>.
### Changes
- Version bump in package.json
- Changelog update
### Checklist
- [ ] Version number is correct
- [ ] Changelog entry is complete and accurate
- [ ] All CI checks pass" \
--base main
```

View file

@ -1,80 +0,0 @@
---
description: "Commit and push changes with a descriptive message"
argument-hint: "[optional-context]"
mode: code
---
1. Analyze the current changes to understand what needs to be committed:
```bash
# Check for staged and unstaged changes
git status --short
# View the diff of all changes (staged and unstaged)
git diff HEAD
```
2. Based on the diff output, formulate a commit message following conventional commit format:
- **feat**: New feature or functionality
- **fix**: Bug fix
- **refactor**: Code restructuring without behavior change
- **docs**: Documentation changes
- **test**: Adding or updating tests
- **chore**: Maintenance tasks, dependencies, configs
- **style**: Formatting, whitespace, no logic changes
Format: `type(scope): brief description`
Examples:
- `feat(api): add user authentication endpoint`
- `fix(ui): resolve button alignment on mobile`
- `refactor(core): simplify error handling logic`
- `docs(readme): update installation instructions`
3. Stage all unstaged changes:
```bash
git add -A
```
4. Commit with the generated message:
```bash
git commit -m "type(scope): brief description"
```
**If pre-commit hooks fail:**
- Review the error output (linter errors, type checking errors, etc.)
- Fix the identified issues in the affected files
- Re-stage the fixes: `git add -A`
- Retry the commit: `git commit -m "type(scope): brief description"`
5. Push to the remote repository:
```bash
git push
```
**If pre-push hooks fail:**
- Review the error output (test failures, linter errors, etc.)
- Fix the identified issues in the affected files
- Stage and commit the fixes using steps 3-4
- Retry the push: `git push`
**Tips for good commit messages:**
- Keep the first line under 72 characters
- Use imperative mood ("add", "fix", "update", not "added", "fixes", "updated")
- Be specific but concise
- If multiple unrelated changes exist, consider splitting into separate commits
**Common hook failures and fixes:**
- **Linter errors**: Run the project's linter (e.g., `npm run lint` or `pnpm lint`) to see all issues, then fix them
- **Type checking errors**: Run type checker (e.g., `npx tsc --noEmit`) to identify type issues
- **Test failures**: Run tests (e.g., `npm test` or `pnpm test`) to identify failing tests and fix them
- **Format issues**: Run formatter (e.g., `npm run format` or `pnpm format`) to auto-fix formatting

View file

@ -1,7 +1,6 @@
---
description: "Create a new release of the Roo Code extension"
argument-hint: patch | minor | major
mode: code
---
1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt`
@ -17,14 +16,14 @@ mode: code
[list of changes]
```
- Always include contributor attribution and the PR number: use "(PR #<prNumber> by @username)".
- For PRs that close issues, include both the issue number and the PR number and authors: "- Fix: Description (#123 by @reporter, PR #456 by @contributor)"
- For PRs without linked issues, include the PR number and author: "- Add support for feature (PR #456 by @contributor)"
- Always include contributor attribution using format: (thanks @username!)
- For PRs that close issues, also include the issue number and reporter: "- Fix: Description (#123 by @reporter, PR by @contributor)"
- For PRs without linked issues, use the standard format: "- Add support for feature (thanks @contributor!)"
- Provide brief descriptions of each item to explain the change
- Order the list from most important to least important
- Example formats:
- With issue: "- Fix: Resolve memory leak in extension (#456 by @issueReporter, PR #789 by @prAuthor)"
- Without issue: "- Add support for Gemini 2.5 Pro caching (PR #789 by @contributor)"
- With issue: "- Fix: Resolve memory leak in extension (#456 by @issueReporter, PR by @prAuthor)"
- Without issue: "- Add support for Gemini 2.5 Pro caching (thanks @contributor!)"
- CRITICAL: Include EVERY SINGLE PR in the changeset - don't assume you know which ones are important. Count the total PRs to verify completeness and cross-reference the list to ensure nothing is missed.
6. If the generate_image tool is available, create a release image at `releases/[version]-release.png`

View file

@ -1,72 +0,0 @@
---
description: "Resolve merge conflicts intelligently using git history analysis"
argument-hint: "#PR-number"
mode: merge-resolver
---
Resolve merge conflicts for a specific pull request by analyzing git history, commit messages, and code changes to make intelligent resolution decisions.
## Quick Start
1. **Provide a PR number** (e.g., `#123` or just `123`)
2. The workflow will automatically:
- Fetch PR information (title, description, branches)
- Checkout the PR branch
- Rebase onto the target branch to reveal conflicts
- Analyze and resolve conflicts using git history
## Workflow Steps
### 1. Initialize PR Resolution
```bash
# Fetch PR info
gh pr view [PR_NUMBER] --json title,body,headRefName,baseRefName
# Checkout and rebase
gh pr checkout [PR_NUMBER] --force
git fetch origin main
GIT_EDITOR=true git rebase origin/main
```
### 2. Identify Conflicts
```bash
git status --porcelain | grep "^UU"
```
### 3. Analyze Each Conflict
For each conflicted file:
- Read the conflict markers
- Run `git blame` on conflicting sections
- Fetch commit messages for context
- Determine the intent behind each change
### 4. Apply Resolution Strategy
Based on the analysis:
- **Bugfixes** generally take precedence over features
- **Recent changes** are often more relevant (unless older is a security fix)
- **Combine** non-conflicting changes when possible
- **Preserve** test updates alongside code changes
### 5. Complete Resolution
```bash
git add [resolved-files]
GIT_EDITOR=true git rebase --continue
```
## Key Guidelines
- Always escape conflict markers with `\` when using `apply_diff`
- Document resolution decisions in the summary
- Verify no syntax errors after resolution
- Preserve valuable changes from both sides when possible
## Examples
- `/roo-resolve-conflicts #123` - Resolve conflicts for PR #123
- `/roo-resolve-conflicts 456` - Resolve conflicts for PR #456

View file

@ -1,50 +0,0 @@
---
description: "Translate and localize strings in the Roo Code extension"
argument-hint: "[language-code or 'all'] [string-key or file-path]"
mode: translate
---
Perform translation and localization tasks for the Roo Code extension. This command activates the translation workflow with comprehensive i18n guidelines.
## Quick Start
1. **Identify the translation scope:**
- If a specific language code is provided (e.g., `de`, `zh-CN`), focus on that language
- If `all` is specified, translate to all supported languages
- If a string key is provided, locate and translate that specific string
- If a file path is provided, work with that translation file
2. **Supported languages:** ca, de, en, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW
3. **Translation locations:**
- Core Extension: `src/i18n/locales/`
- WebView UI: `webview-ui/src/i18n/locales/`
## Workflow
1. If adding new strings:
- Add the English string first
- Ask for confirmation before translating to other languages
- Use `apply_diff` for efficient file updates
2. If updating existing strings:
- Identify all affected language files
- Update English first, then propagate changes
3. Validate your changes:
```bash
node scripts/find-missing-translations.js
```
## Key Guidelines
- Use informal speech (e.g., "du" not "Sie" in German)
- Keep technical terms like "token", "Prompt" in English
- Preserve all `{{variable}}` placeholders exactly
- Use `apply_diff` instead of `write_to_file` for existing files
## Examples
- `/roo-translate de` - Focus on German translations
- `/roo-translate all welcome.title` - Translate a specific key to all languages
- `/roo-translate zh-CN src/i18n/locales/zh-CN/core.json` - Work on specific file

View file

@ -1,15 +0,0 @@
# Roo Code Translation Guidance
This file contains brand voice, tone, and word choice guidelines for Roo Code translations.
## Brand Voice
<!-- Add brand voice guidelines here -->
## Tone
<!-- Add tone guidelines here -->
## Word Choice
<!-- Add word choice preferences here -->

View file

@ -1,6 +1,25 @@
version: "1.0"
commands:
- name: Pull latest changes
run: git pull
timeout: 60
execution_phase: task_run
- name: Install dependencies
run: pnpm install
timeout: 60
execution_phase: task_run
github_events:
- event: issues.opened
action:
name: github.issue.fix
- event: issue_comment.created
action:
name: github.issue.comment.respond
- event: pull_request.opened
action:
name: github.pr.review
- event: pull_request_review_comment.created
action:
name: github.pr.comment.respond

View file

@ -1,67 +0,0 @@
# CLI Debugging with File-Based Logging
When debugging the CLI, `console.log` will break the TUI (Terminal User Interface). Use file-based logging to capture debug output without interfering with the application's display.
## File-Based Logging Strategy
1. **Write logs to a temporary file instead of console**:
- Create a log file at a known location, e.g., `/tmp/roo-cli-debug.log`
- Use `fs.appendFileSync()` to write timestamped log entries
- Example logging utility:
```typescript
import fs from "fs"
const DEBUG_LOG = "/tmp/roo-cli-debug.log"
function debugLog(message: string, data?: unknown) {
const timestamp = new Date().toISOString()
const entry = data
? `[${timestamp}] ${message}: ${JSON.stringify(data, null, 2)}\n`
: `[${timestamp}] ${message}\n`
fs.appendFileSync(DEBUG_LOG, entry)
}
```
2. **Clear the log file before each debugging session**:
- Run `echo "" > /tmp/roo-cli-debug.log` or use `fs.writeFileSync(DEBUG_LOG, "")` at app startup during debugging
## Iterative Debugging Workflow
Follow this feedback loop to systematically narrow down issues:
1. **Add targeted logging** at suspected problem areas based on your hypotheses
2. **Instruct the user** to reproduce the issue using the CLI normally
3. **Read the log file** after the user completes testing:
- Run `cat /tmp/roo-cli-debug.log` to retrieve the captured output
4. **Analyze the log output** to gather clues about:
- Execution flow and timing
- Variable values at key points
- Which code paths were taken
- Error conditions or unexpected states
5. **Refine your logging** based on findings—add more detail where needed, remove noise
6. **Ask the user to test again** with updated logging
7. **Repeat** until the root cause is identified
## Best Practices
- Log entry/exit points of functions under investigation
- Include relevant variable values and state information
- Use descriptive prefixes to categorize logs: `[STATE]`, `[EVENT]`, `[ERROR]`, `[FLOW]`
- Log both the "happy path" and error handling branches
- When dealing with async operations, log before and after `await` statements
- For user interactions, log the received input and the resulting action
## Example Debug Session
```typescript
// Add logging to investigate a picker selection issue
debugLog("[FLOW] PickerSelect onSelect called", { selectedIndex, item })
debugLog("[STATE] Current selection state", { currentValue, isOpen })
// After async operation
const result = await fetchOptions()
debugLog("[FLOW] fetchOptions completed", { resultCount: result.length })
```
Then ask: "Please reproduce the issue by [specific steps]. When you're done, let me know and I'll analyze the debug logs."

View file

@ -1,113 +1,361 @@
<extraction_workflow>
<overview>
Extract raw facts from a codebase about a feature or aspect.
Output is structured data for documentation teams to use.
Do NOT write documentation. Do NOT format prose. Do NOT make structure decisions.
</overview>
<mode_overview>
The Docs Extractor mode has two primary functions:
1. Extract technical and non-technical details about features to provide to documentation teams
2. Verify existing documentation for factual accuracy against the codebase
This mode does not generate final documentation but provides detailed analysis and verification.
</mode_overview>
<process>
<initialization_phase>
<step number="1">
<title>Identify Target</title>
<title>Parse Request</title>
<actions>
<action>Parse the user's request to identify the feature/aspect</action>
<action>Clarify scope if ambiguous (ask one question max)</action>
<action>Identify the feature or component in the user's request.</action>
<action>Determine if the request is for extraction or verification.</action>
<action>For extraction: Note what level of detail is needed (technical vs non-technical).</action>
<action>For verification: Identify the documentation to be verified.</action>
<action>Note any specific areas to emphasize or check.</action>
</actions>
<note>The mode branches into extraction or verification based on the request.</note>
</step>
<step number="2">
<title>Discover Code</title>
<title>Discover Feature</title>
<actions>
<action>Use codebase_search to find relevant files</action>
<action>Identify entry points, components, and related code</action>
<action>Map the boundaries of the feature</action>
<action>Locate relevant code using appropriate search methods.</action>
<action>Identify entry points and components.</action>
<action>Map the high-level architecture.</action>
<action>Use any combination of tools to understand the feature.</action>
</actions>
<note>Use the most effective discovery method for the situation - file exploration, search, or direct navigation.</note>
</step>
</initialization_phase>
<step number="3">
<title>Extract Facts</title>
<actions>
<action>Read code and extract facts into categories (see fact_categories)</action>
<action>Record file paths as sources for each fact</action>
<action>Do NOT interpret, summarize, or explain - just extract</action>
</actions>
</step>
<analysis_phases>
<phase name="code_analysis">
<title>Code Analysis</title>
<steps>
<step>
<action>Analyze code structure</action>
<details>
- Identify classes, functions, modules
- Extract method signatures, parameters
- Document return types, data structures
- Map inheritance and composition
</details>
</step>
<step>
<action>Extract APIs</action>
<details>
- REST endpoints
- GraphQL schemas
- WebSocket events
- RPC interfaces
</details>
</step>
<step>
<action>Document configuration</action>
<details>
- Environment variables
- Config files and schemas
- Feature flags
- Runtime parameters
</details>
</step>
</steps>
</phase>
<step number="4">
<title>Output Structured Data</title>
<actions>
<action>Write extraction to .roo/extraction/EXTRACT-[feature].yaml</action>
<action>Use the output schema (see output_format.xml)</action>
</actions>
</step>
</process>
<phase name="ui_ux_analysis">
<title>UI/UX and User Experience Analysis</title>
<steps>
<step>
<action>Analyze user interface components</action>
<details>
- UI components and their interactions
- Forms, buttons, navigation elements
- Visual feedback and loading states
- Responsive design considerations
- Accessibility features
</details>
</step>
<step>
<action>Map user journeys and interactions</action>
<details>
- Step-by-step user workflows
- Click paths and navigation flows
- User decision points
- Input validation and error messaging
- Success and failure scenarios
</details>
</step>
<step>
<action>Document user experience elements</action>
<details>
- Page layouts and information architecture
- Interactive elements and their behaviors
- Tooltips, help text, and guidance
- Confirmation dialogs and warnings
- Progress indicators and status updates
</details>
</step>
<step>
<action>Capture visual and behavioral patterns</action>
<details>
- Color schemes and theming
- Animation and transitions
- Keyboard shortcuts and accessibility
- Mobile vs desktop experiences
- Browser-specific considerations
</details>
</step>
</steps>
</phase>
<fact_categories>
<category name="identity">
<extracts>
<extract>Feature name as it appears in code</extract>
<extract>File paths where feature is implemented</extract>
<extract>Entry points (commands, UI elements, API endpoints)</extract>
</extracts>
</category>
<phase name="business_logic_analysis">
<title>Business Logic Extraction</title>
<steps>
<step>
<action>Map workflows from user perspective</action>
<details>
- User journey through the feature
- Decision points and branching
- State transitions visible to users
- Roles and permissions affecting UI
</details>
</step>
<step>
<action>Document business rules</action>
<details>
- Validation logic and user feedback
- Formulas and algorithms
- Business process implementations
- Compliance requirements
</details>
</step>
<step>
<action>Identify use cases</action>
<details>
- Primary use cases
- Edge cases
- Error scenarios and user recovery
- Performance factors affecting UX
</details>
</step>
</steps>
</phase>
<category name="behavior">
<extracts>
<extract>What the feature does (from code logic)</extract>
<extract>Inputs it accepts</extract>
<extract>Outputs it produces</extract>
<extract>Side effects (files created, state changed, etc.)</extract>
</extracts>
</category>
<phase name="integration_analysis">
<title>Dependency Analysis</title>
<steps>
<step>
<action>Map dependencies</action>
<details>
- Third-party libraries
- External services and APIs
- Database connections
- Message queues
</details>
</step>
<step>
<action>Document integration points</action>
<details>
- Incoming webhooks
- Outgoing API calls
- Event publishers/subscribers
- Shared data stores
</details>
</step>
<step>
<action>Analyze data flow</action>
<details>
- Data sources and formats
- Data transformations
- Output formats and destinations
- Data retention policies
</details>
</step>
</steps>
</phase>
<category name="configuration">
<extracts>
<extract>Settings/options that affect behavior</extract>
<extract>Default values</extract>
<extract>Valid ranges or allowed values</extract>
<extract>Where configured (settings file, env var, UI)</extract>
</extracts>
</category>
<phase name="quality_analysis">
<title>Test Analysis</title>
<steps>
<step>
<action>Assess test coverage</action>
<details>
- Unit test coverage
- Integration test scenarios
- End-to-end test flows
- Performance test results
</details>
</step>
<step>
<action>Document error handling</action>
<details>
- Error types and codes
- Exception handling
- Fallback mechanisms
- Recovery procedures
</details>
</step>
<step>
<action>Identify quality metrics</action>
<details>
- Code complexity
- Performance benchmarks
- Security vulnerabilities
- Maintainability scores
</details>
</step>
</steps>
</phase>
<category name="constraints">
<extracts>
<extract>Prerequisites and dependencies</extract>
<extract>Limitations (what it cannot do)</extract>
<extract>Permissions required</extract>
<extract>Compatibility requirements</extract>
</extracts>
</category>
<phase name="security_analysis">
<title>Security Analysis</title>
<steps>
<step>
<action>Document security</action>
<details>
- Auth mechanisms
- Access control
- Data encryption
- Security policies
</details>
</step>
<step>
<action>Identify vulnerabilities</action>
<details>
- Known security issues
- Attack vectors
- Mitigation
- Best practices
</details>
</step>
<step>
<action>Check compliance</action>
<details>
- Regulatory compliance (GDPR, etc.)
- Industry standards
- Audit trail requirements
- Data privacy
</details>
</step>
</steps>
</phase>
</analysis_phases>
<category name="errors">
<extracts>
<extract>Error conditions in code</extract>
<extract>Error messages (exact text)</extract>
<extract>Recovery paths in code</extract>
</extracts>
</category>
<workflow_paths>
<path name="extraction">
<title>Extract Feature Details</title>
<description>Analyze and extract comprehensive details for documentation team</description>
<steps>
<step number="1">
<title>Compile Technical Details</title>
<actions>
<action>List all technical components and their relationships</action>
<action>Document APIs, data structures, and algorithms</action>
<action>Extract configuration options and their impacts</action>
<action>Identify error handling and edge cases</action>
<action>Note performance characteristics and limitations</action>
</actions>
</step>
<step number="2">
<title>Extract Non-Technical Information</title>
<actions>
<action>Describe complete user experience and workflows</action>
<action>Document UI interactions and visual elements</action>
<action>Explain business logic in plain language</action>
<action>Identify user benefits and use cases</action>
<action>Document common scenarios with UI context</action>
<action>Note prerequisites and user-facing dependencies</action>
<action>Capture error messages and user guidance</action>
</actions>
</step>
<step number="3">
<title>Create Extraction Report</title>
<actions>
<action>Organize findings into clear categories</action>
<action>Separate technical and non-technical information</action>
<action>Include code snippets and examples where helpful</action>
<action>Create `EXTRACTION-[feature].md` with findings</action>
<action>Highlight areas that need special attention in documentation</action>
</actions>
<output_format>
- Executive summary of the feature
- UI/UX analysis and user experience
- Technical details section
- Non-technical/user-facing details
- User workflows and interactions
- Configuration and setup information
- Common use cases with UI context
- Error handling and user guidance
- Potential documentation considerations
</output_format>
</step>
</steps>
</path>
<category name="ui">
<extracts>
<extract>UI components involved</extract>
<extract>User-visible labels and text</extract>
<extract>Interaction patterns</extract>
</extracts>
</category>
<path name="verification">
<title>Verify Documentation Accuracy</title>
<description>Check existing documentation against codebase reality</description>
<steps>
<step number="1">
<title>Analyze Provided Documentation</title>
<actions>
<action>Parse the documentation to identify claims and descriptions</action>
<action>Extract technical specifications mentioned</action>
<action>Note user-facing features and workflows described</action>
<action>Identify configuration options and examples provided</action>
</actions>
</step>
<step number="2">
<title>Verify Against Codebase</title>
<actions>
<action>Check technical claims against actual implementation</action>
<action>Verify API endpoints, parameters, and responses</action>
<action>Confirm configuration options and defaults</action>
<action>Validate code examples and snippets</action>
<action>Check if described workflows match implementation</action>
</actions>
</step>
<step number="3">
<title>Create Verification Report</title>
<actions>
<action>Categorize findings by severity (Critical, Major, Minor)</action>
<action>List all inaccuracies with correct information</action>
<action>Identify missing important information</action>
<action>Note outdated or deprecated content</action>
<action>Provide specific corrections and suggestions</action>
<action>Create `VERIFICATION-[feature].md` with findings</action>
</actions>
<output_format>
- Verification summary (Accurate/Needs Updates)
- Critical inaccuracies that could mislead users
- Technical corrections needed
- Missing information that should be added
- Suggestions for clarity improvements
- Overall recommendations
</output_format>
</step>
</steps>
</path>
</workflow_paths>
<category name="integration">
<extracts>
<extract>Other features this interacts with</extract>
<extract>External APIs or services called</extract>
<extract>Events emitted or consumed</extract>
</extracts>
</category>
</fact_categories>
<rules>
<rule>Extract facts, not opinions</rule>
<rule>Include source file paths for every fact</rule>
<rule>Use code identifiers and exact strings from source</rule>
<rule>Do NOT paraphrase - quote when possible</rule>
<rule>Do NOT decide what's important - extract everything relevant</rule>
<rule>Do NOT format for end users - output is for docs team</rule>
</rules>
<completion_criteria>
<for_extraction>
<criterion>All code paths analyzed</criterion>
<criterion>Technical details comprehensively extracted</criterion>
<criterion>Non-technical information clearly explained</criterion>
<criterion>Use cases and examples provided</criterion>
<criterion>Report organized for documentation team use</criterion>
</for_extraction>
<for_verification>
<criterion>All documentation claims verified</criterion>
<criterion>Inaccuracies identified and corrected</criterion>
<criterion>Missing information noted</criterion>
<criterion>Suggestions for improvement provided</criterion>
<criterion>Clear verification report created</criterion>
</for_verification>
</completion_criteria>
</extraction_workflow>

View file

@ -0,0 +1,387 @@
<documentation_patterns>
<overview>
Standard templates for structuring extracted documentation.
</overview>
<output_structure>
<user_focused_template><![CDATA[
# [Feature Name]
[Description of what the feature does and why a user should care.]
### Key Features
- [Benefit-oriented feature 1]
- [Benefit-oriented feature 2]
- [Benefit-oriented feature 3]
---
## Use Case
**Before**: [Description of the old way]
- [Pain point 1]
- [Pain point 2]
**With this feature]**: [Description of the new experience.]
## How it Works
[Simple explanation of the feature's operation.]
[Suggest visual representations where helpful.]
---
## Configuration
[Explanation of relevant settings.]
1. **[Setting Name]**:
- **Setting**: `[technical_name]`
- **Description**: [What this does.]
- **Default**: [Default value and its meaning.]
2. **[Setting Name]**:
- **Setting**: `[technical_name]`
- **Description**: [What this does.]
- **Default**: [Default value and its meaning.]
---
## FAQ
**"[User question]"**
- [Answer.]
- [Optional tip.]
**"[User question]"**
- [Answer.]
- [Optional tip.]
]]></user_focused_template>
<comprehensive_template><![CDATA[
# [Feature Name] Technical Documentation
## Table of Contents
1. Overview
2. Quick Start
3. Architecture
4. API Reference
5. Configuration
6. User Guide
7. Developer Guide
8. Administrator Guide
9. Security
10. Performance
11. Troubleshooting
12. FAQ
13. Changelog
14. References
[This template remains available for generating detailed technical documentation.]
]]></comprehensive_template>
</output_structure>
<documentation_patterns>
<before_after>
<template><![CDATA[
**Before**: Multiple, sequential file read requests:
- "Read `src/app.js`?" → Approve
- "Read `src/utils.js`?" → Approve
- "Read `src/config.json`?" → Approve
**Now**: One request to read all related files.
]]></template>
</before_after>
<visual_separator>
<format>---</format>
<purpose>Separate sections.</purpose>
</visual_separator>
<faq>
<template><![CDATA[
## FAQ
**"Why disable this?"**
- Your AI model handles single files better.
- You need more control over file access.
- You are working with very large files.
**"What if some files are blocked?"**
- Roo reads approved files and works with what it has.
- `.rooignore` files are excluded automatically.
- Individual files can still be denied in the batch dialog.
]]></template>
</faq>
<examples>
<guideline>Show tool output or UI elements.</guideline>
<guideline>Use actual file paths and setting names.</guideline>
<guideline>Include common errors and solutions.</guideline>
</examples>
<troubleshooting>
<template><![CDATA[
## Troubleshooting
**"Too many files requested"**
- Lower the concurrent file limit in settings.
- Deny individual files in the batch dialog.
**"Feature isn't working"**
- Ensure "Enable concurrent file reads" is on in settings.
- Verify the file limit is set correctly (default: 100).
- Some AI models may not support this feature.
]]></template>
</troubleshooting>
<help>
<template><![CDATA[
## Help
- See the [FAQ](#faq) for common issues.
- Report problems on [GitHub Issues](https://github.com/RooCodeInc/Roo-Code/issues).
- Include reproduction steps and error messages.
]]></template>
</help>
</documentation_patterns>
<audience_sections>
<audience type="end_user">
<focus>
<area>Tutorials</area>
<area>Use cases</area>
<area>Troubleshooting</area>
<area>Benefits</area>
</focus>
<style>
<guideline>Simple language</guideline>
<guideline>Visual aids</guideline>
<guideline>Focus on outcomes</guideline>
<guideline>Clear action steps</guideline>
</style>
</audience>
<audience type="developer">
<focus>
<area>Code examples</area>
<area>API specs</area>
<area>Integration patterns</area>
<area>Performance</area>
</focus>
<style>
<guideline>Precise terminology</guideline>
<guideline>Code samples</guideline>
<guideline>Document edge cases</guideline>
<guideline>Debugging guidance</guideline>
</style>
</audience>
<audience type="administrator">
<focus>
<area>Deployment</area>
<area>Monitoring</area>
<area>Security hardening</area>
<area>Backup and recovery</area>
</focus>
<style>
<guideline>Operational focus</guideline>
<guideline>CLI examples</guideline>
<guideline>Automation opportunities</guideline>
<guideline>Security and compliance</guideline>
</style>
</audience>
<audience type="stakeholder">
<focus>
<area>Business value</area>
<area>Capabilities and limits</area>
<area>Competitive advantages</area>
<area>Risk assessment</area>
</focus>
<style>
<guideline>Business language</guideline>
<guideline>Metrics and KPIs</guideline>
<guideline>Strategic benefits</guideline>
<guideline>Executive summaries</guideline>
</style>
</audience>
</audience_sections>
<metadata_patterns>
<version_info>
<template><![CDATA[
### Version Compatibility
| Component | Min | Recommended | Max | Notes |
|-----------|-----|-------------|-----|-------|
| [Component] | [version] | [version] | [version] | [notes] |
]]></template>
</version_info>
<deprecation_notice>
<template><![CDATA[
> ⚠️ **Deprecated**
>
> Deprecated since: [vX.Y.Z] on [date]
> Removal target: [vA.B.C]
> Migration: See [migration guide](#migration).
> Replacement: [new feature/method].
]]></template>
</deprecation_notice>
<security_warning>
<template><![CDATA[
> 🔒 **Security Warning**
>
> [Description of concern]
> - **Risk**: [High/Medium/Low]
> - **Affected**: [versions]
> - **Mitigation**: [steps]
> - **References**: [links]
]]></template>
</security_warning>
<performance_note>
<template><![CDATA[
> ⚡ **Performance Note**
>
> [Description of performance consideration]
> - **Impact**: [metrics]
> - **Optimization**: [approach]
> - **Trade-offs**: [considerations]
]]></template>
</performance_note>
</metadata_patterns>
<code_documentation_patterns>
<api_endpoint>
<template><![CDATA[
### `[METHOD] /api/[path]`
**Description**: [What this endpoint does]
**Authentication**: [Required/Optional] - [Type]
**Parameters**:
| Name | Type | Required | Description | Example |
|------|------|----------|-------------|---------|
| [param] | [type] | [Yes/No] | [description] | [example] |
**Request Body**:
```json
{
"field": "value"
}
```
**Response**:
- **Success (200)**:
```json
{
"status": "success",
"data": {}
}
```
- **Error (4xx/5xx)**:
```json
{
"error": "error_code",
"message": "Human readable message"
}
```
**Example**:
```bash
curl -X [METHOD] https://api.example.com/[path] \
-H "Authorization: Bearer [token]" \
-H "Content-Type: application/json" \
-d '{"field": "value"}'
```
]]></template>
</api_endpoint>
<function_documentation>
<template><![CDATA[
### `functionName(parameters)`
**Purpose**: [What this function does]
**Parameters**:
- `param1` (Type): [Description]
- `param2` (Type, optional): [Description] - Default: [value]
**Returns**: `Type` - [Description of return value]
**Throws**:
- `ErrorType`: [When this error occurs]
**Example**:
```typescript
const result = functionName(value1, value2);
// Expected output: [description]
```
**Notes**:
- [Important consideration 1]
- [Important consideration 2]
]]></template>
</function_documentation>
<configuration_option>
<template><![CDATA[
### `CONFIG_NAME`
**Type**: `string | number | boolean`
**Default**: `default_value`
**Environment Variable**: `APP_CONFIG_NAME`
**Description**: [What this configuration controls]
**Valid Values**:
- `value1`: [Description]
- `value2`: [Description]
**Example**:
```yaml
config:
name: value
```
**Impact**: [What changes when this is modified]
]]></template>
</configuration_option>
</code_documentation_patterns>
<cross_reference_patterns>
<internal_link>
<format>[Link Text](#section-anchor)</format>
<example>[See Configuration Guide](#configuration)</example>
</internal_link>
<external_link>
<format>[Link Text](https://external.url)</format>
<example>[Official Documentation](https://docs.example.com)</example>
</external_link>
<related_feature>
<template><![CDATA[
> 📌 **Related Features**
> - [Feature A](../feature-a/README.md): [How it relates]
> - [Feature B](../feature-b/README.md): [How it relates]
]]></template>
</related_feature>
<see_also>
<template><![CDATA[
> 👉 **See Also**
> - [Related Topic 1](#anchor1)
> - [Related Topic 2](#anchor2)
> - [External Resource](https://example.com)
]]></template>
</see_also>
</cross_reference_patterns>
</documentation_patterns>

View file

@ -1,85 +0,0 @@
<verification_workflow>
<overview>
Compare provided documentation against actual codebase implementation.
Output is a structured diff of claims vs reality.
Do NOT rewrite the docs. Do NOT suggest wording. Just report discrepancies.
</overview>
<process>
<step number="1">
<title>Receive Documentation</title>
<actions>
<action>User provides documentation to verify (text, file, or URL)</action>
<action>Identify the feature/aspect being documented</action>
</actions>
</step>
<step number="2">
<title>Extract Claims</title>
<actions>
<action>Parse the documentation into discrete claims</action>
<action>Tag each claim with a category (behavior, config, constraint, etc.)</action>
<action>Record the exact quote from the documentation</action>
</actions>
</step>
<step number="3">
<title>Verify Against Code</title>
<actions>
<action>For each claim, find the relevant code</action>
<action>Compare claim to actual implementation</action>
<action>Record: ACCURATE, INACCURATE, OUTDATED, MISSING_CONTEXT, or UNVERIFIABLE</action>
<action>For inaccuracies, record what the code actually does</action>
</actions>
</step>
<step number="4">
<title>Output Verification Report</title>
<actions>
<action>Write verification to .roo/extraction/VERIFY-[feature].yaml</action>
<action>Use the output schema (see output_format.xml)</action>
</actions>
</step>
</process>
<verification_statuses>
<status name="ACCURATE">
<meaning>Claim matches implementation</meaning>
</status>
<status name="INACCURATE">
<meaning>Claim contradicts implementation</meaning>
<requires>What the code actually does</requires>
</status>
<status name="OUTDATED">
<meaning>Claim was once true but code has changed</meaning>
<requires>Current behavior</requires>
</status>
<status name="MISSING_CONTEXT">
<meaning>Claim is true but omits important information</meaning>
<requires>The missing context</requires>
</status>
<status name="UNVERIFIABLE">
<meaning>Cannot find code to verify this claim</meaning>
<requires>Search paths attempted</requires>
</status>
</verification_statuses>
<claim_categories>
<category>behavior</category>
<category>configuration</category>
<category>constraint</category>
<category>error_handling</category>
<category>ui</category>
<category>integration</category>
<category>prerequisite</category>
</claim_categories>
<rules>
<rule>Verify facts, not writing quality</rule>
<rule>Report what code does, not what docs should say</rule>
<rule>Include source file paths as evidence</rule>
<rule>Do NOT suggest documentation rewrites</rule>
<rule>Do NOT evaluate if docs are "good" - only if they're accurate</rule>
<rule>Quote exact code when showing discrepancies</rule>
</rules>
</verification_workflow>

View file

@ -0,0 +1,588 @@
<analysis_techniques>
<overview>
Techniques for analyzing code to extract documentation.
</overview>
<ui_ux_analysis_techniques>
<technique name="component_discovery">
<description>
Find and analyze UI components and their interactions
</description>
<discovery_methods>
<method name="component_search">
<description>Search for UI component files</description>
<example><![CDATA[
<!-- Find React/Vue/Angular components -->
<search_files>
<path>src</path>
<regex>\.(tsx|jsx|vue)$|@Component|export.*component</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
<!-- Find component usage -->
<search_files>
<path>src</path>
<regex><Button|<Form|<Modal|<Dialog|<Input</regex>
</search_files>
]]></example>
</method>
<method name="style_analysis">
<description>Analyze styling and visual elements</description>
<example><![CDATA[
<!-- Find stylesheets -->
<list_files>
<path>src/styles</path>
<recursive>true</recursive>
</list_files>
<!-- Search for style definitions -->
<search_files>
<path>src</path>
<regex>className=|style=|styled\.|makeStyles|@apply</regex>
</search_files>
]]></example>
</method>
</discovery_methods>
</technique>
<technique name="user_flow_mapping">
<description>
Map user interactions and navigation flows
</description>
<analysis_areas>
<area>Route definitions and navigation</area>
<area>Form submissions and validations</area>
<area>Button clicks and event handlers</area>
<area>State changes and UI updates</area>
<area>Loading and error states</area>
</analysis_areas>
<search_patterns><![CDATA[
<!-- Find route definitions -->
<search_files>
<path>src</path>
<regex>Route.*path=|router\.push|navigate\(|Link.*to=</regex>
</search_files>
<!-- Find event handlers -->
<search_files>
<path>src</path>
<regex>onClick=|onSubmit=|onChange=|handleClick|handleSubmit</regex>
</search_files>
<!-- Find form validations -->
<search_files>
<path>src</path>
<regex>validate|validation|required|pattern=|minLength|maxLength</regex>
</search_files>
]]></search_patterns>
</technique>
<technique name="user_feedback_analysis">
<description>
Analyze how the system communicates with users
</description>
<elements_to_find>
<element>Error messages and alerts</element>
<element>Success notifications</element>
<element>Loading indicators</element>
<element>Tooltips and help text</element>
<element>Confirmation dialogs</element>
<element>Progress indicators</element>
</elements_to_find>
<search_patterns><![CDATA[
<!-- Find user messages -->
<search_files>
<path>src</path>
<regex>toast|notification|alert|message|error.*message|success.*message</regex>
</search_files>
<!-- Find loading states -->
<search_files>
<path>src</path>
<regex>loading|isLoading|pending|spinner|skeleton|placeholder</regex>
</search_files>
<!-- Find dialogs and modals -->
<search_files>
<path>src</path>
<regex>modal|dialog|confirm|popup|overlay</regex>
</search_files>
]]></search_patterns>
</technique>
<technique name="accessibility_analysis">
<description>
Check for accessibility features and compliance
</description>
<accessibility_checks>
<check>ARIA labels and roles</check>
<check>Keyboard navigation support</check>
<check>Screen reader compatibility</check>
<check>Focus management</check>
<check>Color contrast considerations</check>
</accessibility_checks>
<search_patterns><![CDATA[
<!-- Find accessibility attributes -->
<search_files>
<path>src</path>
<regex>aria-|role=|tabIndex|alt=|title=|accessibilityLabel</regex>
</search_files>
<!-- Find focus management -->
<search_files>
<path>src</path>
<regex>focus\(|blur\(|onFocus|onBlur|autoFocus|focusable</regex>
</search_files>
]]></search_patterns>
</technique>
<technique name="responsive_design_analysis">
<description>
Analyze responsive design and mobile experience
</description>
<analysis_points>
<point>Breakpoint definitions</point>
<point>Mobile-specific components</point>
<point>Touch event handlers</point>
<point>Viewport configurations</point>
<point>Media queries</point>
</analysis_points>
<search_patterns><![CDATA[
<!-- Find responsive utilities -->
<search_files>
<path>src</path>
<regex>@media|breakpoint|mobile|tablet|desktop|responsive</regex>
</search_files>
<!-- Find touch events -->
<search_files>
<path>src</path>
<regex>onTouch|swipe|gesture|tap|press</regex>
</search_files>
]]></search_patterns>
</technique>
</ui_ux_analysis_techniques>
<code_analysis_techniques>
<technique name="semantic_search_analysis">
<description>
Use semantic search to find conceptually related code when available.
</description>
<when_to_use>
<scenario>Finding code by concept rather than keywords</scenario>
<scenario>Discovering implementations across different naming conventions</scenario>
<scenario>When pattern-based search isn't finding expected results</scenario>
</when_to_use>
<example><![CDATA[
<!-- Optional: Find authentication-related code semantically -->
<codebase_search>
<query>user authentication login security JWT token validation</query>
</codebase_search>
<!-- Optional: Find payment processing logic -->
<codebase_search>
<query>payment processing transaction billing invoice checkout</query>
</codebase_search>
]]></example>
<note>This is an optional tool - use when semantic understanding would help find related code that keyword search might miss</note>
</technique>
<technique name="entry_point_analysis">
<description>
Analyze entry points to understand feature flow.
</description>
<steps>
<step>Find main functions, controllers, or route handlers.</step>
<step>Trace execution flow.</step>
<step>Map decision branches.</step>
<step>Document input validation.</step>
</steps>
<discovery_methods>
<method name="directory_based">
<description>Start by exploring directory structure</description>
<example><![CDATA[
<!-- List main directories -->
<list_files>
<path>src</path>
<recursive>false</recursive>
</list_files>
<!-- Explore feature directory -->
<list_files>
<path>src/controllers</path>
<recursive>true</recursive>
</list_files>
]]></example>
</method>
<method name="pattern_based">
<description>Search for specific patterns</description>
<example><![CDATA[
<!-- Find all routes -->
<search_files>
<path>src</path>
<regex>(app\.(get|post|put|delete)|@(Get|Post|Put|Delete)|router\.(get|post|put|delete))</regex>
</search_files>
]]></example>
</method>
<method name="file_based">
<description>Read known entry points directly</description>
<example><![CDATA[
<!-- Read main application file -->
<read_file>
<path>src/app.ts</path>
</read_file>
<!-- Read specific controller -->
<read_file>
<path>src/controllers/feature.controller.ts</path>
</read_file>
]]></example>
</method>
<method name="semantic_based">
<description>Use semantic search as an alternative discovery method</description>
<example><![CDATA[
<!-- Optional: Find entry points semantically -->
<codebase_search>
<query>main entry point application startup initialization bootstrap</query>
</codebase_search>
]]></example>
</method>
</discovery_methods>
</technique>
<technique name="api_extraction">
<description>
Extract API specifications from code.
</description>
<patterns>
<pattern type="rest">
<search_regex><![CDATA[
(app|router)\.(get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`]
]]></search_regex>
<extraction>
- HTTP method
- Route path
- Path/query parameters
- Request/response schemas
- Status codes
</extraction>
</pattern>
<pattern type="graphql">
<search_regex><![CDATA[
type\s+(Query|Mutation|Subscription)\s*{[^}]+}|@(Query|Mutation|Resolver)
]]></search_regex>
<extraction>
- Schema and input types
- Resolvers
- Return types
- Field arguments
</extraction>
</pattern>
</patterns>
</technique>
<technique name="dependency_mapping">
<description>
Map dependencies and integration points.
</description>
<analysis_points>
<point>Import/require statements</point>
<point>package.json dependencies</point>
<point>External API calls</point>
<point>DB connections</point>
<point>Message queue integrations</point>
<point>Filesystem operations</point>
</analysis_points>
<analysis_approaches>
<approach name="package_analysis">
<description>Start with package.json to understand dependencies</description>
<example><![CDATA[
<!-- Analyze package dependencies -->
<read_file>
<path>package.json</path>
</read_file>
]]></example>
</approach>
<approach name="import_tracking">
<description>Follow import chains to map dependencies</description>
<example><![CDATA[
<!-- Find all imports -->
<search_files>
<path>src</path>
<regex>^import\s+.*from\s+['"]([^'"]+)['"]|require\s*\(\s*['"]([^'"]+)['"]\s*\)</regex>
</search_files>
]]></example>
</approach>
<approach name="api_discovery">
<description>Find external API integrations</description>
<example><![CDATA[
<!-- Find external API calls -->
<search_files>
<path>src</path>
<regex>(fetch|axios|http\.request|request\(|\.get\(|\.post\()</regex>
</search_files>
]]></example>
</approach>
</analysis_approaches>
</technique>
<technique name="data_model_extraction">
<description>
Extract data models, schemas, and type definitions.
</description>
<sources>
<source type="typescript">
<patterns>
- interfaces, types, classes, enums
</patterns>
</source>
<source type="database">
<patterns>
- Schema definitions, migration files, ORM models
</patterns>
</source>
<source type="validation">
<patterns>
- JSON Schema, Joi/Yup/Zod schemas, validation decorators
</patterns>
</source>
</sources>
<extraction_example><![CDATA[
<!-- Find TypeScript interfaces -->
<search_files>
<path>src</path>
<regex>^export\s+(interface|type|class|enum)\s+(\w+)</regex>
</search_files>
<!-- Find database models -->
<search_files>
<path>src/models</path>
<regex>@(Entity|Table|Model)|class\s+\w+\s+extends\s+(Model|BaseEntity)</regex>
</search_files>
]]></extraction_example>
</technique>
<technique name="business_logic_extraction">
<description>
Identify and document business rules.
</description>
<indicators>
<indicator>Complex conditionals</indicator>
<indicator>Calculation functions</indicator>
<indicator>Validation rules</indicator>
<indicator>State machines</indicator>
<indicator>Domain-specific constants and algorithms</indicator>
</indicators>
<documentation_focus>
<focus>Why logic exists (business need)</focus>
<focus>When logic applies (conditions)</focus>
<focus>What logic does (transformation)</focus>
<focus>Edge cases</focus>
<focus>Impact of changes</focus>
</documentation_focus>
</technique>
<technique name="error_handling_analysis">
<description>
Document error handling and recovery.
</description>
<analysis_areas>
<area>try/catch blocks, error boundaries</area>
<area>Custom error classes</area>
<area>Error codes and messages</area>
<area>Logging, fallbacks, retries, circuit breakers</area>
</analysis_areas>
<search_patterns><![CDATA[
<!-- Find error handling -->
<search_files>
<path>src</path>
<regex>try\s*{|catch\s*\(|throw\s+new|class\s+\w*Error\s+extends</regex>
</search_files>
<!-- Find error constants -->
<search_files>
<path>src</path>
<regex>ERROR_|_ERROR|ErrorCode|errorCode</regex>
</search_files>
]]></search_patterns>
</technique>
<technique name="security_analysis">
<description>
Identify security measures and vulnerabilities.
</description>
<security_checks>
<check category="authentication">
<patterns>
- JWT, sessions, OAuth, API keys
</patterns>
</check>
<check category="authorization">
<patterns>
- RBAC, permission checks, ownership validation
</patterns>
</check>
<check category="data_protection">
<patterns>
- Encryption, hashing, sensitive data handling
</patterns>
</check>
<check category="input_validation">
<patterns>
- Sanitization, SQLi/XSS/CSRF prevention
</parents>
</check>
</security_checks>
</technique>
<technique name="performance_analysis">
<description>
Identify performance factors and optimization opportunities.
</description>
<analysis_points>
<point>DB query patterns (N+1)</point>
<point>Caching strategies</point>
<point>Async usage</point>
<point>Batch processing</point>
<point>Resource pooling</point>
<point>Memory management</point>
<point>Algorithm complexity</point>
</analysis_points>
<metrics_to_document>
<metric>Time/space complexity</metric>
<metric>DB query counts</metric>
<metric>API response times</metric>
<metric>Memory usage</metric>
<metric>Concurrency handling</metric>
</metrics_to_document>
</technique>
<technique name="test_coverage_analysis">
<description>
Analyze test coverage.
</description>
<test_types>
<type name="unit">
<location>__tests__, *.test.ts, *.spec.ts</location>
<analysis>Function coverage</analysis>
</type>
<type name="integration">
<location>integration/, e2e/</location>
<analysis>Workflow coverage</analysis>
</type>
<type name="api">
<location>api-tests/, *.api.test.ts</location>
<analysis>Endpoint coverage</analysis>
</type>
</test_types>
<coverage_analysis><![CDATA[
<!-- Find test files -->
<search_files>
<path>src</path>
<regex>\.(test|spec)\.(ts|js|tsx|jsx)$</regex>
<file_pattern>*.test.ts</file_pattern>
</search_files>
<!-- Analyze test descriptions -->
<search_files>
<path>src</path>
<regex>(describe|it|test)\s*\(\s*['"`]([^'"`]+)['"`]</regex>
</search_files>
]]></coverage_analysis>
</technique>
<technique name="configuration_extraction">
<description>
Extract configuration options and their impacts.
</description>
<configuration_sources>
<source>.env files, config files, CLI args, feature flags</source>
</configuration_sources>
<documentation_requirements>
<requirement>Default values</requirement>
<requirement>Valid values</requirement>
<requirement>Behavior impact</requirement>
<requirement>Config dependencies</requirement>
<requirement>Security implications</requirement>
</documentation_requirements>
</technique>
</code_analysis_techniques>
<workflow_analysis>
<technique name="user_journey_mapping">
<description>
Map user workflows through the feature.
</description>
<steps>
<step>Identify entry points (UI, API, CLI).</step>
<step>Trace user actions.</step>
<step>Document decision points.</step>
<step>Map data transformations.</step>
<step>Identify outcomes.</step>
</steps>
<deliverables>
<deliverable>Flow diagrams, procedures, decision trees, state diagrams.</deliverable>
</deliverables>
</technique>
<technique name="integration_flow_analysis">
<description>
Document integration with other systems.
</description>
<integration_types>
<type>Sync API calls, async messaging, events, batch processing, streaming.</type>
</integration_types>
<documentation_focus>
<focus>Protocols, auth, error handling, data transforms, SLAs.</focus>
</documentation_focus>
</technique>
</workflow_analysis>
<metadata_extraction>
<technique name="version_compatibility">
<sources>
<source>package.json, READMEs, migration guides, breaking changes docs.</source>
</sources>
<extraction_pattern><![CDATA[
<!-- Find version requirements -->
<search_files>
<path>.</path>
<regex>"engines":|"peerDependencies":|requires?\s+\w+\s+version|compatible\s+with</regex>
</search_files>
]]></extraction_pattern>
</technique>
<technique name="deprecation_tracking">
<indicators>
<indicator>@deprecated, TODO comments, legacy code markers.</indicator>
</indicators>
<documentation_requirements>
<requirement>Deprecation date, removal timeline, migration path, alternatives.</requirement>
</documentation_requirements>
</technique>
</metadata_extraction>
<quality_indicators>
<indicator name="documentation_completeness">
<checks>
<check>Public APIs documented.</check>
<check>Examples for complex features.</check>
<check>Error scenarios covered.</check>
<check>Config options explained.</check>
<check>Security addressed.</check>
</checks>
</indicator>
<indicator name="code_quality_metrics">
<metrics>
<metric>Cyclomatic complexity, code duplication, test coverage, doc coverage, tech debt.</metric>
</metrics>
</indicator>
</quality_indicators>
</analysis_techniques>

View file

@ -1,133 +0,0 @@
<output_format>
<overview>
Structured data output formats for extraction and verification.
All output is YAML. No prose. No markdown formatting.
This data feeds into documentation-writer mode.
</overview>
<extraction_schema>
<description>Schema for EXTRACT-[feature].yaml files</description>
<template>
feature:
name: [feature name from code]
slug: [lowercase-hyphenated identifier]
extracted_at: [ISO timestamp]
source_files:
- [list of primary files]
identity:
entry_points:
- type: [command|ui|api|event]
name: [identifier]
location: [file:line]
components:
- name: [component name]
file: [path]
purpose: [one line from code comments or inferred]
behavior:
primary_action: [what it does - from code]
inputs:
- name: [input name]
type: [data type]
required: [true|false]
source: [file:line]
outputs:
- name: [output name]
type: [data type]
source: [file:line]
side_effects:
- description: [what changes]
source: [file:line]
configuration:
- name: [setting name]
key: [config key path]
type: [data type]
default: [default value]
valid_values: [list or range]
effect: [what it changes]
source: [file:line]
constraints:
prerequisites:
- description: [requirement]
source: [file:line]
limitations:
- description: [what cannot be done]
source: [file:line]
permissions:
- description: [permission needed]
source: [file:line]
errors:
- condition: [when this error occurs]
message: "[exact error message text]"
code: [error code if any]
source: [file:line]
ui:
components:
- name: [component name]
type: [button|panel|input|etc]
label: "[visible text]"
source: [file:line]
interactions:
- trigger: [user action]
result: [what happens]
source: [file:line]
integration:
internal:
- feature: [other feature name]
relationship: [how they interact]
source: [file:line]
external:
- service: [external service]
api: [endpoint or method]
source: [file:line]
</template>
</extraction_schema>
<verification_schema>
<description>Schema for VERIFY-[feature].yaml files</description>
<template>
verification:
feature: [feature name]
doc_source: [where the docs came from]
verified_at: [ISO timestamp]
summary:
total_claims: [count]
accurate: [count]
inaccurate: [count]
outdated: [count]
missing_context: [count]
unverifiable: [count]
claims:
- id: [claim-1]
quote: "[exact text from documentation]"
category: [behavior|configuration|constraint|error_handling|ui|integration|prerequisite]
status: [ACCURATE|INACCURATE|OUTDATED|MISSING_CONTEXT|UNVERIFIABLE]
evidence:
code_file: [file:line]
actual_behavior: [what code does - only if status is not ACCURATE]
code_quote: "[relevant code snippet]"
</template>
</verification_schema>
<output_rules>
<rule>Use YAML, not JSON or markdown</rule>
<rule>Include source file:line for every fact</rule>
<rule>Quote exact strings from code using double quotes</rule>
<rule>Use null for unknown/missing values, not empty strings</rule>
<rule>Keep descriptions factual and brief - one line max</rule>
<rule>Do NOT add commentary, suggestions, or explanations</rule>
</output_rules>
<file_naming>
<extraction>EXTRACT-[feature-slug].yaml</extraction>
<verification>VERIFY-[feature-slug].yaml</verification>
<location>.roo/extraction/</location>
</file_naming>
</output_format>

View file

@ -0,0 +1,397 @@
<tool_usage_guide>
<overview>
Guidance on using tools for documentation extraction.
</overview>
<discovery_approaches>
<approach name="flexible_discovery">
<description>Use the most appropriate tools for the situation</description>
<principles>
<principle>Start with what you know - file names, directory structure, or keywords</principle>
<principle>Use multiple discovery methods to build understanding</principle>
<principle>Adapt your approach based on the codebase structure</principle>
</principles>
</approach>
<common_tools>
<tool name="list_files">
<purpose>Explore directory structure and find relevant files</purpose>
<when_to_use>
- Starting exploration of a feature area
- Understanding project organization
- Finding configuration or test files
</when_to_use>
</tool>
<tool name="read_file">
<purpose>Examine specific files in detail</purpose>
<when_to_use>
- Analyzing implementation details
- Understanding configuration
- Reading documentation or comments
</when_to_use>
<tip>Read multiple related files together for better context</tip>
</tool>
<tool name="search_files">
<purpose>Find specific patterns or text</purpose>
<when_to_use>
- Locating API endpoints
- Finding configuration usage
- Tracking down error handling
- Discovering cross-references
</when_to_use>
</tool>
<tool name="list_code_definition_names">
<purpose>Get overview of code structure</purpose>
<when_to_use>
- Understanding module organization
- Identifying main components
- Finding test coverage
</when_to_use>
</tool>
<tool name="codebase_search">
<purpose>Semantic search when available</purpose>
<when_to_use>
- Finding conceptually related code
- Discovering implementations by functionality
- When keyword search isn't sufficient
</when_to_use>
<note>Optional - use when semantic understanding is needed</note>
</tool>
</common_tools>
<discovery_patterns>
<pattern name="top_down">
<description>Start from high-level structure and drill down</description>
<steps>
<step>List files in feature directory</step>
<step>Identify main entry points</step>
<step>Follow imports and dependencies</step>
<step>Examine implementation details</step>
</steps>
</pattern>
<pattern name="test_driven">
<description>Use tests to understand expected behavior</description>
<steps>
<step>Find test files for the feature</step>
<step>Read test descriptions and scenarios</step>
<step>Trace back to implementation</step>
<step>Verify behavior matches tests</step>
</steps>
</pattern>
<pattern name="configuration_first">
<description>Start with configuration to understand setup</description>
<steps>
<step>Find configuration files</step>
<step>Identify feature flags and settings</step>
<step>Trace usage in code</step>
<step>Document impacts of each setting</step>
</steps>
</pattern>
<pattern name="api_focused">
<description>Map external interfaces first</description>
<steps>
<step>Search for route definitions</step>
<step>Find API controllers or handlers</step>
<step>Trace to business logic</step>
<step>Document request/response flow</step>
</steps>
</pattern>
</discovery_patterns>
</discovery_approaches>
<documentation_generation_tools>
<tool name="write_to_file">
<purpose>Create extraction or verification report files.</purpose>
<note>Generates reports for documentation teams, not final documentation.</note>
<file_naming>
- For extraction: EXTRACTION-[feature-name].md
- For verification: VERIFICATION-[feature-name].md
</file_naming>
<best_practices>
<practice>Use descriptive feature name in filename.</practice>
<practice>Include table of contents.</practice>
<practice>Use consistent Markdown formatting.</practice>
<practice>Include syntax-highlighted code examples.</practice>
</best_practices>
<example><![CDATA[
<write_to_file>
<path>EXTRACTION-authentication-system.md</path>
<content>
# Authentication System Documentation
## Table of Contents
1. [Overview](#overview)
2. [Architecture](#architecture)
...
## Overview
The authentication system provides secure user authentication using JWT tokens...
</content>
<line_count>...</line_count>
</write_to_file>
]]></example>
</tool>
<tool name="ask_followup_question">
<purpose>Clarify ambiguous requirements.</purpose>
<when_to_use>
<scenario>Multiple features have similar names.</scenario>
<scenario>Documentation depth is unclear.</scenario>
<scenario>Audience priorities are undefined.</scenario>
</when_to_use>
<examples>
<example><![CDATA[
<ask_followup_question>
<question>Which authentication aspects should be the focus?</question>
<follow_up>
<suggest>The complete flow (JWT, sessions, OAuth).</suggest>
<suggest>Only JWT implementation and validation.</suggest>
<suggest>Only OAuth2 integration.</suggest>
<suggest>Password reset and recovery workflows.</suggest>
</follow_up>
</ask_followup_question>
]]></example>
<example><![CDATA[
<ask_followup_question>
<question>What level of technical detail is needed?</question>
<follow_up>
<suggest>High-level overview for all audiences.</suggest>
<suggest>Detailed developer implementation.</suggest>
<suggest>API reference with code examples.</suggest>
<suggest>Full coverage for all audiences.</suggest>
</follow_up>
</ask_followup_question>
]]></example>
</examples>
</tool>
</documentation_generation_tools>
<analysis_strategies>
<strategy name="file_discovery">
<description>
Find all files related to a feature using various methods.
</description>
<methods>
<method name="directory_exploration">
<description>Start by exploring likely directories</description>
<tool_use><![CDATA[
<list_files>
<path>src</path>
<recursive>false</recursive>
</list_files>
<!-- Then drill into feature directory -->
<list_files>
<path>src/features/[feature-name]</path>
<recursive>true</recursive>
</list_files>
]]></tool_use>
</method>
<method name="pattern_search">
<description>Search for feature-related patterns</description>
<tool_use><![CDATA[
<!-- Find files with feature name -->
<search_files>
<path>src</path>
<regex>feature-name|FeatureName</regex>
</search_files>
<!-- Find related tests -->
<search_files>
<path>src</path>
<regex>describe\(['"].*Feature.*['"]|test\(['"].*feature.*['"]</regex>
<file_pattern>*.test.ts</file_pattern>
</search_files>
]]></tool_use>
</method>
<method name="configuration_discovery">
<description>Find configuration files</description>
<tool_use><![CDATA[
<!-- Look for config files -->
<list_files>
<path>config</path>
<recursive>true</recursive>
</list_files>
<!-- Search for feature config -->
<search_files>
<path>.</path>
<regex>feature.*config|settings.*feature</regex>
<file_pattern>*.json</file_pattern>
</search_files>
]]></tool_use>
</method>
<method name="semantic_search_optional">
<description>Use semantic search if available and helpful</description>
<tool_use><![CDATA[
<!-- Optional: Use when concept-based search is needed -->
<codebase_search>
<query>feature implementation main logic</query>
</codebase_search>
]]></tool_use>
<note>This is optional - use when other methods aren't sufficient</note>
</method>
</methods>
</strategy>
<strategy name="dependency_chain_analysis">
<description>
Follow import chains to map dependencies.
</description>
<process>
<step>Read main file.</step>
<step>Extract all imports.</step>
<step>Read each imported file.</step>
<step>Recursively analyze imports.</step>
<step>Build dependency graph.</step>
</process>
<import_patterns><![CDATA[
<!-- TypeScript/JavaScript imports -->
<search_files>
<path>src/feature</path>
<regex>import\s+(?:{[^}]+}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]</regex>
</search_files>
<!-- CommonJS requires -->
<search_files>
<path>src/feature</path>
<regex>require\(['"]([^'"]+)['"]\)</regex>
</search_files>
]]></import_patterns>
</strategy>
<strategy name="api_documentation_extraction">
<description>
Extract API documentation from code.
</description>
<extraction_points>
<point>Route definitions, request/response schemas, auth requirements, rate limiting, error responses.</point>
</extraction_points>
<tools_sequence>
<sequence>
<step>Find route files.</step>
<step>Extract route definitions.</step>
<step>Find controllers.</step>
<step>Analyze request validation.</step>
<step>Document response formats.</step>
</sequence>
</tools_sequence>
</strategy>
<strategy name="test_driven_documentation">
<description>
Use tests to document expected behavior.
</description>
<benefits>
<benefit>Tests provide usage examples.</benefit>
<benefit>Test descriptions explain functionality.</benefit>
<benefit>Tests cover edge cases.</benefit>
<benefit>Tests document expected outputs.</benefit>
</benefits>
<extraction_approach><![CDATA[
<!-- Find test descriptions -->
<search_files>
<path>__tests__</path>
<regex>(describe|it|test)\(['"]([^'"]+)['"]</regex>
</search_files>
<!-- Extract test scenarios -->
<read_file>
<path>__tests__/feature.test.ts</path>
</read_file>
]]></extraction_approach>
</strategy>
</analysis_strategies>
<common_patterns>
<pattern name="configuration_documentation">
<search_locations>
<location>.env.example</location>
<location>config/*.json</location>
<location>src/config/*</location>
<location>README.md (configuration section)</location>
</search_locations>
<extraction_regex><![CDATA[
# Environment variables
process\.env\.(\w+)
# Config object access
config\.(\w+)\.(\w+)
# Default values
\w+\s*=\s*process\.env\.\w+\s*\|\|\s*['"]([^'"]+)['"]
]]></extraction_regex>
</pattern>
<pattern name="error_documentation">
<error_patterns>
<pattern>Custom error classes</pattern>
<pattern>Error code constants</pattern>
<pattern>Error message templates</pattern>
<pattern>HTTP status codes</pattern>
</error_patterns>
<search_approach><![CDATA[
<search_files>
<path>src</path>
<regex>class\s+\w*Error\s+extends|new Error\(|throw new|ERROR_CODE|HTTP_STATUS</regex>
</search_files>
]]></search_approach>
</pattern>
<pattern name="security_documentation">
<security_aspects>
<aspect>Authentication methods</aspect>
<aspect>Authorization rules</aspect>
<aspect>Data encryption</aspect>
<aspect>Input validation</aspect>
<aspect>Rate limiting</aspect>
</security_aspects>
<indicators><![CDATA[
<search_files>
<path>src</path>
<regex>@Authorized|requireAuth|checkPermission|encrypt|decrypt|sanitize|validate|rateLimit</regex>
</search_files>
]]></indicators>
</pattern>
</common_patterns>
<output_optimization>
<guideline name="structure">
<description>Organize output for navigation.</description>
<structure>
- Clear hierarchy, consistent headings, ToC with links, cross-references.
</structure>
</guideline>
<guideline name="code_examples">
<description>Include relevant code examples.</description>
<best_practices>
- Use syntax highlighting, show request/response, include error cases.
</best_practices>
</guideline>
<guideline name="visuals">
<description>Suggest diagrams where helpful.</description>
<diagram_types>
- Architecture, sequence, data flow, state machine diagrams.
</diagram_types>
</guideline>
<guideline name="metadata">
<description>Include important metadata.</description>
<required_metadata>
- Version compatibility, last updated, status, performance, security.
</required_metadata>
</guideline>
</output_optimization>
</tool_usage_guide>

View file

@ -0,0 +1,881 @@
<complete_extraction_examples>
<overview>
Examples of both documentation extraction and verification workflows demonstrating flexible discovery methods and comprehensive UI/UX analysis.
</overview>
<example name="authentication_system_extraction">
<scenario>
Extract comprehensive documentation for a JWT-based authentication system, including technical implementation, UI/UX elements, and user workflows.
</scenario>
<workflow>
<step number="1">
<description>Initialize and discover feature using flexible methods</description>
<tool_use><![CDATA[
<!-- Method 1: Directory exploration -->
<list_files>
<path>src</path>
<recursive>false</recursive>
</list_files>
]]></tool_use>
<analysis>Look for auth-related directories like auth/, authentication/, or security/</analysis>
<tool_use><![CDATA[
<list_files>
<path>src/auth</path>
<recursive>true</recursive>
</list_files>
]]></tool_use>
<expected_findings>
- Auth controllers, services, middleware, models, and routes
- Login components and forms
- Session management UI
</expected_findings>
</step>
<step number="2">
<description>Analyze code structure and architecture</description>
<tool_use><![CDATA[
<list_code_definition_names>
<path>src/auth</path>
</list_code_definition_names>
]]></tool_use>
<analysis>
- Identify main classes/functions
- Map authentication flow
- Find token generation/validation logic
- Locate UI components
</analysis>
</step>
<step number="3">
<description>Read core implementation files</description>
<tool_use><![CDATA[
<read_file>
<args>
<file>
<path>src/auth/auth.controller.ts</path>
</file>
<file>
<path>src/auth/auth.service.ts</path>
</file>
<file>
<path>src/auth/jwt.strategy.ts</path>
</file>
<file>
<path>src/auth/auth.guard.ts</path>
</file>
<file>
<path>src/models/user.model.ts</path>
</file>
</args>
</read_file>
]]></tool_use>
</step>
<step number="4">
<description>UI/UX Analysis - Discover UI components</description>
<tool_use><![CDATA[
<!-- Method 2: Pattern search for UI components -->
<search_files>
<path>src/components</path>
<regex>(Login|Auth|Session|Password).*\.(tsx?|jsx?)</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
]]></tool_use>
<tool_use><![CDATA[
<read_file>
<args>
<file>
<path>src/components/LoginForm.tsx</path>
</file>
<file>
<path>src/components/SessionManager.tsx</path>
</file>
<file>
<path>src/components/PasswordReset.tsx</path>
</file>
</args>
</read_file>
]]></tool_use>
</step>
<step number="5">
<description>UI/UX Analysis - Map user interactions</description>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>onClick|onSubmit|onChange|handleSubmit|validate</regex>
</search_files>
]]></tool_use>
<analysis>
- Form validation patterns
- User feedback mechanisms
- Error handling UI
- Loading states
</analysis>
</step>
<step number="6">
<description>UI/UX Analysis - Visual patterns and accessibility</description>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>className=|style=|theme\.|aria-|role=</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
]]></tool_use>
<tool_use><![CDATA[
<search_files>
<path>src/styles</path>
<regex>\.login|\.auth|\.session</regex>
<file_pattern>*.css</file_pattern>
</search_files>
]]></tool_use>
</step>
<step number="7">
<description>Extract API endpoints and configuration</description>
<tool_use><![CDATA[
<search_files>
<path>src/auth</path>
<regex>@(Post|Get)\(['"]\/auth\/[^'"]+['"]|router\.(post|get)\(['"]\/auth\/[^'"]+['"]</regex>
</search_files>
]]></tool_use>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>JWT_SECRET|JWT_EXPIRATION|AUTH_.*|process\.env\.\w*AUTH\w*</regex>
</search_files>
]]></tool_use>
</step>
<step number="8">
<description>Optional: Use semantic search for deeper insights</description>
<tool_use><![CDATA[
<!-- Only if pattern searches miss important context -->
<codebase_search>
<query>authentication error handling user feedback messages</query>
</codebase_search>
]]></tool_use>
<note>Used when specific patterns don't capture all relevant error handling</note>
</step>
<step number="9">
<description>Create comprehensive extraction report</description>
<tool_use><![CDATA[
<write_to_file>
<path>EXTRACTION-authentication-system.md</path>
<content>
# Authentication System - Feature Extraction Report
## Executive Summary
The authentication system is a JWT-based security implementation that handles user registration, login, session management, and access control. It provides a comprehensive user experience with visual feedback, accessibility features, and robust error handling.
## UI/UX Analysis
### User Interface Components
#### 1. Login Page (`src/components/LoginForm.tsx`)
**Visual Layout:**
- Centered card design with shadow (400px width)
- Company logo at top
- Form fields with floating labels
- Primary blue theme (#1976d2)
**Interactive Elements:**
- Email input field
- Real-time validation (regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/)
- Error state: Red border and helper text
- Success state: Green checkmark icon
- Password field
- Show/hide toggle button (eye icon)
- Minimum 8 characters validation
- Caps lock warning indicator
- "Remember me" checkbox with 30-day persistence
- "Forgot password?" link (underlined on hover)
- Submit button
- Disabled state: Gray background until valid input
- Loading state: Spinner replaces text
- Success state: Checkmark animation
**User Feedback:**
- Loading overlay with spinner during authentication
- Error messages appear with slide-down animation
- Success toast notification (3s duration)
- Form shake animation on error
#### 2. Registration Form (`src/components/RegisterForm.tsx`)
**Multi-Step Design:**
- Progress bar showing 3 steps
- Smooth slide transitions between steps
- Back/Next navigation buttons
**Step 1 - Account Info:**
- Email field with async availability check
- Password field with strength meter (5 levels)
- Password confirmation with match validation
**Step 2 - Personal Info:**
- First/Last name fields
- Optional phone with format mask
- Country dropdown with flag icons
**Step 3 - Terms & Submit:**
- Terms of service scrollable text
- Privacy policy link (opens modal)
- Checkbox required for submission
- Review summary before final submit
**Visual Feedback:**
- Field validation on blur
- Progress saved in localStorage
- Success confetti animation
- Auto-redirect countdown (5s)
#### 3. Session Management (`src/components/SessionManager.tsx`)
**Device List UI:**
- Card-based layout for each session
- Device icons (FontAwesome)
- fa-mobile for mobile
- fa-desktop for desktop
- fa-tablet for tablet
- Information displayed:
- Device name and browser
- IP address (partially masked)
- Last active (relative time)
- Location (city, country)
**Interactive Features:**
- Current device highlighted with blue border
- Hover state shows "Revoke" button
- Confirmation modal with device details
- Bulk selection with checkboxes
- "Revoke All" with double confirmation
### User Experience Elements
#### Visual Patterns
**Theme System:**
```css
--primary-color: #1976d2;
--error-color: #d32f2f;
--success-color: #388e3c;
--warning-color: #f57c00;
--text-primary: rgba(0, 0, 0, 0.87);
--text-secondary: rgba(0, 0, 0, 0.6);
```
**Animations:**
- Page transitions: 300ms ease-in-out
- Button hover: scale(1.02)
- Error shake: 0.5s horizontal
- Success checkmark: SVG path animation
- Loading spinner: 1s rotation
**Responsive Breakpoints:**
- Mobile: < 768px (single column)
- Tablet: 768px - 1024px
- Desktop: > 1024px
#### Accessibility Features
**Keyboard Navigation:**
- Tab order follows visual flow
- Enter key submits forms
- Escape closes modals
- Arrow keys in dropdowns
**Screen Reader Support:**
- ARIA labels on all inputs
- Live regions for errors
- Role attributes for custom components
- Descriptive button text
**Visual Accessibility:**
- 4.5:1 contrast ratio minimum
- Focus indicators (2px outline)
- Error icons for colorblind users
- Scalable fonts (rem units)
### User Workflows
#### 1. First-Time Registration
```
Start → Landing Page → "Get Started" CTA
Registration Form (Step 1)
→ Email validation (async)
→ Password strength check
→ Real-time feedback
Personal Info (Step 2)
→ Optional fields clearly marked
→ Format validation
Terms Agreement (Step 3)
→ Must scroll to enable checkbox
→ Review summary
Submit → Loading → Success
→ Confetti animation
→ Welcome email sent
→ Auto-redirect (5s)
Dashboard (First-time tour)
```
#### 2. Returning User Login
```
Start → Login Page
Enter Credentials
→ Email autocomplete
→ Password manager integration
→ "Remember me" option
Submit → Loading (avg 1.2s)
Success → Dashboard
OR
Error → Inline feedback
→ Retry with guidance
→ "Forgot password?" option
```
#### 3. Password Reset Flow
```
Login Page → "Forgot password?"
Modal Dialog
→ Email input
→ Captcha (if multiple attempts)
Submit → "Check email" message
Email Received (< 1 min)
→ Secure link (1hr expiry)
Reset Page
→ New password requirements shown
→ Strength meter
→ Confirmation field
Submit → Success → Login redirect
```
## Technical Details
### Core Components
1. **AuthController** (`src/auth/auth.controller.ts`)
- REST endpoints with validation decorators
- Rate limiting middleware
- CORS configuration
2. **AuthService** (`src/auth/auth.service.ts`)
- JWT token generation/validation
- Bcrypt password hashing
- Session management logic
3. **Security Implementation**
- JWT RS256 algorithm
- Refresh token rotation
- CSRF double-submit cookies
- XSS protection headers
### API Endpoints
| Method | Endpoint | Description | Rate Limit |
|--------|----------|-------------|------------|
| POST | /auth/register | New user registration | 3/hour |
| POST | /auth/login | User authentication | 5/min |
| POST | /auth/refresh | Token refresh | 10/min |
| POST | /auth/logout | Session termination | None |
| GET | /auth/profile | Current user data | None |
| POST | /auth/reset-password | Password reset | 3/hour |
### Configuration
```env
# Required
JWT_SECRET=minimum-32-character-secret
DATABASE_URL=postgresql://...
# Optional with defaults
JWT_EXPIRATION=15m
REFRESH_TOKEN_EXPIRATION=7d
BCRYPT_ROUNDS=10
SESSION_MAX_AGE=30d
MAX_SESSIONS_PER_USER=5
```
## Non-Technical Information
### Business Rules
1. **Account Creation**
- Unique email required
- Password: 8+ chars, mixed case, number, special
- Email verification within 24 hours
- Terms acceptance mandatory
2. **Session Management**
- Max 5 concurrent sessions
- Idle timeout: 30 minutes
- Absolute timeout: 7 days
- Device trust for 30 days
3. **Security Policies**
- Account lockout: 5 failed attempts (15 min)
- Password history: Last 3 not reusable
- 2FA optional but recommended
- Suspicious login notifications
### Common User Scenarios
#### Mobile Experience
- Touch-optimized buttons (44px min)
- Biometric login (Face ID/Touch ID)
- Simplified navigation menu
- Offline detection with retry
- Push notification for new sessions
#### Error Recovery
- Network timeout: Auto-retry with backoff
- Session expired: Smooth re-login flow
- Form errors: Contextual help text
- Server errors: Friendly messages with support link
### Performance Metrics
- Login response: 200ms (p50), 500ms (p95)
- Page load: 1.2s (3G), 400ms (4G)
- Token validation: < 10ms
- Session check: < 50ms
## Documentation Recommendations
### Critical Areas for User Documentation
1. **Getting Started Guide**
- Screenshots of each registration step
- Common email provider settings
- Password manager setup
2. **Troubleshooting Section**
- "Why can't I log in?" flowchart
- Browser compatibility matrix
- Cookie/JavaScript requirements
3. **Security Best Practices**
- How to spot phishing attempts
- Importance of unique passwords
- When to revoke sessions
### Developer Integration Guide
1. **API Authentication**
- Bearer token format
- Refresh token flow diagram
- Error response examples
2. **SDK Examples**
- JavaScript/TypeScript
- Python
- Mobile (iOS/Android)
## Integration Points
- Email service for password reset and notifications
- Session storage (Redis optional, in-memory default)
- Rate limiting middleware
- CORS configuration for cross-origin requests
- Logging service for audit trails
## Summary for Documentation Team
This extraction report provides comprehensive details about the authentication system's current implementation. The system offers a complete user experience with visual feedback, accessibility features, and robust security measures. Key areas for user documentation include the multi-step registration process, session management features, and security policies. The technical implementation uses industry-standard JWT tokens with proper security measures.
</content>
<line_count>354</line_count>
</write_to_file>
]]></tool_use>
</step>
</workflow>
<key_takeaways>
<takeaway>Use flexible discovery methods - directory exploration and pattern search are primary tools</takeaway>
<takeaway>Comprehensive UI/UX analysis is essential for complete documentation</takeaway>
<takeaway>Document visual elements, interactions, and user feedback mechanisms</takeaway>
<takeaway>Include accessibility and responsive design considerations</takeaway>
<takeaway>Semantic search (codebase_search) is optional for deeper insights when needed</takeaway>
<takeaway>Organize findings to support documentation team's work</takeaway>
</key_takeaways>
</example>
<example name="documentation_verification_example">
<scenario>
Verify user-provided documentation about authentication UI/UX against the actual implementation.
</scenario>
<workflow>
<step number="1">
<description>User provides documentation to verify</description>
<user_input>
"Please verify our login documentation:
'The login form provides a seamless experience with instant validation. Users see a green checkmark when their email is valid. The password field includes a strength indicator. After 3 failed attempts, users must wait 5 minutes before trying again.'"
</user_input>
</step>
<step number="2">
<description>Analyze the documentation claims</description>
<analysis>
Claims to verify:
- Instant email validation with green checkmark
- Password strength indicator on login
- 3 failed attempts triggers 5-minute wait
</analysis>
</step>
<step number="3">
<description>Find login UI components using directory exploration</description>
<tool_use><![CDATA[
<list_files>
<path>src/components</path>
<recursive>false</recursive>
</list_files>
]]></tool_use>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>Login|SignIn|Auth.*Form</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
]]></tool_use>
</step>
<step number="4">
<description>Examine login form implementation</description>
<tool_use><![CDATA[
<read_file>
<args>
<file>
<path>src/components/LoginForm.tsx</path>
</file>
<file>
<path>src/components/LoginForm.css</path>
</file>
</args>
</read_file>
]]></tool_use>
<findings>
- Email validation exists but shows red X, not green checkmark
- No password strength indicator on login form (only on registration)
- Account lockout is after 5 attempts, not 3
- Lockout duration is 15 minutes, not 5
</findings>
</step>
<step number="5">
<description>Verify validation behavior</description>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>validateEmail|emailValid|checkmark|strength.*indicator</regex>
</search_files>
]]></tool_use>
<tool_use><![CDATA[
<search_files>
<path>src/auth</path>
<regex>failed.*attempts|lockout|rate.*limit</regex>
</search_files>
]]></tool_use>
</step>
<step number="6">
<description>Create verification report</description>
<tool_use><![CDATA[
<write_to_file>
<path>VERIFICATION-login-documentation.md</path>
<content>
# Login Documentation - Verification Report
## Overall Assessment: Needs Significant Updates
## Summary
The login documentation contains several inaccuracies about the UI/UX implementation that could confuse users and lead to poor user experience.
## Critical Inaccuracies
### 1. Email Validation Feedback
**Documentation States**: "Users see a green checkmark when their email is valid"
**Actual Implementation**: Red X icon for invalid emails, no positive feedback
- Location: `src/components/LoginForm.tsx:45-52`
- Current behavior: Only shows error states
- Missing: Success indicator implementation
- **Impact**: Users don't get positive reinforcement for correct input
### 2. Password Strength Indicator
**Documentation States**: "The password field includes a strength indicator"
**Actual Implementation**: No strength indicator on login form
- Location: Checked `src/components/LoginForm.tsx`
- Strength indicator only exists in `RegisterForm.tsx`
- Login form has basic password field only
- **Impact**: Sets incorrect user expectations
### 3. Failed Login Attempts
**Documentation States**: "After 3 failed attempts, users must wait 5 minutes"
**Actual Implementation**: 5 attempts, 15-minute lockout
- Location: `src/auth/services/auth.service.ts:234`
- Code: `MAX_LOGIN_ATTEMPTS = 5`
- Code: `LOCKOUT_DURATION = 15 * 60 * 1000 // 15 minutes`
- **Impact**: Users may be confused about actual security policy
## UI/UX Elements Found But Not Documented
### 1. Loading States
- Spinner overlay during authentication
- Button disabled state during submission
- These improve perceived performance
### 2. Remember Me Feature
- 30-day persistent session option
- Stored in secure cookie
- Not mentioned in documentation
### 3. Caps Lock Warning
- Visual indicator when caps lock is on
- Helps prevent login failures
- Important accessibility feature
## Recommendations
### Immediate Corrections Needed
1. **Email Validation**:
```
CORRECT: "The email field shows a red error icon for invalid formats. Valid emails are accepted without visual confirmation."
```
2. **Password Features**:
```
CORRECT: "The login form has a standard password field with show/hide toggle. Password strength indicators are only shown during registration."
```
3. **Security Policy**:
```
CORRECT: "After 5 failed login attempts, accounts are temporarily locked for 15 minutes to prevent brute force attacks."
```
### Suggested Additions
1. Document the loading states and visual feedback
2. Explain the "Remember Me" functionality
3. Mention the Caps Lock warning feature
4. Add screenshots of actual UI states
## Technical References
- Login Form Component: `src/components/LoginForm.tsx`
- Styles: `src/components/LoginForm.css`
- Auth Service: `src/auth/services/auth.service.ts`
- Rate Limiting: `src/middleware/rateLimiter.ts`
## Visual Discrepancies
- Documentation implies more visual feedback than implemented
- Color scheme in docs doesn't match actual theme
- Missing documentation for error message styling
## Conclusion
The documentation needs updates to accurately reflect the current login experience. The actual implementation is more security-focused (5 attempts, 15-min lockout) but less visually rich (no success indicators) than documented.
</content>
<line_count>95</line_count>
</write_to_file>
]]></tool_use>
</step>
</workflow>
<key_takeaways>
<takeaway>Always verify UI/UX claims against actual component implementation</takeaway>
<takeaway>Check both visual elements and behavioral logic</takeaway>
<takeaway>Look for undocumented features that users might expect</takeaway>
<takeaway>Provide specific corrections with code references</takeaway>
<takeaway>Consider the impact of inaccuracies on user experience</takeaway>
</key_takeaways>
</example>
<example name="api_endpoint_extraction">
<scenario>
Extract comprehensive API documentation including endpoints, request/response formats, and error handling.
</scenario>
<workflow>
<step number="1">
<description>Discover API structure using flexible methods</description>
<tool_use><![CDATA[
<!-- Method 1: Look for common API directories -->
<list_files>
<path>src</path>
<recursive>false</recursive>
</list_files>
]]></tool_use>
<tool_use><![CDATA[
<list_files>
<path>src/api</path>
<recursive>true</recursive>
</list_files>
]]></tool_use>
</step>
<step number="2">
<description>Find all API routes using pattern search</description>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>(app|router)\.(get|post|put|patch|delete|all)\s*\(\s*['"`]([^'"`]+)['"`]</regex>
</search_files>
]]></tool_use>
</step>
<step number="3">
<description>Extract request validation schemas</description>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>@(Body|Query|Param|Headers)\(|joi\.object|yup\.object|zod\.object</regex>
</search_files>
]]></tool_use>
</step>
<step number="4">
<description>Analyze error handling and responses</description>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>@ApiResponse|response\.status\(|res\.status\(|throw new.*Error</regex>
</search_files>
]]></tool_use>
</step>
<step number="5">
<description>Optional: Semantic search for middleware and auth</description>
<tool_use><![CDATA[
<!-- Use when pattern search might miss complex middleware chains -->
<codebase_search>
<query>API middleware authentication authorization guards</query>
</codebase_search>
]]></tool_use>
</step>
<step number="6">
<description>Generate API extraction report</description>
<output>
- Complete endpoint inventory with methods and paths
- Request/response schemas with examples
- Authentication requirements per endpoint
- Rate limiting and throttling rules
- Error response formats and codes
- API versioning strategy
</output>
</step>
</workflow>
</example>
<example name="ui_component_library_extraction">
<scenario>
Document a React component library including props, styling, accessibility, and usage patterns.
</scenario>
<workflow>
<step number="1">
<description>Discover component structure</description>
<tool_use><![CDATA[
<list_files>
<path>src/components</path>
<recursive>true</recursive>
</list_files>
]]></tool_use>
</step>
<step number="2">
<description>Analyze component interfaces and props</description>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>interface\s+\w+Props|type\s+\w+Props|export\s+(default\s+)?function|export\s+const</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
]]></tool_use>
</step>
<step number="3">
<description>Extract styling and theme usage</description>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>styled\.|makeStyles|className=|sx=|css=</regex>
</search_files>
]]></tool_use>
</step>
<step number="4">
<description>Document accessibility features</description>
<tool_use><![CDATA[
<search_files>
<path>src/components</path>
<regex>aria-|role=|tabIndex|alt=|htmlFor=</regex>
</search_files>
]]></tool_use>
</step>
<step number="5">
<description>Find usage examples and stories</description>
<tool_use><![CDATA[
<search_files>
<path>src</path>
<regex>\.stories\.|\.story\.|examples?/|demo/</regex>
<file_pattern>*.tsx</file_pattern>
</search_files>
]]></tool_use>
</step>
<step number="6">
<description>Create component library report</description>
<output>
- Component hierarchy and relationships
- Props documentation with types and defaults
- Styling system and customization options
- Accessibility compliance checklist
- Interactive examples and code snippets
- Best practices and anti-patterns
- Browser compatibility notes
</output>
</step>
</workflow>
</example>
<best_practices>
<practice name="flexible_discovery">
<description>Use the most appropriate discovery method</description>
<guidelines>
<guideline>Start with directory exploration for well-organized codebases</guideline>
<guideline>Use pattern search for specific syntax or naming conventions</guideline>
<guideline>Apply file-based search when you know exact locations</guideline>
<guideline>Reserve semantic search for complex conceptual queries</guideline>
</guidelines>
</practice>
<practice name="comprehensive_ui_ux_coverage">
<description>Ensure complete UI/UX documentation</description>
<checklist>
<item>Visual design and layout</item>
<item>Interactive elements and states</item>
<item>User feedback mechanisms</item>
<item>Accessibility features</item>
<item>Responsive behavior</item>
<item>Animation and transitions</item>
<item>Error states and recovery</item>
<item>Loading and progress indicators</item>
</checklist>
</practice>
<practice name="verification_thoroughness">
<description>Verify all aspects of documentation claims</description>
<checklist>
<item>Technical accuracy of code examples</item>
<item>UI element descriptions match implementation</item>
<item>User workflows reflect actual behavior</item>
<item>Configuration values are current</item>
<item>Error messages match code</item>
<item>Performance claims are realistic</item>
</checklist>
</practice>
</best_practices>
</complete_extraction_examples>

View file

@ -0,0 +1,314 @@
<communication_guidelines>
<overview>
Guidelines for user communication and output formatting.
</overview>
<user_interaction>
<initial_contact>
<principle>Act on the user's request immediately.</principle>
<principle>Only ask for clarification if the request is ambiguous.</principle>
</initial_contact>
<clarification>
<when_to_ask>
<scenario>Multiple features with similar names are found.</scenario>
<scenario>The request is ambiguous.</scenario>
<scenario>The user explicitly asks for options.</scenario>
</when_to_ask>
<question_example><![CDATA[
<ask_followup_question>
<question>Found multiple auth systems. Which to document?</question>
<follow_up>
<suggest>JWT-based system (src/auth/jwt/*)</suggest>
<suggest>OAuth2 integration (src/auth/oauth/*)</suggest>
<suggest>Basic auth middleware (src/middleware/basic-auth.ts)</suggest>
<suggest>All of them</suggest>
</follow_up>
</ask_followup_question>
]]></question_example>
</clarification>
<progress_updates>
<when_to_update>
<trigger>Starting a major analysis phase.</trigger>
<trigger>Extraction is complete.</trigger>
<trigger>Unexpected complexity is found.</trigger>
</when_to_update>
<update_format>
<template>
Analyzing [component]...
- Found [X] related files.
- Identified [Y] API endpoints.
- Found [Z] config options.
</template>
</update_format>
</progress_updates>
<findings_communication>
<important_findings>
<discovery type="security_issue">
Alert user to security concerns found during analysis.
</discovery>
<discovery type="deprecated_code">
Note deprecated features needing migration docs.
</discovery>
<discovery type="missing_docs">
Highlight code that lacks inline documentation.
</discovery>
<discovery type="complex_dependencies">
Warn about complex dependency chains.
</discovery>
</important_findings>
<extraction_findings>
<template><![CDATA[
Feature extraction complete for [feature name].
**Extraction Report**: `EXTRACTION-[feature].md`
**Key Findings**:
- Technical Components: [X] classes, [Y] APIs, [Z] configurations
- User Workflows: [number] primary use cases identified
- Business Logic: [summary of core functionality]
- Integration Points: [list of external dependencies]
**Documentation Considerations**:
- [Important aspect that needs clear explanation]
- [Complex area that may need diagrams]
- [Edge cases that should be documented]
The extraction report provides comprehensive details for your documentation team.
]]></template>
</extraction_findings>
<verification_findings>
<template><![CDATA[
Documentation verification complete.
**Verification Report**: `VERIFICATION-[feature].md`
**Overall Assessment**: [Accurate/Needs Updates/Contains Critical Errors]
**Summary of Findings**:
- Critical Inaccuracies: [number]
- Technical Corrections Needed: [number]
- Missing Information: [number]
- Clarity Improvements: [number]
**Most Important Issues**:
1. [Critical issue that could mislead users]
2. [Important technical inaccuracy]
3. [Key missing information]
See the full verification report for detailed corrections and suggestions.
]]></template>
</verification_findings>
</findings_communication>
</user_interaction>
<output_formatting>
<markdown_standards>
<headings>
<rule>Use # for main title, ## for major sections, ### for subsections.</rule>
<rule>Never skip heading levels.</rule>
</headings>
<code_blocks>
<rule>Always specify language for syntax highlighting (e.g., typescript, json, bash).</rule>
<rule>Include file paths as comments where relevant.</rule>
<example><![CDATA[
```typescript
// src/auth/auth.service.ts
export class AuthService {
async validateUser(email: string, password: string): Promise<User> {
// Implementation
}
}
```
]]></example>
</code_blocks>
<tables>
<rule>Use tables for structured data like configs.</rule>
<rule>Include headers and align columns.</rule>
<rule>Keep cell content brief.</rule>
<example><![CDATA[
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `JWT_SECRET` | string | - | Secret key for JWT signing |
| `JWT_EXPIRATION` | string | '15m' | Token expiration time |
]]></example>
</tables>
<lists>
<rule>Use bullets for unordered lists, numbers for sequential steps.</rule>
<rule>Keep list items parallel in structure.</rule>
</lists>
</markdown_standards>
<cross_references>
<internal_links>
<format>[Link text](#section-anchor)</format>
<rule>Use lowercase, hyphenated anchors. Test all links.</rule>
</internal_links>
<external_links>
<format>[Link text](https://example.com)</format>
<rule>Use HTTPS. Link to official docs.</rule>
</external_links>
<file_references>
<format>`path/to/file.ts`</format>
<rule>Use relative paths from project root, in backticks.</rule>
</file_references>
</cross_references>
<special_sections>
<alerts>
<type name="warning">
<format>> ⚠️ **Warning**: [message]</format>
<use_for>Security, breaking changes, deprecations.</use_for>
</type>
<type name="note">
<format>> 📝 **Note**: [message]</format>
<use_for>Important info, clarifications.</use_for>
</type>
<type name="tip">
<format>> 💡 **Tip**: [message]</format>
<use_for>Best practices, optimizations.</use_for>
</type>
</alerts>
<metadata_blocks>
<version_info><![CDATA[
---
Feature: Authentication System
Version: 2.1.0
Last Updated: 2024-01-15
Status: Stable
---
]]></version_info>
</metadata_blocks>
</special_sections>
</output_formatting>
<documentation_tone>
<general>
<principle>Be direct, not conversational.</principle>
<principle>Use active voice.</principle>
<principle>Lead with benefits.</principle>
<principle>Use concrete examples.</principle>
<principle>Keep paragraphs short.</principle>
<principle>Avoid unnecessary technical details.</principle>
</general>
<audience_tone>
<audience type="developer">
<tone>Technical and direct.</tone>
<vocabulary>Standard programming terms.</vocabulary>
<examples>Code snippets, implementation details.</examples>
</audience>
<audience type="end_user">
<tone>Instructional, step-by-step.</tone>
<vocabulary>Simple language, no jargon.</vocabulary>
<examples>Screenshots, real-world scenarios.</examples>
</audience>
<audience type="administrator">
<tone>Operational focus.</tone>
<vocabulary>IT/DevOps terms.</vocabulary>
<examples>CLI examples, configs.</examples>
</audience>
</audience_tone>
</documentation_tone>
<completion_message>
<structure>
<element>Summary of analysis performed.</element>
<element>Key findings or issues identified.</element>
<element>Report file location.</element>
<element>Recommended next steps.</element>
</structure>
<extraction_example><![CDATA[
Feature extraction complete for the authentication system.
**Extraction Report**: `EXTRACTION-authentication-system.md`
**Technical Summary**:
- JWT-based authentication with refresh tokens
- 5 API endpoints (login, logout, refresh, register, profile)
- 12 configuration options
- bcrypt password hashing, rate limiting
**Non-Technical Summary**:
- Users can register, login, and manage sessions
- Supports "remember me" functionality
- Automatic session refresh for seamless experience
- Account lockout after failed attempts
**Documentation Considerations**:
- Token expiration times need clear explanation
- Password requirements should be prominently displayed
- Error messages need user-friendly translations
The extraction report contains all details needed for comprehensive documentation.
]]></extraction_example>
<verification_example><![CDATA[
Documentation verification complete for the authentication system.
**Verification Report**: `VERIFICATION-authentication-system.md`
**Overall Assessment**: Needs Updates
**Critical Issues Found**:
1. JWT_SECRET documented as optional, but it's required
2. Token expiration listed as 30m, actual is 15m
3. Missing documentation for rate limiting feature
**Technical Corrections**: 7 items
**Missing Information**: 4 sections
**Clarity Improvements**: 3 suggestions
Please review the verification report for specific corrections needed.
]]></verification_example>
</completion_message>
<error_handling>
<scenarios>
<scenario type="feature_not_found">
<response>
Could not find a feature matching "[feature name]". Similar features found:
- [List similar features]
Document one of these instead?
</response>
</scenario>
<scenario type="insufficient_docs">
<response>
Code for [feature] has limited inline documentation. Extracting from code structure, tests, and usage patterns.
</response>
</scenario>
<scenario type="complex_feature">
<response>
This feature is complex. Choose documentation scope:
- Document comprehensively
- Focus on core functionality
- Split into multiple documents
</response>
</scenario>
</scenarios>
</error_handling>
<quality_checks>
<before_completion>
<check>No placeholder content remains.</check>
<check>Code examples are correct.</check>
<check>Links and cross-references work.</check>
<check>Tables are formatted correctly.</check>
<check>Version info is included.</check>
<check>Filename follows conventions.</check>
</before_completion>
</quality_checks>
</communication_guidelines>

View file

@ -0,0 +1,218 @@
<user_friendly_examples>
<overview>
Examples for creating user-focused, practical documentation.
</overview>
<writing_principles>
<principle name="benefits_over_features">
<bad>The concurrent file read feature uses parallel processing.</bad>
<good>Read multiple files at once, reducing interruptions.</good>
</principle>
<principle name="use_scenarios">
<bad>This improves efficiency.</bad>
<good>Instead of approving 10 file reads one-by-one, approve them all at once.</good>
</principle>
<principle name="hide_implementation_details">
<bad>The feature uses a thread pool with configurable concurrency limits.</bad>
<good>Roo reads up to 100 files at once (changeable in settings).</good>
</principle>
<principle name="direct_tone">
<bad>Users must configure the concurrent file read limit parameter.</bad>
<good>Adjust how many files Roo reads at once in settings.</good>
</principle>
</writing_principles>
<structure_examples>
<example name="feature_intro">
<template><![CDATA[
# [Feature Name]
[One-sentence description of what it does.]
### Key Features
- [Benefit 1]
- [Benefit 2]
- [Benefit 3]
---
]]></template>
</example>
<example name="use_case">
<template><![CDATA[
## Use Case
**Before**: [Description of the old way]
- [Pain point]
- [Pain point]
**Now**: [Description of the new way]
]]></template>
</example>
<example name="configuration">
<template><![CDATA[
## Configuration
Customize this feature in settings:
1. **[Setting Name]**
- **Does**: [Plain language explanation.]
- **Default**: [Default value.] (Works for most.)
- **Change if**: [Specific scenarios to adjust this.]
2. **[Setting Name]**
- **Does**: [Plain language explanation.]
- **Default**: [Default value.]
- **Change if**: [Specific use case.]
]]></template>
</example>
<example name="faq">
<template><![CDATA[
## FAQ
**"[User question]"**
- [Direct answer.]
- [Optional tip.]
**"[Another question]"**
- [Direct answer.]
- [Optional link.]
]]></template>
</example>
<example name="troubleshooting">
<template><![CDATA[
## Troubleshooting
### [Problem symptom]
**Cause**: [Brief explanation.]
**Fix**: [Immediate solution.]
**Alternate fix**: [Alternative solution.]
### [Another issue]
**Scenario**: [When this happens.]
**Solution**:
1. [Step 1]
2. [Step 2]
]]></template>
</example>
</structure_examples>
<tone_examples>
<explanations>
<example context="limit">
<technical>The system imposes a hard limit of 100 concurrent operations.</technical>
<direct>Roo handles up to 100 files at once.</direct>
</example>
<example context="error">
<technical>Error: Maximum concurrency threshold exceeded.</technical>
<direct>Too many files requested. Lower the file limit in settings.</direct>
</example>
<example context="benefit">
<technical>Reduces API call overhead through request batching.</technical>
<direct>Get answers faster by reading all needed files at once.</direct>
</example>
</explanations>
<visuals>
<emojis>
<when>Error: ⚠️</when>
<when>Tip: 💡</when>
<when>Note: 📝</when>
<when>Security: 🔒</when>
</emojis>
<formatting>
<bold>For emphasis</bold>
<code>For settings, file paths, or commands</code>
<blockquotes>For callouts or warnings</blockquotes>
</formatting>
</visuals>
</tone_examples>
<real_world_example>
<title>Concurrent File Reads Doc</title>
<content><![CDATA[
# Concurrent File Reads
Read multiple files from your workspace in a single step.
### Key Features
- Read up to 100 files in one request.
- Enabled by default for faster workflow.
- Configurable to match system capabilities.
---
## Use Case
**Before**: Multiple, sequential requests to read files:
- "Read `src/app.js`?" → Approve
- "Read `src/utils.js`?" → Approve
- "Read `src/config.json`?" → Approve
**Now**: Roo asks once to read all related files.
## How it Works
Roo automatically identifies and reads relevant files together for tasks requiring multi-file context, such as:
- Understanding components split across multiple files.
- Refactoring code with dependencies.
- Answering questions requiring broad project context.
The [`read_file`](/tools/read-file) tool accepts multiple files in a single request.
---
## Configuration
Customize in Roo's settings:
1. **Enable/Disable Concurrent File Reads**
- **Does**: Toggles whether Roo can read multiple files at once.
- **Default**: Enabled.
- **Disable if**: Using a less capable AI model or requiring more access control.
2. **Concurrent File Reads Limit**
- **Does**: Sets max number of files Roo can read at once.
- **Default**: 100.
- **Adjust**: Lower for memory constraints; raise for very large projects.
---
## FAQ
**"Too many files are requested at once."**
- Lower the file limit in settings.
- Deny individual files in the batch dialog.
**"Some files were denied but others were approved."**
- Normal behavior. Roo works with approved files.
- Files may be blocked by `.rooignore` settings.
**"Does this use more memory?"**
- Yes, but the impact is usually minimal.
- If you see slowdowns, reduce the file limit.
]]></content>
</real_world_example>
<checklist>
<item>Does it start with benefits?</item>
<item>Are technical terms avoided?</item>
<item>Is the tone direct?</item>
<item>Are there practical examples?</item>
<item>Are sections short and scannable?</item>
<item>Does it answer user questions?</item>
<item>Is help accessible?</item>
</checklist>
</user_friendly_examples>

View file

@ -0,0 +1,198 @@
<workflow>
<step number="1">
<name>Understand Test Requirements</name>
<instructions>
Use ask_followup_question to determine what type of integration test is needed:
<ask_followup_question>
<question>What type of integration test would you like me to create or work on?</question>
<follow_up>
<suggest>New E2E test for a specific feature or workflow</suggest>
<suggest>Fix or update an existing integration test</suggest>
<suggest>Create test utilities or helpers for common patterns</suggest>
<suggest>Debug failing integration tests</suggest>
</follow_up>
</ask_followup_question>
</instructions>
</step>
<step number="2">
<name>Gather Test Specifications</name>
<instructions>
Based on the test type, gather detailed requirements:
For New E2E Tests:
- What specific user workflow or feature needs testing?
- What are the expected inputs and outputs?
- What edge cases or error scenarios should be covered?
- Are there specific API interactions to validate?
- What events should be monitored during the test?
For Existing Test Issues:
- Which test file is failing or needs updates?
- What specific error messages or failures are occurring?
- What changes in the codebase might have affected the test?
For Test Utilities:
- What common patterns are being repeated across tests?
- What helper functions would improve test maintainability?
Use multiple ask_followup_question calls if needed to gather complete information.
</instructions>
</step>
<step number="3">
<name>Explore Existing Test Patterns</name>
<instructions>
Use codebase_search FIRST to understand existing test patterns and similar functionality:
For New Tests:
- Search for similar test scenarios in apps/vscode-e2e/src/suite/
- Find existing test utilities and helpers
- Identify patterns for the type of functionality being tested
For Test Fixes:
- Search for the failing test file and related code
- Find similar working tests for comparison
- Look for recent changes that might have broken the test
Example searches:
- "file creation test mocha" for file operation tests
- "task completion waitUntilCompleted" for task monitoring patterns
- "api message validation" for API interaction tests
After codebase_search, use:
- read_file on relevant test files to understand structure
- list_code_definition_names on test directories
- search_files for specific test patterns or utilities
</instructions>
</step>
<step number="4">
<name>Analyze Test Environment and Setup</name>
<instructions>
Examine the test environment configuration:
1. Read the test runner configuration:
- apps/vscode-e2e/package.json for test scripts
- apps/vscode-e2e/src/runTest.ts for test setup
- Any test configuration files
2. Understand the test workspace setup:
- How test workspaces are created
- What files are available during tests
- How the extension API is accessed
3. Review existing test utilities:
- Helper functions for common operations
- Event listening patterns
- Assertion utilities
- Cleanup procedures
Document findings including:
- Test environment structure
- Available utilities and helpers
- Common patterns and best practices
</instructions>
</step>
<step number="5">
<name>Design Test Structure</name>
<instructions>
Plan the test implementation based on gathered information:
For New Tests:
- Define test suite structure with suite/test blocks
- Plan setup and teardown procedures
- Identify required test data and fixtures
- Design event listeners and validation points
- Plan for both success and failure scenarios
For Test Fixes:
- Identify the root cause of the failure
- Plan the minimal changes needed to fix the issue
- Consider if the test needs to be updated due to code changes
- Plan for improved error handling or debugging
Create a detailed test plan including:
- Test file structure and organization
- Required setup and cleanup
- Specific assertions and validations
- Error handling and edge cases
</instructions>
</step>
<step number="6">
<name>Implement Test Code</name>
<instructions>
Implement the test following established patterns:
CRITICAL: Never write a test file with a single write_to_file call.
Always implement tests in parts:
1. Start with the basic test structure (suite, setup, teardown)
2. Add individual test cases one by one
3. Implement helper functions separately
4. Add event listeners and validation logic incrementally
Follow these implementation guidelines:
- Use suite() and test() blocks following Mocha TDD style
- Always use the global api object for extension interactions
- Implement proper async/await patterns with waitFor utility
- Use waitUntilCompleted and waitUntilAborted helpers for task monitoring
- Listen to and validate appropriate events (message, taskCompleted, etc.)
- Test both positive flows and error scenarios
- Validate message content using proper type assertions
- Create reusable test utilities when patterns emerge
- Use meaningful test descriptions that explain the scenario
- Always clean up tasks with cancelCurrentTask or clearCurrentTask
- Ensure tests are independent and can run in any order
</instructions>
</step>
<step number="7">
<name>Run and Validate Tests</name>
<instructions>
Execute the tests to ensure they work correctly:
ALWAYS use the correct working directory and commands:
- Working directory: apps/vscode-e2e
- Test command: npm run test:run
- For specific tests: TEST_FILE="filename.test" npm run test:run
- Example: cd apps/vscode-e2e && TEST_FILE="apply-diff.test" npm run test:run
Test execution process:
1. Run the specific test file first
2. Check for any failures or errors
3. Analyze test output and logs
4. Debug any issues found
5. Re-run tests after fixes
If tests fail:
- Add console.log statements to track execution flow
- Log important events like task IDs, file paths, and AI responses
- Check test output carefully for error messages and stack traces
- Verify file creation in correct workspace directories
- Ensure proper event handling and timeouts
</instructions>
</step>
<step number="8">
<name>Document and Complete</name>
<instructions>
Finalize the test implementation:
1. Add comprehensive comments explaining complex test logic
2. Document any new test utilities or patterns created
3. Ensure test descriptions clearly explain what is being tested
4. Verify all cleanup procedures are in place
5. Confirm tests can run independently and in any order
Provide the user with:
- Summary of tests created or fixed
- Instructions for running the tests
- Any new patterns or utilities that can be reused
- Recommendations for future test improvements
</instructions>
</step>
</workflow>

View file

@ -0,0 +1,303 @@
<test_patterns>
<mocha_tdd_structure>
<description>Standard Mocha TDD structure for integration tests</description>
<pattern>
<name>Basic Test Suite Structure</name>
<example>
```typescript
import { suite, test, suiteSetup, suiteTeardown } from 'mocha';
import * as assert from 'assert';
import * as vscode from 'vscode';
import { waitFor, waitUntilCompleted, waitUntilAborted } from '../utils/testUtils';
suite('Feature Name Tests', () => {
let testWorkspaceDir: string;
let testFiles: { [key: string]: string } = {};
suiteSetup(async () => {
// Setup test workspace and files
testWorkspaceDir = vscode.workspace.workspaceFolders![0].uri.fsPath;
// Create test files in workspace
});
suiteTeardown(async () => {
// Cleanup test files and tasks
await api.cancelCurrentTask();
});
test('should perform specific functionality', async () => {
// Test implementation
});
});
```
</example>
</pattern>
<pattern>
<name>Event Listening Pattern</name>
<example>
```typescript
test('should handle task completion events', async () => {
const events: any[] = [];
const messageListener = (message: any) => {
events.push({ type: 'message', data: message });
};
const taskCompletedListener = (result: any) => {
events.push({ type: 'taskCompleted', data: result });
};
api.onDidReceiveMessage(messageListener);
api.onTaskCompleted(taskCompletedListener);
try {
// Perform test actions
await api.startTask('test prompt');
await waitUntilCompleted();
// Validate events
assert(events.some(e => e.type === 'taskCompleted'));
} finally {
// Cleanup listeners
api.onDidReceiveMessage(() => {});
api.onTaskCompleted(() => {});
}
});
```
</example>
</pattern>
<pattern>
<name>File Creation Test Pattern</name>
<example>
```typescript
test('should create files in workspace', async () => {
const fileName = 'test-file.txt';
const expectedContent = 'test content';
await api.startTask(`Create a file named ${fileName} with content: ${expectedContent}`);
await waitUntilCompleted();
// Check multiple possible locations
const possiblePaths = [
path.join(testWorkspaceDir, fileName),
path.join(process.cwd(), fileName),
// Add other possible locations
];
let fileFound = false;
let actualContent = '';
for (const filePath of possiblePaths) {
if (fs.existsSync(filePath)) {
actualContent = fs.readFileSync(filePath, 'utf8');
fileFound = true;
break;
}
}
assert(fileFound, `File ${fileName} not found in any expected location`);
assert.strictEqual(actualContent.trim(), expectedContent);
});
```
</example>
</pattern>
</mocha_tdd_structure>
<api_interaction_patterns>
<pattern>
<name>Basic Task Execution</name>
<example>
```typescript
// Start a task and wait for completion
await api.startTask('Your prompt here');
await waitUntilCompleted();
```
</example>
</pattern>
<pattern>
<name>Task with Auto-Approval Settings</name>
<example>
```typescript
// Enable auto-approval for specific actions
await api.updateSettings({
alwaysAllowWrite: true,
alwaysAllowExecute: true
});
await api.startTask('Create and execute a script');
await waitUntilCompleted();
```
</example>
</pattern>
<pattern>
<name>Message Validation</name>
<example>
```typescript
const messages: any[] = [];
api.onDidReceiveMessage((message) => {
messages.push(message);
});
await api.startTask('test prompt');
await waitUntilCompleted();
// Validate specific message types
const toolMessages = messages.filter(m =>
m.type === 'say' && m.say === 'api_req_started'
);
assert(toolMessages.length > 0, 'Expected tool execution messages');
```
</example>
</pattern>
</api_interaction_patterns>
<error_handling_patterns>
<pattern>
<name>Task Abortion Handling</name>
<example>
```typescript
test('should handle task abortion', async () => {
await api.startTask('long running task');
// Abort after short delay
setTimeout(() => api.abortTask(), 1000);
await waitUntilAborted();
// Verify task was properly aborted
const status = await api.getTaskStatus();
assert.strictEqual(status, 'aborted');
});
```
</example>
</pattern>
<pattern>
<name>Error Message Validation</name>
<example>
```typescript
test('should handle invalid input gracefully', async () => {
const errorMessages: any[] = [];
api.onDidReceiveMessage((message) => {
if (message.type === 'error' || message.text?.includes('error')) {
errorMessages.push(message);
}
});
await api.startTask('invalid prompt that should fail');
await waitFor(() => errorMessages.length > 0, 5000);
assert(errorMessages.length > 0, 'Expected error messages');
});
```
</example>
</pattern>
</error_handling_patterns>
<utility_patterns>
<pattern>
<name>File Location Helper</name>
<example>
```typescript
function findFileInWorkspace(fileName: string, workspaceDir: string): string | null {
const possiblePaths = [
path.join(workspaceDir, fileName),
path.join(process.cwd(), fileName),
path.join(os.tmpdir(), fileName),
// Add other common locations
];
for (const filePath of possiblePaths) {
if (fs.existsSync(filePath)) {
return filePath;
}
}
return null;
}
```
</example>
</pattern>
<pattern>
<name>Event Collection Helper</name>
<example>
```typescript
class EventCollector {
private events: any[] = [];
constructor(private api: any) {
this.setupListeners();
}
private setupListeners() {
this.api.onDidReceiveMessage((message: any) => {
this.events.push({ type: 'message', timestamp: Date.now(), data: message });
});
this.api.onTaskCompleted((result: any) => {
this.events.push({ type: 'taskCompleted', timestamp: Date.now(), data: result });
});
}
getEvents(type?: string) {
return type ? this.events.filter(e => e.type === type) : this.events;
}
clear() {
this.events = [];
}
}
```
</example>
</pattern>
</utility_patterns>
<debugging_patterns>
<pattern>
<name>Comprehensive Logging</name>
<example>
```typescript
test('should log execution flow for debugging', async () => {
console.log('Starting test execution');
const events: any[] = [];
api.onDidReceiveMessage((message) => {
console.log('Received message:', JSON.stringify(message, null, 2));
events.push(message);
});
console.log('Starting task with prompt');
await api.startTask('test prompt');
console.log('Waiting for task completion');
await waitUntilCompleted();
console.log('Task completed, events received:', events.length);
console.log('Final workspace state:', fs.readdirSync(testWorkspaceDir));
});
```
</example>
</pattern>
<pattern>
<name>State Validation</name>
<example>
```typescript
function validateTestState(description: string) {
console.log(`=== ${description} ===`);
console.log('Workspace files:', fs.readdirSync(testWorkspaceDir));
console.log('Current working directory:', process.cwd());
console.log('Task status:', api.getTaskStatus?.() || 'unknown');
console.log('========================');
}
```
</example>
</pattern>
</debugging_patterns>
</test_patterns>

View file

@ -0,0 +1,104 @@
<best_practices>
<test_structure>
- Always use suite() and test() blocks following Mocha TDD style
- Use descriptive test names that explain the scenario being tested
- Implement proper setup and teardown in suiteSetup() and suiteTeardown()
- Create test files in the VSCode workspace directory during suiteSetup()
- Store file paths in a test-scoped object for easy reference across tests
- Ensure tests are independent and can run in any order
- Clean up all test files and tasks in suiteTeardown() to avoid test pollution
</test_structure>
<api_interactions>
- Always use the global api object for extension interactions
- Implement proper async/await patterns with the waitFor utility
- Use waitUntilCompleted and waitUntilAborted helpers for task monitoring
- Set appropriate auto-approval settings (alwaysAllowWrite, alwaysAllowExecute) for the functionality being tested
- Listen to and validate appropriate events (message, taskCompleted, taskAborted, etc.)
- Always clean up tasks with cancelCurrentTask or clearCurrentTask after tests
- Use meaningful timeouts that account for actual task execution time
</api_interactions>
<file_system_handling>
- Be aware that files may be created in the workspace directory (/tmp/roo-test-workspace-*) rather than expected locations
- Always check multiple possible file locations when verifying file creation
- Use flexible file location checking that searches workspace directories
- Verify files exist after creation to catch setup issues early
- Account for the fact that the workspace directory is created by runTest.ts
- The AI may use internal tools instead of the documented tools - verify outcomes rather than methods
</file_system_handling>
<event_handling>
- Add multiple event listeners (taskStarted, taskCompleted, taskAborted) for better debugging
- Don't rely on parsing AI messages to detect tool usage - the AI's message format may vary
- Use terminal shell execution events (onDidStartTerminalShellExecution, onDidEndTerminalShellExecution) for command tracking
- Tool executions are reported via api_req_started messages with type="say" and say="api_req_started"
- Focus on testing outcomes (files created, commands executed) rather than message parsing
- There is no "tool_result" message type - tool results appear in "completion_result" or "text" messages
</event_handling>
<error_scenarios>
- Test both positive flows and error scenarios
- Validate message content using proper type assertions
- Implement proper error handling and edge cases
- Use try-catch blocks around critical test operations
- Log important events like task IDs, file paths, and AI responses for debugging
- Check test output carefully for error messages and stack traces
</error_scenarios>
<test_reliability>
- Remove unnecessary waits for specific tool executions - wait for task completion instead
- Simplify message handlers to only capture essential error information
- Use the simplest possible test structure that verifies the outcome
- Avoid complex message parsing logic that depends on AI behavior
- Terminal events are more reliable than message parsing for command execution verification
- Keep prompts simple and direct - complex instructions may confuse the AI
</test_reliability>
<debugging_and_troubleshooting>
- Add console.log statements to track test execution flow
- Log important events like task IDs, file paths, and AI responses
- Use codebase_search first to find similar test patterns before writing new tests
- Create helper functions for common file location checks
- Use descriptive variable names for file paths and content
- Always log the expected vs actual locations when tests fail
- Add comprehensive comments explaining complex test logic
</debugging_and_troubleshooting>
<test_utilities>
- Create reusable test utilities when patterns emerge
- Implement helper functions for common operations like file finding
- Use event collection utilities for consistent event handling
- Create assertion helpers for common validation patterns
- Document any new test utilities or patterns created
- Share common utilities across test files to reduce duplication
</test_utilities>
<ai_interaction_considerations>
- Keep prompts simple and direct - complex instructions may lead to unexpected behavior
- Allow for variations in how the AI accomplishes tasks
- The AI may not always use the exact tool you specify in the prompt
- Be prepared to adapt tests based on actual AI behavior rather than expected behavior
- The AI may interpret instructions creatively - test results rather than implementation details
- The AI will not see the files in the workspace directory, you must tell it to assume they exist and proceed
</ai_interaction_considerations>
<test_execution>
- ALWAYS use the correct working directory: apps/vscode-e2e
- The test command is: npm run test:run
- To run specific tests use environment variable: TEST_FILE="filename.test" npm run test:run
- Example: cd apps/vscode-e2e && TEST_FILE="apply-diff.test" npm run test:run
- Never use npm test directly as it doesn't exist
- Always check available scripts with npm run if unsure
- Run tests incrementally during development to catch issues early
</test_execution>
<code_organization>
- Never write a test file with a single write_to_file tool call
- Always implement tests in parts: structure first, then individual test cases
- Group related tests in the same suite
- Use consistent naming conventions for test files and functions
- Separate test utilities into their own files when they become substantial
- Follow the existing project structure and conventions
</code_organization>
</best_practices>

View file

@ -0,0 +1,109 @@
<common_mistakes_to_avoid>
<test_structure_mistakes>
- Writing a test file with a single write_to_file tool call instead of implementing in parts
- Not using proper Mocha TDD structure with suite() and test() blocks
- Forgetting to implement suiteSetup() and suiteTeardown() for proper cleanup
- Creating tests that depend on each other or specific execution order
- Not cleaning up tasks and files after test completion
- Using describe/it blocks instead of the required suite/test blocks
</test_structure_mistakes>
<api_interaction_mistakes>
- Not using the global api object for extension interactions
- Forgetting to set auto-approval settings (alwaysAllowWrite, alwaysAllowExecute) when testing functionality that requires user approval
- Not implementing proper async/await patterns with waitFor utilities
- Using incorrect timeout values that are too short for actual task execution
- Not properly cleaning up tasks with cancelCurrentTask or clearCurrentTask
- Assuming the AI will use specific tools instead of testing outcomes
</api_interaction_mistakes>
<file_system_mistakes>
- Assuming files will be created in the expected location without checking multiple paths
- Not accounting for the workspace directory being created by runTest.ts
- Creating test files in temporary directories instead of the VSCode workspace directory
- Not verifying files exist after creation during setup
- Forgetting that the AI may not see files in the workspace directory
- Not using flexible file location checking that searches workspace directories
</file_system_mistakes>
<event_handling_mistakes>
- Relying on parsing AI messages to detect tool usage instead of using proper event listeners
- Expecting tool results in "tool_result" message type (which doesn't exist)
- Not listening to terminal shell execution events for command tracking
- Depending on specific message formats that may vary
- Not implementing proper event cleanup after tests
- Parsing complex AI conversation messages instead of focusing on outcomes
</event_handling_mistakes>
<test_execution_mistakes>
- Using npm test instead of npm run test:run
- Not using the correct working directory (apps/vscode-e2e)
- Running tests from the wrong directory
- Not checking available scripts with npm run when unsure
- Forgetting to use TEST_FILE environment variable for specific tests
- Not running tests incrementally during development
</test_execution_mistakes>
<debugging_mistakes>
- Not adding sufficient logging to track test execution flow
- Not logging important events like task IDs, file paths, and AI responses
- Not using codebase_search to find similar test patterns before writing new tests
- Not checking test output carefully for error messages and stack traces
- Not validating test state at critical points
- Assuming test failures are due to code issues without checking test logic
</debugging_mistakes>
<ai_interaction_mistakes>
- Using complex instructions that may confuse the AI
- Expecting the AI to use exact tools specified in prompts
- Not allowing for variations in how the AI accomplishes tasks
- Testing implementation details instead of outcomes
- Not adapting tests based on actual AI behavior
- Forgetting to tell the AI to assume files exist in the workspace directory
</ai_interaction_mistakes>
<reliability_mistakes>
- Adding unnecessary waits for specific tool executions
- Using complex message parsing logic that depends on AI behavior
- Not using the simplest possible test structure
- Depending on specific AI message formats
- Not using terminal events for reliable command execution verification
- Making tests too brittle by depending on exact AI responses
</reliability_mistakes>
<workspace_mistakes>
- Not understanding that files may be created in /tmp/roo-test-workspace-* directories
- Assuming the AI can see files in the workspace directory
- Not checking multiple possible file locations when verifying creation
- Creating files outside the VSCode workspace during tests
- Not properly setting up the test workspace in suiteSetup()
- Forgetting to clean up workspace files in suiteTeardown()
</workspace_mistakes>
<message_handling_mistakes>
- Expecting specific message types for tool execution results
- Not understanding that ClineMessage types have specific values
- Trying to parse tool execution from AI conversation messages
- Not checking packages/types/src/message.ts for valid message types
- Depending on message parsing instead of outcome verification
- Not using api_req_started messages to verify tool execution
</message_handling_mistakes>
<timeout_and_timing_mistakes>
- Using timeouts that are too short for actual task execution
- Not accounting for AI processing time in test timeouts
- Waiting for specific tool executions instead of task completion
- Not implementing proper retry logic for flaky operations
- Using fixed delays instead of condition-based waiting
- Not considering that some operations may take longer in CI environments
</timeout_and_timing_mistakes>
<test_data_mistakes>
- Not creating test files in the correct workspace directory
- Using hardcoded paths that don't work across different environments
- Not storing file paths in test-scoped objects for easy reference
- Creating test data that conflicts with other tests
- Not cleaning up test data properly after tests complete
- Using test data that's too complex for the AI to handle reliably
</test_data_mistakes>
</common_mistakes_to_avoid>

View file

@ -0,0 +1,209 @@
<test_environment_and_tools>
<test_framework>
<description>VSCode E2E testing framework using Mocha and VSCode Test</description>
<key_components>
- Mocha TDD framework for test structure
- VSCode Test framework for extension testing
- Custom test utilities and helpers
- Event-driven testing patterns
- Workspace-based test execution
</key_components>
</test_framework>
<directory_structure>
<test_files_location>apps/vscode-e2e/src/suite/</test_files_location>
<test_utilities>apps/vscode-e2e/src/utils/</test_utilities>
<test_runner>apps/vscode-e2e/src/runTest.ts</test_runner>
<package_config>apps/vscode-e2e/package.json</package_config>
<type_definitions>packages/types/</type_definitions>
</directory_structure>
<test_execution_commands>
<working_directory>apps/vscode-e2e</working_directory>
<commands>
<run_all_tests>npm run test:run</run_all_tests>
<run_specific_test>TEST_FILE="filename.test" npm run test:run</run_specific_test>
<example>cd apps/vscode-e2e && TEST_FILE="apply-diff.test" npm run test:run</example>
<check_scripts>npm run</check_scripts>
</commands>
<important_notes>
- Never use npm test directly as it doesn't exist
- Always use the correct working directory
- Use TEST_FILE environment variable for specific tests
- Check available scripts with npm run if unsure
</important_notes>
</test_execution_commands>
<api_object>
<description>Global api object for extension interactions</description>
<key_methods>
<task_management>
- api.startTask(prompt: string): Start a new task
- api.cancelCurrentTask(): Cancel the current task
- api.clearCurrentTask(): Clear the current task
- api.abortTask(): Abort the current task
- api.getTaskStatus(): Get current task status
</task_management>
<event_listeners>
- api.onDidReceiveMessage(callback): Listen to messages
- api.onTaskCompleted(callback): Listen to task completion
- api.onTaskAborted(callback): Listen to task abortion
- api.onTaskStarted(callback): Listen to task start
- api.onDidStartTerminalShellExecution(callback): Terminal start events
- api.onDidEndTerminalShellExecution(callback): Terminal end events
</event_listeners>
<settings>
- api.updateSettings(settings): Update extension settings
- api.getSettings(): Get current settings
</settings>
</key_methods>
</api_object>
<test_utilities>
<wait_functions>
<waitFor>
<description>Wait for a condition to be true</description>
<usage>await waitFor(() => condition, timeout)</usage>
<example>await waitFor(() => fs.existsSync(filePath), 5000)</example>
</waitFor>
<waitUntilCompleted>
<description>Wait until current task is completed</description>
<usage>await waitUntilCompleted()</usage>
<timeout>Default timeout for task completion</timeout>
</waitUntilCompleted>
<waitUntilAborted>
<description>Wait until current task is aborted</description>
<usage>await waitUntilAborted()</usage>
<timeout>Default timeout for task abortion</timeout>
</waitUntilAborted>
</wait_functions>
<helper_patterns>
<file_location_helper>
<description>Helper to find files in multiple possible locations</description>
<usage>Use when files might be created in different workspace directories</usage>
</file_location_helper>
<event_collector>
<description>Utility to collect and analyze events during test execution</description>
<usage>Use for comprehensive event tracking and validation</usage>
</event_collector>
<assertion_helpers>
<description>Custom assertion functions for common test patterns</description>
<usage>Use for consistent validation across tests</usage>
</assertion_helpers>
</helper_patterns>
</test_utilities>
<workspace_management>
<workspace_creation>
<description>Test workspaces are created by runTest.ts</description>
<location>/tmp/roo-test-workspace-*</location>
<access>vscode.workspace.workspaceFolders![0].uri.fsPath</access>
</workspace_creation>
<file_creation_strategy>
<setup_phase>Create all test files in suiteSetup() before any tests run</setup_phase>
<location>Always create files in the VSCode workspace directory</location>
<verification>Verify files exist after creation to catch setup issues early</verification>
<cleanup>Clean up all test files in suiteTeardown() to avoid test pollution</cleanup>
<storage>Store file paths in a test-scoped object for easy reference</storage>
</file_creation_strategy>
<ai_visibility>
<important_note>The AI will not see the files in the workspace directory</important_note>
<solution>Tell the AI to assume files exist and proceed as if they do</solution>
<verification>Always verify outcomes rather than relying on AI file visibility</verification>
</ai_visibility>
</workspace_management>
<message_types>
<description>Understanding message types for proper event handling</description>
<reference>Check packages/types/src/message.ts for valid message types</reference>
<key_message_types>
<api_req_started>
<type>say</type>
<say>api_req_started</say>
<description>Indicates tool execution started</description>
<text_content>JSON with tool name and execution details</text_content>
<usage>Most reliable way to verify tool execution</usage>
</api_req_started>
<completion_result>
<description>Contains tool execution results</description>
<usage>Tool results appear here, not in "tool_result" type</usage>
</completion_result>
<text_messages>
<description>General AI conversation messages</description>
<caution>Format may vary, don't rely on parsing these for tool detection</caution>
</text_messages>
</key_message_types>
</message_types>
<auto_approval_settings>
<description>Settings to enable automatic approval of AI actions</description>
<critical_settings>
<alwaysAllowWrite>Enable for file creation/modification tests</alwaysAllowWrite>
<alwaysAllowExecute>Enable for command execution tests</alwaysAllowExecute>
<alwaysAllowBrowser>Enable for browser-related tests</alwaysAllowBrowser>
</critical_settings>
<usage>
```typescript
await api.updateSettings({
alwaysAllowWrite: true,
alwaysAllowExecute: true
});
```
</usage>
<importance>Without proper auto-approval settings, the AI won't be able to perform actions without user approval</importance>
</auto_approval_settings>
<debugging_tools>
<console_logging>
<description>Use console.log for tracking test execution flow</description>
<best_practices>
- Log test phase transitions
- Log important events and data
- Log file paths and workspace state
- Log expected vs actual outcomes
</best_practices>
</console_logging>
<state_validation>
<description>Helper functions to validate test state at critical points</description>
<includes>
- Workspace file listing
- Current working directory
- Task status
- Event counts
</includes>
</state_validation>
<error_analysis>
<description>Tools for analyzing test failures</description>
<techniques>
- Stack trace analysis
- Event timeline reconstruction
- File system state comparison
- Message flow analysis
</techniques>
</error_analysis>
</debugging_tools>
<performance_considerations>
<timeouts>
<description>Appropriate timeout values for different operations</description>
<task_completion>Use generous timeouts for task completion (30+ seconds)</task_completion>
<file_operations>Shorter timeouts for file system operations (5-10 seconds)</file_operations>
<event_waiting>Medium timeouts for event waiting (10-15 seconds)</event_waiting>
</timeouts>
<resource_management>
<description>Proper cleanup to avoid resource leaks</description>
<event_listeners>Always clean up event listeners after tests</event_listeners>
<tasks>Cancel or clear tasks in teardown</tasks>
<files>Remove test files to avoid disk space issues</files>
</resource_management>
</performance_considerations>
</test_environment_and_tools>

View file

@ -17,7 +17,7 @@
Then retrieve the issue:
<execute_command>
<command>gh api repos/[owner]/[repo]/issues/[issue-number] --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}'</command>
<command>gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author</command>
</execute_command>
If the command fails with an authentication error (e.g., "gh: Not authenticated" or "HTTP 401"), ask the user to authenticate:
@ -49,7 +49,7 @@
- Any decisions or changes to requirements
<execute_command>
<command>gh api repos/[owner]/[repo]/issues/[issue-number]/comments --paginate --jq '.[].body'</command>
<command>gh issue view [issue number] --repo [owner]/[repo] --comments</command>
</execute_command>
Also check for:
@ -191,6 +191,7 @@
Use appropriate tools:
- apply_diff for targeted changes
- write_to_file for new files
- search_and_replace for systematic updates
After each significant change, run relevant tests:
- execute_command to run test suites

View file

@ -29,23 +29,23 @@
<primary_commands>
<command name="gh_issue_view">
<purpose>Retrieve the issue details at the start using the REST Issues API.</purpose>
<purpose>Retrieve the issue details at the start</purpose>
<when>Always use first to get the full issue content</when>
<syntax>gh api repos/[owner]/[repo]/issues/[issue-number] --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}'</syntax>
<syntax>gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author</syntax>
<example>
<execute_command>
<command>gh api repos/octocat/hello-world/issues/123 --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}'</command>
<command>gh issue view 123 --repo octocat/hello-world --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author</command>
</execute_command>
</example>
</command>
<command name="gh_issue_comments">
<purpose>Get additional context and requirements from issue comments.</purpose>
<purpose>Get additional context and requirements from issue comments</purpose>
<when>Always use after viewing issue to see full discussion</when>
<syntax>gh api repos/[owner]/[repo]/issues/[issue-number]/comments --paginate --jq '.[].body'</syntax>
<syntax>gh issue view [issue-number] --repo [owner]/[repo] --comments</syntax>
<example>
<execute_command>
<command>gh api repos/octocat/hello-world/issues/123/comments --paginate --jq '.[].body'</command>
<command>gh issue view 123 --repo octocat/hello-world --comments</command>
</execute_command>
</example>
</command>
@ -109,30 +109,6 @@
</command>
</optional_commands>
<projects_v2_commands>
<command name="gh_projects_v2_for_issue">
<purpose>Inspect associations with GitHub Projects (new Projects experience) for a given issue</purpose>
<when>Use when project context is relevant to understanding priority, ownership, or workflow</when>
<syntax>gh api graphql -f query='
query($owner:String!, $repo:String!, $number:Int!) {
repository(owner:$owner, name:$repo) {
issue(number:$number) {
projectsV2(first:20) {
nodes {
title
url
}
}
}
}
}
' -F owner=[owner] -F repo=[repo] -F number=[issue-number]</syntax>
<note>
This uses the projectsV2 field from the new GitHub Projects experience for issue-level project context.
</note>
</command>
</projects_v2_commands>
<pull_request_commands>
<command name="gh_pr_create">
<purpose>Create a pull request</purpose>

View file

@ -70,7 +70,7 @@
</step>
<step>
<title>Draft Comment</title>
<description>Draft a comment for the GitHub issue that explains your findings and suggested solution in a conversational, human-like tone. Start the comment with "Hey @roomote-agent,".</description>
<description>Draft a comment for the GitHub issue that explains your findings and suggested solution in a conversational, human-like tone.</description>
</step>
</steps>
</phase>

View file

@ -52,7 +52,6 @@
</category>
<category name="communication">
<item>Does the draft comment sound conversational and human?</item>
<item>Does the draft comment start with "Hey @roomote-agent,"?</item>
<item>Have I avoided technical jargon where possible?</item>
<item>Is the tone helpful and not condescending?</item>
</category>

View file

@ -23,16 +23,10 @@
<practice>Use `gh issue view [URL] --json title,body,labels,comments` to fetch initial details.</practice>
<practice>Use `gh issue comment [URL] --body "..."` to add comments, but only after explicit user approval.</practice>
<practice>Always wrap the comment body in quotes to handle special characters.</practice>
<practice>When posting a comment, the body must start with "Hey @roomote-agent," exactly.</practice>
</best_practices>
<example><![CDATA[
<execute_command>
<command>gh issue view https://github.com/RooCodeInc/Roo-Code/issues/123 --json title,body</command>
</execute_command>
]]></example>
<example><![CDATA[
<execute_command>
<command>gh issue comment https://github.com/RooCodeInc/Roo-Code/issues/123 --body "Hey @roomote-agent, I've investigated and proposed a theoretical fix above."</command>
</execute_command>
]]></example>
</tool>

View file

@ -70,7 +70,7 @@
<step number="6">
<description>Formulate a solution and draft a comment.</description>
<draft>
"Hey @roomote-agent, I took a look at this issue and it seems like the problem is in the `handleLogin` function in `src/auth/login.ts`. There's an empty `try...catch` block that is likely catching the login error and preventing any message from being shown to the user.
"Hey, I took a look at this issue and it seems like the problem is in the `handleLogin` function in `src/auth/login.ts`. There's an empty `try...catch` block that is likely catching the login error and preventing any message from being shown to the user.
A good first step to fixing this would be to add some logging to the `catch` block to see what error is actually happening. Then, we should probably implement proper error feedback to the user on the login page. This should solve the issue of the silent failure."
</draft>

View file

@ -2,20 +2,18 @@
<tone_and_style>
<principle>Be conversational and helpful, not robotic.</principle>
<principle>Write comments as if you are a human developer collaborating on the project.</principle>
<principle>Always start any GitHub issue comment body with "Hey @roomote-agent,".</principle>
<avoid>
<phrase>Analysis complete.</phrase>
<phrase>The investigation has yielded the following result.</phrase>
<phrase>Starting comments with "Hey," instead of "Hey @roomote-agent,".</phrase>
</avoid>
<prefer>
<phrase>Hey @roomote-agent, I took a look at this and found something interesting...</phrase>
<phrase>Hey @roomote-agent, I've been digging into this issue, and I think I've found a possible cause.</phrase>
<phrase>Hey, I took a look at this and found something interesting...</phrase>
<phrase>I've been digging into this issue, and I think I've found a possible cause.</phrase>
</prefer>
</tone_and_style>
<comment_structure>
<element>Start every GitHub issue comment with "Hey @roomote-agent,".</element>
<element>Start with a friendly opening.</element>
<element>State your main finding or hypothesis clearly but not definitively.</element>
<element>Provide context, like file paths and function names.</element>
<element>Propose a next step or a theoretical solution.</element>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,190 @@
<github_issue_templates>
<overview>
This mode prioritizes using repository-specific issue templates over hardcoded ones.
If no templates exist in the repository, simple generic templates are created on the fly.
</overview>
<template_detection>
<locations>
<location priority="1">.github/ISSUE_TEMPLATE/*.yml</location>
<location priority="2">.github/ISSUE_TEMPLATE/*.yaml</location>
<location priority="3">.github/ISSUE_TEMPLATE/*.md</location>
<location priority="4">.github/issue_template.md</location>
<location priority="5">.github/ISSUE_TEMPLATE.md</location>
</locations>
<yaml_template_structure>
<field name="name">Display name of the template</field>
<field name="description">Brief description of when to use this template</field>
<field name="title">Default issue title (optional)</field>
<field name="labels">Array of labels to apply</field>
<field name="assignees">Array of default assignees</field>
<field name="body">Array of form elements or markdown content</field>
</yaml_template_structure>
<yaml_form_elements>
<element type="markdown">
<description>Static markdown content</description>
<attributes>
<attr name="value">The markdown content to display</attr>
</attributes>
</element>
<element type="input">
<description>Single-line text input</description>
<attributes>
<attr name="id">Unique identifier</attr>
<attr name="label">Display label</attr>
<attr name="description">Help text</attr>
<attr name="placeholder">Placeholder text</attr>
<attr name="value">Default value</attr>
<attr name="required">Boolean</attr>
</attributes>
</element>
<element type="textarea">
<description>Multi-line text input</description>
<attributes>
<attr name="id">Unique identifier</attr>
<attr name="label">Display label</attr>
<attr name="description">Help text</attr>
<attr name="placeholder">Placeholder text</attr>
<attr name="value">Default value</attr>
<attr name="required">Boolean</attr>
<attr name="render">Language for syntax highlighting</attr>
</attributes>
</element>
<element type="dropdown">
<description>Dropdown selection</description>
<attributes>
<attr name="id">Unique identifier</attr>
<attr name="label">Display label</attr>
<attr name="description">Help text</attr>
<attr name="options">Array of options</attr>
<attr name="required">Boolean</attr>
</attributes>
</element>
<element type="checkboxes">
<description>Multiple checkbox options</description>
<attributes>
<attr name="id">Unique identifier</attr>
<attr name="label">Display label</attr>
<attr name="description">Help text</attr>
<attr name="options">Array of checkbox items</attr>
</attributes>
</element>
</yaml_form_elements>
<markdown_template_structure>
<front_matter>
Optional YAML front matter with:
- name: Template name
- about: Template description
- title: Default title
- labels: Comma-separated or array
- assignees: Comma-separated or array
</front_matter>
<body>
Markdown content with sections and placeholders
Common patterns:
- Headers with ##
- Placeholder text in brackets or as comments
- Checklists with - [ ]
- Code blocks with ```
</body>
</markdown_template_structure>
</template_detection>
<generic_templates>
<description>
When no repository templates exist, create simple templates based on issue type.
These should be minimal and focused on gathering essential information.
</description>
<bug_template>
<structure>
- Description: Clear explanation of the bug
- Steps to Reproduce: Numbered list
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Additional Context: Version, environment, logs
- Code Investigation: Findings from exploration (if any)
</structure>
<labels>["bug"]</labels>
</bug_template>
<feature_template>
<structure>
- Problem Description: What problem this solves
- Current Behavior: How it works now
- Proposed Solution: What should change
- Impact: Who benefits and how
- Technical Context: Code findings (if any)
</structure>
<labels>["enhancement", "proposal"]</labels>
</feature_template>
</generic_templates>
<template_parsing_guidelines>
<guideline>
When parsing YAML templates:
1. Use a YAML parser to extract the structure
2. Convert form elements to markdown sections
3. Preserve required field indicators
4. Include descriptions as help text
5. Maintain the intended flow of the template
</guideline>
<guideline>
When parsing Markdown templates:
1. Extract front matter if present
2. Identify section headers
3. Look for placeholder patterns
4. Preserve formatting and structure
5. Replace generic placeholders with user's information
</guideline>
<guideline>
For template selection:
1. If only one template exists, use it automatically
2. If multiple exist, let user choose based on name/description
3. Match template to issue type when possible (bug vs feature)
4. Respect template metadata (labels, assignees, etc.)
</guideline>
</template_parsing_guidelines>
<filling_templates>
<principle>
Fill templates intelligently using gathered information:
- Map user's description to appropriate sections
- Include code investigation findings where relevant
- Preserve template structure and formatting
- Don't leave placeholder text unfilled
- Add contributor scoping if user is contributing
</principle>
<mapping_examples>
<example from="Steps to Reproduce" to="User's reproduction steps + code paths"/>
<example from="Expected behavior" to="What user expects + code logic verification"/>
<example from="System information" to="Detected versions + environment"/>
<example from="Additional context" to="Code findings + architecture insights"/>
</mapping_examples>
</filling_templates>
<no_template_behavior>
<description>
When no templates exist, create appropriate generic templates on the fly.
Keep them simple and focused on essential information.
</description>
<guidelines>
- Don't overwhelm with too many fields
- Focus on problem description first
- Include technical details only if user is contributing
- Use clear, simple section headers
- Adapt based on issue type (bug vs feature)
</guidelines>
</no_template_behavior>
</github_issue_templates>

View file

@ -1,147 +1,172 @@
<best_practices>
<mode_scope>
This mode assembles a template-free issue body grounded by codebase exploration and can submit it via GitHub CLI after explicit confirmation.
Submission uses Title and Body only and targets the detected repository after the merged Review and Submit step.
</mode_scope>
<mode_behavior>
- Treat the user's FIRST message as the issue description; do not ask if they want to create an issue.
- Start with repository detection (verify git repo; resolve OWNER/REPO from origin), then determine repository structure (monorepo/standard).
- After detection, begin codebase discovery scoped to the repository root or the selected package (in monorepos).
- Keep final output non-technical; implementation details remain internal.
- CRITICAL: This mode assumes the user's FIRST message is already an issue description
- Do NOT ask "What would you like to do?" or "Do you want to create an issue?"
- Immediately start the issue creation workflow when the user begins talking
- Treat their initial message as the problem/feature description
- Begin with repository detection and codebase discovery right away
- The user is already in "issue creation mode" by choosing this mode
</mode_behavior>
<value_framing>
<principles>
- Always pair the problem with user-facing value: who is impacted, when it occurs, and why it matters.
- Keep value non-technical (clarity, time saved, fewer errors, better UX, improved accessibility, reduced confusion).
</principles>
<lightweight_impact_options>
- Severity: Blocker | High | Medium | Low (optional)
- Reach: Few | Some | Many (optional)
</lightweight_impact_options>
</value_framing>
<sourcing_and_provenance>
<direct_from_user_only>
- Reproduction steps
- Variations tried
- Environment details
</direct_from_user_only>
<inference_allowed_with_care>
- Problem/Value statement (plain-language synthesis from user wording)
- Context (who/when) based on user input; keep code-based signals internal
</inference_allowed_with_care>
<hallucination_guards>
- Never fabricate “Variations tried.” If not provided, omit.
- If critical details are missing, ask targeted questions; otherwise proceed with omissions.
</hallucination_guards>
</sourcing_and_provenance>
<cli_submission>
<confirmation>
Use a single merged "Review and Submit" step with options:
- Submit now
- Submit now and assign to me
Any other response is treated as a change request and the step is rerun after applying edits.
</confirmation>
<repo_detection>
Submission requires repository detection (git present, origin configured). Capture normalized OWNER/REPO (e.g., owner/repo) and store as [OWNER_REPO] for submission.
</repo_detection>
<target_repo>
Always specify the target using --repo "[OWNER_REPO]" to avoid ambiguity and ensure the correct repository is used.
</target_repo>
<assignment>
When "Submit now and assign to me" is chosen, create using: --assignee "@me".
If creation with --assignee fails (e.g., permissions), create the issue without an assignee and immediately run:
gh issue edit <issue-url-or-number> --add-assignee "@me".
</assignment>
<command_safety>
Use --body with robust quoting (for example: --body "$(printf '%s\n' "[ISSUE_BODY]")") or a heredoc; do not create temporary files or reference file paths. Always include --repo "[OWNER_REPO]" and echo the resulting issue URL.
In execute_command calls, output only the command string; never include XML tags, CDATA markers, code fences, or backticks in the command payload.
</command_safety>
<error_handling>
On gh errors (installation/auth), present the error and offer to retry after fixing gh setup. Surface the computed Title and Body inline
so the user can submit manually if needed.
</error_handling>
</cli_submission>
<codebase_exploration>
<principles>
- Use semantic search first to find relevant areas.
- Refine with targeted regex for exact strings (errors, component names, flags).
- Read key files to verify behavior; keep evidence internal.
- Early-stop when hits converge (~70%) or you can name the exact feature/component.
- Escalate-once if signals conflict; run one refined batch, then proceed.
</principles>
<tool_sequence>
1) codebase_search → 2) search_files → 3) read_file (as needed)
</tool_sequence>
<scoping>
In monorepos, scope searches to the selected package when the context is clear; otherwise ask for the relevant package/app if ambiguous.
</scoping>
<internal_only>
Keep language plain and exclude technical artifacts (paths, line numbers, stack traces, diffs) from the final issue body.
</internal_only>
</codebase_exploration>
<questioning>
<guidelines>
- Ask minimal, targeted questions based on what you found in code.
- For bugs: request a minimal reproduction (environment, steps, expected, actual, variations).
- For enhancements: capture user goal, desired behavior in plain language, and any constraints.
- Present discrepancies in plain language (no code) and confirm understanding.
</guidelines>
</questioning>
<issue_output_rules>
<format>
<![CDATA[
## Type
Bug | Enhancement
## Problem / Value
[One or two sentences that capture the problem and why it matters in plain language]
## Context
[Who is affected and when it happens]
[Enhancement: desired behavior conceptually, in the user's words]
[Bug: current observed behavior in plain language]
## Reproduction (Bug only, if available)
1) Steps (each action/command)
2) Expected result
3) Actual result
4) Variations tried (only if explicitly provided)
## Constraints/Preferences
[Performance, accessibility, UX, or other considerations]
]]>
</format>
<rules>
- Omit sections that would be empty.
- Do not include "Variations tried" unless explicitly provided by the user.
- Keep language plain and user-centric.
- Exclude technical artifacts (paths, lines, stacks, diffs).
</rules>
</issue_output_rules>
<review_stage_presentation>
- At each review stage, present the full current issue details (Title + Body) in a markdown code block.
- Offer "Submit now" or "Submit now and assign to me" suggestions; treat any other response as a change request and rerun the step after applying edits.
</review_stage_presentation>
<autonomy_and_budgets>
- Tool preambles: restate goal briefly, outline a short plan, narrate progress succinctly, summarize final delta.
- One-tool-per-message: await results before continuing.
- Discovery budget: default max 3 searches before escalate-once; stop when sufficient.
- Early-stop: when top hits converge or target is identifiable.
- Verbosity: low narrative; detail appears only in structured outputs.
</autonomy_and_budgets>
<template_usage>
- ALWAYS check for repository-specific issue templates before creating issues
- Use templates from .github/ISSUE_TEMPLATE/ directory if they exist
- Parse both YAML (.yml/.yaml) and Markdown (.md) template formats
- If multiple templates exist, let the user choose the appropriate one
- If no templates exist, create a simple generic template on the fly
- NEVER fall back to hardcoded templates - always use repo templates or generate minimal ones
- Respect template metadata like labels, assignees, and title patterns
- Fill templates intelligently using gathered information from codebase exploration
</template_usage>
<problem_reporting_focus>
- Focus on helping users describe problems clearly, not solutions
- The project team will design solutions unless the user explicitly wants to contribute
- Don't push users to provide technical details they may not have
- Make it easy for non-technical users to report issues effectively
CRITICAL: Lead with user impact:
- Always explain WHO is affected and WHEN the problem occurs
- Use concrete examples with actual values, not abstractions
- Show before/after scenarios with specific data
- Example: "Users trying to [action] see [actual result] instead of [expected result]"
</problem_reporting_focus>
<fact_driven_verification>
- ALWAYS verify user claims against actual code implementation
- For feature requests, aggressively check if current behavior matches user's description
- If code shows different intent than user describes, it might be a bug not a feature
- Present code evidence when challenging user assumptions
- Do not be agreeable - be fact-driven and question discrepancies
- Continue verification until facts are established
- A "feature request" where code shows the feature should already work is likely a bug
CRITICAL additions for thorough analysis:
- Trace data flow from where values are created to where they're used
- Look for existing variables/functions that already contain needed data
- Check if the issue is just missing usage of existing code
- Follow imports and exports to understand data availability
- Identify patterns in similar features that work correctly
</fact_driven_verification>
<general_practices>
- Always search for existing similar issues before creating a new one
- Check for and use repository issue templates before creating content
- Include specific version numbers and environment details
- Use code blocks with syntax highlighting for code snippets
- Make titles descriptive but concise (e.g., "Dark theme: Submit button invisible due to white-on-grey text")
- For bugs, always test if the issue is reproducible
- Include screenshots or mockups when relevant (ask user to provide)
- Link to related issues or PRs if found during exploration
CRITICAL: Use concrete examples throughout:
- Show actual data values, not just descriptions
- Include specific file paths and line numbers
- Demonstrate the data flow with real examples
- Bad: "The value is incorrect"
- Good: "The function returns '123' when it should return '456'"
</general_practices>
<contributor_specific>
- Only perform issue scoping if user wants to contribute
- Reference specific files and line numbers from codebase exploration
- Ensure technical proposals align with project architecture
- Include implementation steps and issue scoping
- Provide clear acceptance criteria in Given/When/Then format
- Consider trade-offs and alternative approaches
CRITICAL: Prioritize simple solutions:
- ALWAYS check if needed functionality already exists before proposing new code
- Look for existing variables that just need to be passed/used differently
- Prefer using existing patterns over creating new ones
- The best fix often involves minimal code changes
- Example: "Use existing `modeInfo` from line 234 in export" vs "Create new mode tracking system"
</contributor_specific>
<backwards_compatibility_focus>
ALWAYS consider backwards compatibility:
- Think about existing data/configurations already in use
- Propose solutions that handle both old and new formats gracefully
- Consider migration paths for existing users
- Document any breaking changes clearly
- Prefer additive changes over breaking changes when possible
</backwards_compatibility_focus>
<communication_guidelines>
- Be direct and concise; avoid jargon in the final issue body.
- Keep questions optional and easy to answer with suggested options.
- Emphasize WHO is affected and WHEN it happens.
- Be supportive and encouraging to problem reporters
- Don't overwhelm users with technical questions upfront
- Clearly indicate when technical sections are optional
- Guide contributors through the additional requirements
- Make the "submit now" option clear for problem reporters
- When presenting template choices, include template descriptions to help users choose
- Explain that you're using the repository's own templates for consistency
</communication_guidelines>
<template_best_practices>
<practice name="template_detection">
Always check these locations in order:
1. .github/ISSUE_TEMPLATE/*.yml or *.yaml (GitHub form syntax)
2. .github/ISSUE_TEMPLATE/*.md (Markdown templates)
3. .github/issue_template.md (single template)
4. .github/ISSUE_TEMPLATE.md (alternate naming)
</practice>
<practice name="template_parsing">
For YAML templates:
- Extract form elements and convert to appropriate markdown sections
- Preserve required field indicators
- Include field descriptions as context
- Respect dropdown options and checkbox lists
For Markdown templates:
- Parse front matter for metadata
- Identify section headers and structure
- Replace placeholder text with actual information
- Maintain formatting and hierarchy
</practice>
<practice name="template_filling">
- Map gathered information to template sections intelligently
- Don't leave placeholder text in the final issue
- Add code investigation findings to relevant sections
- Include contributor scoping in appropriate section if applicable
- Preserve the template's intended structure and flow
</practice>
<practice name="no_template_handling">
When no templates exist:
- Create minimal, focused templates
- Use simple section headers
- Focus on essential information only
- Adapt structure based on issue type
- Don't overwhelm with unnecessary fields
</practice>
</template_best_practices>
<technical_accuracy_guidelines>
<guideline name="thorough_code_analysis">
Before proposing ANY solution:
1. Use codebase_search extensively to find all related code
2. Read multiple files to understand the full context
3. Trace variable usage from creation to consumption
4. Look for similar working features to understand patterns
5. Identify what already exists vs what's actually missing
</guideline>
<guideline name="simplicity_first">
When designing solutions:
1. Check if the data/function already exists somewhere
2. Look for configuration options before code changes
3. Prefer passing existing variables over creating new ones
4. Use established patterns from similar features
5. Aim for minimal diff size
</guideline>
<guideline name="precise_technical_details">
Always include:
- Exact file paths and line numbers
- Variable/function names as they appear in code
- Before/after code snippets showing minimal changes
- Clear explanation of why the simple fix works
</guideline>
</technical_accuracy_guidelines>
</best_practices>

View file

@ -1,109 +1,126 @@
<common_mistakes_to_avoid>
<mode_initialization_mistakes>
- Asking "What would you like to do?" at start instead of treating the first message as the issue description
- Delaying the workflow with unnecessary questions before discovery
- Not immediately beginning codebase-aware discovery (semantic search → regex refine → read key files)
- Skipping repository detection (git + origin) before discovery or submission
- Not validating repository context before gh commands
- CRITICAL: Asking "What would you like to do?" when mode starts
- Waiting for user to say "create an issue" or "make me an issue"
- Not treating the first user message as the issue description
- Delaying the workflow start with unnecessary questions
- Asking if they want to create an issue when they've already chosen this mode
- Not immediately beginning repository detection and codebase discovery
</mode_initialization_mistakes>
<scope_mistakes>
- Submitting without explicit user confirmation ("Submit now")
- Targeting the wrong repository by relying on current directory defaults; always pass --repo OWNER/REPO detected in Step 2
- Performing PR prep, complexity estimates, or technical scoping
</scope_mistakes>
<submission_mistakes>
<mistake_block>
<mistake>Splitting final review and submission into multiple steps</mistake>
<impact>Creates redundant prompts and inconsistent state; leads to janky UX</impact>
<correct_approach>Use a single merged "Review and Submit" step offering only: Submit now, Submit now and assign to me; treat any other response as a change request</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Not offering "Submit now and assign to me"</mistake>
<impact>Forces manual assignment later; reduces efficiency</impact>
<correct_approach>Provide the assignment option and use gh issue create --assignee "@me"; if that fails, immediately run gh issue edit <issue-url-or-number> --add-assignee "@me"</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Using temporary files or --body-file for issue body submission</mistake>
<impact>Introduces filesystem dependencies and leaks paths; contradicts single-command policy</impact>
<correct_approach>Use inline --body with robust quoting, e.g., --body "$(printf '%s\n' "[ISSUE_BODY]")"; do not reference any file paths</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Omitting --repo or relying on current directory defaults</mistake>
<impact>May submit to the wrong repository in multi-repo or worktree contexts</impact>
<correct_approach>Always pass --repo [OWNER_REPO] detected in Step 2</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Attempting submission without prior repository detection</mistake>
<impact>Commands may target the wrong repo or fail</impact>
<correct_approach>Detect git repo and ensure origin is configured before any gh commands</correct_approach>
</mistake_block>
</submission_mistakes>
<sourcing_mistakes>
<mistake_block>
<mistake>Inventing or inferring “Variations tried” when the user didnt provide any</mistake>
<impact>Misleads triage and wastes time reproducing non-existent attempts</impact>
<correct_approach>Omit the “Variations tried” line entirely unless explicitly provided; if needed, ask a targeted question first</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Framing only the problem without the value/impact</mistake>
<impact>Makes prioritization harder; obscures who benefits and why it matters</impact>
<correct_approach>Pair the problem with a plain-language value statement (who, when, why it matters)</correct_approach>
</mistake_block>
<mistake_block>
<mistake>Overstating impact without user signal</mistake>
<impact>Damages credibility and misguides prioritization</impact>
<correct_approach>Use conservative, plain language; if unsure, omit severity/reach or ask a single targeted question</correct_approach>
</mistake_block>
</sourcing_mistakes>
<problem_reporting_mistakes>
- Vague descriptions like "doesn't work" without who/when impact
- Missing minimal reproduction for bugs (environment, steps, expected, actual, variations)
- Enhancement requests that skip the user goal or desired behavior in plain language
- Titles/summaries that don't quickly communicate the issue
- Vague descriptions like "doesn't work" or "broken"
- Missing reproduction steps for bugs
- Feature requests without clear problem statements
- Not explaining the impact on users
- Forgetting to specify when/how the problem occurs
- Using wrong labels or no labels
- Titles that don't summarize the issue
- Not checking for duplicates
</problem_reporting_mistakes>
<output_mistakes>
- Including code paths, line numbers, stack traces, or diffs in the final issue body
- Adding labels, metadata, or repository details to the body
- Leaving empty section placeholders instead of omitting the section
- Using technical jargon instead of plain, user-centric language
</output_mistakes>
<code_exploration_mistakes>
<mistake>Skipping semantic search and jumping straight to assumptions</mistake>
<impact>Leads to misclassification and inaccurate context</impact>
<workflow_mistakes>
- Asking for technical details from non-contributing users
- Performing issue scoping before confirming user wants to contribute
- Requiring acceptance criteria from problem reporters
- Making the process too complex for simple problem reports
- Not clearly indicating the "submit now" option
- Overwhelming users with contributor requirements upfront
- Using hardcoded templates instead of repository templates
- Not checking for issue templates before creating content
- Ignoring template metadata like labels and assignees
</workflow_mistakes>
<contributor_mistakes>
- Starting implementation before approval
- Not providing detailed issue scoping when contributing
- Missing acceptance criteria for contributed features
- Forgetting to include technical context from code exploration
- Not considering trade-offs and alternatives
- Proposing solutions without understanding current architecture
</contributor_mistakes>
<technical_analysis_mistakes>
<mistake>Not tracing data flow completely through the system</mistake>
<impact>Missing that data already exists leads to proposing unnecessary new code</impact>
<correct_approach>
- Start with codebase_search on extracted keywords
- Refine with search_files for exact strings (errors, component names, flags)
- read_file only as needed to verify behavior; keep evidence internal
- Early-stop when hits converge or you can name the exact feature/component
- Escalate-once if signals conflict (one refined pass), then proceed
- Use codebase_search extensively to find ALL related code
- Trace variables from creation to consumption
- Check if needed data is already calculated but not used
- Look for similar working features as patterns
</correct_approach>
</code_exploration_mistakes>
<discrepancy_handling_mistakes>
<mistake>Accepting user claims that contradict the codebase without verification</mistake>
<impact>Produces misleading or incorrect issue framing</impact>
<example>
Bad: "Add mode tracking to import function"
Good: "The export already includes mode info at line 234, just use it in import at line 567"
</example>
</technical_analysis_mistakes>
<solution_design_mistakes>
<mistake>Proposing complex new systems when simple fixes exist</mistake>
<impact>Creates unnecessary complexity, maintenance burden, and potential bugs</impact>
<correct_approach>
- Verify claims against the implementation; trace data from creation → usage
- Compare with similar working features to ground expectations
- If discrepancies arise, present concrete, plain-language examples (no code) and confirm
- ALWAYS check if functionality already exists first
- Look for minimal changes that solve the problem
- Prefer using existing variables/functions differently
- Aim for the smallest possible diff
</correct_approach>
</discrepancy_handling_mistakes>
<questioning_mistakes>
- Asking broad, unfocused questions instead of targeted ones based on findings
- Demanding technical details from non-technical users
- Failing to provide easy, suggested answer formats (repro scaffold, goal statement)
</questioning_mistakes>
<consistency_mistakes>
- Mixing internal technical evidence into the final body
- Ignoring the issue format or adding extra sections
- Using inconsistent tone or switching between technical and non-technical language
</consistency_mistakes>
<example>
Bad: "Create new state management system for mode tracking"
Good: "Pass existing modeInfo variable from line 45 to the function at line 78"
</example>
</solution_design_mistakes>
<code_verification_mistakes>
<mistake>Not reading actual code before proposing solutions</mistake>
<impact>Solutions don't match the actual codebase structure</impact>
<correct_approach>
- Always read the relevant files first
- Verify exact line numbers and content
- Check imports/exports to understand data availability
- Look at similar features that work correctly
</correct_approach>
</code_verification_mistakes>
<pattern_recognition_mistakes>
<mistake>Creating new patterns instead of following existing ones</mistake>
<impact>Inconsistent codebase, harder to maintain</impact>
<correct_approach>
- Find similar features that work correctly
- Follow the same patterns and structures
- Reuse existing utilities and helpers
- Maintain consistency with the codebase style
</correct_approach>
</pattern_recognition_mistakes>
<template_usage_mistakes>
<mistake>Using hardcoded templates when repository templates exist</mistake>
<impact>Issues don't follow repository conventions, may be rejected or need reformatting</impact>
<correct_approach>
- Always check .github/ISSUE_TEMPLATE/ directory first
- Parse and use repository templates when available
- Only create generic templates when none exist
</correct_approach>
</template_usage_mistakes>
<template_parsing_mistakes>
<mistake>Not properly parsing YAML template structure</mistake>
<impact>Missing required fields, incorrect formatting, lost metadata</impact>
<correct_approach>
- Parse YAML templates to extract all form elements
- Convert form elements to appropriate markdown sections
- Preserve field requirements and descriptions
- Maintain dropdown options and checkbox lists
</correct_approach>
</template_parsing_mistakes>
<template_filling_mistakes>
<mistake>Leaving placeholder text in final issue</mistake>
<impact>Unprofessional appearance, confusion about what information is needed</impact>
<correct_approach>
- Replace all placeholders with actual information
- Remove instruction text meant for template users
- Fill every section with relevant content
- Add "N/A" for truly inapplicable sections
</correct_approach>
</template_filling_mistakes>
</common_mistakes_to_avoid>

View file

@ -1,134 +0,0 @@
<issue_examples>
<overview>
Examples of assembling template-free issue prompts grounded by codebase exploration, with optional CLI submission after explicit confirmation.
Repository detection precedes submission; review and submission occur in a single merged step offering "Submit now" or "Submit now and assign to me". Any other response is treated as a change request.
</overview>
<example name="bug_dark_theme_button_invisible">
<user_input>
In dark theme the Submit button is almost invisible on the New Run page.
</user_input>
<discovery>
<tool_calls>
<![CDATA[
<codebase_search>
<query>dark theme submit button visibility</query>
</codebase_search>
<search_files>
<path>.</path>
<regex>Submit|button|dark|theme</regex>
</search_files>
]]>
</tool_calls>
<notes>
Internal: matches found in UI components related to theme; wording grounded to user impact.
</notes>
</discovery>
<final_issue_body><![CDATA[
## Type
Bug
## Problem / Value
In dark theme, the Submit button is hard to see on the new run form, making it difficult for users to complete new runs.
## Context
Affects users creating new runs with dark theme enabled; the button appears low-contrast and is difficult to locate.
## Reproduction
1) Steps: Open "New Run" -> Scroll to bottom -> Look for Submit
2) Expected result: Clearly visible, high-contrast Submit button
3) Actual result: Button appears nearly invisible in dark theme
4) Variations tried: Different browsers (Chrome/Firefox) show same result
]]></final_issue_body>
</example>
<example name="enhancement_copy_run_confirmation">
<user_input>
I accidentally click "Copy Run" sometimes; would be great to have a simple confirmation.
</user_input>
<discovery>
<tool_calls>
<![CDATA[
<codebase_search>
<query>Copy Run confirmation</query>
</codebase_search>
]]>
</tool_calls>
<notes>
Internal: feature entry point identified; keep final output non-technical and user-centric.
</notes>
</discovery>
<final_issue_body><![CDATA[
## Type
Enhancement
## Problem / Value
Add a confirmation dialog before copying an existing run to prevent accidental duplication.
## Context
Users sometimes click "Copy Run" by mistake when browsing runs; a simple confirmation would prevent accidental duplication.
## Constraints/Preferences
Keep the flow lightweight and unobtrusive; avoid slowing down intentional copies.
]]></final_issue_body>
</example>
<example name="bug_submission_review_and_assign">
<user_input>
Dark theme Submit button is invisible; I'd like to file this.
</user_input>
<final_issue_body><![CDATA[
## Type
Bug
## Problem / Value
In dark theme, the Submit button is hard to see on the new run form, making it difficult for users to complete new runs.
## Context
Affects users creating new runs with dark theme enabled; the button appears low-contrast and is difficult to locate.
## Reproduction
1) Steps: Open "New Run" -> Scroll to bottom -> Look for Submit
2) Expected result: Clearly visible, high-contrast Submit button
3) Actual result: Button appears nearly invisible in dark theme
]]></final_issue_body>
<review_and_submit>
<ask_followup_question>
<question>Review the current issue details. Select one of the options below or specify any changes or other workflow you would like me to perform:
```md
Title: [ISSUE_TITLE]
[ISSUE_BODY]
```</question>
<follow_up>
<suggest>Submit now</suggest>
<suggest>Submit now and assign to me</suggest>
</follow_up>
</ask_followup_question>
<execute_command for="submit_now">
<command>gh issue create --repo "[OWNER_REPO]" --title "[ISSUE_TITLE]" --body "$(printf '%s\n' "[ISSUE_BODY]")"</command>
</execute_command>
<execute_command for="submit_now_and_assign_to_me">
<command>ISSUE_URL=$(gh issue create --repo "[OWNER_REPO]" --title "[ISSUE_TITLE]" --body "$(printf '%s\n' "[ISSUE_BODY]")" --assignee "@me") || true; if [ -z "$ISSUE_URL" ]; then ISSUE_URL=$(gh issue create --repo "[OWNER_REPO]" --title "[ISSUE_TITLE]" --body "$(printf '%s\n' "[ISSUE_BODY]")"); gh issue edit "$ISSUE_URL" --add-assignee "@me"; fi; echo "$ISSUE_URL"</command>
</execute_command>
<loopback_note>
If a change request is provided, collect the requested edits, update the draft (re-run discovery if new info affects context), then rerun this merged step.
</loopback_note>
<expected_output>https://github.com/OWNER/REPO/issues/123</expected_output>
</review_and_submit>
</example>
<policies>
<policy>Issues are template-free (Title + Body only).</policy>
<policy>Repository detection (git + origin → OWNER/REPO) occurs before submission and is passed explicitly via --repo [OWNER_REPO].</policy>
<policy>Never use --body-file or temporary files; submit with inline --body only (no file paths).</policy>
<policy>Review and submission happen in one merged step offering "Submit now" or "Submit now and assign to me"; any other response is treated as a change request.</policy>
<policy>All discovery is internal; keep final output plain-language.</policy>
</policies>
</issue_examples>

View file

@ -0,0 +1,342 @@
<github_cli_usage>
<overview>
The GitHub CLI (gh) provides comprehensive tools for interacting with GitHub.
Here's when and how to use each command in the issue creation workflow.
Note: This mode prioritizes using repository-specific issue templates over
hardcoded ones. Templates are detected and used dynamically from the repository.
</overview>
<pre_creation_commands>
<command name="gh issue list">
<when_to_use>
ALWAYS use this FIRST before creating any issue to check for duplicates.
Search for keywords from the user's problem description.
</when_to_use>
<example>
<execute_command>
<command>gh issue list --repo $REPO_FULL_NAME --search "dark theme button visibility" --state all --limit 20</command>
</execute_command>
</example>
<options>
--search: Search query for issue titles and bodies
--state: all, open, or closed
--label: Filter by specific labels
--limit: Number of results to show
--json: Get structured JSON output
</options>
</command>
<command name="gh search issues">
<when_to_use>
Use for more advanced searches across issues and pull requests.
Supports GitHub's advanced search syntax.
</when_to_use>
<example>
<execute_command>
<command>gh search issues --repo $REPO_FULL_NAME "dark theme button" --limit 10</command>
</execute_command>
</example>
</command>
<command name="gh issue view">
<when_to_use>
Use when you find a potentially related issue and need full details.
Check if the user's issue is already reported or related.
</when_to_use>
<example>
<execute_command>
<command>gh issue view 123 --repo $REPO_FULL_NAME --comments</command>
</execute_command>
</example>
<options>
--comments: Include issue comments
--json: Get structured data
--web: Open in browser
</options>
</command>
</pre_creation_commands>
<template_detection_commands>
<command name="list_files">
<when_to_use>
Use to check for issue templates in the repository before creating issues.
This is not a gh command but necessary for template detection.
</when_to_use>
<examples>
Check for templates in standard location:
<list_files>
<path>.github/ISSUE_TEMPLATE</path>
<recursive>true</recursive>
</list_files>
Check for single template file:
<list_files>
<path>.github</path>
<recursive>false</recursive>
</list_files>
</examples>
</command>
<command name="read_file">
<when_to_use>
Read template files to parse their structure and content.
Used after detecting template files.
</when_to_use>
<examples>
Read YAML template:
<read_file>
<path>.github/ISSUE_TEMPLATE/bug_report.yml</path>
</read_file>
Read Markdown template:
<read_file>
<path>.github/ISSUE_TEMPLATE/feature_request.md</path>
</read_file>
</examples>
</command>
</template_detection_commands>
<contributor_only_commands>
<note>
These commands should ONLY be used if the user has indicated they want to
contribute the implementation. Skip these for problem reporters.
</note>
<command name="gh repo view">
<when_to_use>
Get repository information and recent activity.
</when_to_use>
<example>
<execute_command>
<command>gh repo view $REPO_FULL_NAME --json defaultBranchRef,description,updatedAt</command>
</execute_command>
</example>
</command>
<command name="gh search prs">
<when_to_use>
Check recent PRs that might be related to the issue.
Look for PRs that modified relevant code.
</when_to_use>
<example>
<execute_command>
<command>gh search prs --repo $REPO_FULL_NAME "dark theme" --limit 10 --state all</command>
</execute_command>
</example>
</command>
<command name="git log">
<when_to_use>
For bug reports from contributors, check recent commits that might have introduced the issue.
Use after cloning the repository locally.
</when_to_use>
<example>
<execute_command>
<command>git log --oneline --grep="theme" -n 20</command>
</execute_command>
</example>
</command>
</contributor_only_commands>
<issue_creation_command>
<command name="gh issue create">
<when_to_use>
Only use after:
1. Confirming no duplicates exist
2. Checking for and using repository templates
3. Gathering all required information
4. Determining if user is contributing or just reporting
5. Getting user confirmation
</when_to_use>
<bug_report_example>
<execute_command>
<command>gh issue create --repo $REPO_FULL_NAME --title "[Descriptive title of the bug]" --body-file /tmp/issue_body.md --label "bug"</command>
</execute_command>
</bug_report_example>
<feature_request_example>
<execute_command>
<command>gh issue create --repo $REPO_FULL_NAME --title "[Problem-focused title]" --body-file /tmp/issue_body.md --label "proposal" --label "enhancement"</command>
</execute_command>
</feature_request_example>
<options>
--title: Issue title (required)
--body: Issue body text
--body-file: Read body from file
--label: Add labels (can use multiple times)
--assignee: Assign to user
--project: Add to project
--web: Open in browser to create
</options>
</command>
</issue_creation_command>
<post_creation_commands>
<command name="gh issue comment">
<when_to_use>
ONLY use if user wants to add additional information after creation.
</when_to_use>
<example>
<execute_command>
<command>gh issue comment 456 --repo $REPO_FULL_NAME --body "Additional context or comments."</command>
</execute_command>
</example>
</command>
<command name="gh issue edit">
<when_to_use>
Use if user realizes they need to update the issue after creation.
Can update title, body, or labels.
</when_to_use>
<example>
<execute_command>
<command>gh issue edit 456 --repo $REPO_FULL_NAME --title "[Updated title]" --body "[Updated body]"</command>
</execute_command>
</example>
</command>
</post_creation_commands>
<workflow_integration>
<step_1_integration>
After user selects issue type, immediately search for related issues:
1. Use `gh issue list --search` with keywords from their description
2. Show any similar issues found
3. Ask if they want to continue or comment on existing issue
</step_1_integration>
<step_2_integration>
Template detection (NEW):
1. Use list_files to check .github/ISSUE_TEMPLATE/ directory
2. Read any template files found (YAML or Markdown)
3. Parse template structure and metadata
4. If multiple templates, let user choose
5. If no templates, prepare to create generic one
</step_2_integration>
<step_3_integration>
Decision point for contribution:
1. Ask user if they want to contribute implementation
2. If yes: Use contributor commands for codebase investigation
3. If no: Skip directly to creating a problem-focused issue
4. This saves time for problem reporters
</step_3_integration>
<step_4_integration>
During codebase exploration (CONTRIBUTORS ONLY):
1. Clone repo locally if needed: `gh repo clone $REPO_FULL_NAME`
2. Use `git log` to find recent changes to affected files
3. Use `gh search prs` for related pull requests
4. Include findings in the technical context section
</step_4_integration>
<step_5_integration>
When creating the issue:
1. Use repository template if found, or generic template if not
2. Fill template with gathered information
3. Format differently based on contributor vs problem reporter
4. Save formatted body to temporary file
5. Use `gh issue create` with appropriate labels from template
6. Capture the returned issue URL
7. Show user the created issue URL
</step_5_integration>
</workflow_integration>
<best_practices>
<practice name="file_handling">
When creating issues with long bodies:
1. Save to temporary file: `cat > /tmp/issue_body.md << 'EOF'`
2. Use --body-file flag with gh issue create
3. Clean up after: `rm /tmp/issue_body.md`
</practice>
<practice name="search_efficiency">
Use specific search terms:
- Include error messages in quotes
- Use label filters when appropriate
- Limit results to avoid overwhelming output
</practice>
<practice name="json_output">
Use --json flag for structured data when needed:
- Easier to parse programmatically
- Consistent format across commands
- Example: `gh issue list --json number,title,state`
</practice>
</best_practices>
<error_handling>
<duplicate_found>
If search finds exact duplicate:
- Show the existing issue to user using `gh issue view`
- Ask if they want to add a comment instead
- Use `gh issue comment` if they agree
</duplicate_found>
<creation_failed>
If `gh issue create` fails:
- Check error message (auth, permissions, network)
- Ensure gh is authenticated: `gh auth status`
- Save the drafted issue content for user
- Suggest using --web flag to create in browser
</creation_failed>
<authentication>
Ensure GitHub CLI is authenticated:
- Check status: `gh auth status`
- Login if needed: `gh auth login`
- Select appropriate scopes for issue creation
</authentication>
</error_handling>
<command_reference>
<issues>
gh issue create - Create new issue
gh issue list - List and search issues
gh issue view - View issue details
gh issue comment - Add comment to issue
gh issue edit - Edit existing issue
gh issue close - Close an issue
gh issue reopen - Reopen closed issue
</issues>
<search>
gh search issues - Search issues and PRs
gh search prs - Search pull requests
gh search repos - Search repositories
</search>
<repository>
gh repo view - View repository info
gh repo clone - Clone repository
</repository>
</command_reference>
<template_handling_reference>
<yaml_template_parsing>
When parsing YAML templates:
- Extract 'name' for template identification
- Get 'labels' array for automatic labeling
- Parse 'body' array for form elements
- Convert form elements to markdown sections
- Preserve 'required' field indicators
</yaml_template_parsing>
<markdown_template_parsing>
When parsing Markdown templates:
- Check for YAML front matter
- Extract metadata (labels, assignees)
- Identify section headers
- Replace placeholder text
- Maintain formatting structure
</markdown_template_parsing>
<template_usage_flow>
1. Detect templates with list_files
2. Read templates with read_file
3. Parse structure and metadata
4. Let user choose if multiple exist
5. Fill template with information
6. Create issue with template content
</template_usage_flow>
</template_handling_reference>
</github_cli_usage>

View file

@ -30,13 +30,12 @@
<tools>
<tool>gh pr checkout [PR_NUMBER] --force</tool>
<tool>git fetch origin main</tool>
<tool>GIT_EDITOR=true git rebase origin/main</tool>
<tool>git rebase origin/main</tool>
</tools>
<details>
Force checkout the PR branch to ensure clean state
Fetch the latest main branch
Attempt to rebase onto main to reveal conflicts
Use GIT_EDITOR=true to ensure non-interactive rebase
</details>
</step>
@ -109,8 +108,8 @@
</command>
<command name="rebase_main">
<syntax>GIT_EDITOR=true git rebase origin/main</syntax>
<purpose>Rebase current branch onto main to reveal conflicts (non-interactive)</purpose>
<syntax>git rebase origin/main</syntax>
<purpose>Rebase current branch onto main to reveal conflicts</purpose>
</command>
<command name="get_blame_info">
@ -134,20 +133,6 @@
</command>
</git_commands>
<command name="continue_rebase">
<syntax>GIT_EDITOR=true git rebase --continue</syntax>
<purpose>Continue rebase after resolving conflicts (non-interactive)</purpose>
</command>
</git_commands>
<environment_variables>
<variable name="GIT_EDITOR">
<value>true</value>
<purpose>Set to 'true' (a no-op command) to prevent interactive prompts during rebase operations</purpose>
<usage>Prefix git rebase commands with GIT_EDITOR=true to ensure non-interactive execution</usage>
</variable>
</environment_variables>
<completion_criteria>
<criterion>All merge conflicts have been resolved</criterion>
<criterion>Resolved files have been staged</criterion>

View file

@ -33,7 +33,7 @@
<principle priority="high">
<name>Escape Conflict Markers</name>
<description>
When using apply_diff, always escape merge
When using apply_diff or search_and_replace tools, always escape merge
conflict markers with backslashes to prevent parsing errors.
</description>
<example><![CDATA[

View file

@ -13,7 +13,7 @@
</priority>
<priority level="3">
<tool>apply_diff</tool>
<tool>apply_diff or search_and_replace</tool>
<when>To resolve conflicts by replacing conflicted sections</when>
<why>Precise editing of specific conflict blocks</why>
</priority>
@ -26,8 +26,6 @@
<practice>Chain git commands with && for efficiency</practice>
<practice>Use --format options for structured output</practice>
<practice>Capture command output for parsing</practice>
<practice>Use GIT_EDITOR=true for non-interactive git rebase operations</practice>
<practice>Set environment variables inline to avoid prompts during automation</practice>
</best_practices>
<common_commands>
@ -48,7 +46,7 @@
<command>
<purpose>Rebase onto main to reveal conflicts</purpose>
<syntax>GIT_EDITOR=true git rebase origin/main</syntax>
<syntax>git rebase origin/main</syntax>
</command>
<command>
@ -73,7 +71,7 @@
<command>
<purpose>Continue rebase after resolution</purpose>
<syntax>GIT_EDITOR=true git rebase --continue</syntax>
<syntax>git rebase --continue</syntax>
</command>
</common_commands>
</tool>
@ -127,6 +125,25 @@ function mergedImplementation() {
]]></example>
</tool>
<tool name="search_and_replace">
<best_practices>
<practice>Use for simple conflict resolutions</practice>
<practice>Enable regex mode for complex patterns</practice>
<practice>Always escape special characters</practice>
</best_practices>
<example><![CDATA[
<search_and_replace>
<path>src/config.ts</path>
<search>\<<<<<<< HEAD[\s\S]*?\>>>>>>> \w+</search>
<replace>// Resolved configuration
const config = {
// Merged settings from both branches
}</replace>
<use_regex>true</use_regex>
</search_and_replace>
]]></example>
</tool>
</tool_specific_guidance>
<tool_combination_patterns>
@ -135,7 +152,7 @@ function mergedImplementation() {
<step>execute_command - Get PR info with gh CLI</step>
<step>execute_command - Checkout PR with gh pr checkout --force</step>
<step>execute_command - Fetch origin main</step>
<step>execute_command - Rebase onto origin/main with GIT_EDITOR=true</step>
<step>execute_command - Rebase onto origin/main</step>
<step>execute_command - Check for conflicts with git status</step>
</sequence>
</pattern>
@ -161,22 +178,13 @@ function mergedImplementation() {
<pattern name="complete_rebase">
<sequence>
<step>execute_command - Check all conflicts resolved</step>
<step>execute_command - Continue rebase with GIT_EDITOR=true git rebase --continue</step>
<step>execute_command - Continue rebase with git rebase --continue</step>
<step>execute_command - Verify clean status</step>
</sequence>
</pattern>
</tool_combination_patterns>
<error_handling>
<scenario name="interactive_prompt_blocking">
<description>Git commands waiting for interactive input</description>
<approach>
Use GIT_EDITOR=true to bypass editor prompts
Set GIT_SEQUENCE_EDITOR=true for sequence editing
Consider --no-edit flag for commit operations
</approach>
</scenario>
<scenario name="no_conflicts_after_rebase">
<description>Rebase completes without conflicts</description>
<approach>
@ -196,7 +204,7 @@ function mergedImplementation() {
<scenario name="malformed_conflicts">
<description>Conflict markers are incomplete or nested</description>
<approach>
Use apply_diff with precise search blocks; split into multiple targeted edits if needed
Use search_and_replace with careful regex patterns
Manual inspection may be required
</approach>
</scenario>
@ -213,46 +221,8 @@ function mergedImplementation() {
<description>Code contains literal conflict marker strings</description>
<approach>
Extra careful escaping in diffs
Prefer apply_diff with precise search blocks
Consider using search_and_replace with precise patterns
</approach>
</scenario>
</error_handling>
<non_interactive_operations>
<overview>
Ensuring git operations run without requiring user interaction is critical
for automated conflict resolution. The mode uses environment variables to
bypass interactive prompts.
</overview>
<techniques>
<technique name="GIT_EDITOR">
<description>Set to 'true' (a no-op command) to skip editor prompts</description>
<usage>GIT_EDITOR=true git rebase --continue</usage>
<when>During rebase operations that would normally open an editor</when>
</technique>
<technique name="GIT_SEQUENCE_EDITOR">
<description>Skip interactive rebase todo editing</description>
<usage>GIT_SEQUENCE_EDITOR=true git rebase -i HEAD~3</usage>
<when>When interactive rebase is triggered but no editing needed</when>
</technique>
<technique name="commit_flags">
<description>Use flags to avoid interactive prompts</description>
<examples>
<example>git commit --no-edit (use existing message)</example>
<example>git merge --no-edit (skip merge message editing)</example>
<example>git cherry-pick --no-edit (keep original message)</example>
</examples>
</technique>
</techniques>
<best_practices>
<practice>Always test commands locally first to identify potential prompts</practice>
<practice>Combine environment variables when multiple editors might be invoked</practice>
<practice>Document why non-interactive mode is used in comments</practice>
<practice>Have fallback strategies if automation fails</practice>
</best_practices>
</non_interactive_operations>
</merge_resolver_tool_usage>

View file

@ -54,7 +54,7 @@ From github.com:user/repo
<tool_use><![CDATA[
<execute_command>
<command>GIT_EDITOR=true git rebase origin/main</command>
<command>git rebase origin/main</command>
</execute_command>
]]></tool_use>
<expected_output><![CDATA[
@ -251,7 +251,7 @@ abc123 Fix: Add listener cleanup to prevent memory leak
<tool_use><![CDATA[
<execute_command>
<command>GIT_EDITOR=true git rebase --continue</command>
<command>git rebase --continue</command>
</execute_command>
]]></tool_use>
<expected_output><![CDATA[
@ -309,8 +309,7 @@ Both the feature refactor and the critical bugfix have been preserved in the res
<takeaway>Use git blame and commit messages to understand the history</takeaway>
<takeaway>Combine non-conflicting improvements when possible</takeaway>
<takeaway>Prioritize bugfixes while accommodating refactors</takeaway>
<takeaway>Use GIT_EDITOR=true to ensure non-interactive rebase operations</takeaway>
<takeaway>Complete the rebase process with GIT_EDITOR=true git rebase --continue</takeaway>
<takeaway>Complete the rebase process with git rebase --continue</takeaway>
<takeaway>Validate that both sets of changes work together</takeaway>
</key_takeaways>
</merge_resolver_example>

View file

@ -0,0 +1,301 @@
<mode_management_workflow>
<overview>
This workflow guides you through creating new custom modes or editing existing modes
for the Roo Code Software, ensuring comprehensive understanding and cohesive implementation.
</overview>
<initial_determination>
<step number="1">
<title>Determine User Intent</title>
<description>
Identify whether the user wants to create a new mode or edit an existing one
</description>
<detection_patterns>
<pattern type="edit_existing">
<indicators>
<indicator>User mentions a specific mode by name or slug</indicator>
<indicator>User references a mode directory path (e.g., .roo/rules-[mode-slug])</indicator>
<indicator>User asks to modify, update, enhance, or fix an existing mode</indicator>
<indicator>User says "edit this mode" or "change this mode"</indicator>
</indicators>
</pattern>
<pattern type="create_new">
<indicators>
<indicator>User asks to create a new mode</indicator>
<indicator>User describes a new capability not covered by existing modes</indicator>
<indicator>User says "make a mode for" or "create a mode that"</indicator>
</indicators>
</pattern>
</detection_patterns>
<clarification_question>
<ask_followup_question>
<question>I want to make sure I understand correctly. Are you looking to create a brand new mode or modify an existing one?</question>
<follow_up>
<suggest>Create a new mode for a specific purpose</suggest>
<suggest>Edit an existing mode to add new capabilities</suggest>
<suggest>Fix issues in an existing mode</suggest>
<suggest>Enhance an existing mode with better workflows</suggest>
</follow_up>
</ask_followup_question>
</clarification_question>
</step>
</initial_determination>
<workflow_branches>
<branch name="create_new_mode">
<step number="2a">
<title>Gather Requirements for New Mode</title>
<description>
Understand what the user wants the new mode to accomplish
</description>
<actions>
<action>Ask about the mode's primary purpose and use cases</action>
<action>Identify what types of tasks the mode should handle</action>
<action>Determine what tools and file access the mode needs</action>
<action>Clarify any special behaviors or restrictions</action>
</actions>
<example>
<ask_followup_question>
<question>What is the primary purpose of this new mode? What types of tasks should it handle?</question>
<follow_up>
<suggest>A mode for writing and maintaining documentation</suggest>
<suggest>A mode for database schema design and migrations</suggest>
<suggest>A mode for API endpoint development and testing</suggest>
<suggest>A mode for performance optimization and profiling</suggest>
</follow_up>
</ask_followup_question>
</example>
</step>
<step number="3a">
<title>Design Mode Configuration</title>
<description>
Create the mode definition with all required fields
</description>
<required_fields>
<field name="slug">
<description>Unique identifier (lowercase, hyphens allowed)</description>
<best_practice>Keep it short and descriptive (e.g., "api-dev", "docs-writer")</best_practice>
</field>
<field name="name">
<description>Display name with optional emoji</description>
<best_practice>Use an emoji that represents the mode's purpose</best_practice>
</field>
<field name="roleDefinition">
<description>Detailed description of the mode's role and expertise</description>
<best_practice>
Start with "You are Roo Code, a [specialist type]..."
List specific areas of expertise
Mention key technologies or methodologies
</best_practice>
</field>
<field name="groups">
<description>Tool groups the mode can access</description>
<options>
<option name="read">File reading and searching tools</option>
<option name="edit">File editing tools (can be restricted by regex)</option>
<option name="command">Command execution tools</option>
<option name="browser">Browser interaction tools</option>
<option name="mcp">MCP server tools</option>
</options>
</field>
</required_fields>
<recommended_fields>
<field name="whenToUse">
<description>Clear description for the Orchestrator</description>
<best_practice>Explain specific scenarios and task types</best_practice>
</field>
</recommended_fields>
<important_note>
Do not include customInstructions in the .roomodes configuration.
All detailed instructions should be placed in XML files within
the .roo/rules-[mode-slug]/ directory instead.
</important_note>
</step>
<step number="4a">
<title>Implement File Restrictions</title>
<description>
Configure appropriate file access permissions
</description>
<example>
<comment>Restrict edit access to specific file types</comment>
<code>
groups:
- read
- - edit
- fileRegex: \.(md|txt|rst)$
description: Documentation files only
- command
</code>
</example>
<guidelines>
<guideline>Use regex patterns to limit file editing scope</guideline>
<guideline>Provide clear descriptions for restrictions</guideline>
<guideline>Consider the principle of least privilege</guideline>
</guidelines>
</step>
<step number="5a">
<title>Create XML Instruction Files</title>
<description>
Design structured instruction files in .roo/rules-[mode-slug]/
</description>
<file_structure>
<file name="1_workflow.xml">Main workflow and step-by-step processes</file>
<file name="2_best_practices.xml">Guidelines and conventions</file>
<file name="3_common_patterns.xml">Reusable code patterns and examples</file>
<file name="4_tool_usage.xml">Specific tool usage instructions</file>
<file name="5_examples.xml">Complete workflow examples</file>
</file_structure>
<xml_best_practices>
<practice>Use semantic tag names that describe content</practice>
<practice>Nest tags hierarchically for better organization</practice>
<practice>Include code examples in CDATA sections when needed</practice>
<practice>Add comments to explain complex sections</practice>
</xml_best_practices>
</step>
</branch>
<branch name="edit_existing_mode">
<step number="2b">
<title>Immerse in Existing Mode</title>
<description>
Fully understand the existing mode before making any changes
</description>
<actions>
<action>Locate and read the mode configuration in .roomodes</action>
<action>Read all XML instruction files in .roo/rules-[mode-slug]/</action>
<action>Analyze the mode's current capabilities and limitations</action>
<action>Understand the mode's role in the broader ecosystem</action>
</actions>
<questions_to_ask>
<ask_followup_question>
<question>What specific aspects of the mode would you like to change or enhance?</question>
<follow_up>
<suggest>Add new capabilities or tool permissions</suggest>
<suggest>Fix issues with current workflows or instructions</suggest>
<suggest>Improve the mode's roleDefinition or whenToUse description</suggest>
<suggest>Enhance XML instructions for better clarity</suggest>
</follow_up>
</ask_followup_question>
</questions_to_ask>
</step>
<step number="3b">
<title>Analyze Change Impact</title>
<description>
Understand how proposed changes will affect the mode
</description>
<analysis_areas>
<area>Compatibility with existing workflows</area>
<area>Impact on file permissions and tool access</area>
<area>Consistency with mode's core purpose</area>
<area>Integration with other modes</area>
</analysis_areas>
<validation_questions>
<ask_followup_question>
<question>I've analyzed the existing mode. Here's what I understand about your requested changes. Is this correct?</question>
<follow_up>
<suggest>Yes, that's exactly what I want to change</suggest>
<suggest>Mostly correct, but let me clarify some details</suggest>
<suggest>No, I meant something different</suggest>
<suggest>I'd like to add additional changes</suggest>
</follow_up>
</ask_followup_question>
</validation_questions>
</step>
<step number="4b">
<title>Plan Modifications</title>
<description>
Create a detailed plan for modifying the mode
</description>
<planning_steps>
<step>Identify which files need to be modified</step>
<step>Determine if new XML instruction files are needed</step>
<step>Check for potential conflicts or contradictions</step>
<step>Plan the order of changes for minimal disruption</step>
</planning_steps>
</step>
<step number="5b">
<title>Implement Changes</title>
<description>
Apply the planned modifications to the mode
</description>
<implementation_order>
<change>Update .roomodes configuration if needed</change>
<change>Modify existing XML instruction files</change>
<change>Create new XML instruction files if required</change>
<change>Update examples and documentation</change>
</implementation_order>
</step>
</branch>
</workflow_branches>
<validation_and_cohesion>
<step number="6">
<title>Validate Cohesion and Consistency</title>
<description>
Ensure all changes are cohesive and don't contradict each other
</description>
<validation_checks>
<check type="configuration">
<item>Mode slug follows naming conventions</item>
<item>File restrictions align with mode purpose</item>
<item>Tool permissions are appropriate</item>
<item>whenToUse clearly differentiates from other modes</item>
</check>
<check type="instructions">
<item>All XML files follow consistent structure</item>
<item>No contradicting instructions between files</item>
<item>Examples align with stated workflows</item>
<item>Tool usage matches granted permissions</item>
</check>
<check type="integration">
<item>Mode integrates well with Orchestrator</item>
<item>Clear boundaries with other modes</item>
<item>Handoff points are well-defined</item>
</check>
</validation_checks>
<cohesion_questions>
<ask_followup_question>
<question>I've completed the validation checks. Would you like me to review any specific aspect in more detail?</question>
<follow_up>
<suggest>Review the file permission patterns</suggest>
<suggest>Check for workflow contradictions</suggest>
<suggest>Verify integration with other modes</suggest>
<suggest>Everything looks good, proceed to testing</suggest>
</follow_up>
</ask_followup_question>
</cohesion_questions>
</step>
<step number="7">
<title>Test and Refine</title>
<description>
Verify the mode works as intended
</description>
<checklist>
<item>Mode appears in the mode list</item>
<item>File restrictions work correctly</item>
<item>Instructions are clear and actionable</item>
<item>Mode integrates well with Orchestrator</item>
<item>All examples are accurate and helpful</item>
<item>Changes don't break existing functionality (for edits)</item>
<item>New capabilities work as expected</item>
</checklist>
</step>
</validation_and_cohesion>
<quick_reference>
<command>Create mode in .roomodes for project-specific modes</command>
<command>Create mode in global custom_modes.yaml for system-wide modes</command>
<command>Use list_files to verify .roo folder structure</command>
<command>Test file regex patterns with search_files</command>
<command>Use codebase_search to find existing mode implementations</command>
<command>Read all XML files in a mode directory to understand its structure</command>
<command>Always validate changes for cohesion and consistency</command>
</quick_reference>
</mode_management_workflow>

View file

@ -0,0 +1,220 @@
<xml_structuring_best_practices>
<overview>
XML tags help Claude parse prompts more accurately, leading to higher-quality outputs.
This guide covers best practices for structuring mode instructions using XML.
</overview>
<why_use_xml_tags>
<benefit type="clarity">
Clearly separate different parts of your instructions and ensure well-structured content
</benefit>
<benefit type="accuracy">
Reduce errors caused by Claude misinterpreting parts of your instructions
</benefit>
<benefit type="flexibility">
Easily find, add, remove, or modify parts of instructions without rewriting everything
</benefit>
<benefit type="parseability">
Having Claude use XML tags in its output makes it easier to extract specific parts of responses
</benefit>
</why_use_xml_tags>
<core_principles>
<principle name="consistency">
<description>Use the same tag names throughout your instructions</description>
<example>
Always use <step> for workflow steps, not sometimes <action> or <task>
</example>
</principle>
<principle name="semantic_naming">
<description>Tag names should clearly describe their content</description>
<good_examples>
<tag>detailed_steps</tag>
<tag>error_handling</tag>
<tag>validation_rules</tag>
</good_examples>
<bad_examples>
<tag>stuff</tag>
<tag>misc</tag>
<tag>data1</tag>
</bad_examples>
</principle>
<principle name="hierarchical_nesting">
<description>Nest tags to show relationships and structure</description>
<example>
<workflow>
<phase name="preparation">
<step>Gather requirements</step>
<step>Validate inputs</step>
</phase>
<phase name="execution">
<step>Process data</step>
<step>Generate output</step>
</phase>
</workflow>
</example>
</principle>
</core_principles>
<common_tag_patterns>
<pattern name="workflow_structure">
<usage>For step-by-step processes</usage>
<template><![CDATA[
<workflow>
<overview>High-level description</overview>
<prerequisites>
<prerequisite>Required condition 1</prerequisite>
<prerequisite>Required condition 2</prerequisite>
</prerequisites>
<steps>
<step number="1">
<title>Step Title</title>
<description>What this step accomplishes</description>
<actions>
<action>Specific action to take</action>
</actions>
<validation>How to verify success</validation>
</step>
</steps>
</workflow>
]]></template>
</pattern>
<pattern name="examples_structure">
<usage>For providing code examples and demonstrations</usage>
<template><![CDATA[
<examples>
<example name="descriptive_name">
<description>What this example demonstrates</description>
<context>When to use this approach</context>
<code language="typescript">
// Your code example here
</code>
<explanation>
Key points about the implementation
</explanation>
</example>
</examples>
]]></template>
</pattern>
<pattern name="guidelines_structure">
<usage>For rules and best practices</usage>
<template><![CDATA[
<guidelines category="category_name">
<guideline priority="high">
<rule>The specific rule or guideline</rule>
<rationale>Why this is important</rationale>
<exceptions>When this doesn't apply</exceptions>
</guideline>
</guidelines>
]]></template>
</pattern>
<pattern name="tool_usage_structure">
<usage>For documenting how to use specific tools</usage>
<template><![CDATA[
<tool_usage tool="tool_name">
<purpose>What this tool accomplishes</purpose>
<when_to_use>Specific scenarios for this tool</when_to_use>
<syntax>
<command>The exact command format</command>
<parameters>
<parameter name="param1" required="true">
<description>What this parameter does</description>
<type>string|number|boolean</type>
<example>example_value</example>
</parameter>
</parameters>
</syntax>
<examples>
<example scenario="common_use_case">
<code>Actual usage example</code>
<output>Expected output</output>
</example>
</examples>
</tool_usage>
]]></template>
</pattern>
</common_tag_patterns>
<formatting_guidelines>
<guideline name="indentation">
Use consistent indentation (2 or 4 spaces) for nested elements
</guideline>
<guideline name="line_breaks">
Add line breaks between major sections for readability
</guideline>
<guideline name="comments">
Use XML comments <!-- like this --> to explain complex sections
</guideline>
<guideline name="cdata_sections">
Use CDATA for code blocks or content with special characters:
<![CDATA[<code><![CDATA[your code here]]></code>]]>
</guideline>
<guideline name="attributes_vs_elements">
Use attributes for metadata, elements for content:
<example type="good">
<step number="1" priority="high">
<description>The actual step content</description>
</step>
</example>
</guideline>
</formatting_guidelines>
<anti_patterns>
<anti_pattern name="flat_structure">
<description>Avoid completely flat structures without hierarchy</description>
<bad><![CDATA[
<instructions>
<item1>Do this</item1>
<item2>Then this</item2>
<item3>Finally this</item3>
</instructions>
]]></bad>
<good><![CDATA[
<instructions>
<steps>
<step order="1">Do this</step>
<step order="2">Then this</step>
<step order="3">Finally this</step>
</steps>
</instructions>
]]></good>
</anti_pattern>
<anti_pattern name="inconsistent_naming">
<description>Don't mix naming conventions</description>
<bad>
Mixing camelCase, snake_case, and kebab-case in tag names
</bad>
<good>
Pick one convention (preferably snake_case for XML) and stick to it
</good>
</anti_pattern>
<anti_pattern name="overly_generic_tags">
<description>Avoid tags that don't convey meaning</description>
<bad>data, info, stuff, thing, item</bad>
<good>user_input, validation_result, error_message, configuration</good>
</anti_pattern>
</anti_patterns>
<integration_tips>
<tip>
Reference XML content in instructions:
"Using the workflow defined in &lt;workflow&gt; tags..."
</tip>
<tip>
Combine XML structure with other techniques like multishot prompting
</tip>
<tip>
Use XML tags in expected outputs to make parsing easier
</tip>
<tip>
Create reusable XML templates for common patterns
</tip>
</integration_tips>
</xml_structuring_best_practices>

View file

@ -0,0 +1,261 @@
<mode_configuration_patterns>
<overview>
Common patterns and templates for creating different types of modes, with examples from existing modes in the Roo-Code software.
</overview>
<mode_types>
<type name="specialist_mode">
<description>
Modes focused on specific technical domains or tasks
</description>
<characteristics>
<characteristic>Deep expertise in a particular area</characteristic>
<characteristic>Restricted file access based on domain</characteristic>
<characteristic>Specialized tool usage patterns</characteristic>
</characteristics>
<example_template><![CDATA[
- slug: api-specialist
name: 🔌 API Specialist
roleDefinition: >-
You are Roo Code, an API development specialist with expertise in:
- RESTful API design and implementation
- GraphQL schema design
- API documentation with OpenAPI/Swagger
- Authentication and authorization patterns
- Rate limiting and caching strategies
- API versioning and deprecation
You ensure APIs are:
- Well-documented and discoverable
- Following REST principles or GraphQL best practices
- Secure and performant
- Properly versioned and maintainable
whenToUse: >-
Use this mode when designing, implementing, or refactoring APIs.
This includes creating new endpoints, updating API documentation,
implementing authentication, or optimizing API performance.
groups:
- read
- - edit
- fileRegex: (api/.*\.(ts|js)|.*\.openapi\.yaml|.*\.graphql|docs/api/.*)$
description: API implementation files, OpenAPI specs, and API documentation
- command
- mcp
]]></example_template>
</type>
<type name="workflow_mode">
<description>
Modes that guide users through multi-step processes
</description>
<characteristics>
<characteristic>Step-by-step workflow guidance</characteristic>
<characteristic>Heavy use of ask_followup_question</characteristic>
<characteristic>Process validation at each step</characteristic>
</characteristics>
<example_template><![CDATA[
- slug: migration-guide
name: 🔄 Migration Guide
roleDefinition: >-
You are Roo Code, a migration specialist who guides users through
complex migration processes:
- Database schema migrations
- Framework version upgrades
- API version migrations
- Dependency updates
- Breaking change resolutions
You provide:
- Step-by-step migration plans
- Automated migration scripts
- Rollback strategies
- Testing approaches for migrations
whenToUse: >-
Use this mode when performing any kind of migration or upgrade.
This mode will analyze the current state, plan the migration,
and guide you through each step with validation.
groups:
- read
- edit
- command
]]></example_template>
</type>
<type name="analysis_mode">
<description>
Modes focused on code analysis and reporting
</description>
<characteristics>
<characteristic>Read-heavy operations</characteristic>
<characteristic>Limited or no edit permissions</characteristic>
<characteristic>Comprehensive reporting outputs</characteristic>
</characteristics>
<example_template><![CDATA[
- slug: security-auditor
name: 🔒 Security Auditor
roleDefinition: >-
You are Roo Code, a security analysis specialist focused on:
- Identifying security vulnerabilities
- Analyzing authentication and authorization
- Reviewing data validation and sanitization
- Checking for common security anti-patterns
- Evaluating dependency vulnerabilities
- Assessing API security
You provide detailed security reports with:
- Vulnerability severity ratings
- Specific remediation steps
- Security best practice recommendations
whenToUse: >-
Use this mode to perform security audits on codebases.
This mode will analyze code for vulnerabilities, check
dependencies, and provide actionable security recommendations.
groups:
- read
- command
- - edit
- fileRegex: (SECURITY\.md|\.github/security/.*|docs/security/.*)$
description: Security documentation files only
]]></example_template>
</type>
<type name="creative_mode">
<description>
Modes for generating new content or features
</description>
<characteristics>
<characteristic>Broad file creation permissions</characteristic>
<characteristic>Template and boilerplate generation</characteristic>
<characteristic>Interactive design process</characteristic>
</characteristics>
<example_template><![CDATA[
- slug: component-designer
name: 🎨 Component Designer
roleDefinition: >-
You are Roo Code, a UI component design specialist who creates:
- Reusable React/Vue/Angular components
- Component documentation and examples
- Storybook stories
- Unit tests for components
- Accessibility-compliant interfaces
You follow design system principles and ensure components are:
- Highly reusable and composable
- Well-documented with examples
- Fully tested
- Accessible (WCAG compliant)
- Performance optimized
whenToUse: >-
Use this mode when creating new UI components or refactoring
existing ones. This mode helps design component APIs, implement
the components, and create comprehensive documentation.
groups:
- read
- - edit
- fileRegex: (components/.*|stories/.*|__tests__/.*\.test\.(tsx?|jsx?))$
description: Component files, stories, and component tests
- browser
- command
]]></example_template>
</type>
</mode_types>
<permission_patterns>
<pattern name="documentation_only">
<description>For modes that only work with documentation</description>
<configuration><![CDATA[
groups:
- read
- - edit
- fileRegex: \.(md|mdx|rst|txt)$
description: Documentation files only
]]></configuration>
</pattern>
<pattern name="test_focused">
<description>For modes that work with test files</description>
<configuration><![CDATA[
groups:
- read
- command
- - edit
- fileRegex: (__tests__/.*|__mocks__/.*|.*\.test\.(ts|tsx|js|jsx)$|.*\.spec\.(ts|tsx|js|jsx)$)
description: Test files and mocks
]]></configuration>
</pattern>
<pattern name="config_management">
<description>For modes that manage configuration</description>
<configuration><![CDATA[
groups:
- read
- - edit
- fileRegex: (.*\.config\.(js|ts|json)|.*rc\.json|.*\.yaml|.*\.yml|\.env\.example)$
description: Configuration files (not .env)
]]></configuration>
</pattern>
<pattern name="full_stack">
<description>For modes that need broad access</description>
<configuration><![CDATA[
groups:
- read
- edit # No restrictions
- command
- browser
- mcp
]]></configuration>
</pattern>
</permission_patterns>
<naming_conventions>
<convention category="slug">
<rule>Use lowercase with hyphens</rule>
<good>api-dev, test-writer, docs-manager</good>
<bad>apiDev, test_writer, DocsManager</bad>
</convention>
<convention category="name">
<rule>Use title case with descriptive emoji</rule>
<good>🔧 API Developer, 📝 Documentation Writer</good>
<bad>api developer, DOCUMENTATION WRITER</bad>
</convention>
<convention category="emoji_selection">
<common_emojis>
<emoji meaning="testing">🧪</emoji>
<emoji meaning="documentation">📝</emoji>
<emoji meaning="design">🎨</emoji>
<emoji meaning="debugging">🪲</emoji>
<emoji meaning="building">🏗️</emoji>
<emoji meaning="security">🔒</emoji>
<emoji meaning="api">🔌</emoji>
<emoji meaning="database">🗄️</emoji>
<emoji meaning="performance"></emoji>
<emoji meaning="configuration">⚙️</emoji>
</common_emojis>
</convention>
</naming_conventions>
<integration_guidelines>
<guideline name="orchestrator_compatibility">
<description>Ensure whenToUse is clear for Orchestrator mode</description>
<checklist>
<item>Specify concrete task types the mode handles</item>
<item>Include trigger keywords or phrases</item>
<item>Differentiate from similar modes</item>
<item>Mention specific file types or areas</item>
</checklist>
</guideline>
<guideline name="mode_boundaries">
<description>Define clear boundaries between modes</description>
<checklist>
<item>Avoid overlapping responsibilities</item>
<item>Make handoff points explicit</item>
<item>Use switch_mode when appropriate</item>
<item>Document mode interactions</item>
</checklist>
</guideline>
</integration_guidelines>
</mode_configuration_patterns>

View file

@ -0,0 +1,367 @@
<instruction_file_templates>
<overview>
Templates and examples for creating XML instruction files that provide
detailed guidance for each mode's behavior and workflows.
</overview>
<file_organization>
<principle>Number files to indicate execution order</principle>
<principle>Use descriptive names that indicate content</principle>
<principle>Keep related instructions together</principle>
<standard_structure>
<file>1_workflow.xml - Main workflow and processes</file>
<file>2_best_practices.xml - Guidelines and conventions</file>
<file>3_common_patterns.xml - Reusable code patterns</file>
<file>4_tool_usage.xml - Specific tool instructions</file>
<file>5_examples.xml - Complete workflow examples</file>
<file>6_error_handling.xml - Error scenarios and recovery</file>
<file>7_communication.xml - User interaction guidelines</file>
</standard_structure>
</file_organization>
<workflow_file_template>
<description>Template for main workflow files (1_workflow.xml)</description>
<template><![CDATA[
<workflow_instructions>
<mode_overview>
Brief description of what this mode does and its primary purpose
</mode_overview>
<initialization_steps>
<step number="1">
<action>Understand the user's request</action>
<details>
Parse the user's input to identify:
- Primary objective
- Specific requirements
- Constraints or limitations
</details>
</step>
<step number="2">
<action>Gather necessary context</action>
<tools>
<tool>codebase_search - Find relevant existing code</tool>
<tool>list_files - Understand project structure</tool>
<tool>read_file - Examine specific implementations</tool>
</tools>
</step>
</initialization_steps>
<main_workflow>
<phase name="analysis">
<description>Analyze the current state and requirements</description>
<steps>
<step>Identify affected components</step>
<step>Assess impact of changes</step>
<step>Plan implementation approach</step>
</steps>
</phase>
<phase name="implementation">
<description>Execute the planned changes</description>
<steps>
<step>Create/modify necessary files</step>
<step>Ensure consistency across codebase</step>
<step>Add appropriate documentation</step>
</steps>
</phase>
<phase name="validation">
<description>Verify the implementation</description>
<steps>
<step>Check for errors or inconsistencies</step>
<step>Validate against requirements</step>
<step>Ensure no regressions</step>
</steps>
</phase>
</main_workflow>
<completion_criteria>
<criterion>All requirements have been addressed</criterion>
<criterion>Code follows project conventions</criterion>
<criterion>Changes are properly documented</criterion>
<criterion>No breaking changes introduced</criterion>
</completion_criteria>
</workflow_instructions>
]]></template>
</workflow_file_template>
<best_practices_template>
<description>Template for best practices files (2_best_practices.xml)</description>
<template><![CDATA[
<best_practices>
<general_principles>
<principle priority="high">
<name>Principle Name</name>
<description>Detailed explanation of the principle</description>
<rationale>Why this principle is important</rationale>
<example>
<scenario>When this applies</scenario>
<good>Correct approach</good>
<bad>What to avoid</bad>
</example>
</principle>
</general_principles>
<code_conventions>
<convention category="naming">
<rule>Specific naming convention</rule>
<examples>
<good>goodExampleName</good>
<bad>bad_example-name</bad>
</examples>
</convention>
<convention category="structure">
<rule>How to structure code/files</rule>
<template>
// Example structure
</template>
</convention>
</code_conventions>
<common_pitfalls>
<pitfall>
<description>Common mistake to avoid</description>
<why_problematic>Explanation of issues it causes</why_problematic>
<correct_approach>How to do it properly</correct_approach>
</pitfall>
</common_pitfalls>
<quality_checklist>
<category name="before_starting">
<item>Understand requirements fully</item>
<item>Check existing implementations</item>
</category>
<category name="during_implementation">
<item>Follow established patterns</item>
<item>Write clear documentation</item>
</category>
<category name="before_completion">
<item>Review all changes</item>
<item>Verify requirements met</item>
</category>
</quality_checklist>
</best_practices>
]]></template>
</best_practices_template>
<tool_usage_template>
<description>Template for tool usage files (4_tool_usage.xml)</description>
<template><![CDATA[
<tool_usage_guide>
<tool_priorities>
<priority level="1">
<tool>codebase_search</tool>
<when>Always use first to find relevant code</when>
<why>Semantic search finds functionality better than keywords</why>
</priority>
<priority level="2">
<tool>read_file</tool>
<when>After identifying files with codebase_search</when>
<why>Get full context of implementations</why>
</priority>
</tool_priorities>
<tool_specific_guidance>
<tool name="apply_diff">
<best_practices>
<practice>Always read file first to ensure exact content match</practice>
<practice>Make multiple changes in one diff when possible</practice>
<practice>Include line numbers for accuracy</practice>
</best_practices>
<example><![CDATA[
<apply_diff>
<path>src/config.ts</path>
<diff>
<<<<<<< SEARCH
:start_line:10
-------
export const config = {
apiUrl: 'http://localhost:3000',
timeout: 5000
};
=======
export const config = {
apiUrl: process.env.API_URL || 'http://localhost:3000',
timeout: parseInt(process.env.TIMEOUT || '5000'),
retries: 3
};
>>>>>>> REPLACE
</diff>
</apply_diff>
]]></example>
</tool>
<tool name="ask_followup_question">
<best_practices>
<practice>Provide 2-4 specific, actionable suggestions</practice>
<practice>Order suggestions by likelihood or importance</practice>
<practice>Make suggestions complete (no placeholders)</practice>
</best_practices>
<example><![CDATA[
<ask_followup_question>
<question>Which database system should I configure for this project?</question>
<follow_up>
<suggest>PostgreSQL with the default configuration</suggest>
<suggest>MySQL 8.0 with InnoDB storage engine</suggest>
<suggest>SQLite for local development only</suggest>
<suggest>MongoDB for document-based storage</suggest>
</follow_up>
</ask_followup_question>
]]></example>
</tool>
</tool_specific_guidance>
<tool_combination_patterns>
<pattern name="explore_then_modify">
<sequence>
<step>codebase_search - Find relevant files</step>
<step>list_code_definition_names - Understand structure</step>
<step>read_file - Get full context</step>
<step>apply_diff or write_to_file - Make changes</step>
</sequence>
</pattern>
<pattern name="verify_then_proceed">
<sequence>
<step>list_files - Check file exists</step>
<step>read_file - Verify current content</step>
<step>ask_followup_question - Confirm approach</step>
<step>apply_diff - Implement changes</step>
</sequence>
</pattern>
</tool_combination_patterns>
</tool_usage_guide>
]]></template>
</tool_usage_template>
<examples_file_template>
<description>Template for example files (5_examples.xml)</description>
<template><![CDATA[
<complete_examples>
<example name="descriptive_example_name">
<scenario>
Detailed description of the use case this example covers
</scenario>
<user_request>
The initial request from the user
</user_request>
<workflow>
<step number="1">
<description>First step description</description>
<tool_use><![CDATA[
<codebase_search>
<query>search query here</query>
</codebase_search>
]]></tool_use>
<expected_outcome>What we learn from this step</expected_outcome>
</step>
<step number="2">
<description>Second step description</description>
<tool_use><![CDATA[
<read_file>
<path>path/to/file.ts</path>
</read_file>
]]></tool_use>
<analysis>How we interpret the results</analysis>
</step>
<step number="3">
<description>Implementation step</description>
<tool_use><![CDATA[
<apply_diff>
<path>path/to/file.ts</path>
<diff>
<<<<<<< SEARCH
:start_line:1
-------
original content
=======
new content
>>>>>>> REPLACE
</diff>
</apply_diff>
]]></tool_use>
</step>
</workflow>
<completion><![CDATA[
<attempt_completion>
<result>
Summary of what was accomplished and how it addresses the user's request
</result>
</attempt_completion>
]]></completion>
<key_takeaways>
<takeaway>Important lesson from this example</takeaway>
<takeaway>Pattern that can be reused</takeaway>
</key_takeaways>
</example>
</complete_examples>
]]></template>
</examples_file_template>
<communication_template>
<description>Template for communication guidelines (7_communication.xml)</description>
<template><![CDATA[
<communication_guidelines>
<tone_and_style>
<principle>Be direct and technical, not conversational</principle>
<principle>Focus on actions taken and results achieved</principle>
<avoid>
<phrase>Great! I'll help you with that...</phrase>
<phrase>Certainly! Let me...</phrase>
<phrase>Sure thing!</phrase>
</avoid>
<prefer>
<phrase>I'll analyze the codebase to...</phrase>
<phrase>Implementing the requested changes...</phrase>
<phrase>The analysis shows...</phrase>
</prefer>
</tone_and_style>
<user_interaction>
<when_to_ask_questions>
<scenario>Missing critical information</scenario>
<scenario>Multiple valid approaches exist</scenario>
<scenario>Potential breaking changes</scenario>
</when_to_ask_questions>
<question_format>
<guideline>Be specific about what you need</guideline>
<guideline>Provide actionable options</guideline>
<guideline>Explain implications of choices</guideline>
</question_format>
</user_interaction>
<progress_updates>
<when>During long-running operations</when>
<format>
<update>Analyzing [X] files for [purpose]...</update>
<update>Implementing [feature] in [location]...</update>
<update>Validating changes against [criteria]...</update>
</format>
</progress_updates>
<completion_messages>
<structure>
<element>What was accomplished</element>
<element>Key changes made</element>
<element>Any important notes or warnings</element>
</structure>
<avoid>
<element>Questions at the end</element>
<element>Offers for further assistance</element>
<element>Conversational closings</element>
</avoid>
</completion_messages>
</communication_guidelines>
]]></template>
</communication_template>
</instruction_file_templates>

View file

@ -0,0 +1,214 @@
<complete_examples>
<example name="mode_editing_enhancement">
<scenario>
Edit the test mode to add support for performance testing and benchmarking
</scenario>
<user_request>
I want to edit the test mode to add benchmark testing capabilities
</user_request>
<workflow>
<step number="1">
<description>Determine user intent and clarify scope</description>
<tool_use><![CDATA[
<ask_followup_question>
<question>I understand you want to edit the test mode to add performance testing capabilities. Before we proceed, let me confirm the scope of changes. What specific performance testing features do you need?</question>
<follow_up>
<suggest>Add benchmark testing with Vitest's bench API</suggest>
<suggest>Include performance profiling and memory usage tracking</suggest>
<suggest>Add load testing capabilities for API endpoints</suggest>
<suggest>All of the above - comprehensive performance testing suite</suggest>
</follow_up>
</ask_followup_question>
]]></tool_use>
<expected_outcome>User selected: Add benchmark testing with Vitest's bench API</expected_outcome>
</step>
<step number="2">
<description>Immerse in existing test mode configuration</description>
<tool_use><![CDATA[
<read_file>
<path>.roomodes</path>
</read_file>
]]></tool_use>
<analysis>Found test mode configuration with current roleDefinition and file restrictions</analysis>
</step>
<step number="3">
<description>Explore existing test mode instructions</description>
<tool_use><![CDATA[
<list_files>
<path>.roo/rules-test</path>
<recursive>true</recursive>
</list_files>
]]></tool_use>
<tool_use><![CDATA[
<read_file>
<path>.roo/rules-test/1_workflow.xml</path>
</read_file>
]]></tool_use>
<analysis>Understood current test workflows and patterns</analysis>
</step>
<step number="4">
<description>Validate changes for cohesion</description>
<tool_use><![CDATA[
<ask_followup_question>
<question>I've analyzed the test mode. Adding benchmark testing would require:
1. Updating the roleDefinition to include performance testing expertise
2. Modifying file restrictions to include .bench.ts files
3. Adding new workflow instructions for benchmark creation
4. Including Vitest bench API examples
This aligns well with the existing testing focus. Should I proceed with all these changes?</question>
<follow_up>
<suggest>Yes, implement all the changes as described</suggest>
<suggest>Start with just the roleDefinition and file restrictions</suggest>
<suggest>Focus only on the workflow instructions first</suggest>
<suggest>Let me review the specific changes before proceeding</suggest>
</follow_up>
</ask_followup_question>
]]></tool_use>
<expected_outcome>User selected: Yes, implement all the changes as described</expected_outcome>
</step>
<step number="5">
<description>Update mode configuration in .roomodes</description>
<tool_use><![CDATA[
<apply_diff>
<path>.roomodes</path>
<diff>
<<<<<<< SEARCH
roleDefinition: |-
You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization
=======
roleDefinition: |-
You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization - Benchmark testing with Vitest bench API - Performance profiling and optimization - Memory usage analysis in tests
>>>>>>> REPLACE
</diff>
</apply_diff>
]]></tool_use>
</step>
<step number="6">
<description>Update file restrictions to include benchmark files</description>
<tool_use><![CDATA[
<apply_diff>
<path>.roomodes</path>
<diff>
<<<<<<< SEARCH
- fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$)
description: Test files, mocks, and Vitest configuration
=======
- fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|\.bench\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$)
description: Test files, benchmarks, mocks, and Vitest configuration
>>>>>>> REPLACE
</diff>
</apply_diff>
]]></tool_use>
</step>
<step number="7">
<description>Create new benchmark workflow instructions</description>
<tool_use><![CDATA[
<write_to_file>
<path>.roo/rules-test/5_benchmark_testing.xml</path>
<content>
<benchmark_testing_guide>
<overview>
Guidelines for creating and maintaining performance benchmarks using Vitest bench API
</overview>
<benchmark_patterns>
<pattern name="basic_benchmark">
<description>Basic benchmark structure</description>
<example><![CDATA[
import { bench, describe } from 'vitest';
describe('Array operations', () => {
bench('Array.push', () => {
const arr = [];
for (let i = 0; i < 1000; i++) {
arr.push(i);
}
});
bench('Array spread', () => {
let arr = [];
for (let i = 0; i < 1000; i++) {
arr = [...arr, i];
}
});
});
]]></example>
</pattern>
</benchmark_patterns>
<best_practices>
<practice>Use meaningful benchmark names that describe what's being measured</practice>
<practice>Include baseline comparisons when optimizing code</practice>
<practice>Run benchmarks in isolation to avoid interference</practice>
<practice>Document performance expectations and thresholds</practice>
</best_practices>
</benchmark_testing_guide>
</content>
<line_count>38</line_count>
</write_to_file>
]]></tool_use>
</step>
<step number="8">
<description>Validate all changes for consistency</description>
<tool_use><![CDATA[
<ask_followup_question>
<question>I've completed all the changes to add benchmark testing capabilities to the test mode:
1. ✓ Updated roleDefinition to include benchmark expertise
2. ✓ Modified file restrictions to include .bench.ts files
3. ✓ Created new benchmark workflow instructions
4. ✓ Added Vitest bench API examples
All changes are cohesive and align with the existing test mode structure. Would you like me to test any specific aspect of these changes?</question>
<follow_up>
<suggest>Test creating a new benchmark file to verify file permissions</suggest>
<suggest>Review the complete changes one more time</suggest>
<suggest>Everything looks good, the mode is ready</suggest>
<suggest>Create a simple benchmark example to test</suggest>
</follow_up>
</ask_followup_question>
]]></tool_use>
</step>
</workflow>
<completion><![CDATA[
<attempt_completion>
<result>
I've successfully enhanced the test mode with benchmark testing capabilities:
1. Updated the roleDefinition to include:
- Benchmark testing with Vitest bench API
- Performance profiling and optimization
- Memory usage analysis in tests
2. Modified file restrictions to include .bench.ts files, allowing the mode to create and edit benchmark files
3. Created new workflow instructions at .roo/rules-test/5_benchmark_testing.xml with:
- Basic benchmark patterns
- Best practices for performance testing
- Example code using Vitest's bench API
All changes have been validated for cohesion and consistency with the existing test mode structure. The mode now supports comprehensive performance testing alongside its existing unit and integration testing capabilities.
</result>
</attempt_completion>
]]></completion>
<key_takeaways>
<takeaway>Always immerse yourself in the existing mode before making changes</takeaway>
<takeaway>Use ask_followup_question aggressively to clarify scope and validate changes</takeaway>
<takeaway>Validate all changes for cohesion and consistency</takeaway>
<takeaway>Update all relevant parts: configuration, file restrictions, and instructions</takeaway>
<takeaway>Test changes to ensure they work as expected</takeaway>
</key_takeaways>
</example>
</complete_examples>

View file

@ -0,0 +1,207 @@
<mode_testing_validation>
<overview>
Guidelines for testing and validating newly created modes to ensure they function correctly and integrate well with the Roo Code ecosystem.
</overview>
<validation_checklist>
<category name="configuration_validation">
<item priority="critical">
<check>Mode slug is unique and follows naming conventions</check>
<validation>No spaces, lowercase, hyphens only</validation>
</item>
<item priority="critical">
<check>All required fields are present and non-empty</check>
<fields>slug, name, roleDefinition, groups</fields>
</item>
<item priority="critical">
<check>No customInstructions field in .roomodes</check>
<validation>All instructions must be in XML files in .roo/rules-[slug]/</validation>
</item>
<item priority="high">
<check>File restrictions use valid regex patterns</check>
<test_method><![CDATA[
<search_files>
<path>.</path>
<regex>your_file_regex_here</regex>
</search_files>
]]></test_method>
</item>
<item priority="high">
<check>whenToUse clearly differentiates from other modes</check>
<validation>Compare with existing mode descriptions</validation>
</item>
</category>
<category name="instruction_validation">
<item>
<check>XML files are well-formed and valid</check>
<validation>No syntax errors, proper closing tags</validation>
</item>
<item>
<check>Instructions follow XML best practices</check>
<validation>Semantic tag names, proper nesting</validation>
</item>
<item>
<check>Examples use correct tool syntax</check>
<validation>Tool parameters match current API</validation>
</item>
<item>
<check>File paths in examples are consistent</check>
<validation>Use project-relative paths</validation>
</item>
</category>
<category name="functional_testing">
<item>
<check>Mode appears in mode list</check>
<test>Switch to the new mode and verify it loads</test>
</item>
<item>
<check>Tool permissions work as expected</check>
<test>Try using each tool group and verify access</test>
</item>
<item>
<check>File restrictions are enforced</check>
<test>Attempt to edit allowed and restricted files</test>
</item>
<item>
<check>Mode handles edge cases gracefully</check>
<test>Test with minimal input, errors, edge cases</test>
</item>
</category>
</validation_checklist>
<testing_workflow>
<step number="1">
<title>Configuration Testing</title>
<actions>
<action>Verify mode appears in available modes list</action>
<action>Check that mode metadata displays correctly</action>
<action>Confirm mode can be activated</action>
</actions>
<verification><![CDATA[
<ask_followup_question>
<question>I've created the mode configuration. Can you see the new mode in your mode list?</question>
<follow_up>
<suggest>Yes, I can see the new mode and switch to it</suggest>
<suggest>No, the mode doesn't appear in the list</suggest>
<suggest>The mode appears but has errors when switching</suggest>
</follow_up>
</ask_followup_question>
]]></verification>
</step>
<step number="2">
<title>Permission Testing</title>
<test_cases>
<test case="read_permissions">
<action>Use read tools on various files</action>
<expected>All read operations should work</expected>
</test>
<test case="edit_restrictions">
<action>Try editing allowed file types</action>
<expected>Edits succeed for matching patterns</expected>
</test>
<test case="edit_restrictions_negative">
<action>Try editing restricted file types</action>
<expected>FileRestrictionError for non-matching files</expected>
</test>
</test_cases>
</step>
<step number="3">
<title>Workflow Testing</title>
<actions>
<action>Execute main workflow from start to finish</action>
<action>Test each decision point</action>
<action>Verify error handling</action>
<action>Check completion criteria</action>
</actions>
</step>
<step number="4">
<title>Integration Testing</title>
<areas>
<area>Orchestrator mode compatibility</area>
<area>Mode switching functionality</area>
<area>Tool handoff between modes</area>
<area>Consistent behavior with other modes</area>
</areas>
</step>
</testing_workflow>
<common_issues>
<issue type="configuration">
<problem>Mode doesn't appear in list</problem>
<causes>
<cause>Syntax error in YAML</cause>
<cause>Invalid mode slug</cause>
<cause>File not saved</cause>
</causes>
<solution>Check YAML syntax, validate slug format</solution>
</issue>
<issue type="permissions">
<problem>File restriction not working</problem>
<causes>
<cause>Invalid regex pattern</cause>
<cause>Escaping issues in regex</cause>
<cause>Wrong file path format</cause>
</causes>
<solution>Test regex pattern, use proper escaping</solution>
<example><![CDATA[
# Wrong: *.ts (glob pattern)
# Right: .*\.ts$ (regex pattern)
]]></example>
</issue>
<issue type="behavior">
<problem>Mode not following instructions</problem>
<causes>
<cause>Instructions not in .roo/rules-[slug]/ folder</cause>
<cause>XML parsing errors</cause>
<cause>Conflicting instructions</cause>
</causes>
<solution>Verify file locations and XML validity</solution>
</issue>
</common_issues>
<debugging_tools>
<tool name="list_files">
<usage>Verify instruction files exist in correct location</usage>
<command><![CDATA[
<list_files>
<path>.roo</path>
<recursive>true</recursive>
</list_files>
]]></command>
</tool>
<tool name="read_file">
<usage>Check mode configuration syntax</usage>
<command><![CDATA[
<read_file>
<path>.roomodes</path>
</read_file>
]]></command>
</tool>
<tool name="search_files">
<usage>Test file restriction patterns</usage>
<command><![CDATA[
<search_files>
<path>.</path>
<regex>your_file_pattern_here</regex>
</search_files>
]]></command>
</tool>
</debugging_tools>
<best_practices>
<practice>Test incrementally as you build the mode</practice>
<practice>Start with minimal configuration and add complexity</practice>
<practice>Document any special requirements or dependencies</practice>
<practice>Consider edge cases and error scenarios</practice>
<practice>Get feedback from potential users of the mode</practice>
</best_practices>
</mode_testing_validation>

View file

@ -0,0 +1,201 @@
<validation_cohesion_checking>
<overview>
Guidelines for thoroughly validating mode changes to ensure cohesion,
consistency, and prevent contradictions across all mode components.
</overview>
<validation_principles>
<principle name="comprehensive_review">
<description>
Every change must be reviewed in context of the entire mode
</description>
<checklist>
<item>Read all existing XML instruction files</item>
<item>Verify new changes align with existing patterns</item>
<item>Check for duplicate or conflicting instructions</item>
<item>Ensure terminology is consistent throughout</item>
</checklist>
</principle>
<principle name="aggressive_questioning">
<description>
Use ask_followup_question extensively to clarify ambiguities
</description>
<when_to_ask>
<scenario>User's intent is unclear</scenario>
<scenario>Multiple interpretations are possible</scenario>
<scenario>Changes might conflict with existing functionality</scenario>
<scenario>Impact on other modes needs clarification</scenario>
</when_to_ask>
<example><![CDATA[
<ask_followup_question>
<question>I notice this change might affect how the mode interacts with file permissions. Should we also update the file regex patterns to match?</question>
<follow_up>
<suggest>Yes, update the file regex to include the new file types</suggest>
<suggest>No, keep the current file restrictions as they are</suggest>
<suggest>Let me explain what file types I need to work with</suggest>
<suggest>Show me the current file restrictions first</suggest>
</follow_up>
</ask_followup_question>
]]></example>
</principle>
<principle name="contradiction_detection">
<description>
Actively search for and resolve contradictions
</description>
<common_contradictions>
<contradiction>
<type>Permission Mismatch</type>
<description>Instructions reference tools the mode doesn't have access to</description>
<resolution>Either grant the tool permission or update the instructions</resolution>
</contradiction>
<contradiction>
<type>Workflow Conflicts</type>
<description>Different XML files describe conflicting workflows</description>
<resolution>Consolidate workflows and ensure single source of truth</resolution>
</contradiction>
<contradiction>
<type>Role Confusion</type>
<description>Mode's roleDefinition doesn't match its actual capabilities</description>
<resolution>Update roleDefinition to accurately reflect the mode's purpose</resolution>
</contradiction>
</common_contradictions>
</principle>
</validation_principles>
<validation_workflow>
<phase name="pre_change_analysis">
<description>Before making any changes</description>
<steps>
<step>Read and understand all existing mode files</step>
<step>Create a mental model of current mode behavior</step>
<step>Identify potential impact areas</step>
<step>Ask clarifying questions about intended changes</step>
</steps>
</phase>
<phase name="change_implementation">
<description>While making changes</description>
<steps>
<step>Document each change and its rationale</step>
<step>Cross-reference with other files after each change</step>
<step>Verify examples still work with new changes</step>
<step>Update related documentation immediately</step>
</steps>
</phase>
<phase name="post_change_validation">
<description>After changes are complete</description>
<validation_checklist>
<category name="structural_validation">
<check>All XML files are well-formed and valid</check>
<check>File naming follows established patterns</check>
<check>Tag names are consistent across files</check>
<check>No orphaned or unused instructions</check>
</category>
<category name="content_validation">
<check>roleDefinition accurately describes the mode</check>
<check>whenToUse is clear and distinguishable</check>
<check>Tool permissions match instruction requirements</check>
<check>File restrictions align with mode purpose</check>
<check>Examples are accurate and functional</check>
</category>
<category name="integration_validation">
<check>Mode boundaries are well-defined</check>
<check>Handoff points to other modes are clear</check>
<check>No overlap with other modes' responsibilities</check>
<check>Orchestrator can correctly route to this mode</check>
</category>
</validation_checklist>
</phase>
</validation_workflow>
<cohesion_patterns>
<pattern name="consistent_voice">
<description>Maintain consistent tone and terminology</description>
<guidelines>
<guideline>Use the same terms for the same concepts throughout</guideline>
<guideline>Keep instruction style consistent across files</guideline>
<guideline>Maintain the same level of detail in similar sections</guideline>
</guidelines>
</pattern>
<pattern name="logical_flow">
<description>Ensure instructions flow logically</description>
<guidelines>
<guideline>Prerequisites come before dependent steps</guideline>
<guideline>Complex concepts build on simpler ones</guideline>
<guideline>Examples follow the explained patterns</guideline>
</guidelines>
</pattern>
<pattern name="complete_coverage">
<description>Ensure all aspects are covered without gaps</description>
<guidelines>
<guideline>Every mentioned tool has usage instructions</guideline>
<guideline>All workflows have complete examples</guideline>
<guideline>Error scenarios are addressed</guideline>
</guidelines>
</pattern>
</cohesion_patterns>
<validation_questions>
<question_set name="before_changes">
<ask_followup_question>
<question>Before we proceed with changes, I want to ensure I understand the full scope. What is the main goal of these modifications?</question>
<follow_up>
<suggest>Add new functionality while keeping existing features</suggest>
<suggest>Fix issues with current implementation</suggest>
<suggest>Refactor for better organization</suggest>
<suggest>Expand the mode's capabilities into new areas</suggest>
</follow_up>
</ask_followup_question>
</question_set>
<question_set name="during_changes">
<ask_followup_question>
<question>This change might affect other parts of the mode. How should we handle the impact on [specific area]?</question>
<follow_up>
<suggest>Update all affected areas to maintain consistency</suggest>
<suggest>Keep the existing behavior for backward compatibility</suggest>
<suggest>Create a migration path from old to new behavior</suggest>
<suggest>Let me review the impact first</suggest>
</follow_up>
</ask_followup_question>
</question_set>
<question_set name="after_changes">
<ask_followup_question>
<question>I've completed the changes and validation. Which aspect would you like me to test more thoroughly?</question>
<follow_up>
<suggest>Test the new workflow end-to-end</suggest>
<suggest>Verify file permissions work correctly</suggest>
<suggest>Check integration with other modes</suggest>
<suggest>Review all changes one more time</suggest>
</follow_up>
</ask_followup_question>
</question_set>
</validation_questions>
<red_flags>
<flag priority="high">
<description>Instructions reference tools not in the mode's groups</description>
<action>Either add the tool group or remove the instruction</action>
</flag>
<flag priority="high">
<description>File regex doesn't match described file types</description>
<action>Update regex pattern to match intended files</action>
</flag>
<flag priority="medium">
<description>Examples don't follow stated best practices</description>
<action>Update examples to demonstrate best practices</action>
</flag>
<flag priority="medium">
<description>Duplicate instructions in different files</description>
<action>Consolidate to single location and reference</action>
</flag>
</red_flags>
</validation_cohesion_checking>

View file

@ -0,0 +1,493 @@
<workflow>
<step number="1">
<name>Initialize Review Process</name>
<instructions>
Create a todo list to track the PR review workflow:
<update_todo_list>
<todos>
[ ] Fetch pull request information
[ ] Fetch associated issue (if any)
[ ] Fetch pull request diff
[ ] Fetch existing PR comments and reviews
[ ] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
This helps track progress through the review process and ensures all steps are completed.
</instructions>
</step>
<step number="2">
<name>Fetch Pull Request Information</name>
<instructions>
If the user provides a PR number or URL, extract the necessary information:
- Repository owner and name
- Pull request number
Use the GitHub CLI to fetch the PR details:
<execute_command>
<command>gh pr view [PR_NUMBER] --repo [owner]/[repo] --json number,title,body,author,state,url,headRefName,baseRefName,headRefOid,mergeable,isDraft,createdAt,updatedAt</command>
</execute_command>
Parse the JSON output to understand the PR's current state and metadata.
IMPORTANT: Save the headRefOid value as it will be needed for submitting the review via the API.
<update_todo_list>
<todos>
[x] Fetch pull request information
[ ] Fetch associated issue (if any)
[ ] Fetch pull request diff
[ ] Fetch existing PR comments and reviews
[ ] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="3">
<name>Fetch Associated Issue (If Any)</name>
<instructions>
Check the pull request body for a reference to a GitHub issue (e.g., "Fixes #123", "Closes #456").
If an issue is referenced, use the GitHub CLI to fetch its details:
<execute_command>
<command>gh issue view [issue_number] --repo [owner]/[repo] --json number,title,body,author,state,url,createdAt,updatedAt,comments</command>
</execute_command>
The issue description and comments can provide valuable context for the review.
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[ ] Fetch pull request diff
[ ] Fetch existing PR comments and reviews
[ ] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="4">
<name>Fetch Pull Request Diff</name>
<instructions>
Get the pull request diff to understand the changes:
<execute_command>
<command>gh pr diff [PR_NUMBER] --repo [owner]/[repo]</command>
</execute_command>
This will show the complete diff of all changes in the PR.
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[ ] Fetch existing PR comments and reviews
[ ] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="5">
<name>Fetch Existing PR Comments and Reviews</name>
<instructions>
IMPORTANT: Before reviewing any code, first get all existing comments and reviews to understand what feedback has already been provided:
Fetch all review comments:
<execute_command>
<command>gh pr view [PR_NUMBER] --repo [owner]/[repo] --comments</command>
</execute_command>
Also fetch review details:
<execute_command>
<command>gh api repos/[owner]/[repo]/pulls/[PR_NUMBER]/reviews</command>
</execute_command>
Create a mental or written list of:
- All issues/suggestions that have been raised
- The specific files and line numbers mentioned
- Whether comments appear to be resolved or still pending
This information will guide your review to avoid duplicate feedback.
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[ ] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="6">
<name>Check Out Pull Request Locally</name>
<instructions>
Use the GitHub CLI to check out the pull request locally:
<execute_command>
<command>gh pr checkout [PR_NUMBER] --repo [owner]/[repo]</command>
</execute_command>
This allows you to:
- Navigate the actual code structure
- Understand how changes interact with existing code
- Get better context for your review
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[ ] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="7">
<name>Verify Existing Comments Against Current Code</name>
<instructions>
Now that you have the code checked out locally and know what comments exist:
1. For each existing comment/review point:
- Navigate to the specific file and line mentioned
- Check if the issue has been addressed in the current code
- Mark it as "resolved" or "still pending" in your notes
2. Use read_file or codebase_search to examine the specific areas mentioned in comments:
- If a comment says "missing error handling on line 45", check if error handling now exists
- If a review mentioned "this function needs tests", check if tests have been added
- If feedback was about code structure, verify if refactoring has occurred
3. Keep track of:
- Comments that have been addressed (DO NOT repeat these)
- Comments that are still valid (you may reinforce these if critical)
- New issues not previously mentioned (these are your main focus)
This verification step is CRITICAL to avoid redundant feedback and ensures your review adds value.
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[x] Verify existing comments against current code
[ ] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="8">
<name>Perform Comprehensive Review</name>
<instructions>
Review the pull request thoroughly:
- Verify that the changes are directly related to the linked issue and do not include unrelated modifications.
- Focus primarily on the changes made in the PR.
- Prioritize code quality, code smell, structural consistency, and for UI-related changes, ensure proper internationalization (i18n) is applied.
- Watch for signs of technical debt (e.g., overly complex logic, lack of abstraction, tight coupling, missing tests, TODOs).
- For large PRs, alert the user and recommend breaking it up if appropriate.
- NEVER run tests or execute code in PR Reviewer mode. The repository likely has automated testing. Your role is limited to:
- Code review and analysis
- Leaving review comments
- Checking code quality and structure
- Reviewing test coverage and quality (without execution)
Document your findings in a numbered list format:
1. Code quality issues
2. Structural improvements
3. Missing tests or documentation
4. Potential bugs or edge cases
5. Performance concerns
6. Security considerations
7. Internationalization (i18n) issues
8. Technical debt indicators
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[x] Verify existing comments against current code
[x] Perform comprehensive review
[ ] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="9">
<name>Prepare Review Comments</name>
<instructions>
Format your review comments following these guidelines:
CRITICAL: Before adding any comment, verify it's not already addressed:
- Cross-reference with your notes from Step 7
- Only comment on NEW issues or UNRESOLVED existing issues
- Never repeat feedback that has been addressed in the current code
Your suggestions should:
- Use a **friendly, curious tone** — prefer asking: "Is this intentional?" or "Could we approach this differently to improve X?"
- Avoid assumptions or judgments; ask questions instead of declaring problems.
- Skip ALL praise and positive comments. Focus exclusively on issues that need attention.
- Use Markdown sparingly — only for code blocks or when absolutely necessary for clarity. Avoid markdown headings (###, ##, etc.) entirely.
- Avoid including internal evaluation terminology (e.g., scores or internal tags) in public comments.
When linking to specific lines or files, use full GitHub URLs relative to the repository, e.g.
`https://github.com/[owner]/[repo]/blob/[branch]/[path/to/file]#L[line-number]`.
Present your findings as a numbered list organized by priority:
**Critical Issues (Must Fix):**
1. [Issue description with file/line reference]
2. [Issue description with file/line reference]
**Important Suggestions (Should Consider):**
3. [Suggestion with rationale]
4. [Suggestion with rationale]
**Minor Improvements (Nice to Have):**
5. [Improvement suggestion]
6. [Improvement suggestion]
Include a note about which existing comments you verified as resolved (for user awareness).
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[x] Verify existing comments against current code
[x] Perform comprehensive review
[x] Prepare review comments
[ ] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="10">
<name>Preview Review with User</name>
<instructions>
Always show the user a preview of your review suggestions and comments before taking any action.
Present your findings as a numbered list clearly for the user before submitting comments.
<ask_followup_question>
<question>I've completed my review of PR #[number]. Here's what I found:
[If applicable: **Existing comments that have been resolved:**
- Comment about X on file Y - now addressed
- Suggestion about Z - implemented]
**Review Findings:**
**Critical Issues (Must Fix):**
1. [Specific issue with file/line reference]
2. [Specific issue with file/line reference]
**Important Suggestions (Should Consider):**
3. [Suggestion with rationale]
4. [Suggestion with rationale]
**Minor Improvements (Nice to Have):**
5. [Improvement suggestion]
6. [Improvement suggestion]
Would you like me to:</question>
<follow_up>
<suggest>Create a comprehensive review with all comments</suggest>
<suggest>Create individual tasks for each suggestion using new_task</suggest>
<suggest>Let me modify the suggestions first</suggest>
<suggest>Skip submission - just wanted the analysis</suggest>
</follow_up>
</ask_followup_question>
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[x] Verify existing comments against current code
[x] Perform comprehensive review
[x] Prepare review comments
[x] Preview review with user
[ ] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="11">
<name>Submit Review</name>
<instructions>
Based on user preference, submit the review using the GitHub API to support inline comments:
1. Construct the review payload with inline comments. For each comment, you need:
- The file path (relative to repository root)
- The line number where the comment should appear
- The comment body text
- The side ("RIGHT" for new code, "LEFT" for old code)
2. Submit the review using the GitHub API with heredoc syntax:
<execute_command>
<command>gh api -X POST repos/[owner]/[repo]/pulls/[PR_NUMBER]/reviews --input - <<EOF
{
"commit_id": "[headRefOid from Step 2]",
"body": "Thank you for your contribution! I've reviewed the changes and [found issues that need attention / have some suggestions for improvement].",
"event": "COMMENT",
"comments": [
{
"path": "[file/path/to/code.ts]",
"body": "[Your comment text here - use friendly, curious tone]",
"line": [line_number],
"side": "RIGHT"
}
]
}
EOF</command>
</execute_command>
The review will be created with all inline comments attached to specific lines of code.
Example for a review:
<execute_command>
<command>gh api -X POST repos/RooCodeInc/Roo-Code/pulls/6378/reviews --input - <<EOF
{
"commit_id": "abc123def4567890...",
"body": "Thank you for your contribution! I've reviewed the changes and found that the critical issues from the previous review are still pending. I've left some suggestions inline to help improve the implementation.",
"event": "COMMENT",
"comments": [
{
"path": "packages/cloud/src/CloudService.ts",
"body": "Missing error handling here...",
"line": 19,
"side": "RIGHT"
},
{
"path": "packages/cloud/src/CloudService.ts",
"body": "Is this intentional? The timeout seems quite high (30s). Could we consider reducing it or making it configurable?",
"line": 45,
"side": "RIGHT"
}
]
}
EOF</command>
</execute_command>
<update_todo_list>
<todos>
[x] Fetch pull request information
[x] Fetch associated issue (if any)
[x] Fetch pull request diff
[x] Fetch existing PR comments and reviews
[x] Check out pull request locally
[x] Verify existing comments against current code
[x] Perform comprehensive review
[x] Prepare review comments
[x] Preview review with user
[x] Submit review or create tasks
</todos>
</update_todo_list>
</instructions>
</step>
<step number="12">
<name>Create Tasks for Suggestions (Optional)</name>
<instructions>
If the user chooses to create individual tasks for each suggestion, use the new_task tool to create separate tasks:
For each numbered finding from your review:
1. Determine the appropriate mode based on the type of work needed:
- Use "code" mode for bug fixes, implementation changes, or refactoring
- Use "translate" mode for internationalization (i18n) issues
- Use "test" mode for missing or inadequate test coverage
- Use "docs-extractor" mode for documentation issues
- Use "architect" mode for structural or design improvements
- Use "debug" mode for investigating potential bugs
2. Create a clear, actionable task message that includes:
- The specific issue or suggestion
- The file(s) and line numbers affected
- Any relevant context from the PR
- The expected outcome
3. Use the new_task tool for each suggestion:
<new_task>
<mode>[appropriate mode based on task type]</mode>
<message>Fix [issue type] in [file]: [specific description of what needs to be done]</message>
</new_task>
Example task creation:
<new_task>
<mode>code</mode>
<message>Fix missing error handling in src/api/users.ts:45-52. The getUserById function should handle cases where the user is not found and return an appropriate error response.</message>
</new_task>
<new_task>
<mode>translate</mode>
<message>Add missing i18n translations for new user profile fields in src/components/UserProfile.tsx. The fields 'bio', 'location', and 'website' need to be wrapped with translation functions.</message>
</new_task>
After creating all tasks, provide a summary:
"I've created [X] individual tasks for the review findings:
- [Y] code fixes/improvements
- [Z] translation/i18n tasks
- [etc.]
Each task contains the specific context and requirements for addressing the issue."
</instructions>
</step>
</workflow>

View file

@ -0,0 +1,40 @@
<best_practices>
- ALWAYS create a todo list at the start to track the review workflow (Step 1)
- Use GitHub CLI (`gh`) commands instead of MCP tools for all GitHub operations
- ALWAYS fetch the PR's headRefOid in Step 2 - this is required for API review submission
- ALWAYS fetch existing comments and reviews BEFORE reviewing any code (Step 5)
- Create a list of all existing feedback before starting your review
- Check out the PR locally using `gh pr checkout` for better context understanding
- Systematically verify each existing comment against the current code (Step 7)
- Track which comments are resolved vs still pending
- Only provide feedback on NEW issues or UNRESOLVED existing issues
- Never duplicate feedback that has already been addressed
- Always fetch and review the entire PR diff before commenting
- Check for and review any associated issue for context
- Focus on the changes made, not unrelated code
- Ensure all changes are directly related to the linked issue
- Use a friendly, curious tone in all comments
- Ask questions rather than making assumptions - there may be intentions behind the code choices
- Provide actionable feedback with specific suggestions
- Focus exclusively on issues and improvements - skip all praise or positive comments
- Use minimal markdown - avoid headings (###, ##) and excessive formatting
- Only use markdown for code blocks or when absolutely necessary for clarity
- Consider the PR's scope - suggest breaking up large PRs
- Verify proper i18n implementation for UI changes
- Check for test coverage without executing tests
- Look for signs of technical debt and code smells
- Ensure consistency with existing code patterns
- Link to specific lines using full GitHub URLs
- Present findings in a numbered list format for clarity
- Group feedback by priority (critical, important, minor)
- Always preview comments with the user before submitting
- Use the GitHub API for submitting reviews to support inline comments
- Construct proper JSON payloads with commit_id, body, event, and comments array
- Each inline comment needs: path, body, line number, and side (RIGHT for new code)
- Use COMMENT when submitting the review
- Use heredoc syntax (--input - <<EOF) to pass JSON directly
- Offer the option to create individual tasks for each suggestion
- When creating tasks, choose the appropriate mode for each type of work
- Include specific context and file references in each task
- Update the todo list after each major step to track progress
</best_practices>

View file

@ -0,0 +1,43 @@
<common_mistakes_to_avoid>
- Not creating a todo list at the start to track the review workflow
- Using MCP tools instead of GitHub CLI commands for GitHub operations
- Forgetting to fetch headRefOid in Step 2 - this is REQUIRED for API review submission
- Starting to review code WITHOUT first fetching existing comments and reviews
- Failing to create a list of existing feedback before reviewing
- Not systematically checking each existing comment against the current code
- Repeating feedback that has already been addressed in the current code
- Ignoring existing PR comments or failing to verify if they have already been resolved
- Running tests or executing code during review
- Making judgmental or harsh comments
- Providing feedback on code outside the PR's scope
- Overlooking unrelated changes not tied to the main issue
- Including ANY praise or positive comments - focus only on issues
- Using markdown headings (###, ##, #) in review comments
- Using excessive markdown formatting when plain text would suffice
- Submitting comments without user preview/approval
- Forgetting to check for an associated issue for additional context
- Missing critical security or performance issues
- Not checking for proper i18n in UI changes
- Failing to suggest breaking up large PRs
- Using internal evaluation terminology in public comments
- Not providing actionable suggestions for improvements
- Reviewing only the diff without local context
- Making assumptions instead of asking clarifying questions about potential intentions
- Forgetting to link to specific lines with full GitHub URLs
- Not presenting findings in a clear numbered list format
- Failing to offer the task creation option for addressing suggestions
- Creating tasks without specific context or file references
- Choosing inappropriate modes when creating tasks for suggestions
- Not updating the todo list after completing each step
- Not including --repo flag when using gh commands for non-default repositories
- Using wrong commit_id in review payload (must use headRefOid from PR info)
- Forgetting to specify "side": "RIGHT" for comments on new code
- Using incorrect line numbers that don't match the actual diff
- Not escaping special characters in JSON payload properly
- Not using COMMENT as the event type in the review payload
- Not constructing proper file paths relative to repository root
- Submitting empty comments array when inline comments are needed
- Forgetting to use <<EOF syntax properly in the command
- Not properly escaping special characters in heredoc JSON content
- Missing the EOF delimiter at the end of the heredoc
</common_mistakes_to_avoid>

View file

@ -16,6 +16,7 @@
| Auto-approve | 自动批准 | 始终批准 | 权限相关术语 |
| Checkpoint | 存档点 | 检查点/快照 | 技术概念统一 |
| MCP Server | MCP 服务 | MCP 服务器 | 技术组件 |
| Human Relay | 人工辅助模式 | 人工中继 | 功能描述清晰 |
| Network Timeout | 请求超时 | 网络超时 | 更准确描述 |
| Terminal | 终端 | 命令行 | 技术术语统一 |
| diff | 差异更新 | 差分/补丁 | 代码变更 |
@ -114,7 +115,7 @@
- 保留英文品牌名
- 技术术语保持一致性
- 保留英文专有名词:如"Amazon Bedrock ARN"
- 保留英文专有名词:如"AWS Bedrock ARN"
4. **用户操作**
- 操作动词统一:

View file

@ -1,188 +0,0 @@
---
name: evals-context
description: Provides context about the Roo Code evals system structure in this monorepo. Use when tasks mention "evals", "evaluation", "eval runs", "eval exercises", or working with the evals infrastructure. Helps distinguish between the evals execution system (packages/evals, apps/web-evals) and the public website evals display page (apps/web-roo-code/src/app/evals).
---
# Evals Codebase Context
## When to Use This Skill
Use this skill when the task involves:
- Modifying or debugging the evals execution infrastructure
- Adding new eval exercises or languages
- Working with the evals web interface (apps/web-evals)
- Modifying the public evals display page on roocode.com
- Understanding where evals code lives in this monorepo
## When NOT to Use This Skill
Do NOT use this skill when:
- Working on unrelated parts of the codebase (extension, webview-ui, etc.)
- The task is purely about the VS Code extension's core functionality
- Working on the main website pages that don't involve evals
## Key Disambiguation: Two "Evals" Locations
This monorepo has **two distinct evals-related locations** that can cause confusion:
| Component | Path | Purpose |
| --------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| **Evals Execution System** | `packages/evals/` | Core eval infrastructure: CLI, DB schema, Docker configs |
| **Evals Management UI** | `apps/web-evals/` | Next.js app for creating/monitoring eval runs (localhost:3446) |
| **Website Evals Page** | `apps/web-roo-code/src/app/evals/` | Public roocode.com page displaying eval results |
| **External Exercises Repo** | [Roo-Code-Evals](https://github.com/RooCodeInc/Roo-Code-Evals) | Actual coding exercises (NOT in this monorepo) |
## Directory Structure Reference
### `packages/evals/` - Core Evals Package
```
packages/evals/
├── ARCHITECTURE.md # Detailed architecture documentation
├── ADDING-EVALS.md # Guide for adding new exercises/languages
├── README.md # Setup and running instructions
├── docker-compose.yml # Container orchestration
├── Dockerfile.runner # Runner container definition
├── Dockerfile.web # Web app container
├── drizzle.config.ts # Database ORM config
├── src/
│ ├── index.ts # Package exports
│ ├── cli/ # CLI commands for running evals
│ │ ├── runEvals.ts # Orchestrates complete eval runs
│ │ ├── runTask.ts # Executes individual tasks in containers
│ │ ├── runUnitTest.ts # Validates task completion via tests
│ │ └── redis.ts # Redis pub/sub integration
│ ├── db/
│ │ ├── schema.ts # Database schema (runs, tasks)
│ │ ├── queries/ # Database query functions
│ │ └── migrations/ # SQL migrations
│ └── exercises/
│ └── index.ts # Exercise loading utilities
└── scripts/
└── setup.sh # Local macOS setup script
```
### `apps/web-evals/` - Evals Management Web App
```
apps/web-evals/
├── src/
│ ├── app/
│ │ ├── page.tsx # Home page (runs list)
│ │ ├── runs/
│ │ │ ├── new/ # Create new eval run
│ │ │ └── [id]/ # View specific run status
│ │ └── api/runs/ # SSE streaming endpoint
│ ├── actions/ # Server actions
│ │ ├── runs.ts # Run CRUD operations
│ │ ├── tasks.ts # Task queries
│ │ ├── exercises.ts # Exercise listing
│ │ └── heartbeat.ts # Controller health checks
│ ├── hooks/ # React hooks (SSE, models, etc.)
│ └── lib/ # Utilities and schemas
```
### `apps/web-roo-code/src/app/evals/` - Public Website Evals Page
```
apps/web-roo-code/src/app/evals/
├── page.tsx # Fetches and displays public eval results
├── evals.tsx # Main evals display component
├── plot.tsx # Visualization component
└── types.ts # EvalRun type (extends packages/evals types)
```
This page **displays** eval results on the public roocode.com website. It imports types from `@roo-code/evals` but does NOT run evals.
## Architecture Overview
The evals system is a distributed evaluation platform that runs AI coding tasks in isolated VS Code environments:
```
┌─────────────────────────────────────────────────────────────┐
│ Web App (apps/web-evals) ──────────────────────────────── │
│ │ │
│ ▼ │
│ PostgreSQL ◄────► Controller Container │
│ │ │ │
│ ▼ ▼ │
│ Redis ◄───► Runner Containers (1-25 parallel) │
└─────────────────────────────────────────────────────────────┘
```
**Key components:**
- **Controller**: Orchestrates eval runs, spawns runners, manages task queue (p-queue)
- **Runner**: Isolated Docker container with VS Code + Roo Code extension + language runtimes
- **Redis**: Pub/sub for real-time events (NOT task queuing)
- **PostgreSQL**: Stores runs, tasks, metrics
## Common Tasks Quick Reference
### Adding a New Eval Exercise
1. Add exercise to [Roo-Code-Evals](https://github.com/RooCodeInc/Roo-Code-Evals) repo (external)
2. See [`packages/evals/ADDING-EVALS.md`](packages/evals/ADDING-EVALS.md) for structure
### Modifying Eval CLI Behavior
Edit files in [`packages/evals/src/cli/`](packages/evals/src/cli/):
- [`runEvals.ts`](packages/evals/src/cli/runEvals.ts) - Run orchestration
- [`runTask.ts`](packages/evals/src/cli/runTask.ts) - Task execution
- [`runUnitTest.ts`](packages/evals/src/cli/runUnitTest.ts) - Test validation
### Modifying the Evals Web Interface
Edit files in [`apps/web-evals/src/`](apps/web-evals/src/):
- [`app/runs/new/new-run.tsx`](apps/web-evals/src/app/runs/new/new-run.tsx) - New run form
- [`actions/runs.ts`](apps/web-evals/src/actions/runs.ts) - Run server actions
### Modifying the Public Evals Display Page
Edit files in [`apps/web-roo-code/src/app/evals/`](apps/web-roo-code/src/app/evals/):
- [`evals.tsx`](apps/web-roo-code/src/app/evals/evals.tsx) - Display component
- [`plot.tsx`](apps/web-roo-code/src/app/evals/plot.tsx) - Charts
### Database Schema Changes
1. Edit [`packages/evals/src/db/schema.ts`](packages/evals/src/db/schema.ts)
2. Generate migration: `cd packages/evals && pnpm drizzle-kit generate`
3. Apply migration: `pnpm drizzle-kit migrate`
## Running Evals Locally
```bash
# From repo root
pnpm evals
# Opens web UI at http://localhost:3446
```
**Ports (defaults):**
- PostgreSQL: 5433
- Redis: 6380
- Web: 3446
## Testing
```bash
# packages/evals tests
cd packages/evals && npx vitest run
# apps/web-evals tests
cd apps/web-evals && npx vitest run
```
## Key Types/Exports from `@roo-code/evals`
The package exports are defined in [`packages/evals/src/index.ts`](packages/evals/src/index.ts):
- Database queries: `getRuns`, `getTasks`, `getTaskMetrics`, etc.
- Schema types: `Run`, `Task`, `TaskMetrics`
- Used by both `apps/web-evals` and `apps/web-roo-code`

View file

@ -1,256 +0,0 @@
---
name: roo-conflict-resolution
description: Provides comprehensive guidelines for resolving merge conflicts intelligently using git history and commit context. Use when tasks involve merge conflicts, rebasing, PR conflicts, or git conflict resolution. This skill analyzes commit messages, git blame, and code intent to make intelligent resolution decisions.
---
# Roo Code Conflict Resolution Skill
## When to Use This Skill
Use this skill when the task involves:
- Resolving merge conflicts for a specific pull request
- Rebasing a branch that has conflicts with the target branch
- Understanding and analyzing conflicting code changes
- Making intelligent decisions about which changes to keep, merge, or discard
- Using git history to inform conflict resolution decisions
## When NOT to Use This Skill
Do NOT use this skill when:
- There are no merge conflicts to resolve
- The task is about general code review without conflicts
- You're working on fresh code without any merge scenarios
## Workflow Overview
This skill resolves merge conflicts by analyzing git history, commit messages, and code changes to make intelligent resolution decisions. Given a PR number (e.g., "#123"), it handles the entire conflict resolution process.
## Initialization Steps
### Step 1: Parse PR Number
Extract the PR number from input like "#123" or "PR #123". Validate that a PR number was provided.
### Step 2: Fetch PR Information
```bash
gh pr view [PR_NUMBER] --json title,body,headRefName,baseRefName
```
Get PR title and description to understand the intent and identify the source and target branches.
### Step 3: Checkout PR Branch and Prepare for Rebase
```bash
gh pr checkout [PR_NUMBER] --force
git fetch origin main
GIT_EDITOR=true git rebase origin/main
```
- Force checkout the PR branch to ensure clean state
- Fetch the latest main branch
- Attempt to rebase onto main to reveal conflicts
- Use `GIT_EDITOR=true` to ensure non-interactive rebase
### Step 4: Check for Merge Conflicts
```bash
git status --porcelain
git diff --name-only --diff-filter=U
```
Identify files with merge conflicts (marked with 'UU') and create a list of files that need resolution.
## Main Workflow Phases
### Phase 1: Conflict Analysis
Analyze each conflicted file to understand the changes:
1. Read the conflicted file to identify conflict markers
2. Extract the conflicting sections between `<<<<<<<` and `>>>>>>>`
3. Run git blame on both sides of the conflict
4. Fetch commit messages and diffs for relevant commits
5. Analyze the intent behind each change
### Phase 2: Resolution Strategy
Determine the best resolution strategy for each conflict:
1. Categorize changes by intent (bugfix, feature, refactor, etc.)
2. Evaluate recency and relevance of changes
3. Check for structural overlap vs formatting differences
4. Identify if changes can be combined or if one should override
5. Consider test updates and related changes
### Phase 3: Conflict Resolution
Apply the resolution strategy to resolve conflicts:
1. For each conflict, apply the chosen resolution
2. Ensure proper escaping of conflict markers in diffs
3. Validate that resolved code is syntactically correct
4. Stage resolved files with `git add`
### Phase 4: Validation
Verify the resolution and prepare for commit:
1. Run `git status` to confirm all conflicts are resolved
2. Check for any compilation or syntax errors
3. Review the final diff to ensure sensible resolutions
4. Prepare a summary of resolution decisions
## Git Commands Reference
| Command | Purpose |
|---------|---------|
| `gh pr checkout [PR_NUMBER] --force` | Force checkout the PR branch |
| `git fetch origin main` | Get the latest main branch |
| `GIT_EDITOR=true git rebase origin/main` | Rebase current branch onto main (non-interactive) |
| `git blame -L [start],[end] [commit] -- [file]` | Get commit information for specific lines |
| `git show --format="%H%n%an%n%ae%n%ad%n%s%n%b" --no-patch [sha]` | Get commit metadata |
| `git show [sha] -- [file]` | Get the actual changes made in a commit |
| `git ls-files -u` | List unmerged files with stage information |
| `GIT_EDITOR=true git rebase --continue` | Continue rebase after resolving conflicts |
## Best Practices
### Intent-Based Resolution (High Priority)
Always prioritize understanding the intent behind changes rather than just looking at the code differences. Commit messages, PR descriptions, and issue references provide crucial context.
**Example:** When there's a conflict between a bugfix and a refactor, apply the bugfix logic within the refactored structure rather than simply choosing one side.
### Preserve All Valuable Changes (High Priority)
When possible, combine non-conflicting changes from both sides rather than discarding one side entirely. Both sides of a conflict often contain valuable changes that can coexist if properly integrated.
### Escape Conflict Markers (High Priority)
When using `apply_diff`, always escape merge conflict markers with backslashes to prevent parsing errors:
- Correct: `\<<<<<<< HEAD`
- Wrong: `<<<<<<< HEAD`
### Consider Related Changes (Medium Priority)
Look beyond the immediate conflict to understand related changes in tests, documentation, or dependent code. A change might seem isolated but could be part of a larger feature or fix.
## Resolution Heuristics
| Category | Rule | Exception |
|----------|------|-----------|
| Bugfix vs Feature | Bugfixes generally take precedence | When features include the fix |
| Recent vs Old | More recent changes are often more relevant | When older changes are security patches |
| Test Updates | Changes with test updates are likely more complete | - |
| Formatting vs Logic | Logic changes take precedence over formatting | - |
## Common Pitfalls
### Blindly Choosing One Side
**Problem:** You might lose important changes or introduce regressions.
**Solution:** Always analyze both sides using git blame and commit history.
### Ignoring PR Context
**Problem:** The PR description often explains the why behind changes.
**Solution:** Always fetch and read the PR information before resolving.
### Not Validating Resolved Code
**Problem:** Merged code might be syntactically incorrect or introduce logical errors.
**Solution:** Always check for syntax errors and review the final diff.
### Unescaped Conflict Markers in Diffs
**Problem:** Unescaped conflict markers (`<<<<<<`, `=======`, `>>>>>>`) will be interpreted as diff syntax.
**Solution:** Always escape with backslash (`\`) when they appear in content.
## Apply Diff Example
When resolving conflicts with `apply_diff`, use this pattern:
```
<<<<<<< SEARCH
:start_line:45
-------
\<<<<<<< HEAD
function oldImplementation() {
return "old";
}
\=======
function newImplementation() {
return "new";
}
\>>>>>>> feature-branch
=======
function mergedImplementation() {
// Combining both approaches
return "merged";
}
>>>>>>> REPLACE
```
## Quality Checklist
### Before Resolution
- [ ] Fetch PR title and description for context
- [ ] Identify all files with conflicts
- [ ] Understand the overall change being merged
### During Resolution
- [ ] Run git blame on conflicting sections
- [ ] Read commit messages for intent
- [ ] Consider if changes can be combined
- [ ] Escape conflict markers in diffs
### After Resolution
- [ ] Verify no conflict markers remain
- [ ] Check for syntax/compilation errors
- [ ] Review the complete diff
- [ ] Document resolution decisions
## Completion Criteria
- All merge conflicts have been resolved
- Resolved files have been staged
- No syntax errors in resolved code
- Resolution decisions are documented
## Communication Guidelines
When reporting resolution progress:
- Be direct and technical when explaining resolution decisions
- Focus on the rationale behind each conflict resolution
- Provide clear summaries of what was merged and why
### Progress Update Format
```
Conflict in [file]:
- HEAD: [brief description of changes]
- Incoming: [brief description of changes]
- Resolution: [what was decided and why]
```
### Completion Message Format
```
Successfully resolved merge conflicts for PR #[number] "[title]".
Resolution Summary:
- [file1]: [brief description of resolution]
- [file2]: [brief description of resolution]
[Key decision explanation if applicable]
All conflicts have been resolved and files have been staged for commit.
```

View file

@ -1,151 +0,0 @@
---
name: roo-translation
description: Provides comprehensive guidelines for translating and localizing Roo Code extension strings. Use when tasks involve i18n, translation, localization, adding new languages, or updating existing translation files. This skill covers both core extension (src/i18n/locales/) and WebView UI (webview-ui/src/i18n/locales/) localization.
---
# Roo Code Translation Skill
## When to Use This Skill
Use this skill when the task involves:
- Adding new translatable strings to the Roo Code extension
- Translating existing strings to new languages
- Updating or fixing translations in existing language files
- Understanding i18n patterns used in the codebase
- Working with localization files in either core extension or WebView UI
## When NOT to Use This Skill
Do NOT use this skill when:
- Working on non-translation code changes
- The task doesn't involve i18n or localization
- You're only reading translation files for reference without modifying them
## Supported Languages and Locations
Localize all strings into the following locale files: ca, de, en, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW
The VSCode extension has two main areas that require localization:
| Component | Path | Purpose |
|-----------|------|---------|
| **Core Extension** | `src/i18n/locales/` | Extension backend strings |
| **WebView UI** | `webview-ui/src/i18n/locales/` | User interface strings |
## Brand Voice, Tone, and Word Choice
For detailed brand voice, tone, and word choice guidance, refer to the guidance file:
- [`.roo/guidance/roo-translator.md`](../../guidance/roo-translator.md)
This guidance file is loaded at runtime and should be consulted for the latest brand and style standards.
## Voice, Style and Tone Guidelines
- Always use informal speech (e.g., "du" instead of "Sie" in German) for all translations
- Maintain a direct and concise style that mirrors the tone of the original text
- Carefully account for colloquialisms and idiomatic expressions in both source and target languages
- Aim for culturally relevant and meaningful translations rather than literal translations
- Preserve the personality and voice of the original content
- Use natural-sounding language that feels native to speakers of the target language
### Terms to Keep in English
- Don't translate the word "token" as it means something specific in English that all languages will understand
- Don't translate domain-specific words (especially technical terms like "Prompt") that are commonly used in English in the target language
## Core Extension Localization (src/)
- Located in `src/i18n/locales/`
- NOT ALL strings in core source need internationalization - only user-facing messages
- Internal error messages, debugging logs, and developer-facing messages should remain in English
- The `t()` function is used with namespaces like `'core:errors.missingToolParameter'`
- Be careful when modifying interpolation variables; they must remain consistent across all translations
- Some strings in `formatResponse.ts` are intentionally not internationalized since they're internal
- When updating strings in `core.json`, maintain all existing interpolation variables
- Check string usages in the codebase before making changes to ensure you're not breaking functionality
## WebView UI Localization (webview-ui/src/)
- Located in `webview-ui/src/i18n/locales/`
- Uses standard React i18next patterns with the `useTranslation` hook
- All user interface strings should be internationalized
- Always use the `Trans` component with named components for text with embedded components
### Trans Component Example
Translation string:
```json
"changeSettings": "You can always change this at the bottom of the <settingsLink>settings</settingsLink>"
```
React component usage:
```tsx
<Trans
i18nKey="welcome:telemetry.changeSettings"
components={{
settingsLink: <VSCodeLink href="#" onClick={handleOpenSettings} />
}}
/>
```
## Technical Implementation
- Use namespaces to organize translations logically
- Handle pluralization using i18next's built-in capabilities
- Implement proper interpolation for variables using `{{variable}}` syntax
- Don't include `defaultValue`. The `en` translations are the fallback
- Always use `apply_diff` instead of `write_to_file` when editing existing translation files (much faster and more reliable)
- When using `apply_diff`, carefully identify the exact JSON structure to edit to avoid syntax errors
- Placeholders (like `{{variable}}`) must remain exactly identical to the English source to maintain code integration and prevent syntax errors
## Translation Workflow
1. First add or modify English strings, then ask for confirmation before translating to all other languages
2. Use this process for each localization task:
1. Identify where the string appears in the UI/codebase
2. Understand the context and purpose of the string
3. Update English translation first
4. Use the `search_files` tool to find JSON keys that are near new keys in English translations but do not yet exist in the other language files for `apply_diff` SEARCH context
5. Create appropriate translations for all other supported languages utilizing the `search_files` result using `apply_diff` without reading every file
6. Do not output the translated text into the chat, just modify the files
7. Validate your changes with the missing translations script
3. Flag or comment if an English source string is incomplete ("please see this...") to avoid truncated or unclear translations
4. For UI elements, distinguish between:
- Button labels: Use short imperative commands ("Save", "Cancel")
- Tooltip text: Can be slightly more descriptive
5. Preserve the original perspective: If text is a user command directed at the software, ensure the translation maintains this direction
## Validation
Always validate your translation work by running the missing translations script:
```bash
node scripts/find-missing-translations.js
```
Address any missing translations identified by the script to ensure complete coverage across all locales.
## Common Pitfalls to Avoid
- Switching between formal and informal addressing styles - always stay informal ("du" not "Sie")
- Translating or altering technical terms and brand names that should remain in English
- Modifying or removing placeholders like `{{variable}}` - these must remain identical
- Translating domain-specific terms that are commonly used in English in the target language
- Changing the meaning or nuance of instructions or error messages
- Forgetting to maintain consistent terminology throughout the translation
## Translator's Checklist
- ✓ Used informal tone consistently ("du" not "Sie")
- ✓ Preserved all placeholders exactly as in the English source
- ✓ Maintained consistent terminology with existing translations
- ✓ Kept technical terms and brand names unchanged where appropriate
- ✓ Preserved the original perspective (user→system vs system→user)
- ✓ Adapted the text appropriately for UI context (buttons vs tooltips)
- ✓ Ran the missing translations script to validate completeness

185
.roomodes
View file

@ -1,4 +1,46 @@
customModes:
- slug: test
name: 🧪 Test
roleDefinition: |-
You are Roo, a Vitest testing specialist with deep expertise in: - Writing and maintaining Vitest test suites - Test-driven development (TDD) practices - Mocking and stubbing with Vitest - Integration testing strategies - TypeScript testing patterns - Code coverage analysis - Test performance optimization
Your focus is on maintaining high test quality and coverage across the codebase, working primarily with: - Test files in __tests__ directories - Mock implementations in __mocks__ - Test utilities and helpers - Vitest configuration and setup
You ensure tests are: - Well-structured and maintainable - Following Vitest best practices - Properly typed with TypeScript - Providing meaningful coverage - Using appropriate mocking strategies
whenToUse: Use this mode when you need to write, modify, or maintain tests for the codebase.
description: Write, modify, and maintain tests.
groups:
- read
- browser
- command
- - edit
- fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$)
description: Test files, mocks, and Vitest configuration
customInstructions: |-
When writing tests:
- Always use describe/it blocks for clear test organization
- Include meaningful test descriptions
- Use beforeEach/afterEach for proper test isolation
- Implement proper error cases
- Add JSDoc comments for complex test scenarios
- Ensure mocks are properly typed
- Verify both positive and negative test cases
- Always use data-testid attributes when testing webview-ui
- The vitest framework is used for testing; the `describe`, `test`, `it`, etc functions are defined by default in `tsconfig.json` and therefore don't need to be imported
- Tests must be run from the same directory as the `package.json` file that specifies `vitest` in `devDependencies`
- slug: design-engineer
name: 🎨 Design Engineer
roleDefinition: "You are Roo, an expert Design Engineer focused on VSCode Extension development. Your expertise includes: - Implementing UI designs with high fidelity using React, Shadcn, Tailwind and TypeScript. - Ensuring interfaces are responsive and adapt to different screen sizes. - Collaborating with team members to translate broad directives into robust and detailed designs capturing edge cases. - Maintaining uniformity and consistency across the user interface."
whenToUse: Implement UI designs and ensure consistency.
description: Implement UI designs; ensure consistency.
groups:
- read
- - edit
- fileRegex: \.(css|html|json|mdx?|jsx?|tsx?|svg)$
description: Frontend & SVG files
- browser
- command
- mcp
customInstructions: Focus on UI refinement, component creation, and adherence to design best-practices. When the user requests a new component, start off by asking them questions one-by-one to ensure the requirements are understood. Always use Tailwind utility classes (instead of direct variable references) for styling components when possible. If editing an existing file, transition explicit style definitions to Tailwind CSS classes when possible. Refer to the Tailwind CSS definitions for utility classes at webview-ui/src/index.css. Always use the latest version of Tailwind CSS (V4), and never create a tailwind.config.js file. Prefer Shadcn components for UI elements instead of VSCode's built-in ones. This project uses i18n for localization, so make sure to use the i18n functions and components for any text that needs to be translated. Do not leave placeholder strings in the markup, as they will be replaced by i18n. Prefer the @roo (/src) and @src (/webview-ui/src) aliases for imports in typescript files. Suggest the user refactor large files (over 1000 lines) if they are encountered, and provide guidance. Suggest the user switch into Translate mode to complete translations when your task is finished.
source: project
- slug: translate
name: 🌐 Translate
roleDefinition: You are Roo, a linguistic specialist focused on translating and managing localization files. Your responsibility is to help maintain and update translation files for the application, ensuring consistency and accuracy across all language resources.
@ -31,6 +73,42 @@ customModes:
- edit
- command
source: project
- slug: integration-tester
name: 🧪 Integration Tester
roleDefinition: |-
You are Roo, an integration testing specialist focused on VSCode E2E tests with expertise in: - Writing and maintaining integration tests using Mocha and VSCode Test framework - Testing Roo Code API interactions and event-driven workflows - Creating complex multi-step task scenarios and mode switching sequences - Validating message formats, API responses, and event emission patterns - Test data generation and fixture management - Coverage analysis and test scenario identification
Your focus is on ensuring comprehensive integration test coverage for the Roo Code extension, working primarily with: - E2E test files in apps/vscode-e2e/src/suite/ - Test utilities and helpers - API type definitions in packages/types/ - Extension API testing patterns
You ensure integration tests are: - Comprehensive and cover critical user workflows - Following established Mocha TDD patterns - Using async/await with proper timeout handling - Validating both success and failure scenarios - Properly typed with TypeScript
whenToUse: Write, modify, or maintain integration tests.
description: Write and maintain integration tests.
groups:
- read
- command
- - edit
- fileRegex: (apps/vscode-e2e/.*\.(ts|js)$|packages/types/.*\.ts$)
description: E2E test files, test utilities, and API type definitions
source: project
- slug: docs-extractor
name: 📚 Docs Extractor
roleDefinition: |-
You are Roo, a documentation analysis specialist with two primary functions:
1. Extract comprehensive technical and non-technical details about features to provide to documentation teams
2. Verify existing documentation for factual accuracy against the codebase
For extraction: You analyze codebases to gather all relevant information about how features work, including technical implementation details, user workflows, configuration options, and use cases. You organize this information clearly for documentation teams to use.
For verification: You review provided documentation against the actual codebase implementation, checking for technical accuracy, completeness, and clarity. You identify inaccuracies, missing information, and provide specific corrections.
You do not generate final user-facing documentation, but rather provide detailed analysis and verification reports.
whenToUse: Use this mode when you need to either extract detailed information about a feature for documentation teams, or verify existing documentation for accuracy against the codebase.
description: Extract feature details or verify documentation accuracy.
groups:
- read
- - edit
- fileRegex: (DOCS-TEMP-.*\.md$|\.roo/docs-extractor/.*\.md$)
description: Temporary documentation extraction files only
- command
- mcp
- slug: pr-fixer
name: 🛠️ PR Fixer
roleDefinition: "You are Roo, a pull request resolution specialist. Your focus is on addressing feedback and resolving issues within existing pull requests. Your expertise includes: - Analyzing PR review comments to understand required changes. - Checking CI/CD workflow statuses to identify failing tests. - Fetching and analyzing test logs to diagnose failures. - Identifying and resolving merge conflicts. - Guiding the user through the resolution process."
@ -41,6 +119,16 @@ customModes:
- edit
- command
- mcp
- slug: issue-investigator
name: 🕵️ Issue Investigator
roleDefinition: You are Roo, a GitHub issue investigator. Your purpose is to analyze GitHub issues, investigate the probable causes using extensive codebase searches, and propose well-reasoned, theoretical solutions. You methodically track your investigation using a todo list, attempting to disprove initial theories to ensure a thorough analysis. Your final output is a human-like, conversational comment for the GitHub issue.
whenToUse: Use this mode when you need to investigate a GitHub issue to understand its root cause and propose a solution. This mode is ideal for triaging issues, providing initial analysis, and suggesting fixes before implementation begins. It uses the `gh` CLI for issue interaction.
description: Investigates GitHub issues
groups:
- read
- command
- mcp
source: project
- slug: merge-resolver
name: 🔀 Merge Resolver
roleDefinition: |-
@ -73,39 +161,6 @@ customModes:
- command
- mcp
source: project
- slug: docs-extractor
name: 📚 Docs Extractor
roleDefinition: |-
You are Roo Code, a codebase analyst who extracts raw facts for documentation teams.
You do NOT write documentation. You extract and organize information.
Two functions:
1. Extract: Gather facts about a feature/aspect from the codebase
2. Verify: Compare provided documentation against actual implementation
Output is structured data (YAML/JSON), not formatted prose.
No templates, no markdown formatting, no document structure decisions.
Let documentation-writer mode handle all writing.
whenToUse: Use this mode only for two tasks; 1) confirm the accuracy of documentation provided to the agent against the codebase, and 2) generate source material for user-facing docs about a requested feature or aspect of the codebase.
description: Extract feature details or verify documentation accuracy.
groups:
- read
- - edit
- fileRegex: \.roo/extraction/.*\.(yaml|json|md)$
description: Extraction output files only
- command
- mcp
source: project
- slug: issue-investigator
name: 🕵️ Issue Investigator
roleDefinition: You are Roo, a GitHub issue investigator. Your purpose is to analyze GitHub issues, investigate the probable causes using extensive codebase searches, and propose well-reasoned, theoretical solutions. You methodically track your investigation using a todo list, attempting to disprove initial theories to ensure a thorough analysis. Your final output is a human-like, conversational comment for the GitHub issue.
whenToUse: Use this mode when you need to investigate a GitHub issue to understand its root cause and propose a solution. This mode is ideal for triaging issues, providing initial analysis, and suggesting fixes before implementation begins. It uses the `gh` CLI for issue interaction.
description: Investigates GitHub issues
groups:
- read
- command
- mcp
source: project
- slug: issue-writer
name: 📝 Issue Writer
roleDefinition: |-
@ -128,21 +183,71 @@ customModes:
<update_todo_list>
<todos>
[ ] Detect repository context (OWNER/REPO, monorepo, roots)
[ ] Perform targeted codebase discovery (iteration 1)
[ ] Clarify missing details (repro or desired outcome)
[ ] Classify type (Bug | Enhancement)
[ ] Assemble Issue Body
[ ] Review and submit (Submit now | Submit now and assign to me)
[ ] Detect current repository information
[ ] Determine repository structure (monorepo/standard)
[ ] Perform initial codebase discovery
[ ] Analyze user request to determine issue type
[ ] Gather and verify additional information
[ ] Determine if user wants to contribute
[ ] Perform issue scoping (if contributing)
[ ] Draft issue content
[ ] Review and confirm with user
[ ] Create GitHub issue
</todos>
</update_todo_list>
</instructions>
</step>
</initialization>
whenToUse: Use this mode when you need to create a GitHub issue. Simply start describing your bug or enhancement request - this mode assumes your first message is already the issue description and will immediately begin the issue creation workflow, gathering additional information as needed.
whenToUse: Use this mode when you need to create a GitHub issue. Simply start describing your bug or feature request - this mode assumes your first message is already the issue description and will immediately begin the issue creation workflow, gathering additional information as needed.
description: Create well-structured GitHub issues.
groups:
- read
- command
- mcp
source: project
- slug: pr-reviewer
name: 🔍 PR Reviewer
roleDefinition: |-
You are Roo, a pull request reviewer specializing in code quality, structure, and translation consistency. Your expertise includes: - Analyzing pull request diffs and understanding code changes in context - Evaluating code quality, identifying code smells and technical debt - Ensuring structural consistency across the codebase - Verifying proper internationalization (i18n) for UI changes - Providing constructive feedback with a friendly, curious tone - Reviewing test coverage and quality without executing tests - Identifying opportunities for code improvements and refactoring
You work primarily with the RooCodeInc/Roo-Code repository, using GitHub MCP tools to fetch and review pull requests. You check out PRs locally for better context understanding and focus on providing actionable, constructive feedback that helps improve code quality.
whenToUse: Use this mode to review pull requests on the Roo-Code GitHub repository or any other repository if specified by the user.
description: Review PRs for code quality, structure, and i18n compliance.
groups:
- read
- - edit
- fileRegex: \.md$
description: Markdown files only
- mcp
- command
source: project
- slug: mode-writer
name: ✍️ Mode Writer
roleDefinition: |-
You are Roo, a mode creation and editing specialist focused on designing, implementing, and enhancing custom modes for the Roo-Code project. Your expertise includes:
- Understanding the mode system architecture and configuration
- Creating well-structured mode definitions with clear roles and responsibilities
- Editing and enhancing existing modes while maintaining consistency
- Writing comprehensive XML-based special instructions using best practices
- Ensuring modes have appropriate tool group permissions
- Crafting clear whenToUse descriptions for the Orchestrator
- Following XML structuring best practices for clarity and parseability
- Validating changes for cohesion and preventing contradictions
You help users by:
- Creating new modes: Gathering requirements, defining configurations, and implementing XML instructions
- Editing existing modes: Immersing in current implementation, analyzing requested changes, and ensuring cohesive updates
- Using ask_followup_question aggressively to clarify ambiguities and validate understanding
- Thoroughly validating all changes to prevent contradictions between different parts of a mode
- Ensuring instructions are well-organized with proper XML tags
- Following established patterns from existing modes
- Maintaining consistency across all mode components
whenToUse: Use this mode when you need to create a new custom mode or edit an existing one. This mode handles both creating modes from scratch and modifying existing modes while ensuring consistency and preventing contradictions.
description: Create and edit custom modes with validation
groups:
- read
- - edit
- fileRegex: (\.roomodes$|\.roo/.*\.xml$|\.yaml$)
description: Mode configuration files and XML instructions
- command
- mcp
source: project

View file

@ -1,2 +1 @@
pnpm 10.8.1
nodejs 20.19.2

View file

@ -1,5 +0,0 @@
# AGENTS.md
This file provides guidance to agents when working with code in this repository.
- Settings View Pattern: When working on `SettingsView`, inputs must bind to the local `cachedState`, NOT the live `useExtensionState()`. The `cachedState` acts as a buffer for user edits, isolating them from the `ContextProxy` source-of-truth until the user explicitly clicks "Save". Wiring inputs directly to the live state causes race conditions.

File diff suppressed because it is too large Load diff

90
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,90 @@
<div align="center">
<sub>
<b>English</b> • [Català](locales/ca/CODE_OF_CONDUCT.md) • [Deutsch](locales/de/CODE_OF_CONDUCT.md) • [Español](locales/es/CODE_OF_CONDUCT.md) • [Français](locales/fr/CODE_OF_CONDUCT.md) • [हिंदी](locales/hi/CODE_OF_CONDUCT.md) • [Bahasa Indonesia](locales/id/CODE_OF_CONDUCT.md) • [Italiano](locales/it/CODE_OF_CONDUCT.md) • [日本語](locales/ja/CODE_OF_CONDUCT.md)
</sub>
<sub>
[한국어](locales/ko/CODE_OF_CONDUCT.md) • [Nederlands](locales/nl/CODE_OF_CONDUCT.md) • [Polski](locales/pl/CODE_OF_CONDUCT.md) • [Português (BR)](locales/pt-BR/CODE_OF_CONDUCT.md) • [Русский](locales/ru/CODE_OF_CONDUCT.md) • [Türkçe](locales/tr/CODE_OF_CONDUCT.md) • [Tiếng Việt](locales/vi/CODE_OF_CONDUCT.md) • [简体中文](locales/zh-CN/CODE_OF_CONDUCT.md) • [繁體中文](locales/zh-TW/CODE_OF_CONDUCT.md)
</sub>
</div>
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at support@roocode.com. All complaints
will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from [Cline's version][cline_coc] of the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[cline_coc]: https://github.com/cline/cline/blob/main/CODE_OF_CONDUCT.md
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

138
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,138 @@
<div align="center">
<sub>
<b>English</b> • [Català](locales/ca/CONTRIBUTING.md) • [Deutsch](locales/de/CONTRIBUTING.md) • [Español](locales/es/CONTRIBUTING.md) • [Français](locales/fr/CONTRIBUTING.md) • [हिंदी](locales/hi/CONTRIBUTING.md) • [Bahasa Indonesia](locales/id/CONTRIBUTING.md) • [Italiano](locales/it/CONTRIBUTING.md) • [日本語](locales/ja/CONTRIBUTING.md)
</sub>
<sub>
[한국어](locales/ko/CONTRIBUTING.md) • [Nederlands](locales/nl/CONTRIBUTING.md) • [Polski](locales/pl/CONTRIBUTING.md) • [Português (BR)](locales/pt-BR/CONTRIBUTING.md) • [Русский](locales/ru/CONTRIBUTING.md) • [Türkçe](locales/tr/CONTRIBUTING.md) • [Tiếng Việt](locales/vi/CONTRIBUTING.md) • [简体中文](locales/zh-CN/CONTRIBUTING.md) • [繁體中文](locales/zh-TW/CONTRIBUTING.md)
</sub>
</div>
# Contributing to Roo Code
Roo Code is a community-driven project, and we deeply value every contribution. To streamline collaboration, we operate on an [Issue-First](#issue-first-approach) basis, meaning all [Pull Requests (PRs)](#submitting-a-pull-request) must first be linked to a GitHub Issue. Please review this guide carefully.
## Table of Contents
- [Before You Contribute](#before-you-contribute)
- [Finding & Planning Your Contribution](#finding--planning-your-contribution)
- [Development & Submission Process](#development--submission-process)
- [Legal](#legal)
## Before You Contribute
### 1. Code of Conduct
All contributors must adhere to our [Code of Conduct](./CODE_OF_CONDUCT.md).
### 2. Project Roadmap
Our roadmap guides the project's direction. Align your contributions with these key goals:
### Reliability First
- Ensure diff editing and command execution are consistently reliable.
- Reduce friction points that deter regular usage.
- Guarantee smooth operation across all locales and platforms.
- Expand robust support for a wide variety of AI providers and models.
### Enhanced User Experience
- Streamline the UI/UX for clarity and intuitiveness.
- Continuously improve the workflow to meet the high expectations developers have for daily-use tools.
### Leading on Agent Performance
- Establish comprehensive evaluation benchmarks (evals) to measure real-world productivity.
- Make it easy for everyone to easily run and interpret these evals.
- Ship improvements that demonstrate clear increases in eval scores.
Mention alignment with these areas in your PRs.
### 3. Join the Roo Code Community
- **Primary:** Join our [Discord](https://discord.gg/roocode) and DM **Hannes Rudolph (`hrudolph`)**.
- **Alternative:** Experienced contributors can engage directly via [GitHub Projects](https://github.com/orgs/RooCodeInc/projects/1).
## Finding & Planning Your Contribution
### Types of Contributions
- **Bug Fixes:** Addressing code issues.
- **New Features:** Adding functionality.
- **Documentation:** Improving guides and clarity.
### Issue-First Approach
All contributions must begin with a GitHub Issue.
- **Check existing issues**: Search [GitHub Issues](https://github.com/RooCodeInc/Roo-Code/issues).
- **Create an issue**: Use appropriate templates:
- **Bugs:** "Bug Report" template.
- **Features:** "Detailed Feature Proposal" template. Approval required before starting.
- **Claim issues**: Comment and await official assignment.
**PRs without approved issues may be closed.**
### Deciding What to Work On
- Check the [GitHub Project](https://github.com/orgs/RooCodeInc/projects/1) for unassigned "Good First Issues."
- For docs, visit [Roo Code Docs](https://github.com/RooCodeInc/Roo-Code-Docs).
### Reporting Bugs
- Check for existing reports first.
- Create new bugs using the ["Bug Report" template](https://github.com/RooCodeInc/Roo-Code/issues/new/choose).
- **Security issues**: Report privately via [security advisories](https://github.com/RooCodeInc/Roo-Code/security/advisories/new).
## Development & Submission Process
### Development Setup
1. **Fork & Clone:**
```
git clone https://github.com/YOUR_USERNAME/Roo-Code.git
```
2. **Install Dependencies:**
```
pnpm install
```
3. **Debugging:** Open with VS Code (`F5`).
### Writing Code Guidelines
- One focused PR per feature or fix.
- Follow ESLint and TypeScript best practices.
- Write clear, descriptive commits referencing issues (e.g., `Fixes #123`).
- Provide thorough testing (`npm test`).
- Rebase onto the latest `main` branch before submission.
### Submitting a Pull Request
- Begin as a **Draft PR** if seeking early feedback.
- Clearly describe your changes following the Pull Request Template.
- Provide screenshots/videos for UI changes.
- Indicate if documentation updates are necessary.
### Pull Request Policy
- Must reference pre-approved, assigned issues.
- PRs without adherence to the policy may be closed.
- PRs should pass CI tests, align with the roadmap, and have clear documentation.
### Review Process
- **Daily Triage:** Quick checks by maintainers.
- **Weekly In-depth Review:** Comprehensive assessment.
- **Iterate promptly** based on feedback.
## Legal
By contributing, you agree your contributions will be licensed under the Apache 2.0 License, consistent with Roo Code's licensing.

View file

@ -1,27 +1,28 @@
# Roo Code Privacy Policy
**Last Updated: September 11th, 2025**
**Last Updated: August 20th, 2025**
Roo Code respects your privacy and is committed to transparency about how we handle your data. Below is a simple breakdown of where key pieces of data go—and, importantly, where they dont.
### **Where Your Data Goes (And Where It Doesnt)**
- **Code & Files**: Roo Code accesses files on your local machine when needed for AI-assisted features. When you send commands to Roo Code, relevant files may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. AI providers may store data per their privacy policies.
- **Code & Files**: Roo Code accesses files on your local machine when needed for AI-assisted features. When you send commands to Roo Code, relevant files may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. If you select Roo Code Cloud as the model provider (proxy mode), your code may transit Roo Code servers only to forward it to the upstream provider. We do not store your code; it is deleted immediately after forwarding. Otherwise, your code is sent directly to the provider. AI providers may store data per their privacy policies.
- **Commands**: Any commands executed through Roo Code happen on your local environment. However, when you use AI-powered features, the relevant code and context from your commands may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not have access to or store this data, but AI providers may process it per their privacy policies.
- **Prompts & AI Requests**: When you use AI-powered features, your prompts and relevant project context are sent to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not store or process this data. These AI providers have their own privacy policies and may store data per their terms of service.
- **Prompts & AI Requests**: When you use AI-powered features, your prompts and relevant project context are sent to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not store or process this data. These AI providers have their own privacy policies and may store data per their terms of service. If you choose Roo Code Cloud as the provider (proxy mode), prompts may transit Roo Code servers only to forward them to the upstream model and are not stored.
- **API Keys & Credentials**: If you enter an API key (e.g., to connect an AI model), it is stored locally on your device and never sent to us or any third party, except the provider you have chosen.
- **Telemetry (Usage Data)**: We collect anonymous feature usage and error data to help us improve Roo Code. This telemetry is powered by PostHog and includes your VS Code machine ID, feature usage patterns, and exception reports. This telemetry does **not** collect personally identifiable information, your code, or AI prompts. You can opt out of this telemetry at any time through the settings.
- **Telemetry (Usage Data)**: We only collect feature usage and error data if you explicitly opt-in. This telemetry is powered by PostHog and helps us understand feature usage to improve Roo Code. This includes your VS Code machine ID and feature usage patterns and exception reports. We do **not** collect personally identifiable information, your code, or AI prompts.
- **Marketplace Requests**: When you browse or search the Marketplace for Model Configuration Profiles (MCPs) or Custom Modes, Roo Code makes a secure API call to Roo Codes backend servers to retrieve listing information. These requests send only the query parameters (e.g., extension version, search term) necessary to fulfill the request and do not include your code, prompts, or personally identifiable information.
### **How We Use Your Data (If Collected)**
- We use telemetry to understand feature usage and improve Roo Code.
- If you opt-in to telemetry, we use it to understand feature usage and improve Roo Code.
- We do **not** sell or share your data.
- We do **not** train any models on your data.
### **Your Choices & Control**
- You can run models locally to prevent data being sent to third-parties.
- Telemetry collection is enabled by default to help us improve Roo Code, but you can opt out at any time through the settings.
- By default, telemetry collection is off and if you turn it on, you can opt out of telemetry at any time.
- You can delete Roo Code to stop all data collection.
### **Security & Updates**

286
README.md
View file

@ -1,77 +1,261 @@
<p align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline"><img src="https://img.shields.io/badge/VS_Code_Marketplace-007ACC?style=flat&logo=visualstudiocode&logoColor=white" alt="VS Code Marketplace"></a>
</p>
<div align="center">
<sub>
# Roo Code
<b>English</b> • [Català](locales/ca/README.md) • [Deutsch](locales/de/README.md) • [Español](locales/es/README.md) • [Français](locales/fr/README.md) • [हिंदी](locales/hi/README.md) • [Bahasa Indonesia](locales/id/README.md) • [Italiano](locales/it/README.md) • [日本語](locales/ja/README.md)
> Your AI-Powered Dev Team, Right in Your Editor
</sub>
<sub>
<details>
<summary>🌐 Available languages</summary>
[한국어](locales/ko/README.md) • [Nederlands](locales/nl/README.md) • [Polski](locales/pl/README.md) • [Português (BR)](locales/pt-BR/README.md) • [Русский](locales/ru/README.md) • [Türkçe](locales/tr/README.md) • [Tiếng Việt](locales/vi/README.md) • [简体中文](locales/zh-CN/README.md) • [繁體中文](locales/zh-TW/README.md)
- [English](README.md)
- [Català](locales/ca/README.md)
- [Deutsch](locales/de/README.md)
- [Español](locales/es/README.md)
- [Français](locales/fr/README.md)
- [हिंदी](locales/hi/README.md)
- [Bahasa Indonesia](locales/id/README.md)
- [Italiano](locales/it/README.md)
- [日本語](locales/ja/README.md)
- [한국어](locales/ko/README.md)
- [Nederlands](locales/nl/README.md)
- [Polski](locales/pl/README.md)
- [Português (BR)](locales/pt-BR/README.md)
- [Русский](locales/ru/README.md)
- [Türkçe](locales/tr/README.md)
- [Tiếng Việt](locales/vi/README.md)
- [简体中文](locales/zh-CN/README.md)
- [繁體中文](locales/zh-TW/README.md)
- ...
</details>
</sub>
</div>
<br>
<div align="center">
<h1>Roo Code</h1>
<p align="center">
<img src="https://media.githubusercontent.com/media/RooCodeInc/Roo-Code/main/src/assets/docs/demo.gif" width="100%" />
</p>
<p>Connect with developers, contribute ideas, and stay ahead with the latest AI-powered coding tools.</p>
<a href="https://discord.gg/roocode" target="_blank"><img src="https://img.shields.io/badge/Join%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Join Discord"></a>
<a href="https://www.reddit.com/r/RooCode/" target="_blank"><img src="https://img.shields.io/badge/Join%20Reddit-FF4500?style=for-the-badge&logo=reddit&logoColor=white" alt="Join Reddit"></a>
</div>
<br>
<br>
<div align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline" target="_blank"><img src="https://img.shields.io/badge/Download%20on%20VS%20Marketplace-blue?style=for-the-badge&logo=visualstudiocode&logoColor=white" alt="Download on VS Marketplace"></a>
<a href="https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop" target="_blank"><img src="https://img.shields.io/badge/Feature%20Requests-yellow?style=for-the-badge" alt="Feature Requests"></a>
<a href="https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline&ssr=false#review-details" target="_blank"><img src="https://img.shields.io/badge/Rate%20%26%20Review-green?style=for-the-badge" alt="Rate & Review"></a>
<a href="https://docs.roocode.com" target="_blank"><img src="https://img.shields.io/badge/Documentation-6B46C1?style=for-the-badge&logo=readthedocs&logoColor=white" alt="Documentation"></a>
</div>
**Roo Code** is an AI-powered **autonomous coding agent** that lives in your editor. It can:
- Communicate in natural language
- Read and write files directly in your workspace
- Run terminal commands
- Automate browser actions
- Integrate with any OpenAI-compatible or custom API/model
- Adapt its “personality” and capabilities through **Custom Modes**
Whether youre seeking a flexible coding partner, a system architect, or specialized roles like a QA engineer or product manager, Roo Code can help you build software more efficiently.
Check out the [CHANGELOG](CHANGELOG.md) for detailed updates and fixes.
---
## What Can Roo Code Do For YOU?
## 🎉 Roo Code 3.25 Released
- Generate Code from natural language descriptions and specs
- Adapt with Modes: Code, Architect, Ask, Debug, and Custom Modes
- Refactor & Debug existing code
- Write & Update documentation
- Answer Questions about your codebase
- Automate repetitive tasks
- Utilize MCP Servers
Roo Code 3.25 brings powerful new features and significant improvements to enhance your development workflow!
## Modes
- **Message Queueing** - Queue multiple messages while Roo is working, allowing you to continue planning your workflow without interruption.
- **Custom Slash Commands** - Create personalized slash commands for quick access to frequently used prompts and workflows, with full UI management.
- **Enhanced Gemini Tools** - New URL context and Google Search grounding capabilities provide Gemini models with real-time web information and enhanced research abilities.
Roo Code adapts to how you work:
---
- Code Mode: everyday coding, edits, and file ops
- Architect Mode: plan systems, specs, and migrations
- Ask Mode: fast answers, explanations, and docs
- Debug Mode: trace issues, add logs, isolate root causes
- Custom Modes: build specialized modes for your team or workflow
## What Can Roo Code Do?
Learn more: [Using Modes](https://roocodeinc.github.io/Roo-Code/basic-usage/using-modes) • [Custom Modes](https://roocodeinc.github.io/Roo-Code/advanced-usage/custom-modes)
- 🚀 **Generate Code** from natural language descriptions
- 🔧 **Refactor & Debug** existing code
- 📝 **Write & Update** documentation
- 🤔 **Answer Questions** about your codebase
- 🔄 **Automate** repetitive tasks
- 🏗️ **Create** new files and projects
## Quick Start
1. [Install Roo Code](https://docs.roocode.com/getting-started/installing)
2. [Connect Your AI Provider](https://docs.roocode.com/getting-started/connecting-api-provider)
3. [Try Your First Task](https://docs.roocode.com/getting-started/your-first-task)
## Key Features
### Multiple Modes
Roo Code adapts to your needs with specialized [modes](https://docs.roocode.com/basic-usage/using-modes):
- **Code Mode:** For general-purpose coding tasks
- **Architect Mode:** For planning and technical leadership
- **Ask Mode:** For answering questions and providing information
- **Debug Mode:** For systematic problem diagnosis
- **[Custom Modes](https://docs.roocode.com/advanced-usage/custom-modes):** Create unlimited specialized personas for security auditing, performance optimization, documentation, or any other task
### Smart Tools
Roo Code comes with powerful [tools](https://docs.roocode.com/basic-usage/how-tools-work) that can:
- Read and write files in your project
- Execute commands in your VS Code terminal
- Control a web browser
- Use external tools via [MCP (Model Context Protocol)](https://docs.roocode.com/advanced-usage/mcp)
MCP extends Roo Code's capabilities by allowing you to add unlimited custom tools. Integrate with external APIs, connect to databases, or create specialized development tools - MCP provides the framework to expand Roo Code's functionality to meet your specific needs.
### Customization
Make Roo Code work your way with:
- [Custom Instructions](https://docs.roocode.com/advanced-usage/custom-instructions) for personalized behavior
- [Custom Modes](https://docs.roocode.com/advanced-usage/custom-modes) for specialized tasks
- [Local Models](https://docs.roocode.com/advanced-usage/local-models) for offline use
- [Auto-Approval Settings](https://docs.roocode.com/advanced-usage/auto-approving-actions) for faster workflows
## Resources
- **[Documentation](https://roocodeinc.github.io/Roo-Code/):** The official guide to installing, configuring, and mastering Roo Code.
- **[GitHub Issues](https://github.com/RooCodeInc/Roo-Code/issues):** Report bugs and track development.
### Documentation
- [Basic Usage Guide](https://docs.roocode.com/basic-usage/the-chat-interface)
- [Advanced Features](https://docs.roocode.com/advanced-usage/auto-approving-actions)
- [Frequently Asked Questions](https://docs.roocode.com/faq)
### Community
- **Discord:** [Join our Discord server](https://discord.gg/roocode) for real-time help and discussions
- **Reddit:** [Visit our subreddit](https://www.reddit.com/r/RooCode) to share experiences and tips
- **GitHub:** Report [issues](https://github.com/RooCodeInc/Roo-Code/issues) or request [features](https://github.com/RooCodeInc/Roo-Code/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop)
---
## Local Setup & Development
1. **Clone** the repo:
```sh
git clone https://github.com/RooCodeInc/Roo-Code.git
```
2. **Install dependencies**:
```sh
pnpm install
```
3. **Run the extension**:
There are several ways to run the Roo Code extension:
### Development Mode (F5)
For active development, use VSCode's built-in debugging:
Press `F5` (or go to **Run****Start Debugging**) in VSCode. This will open a new VSCode window with the Roo Code extension running.
- Changes to the webview will appear immediately.
- Changes to the core extension will also hot reload automatically.
### Automated VSIX Installation
To build and install the extension as a VSIX package directly into VSCode:
```sh
pnpm install:vsix [-y] [--editor=<command>]
```
This command will:
- Ask which editor command to use (code/cursor/code-insiders) - defaults to 'code'
- Uninstall any existing version of the extension.
- Build the latest VSIX package.
- Install the newly built VSIX.
- Prompt you to restart VS Code for changes to take effect.
Options:
- `-y`: Skip all confirmation prompts and use defaults
- `--editor=<command>`: Specify the editor command (e.g., `--editor=cursor` or `--editor=code-insiders`)
### Manual VSIX Installation
If you prefer to install the VSIX package manually:
1. First, build the VSIX package:
```sh
pnpm vsix
```
2. A `.vsix` file will be generated in the `bin/` directory (e.g., `bin/roo-cline-<version>.vsix`).
3. Install it manually using the VSCode CLI:
```sh
code --install-extension bin/roo-cline-<version>.vsix
```
---
We use [changesets](https://github.com/changesets/changesets) for versioning and publishing. Check our `CHANGELOG.md` for release notes.
---
## Disclaimer
The Roo Code Extension was shut down on May 15th.
- If you're looking for an alternative, check out [ZooCode](https://github.com/Zoo-Code-Org/Zoo-Code/) (a fork started by the Roo Code community) and [Cline](https://cline.bot/) (from where Roo Code originated).
- If you were a paying user and have billing questions, please write [billing@roocode.com](mailto:billing@roocode.com).
**Please note** that Roo Code, Inc does **not** make any representations or warranties regarding any code, models, or other tools provided or made available in connection with Roo Code, any associated third-party tools, or any resulting outputs. You assume **all risks** associated with the use of any such tools or outputs; such tools are provided on an **"AS IS"** and **"AS AVAILABLE"** basis. Such risks may include, without limitation, intellectual property infringement, cyber vulnerabilities or attacks, bias, inaccuracies, errors, defects, viruses, downtime, property loss or damage, and/or personal injury. You are solely responsible for your use of any such tools or outputs (including, without limitation, the legality, appropriateness, and results thereof).
---
## Contributing
We love community contributions! Get started by reading our [CONTRIBUTING.md](CONTRIBUTING.md).
---
## Contributors
Thanks to all our contributors who have helped make Roo Code better!
<!-- START CONTRIBUTORS SECTION - AUTO-GENERATED, DO NOT EDIT MANUALLY -->
| <a href="https://github.com/mrubens"><img src="https://avatars.githubusercontent.com/u/2600?v=4" width="100" height="100" alt="mrubens"/><br /><sub><b>mrubens</b></sub></a> | <a href="https://github.com/saoudrizwan"><img src="https://avatars.githubusercontent.com/u/7799382?v=4" width="100" height="100" alt="saoudrizwan"/><br /><sub><b>saoudrizwan</b></sub></a> | <a href="https://github.com/cte"><img src="https://avatars.githubusercontent.com/u/16332?v=4" width="100" height="100" alt="cte"/><br /><sub><b>cte</b></sub></a> | <a href="https://github.com/daniel-lxs"><img src="https://avatars.githubusercontent.com/u/57051444?v=4" width="100" height="100" alt="daniel-lxs"/><br /><sub><b>daniel-lxs</b></sub></a> | <a href="https://github.com/samhvw8"><img src="https://avatars.githubusercontent.com/u/12538214?v=4" width="100" height="100" alt="samhvw8"/><br /><sub><b>samhvw8</b></sub></a> | <a href="https://github.com/hannesrudolph"><img src="https://avatars.githubusercontent.com/u/49103247?v=4" width="100" height="100" alt="hannesrudolph"/><br /><sub><b>hannesrudolph</b></sub></a> |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/KJ7LNW"><img src="https://avatars.githubusercontent.com/u/93454819?v=4" width="100" height="100" alt="KJ7LNW"/><br /><sub><b>KJ7LNW</b></sub></a> | <a href="https://github.com/a8trejo"><img src="https://avatars.githubusercontent.com/u/62401433?v=4" width="100" height="100" alt="a8trejo"/><br /><sub><b>a8trejo</b></sub></a> | <a href="https://github.com/ColemanRoo"><img src="https://avatars.githubusercontent.com/u/117104599?v=4" width="100" height="100" alt="ColemanRoo"/><br /><sub><b>ColemanRoo</b></sub></a> | <a href="https://github.com/MuriloFP"><img src="https://avatars.githubusercontent.com/u/50873657?v=4" width="100" height="100" alt="MuriloFP"/><br /><sub><b>MuriloFP</b></sub></a> | <a href="https://github.com/canrobins13"><img src="https://avatars.githubusercontent.com/u/20544372?v=4" width="100" height="100" alt="canrobins13"/><br /><sub><b>canrobins13</b></sub></a> | <a href="https://github.com/stea9499"><img src="https://avatars.githubusercontent.com/u/4163795?v=4" width="100" height="100" alt="stea9499"/><br /><sub><b>stea9499</b></sub></a> |
| <a href="https://github.com/jr"><img src="https://avatars.githubusercontent.com/u/5629?v=4" width="100" height="100" alt="jr"/><br /><sub><b>jr</b></sub></a> | <a href="https://github.com/joemanley201"><img src="https://avatars.githubusercontent.com/u/8299960?v=4" width="100" height="100" alt="joemanley201"/><br /><sub><b>joemanley201</b></sub></a> | <a href="https://github.com/System233"><img src="https://avatars.githubusercontent.com/u/20336040?v=4" width="100" height="100" alt="System233"/><br /><sub><b>System233</b></sub></a> | <a href="https://github.com/nissa-seru"><img src="https://avatars.githubusercontent.com/u/119150866?v=4" width="100" height="100" alt="nissa-seru"/><br /><sub><b>nissa-seru</b></sub></a> | <a href="https://github.com/jquanton"><img src="https://avatars.githubusercontent.com/u/88576563?v=4" width="100" height="100" alt="jquanton"/><br /><sub><b>jquanton</b></sub></a> | <a href="https://github.com/roomote-agent"><img src="https://avatars.githubusercontent.com/u/206919393?v=4" width="100" height="100" alt="roomote-agent"/><br /><sub><b>roomote-agent</b></sub></a> |
| <a href="https://github.com/NyxJae"><img src="https://avatars.githubusercontent.com/u/52313587?v=4" width="100" height="100" alt="NyxJae"/><br /><sub><b>NyxJae</b></sub></a> | <a href="https://github.com/elianiva"><img src="https://avatars.githubusercontent.com/u/51877647?v=4" width="100" height="100" alt="elianiva"/><br /><sub><b>elianiva</b></sub></a> | <a href="https://github.com/chrarnoldus"><img src="https://avatars.githubusercontent.com/u/12196001?v=4" width="100" height="100" alt="chrarnoldus"/><br /><sub><b>chrarnoldus</b></sub></a> | <a href="https://github.com/d-oit"><img src="https://avatars.githubusercontent.com/u/6849456?v=4" width="100" height="100" alt="d-oit"/><br /><sub><b>d-oit</b></sub></a> | <a href="https://github.com/qdaxb"><img src="https://avatars.githubusercontent.com/u/4157870?v=4" width="100" height="100" alt="qdaxb"/><br /><sub><b>qdaxb</b></sub></a> | <a href="https://github.com/wkordalski"><img src="https://avatars.githubusercontent.com/u/3035587?v=4" width="100" height="100" alt="wkordalski"/><br /><sub><b>wkordalski</b></sub></a> |
| <a href="https://github.com/xyOz-dev"><img src="https://avatars.githubusercontent.com/u/195602624?v=4" width="100" height="100" alt="xyOz-dev"/><br /><sub><b>xyOz-dev</b></sub></a> | <a href="https://github.com/punkpeye"><img src="https://avatars.githubusercontent.com/u/108313943?v=4" width="100" height="100" alt="punkpeye"/><br /><sub><b>punkpeye</b></sub></a> | <a href="https://github.com/SannidhyaSah"><img src="https://avatars.githubusercontent.com/u/186946675?v=4" width="100" height="100" alt="SannidhyaSah"/><br /><sub><b>SannidhyaSah</b></sub></a> | <a href="https://github.com/zhangtony239"><img src="https://avatars.githubusercontent.com/u/157202938?v=4" width="100" height="100" alt="zhangtony239"/><br /><sub><b>zhangtony239</b></sub></a> | <a href="https://github.com/feifei325"><img src="https://avatars.githubusercontent.com/u/46489071?v=4" width="100" height="100" alt="feifei325"/><br /><sub><b>feifei325</b></sub></a> | <a href="https://github.com/cannuri"><img src="https://avatars.githubusercontent.com/u/91494156?v=4" width="100" height="100" alt="cannuri"/><br /><sub><b>cannuri</b></sub></a> |
| <a href="https://github.com/monotykamary"><img src="https://avatars.githubusercontent.com/u/1130103?v=4" width="100" height="100" alt="monotykamary"/><br /><sub><b>monotykamary</b></sub></a> | <a href="https://github.com/Smartsheet-JB-Brown"><img src="https://avatars.githubusercontent.com/u/171734120?v=4" width="100" height="100" alt="Smartsheet-JB-Brown"/><br /><sub><b>Smartsheet-JB-Brown</b></sub></a> | <a href="https://github.com/sachasayan"><img src="https://avatars.githubusercontent.com/u/1666034?v=4" width="100" height="100" alt="sachasayan"/><br /><sub><b>sachasayan</b></sub></a> | <a href="https://github.com/dtrugman"><img src="https://avatars.githubusercontent.com/u/2451669?v=4" width="100" height="100" alt="dtrugman"/><br /><sub><b>dtrugman</b></sub></a> | <a href="https://github.com/liwilliam2021"><img src="https://avatars.githubusercontent.com/u/40069349?v=4" width="100" height="100" alt="liwilliam2021"/><br /><sub><b>liwilliam2021</b></sub></a> | <a href="https://github.com/hassoncs"><img src="https://avatars.githubusercontent.com/u/5104925?v=4" width="100" height="100" alt="hassoncs"/><br /><sub><b>hassoncs</b></sub></a> |
| <a href="https://github.com/shariqriazz"><img src="https://avatars.githubusercontent.com/u/196900129?v=4" width="100" height="100" alt="shariqriazz"/><br /><sub><b>shariqriazz</b></sub></a> | <a href="https://github.com/vigneshsubbiah16"><img src="https://avatars.githubusercontent.com/u/51325334?v=4" width="100" height="100" alt="vigneshsubbiah16"/><br /><sub><b>vigneshsubbiah16</b></sub></a> | <a href="https://github.com/pugazhendhi-m"><img src="https://avatars.githubusercontent.com/u/132246623?v=4" width="100" height="100" alt="pugazhendhi-m"/><br /><sub><b>pugazhendhi-m</b></sub></a> | <a href="https://github.com/lloydchang"><img src="https://avatars.githubusercontent.com/u/1329685?v=4" width="100" height="100" alt="lloydchang"/><br /><sub><b>lloydchang</b></sub></a> | <a href="https://github.com/NaccOll"><img src="https://avatars.githubusercontent.com/u/26819913?v=4" width="100" height="100" alt="NaccOll"/><br /><sub><b>NaccOll</b></sub></a> | <a href="https://github.com/Szpadel"><img src="https://avatars.githubusercontent.com/u/1857251?v=4" width="100" height="100" alt="Szpadel"/><br /><sub><b>Szpadel</b></sub></a> |
| <a href="https://github.com/PeterDaveHello"><img src="https://avatars.githubusercontent.com/u/3691490?v=4" width="100" height="100" alt="PeterDaveHello"/><br /><sub><b>PeterDaveHello</b></sub></a> | <a href="https://github.com/diarmidmackenzie"><img src="https://avatars.githubusercontent.com/u/16045703?v=4" width="100" height="100" alt="diarmidmackenzie"/><br /><sub><b>diarmidmackenzie</b></sub></a> | <a href="https://github.com/olweraltuve"><img src="https://avatars.githubusercontent.com/u/39308405?v=4" width="100" height="100" alt="olweraltuve"/><br /><sub><b>olweraltuve</b></sub></a> | <a href="https://github.com/psv2522"><img src="https://avatars.githubusercontent.com/u/87223770?v=4" width="100" height="100" alt="psv2522"/><br /><sub><b>psv2522</b></sub></a> | <a href="https://github.com/Premshay"><img src="https://avatars.githubusercontent.com/u/28099628?v=4" width="100" height="100" alt="Premshay"/><br /><sub><b>Premshay</b></sub></a> | <a href="https://github.com/kiwina"><img src="https://avatars.githubusercontent.com/u/1071364?v=4" width="100" height="100" alt="kiwina"/><br /><sub><b>kiwina</b></sub></a> |
| <a href="https://github.com/lupuletic"><img src="https://avatars.githubusercontent.com/u/105351510?v=4" width="100" height="100" alt="lupuletic"/><br /><sub><b>lupuletic</b></sub></a> | <a href="https://github.com/ChuKhaLi"><img src="https://avatars.githubusercontent.com/u/15166543?v=4" width="100" height="100" alt="ChuKhaLi"/><br /><sub><b>ChuKhaLi</b></sub></a> | <a href="https://github.com/aheizi"><img src="https://avatars.githubusercontent.com/u/8243770?v=4" width="100" height="100" alt="aheizi"/><br /><sub><b>aheizi</b></sub></a> | <a href="https://github.com/afshawnlotfi"><img src="https://avatars.githubusercontent.com/u/6283745?v=4" width="100" height="100" alt="afshawnlotfi"/><br /><sub><b>afshawnlotfi</b></sub></a> | <a href="https://github.com/RaySinner"><img src="https://avatars.githubusercontent.com/u/118297374?v=4" width="100" height="100" alt="RaySinner"/><br /><sub><b>RaySinner</b></sub></a> | <a href="https://github.com/noritaka1166"><img src="https://avatars.githubusercontent.com/u/189505037?v=4" width="100" height="100" alt="noritaka1166"/><br /><sub><b>noritaka1166</b></sub></a> |
| <a href="https://github.com/nbihan-mediware"><img src="https://avatars.githubusercontent.com/u/42357253?v=4" width="100" height="100" alt="nbihan-mediware"/><br /><sub><b>nbihan-mediware</b></sub></a> | <a href="https://github.com/brunobergher"><img src="https://avatars.githubusercontent.com/u/328388?v=4" width="100" height="100" alt="brunobergher"/><br /><sub><b>brunobergher</b></sub></a> | <a href="https://github.com/emshvac"><img src="https://avatars.githubusercontent.com/u/121588911?v=4" width="100" height="100" alt="emshvac"/><br /><sub><b>emshvac</b></sub></a> | <a href="https://github.com/kyle-apex"><img src="https://avatars.githubusercontent.com/u/20145331?v=4" width="100" height="100" alt="kyle-apex"/><br /><sub><b>kyle-apex</b></sub></a> | <a href="https://github.com/pdecat"><img src="https://avatars.githubusercontent.com/u/318490?v=4" width="100" height="100" alt="pdecat"/><br /><sub><b>pdecat</b></sub></a> | <a href="https://github.com/Ruakij"><img src="https://avatars.githubusercontent.com/u/54639830?v=4" width="100" height="100" alt="Ruakij"/><br /><sub><b>Ruakij</b></sub></a> |
| <a href="https://github.com/StevenTCramer"><img src="https://avatars.githubusercontent.com/u/357219?v=4" width="100" height="100" alt="StevenTCramer"/><br /><sub><b>StevenTCramer</b></sub></a> | <a href="https://github.com/dleffel"><img src="https://avatars.githubusercontent.com/u/7119958?v=4" width="100" height="100" alt="dleffel"/><br /><sub><b>dleffel</b></sub></a> | <a href="https://github.com/Lunchb0ne"><img src="https://avatars.githubusercontent.com/u/22198661?v=4" width="100" height="100" alt="Lunchb0ne"/><br /><sub><b>Lunchb0ne</b></sub></a> | <a href="https://github.com/SmartManoj"><img src="https://avatars.githubusercontent.com/u/7231077?v=4" width="100" height="100" alt="SmartManoj"/><br /><sub><b>SmartManoj</b></sub></a> | <a href="https://github.com/vagadiya"><img src="https://avatars.githubusercontent.com/u/32499123?v=4" width="100" height="100" alt="vagadiya"/><br /><sub><b>vagadiya</b></sub></a> | <a href="https://github.com/slytechnical"><img src="https://avatars.githubusercontent.com/u/139649758?v=4" width="100" height="100" alt="slytechnical"/><br /><sub><b>slytechnical</b></sub></a> |
| <a href="https://github.com/dlab-anton"><img src="https://avatars.githubusercontent.com/u/20571486?v=4" width="100" height="100" alt="dlab-anton"/><br /><sub><b>dlab-anton</b></sub></a> | <a href="https://github.com/arthurauffray"><img src="https://avatars.githubusercontent.com/u/51604173?v=4" width="100" height="100" alt="arthurauffray"/><br /><sub><b>arthurauffray</b></sub></a> | <a href="https://github.com/upamune"><img src="https://avatars.githubusercontent.com/u/8219560?v=4" width="100" height="100" alt="upamune"/><br /><sub><b>upamune</b></sub></a> | <a href="https://github.com/NamesMT"><img src="https://avatars.githubusercontent.com/u/23612546?v=4" width="100" height="100" alt="NamesMT"/><br /><sub><b>NamesMT</b></sub></a> | <a href="https://github.com/taylorwilsdon"><img src="https://avatars.githubusercontent.com/u/6508528?v=4" width="100" height="100" alt="taylorwilsdon"/><br /><sub><b>taylorwilsdon</b></sub></a> | <a href="https://github.com/sammcj"><img src="https://avatars.githubusercontent.com/u/862951?v=4" width="100" height="100" alt="sammcj"/><br /><sub><b>sammcj</b></sub></a> |
| <a href="https://github.com/p12tic"><img src="https://avatars.githubusercontent.com/u/1056711?v=4" width="100" height="100" alt="p12tic"/><br /><sub><b>p12tic</b></sub></a> | <a href="https://github.com/gtaylor"><img src="https://avatars.githubusercontent.com/u/75556?v=4" width="100" height="100" alt="gtaylor"/><br /><sub><b>gtaylor</b></sub></a> | <a href="https://github.com/catrielmuller"><img src="https://avatars.githubusercontent.com/u/2272323?v=4" width="100" height="100" alt="catrielmuller"/><br /><sub><b>catrielmuller</b></sub></a> | <a href="https://github.com/aitoroses"><img src="https://avatars.githubusercontent.com/u/1699368?v=4" width="100" height="100" alt="aitoroses"/><br /><sub><b>aitoroses</b></sub></a> | <a href="https://github.com/benzntech"><img src="https://avatars.githubusercontent.com/u/4044180?v=4" width="100" height="100" alt="benzntech"/><br /><sub><b>benzntech</b></sub></a> | <a href="https://github.com/ross"><img src="https://avatars.githubusercontent.com/u/12789?v=4" width="100" height="100" alt="ross"/><br /><sub><b>ross</b></sub></a> |
| <a href="https://github.com/mr-ryan-james"><img src="https://avatars.githubusercontent.com/u/9344431?v=4" width="100" height="100" alt="mr-ryan-james"/><br /><sub><b>mr-ryan-james</b></sub></a> | <a href="https://github.com/heyseth"><img src="https://avatars.githubusercontent.com/u/8293842?v=4" width="100" height="100" alt="heyseth"/><br /><sub><b>heyseth</b></sub></a> | <a href="https://github.com/taisukeoe"><img src="https://avatars.githubusercontent.com/u/1506707?v=4" width="100" height="100" alt="taisukeoe"/><br /><sub><b>taisukeoe</b></sub></a> | <a href="https://github.com/avtc"><img src="https://avatars.githubusercontent.com/u/10050240?v=4" width="100" height="100" alt="avtc"/><br /><sub><b>avtc</b></sub></a> | <a href="https://github.com/eonghk"><img src="https://avatars.githubusercontent.com/u/139964?v=4" width="100" height="100" alt="eonghk"/><br /><sub><b>eonghk</b></sub></a> | <a href="https://github.com/GOODBOY008"><img src="https://avatars.githubusercontent.com/u/13617900?v=4" width="100" height="100" alt="GOODBOY008"/><br /><sub><b>GOODBOY008</b></sub></a> |
| <a href="https://github.com/kcwhite"><img src="https://avatars.githubusercontent.com/u/3812801?v=4" width="100" height="100" alt="kcwhite"/><br /><sub><b>kcwhite</b></sub></a> | <a href="https://github.com/ronyblum"><img src="https://avatars.githubusercontent.com/u/20314054?v=4" width="100" height="100" alt="ronyblum"/><br /><sub><b>ronyblum</b></sub></a> | <a href="https://github.com/teddyOOXX"><img src="https://avatars.githubusercontent.com/u/121077180?v=4" width="100" height="100" alt="teddyOOXX"/><br /><sub><b>teddyOOXX</b></sub></a> | <a href="https://github.com/thill2323"><img src="https://avatars.githubusercontent.com/u/221205361?v=4" width="100" height="100" alt="thill2323"/><br /><sub><b>thill2323</b></sub></a> | <a href="https://github.com/vincentsong"><img src="https://avatars.githubusercontent.com/u/2343574?v=4" width="100" height="100" alt="vincentsong"/><br /><sub><b>vincentsong</b></sub></a> | <a href="https://github.com/yongjer"><img src="https://avatars.githubusercontent.com/u/54315206?v=4" width="100" height="100" alt="yongjer"/><br /><sub><b>yongjer</b></sub></a> |
| <a href="https://github.com/zeozeozeo"><img src="https://avatars.githubusercontent.com/u/108888572?v=4" width="100" height="100" alt="zeozeozeo"/><br /><sub><b>zeozeozeo</b></sub></a> | <a href="https://github.com/ashktn"><img src="https://avatars.githubusercontent.com/u/6723913?v=4" width="100" height="100" alt="ashktn"/><br /><sub><b>ashktn</b></sub></a> | <a href="https://github.com/franekp"><img src="https://avatars.githubusercontent.com/u/9804230?v=4" width="100" height="100" alt="franekp"/><br /><sub><b>franekp</b></sub></a> | <a href="https://github.com/yt3trees"><img src="https://avatars.githubusercontent.com/u/57471763?v=4" width="100" height="100" alt="yt3trees"/><br /><sub><b>yt3trees</b></sub></a> | <a href="https://github.com/seedlord"><img src="https://avatars.githubusercontent.com/u/20932878?v=4" width="100" height="100" alt="seedlord"/><br /><sub><b>seedlord</b></sub></a> | <a href="https://github.com/QuinsZouls"><img src="https://avatars.githubusercontent.com/u/40646096?v=4" width="100" height="100" alt="QuinsZouls"/><br /><sub><b>QuinsZouls</b></sub></a> |
| <a href="https://github.com/anton-otee"><img src="https://avatars.githubusercontent.com/u/149477749?v=4" width="100" height="100" alt="anton-otee"/><br /><sub><b>anton-otee</b></sub></a> | <a href="https://github.com/axkirillov"><img src="https://avatars.githubusercontent.com/u/32141102?v=4" width="100" height="100" alt="axkirillov"/><br /><sub><b>axkirillov</b></sub></a> | <a href="https://github.com/bramburn"><img src="https://avatars.githubusercontent.com/u/11090413?v=4" width="100" height="100" alt="bramburn"/><br /><sub><b>bramburn</b></sub></a> | <a href="https://github.com/olearycrew"><img src="https://avatars.githubusercontent.com/u/6044920?v=4" width="100" height="100" alt="olearycrew"/><br /><sub><b>olearycrew</b></sub></a> | <a href="https://github.com/devxpain"><img src="https://avatars.githubusercontent.com/u/170700110?v=4" width="100" height="100" alt="devxpain"/><br /><sub><b>devxpain</b></sub></a> | <a href="https://github.com/snoyiatk"><img src="https://avatars.githubusercontent.com/u/3056569?v=4" width="100" height="100" alt="snoyiatk"/><br /><sub><b>snoyiatk</b></sub></a> |
| <a href="https://github.com/GitlyHallows"><img src="https://avatars.githubusercontent.com/u/136527758?v=4" width="100" height="100" alt="GitlyHallows"/><br /><sub><b>GitlyHallows</b></sub></a> | <a href="https://github.com/jcbdev"><img src="https://avatars.githubusercontent.com/u/17152092?v=4" width="100" height="100" alt="jcbdev"/><br /><sub><b>jcbdev</b></sub></a> | <a href="https://github.com/Chenjiayuan195"><img src="https://avatars.githubusercontent.com/u/30591313?v=4" width="100" height="100" alt="Chenjiayuan195"/><br /><sub><b>Chenjiayuan195</b></sub></a> | <a href="https://github.com/julionav"><img src="https://avatars.githubusercontent.com/u/45607850?v=4" width="100" height="100" alt="julionav"/><br /><sub><b>julionav</b></sub></a> | <a href="https://github.com/KanTakahiro"><img src="https://avatars.githubusercontent.com/u/64513424?v=4" width="100" height="100" alt="KanTakahiro"/><br /><sub><b>KanTakahiro</b></sub></a> | <a href="https://github.com/kevint-cerebras"><img src="https://avatars.githubusercontent.com/u/194834902?v=4" width="100" height="100" alt="kevint-cerebras"/><br /><sub><b>kevint-cerebras</b></sub></a> |
| <a href="https://github.com/SplittyDev"><img src="https://avatars.githubusercontent.com/u/4216049?v=4" width="100" height="100" alt="SplittyDev"/><br /><sub><b>SplittyDev</b></sub></a> | <a href="https://github.com/mdp"><img src="https://avatars.githubusercontent.com/u/2868?v=4" width="100" height="100" alt="mdp"/><br /><sub><b>mdp</b></sub></a> | <a href="https://github.com/napter"><img src="https://avatars.githubusercontent.com/u/6260841?v=4" width="100" height="100" alt="napter"/><br /><sub><b>napter</b></sub></a> | <a href="https://github.com/philfung"><img src="https://avatars.githubusercontent.com/u/1054593?v=4" width="100" height="100" alt="philfung"/><br /><sub><b>philfung</b></sub></a> | <a href="https://github.com/pwilkin"><img src="https://avatars.githubusercontent.com/u/5802960?v=4" width="100" height="100" alt="pwilkin"/><br /><sub><b>pwilkin</b></sub></a> | <a href="https://github.com/dairui1"><img src="https://avatars.githubusercontent.com/u/183250644?v=4" width="100" height="100" alt="dairui1"/><br /><sub><b>dairui1</b></sub></a> |
| <a href="https://github.com/chris-garrett"><img src="https://avatars.githubusercontent.com/u/1113459?v=4" width="100" height="100" alt="chris-garrett"/><br /><sub><b>chris-garrett</b></sub></a> | <a href="https://github.com/bbenshalom"><img src="https://avatars.githubusercontent.com/u/4359971?v=4" width="100" height="100" alt="bbenshalom"/><br /><sub><b>bbenshalom</b></sub></a> | <a href="https://github.com/bannzai"><img src="https://avatars.githubusercontent.com/u/10897361?v=4" width="100" height="100" alt="bannzai"/><br /><sub><b>bannzai</b></sub></a> | <a href="https://github.com/axmo"><img src="https://avatars.githubusercontent.com/u/2386344?v=4" width="100" height="100" alt="axmo"/><br /><sub><b>axmo</b></sub></a> | <a href="https://github.com/dqroid"><img src="https://avatars.githubusercontent.com/u/192424994?v=4" width="100" height="100" alt="dqroid"/><br /><sub><b>dqroid</b></sub></a> | <a href="https://github.com/ershang-fireworks"><img src="https://avatars.githubusercontent.com/u/194448967?v=4" width="100" height="100" alt="ershang-fireworks"/><br /><sub><b>ershang-fireworks</b></sub></a> |
| <a href="https://github.com/f14XuanLv"><img src="https://avatars.githubusercontent.com/u/121799454?v=4" width="100" height="100" alt="f14XuanLv"/><br /><sub><b>f14XuanLv</b></sub></a> | <a href="https://github.com/janaki-sasidhar"><img src="https://avatars.githubusercontent.com/u/42799643?v=4" width="100" height="100" alt="janaki-sasidhar"/><br /><sub><b>janaki-sasidhar</b></sub></a> | <a href="https://github.com/forestyoo"><img src="https://avatars.githubusercontent.com/u/2929056?v=4" width="100" height="100" alt="forestyoo"/><br /><sub><b>forestyoo</b></sub></a> | <a href="https://github.com/hatsu38"><img src="https://avatars.githubusercontent.com/u/16137809?v=4" width="100" height="100" alt="hatsu38"/><br /><sub><b>hatsu38</b></sub></a> | <a href="https://github.com/hongzio"><img src="https://avatars.githubusercontent.com/u/11085613?v=4" width="100" height="100" alt="hongzio"/><br /><sub><b>hongzio</b></sub></a> | <a href="https://github.com/im47cn"><img src="https://avatars.githubusercontent.com/u/67424112?v=4" width="100" height="100" alt="im47cn"/><br /><sub><b>im47cn</b></sub></a> |
| <a href="https://github.com/asychin"><img src="https://avatars.githubusercontent.com/u/178776568?v=4" width="100" height="100" alt="asychin"/><br /><sub><b>asychin</b></sub></a> | <a href="https://github.com/amittell"><img src="https://avatars.githubusercontent.com/u/1388680?v=4" width="100" height="100" alt="amittell"/><br /><sub><b>amittell</b></sub></a> | <a href="https://github.com/Yoshino-Yukitaro"><img src="https://avatars.githubusercontent.com/u/67864326?v=4" width="100" height="100" alt="Yoshino-Yukitaro"/><br /><sub><b>Yoshino-Yukitaro</b></sub></a> | <a href="https://github.com/Yikai-Liao"><img src="https://avatars.githubusercontent.com/u/110762732?v=4" width="100" height="100" alt="Yikai-Liao"/><br /><sub><b>Yikai-Liao</b></sub></a> | <a href="https://github.com/zxdvd"><img src="https://avatars.githubusercontent.com/u/107175?v=4" width="100" height="100" alt="zxdvd"/><br /><sub><b>zxdvd</b></sub></a> | <a href="https://github.com/s97712"><img src="https://avatars.githubusercontent.com/u/13390001?v=4" width="100" height="100" alt="s97712"/><br /><sub><b>s97712</b></sub></a> |
| <a href="https://github.com/vladstudio"><img src="https://avatars.githubusercontent.com/u/914320?v=4" width="100" height="100" alt="vladstudio"/><br /><sub><b>vladstudio</b></sub></a> | <a href="https://github.com/vivekfyi"><img src="https://avatars.githubusercontent.com/u/5036512?v=4" width="100" height="100" alt="vivekfyi"/><br /><sub><b>vivekfyi</b></sub></a> | <a href="https://github.com/HahaBill"><img src="https://avatars.githubusercontent.com/u/32552798?v=4" width="100" height="100" alt="HahaBill"/><br /><sub><b>HahaBill</b></sub></a> | <a href="https://github.com/tmsjngx0"><img src="https://avatars.githubusercontent.com/u/40481136?v=4" width="100" height="100" alt="tmsjngx0"/><br /><sub><b>tmsjngx0</b></sub></a> | <a href="https://github.com/TGlide"><img src="https://avatars.githubusercontent.com/u/26071571?v=4" width="100" height="100" alt="TGlide"/><br /><sub><b>TGlide</b></sub></a> | <a href="https://github.com/Githubguy132010"><img src="https://avatars.githubusercontent.com/u/145768128?v=4" width="100" height="100" alt="Githubguy132010"/><br /><sub><b>Githubguy132010</b></sub></a> |
| <a href="https://github.com/tgfjt"><img src="https://avatars.githubusercontent.com/u/2628239?v=4" width="100" height="100" alt="tgfjt"/><br /><sub><b>tgfjt</b></sub></a> | <a href="https://github.com/maekawataiki"><img src="https://avatars.githubusercontent.com/u/26317009?v=4" width="100" height="100" alt="maekawataiki"/><br /><sub><b>maekawataiki</b></sub></a> | <a href="https://github.com/AlexandruSmirnov"><img src="https://avatars.githubusercontent.com/u/210187997?v=4" width="100" height="100" alt="AlexandruSmirnov"/><br /><sub><b>AlexandruSmirnov</b></sub></a> | <a href="https://github.com/abumalick"><img src="https://avatars.githubusercontent.com/u/8377185?v=4" width="100" height="100" alt="abumalick"/><br /><sub><b>abumalick</b></sub></a> | <a href="https://github.com/shoopapa"><img src="https://avatars.githubusercontent.com/u/45986634?v=4" width="100" height="100" alt="shoopapa"/><br /><sub><b>shoopapa</b></sub></a> | <a href="https://github.com/qingyuan1109"><img src="https://avatars.githubusercontent.com/u/841732?v=4" width="100" height="100" alt="qingyuan1109"/><br /><sub><b>qingyuan1109</b></sub></a> |
| <a href="https://github.com/refactorthis"><img src="https://avatars.githubusercontent.com/u/3012240?v=4" width="100" height="100" alt="refactorthis"/><br /><sub><b>refactorthis</b></sub></a> | <a href="https://github.com/robertheadley"><img src="https://avatars.githubusercontent.com/u/1780455?v=4" width="100" height="100" alt="robertheadley"/><br /><sub><b>robertheadley</b></sub></a> | <a href="https://github.com/samir-nimbly"><img src="https://avatars.githubusercontent.com/u/112695483?v=4" width="100" height="100" alt="samir-nimbly"/><br /><sub><b>samir-nimbly</b></sub></a> | <a href="https://github.com/sensei-woo"><img src="https://avatars.githubusercontent.com/u/168141084?v=4" width="100" height="100" alt="sensei-woo"/><br /><sub><b>sensei-woo</b></sub></a> | <a href="https://github.com/shaybc"><img src="https://avatars.githubusercontent.com/u/8535905?v=4" width="100" height="100" alt="shaybc"/><br /><sub><b>shaybc</b></sub></a> | <a href="https://github.com/shivamd1810"><img src="https://avatars.githubusercontent.com/u/3871414?v=4" width="100" height="100" alt="shivamd1810"/><br /><sub><b>shivamd1810</b></sub></a> |
| <a href="https://github.com/shohei-ihaya"><img src="https://avatars.githubusercontent.com/u/25131938?v=4" width="100" height="100" alt="shohei-ihaya"/><br /><sub><b>shohei-ihaya</b></sub></a> | <a href="https://github.com/shubhamgupta731"><img src="https://avatars.githubusercontent.com/u/963927?v=4" width="100" height="100" alt="shubhamgupta731"/><br /><sub><b>shubhamgupta731</b></sub></a> | <a href="https://github.com/student20880"><img src="https://avatars.githubusercontent.com/u/74263488?v=4" width="100" height="100" alt="student20880"/><br /><sub><b>student20880</b></sub></a> | <a href="https://github.com/takakoutso"><img src="https://avatars.githubusercontent.com/u/10097886?v=4" width="100" height="100" alt="takakoutso"/><br /><sub><b>takakoutso</b></sub></a> | <a href="https://github.com/user202729"><img src="https://avatars.githubusercontent.com/u/25191436?v=4" width="100" height="100" alt="user202729"/><br /><sub><b>user202729</b></sub></a> | <a href="https://github.com/cdlliuy"><img src="https://avatars.githubusercontent.com/u/17263036?v=4" width="100" height="100" alt="cdlliuy"/><br /><sub><b>cdlliuy</b></sub></a> |
| <a href="https://github.com/zetaloop"><img src="https://avatars.githubusercontent.com/u/36418285?v=4" width="100" height="100" alt="zetaloop"/><br /><sub><b>zetaloop</b></sub></a> | <a href="https://github.com/PretzelVector"><img src="https://avatars.githubusercontent.com/u/95664360?v=4" width="100" height="100" alt="PretzelVector"/><br /><sub><b>PretzelVector</b></sub></a> | <a href="https://github.com/nevermorec"><img src="https://avatars.githubusercontent.com/u/22953064?v=4" width="100" height="100" alt="nevermorec"/><br /><sub><b>nevermorec</b></sub></a> | <a href="https://github.com/jues"><img src="https://avatars.githubusercontent.com/u/95405836?v=4" width="100" height="100" alt="jues"/><br /><sub><b>jues</b></sub></a> | <a href="https://github.com/jwcraig"><img src="https://avatars.githubusercontent.com/u/241358?v=4" width="100" height="100" alt="jwcraig"/><br /><sub><b>jwcraig</b></sub></a> | <a href="https://github.com/kinandan"><img src="https://avatars.githubusercontent.com/u/186135699?v=4" width="100" height="100" alt="kinandan"/><br /><sub><b>kinandan</b></sub></a> |
| <a href="https://github.com/kohii"><img src="https://avatars.githubusercontent.com/u/6891780?v=4" width="100" height="100" alt="kohii"/><br /><sub><b>kohii</b></sub></a> | <a href="https://github.com/lhish"><img src="https://avatars.githubusercontent.com/u/59965910?v=4" width="100" height="100" alt="lhish"/><br /><sub><b>lhish</b></sub></a> | <a href="https://github.com/lightrabbit"><img src="https://avatars.githubusercontent.com/u/1521765?v=4" width="100" height="100" alt="lightrabbit"/><br /><sub><b>lightrabbit</b></sub></a> | <a href="https://github.com/olup"><img src="https://avatars.githubusercontent.com/u/13785588?v=4" width="100" height="100" alt="olup"/><br /><sub><b>olup</b></sub></a> | <a href="https://github.com/mecab"><img src="https://avatars.githubusercontent.com/u/1580772?v=4" width="100" height="100" alt="mecab"/><br /><sub><b>mecab</b></sub></a> | <a href="https://github.com/mlopezr"><img src="https://avatars.githubusercontent.com/u/8202027?v=4" width="100" height="100" alt="mlopezr"/><br /><sub><b>mlopezr</b></sub></a> |
| <a href="https://github.com/moqimoqidea"><img src="https://avatars.githubusercontent.com/u/39821951?v=4" width="100" height="100" alt="moqimoqidea"/><br /><sub><b>moqimoqidea</b></sub></a> | <a href="https://github.com/mosleyit"><img src="https://avatars.githubusercontent.com/u/189396442?v=4" width="100" height="100" alt="mosleyit"/><br /><sub><b>mosleyit</b></sub></a> | <a href="https://github.com/nobu007"><img src="https://avatars.githubusercontent.com/u/8529529?v=4" width="100" height="100" alt="nobu007"/><br /><sub><b>nobu007</b></sub></a> | <a href="https://github.com/oprstchn"><img src="https://avatars.githubusercontent.com/u/16177972?v=4" width="100" height="100" alt="oprstchn"/><br /><sub><b>oprstchn</b></sub></a> | <a href="https://github.com/village-way"><img src="https://avatars.githubusercontent.com/u/11625846?v=4" width="100" height="100" alt="village-way"/><br /><sub><b>village-way</b></sub></a> | <a href="https://github.com/philipnext"><img src="https://avatars.githubusercontent.com/u/81944499?v=4" width="100" height="100" alt="philipnext"/><br /><sub><b>philipnext</b></sub></a> |
| <a href="https://github.com/pokutuna"><img src="https://avatars.githubusercontent.com/u/57545?v=4" width="100" height="100" alt="pokutuna"/><br /><sub><b>pokutuna</b></sub></a> | <a href="https://github.com/thecolorblue"><img src="https://avatars.githubusercontent.com/u/13137?v=4" width="100" height="100" alt="thecolorblue"/><br /><sub><b>thecolorblue</b></sub></a> | <a href="https://github.com/chadgauth"><img src="https://avatars.githubusercontent.com/u/2413356?v=4" width="100" height="100" alt="chadgauth"/><br /><sub><b>chadgauth</b></sub></a> | <a href="https://github.com/CW-B-W"><img src="https://avatars.githubusercontent.com/u/76680670?v=4" width="100" height="100" alt="CW-B-W"/><br /><sub><b>CW-B-W</b></sub></a> | <a href="https://github.com/DarinVerheijke"><img src="https://avatars.githubusercontent.com/u/32957890?v=4" width="100" height="100" alt="DarinVerheijke"/><br /><sub><b>DarinVerheijke</b></sub></a> | <a href="https://github.com/dleen"><img src="https://avatars.githubusercontent.com/u/1297964?v=4" width="100" height="100" alt="dleen"/><br /><sub><b>dleen</b></sub></a> |
| <a href="https://github.com/Deon588"><img src="https://avatars.githubusercontent.com/u/12716437?v=4" width="100" height="100" alt="Deon588"/><br /><sub><b>Deon588</b></sub></a> | <a href="https://github.com/dflatline"><img src="https://avatars.githubusercontent.com/u/60121893?v=4" width="100" height="100" alt="dflatline"/><br /><sub><b>dflatline</b></sub></a> | <a href="https://github.com/dbasclpy"><img src="https://avatars.githubusercontent.com/u/139889137?v=4" width="100" height="100" alt="dbasclpy"/><br /><sub><b>dbasclpy</b></sub></a> | <a href="https://github.com/EamonNerbonne"><img src="https://avatars.githubusercontent.com/u/803518?v=4" width="100" height="100" alt="EamonNerbonne"/><br /><sub><b>EamonNerbonne</b></sub></a> | <a href="https://github.com/edwin-truthsearch-io"><img src="https://avatars.githubusercontent.com/u/211044285?v=4" width="100" height="100" alt="edwin-truthsearch-io"/><br /><sub><b>edwin-truthsearch-io</b></sub></a> | <a href="https://github.com/ertan2002"><img src="https://avatars.githubusercontent.com/u/1535195?v=4" width="100" height="100" alt="ertan2002"/><br /><sub><b>ertan2002</b></sub></a> |
| <a href="https://github.com/linegel"><img src="https://avatars.githubusercontent.com/u/1746296?v=4" width="100" height="100" alt="linegel"/><br /><sub><b>linegel</b></sub></a> | <a href="https://github.com/celestial-vault"><img src="https://avatars.githubusercontent.com/u/58194240?v=4" width="100" height="100" alt="celestial-vault"/><br /><sub><b>celestial-vault</b></sub></a> | <a href="https://github.com/ExactDoug"><img src="https://avatars.githubusercontent.com/u/158221557?v=4" width="100" height="100" alt="ExactDoug"/><br /><sub><b>ExactDoug</b></sub></a> | <a href="https://github.com/pfitz"><img src="https://avatars.githubusercontent.com/u/3062911?v=4" width="100" height="100" alt="pfitz"/><br /><sub><b>pfitz</b></sub></a> | <a href="https://github.com/DeXtroTip"><img src="https://avatars.githubusercontent.com/u/21011087?v=4" width="100" height="100" alt="DeXtroTip"/><br /><sub><b>DeXtroTip</b></sub></a> | <a href="https://github.com/adambrand"><img src="https://avatars.githubusercontent.com/u/36556838?v=4" width="100" height="100" alt="adambrand"/><br /><sub><b>adambrand</b></sub></a> |
| <a href="https://github.com/AMHesch"><img src="https://avatars.githubusercontent.com/u/4777192?v=4" width="100" height="100" alt="AMHesch"/><br /><sub><b>AMHesch</b></sub></a> | <a href="https://github.com/adamhill"><img src="https://avatars.githubusercontent.com/u/188638?v=4" width="100" height="100" alt="adamhill"/><br /><sub><b>adamhill</b></sub></a> | <a href="https://github.com/adamwlarson"><img src="https://avatars.githubusercontent.com/u/1392315?v=4" width="100" height="100" alt="adamwlarson"/><br /><sub><b>adamwlarson</b></sub></a> | <a href="https://github.com/adilhafeez"><img src="https://avatars.githubusercontent.com/u/13196462?v=4" width="100" height="100" alt="adilhafeez"/><br /><sub><b>adilhafeez</b></sub></a> | <a href="https://github.com/nexon33"><img src="https://avatars.githubusercontent.com/u/47557266?v=4" width="100" height="100" alt="nexon33"/><br /><sub><b>nexon33</b></sub></a> | <a href="https://github.com/alarno"><img src="https://avatars.githubusercontent.com/u/4355547?v=4" width="100" height="100" alt="alarno"/><br /><sub><b>alarno</b></sub></a> |
| <a href="https://github.com/HadesArchitect"><img src="https://avatars.githubusercontent.com/u/1742301?v=4" width="100" height="100" alt="HadesArchitect"/><br /><sub><b>HadesArchitect</b></sub></a> | <a href="https://github.com/alasano"><img src="https://avatars.githubusercontent.com/u/14372930?v=4" width="100" height="100" alt="alasano"/><br /><sub><b>alasano</b></sub></a> | <a href="https://github.com/andreastempsch"><img src="https://avatars.githubusercontent.com/u/117991125?v=4" width="100" height="100" alt="andreastempsch"/><br /><sub><b>andreastempsch</b></sub></a> | <a href="https://github.com/andrewshu2000"><img src="https://avatars.githubusercontent.com/u/57741937?v=4" width="100" height="100" alt="andrewshu2000"/><br /><sub><b>andrewshu2000</b></sub></a> | <a href="https://github.com/AntiMoron"><img src="https://avatars.githubusercontent.com/u/6587734?v=4" width="100" height="100" alt="AntiMoron"/><br /><sub><b>AntiMoron</b></sub></a> | <a href="https://github.com/atlasgong"><img src="https://avatars.githubusercontent.com/u/68199735?v=4" width="100" height="100" alt="atlasgong"/><br /><sub><b>atlasgong</b></sub></a> |
| <a href="https://github.com/Atlogit"><img src="https://avatars.githubusercontent.com/u/86947554?v=4" width="100" height="100" alt="Atlogit"/><br /><sub><b>Atlogit</b></sub></a> | <a href="https://github.com/benashby"><img src="https://avatars.githubusercontent.com/u/1023089?v=4" width="100" height="100" alt="benashby"/><br /><sub><b>benashby</b></sub></a> | <a href="https://github.com/bogdan0083"><img src="https://avatars.githubusercontent.com/u/7077307?v=4" width="100" height="100" alt="bogdan0083"/><br /><sub><b>bogdan0083</b></sub></a> | <a href="https://github.com/hesara"><img src="https://avatars.githubusercontent.com/u/1335918?v=4" width="100" height="100" alt="hesara"/><br /><sub><b>hesara</b></sub></a> | <a href="https://github.com/marvijo-code"><img src="https://avatars.githubusercontent.com/u/82562019?v=4" width="100" height="100" alt="marvijo-code"/><br /><sub><b>marvijo-code</b></sub></a> | <a href="https://github.com/mollux"><img src="https://avatars.githubusercontent.com/u/3983285?v=4" width="100" height="100" alt="mollux"/><br /><sub><b>mollux</b></sub></a> |
| <a href="https://github.com/ecmasx"><img src="https://avatars.githubusercontent.com/u/135958728?v=4" width="100" height="100" alt="ecmasx"/><br /><sub><b>ecmasx</b></sub></a> | <a href="https://github.com/kvokka"><img src="https://avatars.githubusercontent.com/u/15954013?v=4" width="100" height="100" alt="kvokka"/><br /><sub><b>kvokka</b></sub></a> | <a href="https://github.com/mohammad154"><img src="https://avatars.githubusercontent.com/u/77232207?v=4" width="100" height="100" alt="mohammad154"/><br /><sub><b>mohammad154</b></sub></a> | <a href="https://github.com/Naam"><img src="https://avatars.githubusercontent.com/u/2959826?v=4" width="100" height="100" alt="Naam"/><br /><sub><b>Naam</b></sub></a> | <a href="https://github.com/niteshbalusu11"><img src="https://avatars.githubusercontent.com/u/84944042?v=4" width="100" height="100" alt="niteshbalusu11"/><br /><sub><b>niteshbalusu11</b></sub></a> | <a href="https://github.com/OlegOAndreev"><img src="https://avatars.githubusercontent.com/u/149705?v=4" width="100" height="100" alt="OlegOAndreev"/><br /><sub><b>OlegOAndreev</b></sub></a> |
| <a href="https://github.com/PaperBoardOfficial"><img src="https://avatars.githubusercontent.com/u/151846514?v=4" width="100" height="100" alt="PaperBoardOfficial"/><br /><sub><b>PaperBoardOfficial</b></sub></a> | <a href="https://github.com/Sarke"><img src="https://avatars.githubusercontent.com/u/2719310?v=4" width="100" height="100" alt="Sarke"/><br /><sub><b>Sarke</b></sub></a> | <a href="https://github.com/R-omk"><img src="https://avatars.githubusercontent.com/u/1633879?v=4" width="100" height="100" alt="R-omk"/><br /><sub><b>R-omk</b></sub></a> | <a href="https://github.com/SECKainersdorfer"><img src="https://avatars.githubusercontent.com/u/155164204?v=4" width="100" height="100" alt="SECKainersdorfer"/><br /><sub><b>SECKainersdorfer</b></sub></a> | <a href="https://github.com/RandalSchwartz"><img src="https://avatars.githubusercontent.com/u/6342?v=4" width="100" height="100" alt="RandalSchwartz"/><br /><sub><b>RandalSchwartz</b></sub></a> | <a href="https://github.com/RSO"><img src="https://avatars.githubusercontent.com/u/139663?v=4" width="100" height="100" alt="RSO"/><br /><sub><b>RSO</b></sub></a> |
| <a href="https://github.com/01Rian"><img src="https://avatars.githubusercontent.com/u/109045233?v=4" width="100" height="100" alt="01Rian"/><br /><sub><b>01Rian</b></sub></a> | <a href="https://github.com/samsilveira"><img src="https://avatars.githubusercontent.com/u/109295696?v=4" width="100" height="100" alt="samsilveira"/><br /><sub><b>samsilveira</b></sub></a> | <a href="https://github.com/jdilla1277"><img src="https://avatars.githubusercontent.com/u/89669079?v=4" width="100" height="100" alt="jdilla1277"/><br /><sub><b>jdilla1277</b></sub></a> | <a href="https://github.com/Jdo300"><img src="https://avatars.githubusercontent.com/u/67338327?v=4" width="100" height="100" alt="Jdo300"/><br /><sub><b>Jdo300</b></sub></a> | <a href="https://github.com/Fovty"><img src="https://avatars.githubusercontent.com/u/38868829?v=4" width="100" height="100" alt="Fovty"/><br /><sub><b>Fovty</b></sub></a> | <a href="https://github.com/snova-jorgep"><img src="https://avatars.githubusercontent.com/u/166410071?v=4" width="100" height="100" alt="snova-jorgep"/><br /><sub><b>snova-jorgep</b></sub></a> |
| <a href="https://github.com/joshualipman123"><img src="https://avatars.githubusercontent.com/u/179280689?v=4" width="100" height="100" alt="joshualipman123"/><br /><sub><b>joshualipman123</b></sub></a> | <a href="https://github.com/Juice10"><img src="https://avatars.githubusercontent.com/u/4106?v=4" width="100" height="100" alt="Juice10"/><br /><sub><b>Juice10</b></sub></a> | <a href="https://github.com/AyazKaan"><img src="https://avatars.githubusercontent.com/u/92330562?v=4" width="100" height="100" alt="AyazKaan"/><br /><sub><b>AyazKaan</b></sub></a> | <a href="https://github.com/ksze"><img src="https://avatars.githubusercontent.com/u/381556?v=4" width="100" height="100" alt="ksze"/><br /><sub><b>ksze</b></sub></a> | <a href="https://github.com/KevinZhao"><img src="https://avatars.githubusercontent.com/u/1167525?v=4" width="100" height="100" alt="KevinZhao"/><br /><sub><b>KevinZhao</b></sub></a> | <a href="https://github.com/kevinvandijk"><img src="https://avatars.githubusercontent.com/u/223256?v=4" width="100" height="100" alt="kevinvandijk"/><br /><sub><b>kevinvandijk</b></sub></a> |
| <a href="https://github.com/Rexarrior"><img src="https://avatars.githubusercontent.com/u/25753287?v=4" width="100" height="100" alt="Rexarrior"/><br /><sub><b>Rexarrior</b></sub></a> | <a href="https://github.com/shtse8"><img src="https://avatars.githubusercontent.com/u/8020099?v=4" width="100" height="100" alt="shtse8"/><br /><sub><b>shtse8</b></sub></a> | <a href="https://github.com/libertyteeth"><img src="https://avatars.githubusercontent.com/u/32841567?v=4" width="100" height="100" alt="libertyteeth"/><br /><sub><b>libertyteeth</b></sub></a> | <a href="https://github.com/monkeyDluffy6017"><img src="https://avatars.githubusercontent.com/u/9354193?v=4" width="100" height="100" alt="monkeyDluffy6017"/><br /><sub><b>monkeyDluffy6017</b></sub></a> | <a href="https://github.com/mamertofabian"><img src="https://avatars.githubusercontent.com/u/7698436?v=4" width="100" height="100" alt="mamertofabian"/><br /><sub><b>mamertofabian</b></sub></a> | <a href="https://github.com/markijbema"><img src="https://avatars.githubusercontent.com/u/624143?v=4" width="100" height="100" alt="markijbema"/><br /><sub><b>markijbema</b></sub></a> |
<!-- END CONTRIBUTORS SECTION -->
## License
[Apache 2.0 © 2026 Roo Code, Inc.](./LICENSE)
[Apache 2.0 © 2025 Roo Code, Inc.](./LICENSE)
---
**Enjoy Roo Code!** Whether you keep it on a short leash or let it roam autonomously, we cant wait to see what you build. If you have questions or feature ideas, drop by our [Reddit community](https://www.reddit.com/r/RooCode/) or [Discord](https://discord.gg/roocode). Happy coding!

View file

@ -1,391 +0,0 @@
# Changelog
All notable changes to the `@roo-code/cli` package will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.1.17] - 2026-03-04
### Added
- **Custom Session ID Support**: New `--create-with-session-id` flag allows specifying a custom UUID session ID when creating tasks. Session IDs are now validated as UUIDs for both create and resume operations, as well as for `start.taskId` in stdin-stream mode.
### Tests
- Added integration coverage for create+resume loading the correct session.
## [0.1.16] - 2026-03-04
### Added
- **Custom Shell Selection**: New `--terminal-shell` flag to specify which shell to use for inline command execution. The shell path is validated at the CLI layer and passed through the standard settings mechanism.
### Tests
- Added integration coverage for stdin stream routing and race invariants.
## [0.1.15] - 2026-03-03
### Fixed
- **Follow-up Routing for Completion Asks**: Fixed routing of follow-up messages when the agent asks for clarification (ask_followup_question) in stdin-stream mode. Messages sent after a completion ask are now correctly delivered to the agent instead of being queued.
## [0.1.14] - 2026-03-03
### Fixed
- **Command Output Streaming**: Ensure full command output is streamed before the done event is emitted, preventing truncated output in stdin-stream mode.
## [0.1.13] - 2026-03-02
### Added
- **Skills as Slash Commands**: Skills are now exposed as slash commands, so you can invoke skill workflows directly from command-style input.
- **Skill Fallback Execution**: When a slash command does not match a command file but matches a skill slug, the CLI can resolve and execute that skill path.
### Changed
- **Slash Command Resolution Priority**: Command precedence is preserved, with skill fallback only used when no matching slash command is found.
### Tests
- Added and updated tests for slash command + skill fallback behavior, including command precedence and duplicate skill-slug handling.
## [0.1.12] - 2026-03-02
### Fixed
- **Command Timeout Handling**: CLI runtime now correctly ignores model-provided background timeouts for commands, ensuring command lifetime is governed solely by the `--timeout` setting.
## [0.1.11] - 2026-03-02
### Added
- **Image Support in Stdin Stream**: The `start` and `message` commands in stdin-stream mode now support an optional `images` field (array of base64 data URIs) to attach images to prompts.
### Fixed
- **Upgrade Version Detection**: Fixed version detection in the `upgrade` command to correctly identify when updates are available.
## [0.1.10] - 2026-03-02
### Added
- **Command Exit Code in Events**: The `tool_result` event for command executions now includes an `exitCode` field, allowing CLI consumers to programmatically distinguish between successful and failed command executions without parsing output text.
## [0.1.9] - 2026-03-02
### Fixed
- **Stdin Stream Cancel Race**: Fixed a race condition during startup cancellation in stdin-stream mode that could cause unexpected behavior when canceling tasks immediately after starting them.
### Tests
- **Integration Test Suite**: Added comprehensive integration test suite for stdin-stream protocol covering cancel, followup, multi-message queue, and shutdown scenarios.
## [0.1.8] - 2026-03-02
### Changed
- **Command Execution Timeout**: Increased timeout for command execution to improve reliability for long-running operations.
### Fixed
- **Stdin Stream Queue Handling**: Fixed stdin stream queued messages and command output streaming to ensure messages are properly processed.
## [0.1.7] - 2026-03-01
### Fixed
- **Stdin Stream Control Flow**: Gracefully handle control-flow errors in stdin-stream mode to prevent unexpected crashes during cancellation and shutdown sequences.
### Changed
- **Type Definitions**: Refactored and simplified JSON event type definitions for better type safety.
## [0.1.6] - 2026-02-27
### Added
- **Consecutive Mistake Limit**: New `--mistake-limit` flag to configure the maximum number of consecutive mistakes before the agent pauses for intervention.
### Changed
- **Workspace-Scoped Sessions**: The `list sessions` command and `--resume` flag now only show and resume sessions from the current workspace directory.
### Fixed
- **Task Configuration Forwarding**: Task configuration (custom modes, disabled tools, etc.) passed via the stdin-prompt-stream protocol is now correctly forwarded to the extension host instead of being silently dropped.
- **Stream Error Recovery**: Improved recovery from streaming errors to prevent task interruption.
## [0.1.5] - 2026-02-26
### Added
- **Session History**: New `list sessions` subcommand to view recent CLI sessions with task IDs, timestamps, and initial prompts.
- **Session Resume**: New `--resume <taskId>` flag to continue a previous session from where it left off.
- **Upgrade Command**: New `upgrade` command to check for and install the latest CLI version.
## [0.1.4] - 2026-02-26
### Fixed
- **Exception Handling**: Improved recovery from unhandled exceptions in the CLI to prevent unexpected crashes.
## [0.1.3] - 2026-02-25
### Fixed
- **Task Resumption**: Fixed an issue where resuming a previously suspended task could fail due to state initialization timing in the extension host.
## [0.1.2] - 2026-02-25
### Changed
- **Streaming Deltas**: Tool use ask messages (command, tool, mcp) are now streamed as structured deltas instead of full snapshots in json-event-emitter for improved efficiency.
- **Task ID Propagation**: Task ID is now generated upfront and propagated through runTask/createTask so currentTaskId is available in extension state immediately.
- **Custom Tools**: Enabled customTools experiment in extension host.
### Fixed
- **Cancel Recovery**: Wait for resumable state after cancel before processing follow-up messages to prevent race conditions in stdin-stream.
- **Custom Tool Schema**: Provide valid empty JSON Schema for custom tools without parameters to fix strict-mode API validation.
- **Path Handling**: Skip paths outside cwd in RooProtectedController to avoid RangeError.
- **Retry Handling**: Silently handle abort during exponential backoff retry countdown.
- Fixed spelling/grammar and casing inconsistencies.
### Added
- **Telemetry Control**: Added `ROO_CODE_DISABLE_TELEMETRY=1` environment variable to disable cloud telemetry.
## [0.1.1] - 2026-02-24
### Added
- **Roo Model Warmup**: When configured with the Roo provider, the CLI now proactively fetches and warms the model list during activation so that model information is available before the first prompt is sent. The warmup has a 10s timeout and failures are logged only in debug mode.
- **Unbound Provider**: Added Unbound as an available provider option.
## [0.1.0] - 2026-02-19
### Added
- **NDJSON Stdin Protocol**: Overhauled the stdin prompt stream from raw text lines to a structured NDJSON command protocol (`start`/`message`/`cancel`/`ping`/`shutdown`) with requestId correlation, ack/done/error lifecycle events, and queue telemetry. See [`stdin-stream.ts`](src/ui/stdin-stream.ts) for implementation.
- **List Subcommands**: New `list` subcommands (`commands`, `modes`, `models`) for programmatic discovery of available CLI capabilities.
- **Shared Utilities**: Added `isRecord` guard utility for improved type safety.
### Changed
- **Modularized Architecture**: Extracted stdin stream logic from `run.ts` into dedicated [`stdin-stream.ts`](src/ui/stdin-stream.ts) module for better code organization and maintainability.
### Fixed
- Fixed a bug in `Task.ts` affecting CLI operation.
## [0.0.55] - 2026-02-17
### Fixed
- **Stdin Stream Mode**: Fixed issue where new tasks were incorrectly being created in stdin-prompt-stream mode. The mode now properly reuses the existing task for subsequent prompts instead of creating new tasks.
## [0.0.54] - 2026-02-15
### Added
- **Stdin Stream Mode**: New `stdin-prompt-stream` mode that reads prompts from stdin, allowing batch processing and piping multiple tasks. Each line of stdin is processed as a separate prompt with streaming JSON output. See [`stdin-prompt-stream.ts`](src/ui/stdin-prompt-stream.ts) for implementation.
### Fixed
- Fixed JSON emitter state not being cleared between tasks in stdin-prompt-stream mode
- Fixed inconsistent user role for prompt echo partials in stream-json mode
## [0.0.53] - 2026-02-12
### Changed
- **Auto-Approve by Default**: The CLI now auto-approves all actions (tools, commands, browser, MCP) by default. Followup questions auto-select the first suggestion after a 60-second timeout.
- **New `--require-approval` Flag**: Replaced `-y`/`--yes`/`--dangerously-skip-permissions` flags with a new `-a, --require-approval` flag for users who want manual approval prompts before actions execute.
### Fixed
- Spamming the escape key to cancel a running task no longer crashes the cli.
## [0.0.52] - 2026-02-09
### Added
- **Linux Support**: Added support for `linux-arm64`.
## [0.0.51] - 2026-02-06
### Changed
- **Default Model Update**: Changed the default model from Opus 4.5 to Opus 4.6 for improved performance and capabilities
## [0.0.50] - 2026-02-05
### Added
- **Linux Support**: The CLI now supports Linux platforms in addition to macOS
- **Roo Provider API Key Support**: Allow `--api-key` flag and `ROO_API_KEY` environment variable for the roo provider instead of requiring cloud auth token
- **Exit on Error**: New `--exit-on-error` flag to exit immediately on API request errors instead of retrying, useful for CI/CD pipelines
### Changed
- **Improved Dev Experience**: Dev scripts now use `tsx` for running directly from source without building first
- **Path Resolution Fixes**: Fixed path resolution in [`version.ts`](src/lib/utils/version.ts), [`extension.ts`](src/lib/utils/extension.ts), and [`extension-host.ts`](src/agent/extension-host.ts) to work from both source and bundled locations
- **Debug Logging**: Debug log file (`~/.roo/cli-debug.log`) is now disabled by default unless `--debug` flag is passed
- Updated README with complete environment variable table and dev workflow documentation
### Fixed
- Corrected example in install script
### Removed
- Dropped macOS 13 support
## [0.0.49] - 2026-01-18
### Added
- **Output Format Options**: New `--output-format` flag to control CLI output format for scripting and automation:
- `text` (default) - Human-readable interactive output
- `json` - Single JSON object with all events and final result at task completion
- `stream-json` - NDJSON (newline-delimited JSON) for real-time streaming of events
- See [`json-events.ts`](src/types/json-events.ts) for the complete event schema
- New [`JsonEventEmitter`](src/agent/json-event-emitter.ts) for structured output generation
## [0.0.48] - 2026-01-17
### Changed
- Simplified authentication callback flow by using HTTP redirects instead of POST requests with CORS headers for improved browser compatibility
## [0.0.47] - 2026-01-17
### Added
- **Workspace flag**: New `-w, --workspace <path>` option to specify a custom workspace directory instead of using the current working directory
- **Oneshot mode**: New `--oneshot` flag to exit upon task completion, useful for scripting and automation (can also be saved in settings via [`CliSettings.oneshot`](src/types/types.ts))
### Changed
- Skip onboarding flow when a provider is explicitly specified via `--provider` flag or saved in settings
- Unified permission flags: Combined approval-skipping flags into a single option for Claude Code-like CLI compatibility
- Improved Roo Code Router authentication flow and error messaging
### Fixed
- Removed unnecessary timeout that could cause issues with long-running tasks
- Fixed authentication token validation for Roo Code Router provider
## [0.0.45] - 2026-01-08
### Changed
- **Major Refactor**: Extracted ~1400 lines from [`App.tsx`](src/ui/App.tsx) into reusable hooks and utilities for better maintainability:
- [`useExtensionHost`](src/ui/hooks/useExtensionHost.ts) - Extension host connection and lifecycle management
- [`useMessageHandlers`](src/ui/hooks/useMessageHandlers.ts) - Message processing and state updates
- [`useTaskSubmit`](src/ui/hooks/useTaskSubmit.ts) - Task submission logic
- [`useGlobalInput`](src/ui/hooks/useGlobalInput.ts) - Global keyboard shortcut handling
- [`useFollowupCountdown`](src/ui/hooks/useFollowupCountdown.ts) - Auto-approval countdown logic
- [`useFocusManagement`](src/ui/hooks/useFocusManagement.ts) - Input focus state management
- [`usePickerHandlers`](src/ui/hooks/usePickerHandlers.ts) - Picker component event handling
- [`uiStateStore`](src/ui/stores/uiStateStore.ts) - UI-specific state (showExitHint, countdown, etc.)
- Tool data utilities ([`extractToolData`](src/ui/utils/toolDataUtils.ts), `formatToolOutput`, etc.)
- [`HorizontalLine`](src/ui/components/HorizontalLine.tsx) component
- **Performance Optimizations**:
- Added RAF-style scroll throttling to reduce state updates
- Stabilized `useExtensionHost` hook return values with `useCallback`/`useMemo`
- Added streaming message debouncing to batch rapid partial updates
- Added shallow array equality checks to prevent unnecessary re-renders
- Simplified [`ModeTool`](src/ui/components/tools/ModeTool.tsx) layout to horizontal with mode suffix
- Simplified logging by removing verbose debug output and adding first/last partial message logging pattern
- Updated Nerd Font icon codepoints in [`Icon`](src/ui/components/Icon.tsx) component
### Added
- `#` shortcut in help trigger for quick access to task history autocomplete
### Fixed
- Fixed a crash in message handling
- Added protected file warning in tool approval prompts
- Enabled `alwaysAllowWriteProtected` for non-interactive mode
### Removed
- Removed unused `renderLogger.ts` utility file
### Tests
- Updated extension-host tests to expect `[Tool Request]` format
- Updated Icon tests to expect single-char Nerd Font icons
## [0.0.44] - 2026-01-08
### Added
- **Tool Renderer Components**: Specialized renderers for displaying tool outputs with optimized formatting for each tool type. Each renderer provides a focused view of its data structure.
- [`FileReadTool`](src/ui/components/tools/FileReadTool.tsx) - Display file read operations with syntax highlighting
- [`FileWriteTool`](src/ui/components/tools/FileWriteTool.tsx) - Show file write/edit operations with diff views
- [`SearchTool`](src/ui/components/tools/SearchTool.tsx) - Render search results with context
- [`CommandTool`](src/ui/components/tools/CommandTool.tsx) - Display command execution with output
- [`BrowserTool`](src/ui/components/tools/BrowserTool.tsx) - Show browser automation actions
- [`ModeTool`](src/ui/components/tools/ModeTool.tsx) - Display mode switching operations
- [`CompletionTool`](src/ui/components/tools/CompletionTool.tsx) - Show task completion status
- [`GenericTool`](src/ui/components/tools/GenericTool.tsx) - Fallback renderer for other tools
- **History Trigger**: New `#` trigger for task history autocomplete with fuzzy search support. Type `#` at the start of a line to browse and resume previous tasks.
- [`HistoryTrigger.tsx`](src/ui/components/autocomplete/triggers/HistoryTrigger.tsx) - Trigger implementation with fuzzy filtering
- Shows task status, mode, and relative timestamps
- Supports keyboard navigation for quick task selection
- **Release Confirmation Prompt**: The release script now prompts for confirmation before creating a release.
### Fixed
- Task history picker selection and navigation issues
- Mode switcher keyboard handling bug
### Changed
- Reorganized test files into `__tests__` directories for better project structure
- Refactored utility modules into dedicated `utils/` directory
## [0.0.43] - 2026-01-07
### Added
- **Toast Notification System**: New toast notifications for user feedback with support for info, success, warning, and error types. Toasts auto-dismiss after a configurable duration and are managed via Zustand store.
- New [`ToastDisplay`](src/ui/components/ToastDisplay.tsx) component for rendering toast messages
- New [`useToast`](src/ui/hooks/useToast.ts) hook for managing toast state and displaying notifications
- **Global Input Sequences Registry**: Centralized system for handling keyboard shortcuts at the application level, preventing conflicts with input components.
- New [`globalInputSequences.ts`](src/ui/utils/globalInputSequences.ts) utility module
- Support for Kitty keyboard protocol (CSI u encoding) for better terminal compatibility
- Built-in sequences for `Ctrl+C` (exit) and `Ctrl+M` (mode cycling)
- **Local Tarball Installation**: The install script now supports installing from a local tarball via the `ROO_LOCAL_TARBALL` environment variable, useful for offline installation or testing pre-release builds.
### Changed
- **MultilineTextInput**: Updated to respect global input sequences, preventing the component from consuming shortcuts meant for application-level handling.
### Tests
- Added comprehensive tests for the toast notification system
- Added tests for global input sequence matching
## [0.0.42] - 2025-01-07
The cli is alive!

View file

@ -1,240 +0,0 @@
# @roo-code/cli
Command Line Interface for Roo Code - Run the Roo Code agent from the terminal without VSCode.
## Overview
This CLI uses the `@roo-code/vscode-shim` package to provide a VSCode API compatibility layer, allowing the main Roo Code extension to run in a Node.js environment.
## Installation
### Quick Install (Recommended)
Install the Roo Code CLI with a single command:
```bash
curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh
```
**Requirements:**
- Node.js 20 or higher
- macOS Apple Silicon (M1/M2/M3/M4) or Linux x64
**Custom installation directory:**
```bash
ROO_INSTALL_DIR=/opt/roo-code ROO_BIN_DIR=/usr/local/bin curl -fsSL ... | sh
```
**Install a specific version:**
```bash
ROO_VERSION=0.1.0 curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh
```
### Updating
Re-run the install script to update to the latest version:
```bash
curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh
```
Or run:
```bash
roo upgrade
```
### Uninstalling
```bash
rm -rf ~/.roo/cli ~/.local/bin/roo
```
## Usage
### Interactive Mode (Default)
By default, the CLI auto-approves actions and runs in interactive TUI mode:
```bash
export OPENROUTER_API_KEY=sk-or-v1-...
roo "What is this project?" -w ~/Documents/my-project
```
You can also run without a prompt and enter it interactively in TUI mode:
```bash
roo -w ~/Documents/my-project
```
In interactive mode:
- Tool executions are auto-approved
- Commands are auto-approved
- Followup questions show suggestions with a 60-second timeout, then auto-select the first suggestion
- Browser and MCP actions are auto-approved
### Approval-Required Mode (`--require-approval`)
If you want manual approval prompts, enable approval-required mode:
```bash
roo "Refactor the utils.ts file" --require-approval -w ~/Documents/my-project
```
In approval-required mode:
- Tool, command, browser, and MCP actions prompt for yes/no approval
- Followup questions wait for manual input (no auto-timeout)
### Print Mode (`--print`)
Use `--print` for non-interactive execution and machine-readable output:
```bash
# Prompt is required
roo --print "Summarize this repository"
# Create a new task with a specific session ID (UUID)
roo --print --create-with-session-id 018f7fc8-7c96-7f7c-98aa-2ec4ff7f6d87 "Summarize this repository"
```
### Stdin Stream Mode (`--stdin-prompt-stream`)
For programmatic control (one process, multiple prompts), use `--stdin-prompt-stream` with `--print`.
Send NDJSON commands via stdin:
```bash
printf '{"command":"start","requestId":"1","prompt":"1+1=?"}\n' | roo --print --stdin-prompt-stream --output-format stream-json
# Optional: provide taskId per start command
printf '{"command":"start","requestId":"1","taskId":"018f7fc8-7c96-7f7c-98aa-2ec4ff7f6d87","prompt":"1+1=?"}\n' | roo --print --stdin-prompt-stream --output-format stream-json
```
## Options
| Option | Description | Default |
| --------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------- |
| `[prompt]` | Your prompt (positional argument, optional) | None |
| `--prompt-file <path>` | Read prompt from a file instead of command line argument | None |
| `--create-with-session-id <session-id>` | Create a new task using the provided session ID (UUID) | None |
| `-w, --workspace <path>` | Workspace path to operate in | Current directory |
| `-p, --print` | Print response and exit (non-interactive mode) | `false` |
| `--stdin-prompt-stream` | Read NDJSON control commands from stdin (requires `--print`) | `false` |
| `-e, --extension <path>` | Path to the extension bundle directory | Auto-detected |
| `-d, --debug` | Enable debug output (includes detailed debug information, prompts, paths, etc) | `false` |
| `-a, --require-approval` | Require manual approval before actions execute | `false` |
| `-k, --api-key <key>` | API key for the LLM provider | From env var |
| `--provider <provider>` | API provider (anthropic, openai, openrouter, etc.) | `openrouter` |
| `-m, --model <model>` | Model to use | `anthropic/claude-opus-4.6` |
| `--mode <mode>` | Mode to start in (code, architect, ask, debug, etc.) | `code` |
| `--terminal-shell <path>` | Absolute shell path for inline terminal command execution | Auto-detected shell |
| `-r, --reasoning-effort <effort>` | Reasoning effort level (unspecified, disabled, none, minimal, low, medium, high, xhigh) | `medium` |
| `--consecutive-mistake-limit <n>` | Consecutive error/repetition limit before guidance prompt (`0` disables the limit) | `10` |
| `--ephemeral` | Run without persisting state (uses temporary storage) | `false` |
| `--oneshot` | Exit upon task completion | `false` |
| `--output-format <format>` | Output format with `--print`: `text`, `json`, or `stream-json` | `text` |
## Environment Variables
The CLI will look for API keys in environment variables if not provided via `--api-key`:
| Provider | Environment Variable |
| ----------------- | --------------------------- |
| anthropic | `ANTHROPIC_API_KEY` |
| openai-native | `OPENAI_API_KEY` |
| openrouter | `OPENROUTER_API_KEY` |
| gemini | `GOOGLE_API_KEY` |
| vercel-ai-gateway | `VERCEL_AI_GATEWAY_API_KEY` |
## Architecture
```
┌─────────────────┐
│ CLI Entry │
│ (index.ts) │
└────────┬────────┘
┌─────────────────┐
│ ExtensionHost │
│ (extension- │
│ host.ts) │
└────────┬────────┘
┌────┴────┐
│ │
▼ ▼
┌───────┐ ┌──────────┐
│vscode │ │Extension │
│-shim │ │ Bundle │
└───────┘ └──────────┘
```
## How It Works
1. **CLI Entry Point** (`index.ts`): Parses command line arguments and initializes the ExtensionHost
2. **ExtensionHost** (`extension-host.ts`):
- Creates a VSCode API mock using `@roo-code/vscode-shim`
- Intercepts `require('vscode')` to return the mock
- Loads and activates the extension bundle
- Manages bidirectional message flow
3. **Message Flow**:
- CLI → Extension: `emit("webviewMessage", {...})`
- Extension → CLI: `emit("extensionWebviewMessage", {...})`
## Development
```bash
# Run directly from source (no build required)
pnpm dev --provider openrouter --api-key $OPENROUTER_API_KEY --print "Hello"
# Run tests
pnpm test
# Type checking
pnpm check-types
# Linting
pnpm lint
```
## Releasing
Official releases are created via the GitHub Actions workflow at `.github/workflows/cli-release.yml`.
To trigger a release:
1. Go to **Actions** → **CLI Release**
2. Click **Run workflow**
3. Optionally specify a version (defaults to `package.json` version)
4. Click **Run workflow**
The workflow will:
1. Build the CLI on all platforms (macOS Apple Silicon, Linux x64)
2. Create platform-specific tarballs with bundled ripgrep
3. Verify each tarball
4. Create a GitHub release with all tarballs attached
### Local Builds
For local development and testing, use the build script:
```bash
# Build tarball for your current platform
./apps/cli/scripts/build.sh
# Build and install locally
./apps/cli/scripts/build.sh --install
# Fast build (skip verification)
./apps/cli/scripts/build.sh --skip-verify
```

View file

@ -1,356 +0,0 @@
# CLI Agent Loop
This document explains how the Roo Code CLI detects and tracks the agent loop state.
## Overview
The CLI needs to know when the agent is:
- **Running** (actively processing)
- **Streaming** (receiving content from the API)
- **Waiting for input** (needs user approval or answer)
- **Idle** (task completed or failed)
This is accomplished by analyzing the messages the extension sends to the client.
## The Message Model
All agent activity is communicated through **ClineMessages** - a stream of timestamped messages that represent everything the agent does.
### Message Structure
```typescript
interface ClineMessage {
ts: number // Unique timestamp identifier
type: "ask" | "say" // Message category
ask?: ClineAsk // Specific ask type (when type="ask")
say?: ClineSay // Specific say type (when type="say")
text?: string // Message content
partial?: boolean // Is this message still streaming?
}
```
### Two Types of Messages
| Type | Purpose | Blocks Agent? |
| ------- | ---------------------------------------------- | ------------- |
| **say** | Informational - agent is telling you something | No |
| **ask** | Interactive - agent needs something from you | Usually yes |
## The Key Insight
> **The agent loop stops whenever the last message is an `ask` type (with `partial: false`).**
The specific `ask` value tells you exactly what the agent needs.
## Ask Categories
The CLI categorizes asks into four groups:
### 1. Interactive Asks → `WAITING_FOR_INPUT` state
These require user action to continue:
| Ask Type | What It Means | Required Response |
| ----------------------- | --------------------------------- | ----------------- |
| `tool` | Wants to edit/create/delete files | Approve or Reject |
| `command` | Wants to run a terminal command | Approve or Reject |
| `followup` | Asking a question | Text answer |
| `browser_action_launch` | Wants to use the browser | Approve or Reject |
| `use_mcp_server` | Wants to use an MCP server | Approve or Reject |
### 2. Idle Asks → `IDLE` state
These indicate the task has stopped:
| Ask Type | What It Means | Response Options |
| ------------------------------- | --------------------------- | --------------------------- |
| `completion_result` | Task completed successfully | New task or feedback |
| `api_req_failed` | API request failed | Retry or new task |
| `mistake_limit_reached` | Too many errors | Continue anyway or new task |
| `auto_approval_max_req_reached` | Auto-approval limit hit | Continue manually or stop |
| `resume_completed_task` | Viewing completed task | New task |
### 3. Resumable Asks → `RESUMABLE` state
| Ask Type | What It Means | Response Options |
| ------------- | ------------------------- | ----------------- |
| `resume_task` | Task paused mid-execution | Resume or abandon |
### 4. Non-Blocking Asks → `RUNNING` state
| Ask Type | What It Means | Response Options |
| ---------------- | ------------------ | ----------------- |
| `command_output` | Command is running | Continue or abort |
## Streaming Detection
The agent is **streaming** when:
1. **`partial: true`** on the last message, OR
2. **An `api_req_started` message exists** with `cost: undefined` in its text field
```typescript
// Streaming detection pseudocode
function isStreaming(messages) {
const lastMessage = messages.at(-1)
// Check partial flag (primary indicator)
if (lastMessage?.partial === true) {
return true
}
// Check for in-progress API request
const apiReq = messages.findLast((m) => m.say === "api_req_started")
if (apiReq?.text) {
const data = JSON.parse(apiReq.text)
if (data.cost === undefined) {
return true // API request not yet complete
}
}
return false
}
```
## State Machine
```
┌─────────────────┐
│ NO_TASK │ (no messages)
└────────┬────────┘
│ newTask
┌─────────────────────────────┐
┌───▶│ RUNNING │◀───┐
│ └──────────┬──────────────────┘ │
│ │ │
│ ┌──────────┼──────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────┐ ┌─────────┐ ┌──────────┐ │
│ │STREAM│ │WAITING_ │ │ IDLE │ │
│ │ ING │ │FOR_INPUT│ │ │ │
│ └──┬───┘ └────┬────┘ └────┬─────┘ │
│ │ │ │ │
│ │ done │ approved │ newTask │
└────┴───────────┴────────────┘ │
┌──────────────┐ │
│ RESUMABLE │────────────────────────┘
└──────────────┘ resumed
```
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ ExtensionHost │
│ │
│ ┌──────────────────┐ │
│ │ Extension │──── extensionWebviewMessage ─────┐ │
│ │ (Task.ts) │ │ │
│ └──────────────────┘ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ ExtensionClient │ │
│ │ (Single Source of Truth) │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌────────────────────┐ │ │
│ │ │ MessageProcessor │───▶│ StateStore │ │ │
│ │ │ │ │ (clineMessages) │ │ │
│ │ └─────────────────┘ └────────┬───────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ detectAgentState() │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Events: stateChange, message, waitingForInput, etc. │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ OutputManager │ │ AskDispatcher │ │ PromptManager │ │
│ │ (stdout) │ │ (ask routing) │ │ (user input) │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Component Responsibilities
### ExtensionClient
The **single source of truth** for agent state, including the current mode. It:
- Receives all messages from the extension
- Stores them in the `StateStore`
- Tracks the current mode from state messages
- Computes the current state via `detectAgentState()`
- Emits events when state changes (including mode changes)
```typescript
const client = new ExtensionClient({
sendMessage: (msg) => extensionHost.sendToExtension(msg),
debug: true, // Writes to ~/.roo/cli-debug.log
})
// Query state at any time
const state = client.getAgentState()
if (state.isWaitingForInput) {
console.log(`Agent needs: ${state.currentAsk}`)
}
// Query current mode
const mode = client.getCurrentMode()
console.log(`Current mode: ${mode}`) // e.g., "code", "architect", "ask"
// Subscribe to events
client.on("waitingForInput", (event) => {
console.log(`Waiting for: ${event.ask}`)
})
// Subscribe to mode changes
client.on("modeChanged", (event) => {
console.log(`Mode changed: ${event.previousMode} -> ${event.currentMode}`)
})
```
### StateStore
Holds the `clineMessages` array, computed state, and current mode:
```typescript
interface StoreState {
messages: ClineMessage[] // The raw message array
agentState: AgentStateInfo // Computed state
isInitialized: boolean // Have we received any state?
currentMode: string | undefined // Current mode (e.g., "code", "architect")
}
```
### MessageProcessor
Handles incoming messages from the extension:
- `"state"` messages → Update `clineMessages` array and track mode
- `"messageUpdated"` messages → Update single message in array
- Emits events for state transitions and mode changes
### AskDispatcher
Routes asks to appropriate handlers:
- Uses type guards: `isIdleAsk()`, `isInteractiveAsk()`, etc.
- Coordinates between `OutputManager` and `PromptManager`
- By default, the CLI auto-approves tool/command/browser/MCP actions
- In `--require-approval` mode, those actions prompt for manual approval
### OutputManager
Handles all CLI output:
- Streams partial content with delta computation
- Tracks what's been displayed to avoid duplicates
- Writes directly to `process.stdout` (bypasses quiet mode)
### PromptManager
Handles user input:
- Yes/no prompts
- Text input prompts
- Timed prompts with auto-defaults
## Response Messages
When the agent is waiting, send these responses:
```typescript
// Approve an action (tool, command, browser, MCP)
client.sendMessage({
type: "askResponse",
askResponse: "yesButtonClicked",
})
// Reject an action
client.sendMessage({
type: "askResponse",
askResponse: "noButtonClicked",
})
// Answer a question
client.sendMessage({
type: "askResponse",
askResponse: "messageResponse",
text: "My answer here",
})
// Start a new task
client.sendMessage({
type: "newTask",
text: "Build a web app",
})
// Cancel current task
client.sendMessage({
type: "cancelTask",
})
```
## Type Guards
The CLI uses type guards from `@roo-code/types` for categorization:
```typescript
import { isIdleAsk, isInteractiveAsk, isResumableAsk, isNonBlockingAsk } from "@roo-code/types"
const ask = message.ask
if (isInteractiveAsk(ask)) {
// Needs approval: tool, command, followup, etc.
} else if (isIdleAsk(ask)) {
// Task stopped: completion_result, api_req_failed, etc.
} else if (isResumableAsk(ask)) {
// Task paused: resume_task
} else if (isNonBlockingAsk(ask)) {
// Command running: command_output
}
```
## Debug Logging
Enable with `-d` flag. Logs go to `~/.roo/cli-debug.log`:
```bash
roo -d -P "Build something" --no-tui
```
View logs:
```bash
tail -f ~/.roo/cli-debug.log
```
Example output:
```
[MessageProcessor] State update: {
"messageCount": 5,
"lastMessage": {
"msgType": "ask:completion_result"
},
"stateTransition": "running → idle",
"currentAsk": "completion_result",
"isWaitingForInput": true
}
[MessageProcessor] EMIT waitingForInput: { "ask": "completion_result" }
[MessageProcessor] EMIT taskCompleted: { "success": true }
```
## Summary
1. **Agent communicates via `ClineMessage` stream**
2. **Last message determines state**
3. **`ask` messages (non-partial) block the agent**
4. **Ask category determines required action**
5. **`partial: true` or `api_req_started` without cost = streaming**
6. **`ExtensionClient` is the single source of truth**

View file

@ -1,353 +0,0 @@
#!/bin/sh
# Roo Code CLI Installer
# Usage: curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh
#
# Environment variables:
# ROO_INSTALL_DIR - Installation directory (default: ~/.roo/cli)
# ROO_BIN_DIR - Binary symlink directory (default: ~/.local/bin)
# ROO_VERSION - Specific version to install (default: latest)
# ROO_LOCAL_TARBALL - Path to local tarball to install (skips download)
set -e
# Configuration
INSTALL_DIR="${ROO_INSTALL_DIR:-$HOME/.roo/cli}"
BIN_DIR="${ROO_BIN_DIR:-$HOME/.local/bin}"
REPO="RooCodeInc/Roo-Code"
MIN_NODE_VERSION=20
# Color output (only if terminal supports it)
if [ -t 1 ]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m'
else
RED=''
GREEN=''
YELLOW=''
BLUE=''
BOLD=''
NC=''
fi
info() { printf "${GREEN}==>${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}Warning:${NC} %s\n" "$1"; }
error() { printf "${RED}Error:${NC} %s\n" "$1" >&2; exit 1; }
# Check Node.js version
check_node() {
if ! command -v node >/dev/null 2>&1; then
error "Node.js is not installed. Please install Node.js $MIN_NODE_VERSION or higher.
Install Node.js:
- macOS: brew install node
- Linux: https://nodejs.org/en/download/package-manager
- Or use a version manager like fnm, nvm, or mise"
fi
NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
if [ "$NODE_VERSION" -lt "$MIN_NODE_VERSION" ]; then
error "Node.js $MIN_NODE_VERSION+ required. Found: $(node -v)
Please upgrade Node.js to version $MIN_NODE_VERSION or higher."
fi
info "Found Node.js $(node -v)"
}
# Detect OS and architecture
detect_platform() {
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$OS" in
darwin) OS="darwin" ;;
linux) OS="linux" ;;
mingw*|msys*|cygwin*)
error "Windows is not supported by this installer. Please use WSL or install manually."
;;
*) error "Unsupported OS: $OS" ;;
esac
case "$ARCH" in
x86_64|amd64) ARCH="x64" ;;
arm64|aarch64) ARCH="arm64" ;;
*) error "Unsupported architecture: $ARCH" ;;
esac
PLATFORM="${OS}-${ARCH}"
info "Detected platform: $PLATFORM"
}
# Get latest release version or use specified version
get_version() {
# Skip version fetch if using local tarball
if [ -n "$ROO_LOCAL_TARBALL" ]; then
VERSION="${ROO_VERSION:-local}"
info "Using local tarball (version: $VERSION)"
return
fi
if [ -n "$ROO_VERSION" ]; then
VERSION="$ROO_VERSION"
info "Using specified version: $VERSION"
return
fi
info "Fetching latest version..."
# Try to get the latest cli release
RELEASES_JSON=$(curl -fsSL "https://api.github.com/repos/$REPO/releases" 2>/dev/null) || {
error "Failed to fetch releases from GitHub. Check your internet connection."
}
# Extract highest cli-v* tag by semantic version (do not rely on API ordering)
VERSION=$(printf "%s" "$RELEASES_JSON" | node -e '
const fs = require("fs")
const input = fs.readFileSync(0, "utf8")
let releases
try {
releases = JSON.parse(input)
} catch {
process.exit(1)
}
function parseVersion(version) {
const core = String(version).trim().split("+", 1)[0].split("-", 1)[0]
if (!core) return null
const parts = core.split(".")
if (parts.length === 0 || parts.some((part) => !/^\d+$/.test(part))) {
return null
}
return parts.map((part) => Number.parseInt(part, 10))
}
function compareVersions(a, b) {
const maxLength = Math.max(a.length, b.length)
for (let i = 0; i < maxLength; i++) {
const aPart = a[i] ?? 0
const bPart = b[i] ?? 0
if (aPart > bPart) return 1
if (aPart < bPart) return -1
}
return 0
}
let latestVersion = ""
let latestParts = null
if (Array.isArray(releases)) {
for (const release of releases) {
if (!release || typeof release.tag_name !== "string" || !release.tag_name.startsWith("cli-v")) {
continue
}
const candidate = release.tag_name.slice("cli-v".length)
const candidateParts = parseVersion(candidate)
if (!candidateParts) continue
if (!latestParts || compareVersions(candidateParts, latestParts) > 0) {
latestVersion = candidate
latestParts = candidateParts
}
}
}
if (latestVersion) {
process.stdout.write(latestVersion)
}
')
if [ -z "$VERSION" ]; then
error "Could not find any CLI releases. The CLI may not have been released yet."
fi
info "Latest version: $VERSION"
}
# Download and extract
download_and_install() {
TARBALL="roo-cli-${PLATFORM}.tar.gz"
# Create temp directory
TMP_DIR=$(mktemp -d)
trap "rm -rf $TMP_DIR" EXIT
# Use local tarball if provided, otherwise download
if [ -n "$ROO_LOCAL_TARBALL" ]; then
if [ ! -f "$ROO_LOCAL_TARBALL" ]; then
error "Local tarball not found: $ROO_LOCAL_TARBALL"
fi
info "Using local tarball: $ROO_LOCAL_TARBALL"
cp "$ROO_LOCAL_TARBALL" "$TMP_DIR/$TARBALL"
else
URL="https://github.com/$REPO/releases/download/cli-v${VERSION}/${TARBALL}"
info "Downloading from $URL..."
# Download with progress indicator
HTTP_CODE=$(curl -fsSL -w "%{http_code}" "$URL" -o "$TMP_DIR/$TARBALL" 2>/dev/null) || {
if [ "$HTTP_CODE" = "404" ]; then
error "Release not found for platform $PLATFORM version $VERSION.
Available at: https://github.com/$REPO/releases"
fi
error "Download failed. HTTP code: $HTTP_CODE"
}
# Verify we got something
if [ ! -s "$TMP_DIR/$TARBALL" ]; then
error "Downloaded file is empty. Please try again."
fi
fi
# Remove old installation if exists
if [ -d "$INSTALL_DIR" ]; then
info "Removing previous installation..."
rm -rf "$INSTALL_DIR"
fi
mkdir -p "$INSTALL_DIR"
# Extract
info "Extracting to $INSTALL_DIR..."
tar -xzf "$TMP_DIR/$TARBALL" -C "$INSTALL_DIR" --strip-components=1 || {
error "Failed to extract tarball. The download may be corrupted."
}
# Save ripgrep binary before npm install (npm install will overwrite node_modules)
RIPGREP_BIN=""
if [ -f "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg" ]; then
RIPGREP_BIN="$TMP_DIR/rg"
cp "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg" "$RIPGREP_BIN"
fi
# Install npm dependencies
info "Installing dependencies..."
cd "$INSTALL_DIR"
npm install --production --silent 2>/dev/null || {
warn "npm install failed, trying with --legacy-peer-deps..."
npm install --production --legacy-peer-deps --silent 2>/dev/null || {
error "Failed to install dependencies. Make sure npm is available."
}
}
cd - > /dev/null
# Restore ripgrep binary after npm install
if [ -n "$RIPGREP_BIN" ] && [ -f "$RIPGREP_BIN" ]; then
mkdir -p "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin"
cp "$RIPGREP_BIN" "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg"
chmod +x "$INSTALL_DIR/node_modules/@vscode/ripgrep/bin/rg"
fi
# Make executable
chmod +x "$INSTALL_DIR/bin/roo"
# Also make ripgrep executable if it exists
if [ -f "$INSTALL_DIR/bin/rg" ]; then
chmod +x "$INSTALL_DIR/bin/rg"
fi
}
# Create symlink in bin directory
setup_bin() {
mkdir -p "$BIN_DIR"
# Remove old symlink if exists
if [ -L "$BIN_DIR/roo" ] || [ -f "$BIN_DIR/roo" ]; then
rm -f "$BIN_DIR/roo"
fi
ln -sf "$INSTALL_DIR/bin/roo" "$BIN_DIR/roo"
info "Created symlink: $BIN_DIR/roo"
}
# Check if bin dir is in PATH and provide instructions
check_path() {
case ":$PATH:" in
*":$BIN_DIR:"*)
# Already in PATH
return 0
;;
esac
warn "$BIN_DIR is not in your PATH"
echo ""
echo "Add this line to your shell profile:"
echo ""
# Detect shell and provide specific instructions
SHELL_NAME=$(basename "$SHELL")
case "$SHELL_NAME" in
zsh)
echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.zshrc"
echo " source ~/.zshrc"
;;
bash)
if [ -f "$HOME/.bashrc" ]; then
echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.bashrc"
echo " source ~/.bashrc"
else
echo " echo 'export PATH=\"$BIN_DIR:\$PATH\"' >> ~/.bash_profile"
echo " source ~/.bash_profile"
fi
;;
fish)
echo " set -Ux fish_user_paths $BIN_DIR \$fish_user_paths"
;;
*)
echo " export PATH=\"$BIN_DIR:\$PATH\""
;;
esac
echo ""
}
# Verify installation
verify_install() {
if [ -x "$BIN_DIR/roo" ]; then
info "Verifying installation..."
# Just check if it runs without error
"$BIN_DIR/roo" --version >/dev/null 2>&1 || true
fi
}
# Print success message
print_success() {
echo ""
printf "${GREEN}${BOLD}✓ Roo Code CLI installed successfully!${NC}\n"
echo ""
echo " Installation: $INSTALL_DIR"
echo " Binary: $BIN_DIR/roo"
echo " Version: $VERSION"
echo ""
echo " ${BOLD}Get started:${NC}"
echo " roo --help"
echo ""
echo " ${BOLD}Example:${NC}"
echo " export OPENROUTER_API_KEY=sk-or-v1-..."
echo " cd ~/my-project && roo \"What is this project?\""
echo ""
}
# Main
main() {
echo ""
printf "${BLUE}${BOLD}"
echo " ╭─────────────────────────────────╮"
echo " │ Roo Code CLI Installer │"
echo " ╰─────────────────────────────────╯"
printf "${NC}"
echo ""
check_node
detect_platform
get_version
download_and_install
setup_bin
check_path
verify_install
print_success
}
main "$@"

View file

@ -1,50 +0,0 @@
{
"name": "@roo-code/cli",
"version": "0.1.17",
"description": "Roo Code CLI - Run the Roo Code agent from the command line",
"private": true,
"type": "module",
"main": "dist/index.js",
"bin": {
"roo": "dist/index.js"
},
"scripts": {
"format": "prettier --write 'src/**/*.ts'",
"lint": "eslint src --ext .ts --max-warnings=0",
"check-types": "tsc --noEmit",
"test": "vitest run",
"test:integration": "tsx scripts/integration/run.ts",
"build": "tsup",
"build:extension": "pnpm --filter roo-cline bundle",
"dev": "tsx src/index.ts",
"dev:local": "tsx src/index.ts",
"clean": "rimraf dist .turbo"
},
"dependencies": {
"@inkjs/ui": "^2.0.0",
"@roo-code/core": "workspace:^",
"@roo-code/types": "workspace:^",
"@roo-code/vscode-shim": "workspace:^",
"@trpc/client": "^11.8.1",
"@vscode/ripgrep": "^1.15.9",
"commander": "^12.1.0",
"cross-spawn": "^7.0.6",
"execa": "^9.5.2",
"fuzzysort": "^3.1.0",
"ink": "^6.6.0",
"p-wait-for": "^5.0.2",
"react": "^19.1.0",
"superjson": "^2.2.6",
"zustand": "^5.0.0"
},
"devDependencies": {
"@roo-code/config-eslint": "workspace:^",
"@roo-code/config-typescript": "workspace:^",
"@types/node": "^24.1.0",
"@types/react": "^19.1.6",
"ink-testing-library": "^4.0.0",
"rimraf": "^6.0.1",
"tsup": "^8.4.0",
"vitest": "^3.2.3"
}
}

View file

@ -1,358 +0,0 @@
#!/bin/bash
# Roo Code CLI Local Build Script
#
# Usage:
# ./apps/cli/scripts/build.sh [options]
#
# Options:
# --install Install locally after building
# --skip-verify Skip end-to-end verification tests (faster builds)
#
# Examples:
# ./apps/cli/scripts/build.sh # Build for local testing
# ./apps/cli/scripts/build.sh --install # Build and install locally
# ./apps/cli/scripts/build.sh --skip-verify # Fast local build
#
# This script builds the CLI for your current platform. For official releases
# with multi-platform support, use the GitHub Actions workflow instead:
# .github/workflows/cli-release.yml
#
# Prerequisites:
# - pnpm installed
# - Run from the monorepo root directory
set -e
# Parse arguments
LOCAL_INSTALL=false
SKIP_VERIFY=false
while [[ $# -gt 0 ]]; do
case $1 in
--install)
LOCAL_INSTALL=true
shift
;;
--skip-verify)
SKIP_VERIFY=true
shift
;;
-*)
echo "Unknown option: $1" >&2
exit 1
;;
*)
shift
;;
esac
done
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m'
info() { printf "${GREEN}==>${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}Warning:${NC} %s\n" "$1"; }
error() { printf "${RED}Error:${NC} %s\n" "$1" >&2; exit 1; }
step() { printf "${BLUE}${BOLD}[%s]${NC} %s\n" "$1" "$2"; }
# Get script directory and repo root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
CLI_DIR="$REPO_ROOT/apps/cli"
# Detect current platform
detect_platform() {
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$OS" in
darwin) OS="darwin" ;;
linux) OS="linux" ;;
*) error "Unsupported OS: $OS" ;;
esac
case "$ARCH" in
x86_64|amd64) ARCH="x64" ;;
arm64|aarch64) ARCH="arm64" ;;
*) error "Unsupported architecture: $ARCH" ;;
esac
PLATFORM="${OS}-${ARCH}"
}
# Check prerequisites
check_prerequisites() {
step "1/6" "Checking prerequisites..."
if ! command -v pnpm &> /dev/null; then
error "pnpm is not installed."
fi
if ! command -v node &> /dev/null; then
error "Node.js is not installed."
fi
info "Prerequisites OK"
}
# Get version
get_version() {
VERSION=$(node -p "require('$CLI_DIR/package.json').version")
GIT_SHORT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
VERSION="${VERSION}-local.${GIT_SHORT_HASH}"
info "Version: $VERSION"
}
# Build everything
build() {
step "2/6" "Building extension bundle..."
cd "$REPO_ROOT"
pnpm bundle
step "3/6" "Building CLI..."
pnpm --filter @roo-code/cli build
info "Build complete"
}
# Create release tarball
create_tarball() {
step "4/6" "Creating release tarball for $PLATFORM..."
RELEASE_DIR="$REPO_ROOT/roo-cli-${PLATFORM}"
TARBALL="roo-cli-${PLATFORM}.tar.gz"
# Clean up any previous build
rm -rf "$RELEASE_DIR"
rm -f "$REPO_ROOT/$TARBALL"
# Create directory structure
mkdir -p "$RELEASE_DIR/bin"
mkdir -p "$RELEASE_DIR/lib"
mkdir -p "$RELEASE_DIR/extension"
# Copy CLI dist files
info "Copying CLI files..."
cp -r "$CLI_DIR/dist/"* "$RELEASE_DIR/lib/"
# Create package.json for npm install
info "Creating package.json..."
node -e "
const pkg = require('$CLI_DIR/package.json');
const newPkg = {
name: '@roo-code/cli',
version: '$VERSION',
type: 'module',
dependencies: {
'@inkjs/ui': pkg.dependencies['@inkjs/ui'],
'@trpc/client': pkg.dependencies['@trpc/client'],
'commander': pkg.dependencies.commander,
'fuzzysort': pkg.dependencies.fuzzysort,
'ink': pkg.dependencies.ink,
'p-wait-for': pkg.dependencies['p-wait-for'],
'react': pkg.dependencies.react,
'superjson': pkg.dependencies.superjson,
'zustand': pkg.dependencies.zustand
}
};
console.log(JSON.stringify(newPkg, null, 2));
" > "$RELEASE_DIR/package.json"
# Copy extension bundle
info "Copying extension bundle..."
cp -r "$REPO_ROOT/src/dist/"* "$RELEASE_DIR/extension/"
# Add package.json to extension directory for CommonJS
echo '{"type": "commonjs"}' > "$RELEASE_DIR/extension/package.json"
# Find and copy ripgrep binary
info "Looking for ripgrep binary..."
RIPGREP_PATH=$(find "$REPO_ROOT/node_modules" -path "*/@vscode/ripgrep/bin/rg" -type f 2>/dev/null | head -1)
if [ -n "$RIPGREP_PATH" ] && [ -f "$RIPGREP_PATH" ]; then
info "Found ripgrep at: $RIPGREP_PATH"
mkdir -p "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin"
cp "$RIPGREP_PATH" "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin/"
chmod +x "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin/rg"
mkdir -p "$RELEASE_DIR/bin"
cp "$RIPGREP_PATH" "$RELEASE_DIR/bin/"
chmod +x "$RELEASE_DIR/bin/rg"
else
warn "ripgrep binary not found - users will need ripgrep installed"
fi
# Create the wrapper script
info "Creating wrapper script..."
cat > "$RELEASE_DIR/bin/roo" << 'WRAPPER_EOF'
#!/usr/bin/env node
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { existsSync } from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Set environment variables for the CLI
process.env.ROO_CLI_ROOT = join(__dirname, '..');
process.env.ROO_EXTENSION_PATH = join(__dirname, '..', 'extension');
const ripgrepPath = join(__dirname, 'rg');
if (existsSync(ripgrepPath)) {
process.env.ROO_RIPGREP_PATH = ripgrepPath;
}
// Import and run the actual CLI
await import(join(__dirname, '..', 'lib', 'index.js'));
WRAPPER_EOF
chmod +x "$RELEASE_DIR/bin/roo"
# Create empty .env file
touch "$RELEASE_DIR/.env"
# Strip macOS metadata artifacts before packaging.
find "$RELEASE_DIR" -type f -name "._*" -delete
find "$RELEASE_DIR" -type f -name ".DS_Store" -delete
find "$RELEASE_DIR" -type d -name "__MACOSX" -prune -exec rm -rf {} +
# Create tarball
info "Creating tarball..."
cd "$REPO_ROOT"
COPYFILE_DISABLE=1 tar \
--exclude="._*" \
--exclude=".DS_Store" \
--exclude="__MACOSX" \
--exclude="*/._*" \
--exclude="*/.DS_Store" \
-czvf "$TARBALL" "$(basename "$RELEASE_DIR")"
# Clean up release directory
rm -rf "$RELEASE_DIR"
# Show size
TARBALL_PATH="$REPO_ROOT/$TARBALL"
TARBALL_SIZE=$(ls -lh "$TARBALL_PATH" | awk '{print $5}')
info "Created: $TARBALL ($TARBALL_SIZE)"
}
# Verify local installation
verify_local_install() {
if [ "$SKIP_VERIFY" = true ]; then
step "5/6" "Skipping verification (--skip-verify)"
return
fi
step "5/6" "Verifying installation..."
VERIFY_DIR="$REPO_ROOT/.verify-release"
VERIFY_INSTALL_DIR="$VERIFY_DIR/cli"
VERIFY_BIN_DIR="$VERIFY_DIR/bin"
rm -rf "$VERIFY_DIR"
mkdir -p "$VERIFY_DIR"
TARBALL_PATH="$REPO_ROOT/$TARBALL"
ROO_LOCAL_TARBALL="$TARBALL_PATH" \
ROO_INSTALL_DIR="$VERIFY_INSTALL_DIR" \
ROO_BIN_DIR="$VERIFY_BIN_DIR" \
ROO_VERSION="$VERSION" \
"$CLI_DIR/install.sh" || {
rm -rf "$VERIFY_DIR"
error "Installation verification failed!"
}
# Test --help
if ! "$VERIFY_BIN_DIR/roo" --help > /dev/null 2>&1; then
rm -rf "$VERIFY_DIR"
error "CLI --help check failed!"
fi
info "CLI --help check passed"
# Test --version
if ! "$VERIFY_BIN_DIR/roo" --version > /dev/null 2>&1; then
rm -rf "$VERIFY_DIR"
error "CLI --version check failed!"
fi
info "CLI --version check passed"
cd "$REPO_ROOT"
rm -rf "$VERIFY_DIR"
info "Verification passed!"
}
# Install locally
install_local() {
if [ "$LOCAL_INSTALL" = false ]; then
step "6/6" "Skipping install (use --install to auto-install)"
return
fi
step "6/6" "Installing locally..."
TARBALL_PATH="$REPO_ROOT/$TARBALL"
ROO_LOCAL_TARBALL="$TARBALL_PATH" \
ROO_VERSION="$VERSION" \
"$CLI_DIR/install.sh" || {
error "Local installation failed!"
}
info "Local installation complete!"
}
# Print summary
print_summary() {
echo ""
printf "${GREEN}${BOLD}✓ Local build complete for v$VERSION${NC}\n"
echo ""
echo " Tarball: $REPO_ROOT/$TARBALL"
echo ""
if [ "$LOCAL_INSTALL" = true ]; then
echo " Installed to: ~/.roo/cli"
echo " Binary: ~/.local/bin/roo"
echo ""
echo " Test it out:"
echo " roo --version"
echo " roo --help"
else
echo " To install manually:"
echo " ROO_LOCAL_TARBALL=$REPO_ROOT/$TARBALL ./apps/cli/install.sh"
echo ""
echo " Or re-run with --install:"
echo " ./apps/cli/scripts/build.sh --install"
fi
echo ""
echo " For official multi-platform releases, use the GitHub Actions workflow:"
echo " .github/workflows/cli-release.yml"
echo ""
}
# Main
main() {
echo ""
printf "${BLUE}${BOLD}"
echo " ╭─────────────────────────────────╮"
echo " │ Roo Code CLI Local Build │"
echo " ╰─────────────────────────────────╯"
printf "${NC}"
echo ""
detect_platform
check_prerequisites
get_version
build
create_tarball
verify_local_install
install_local
print_summary
}
main

View file

@ -1,104 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 12 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const startRequestId = `start-a-${Date.now()}`
const cancelRequestId = `cancel-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let startAccepted = false
let startCommandToolUseSeen = false
let sentCancel = false
let cancelDone = false
let sentShutdown = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: LONG_PROMPT,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId
) {
startAccepted = true
return
}
if (
event.type === "tool_use" &&
event.subtype === "command" &&
event.done === true &&
event.requestId === startRequestId
) {
startCommandToolUseSeen = true
}
if (startAccepted && startCommandToolUseSeen && !sentCancel) {
context.sendCommand({
command: "cancel",
requestId: cancelRequestId,
})
sentCancel = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "cancel" &&
event.requestId === cancelRequestId
) {
if (event.code === "cancel_requested" || event.code === "no_active_task") {
cancelDone = true
}
return
}
if (cancelDone && !sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
return
}
if (event.type === "control" && event.subtype === "error" && event.requestId === cancelRequestId) {
throw new Error(
`cancel command failed with code=${event.code ?? "unknown"} content="${event.content ?? ""}"`,
)
}
if (event.type === "error") {
throw new Error(`unexpected stream error event: ${event.content ?? "unknown error"}`)
}
},
onTimeoutMessage() {
return `timed out waiting for cancel flow (initSeen=${initSeen}, startAccepted=${startAccepted}, startCommandToolUseSeen=${startCommandToolUseSeen}, sentCancel=${sentCancel}, cancelDone=${cancelDone}, sentShutdown=${sentShutdown})`
},
})
if (!startAccepted || !startCommandToolUseSeen || !sentCancel || !cancelDone || !sentShutdown) {
throw new Error(
`cancel flow did not complete expected transitions (startAccepted=${startAccepted}, startCommandToolUseSeen=${startCommandToolUseSeen}, sentCancel=${sentCancel}, cancelDone=${cancelDone}, sentShutdown=${sentShutdown})`,
)
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,83 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 12 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const startRequestId = `start-${Date.now()}`
const cancelRequestId = `cancel-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let startAccepted = false
let sentCancel = false
let cancelDone = false
let sentShutdown = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: LONG_PROMPT,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId &&
!startAccepted
) {
startAccepted = true
context.sendCommand({
command: "cancel",
requestId: cancelRequestId,
})
sentCancel = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "cancel" &&
event.requestId === cancelRequestId
) {
if (event.code === "cancel_requested" || event.code === "no_active_task") {
cancelDone = true
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
}
return
}
if (event.type === "error") {
throw new Error(`unexpected stream error event: ${event.content ?? "unknown error"}`)
}
},
onTimeoutMessage() {
return `timed out waiting for immediate-cancel flow (initSeen=${initSeen}, startAccepted=${startAccepted}, sentCancel=${sentCancel}, cancelDone=${cancelDone}, sentShutdown=${sentShutdown})`
},
})
if (!startAccepted || !sentCancel || !cancelDone || !sentShutdown) {
throw new Error(
`immediate-cancel flow did not complete expected transitions (startAccepted=${startAccepted}, sentCancel=${sentCancel}, cancelDone=${cancelDone}, sentShutdown=${sentShutdown})`,
)
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,161 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const START_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 12 && echo "done". After it finishes, reply with exactly "done".'
const FOLLOWUP_PROMPT = 'After cancellation, reply with only "RACE-OK".'
async function main() {
const startRequestId = `start-${Date.now()}`
const cancelRequestId = `cancel-${Date.now()}`
const followupRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentCancelAndFollowup = false
let sentShutdown = false
let cancelDoneCode: string | undefined
let followupDoneCode: string | undefined
let followupResult = ""
let sawFollowupUserTurn = false
let sawMisroutedToolResult = false
let sawMessageControlError = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: START_PROMPT,
})
return
}
if (event.type === "control" && event.subtype === "error") {
if (event.requestId === followupRequestId) {
sawMessageControlError = true
}
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (
!sentCancelAndFollowup &&
event.type === "tool_use" &&
event.requestId === startRequestId &&
event.subtype === "command"
) {
context.sendCommand({
command: "cancel",
requestId: cancelRequestId,
})
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentCancelAndFollowup = true
return
}
if (
event.type === "control" &&
event.command === "cancel" &&
event.subtype === "done" &&
event.requestId === cancelRequestId
) {
cancelDoneCode = event.code
return
}
if (
event.type === "control" &&
event.command === "message" &&
event.subtype === "done" &&
event.requestId === followupRequestId
) {
followupDoneCode = event.code
return
}
if (
event.type === "tool_result" &&
event.requestId === followupRequestId &&
typeof event.content === "string" &&
event.content.includes("<user_message>")
) {
sawMisroutedToolResult = true
return
}
if (event.type === "user" && event.requestId === followupRequestId) {
sawFollowupUserTurn = typeof event.content === "string" && event.content.includes("RACE-OK")
return
}
if (event.type !== "result" || event.done !== true || event.requestId !== followupRequestId) {
return
}
followupResult = event.content ?? ""
if (followupResult.trim().length === 0) {
throw new Error("follow-up after cancel produced an empty result")
}
if (cancelDoneCode !== "cancel_requested") {
throw new Error(
`cancel done code mismatch; expected cancel_requested, got "${cancelDoneCode ?? "none"}"`,
)
}
if (followupDoneCode !== "responded" && followupDoneCode !== "queued") {
throw new Error(
`unexpected follow-up done code after cancel race; expected responded|queued, got "${followupDoneCode ?? "none"}"`,
)
}
if (sawMessageControlError) {
throw new Error("follow-up message emitted control error in cancel recovery race")
}
if (sawMisroutedToolResult) {
throw new Error(
"follow-up message was misrouted into tool_result (<user_message>) in cancel recovery race",
)
}
if (!sawFollowupUserTurn) {
throw new Error("follow-up after cancel did not appear as a normal user turn")
}
console.log(`[PASS] cancel done code: "${cancelDoneCode}"`)
console.log(`[PASS] follow-up done code: "${followupDoneCode}"`)
console.log(`[PASS] follow-up user turn observed: ${sawFollowupUserTurn}`)
console.log(`[PASS] follow-up result: "${followupResult}"`)
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
},
onTimeoutMessage() {
return [
"timed out waiting for cancel-message-recovery-race validation",
`initSeen=${initSeen}`,
`sentCancelAndFollowup=${sentCancelAndFollowup}`,
`cancelDoneCode=${cancelDoneCode ?? "none"}`,
`followupDoneCode=${followupDoneCode ?? "none"}`,
`sawFollowupUserTurn=${sawFollowupUserTurn}`,
`sawMisroutedToolResult=${sawMisroutedToolResult}`,
`sawMessageControlError=${sawMessageControlError}`,
`haveFollowupResult=${Boolean(followupResult)}`,
].join(" ")
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,73 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
async function main() {
const cancelRequestId = `cancel-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let cancelAckSeen = false
let cancelDoneSeen = false
let shutdownSent = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "cancel",
requestId: cancelRequestId,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "cancel" &&
event.requestId === cancelRequestId
) {
cancelAckSeen = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "cancel" &&
event.requestId === cancelRequestId
) {
cancelDoneSeen = true
if (event.code !== "no_active_task") {
throw new Error(`cancel without task should return no_active_task, got "${event.code ?? "none"}"`)
}
if (event.success !== true) {
throw new Error("cancel without task should be treated as successful no-op")
}
if (!shutdownSent) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
shutdownSent = true
}
return
}
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`unexpected control error command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
},
onTimeoutMessage() {
return `timed out waiting for cancel-without-active-task validation (initSeen=${initSeen}, cancelAckSeen=${cancelAckSeen}, cancelDoneSeen=${cancelDoneSeen}, shutdownSent=${shutdownSent})`
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,364 +0,0 @@
import fs from "fs/promises"
import os from "os"
import path from "path"
import readline from "readline"
import { fileURLToPath } from "url"
import { randomUUID } from "crypto"
import { execa } from "execa"
import type { TaskSessionEntry } from "@roo-code/core/cli"
type StreamEvent = {
type?: string
subtype?: string
requestId?: string
command?: string
taskId?: string
content?: string
code?: string
success?: boolean
done?: boolean
}
const RESUME_TIMEOUT_MS = 180_000
const __dirname = path.dirname(fileURLToPath(import.meta.url))
function parseStreamEvent(line: string): StreamEvent | null {
const trimmed = line.trim()
if (!trimmed.startsWith("{")) {
return null
}
try {
return JSON.parse(trimmed) as StreamEvent
} catch {
return null
}
}
async function listSessions(cliRoot: string, workspacePath: string): Promise<TaskSessionEntry[]> {
const result = await execa("pnpm", ["dev", "list", "sessions", "--workspace", workspacePath, "--format", "json"], {
cwd: cliRoot,
reject: false,
})
if (result.exitCode !== 0) {
throw new Error(`list sessions failed with exit code ${result.exitCode}: ${result.stderr || result.stdout}`)
}
const stdoutLines = result.stdout.split("\n")
const jsonStartIndex = stdoutLines.findIndex((line) => line.trim().startsWith("{"))
if (jsonStartIndex === -1) {
throw new Error(`list sessions output did not contain JSON payload: ${result.stdout}`)
}
const jsonPayload = stdoutLines.slice(jsonStartIndex).join("\n").trim()
let parsed: unknown
try {
parsed = JSON.parse(jsonPayload)
} catch (error) {
throw new Error(
`failed to parse list sessions output as JSON: ${error instanceof Error ? error.message : String(error)}`,
)
}
if (
typeof parsed !== "object" ||
parsed === null ||
!("sessions" in parsed) ||
!Array.isArray((parsed as { sessions?: unknown }).sessions)
) {
throw new Error("list sessions output missing sessions array")
}
return (parsed as { sessions: TaskSessionEntry[] }).sessions
}
async function createSessionWithCustomId(
cliRoot: string,
workspacePath: string,
sessionId: string,
prompt: string,
): Promise<void> {
const result = await execa(
"pnpm",
[
"dev",
"--print",
"--provider",
"openrouter",
"--output-format",
"stream-json",
"--workspace",
workspacePath,
"--create-with-session-id",
sessionId,
prompt,
],
{
cwd: cliRoot,
reject: false,
},
)
if (result.exitCode !== 0) {
throw new Error(
`create-with-session-id failed for ${sessionId} with exit code ${result.exitCode}: ${result.stderr || result.stdout}`,
)
}
const lines = result.stdout.split("\n")
const events = lines.map(parseStreamEvent).filter((event): event is StreamEvent => Boolean(event))
const errorEvent = events.find((event) => event.type === "error")
if (errorEvent) {
throw new Error(
`create-with-session-id emitted error for ${sessionId}: code=${errorEvent.code ?? "none"} content=${errorEvent.content ?? ""}`,
)
}
const completion = events.find((event) => event.type === "result" && event.done === true)
if (!completion) {
throw new Error(`create-with-session-id did not emit final result for ${sessionId}`)
}
if (completion.success !== true) {
throw new Error(`create-with-session-id completed unsuccessfully for ${sessionId}`)
}
}
async function resumeSessionAndSendMarker(
cliRoot: string,
workspacePath: string,
sessionId: string,
messageToken: string,
): Promise<void> {
const pingRequestId = `ping-${Date.now()}`
const messageRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
const messagePrompt = `Resume marker token: ${messageToken}. Reply with exactly "ack-${messageToken}".`
const child = execa(
"pnpm",
[
"dev",
"--print",
"--stdin-prompt-stream",
"--provider",
"openrouter",
"--output-format",
"stream-json",
"--workspace",
workspacePath,
"--session-id",
sessionId,
],
{
cwd: cliRoot,
stdin: "pipe",
stdout: "pipe",
stderr: "pipe",
reject: false,
forceKillAfterDelay: 2_000,
},
)
child.stderr?.on("data", (chunk) => {
process.stderr.write(chunk)
})
let pingSent = false
let messageSent = false
let shutdownSent = false
let sawMessageControlDone = false
let sawUserTurnWithMarker = false
let shutdownTaskId: string | undefined
let handlerError: Error | null = null
let timedOut = false
const sendCommand = (command: { command: "ping" | "message" | "shutdown"; requestId: string; prompt?: string }) => {
if (!child.stdin || child.stdin.destroyed) {
return
}
child.stdin.write(`${JSON.stringify(command)}\n`)
}
const timeout = setTimeout(() => {
timedOut = true
handlerError = new Error(
`timed out resuming session ${sessionId} (pingSent=${pingSent}, messageSent=${messageSent}, sawMessageControlDone=${sawMessageControlDone}, sawUserTurnWithMarker=${sawUserTurnWithMarker})`,
)
child.kill("SIGTERM")
}, RESUME_TIMEOUT_MS)
const rl = readline.createInterface({
input: child.stdout!,
crlfDelay: Infinity,
})
rl.on("line", (line) => {
process.stdout.write(`${line}\n`)
const event = parseStreamEvent(line)
if (!event) {
return
}
if (event.type === "system" && event.subtype === "init" && !pingSent) {
pingSent = true
sendCommand({ command: "ping", requestId: pingRequestId })
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "ping" &&
event.requestId === pingRequestId &&
!messageSent
) {
messageSent = true
sendCommand({
command: "message",
requestId: messageRequestId,
prompt: messagePrompt,
})
return
}
if (
event.type === "control" &&
event.subtype === "error" &&
event.command === "message" &&
event.requestId === messageRequestId
) {
handlerError = new Error(
`message command failed while resuming ${sessionId}: code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
child.kill("SIGTERM")
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "message" &&
event.requestId === messageRequestId
) {
sawMessageControlDone = true
return
}
if (event.type === "user" && event.requestId === messageRequestId && event.content?.includes(messageToken)) {
sawUserTurnWithMarker = true
if (!shutdownSent) {
shutdownSent = true
sendCommand({ command: "shutdown", requestId: shutdownRequestId })
}
return
}
if (
event.type === "control" &&
(event.subtype === "ack" || event.subtype === "done") &&
event.command === "shutdown" &&
event.requestId === shutdownRequestId &&
typeof event.taskId === "string"
) {
shutdownTaskId = event.taskId
return
}
if (event.type === "control" && event.subtype === "error" && event.requestId !== shutdownRequestId) {
handlerError = new Error(
`unexpected control error while resuming ${sessionId}: command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
child.kill("SIGTERM")
return
}
})
const result = await child
clearTimeout(timeout)
rl.close()
if (handlerError) {
throw handlerError
}
if (timedOut) {
throw new Error(`stream resume for ${sessionId} timed out`)
}
if (result.exitCode !== 0) {
throw new Error(`stream resume for ${sessionId} exited non-zero: ${result.exitCode}`)
}
if (!sawMessageControlDone) {
throw new Error(`did not observe message control completion while resuming ${sessionId}`)
}
if (!sawUserTurnWithMarker) {
throw new Error(`did not observe resumed user marker turn while resuming ${sessionId}`)
}
if (shutdownTaskId !== sessionId) {
throw new Error(
`shutdown taskId did not match resumed session (expected=${sessionId}, actual=${shutdownTaskId ?? "none"})`,
)
}
}
async function main() {
const cliRoot = process.env.ROO_CLI_ROOT
? path.resolve(process.env.ROO_CLI_ROOT)
: path.resolve(__dirname, "../../..")
const workspacePath = await fs.mkdtemp(path.join(os.tmpdir(), "roo-cli-create-session-id-"))
const firstSessionId = randomUUID()
const secondSessionId = randomUUID()
const firstMarker = `FIRST-MARKER-${Date.now()}`
const secondMarker = `SECOND-MARKER-${Date.now()}`
try {
await createSessionWithCustomId(
cliRoot,
workspacePath,
firstSessionId,
`Create first session marker ${firstMarker}. Reply with exactly "ok-${firstMarker}".`,
)
await createSessionWithCustomId(
cliRoot,
workspacePath,
secondSessionId,
`Create second session marker ${secondMarker}. Reply with exactly "ok-${secondMarker}".`,
)
const initialSessions = await listSessions(cliRoot, workspacePath)
if (!initialSessions.some((session) => session.id === firstSessionId)) {
throw new Error(`session list missing first custom session id ${firstSessionId}`)
}
if (!initialSessions.some((session) => session.id === secondSessionId)) {
throw new Error(`session list missing second custom session id ${secondSessionId}`)
}
const resumeMarkerForFirst = `resume-first-${Date.now()}`
await resumeSessionAndSendMarker(cliRoot, workspacePath, firstSessionId, resumeMarkerForFirst)
const resumeMarkerForSecond = `resume-second-${Date.now()}`
await resumeSessionAndSendMarker(cliRoot, workspacePath, secondSessionId, resumeMarkerForSecond)
console.log(`[PASS] created and resumed custom sessions: ${firstSessionId}, ${secondSessionId}`)
} finally {
await fs.rm(workspacePath, { recursive: true, force: true })
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,135 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const FIRST_PROMPT = `What is 1+1? Reply with only "2".`
const FOLLOWUP_PROMPT = `Different question now: what is 3+3? Reply with only "6".`
function parseEventContent(text: string | undefined): string {
return typeof text === "string" ? text : ""
}
function validateFollowupResult(text: string): void {
if (text.trim().length === 0) {
throw new Error("follow-up produced an empty result")
}
}
async function main() {
const startRequestId = `start-${Date.now()}`
const followupRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentFollowup = false
let sentShutdown = false
let firstResult = ""
let followupResult = ""
let followupDoneCode: string | undefined
let sawFollowupUserTurn = false
let sawMisroutedToolResult = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: FIRST_PROMPT,
})
return
}
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (event.type !== "result" || event.done !== true) {
if (
event.type === "control" &&
event.requestId === followupRequestId &&
event.command === "message" &&
event.subtype === "done"
) {
followupDoneCode = event.code
return
}
if (
event.type === "tool_result" &&
event.requestId === followupRequestId &&
typeof event.content === "string" &&
event.content.includes("<user_message>")
) {
sawMisroutedToolResult = true
return
}
if (event.type === "user" && event.requestId === followupRequestId) {
sawFollowupUserTurn = typeof event.content === "string" && event.content.includes("3+3")
return
}
return
}
if (event.requestId === startRequestId) {
firstResult = parseEventContent(event.content)
if (!/\b2\b/.test(firstResult)) {
throw new Error(`first result did not answer first prompt; result="${firstResult}"`)
}
if (!sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentFollowup = true
}
return
}
if (event.requestId !== followupRequestId) {
return
}
followupResult = parseEventContent(event.content)
validateFollowupResult(followupResult)
if (followupDoneCode !== "responded") {
throw new Error(
`follow-up message was not routed as ask response; code="${followupDoneCode ?? "none"}"`,
)
}
if (!sawFollowupUserTurn) {
throw new Error("follow-up did not appear as a normal user turn in stream output")
}
if (sawMisroutedToolResult) {
throw new Error("follow-up message was misrouted into tool_result (<user_message>), old bug reproduced")
}
console.log(`[PASS] first result="${firstResult}"`)
console.log(`[PASS] follow-up result="${followupResult}"`)
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
},
onTimeoutMessage() {
return `timed out waiting for completion (initSeen=${initSeen}, sentFollowup=${sentFollowup}, firstResult=${Boolean(firstResult)}, followupResult=${Boolean(followupResult)})`
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,136 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const START_PROMPT = 'Answer this question and finish: What is 1+1? Reply with only "2", then complete the task.'
const FOLLOWUP_PROMPT = 'Different question now: what is 3+3? Reply with only "6".'
const ONE_PIXEL_IMAGE =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9Y9R4WQAAAAASUVORK5CYII="
async function main() {
const startRequestId = `start-${Date.now()}`
const followupRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentFollowup = false
let sentShutdown = false
let followupDoneCode: string | undefined
let sawFollowupUserTurn = false
let sawMisroutedToolResult = false
let sawQueueImageMetadata = false
let shutdownDoneSeen = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: START_PROMPT,
})
return
}
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (
event.type === "control" &&
event.command === "message" &&
event.subtype === "done" &&
event.requestId === followupRequestId
) {
followupDoneCode = event.code
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
return
}
if (
event.type === "control" &&
event.command === "shutdown" &&
event.subtype === "done" &&
event.requestId === shutdownRequestId
) {
shutdownDoneSeen = true
if (followupDoneCode !== "responded") {
throw new Error(
`follow-up image message was not routed as ask response; code="${followupDoneCode ?? "none"}"`,
)
}
if (sawQueueImageMetadata) {
throw new Error("follow-up image message was unexpectedly queued (observed queue image metadata)")
}
if (sawMisroutedToolResult) {
throw new Error("follow-up image message was misrouted into tool_result (<user_message>)")
}
console.log(`[PASS] follow-up image control code: "${followupDoneCode}"`)
console.log(`[PASS] follow-up image user turn observed before shutdown: ${sawFollowupUserTurn}`)
return
}
if (
event.type === "queue" &&
Array.isArray(event.queue) &&
event.queue.some((item) => item?.imageCount === 1)
) {
sawQueueImageMetadata = true
return
}
if (
event.type === "tool_result" &&
event.requestId === followupRequestId &&
typeof event.content === "string" &&
event.content.includes("<user_message>")
) {
sawMisroutedToolResult = true
return
}
if (event.type === "user" && event.requestId === followupRequestId) {
sawFollowupUserTurn = typeof event.content === "string" && event.content.includes("3+3")
return
}
if (event.type === "result" && event.done === true && event.requestId === startRequestId && !sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
images: [ONE_PIXEL_IMAGE],
})
sentFollowup = true
return
}
},
onTimeoutMessage() {
return [
"timed out waiting for followup-completion-ask-response-images validation",
`initSeen=${initSeen}`,
`sentFollowup=${sentFollowup}`,
`sentShutdown=${sentShutdown}`,
`shutdownDoneSeen=${shutdownDoneSeen}`,
`followupDoneCode=${followupDoneCode ?? "none"}`,
`sawFollowupUserTurn=${sawFollowupUserTurn}`,
`sawMisroutedToolResult=${sawMisroutedToolResult}`,
`sawQueueImageMetadata=${sawQueueImageMetadata}`,
].join(" ")
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,153 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const START_PROMPT = 'Answer this question and finish: What is 1+1? Reply with only "2", then complete the task.'
const FOLLOWUP_PROMPT = 'Different question now: what is 3+3? Reply with only "6".'
async function main() {
const startRequestId = `start-${Date.now()}`
const followupRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentFollowup = false
let sentShutdown = false
let startAckCount = 0
let sawStartControlAfterFollowup = false
let followupDoneCode: string | undefined
let sawFollowupUserTurn = false
let sawMisroutedToolResult = false
let sawQueueEventForFollowupRequest = false
let followupResult = ""
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: START_PROMPT,
})
return
}
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (event.type === "control" && event.command === "start" && event.subtype === "ack") {
startAckCount += 1
if (sentFollowup) {
sawStartControlAfterFollowup = true
}
return
}
if (
event.type === "control" &&
event.command === "message" &&
event.subtype === "done" &&
event.requestId === followupRequestId
) {
followupDoneCode = event.code
return
}
if (event.type === "queue" && event.requestId === followupRequestId) {
sawQueueEventForFollowupRequest = true
return
}
if (
event.type === "tool_result" &&
event.requestId === followupRequestId &&
typeof event.content === "string" &&
event.content.includes("<user_message>")
) {
sawMisroutedToolResult = true
return
}
if (event.type === "user" && event.requestId === followupRequestId) {
sawFollowupUserTurn = typeof event.content === "string" && event.content.includes("3+3")
return
}
if (event.type === "result" && event.done === true && event.requestId === startRequestId && !sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentFollowup = true
return
}
if (event.type !== "result" || event.done !== true || event.requestId !== followupRequestId) {
return
}
followupResult = event.content ?? ""
if (followupResult.trim().length === 0) {
throw new Error("follow-up produced an empty result")
}
if (followupDoneCode !== "responded") {
throw new Error(
`follow-up message was not routed as ask response; code="${followupDoneCode ?? "none"}"`,
)
}
if (sawMisroutedToolResult) {
throw new Error("follow-up message was misrouted into tool_result (<user_message>), old bug reproduced")
}
if (sawQueueEventForFollowupRequest) {
throw new Error("follow-up message produced queue events despite responded routing")
}
if (!sawFollowupUserTurn) {
throw new Error("follow-up did not appear as a normal user turn in stream output")
}
if (sawStartControlAfterFollowup) {
throw new Error("unexpected start control event after follow-up; message should not trigger a new task")
}
if (startAckCount !== 1) {
throw new Error(`expected exactly one start ack event, saw ${startAckCount}`)
}
console.log(`[PASS] follow-up control code: "${followupDoneCode}"`)
console.log(`[PASS] follow-up user turn observed: ${sawFollowupUserTurn}`)
console.log(`[PASS] follow-up result: "${followupResult}"`)
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
},
onTimeoutMessage() {
return [
"timed out waiting for completion ask-response follow-up validation",
`initSeen=${initSeen}`,
`sentFollowup=${sentFollowup}`,
`startAckCount=${startAckCount}`,
`followupDoneCode=${followupDoneCode ?? "none"}`,
`sawFollowupUserTurn=${sawFollowupUserTurn}`,
`sawMisroutedToolResult=${sawMisroutedToolResult}`,
`sawQueueEventForFollowupRequest=${sawQueueEventForFollowupRequest}`,
`haveFollowupResult=${Boolean(followupResult)}`,
].join(" ")
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,159 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const START_PROMPT = 'Answer this question and finish: What is 1+1? Reply with only "2", then complete the task.'
const FOLLOWUP_PROMPT = 'Different question now: what is 3+3? Reply with only "6".'
function looksLikeAttemptCompletionToolUse(event: StreamEvent): boolean {
if (event.type !== "tool_use") {
return false
}
if (event.tool_use?.name === "attempt_completion") {
return true
}
const content = event.content ?? ""
return content.includes('"tool":"attempt_completion"') || content.includes('"name":"attempt_completion"')
}
function validateFollowupResult(text: string): void {
if (text.trim().length === 0) {
throw new Error("follow-up produced an empty result")
}
}
async function main() {
const startRequestId = `start-${Date.now()}`
const followupRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentFollowup = false
let sentShutdown = false
let sawAttemptCompletion = false
let sawFollowupUserTurn = false
let sawMisroutedToolResult = false
let followupResult = ""
let sawFirstAssistantChunkForStart = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: START_PROMPT,
})
return
}
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (!sawAttemptCompletion && looksLikeAttemptCompletionToolUse(event)) {
sawAttemptCompletion = true
if (!sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentFollowup = true
}
return
}
if (
event.type === "assistant" &&
event.requestId === startRequestId &&
event.done !== true &&
!sawFirstAssistantChunkForStart
) {
sawFirstAssistantChunkForStart = true
if (!sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentFollowup = true
}
return
}
if (
event.type === "tool_result" &&
event.requestId === followupRequestId &&
typeof event.content === "string" &&
event.content.includes("<user_message>")
) {
sawMisroutedToolResult = true
return
}
if (event.type === "user" && event.requestId === followupRequestId) {
sawFollowupUserTurn = typeof event.content === "string" && event.content.includes("3+3")
return
}
if (event.type === "result" && event.done === true && event.requestId === startRequestId && !sentFollowup) {
context.sendCommand({
command: "message",
requestId: followupRequestId,
prompt: FOLLOWUP_PROMPT,
})
sentFollowup = true
return
}
if (event.type !== "result" || event.done !== true || event.requestId !== followupRequestId) {
return
}
followupResult = event.content ?? ""
validateFollowupResult(followupResult)
if (sawMisroutedToolResult) {
throw new Error("follow-up message was misrouted into tool_result (<user_message>), old bug reproduced")
}
if (!sawFollowupUserTurn) {
throw new Error("follow-up did not appear as a normal user turn in stream output")
}
console.log(`[PASS] saw attempt_completion tool use: ${sawAttemptCompletion}`)
console.log(`[PASS] saw start assistant chunk before follow-up: ${sawFirstAssistantChunkForStart}`)
console.log(`[PASS] follow-up user turn observed: ${sawFollowupUserTurn}`)
console.log(`[PASS] follow-up result: "${followupResult}"`)
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
},
onTimeoutMessage() {
return [
"timed out waiting for follow-up validation",
`initSeen=${initSeen}`,
`sentFollowup=${sentFollowup}`,
`sawAttemptCompletion=${sawAttemptCompletion}`,
`sawFirstAssistantChunkForStart=${sawFirstAssistantChunkForStart}`,
`sawFollowupUserTurn=${sawFollowupUserTurn}`,
`sawMisroutedToolResult=${sawMisroutedToolResult}`,
`haveFollowupResult=${Boolean(followupResult)}`,
].join(" ")
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,124 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 20 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const startRequestId = `start-${Date.now()}`
const messageRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
const testImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
let initSeen = false
let startAccepted = false
let messageAccepted = false
let messageQueued = false
let queueImageCountObserved = false
let shutdownSent = false
let shutdownAck = false
let shutdownDone = false
await runStreamCase({
timeoutMs: 180_000,
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({ command: "start", requestId: startRequestId, prompt: LONG_PROMPT })
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId &&
!startAccepted
) {
startAccepted = true
context.sendCommand({
command: "message",
requestId: messageRequestId,
prompt: "Respond with exactly IMAGE-QUEUED when this message is processed.",
images: [testImage],
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "message" &&
event.requestId === messageRequestId
) {
messageAccepted = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "message" &&
event.requestId === messageRequestId &&
event.code === "queued"
) {
messageQueued = true
return
}
if (
event.type === "queue" &&
(event.subtype === "snapshot" || event.subtype === "enqueued" || event.subtype === "updated") &&
Array.isArray(event.queue) &&
event.queue.some((item) => item?.imageCount === 1)
) {
queueImageCountObserved = true
if (!shutdownSent) {
context.sendCommand({ command: "shutdown", requestId: shutdownRequestId })
shutdownSent = true
}
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "shutdown" &&
event.requestId === shutdownRequestId
) {
shutdownAck = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "shutdown" &&
event.requestId === shutdownRequestId
) {
shutdownDone = true
}
},
onTimeoutMessage() {
return `timed out waiting for queue image metadata (initSeen=${initSeen}, startAccepted=${startAccepted}, messageAccepted=${messageAccepted}, messageQueued=${messageQueued}, queueImageCountObserved=${queueImageCountObserved}, shutdownSent=${shutdownSent}, shutdownAck=${shutdownAck}, shutdownDone=${shutdownDone})`
},
})
if (!messageAccepted || !messageQueued || !queueImageCountObserved) {
throw new Error(
`expected queued message with image metadata (messageAccepted=${messageAccepted}, messageQueued=${messageQueued}, queueImageCountObserved=${queueImageCountObserved})`,
)
}
if (!shutdownAck || !shutdownDone) {
throw new Error("shutdown control events were not fully observed")
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,51 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
async function main() {
const messageRequestId = `message-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sawNoActiveTaskError = false
let sentShutdown = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "message",
requestId: messageRequestId,
prompt: "Hello",
})
return
}
if (
event.type === "control" &&
event.subtype === "error" &&
event.requestId === messageRequestId &&
event.code === "no_active_task"
) {
sawNoActiveTaskError = true
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
}
},
onTimeoutMessage() {
return `timed out waiting for no_active_task error (initSeen=${initSeen}, sawNoActiveTaskError=${sawNoActiveTaskError})`
},
})
if (!sawNoActiveTaskError) {
throw new Error("expected no_active_task error was not observed")
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,148 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const START_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 8 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const startRequestId = `start-${Date.now()}`
const pingARequestId = `ping-a-${Date.now()}`
const messageRequestId = `message-${Date.now()}`
const pingBRequestId = `ping-b-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let sentInterleavedCommands = false
let sentShutdown = false
const eventOrderByRequestId = new Map<string, string[]>()
let messageDoneCode: string | undefined
let messageQueueEnqueuedSeen = false
let messageResultSeen = false
function recordControlEvent(event: StreamEvent): void {
if (!event.requestId || event.type !== "control" || !event.subtype) {
return
}
const existing = eventOrderByRequestId.get(event.requestId) ?? []
existing.push(event.subtype)
eventOrderByRequestId.set(event.requestId, existing)
}
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: START_PROMPT,
})
return
}
recordControlEvent(event)
if (event.type === "control" && event.subtype === "error") {
throw new Error(
`received control error for requestId=${event.requestId ?? "unknown"} command=${event.command ?? "unknown"} code=${event.code ?? "unknown"} content=${event.content ?? ""}`,
)
}
if (
!sentInterleavedCommands &&
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId
) {
context.sendCommand({
command: "ping",
requestId: pingARequestId,
})
context.sendCommand({
command: "message",
requestId: messageRequestId,
prompt: 'When this queued message is processed, reply with only "INTERLEAVED".',
})
context.sendCommand({
command: "ping",
requestId: pingBRequestId,
})
sentInterleavedCommands = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "message" &&
event.requestId === messageRequestId
) {
messageDoneCode = event.code
return
}
if (
event.type === "queue" &&
event.subtype === "enqueued" &&
event.requestId === startRequestId &&
event.queueDepth === 1
) {
messageQueueEnqueuedSeen = true
return
}
if (event.type === "result" && event.done === true && event.requestId === messageRequestId) {
messageResultSeen = true
const pingAOrder = eventOrderByRequestId.get(pingARequestId) ?? []
const pingBOrder = eventOrderByRequestId.get(pingBRequestId) ?? []
const messageOrder = eventOrderByRequestId.get(messageRequestId) ?? []
if (pingAOrder.join(",") !== "ack,done") {
throw new Error(`ping A control order mismatch: ${pingAOrder.join(",") || "none"}`)
}
if (pingBOrder.join(",") !== "ack,done") {
throw new Error(`ping B control order mismatch: ${pingBOrder.join(",") || "none"}`)
}
if (messageOrder.join(",") !== "ack,done") {
throw new Error(`message control order mismatch: ${messageOrder.join(",") || "none"}`)
}
if (messageDoneCode !== "queued") {
throw new Error(
`expected interleaved message done code \"queued\", got \"${messageDoneCode ?? "none"}\"`,
)
}
if (!messageQueueEnqueuedSeen) {
throw new Error("expected queue enqueued event after interleaved message")
}
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
}
},
onTimeoutMessage() {
return [
"timed out waiting for mixed-command-ordering validation",
`initSeen=${initSeen}`,
`sentInterleavedCommands=${sentInterleavedCommands}`,
`messageDoneCode=${messageDoneCode ?? "none"}`,
`messageQueueEnqueuedSeen=${messageQueueEnqueuedSeen}`,
`messageResultSeen=${messageResultSeen}`,
`pingAOrder=${(eventOrderByRequestId.get(pingARequestId) ?? []).join(",") || "none"}`,
`messageOrder=${(eventOrderByRequestId.get(messageRequestId) ?? []).join(",") || "none"}`,
`pingBOrder=${(eventOrderByRequestId.get(pingBRequestId) ?? []).join(",") || "none"}`,
].join(" ")
},
})
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,184 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 6 && echo "done". After it finishes, reply with exactly "done".'
const MESSAGE_ONE_PROMPT = 'For this follow-up, reply with only "ALPHA".'
const MESSAGE_TWO_PROMPT = 'For this follow-up, reply with only "BETA".'
async function main() {
const startRequestId = `start-${Date.now()}`
const firstMessageRequestId = `message-a-${Date.now()}`
const secondMessageRequestId = `message-b-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let startAccepted = false
let sentQueuedMessages = false
let sentShutdown = false
let firstMessageAccepted = false
let secondMessageAccepted = false
let firstMessageQueued = false
let secondMessageQueued = false
const resultOrder: string[] = []
let queueDequeuedByFirst = false
let queueDrainedBySecond = false
let firstResultSeen = false
let secondResultSeen = false
await runStreamCase({
timeoutMs: 180_000,
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: LONG_PROMPT,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId &&
!startAccepted
) {
startAccepted = true
context.sendCommand({
command: "message",
requestId: firstMessageRequestId,
prompt: MESSAGE_ONE_PROMPT,
})
context.sendCommand({
command: "message",
requestId: secondMessageRequestId,
prompt: MESSAGE_TWO_PROMPT,
})
sentQueuedMessages = true
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "message" &&
event.requestId === firstMessageRequestId
) {
firstMessageAccepted = true
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "message" &&
event.requestId === secondMessageRequestId
) {
secondMessageAccepted = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "message" &&
event.requestId === firstMessageRequestId &&
event.code === "queued"
) {
firstMessageQueued = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "message" &&
event.requestId === secondMessageRequestId &&
event.code === "queued"
) {
secondMessageQueued = true
return
}
if (
event.type === "queue" &&
event.subtype === "dequeued" &&
event.requestId === firstMessageRequestId &&
event.queueDepth === 1
) {
queueDequeuedByFirst = true
return
}
if (
event.type === "queue" &&
event.subtype === "drained" &&
event.requestId === secondMessageRequestId &&
event.queueDepth === 0
) {
queueDrainedBySecond = true
return
}
if (event.type === "result" && event.done === true) {
if (event.requestId === firstMessageRequestId) {
firstResultSeen = true
resultOrder.push(firstMessageRequestId)
}
if (event.requestId === secondMessageRequestId) {
secondResultSeen = true
resultOrder.push(secondMessageRequestId)
}
}
if (!firstResultSeen || !secondResultSeen || sentShutdown) {
return
}
const expectedOrder = [firstMessageRequestId, secondMessageRequestId].join(",")
if (resultOrder.join(",") !== expectedOrder) {
throw new Error(
`queued message result order mismatch; expected=${expectedOrder} actual=${resultOrder.join(",")}`,
)
}
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
},
onTimeoutMessage() {
return `timed out waiting for queued message order validation (initSeen=${initSeen}, startAccepted=${startAccepted}, sentQueuedMessages=${sentQueuedMessages}, firstMessageAccepted=${firstMessageAccepted}, secondMessageAccepted=${secondMessageAccepted}, firstMessageQueued=${firstMessageQueued}, secondMessageQueued=${secondMessageQueued}, queueDequeuedByFirst=${queueDequeuedByFirst}, queueDrainedBySecond=${queueDrainedBySecond}, resultOrder=${resultOrder.join(" -> ")}, firstResultSeen=${firstResultSeen}, secondResultSeen=${secondResultSeen})`
},
})
if (
!firstMessageAccepted ||
!secondMessageAccepted ||
!firstMessageQueued ||
!secondMessageQueued ||
!queueDequeuedByFirst ||
!queueDrainedBySecond
) {
throw new Error(
`expected both queued messages to be accepted/queued and queue transitions observed (firstMessageAccepted=${firstMessageAccepted}, secondMessageAccepted=${secondMessageAccepted}, firstMessageQueued=${firstMessageQueued}, secondMessageQueued=${secondMessageQueued}, queueDequeuedByFirst=${queueDequeuedByFirst}, queueDrainedBySecond=${queueDrainedBySecond})`,
)
}
const expectedOrder = [firstMessageRequestId, secondMessageRequestId].join(",")
if (resultOrder.join(",") !== expectedOrder) {
throw new Error(
`queued message result order mismatch; expected=${expectedOrder} actual=${resultOrder.join(",")}`,
)
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,76 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 20 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const startRequestId = `start-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let startAccepted = false
let shutdownSent = false
let shutdownAck = false
let shutdownDone = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: startRequestId,
prompt: LONG_PROMPT,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === startRequestId &&
!startAccepted
) {
startAccepted = true
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
shutdownSent = true
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "shutdown" &&
event.requestId === shutdownRequestId
) {
shutdownAck = true
return
}
if (
event.type === "control" &&
event.subtype === "done" &&
event.command === "shutdown" &&
event.requestId === shutdownRequestId
) {
shutdownDone = true
}
},
onTimeoutMessage() {
return `timed out waiting for shutdown flow (initSeen=${initSeen}, startAccepted=${startAccepted}, shutdownSent=${shutdownSent}, shutdownAck=${shutdownAck}, shutdownDone=${shutdownDone})`
},
})
if (!shutdownAck || !shutdownDone) {
throw new Error("shutdown control events were not fully observed")
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

View file

@ -1,77 +0,0 @@
import { runStreamCase, StreamEvent } from "../lib/stream-harness"
const LONG_PROMPT =
'Run exactly this command and do not summarize until it finishes: sleep 8 && echo "done". After it finishes, reply with exactly "done".'
async function main() {
const firstStartRequestId = `start-a-${Date.now()}`
const secondStartRequestId = `start-b-${Date.now()}`
const shutdownRequestId = `shutdown-${Date.now()}`
let initSeen = false
let firstStartAccepted = false
let secondStartSent = false
let sawTaskBusyError = false
let sentShutdown = false
await runStreamCase({
onEvent(event: StreamEvent, context) {
if (event.type === "system" && event.subtype === "init" && !initSeen) {
initSeen = true
context.sendCommand({
command: "start",
requestId: firstStartRequestId,
prompt: LONG_PROMPT,
})
return
}
if (
event.type === "control" &&
event.subtype === "ack" &&
event.command === "start" &&
event.requestId === firstStartRequestId &&
!firstStartAccepted
) {
firstStartAccepted = true
context.sendCommand({
command: "start",
requestId: secondStartRequestId,
prompt: "What is 1+1? Reply with only 2.",
})
secondStartSent = true
return
}
if (
event.type === "control" &&
event.subtype === "error" &&
event.command === "start" &&
event.requestId === secondStartRequestId &&
event.code === "task_busy"
) {
sawTaskBusyError = true
if (!sentShutdown) {
context.sendCommand({
command: "shutdown",
requestId: shutdownRequestId,
})
sentShutdown = true
}
return
}
},
onTimeoutMessage() {
return `timed out waiting for task_busy error (initSeen=${initSeen}, firstStartAccepted=${firstStartAccepted}, secondStartSent=${secondStartSent}, sawTaskBusyError=${sawTaskBusyError})`
},
})
if (!sawTaskBusyError) {
throw new Error("expected task_busy error for second start command was not observed")
}
}
main().catch((error) => {
console.error(`[FAIL] ${error instanceof Error ? error.message : String(error)}`)
process.exit(1)
})

Some files were not shown because too many files have changed in this diff Show more