This file contains guidelines and commands for agentic coding agents working in this repository.
This is a VS Code extension called "Python Smart Execute" that intelligently sends Python code selections to REPLs or Jupyter sessions. It includes decorators in selections and automatically jumps to the beginning of the next line after execution.
- Compile TypeScript:
npm run compile - Watch mode (auto-recompile):
npm run watch - Lint:
npm run lint - Lint with auto-fix:
npm run lint -- --fix - Run all unit tests:
npm run test:unit - Prepublish:
npm run vscode:prepublish
- Single test file:
npm run compile && npx mocha --ui tdd out/test/suite/path/to/test.js - Tests matching pattern:
npm run test:unit -- --grep "pattern" - Example:
npm run compile && npx mocha --ui tdd out/test/suite/smartExecute/smartSelect.test.js
IMPORTANT: When a skill exists for a task, always use the skill tool to load it first, then follow its instructions. Do NOT run commands directly from this file when a skill is available.
Available skills:
- run-unit-tests: Use this skill (not
npm run test:unit) to compile, lint, and run unit tests in one step. This ensures consistent verification across compile, lint, and test phases.
- Unit tests use Mocha with TDD interface (
suite/test) - Integration tests require xvfb and are unavailable in dev-container
- Test files are colocated with implementation in
src/test/suite/{module}/
npm install- Install dependenciesnpm run watch- Start watch mode during development- Press
F5in VS Code to launch Extension Development Host npm run test:unit- Run unit tests during implementation
- Always use
constorlet. Never usevar - Use
constby default, only useletwhen reassignment is needed
- Use ES6 modules (
import/export) - Use named exports:
export function activate(...) - Do not use default exports
- Do not use
namespace
- Use
UpperCamelCasefor classes, interfaces, types, enums - Use
privatevisibility modifier (not#privatefields) - Mark non-reassigned properties with
readonly - Never use the
publicmodifier (it's the default)
- Prefer function declarations for named functions:
function activate(...) - Use arrow functions for anonymous functions/callbacks
- Use
lowerCamelCasefor function names
- Use single quotes for string literals:
'text' - Use template literals for interpolation:
`${variable}` - Always use triple equals (
===) and not equals (!==) - Avoid
anytype - preferunknownor specific types - Avoid type assertions (
x as SomeType) and non-nullability assertions (y!)
- UpperCamelCase: Classes, interfaces, types, enums, decorators
- lowerCamelCase: Variables, parameters, functions, methods, properties
- CONSTANT_CASE: Global constants and enum values
- Do not use
_prefix/suffix for private properties
- Group imports: Node.js built-ins, third-party, local modules
- Use
import * as vscode from "vscode"pattern for VS Code API - Example:
import * as vscode from "vscode"; import * as path from 'path'; import { runTests } from '@vscode/test-electron';
- Use try/catch blocks for async operations
- Return early to reduce nesting
- Example:
async function main() { try { await runTests({ extensionDevelopmentPath, extensionTestsPath }); } catch (err) { console.error('Failed to run tests', err); process.exit(1); } }
- Use
/** */for documentation comments - Use
//for implementation comments - Document why, not what
- Do not add comments unless necessary
src/
├── extension.ts # Main extension entry point
├── navigation/ # Python block navigation module
│ ├── blockFinder.ts # Finds Python code blocks (functions, classes, if/elif/else)
│ ├── blockNavigator.ts # Navigation commands (jumpNextBlock, jumpPreviousBlock)
│ └── multiLineStatement.ts # Multi-line statement handling
├── smartExecute/ # Smart code selection and execution module
│ ├── config.ts # Configuration helpers
│ ├── execution.ts # REPL/Jupyter execution logic
│ ├── selection.ts # Smart code selection utilities
│ └── helpers.ts # Shared helper functions
├── test/
│ ├── runTest.ts # Integration test runner (requires xvfb)
│ ├── runUnitTests.ts # Unit test runner (no VS Code required)
│ └── suite/
│ ├── index.ts # Test suite setup
│ ├── mocks.ts # VS Code API mocks for unit testing
│ ├── vscode.mock.ts # VS Code module mock
│ ├── navigation/ # Navigation tests
│ │ ├── blockFinder.test.ts # Direct-call tests for blockFinder utilities
│ │ ├── blockNavigator.test.ts
│ │ ├── testHelpers.ts # Test utility facility (DocumentState re-export, expectCursorPosition)
│ │ └── testHelpers.test.ts
│ └── smartExecute/ # Smart execution tests
│ ├── testHelpers.ts # Test utility facility (DocumentState, expectSelection)
│ └── testHelpers.test.ts
- Register commands in
activatefunction usingcontext.subscriptions.push - Use
vscode.commands.registerCommandfor command registration - Access configuration with
vscode.workspace.getConfiguration - Handle editor state with
vscode.window.activeTextEditor
- navigation/: Python block navigation utilities (jump to next/previous code blocks)
- smartExecute/: Smart code selection and execution logic
- Functions are exported for testability
- Tests colocated with modules in
src/test/suite/{module}/
- Extension intelligently selects Python code blocks
- Handles decorators, indentation, and code block boundaries
- Supports multi-line statements (dictionaries, function calls, nested brackets)
- Supports both Python REPL and Jupyter execution engines
- Includes cursor stepping functionality after execution
- Use Mocha TDD interface:
suite()andtest() - Group related tests in nested suites
- Use descriptive test names
- Use
MockTextDocumentandMockTextEditorfromsrc/test/suite/mocks.tsfor direct utility function tests - Define multiline content with template literals to preserve formatting
- Use
assert.strictEqualfor string comparisons - Prefer
DocumentState+expectSelectionover raw mocks for any test that goes throughsmartSelect
const originalGetConfig = getConfigSmartExecute;
(getConfigSmartExecute as unknown as () => boolean) = () => true;
// ... test code ...
(getConfigSmartExecute as unknown as () => boolean) = originalGetConfig;- Use
expectSelection: for any scenario reachable throughsmartSelect(block selection, multiline detection, decorator inclusion, control flow) - Use direct-call tests (raw mock + assert): for utility functions not called by
smartSelect(e.g.,findNextCodeLine, used only bystepCursor). These functions cannot be exercised viaexpectSelectionand direct-call tests are the correct pattern.
-
Use
DocumentStateandexpectSelectionfrom./testHelpersto reduce test boilerplate -
DocumentState(content, cursorLine, cursorChar).createEditor()creates a mock editor with cursor position -
expectSelection(state, startLine, endLine, options?)mocks config, calls smartSelect, and asserts selection -
Example:
const state = new DocumentState('@timer\ndef foo():\n pass\n', 1, 0); expectSelection(state, 0, 2); // Expects lines 0-2 selected expectSelection(state, 0, 0, {smartExecute: false}); // Single line when disabled
-
Use
DocumentStateandexpectCursorPositionfromnavigation/testHelpersfor navigation tests -
expectCursorPosition(state, direction, expectedLine, options?)callsjumpNextBlock/jumpPreviousBlockand asserts result position -
direction:'next'or'previous';expectedLine: line number,'first-line', or'last-line' -
options.character: asserts result character position (defaults to 0) -
Example:
const state = new DocumentState('def foo():\n pass\n\ndef bar():\n pass\n', 0, 0); expectCursorPosition(state, 'next', 3); // Jumps to line 3 expectCursorPosition(state, 'previous', 'first-line'); // Jumps to first line
- Before committing: Run
npm run test:unitto verify all tests pass - Use F5: Launch Extension Development Host for manual testing
- Follow existing patterns: Codebase has consistent structure and style
- Export for testing: Make helper functions exportable for testability
- Configuration aware: Extension behavior configurable via VS Code settings
- Error handling: Always handle async errors gracefully
- Type safety: Maintain strict TypeScript compliance