This guide covers setting up a development environment and contributing code to Katana.
-
Bun (latest) - JavaScript runtime and toolkit
curl -fsSL https://bun.sh/install | bash -
Docker Engine 20.10+ with Docker Compose V2
docker --version docker compose version
-
Git
- VS Code with extensions:
- Biome (linting/formatting)
- TypeScript
- Docker
git clone https://github.com/SamuraiWTF/katana.git
cd katanabun install# Run CLI commands directly
bun run src/cli.ts --help
bun run src/cli.ts status
bun run src/cli.ts list
# Run with hot reload (for server development)
bun --hot src/cli.ts proxy startbun build --compile src/cli.ts --outfile bin/katanaThe compiled binary is at bin/katana.
katana/
├── src/
│ ├── cli.ts # CLI entry point
│ ├── server.ts # Web server + reverse proxy
│ ├── commands/ # CLI command implementations
│ │ ├── install.ts
│ │ ├── remove.ts
│ │ └── ...
│ ├── core/ # Business logic
│ │ ├── config-manager.ts
│ │ ├── state-manager.ts
│ │ ├── module-loader.ts
│ │ ├── compose-manager.ts
│ │ ├── cert-manager.ts
│ │ ├── proxy-router.ts
│ │ └── docker-client.ts
│ ├── platform/ # Platform-specific code
│ │ └── linux/
│ ├── types/ # TypeScript types + Zod schemas
│ ├── utils/ # Utility functions
│ ├── ui/ # React dashboard
│ │ ├── App.tsx
│ │ ├── components/
│ │ └── hooks/
│ └── server/ # API route handlers
│ └── routes/
├── modules/ # Module definitions
│ ├── targets/
│ └── tools/
├── tests/
│ └── e2e/ # End-to-end tests
├── docs/ # Documentation
├── package.json
├── tsconfig.json
└── biome.json
-
Create a feature branch:
git checkout -b feature/my-feature
-
Make your changes
-
Run type checking:
bunx tsc --noEmit
-
Run linting:
bunx biome check src/
-
Fix formatting:
bunx biome format --write src/
-
Run tests:
./tests/e2e/run-all.sh
We use Biome for linting and formatting:
# Check for issues
bunx biome check src/
# Fix auto-fixable issues
bunx biome check --apply src/
# Format code
bunx biome format --write src/Configuration is in biome.json.
- Strict mode is enabled
- Use Zod for runtime validation
- Prefer explicit types for public APIs
// Good: explicit return type
async function loadModule(name: string): Promise<Module> {
// ...
}
// Good: use Zod for validation
const result = ModuleSchema.parse(data);The test suite is in tests/e2e/:
# Run all tests
./tests/e2e/run-all.sh
# Run individual test
./tests/e2e/build.sh # Build verification
./tests/e2e/cli.sh # CLI commands
./tests/e2e/state.sh # State management
./tests/e2e/lifecycle.sh # Target lifecycle
./tests/e2e/api.sh # API endpoints (requires proxy)
./tests/e2e/proxy.sh # Proxy routing (requires proxy)Some features require manual testing:
- Dashboard loads at
https://katana.samurai.wtf - Install target via dashboard
- Start/stop target via dashboard
- Remove target via dashboard
- Theme toggle (dark/light)
- CA certificate download
- Certificate import in browser (Firefox, Chrome)
- Target accessible after cert import
For new features, add test cases to the appropriate E2E script or create a new script following the existing pattern.
bun build --compile src/cli.ts --outfile bin/katanaThe UI is built separately and embedded:
# Build UI assets
bun run src/ui/build.ts
# Then build the binary
bun build --compile src/cli.ts --outfile bin/katanaAfter building a new binary, you need to re-apply setcap for privileged port binding:
sudo setcap cap_net_bind_service=+ep ./bin/katana-
Create command file in
src/commands/:// src/commands/mycommand.ts export async function myCommand(args: MyArgs): Promise<void> { // Implementation }
-
Register in
src/cli.ts:program .command("mycommand") .description("Description") .action(async () => { await myCommand(); });
-
Add route handler in
src/server/routes/ -
Register in
src/server.tsroute handling
- Edit components in
src/ui/components/ - Test with hot reload:
bun --hot src/cli.ts proxy start - Rebuild:
bun run src/ui/build.ts
# Run with debug output
DEBUG=* bun run src/cli.ts status# Check container status
docker ps -a | grep katana
# View container logs
docker logs katana-dvwa-dvwa-1
# Inspect container
docker inspect katana-dvwa-dvwa-1
# Shell into container
docker exec -it katana-dvwa-dvwa-1 /bin/sh# Test proxy routing manually
curl -k -H "Host: dvwa.samurai.wtf" https://localhost/
# Check what's listening on port 443
sudo lsof -i :443- Type check passes:
bunx tsc --noEmit - Lint passes:
bunx biome check src/ - Tests pass:
./tests/e2e/run-all.sh - Manual testing done for UI changes
Include:
- What the change does
- Why it's needed
- How to test it
- Screenshots for UI changes
Use clear, descriptive commit messages:
Add certificate renewal reminder to doctor command
- Check certificate expiration in doctor command
- Warn if certificate expires within 30 days
- Add help message with renewal instructions
- Architecture questions: See Architecture
- Module development: See Module Development
- Issues: Open a GitHub issue