Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ examples/.cargo/
examples/rust/**/.cargo/
examples/rust/**/.debug-mcp-linux-build

# Java build artifacts
examples/java/*.class

# Test results and analysis files
test-results*.json
test-output.txt
Expand Down
50 changes: 41 additions & 9 deletions .husky/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ echo "πŸ§ͺ Running tests before push to ensure code quality..."
echo "πŸ’‘ This prevents broken code from being pushed to GitHub."
echo ""

# Source cargo environment if available (for Rust tests)
if [ -f "$HOME/.cargo/env" ]; then
. "$HOME/.cargo/env"
fi

# Auto-detect Docker availability and skip Docker tests if not fully functional
if ! docker buildx version >/dev/null 2>&1; then
export SKIP_DOCKER_TESTS=true
echo "Docker buildx not available - Docker tests will be skipped."
echo ""
fi

# Detect if this push contains only tags (read refs from stdin)
TMP_REFS=$(mktemp 2>/dev/null || echo ./.prepush_tmp)
cat - > "$TMP_REFS"
Expand All @@ -19,14 +31,21 @@ else
fi
rm -f "$TMP_REFS" 2>/dev/null || true

# Log file for verbose output (keeps hook stdout small to avoid SIGPIPE)
PRE_PUSH_LOG=$(mktemp 2>/dev/null || echo ./.pre-push-log)
cleanup_log() { rm -f "$PRE_PUSH_LOG" 2>/dev/null || true; }
trap cleanup_log EXIT

# Run linting first to catch syntax and style issues
echo "πŸ”Ž Running ESLint to catch linting issues..."
pnpm run lint
pnpm run lint > "$PRE_PUSH_LOG" 2>&1

if [ $? -ne 0 ]; then
echo ""
echo "❌ Lint failed! Push blocked to prevent broken code on GitHub."
echo "πŸ’‘ Run 'pnpm run lint' to see all errors, or 'pnpm run lint:fix' for auto-fixes."
echo ""
tail -20 "$PRE_PUSH_LOG"
exit 1
fi

Expand All @@ -35,30 +54,36 @@ echo ""

# Clean build to ensure no stale artifacts
echo "πŸ”¨ Running clean build to ensure fresh compilation..."
npm run clean
npm run build
npm run clean > "$PRE_PUSH_LOG" 2>&1
npm run build >> "$PRE_PUSH_LOG" 2>&1

if [ $? -ne 0 ]; then
echo ""
echo "❌ Build failed! Push blocked to prevent broken code on GitHub."
echo "πŸ’‘ Fix build errors before pushing."
echo ""
tail -20 "$PRE_PUSH_LOG"
exit 1
fi

echo "βœ… Build successful!"
echo ""

# Run tests (reduced suite for tag-only pushes to match release CI)
echo "πŸ§ͺ Running tests (this may take a few minutes)..."
if [ "$TAGS_ONLY" = true ]; then
echo ""
echo "πŸ”– Tag-only push detected. Running reduced CI tests (no e2e, no python) to match release workflow..."
npm run test:ci-no-python
echo "πŸ”– Tag-only push detected. Running reduced CI tests..."
npm run test:ci-no-python > "$PRE_PUSH_LOG" 2>&1
else
# Run the full test suite
npm test
npm test > "$PRE_PUSH_LOG" 2>&1
fi

if [ $? -eq 0 ]; then
TEST_EXIT=$?

# Show the test summary (last few lines contain pass/fail counts)
grep -E "Test Files|Tests |Duration" "$PRE_PUSH_LOG" || true

if [ $TEST_EXIT -eq 0 ]; then
echo ""
echo "βœ… All tests passed! Push will proceed."
echo "πŸš€ Code quality maintained for GitHub repository."
Expand All @@ -67,5 +92,12 @@ else
echo "❌ Tests failed! Push blocked to prevent broken code on GitHub."
echo "πŸ’‘ Fix failing tests or use 'git push --no-verify' for emergency pushes."
echo "πŸ”§ You can still make local commits for WIP - tests only run on push."
echo ""
echo "Failed test details:"
grep -E "FAIL|Error|AssertionError" "$PRE_PUSH_LOG" | head -20 || true
echo ""
echo "Full log: $PRE_PUSH_LOG"
# Keep log on failure so user can inspect
trap - EXIT
exit 1
fi
50 changes: 33 additions & 17 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,26 @@ The project uses a **monorepo architecture** with dynamic adapter loading, allow
```
mcp-debugger/
β”œβ”€β”€ packages/
β”‚ β”œβ”€β”€ shared/ # Shared interfaces, types, and utilities
β”‚ β”œβ”€β”€ adapter-python/ # Python debug adapter using debugpy
β”‚ └── adapter-mock/ # Mock adapter for testing
β”‚ β”œβ”€β”€ shared/ # Shared interfaces, types, and utilities
β”‚ β”œβ”€β”€ adapter-python/ # Python debug adapter using debugpy
β”‚ β”œβ”€β”€ adapter-javascript/ # JavaScript/Node.js adapter using js-debug (v0.16.0+)
β”‚ β”œβ”€β”€ adapter-mock/ # Mock adapter for testing
β”‚ └── mcp-debugger/ # Self-contained CLI bundle (npx distribution)
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ adapters/ # Adapter loading and registry system
β”‚ β”œβ”€β”€ container/ # Dependency injection container
β”‚ β”œβ”€β”€ proxy/ # DAP proxy system
β”‚ └── session/ # Session management
└── tests/ # Comprehensive test suite
β”‚ β”œβ”€β”€ adapters/ # Adapter loading and registry system
β”‚ β”œβ”€β”€ container/ # Dependency injection container
β”‚ β”œβ”€β”€ proxy/ # DAP proxy system
β”‚ └── session/ # Session management
└── tests/ # Comprehensive test suite
```

### Package Details

- **@debugmcp/shared**: Core interfaces and types used across all packages
- **@debugmcp/adapter-python**: Python debugging support via debugpy
- **@debugmcp/adapter-javascript**: JavaScript/Node.js debugging support via js-debug (Alpha in v0.16.0)
- **@debugmcp/adapter-mock**: Mock adapter for testing and development
- **@debugmcp/mcp-debugger**: Self-contained CLI bundle for npm distribution (npx-ready)

## Key Commands

Expand All @@ -43,8 +47,9 @@ npm run build

# Build specific packages
npm run build:shared
npm run build:adapters
npm run build:packages # Build all packages via TypeScript project references
npm run build:adapters # Build mock + python adapters
npm run build:adapters:all # Build all adapters including JavaScript
npm run build:packages # Build all packages in correct order via build-packages.cjs

# Clean build
npm run build:clean
Expand Down Expand Up @@ -223,8 +228,12 @@ Sessions progress through states: IDLE β†’ INITIALIZING β†’ READY β†’ RUNNING
- `src/adapters/adapter-loader.ts` - Dynamic adapter loading
- `packages/shared/` - Shared interfaces and types
- `packages/adapter-python/` - Python debug adapter
- `packages/adapter-javascript/` - JavaScript/Node.js debug adapter
- `packages/adapter-mock/` - Mock adapter for testing

### Distribution
- `packages/mcp-debugger/` - Self-contained CLI bundle for npm/npx distribution

### Supporting Infrastructure
- `src/container/dependencies.ts` - Dependency injection container
- `src/utils/error-messages.ts` - Centralized error messages
Expand All @@ -235,13 +244,14 @@ Sessions progress through states: IDLE β†’ INITIALIZING β†’ READY β†’ RUNNING
## Development Guidelines

1. **TypeScript Strict Mode**: All code must pass TypeScript strict mode checks
2. **Monorepo Management**: Use npm workspaces for package management
3. **Test Coverage**: Maintain >90% test coverage
4. **Error Handling**: Use centralized error messages from `error-messages.ts`
5. **Logging**: Use Winston logger with appropriate log levels
6. **Async Operations**: All DAP operations are async with timeouts
7. **Process Cleanup**: Always ensure proper cleanup of spawned processes
8. **Adapter Development**: New language adapters should implement `IAdapterFactory` from `@debugmcp/shared`
2. **Monorepo Management**: Use npm workspaces (pnpm preferred) for package management
3. **Build Order**: Packages must build in order: shared β†’ adapters β†’ main server. This is managed by `scripts/build-packages.cjs`
4. **Test Coverage**: Maintain >90% test coverage
5. **Error Handling**: Use centralized error messages from `error-messages.ts`
6. **Logging**: Use Winston logger with appropriate log levels
7. **Async Operations**: All DAP operations are async with timeouts
8. **Process Cleanup**: Always ensure proper cleanup of spawned processes
9. **Adapter Development**: New language adapters should implement `IAdapterFactory` from `@debugmcp/shared`

## Testing Approach

Expand Down Expand Up @@ -287,6 +297,12 @@ packages/adapter-nodejs/
- debugpy must be installed: `pip install debugpy`
- The system will auto-detect Python path or use `PYTHON_PATH` env var

### JavaScript/Node.js (Alpha)
- Node.js 18+ must be installed
- Uses bundled js-debug adapter (VSCode's debugger)
- Supports JavaScript and TypeScript debugging
- Auto-detects TypeScript configuration

### Mock (Testing)
- No external requirements
- Used for testing the debug infrastructure
Expand Down
15 changes: 15 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ export default [
// TypeScript flat recommended config (scoped by typescript-eslint to TS files)
...tseslint.configs.recommended,

// Configure no-unused-vars to ignore variables starting with underscore
{
files: ["**/*.ts"],
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
]
}
},

