<ai_meta> <parsing_rules> - Process development patterns in sequential order - Use exact patterns and templates provided - Follow MUST/ALWAYS/REQUIRED directives strictly - Never deviate from established architectural patterns </parsing_rules> <file_conventions> - encoding: UTF-8 - line_endings: LF - indent: 4 spaces (Python, TypeScript, Kotlin) - package_structure: packages/ for Python, vscode-client/ for TypeScript, intellij-client/ for Kotlin </file_conventions> </ai_meta>
RobotCode is a comprehensive Robot Framework toolkit that provides IDE extensions (VS Code, IntelliJ), CLI tools, and Language Server Protocol implementation. It uses Robot Framework's native parser for full compatibility while extending it with modern development tools like DAP debugging, test discovery, and multi-workspace support.
| Task | Command |
|---|---|
| Lint all (style + types) | hatch run lint:all |
| Auto-fix lint | hatch run lint:fix |
| Run tests | pytest . |
| Run tests (specific matrix) | hatch run test.rf70.py311:test |
| Update snapshots | pytest --regtest2-reset |
| Coverage | hatch run cov |
| Build VS Code extension | npm run compile && npm run package |
| Build IntelliJ plugin | cd intellij-client && gradle buildPlugin |
| Bump version | hatch run build:bump |
| File | Purpose |
|---|---|
pyproject.toml |
Root project config, ruff/mypy/pytest settings |
hatch.toml |
Hatch environments, scripts, test matrix |
package.json |
VS Code extension manifest (commands, activation, config) |
robot.toml |
Robot Framework project configuration |
src/robotcode/cli/ |
CLI entry point (robotcode command) |
packages/plugin/ |
Plugin system (pluggy-based hook specs) |
- Namespace packages: All Python packages live under the
robotcode.*namespace. The__init__.pyfiles inrobotcode/directories are empty — never add imports to them. - Plugin registration: New CLI commands or tools must be registered via
[project.entry-points.robotcode]in the package'spyproject.tomland use@hookimplfromrobotcode.plugin. - Snapshot tests: If test output changes intentionally, reset snapshots with
pytest --regtest2-reset. Failing to do so causes false negatives. - Python environment: Always ask your tools which Python interpreter is selected for the workspace before running commands.
- VS Code build: The extension uses esbuild (not webpack). Run
npm run compilefor development,npm run packagefor production. - Version files: Never edit
__version__.pyor version strings manually — usehatch run build:bumpandscripts/update_git_versions.pyto keep all 12+ packages in sync. - Bundled libs: Never edit
bundled/libs/manually — it's regenerated by build scripts. Add new runtime deps tobundled_requirements.txt.
- REVIEW/ANALYZE/CHECK/EXAMINE: READ-ONLY operations. Provide analysis and feedback, NEVER make changes.
- IMPLEMENT/ADD/CREATE/FIX/CHANGE: Implementation required. ALWAYS ask for confirmation and wait for explicit user choice before proceeding.
- IMPROVE/OPTIMIZE/REFACTOR: Always ask for specific approach before implementing.
- MANDATORY WAIT: When presenting implementation options, ALWAYS wait for explicit user choice before proceeding.
- Recognize Intent: Review request vs. Implementation request?
- For Reviews: Analyze and suggest, but don't change anything.
- For Implementation:
- ALWAYS ask for confirmation before implementing.
- If multiple approaches exist, present numbered options A), B), C), D), ...).
- ALWAYS end with "Other approach".
- WAIT for user response before proceeding.
- NEVER start implementation until user explicitly chooses an option.
- Critical Rule: When presenting options, STOP and wait for user input. Do not continue with any implementation.
- Language Server: Python 3.10–3.14 with asyncio
- Protocol: LSP + DAP
- Parser: Robot Framework native parser
- Build: Hatch (Python), esbuild (VS Code), Gradle (IntelliJ)
- Linting: ruff (format + lint) + mypy (type checking)
- Testing: pytest + regtest2 snapshots, matrix across Python 3.10–3.14 × Robot Framework 5.0–7.4
- VS Code extension: TypeScript, manager-based lifecycle
- IntelliJ plugin: Kotlin via LSP4IJ
src/robotcode/cli/ # CLI entry point (Click-based, plugin-loaded commands)
packages/
├── core/ # Base utilities (documents, workspace, URI, async tools)
├── plugin/ # Plugin system (pluggy hookspecs + manager singleton)
├── jsonrpc2/ # JSON-RPC communication layer
├── robot/ # Robot Framework integration (config, diagnostics, project)
├── language_server/ # LSP implementation
├── debugger/ # DAP implementation
├── runner/ # Enhanced RF execution tools
├── analyze/ # Static code analysis
├── repl/ # Interactive RF shell
├── repl_server/ # REPL server for remote connections
└── modifiers/ # Code transformation tools
vscode-client/
├── extension/ # VS Code extension (TypeScript, manager pattern)
└── rendererLog/ # Notebook log renderer
intellij-client/
├── src/main/kotlin/ # IntelliJ plugin (Kotlin, LSP4IJ bridge)
└── build.gradle.kts # Gradle config
All Python packages share the robotcode namespace. Each package lives at:
packages/{name}/src/robotcode/{name}/
Each package has its own pyproject.toml with version, dependencies, and entry points. The __init__.py files in robotcode/ directories are empty — exports are defined in submodules.
The CLI (robotcode command) discovers features via pluggy:
- Hook specs in
packages/plugin/src/robotcode/plugin/specs.pydefineregister_cli_commands()andregister_tool_config_classes() - Packages register via
[project.entry-points.robotcode]in theirpyproject.toml:[project.entry-points.robotcode] langserver = "robotcode.language_server.hooks"
- Hook implementations use
@hookimplto return Click commands or config classes - PluginManager (
PluginManager.instance()) loads all entry points at startup
core ──────────────┐
plugin ─────────┐ │
▼ ▼
jsonrpc2 ──► robot ◄── analyze
│ │
▼ │
language_server ◄┘
│
debugger ◄── runner
repl ◄── repl_server
modifiers (standalone)
coreandpluginare leaf dependencies — most packages depend on themlanguage_serverdepends onjsonrpc2,robot,analyze, and the rootrobotcodeCLIdebuggerdepends onjsonrpc2andrunner
All 12 Python packages + VS Code extension + IntelliJ plugin share a single synchronized version. Each package has its own __version__.py, but versions are never edited manually. Instead:
hatch run build:bump(commitizen) bumps the versionscripts/update_git_versions.pypropagates the version to all__version__.pyfiles, cross-packagepyproject.tomldependencies,package.json, andgradle.properties- CI triggers on git tags (
v*) and usesget_release_versionto derive the version from git history
All inter-package dependencies are pinned to the same version — packages are never independently versioned.
bundled/libs/ is an isolated, offline-capable Python runtime for the VS Code extension. The language server runs from this directory without requiring pip install.
bundled_requirements.txtlists external runtime deps (click, pluggy, tomli, platformdirs, colorama, typing-extensions)scripts/install_bundled_editable.pyinstalls all deps + allpackages/*/intobundled/libs/.pthfiles inbundled/libs/managesys.pathinjection- Never edit
bundled/libs/manually — it's regenerated by the build scripts
LSP features are implemented as modular *ProtocolPart classes in packages/language_server/:
- Each part inherits from
LanguageServerProtocolPart(→GenericJsonRPCProtocolPart) - Methods are annotated with
@rpc_method(name, param_type=..., cancelable=..., threaded=...)frompackages/jsonrpc2/ - Parts register themselves via constructor:
parent.registry.add_class_part_instance(self) - The
RpcRegistrydescriptor auto-discovers all@rpc_methodmethods via introspection; lazy-initializes on first access
To add a new LSP feature: create a new *ProtocolPart class, decorate handlers with @rpc_method, and register the part in the protocol's __init__.
robot.toml(project root): Robot Framework project settings — python paths, suite paths, profiles, analyze optionspyproject.toml: Ruff, mypy, pytest, and coverage configurationhatch.toml: Development environments, test matrix, build scripts- Environment variable prefix:
ROBOTCODE(auto-detected by CLI)
English for all code and docs (REQUIRED): Documentation, comments, docstrings, identifiers, and commit messages must use English regardless of contributor's native language.
Conventional Commits (REQUIRED): <type>(<scope>): <short description>
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Example: feat(cli): add --dry-run flag to publish command
Breaking changes: add BREAKING CHANGE: <description> in footer.
- Readability over cleverness; meaningful names; single responsibility
- Small functions (under 20 lines when possible); early returns over deep nesting
- Type annotations required for all APIs (Python type hints, TypeScript types)
- Explicit error handling with proper exception hierarchies; fail fast
- Async patterns where applicable; lazy loading; appropriate caching
- Inline comments explain why, not what
- pytest with regtest2 for snapshot testing
- Matrix: Python 3.10–3.14 × Robot Framework 5.0–7.4
- Tests in
tests/robotcode/mirror package structure asyncio_mode = "auto"— async tests run automatically- Each test must be independently runnable