// JavaScript rules (only JS files)
{
files: ["**/*.{js,mjs,cjs}"],
Expand Down
23 changes: 23 additions & 0 deletions examples/java/AttachTestProgram.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

public class AttachTestProgram {
public static void main(String[] args) {
System.out.println("AttachTestProgram started - waiting for debugger...");

int counter = 0;
while (true) {
counter++;
System.out.println("Counter: " + counter);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}

// Breakpoint target line
if (counter >= 5) {
System.out.println("Reached counter threshold: " + counter);
}
}
}
}
75 changes: 75 additions & 0 deletions examples/java/TestJavaDebug.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* Comprehensive test script for Java debugging
*/
public class TestJavaDebug {

/**
* Calculate factorial recursively
*/
public static int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}

/**
* Sum an array of numbers
*/
public static int sumArray(int[] numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}

/**
* Process data with multiple operations
*/
public static int[] processData(int[] data) {
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++) {
int processed = data[i] * 2;
result[i] = processed;
}
return result;
}

/**
* Main entry point
*/
public static void main(String[] args) {
// Test variables
int x = 10;
int y = 20;
int z = x + y;

// Test factorial
int factResult = factorial(5);
System.out.println("Factorial of 5: " + factResult);

// Test array operations
int[] numbers = {1, 2, 3, 4, 5};
int sumResult = sumArray(numbers);
System.out.println("Sum of numbers: " + sumResult);

// Test data processing
int[] data = {10, 20, 30};
int[] processed = processData(data);
System.out.print("Processed data: [");
for (int i = 0; i < processed.length; i++) {
System.out.print(processed[i]);
if (i < processed.length - 1) {
System.out.print(", ");
}
}
System.out.println("]");

// Final computation
int finalResult = z * factResult;
System.out.println("Final result: " + finalResult);

System.out.println("Script completed with result: " + finalResult);
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
"zod": "^3.22.4"
},
"optionalDependencies": {
"@debugmcp/adapter-java": "workspace:*",
"@debugmcp/adapter-javascript": "workspace:*",
"@debugmcp/adapter-mock": "workspace:*",
"@debugmcp/adapter-python": "workspace:*",
Expand Down
Loading