This document covers development workflow, build instructions, debugging, and troubleshooting for contributing to Akatsuki Git.
- Rust toolchain:
cargo(package manager)rustc(compiler)- Install via rustup
- Node.js 18+ with
npm - VS Code 1.85+ (for Extension Development Host)
- macOS (Intel and Apple Silicon)
- Linux (tested on Ubuntu/Debian)
- Windows 10/11
akatsuki-git/
├── Cargo.toml # Rust workspace root
├── shared/ # akatsuki-protocol crate
│ ├── src/lib.rs # Rust types (source of truth)
│ └── ts/protocol.ts # TypeScript mirror
├── backend/ # akatsuki-backend binary
│ └── src/ # Rust source files
└── extension/ # VS Code extension
├── package.json
└── src/ # TypeScript source files
From the repository root:
cargo buildThis builds the workspace and produces the binary at:
- Debug:
target/debug/akatsuki-backend - Release:
target/release/akatsuki-backend(usecargo build --release)
cd extension
npm install
npm run compile
npm run copy-protocolThe copy-protocol script copies shared/ts/protocol.ts → extension/src/protocol.ts.
# Clean all build artifacts
cargo clean
rm -rf extension/node_modules extension/out
# Rebuild
cargo build
cd extension && npm install && npm run compile && npm run copy-protocol-
Open the project in VS Code:
code /path/to/akatsuki-git
-
Open the Run and Debug view (or press
Cmd+Shift+D/Ctrl+Shift+D) -
Select "Run Extension" from the dropdown
-
Press
F5to launch the Extension Development Host -
Open a Git repository in the new window to activate Akatsuki Git
The .vscode/launch.json configuration handles:
- Spawning the backend binary
- Forwarding stderr to the "Akatsuki Git" output channel
- Enabling hot reload for TypeScript changes
# From repository root
code --extensionDevelopmentPath=$PWD/extensionThis launches a new VS Code window with the extension loaded.
Test the backend manually with JSON-RPC:
# Ping test
printf '{"jsonrpc":"2.0","id":1,"method":"ping","params":{}}\n' | ./target/debug/akatsuki-backend
# Handshake test
printf '{"jsonrpc":"2.0","id":1,"method":"handshake","params":{"version":1}}\n' | ./target/debug/akatsuki-backendExpected output:
{"jsonrpc":"2.0","id":1,"result":{}}Set the RUST_LOG environment variable:
# From VS Code launch.json (pre-configured)
"RUST_LOG": "akatsuki_backend=debug"
# Or in terminal
export RUST_LOG=akatsuki_backend=debugLogs appear in the "Akatsuki Git" output channel (the extension forwards stderr).
Option 1: Attach to running process
- Start extension via
F5 - Find the backend PID:
ps aux | grep akatsuki-backend - Attach using LLDB:
lldb -p <PID>
Option 2: LLDB VS Code Extension
- Install the LLDB extension
- Add a debug configuration in
.vscode/launch.json:{ "type": "lldb", "request": "attach", "name": "Attach to Backend", "program": "${workspaceFolder}/target/debug/akatsuki-backend" } - Set breakpoints in Rust code and attach
Option 3: CodeLLDB Extension
- Install CodeLLDB
- Use similar attach configuration as above
- Use VS Code's built-in debugger
- Set breakpoints in
.tsfiles - Console logs appear in the "Developer Tools" console (toggle via
Help → Toggle Developer Tools)
Create a test repository to verify rank progression:
# Create test repo
mkdir ~/test-akatsuki
cd ~/test-akatsuki
git init
# Create test commits to cross rank thresholds
for i in {1..100}; do
echo "Commit $i" > file.txt
git add file.txt
git commit -m "Test commit $i"
doneExpected ranks:
- 0–24: Academy Student
- 25–99: Genin
- 100–499: Chunin
- 500–1499: Jonin
- 1500–4999: Anbu
- 5000+: Akatsuki Member
When modifying protocol types:
- Edit Rust source: Update
shared/src/lib.rs - Mirror to TypeScript: Manually update
shared/ts/protocol.ts - Bump version: Increment
PROTOCOL_VERSIONconstant on both sides - Copy: Run
npm run copy-protocolinextension/ - Rebuild: Run
cargo buildandnpm run compile
Example change:
// shared/src/lib.rs
pub const PROTOCOL_VERSION: u32 = 2;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RankInfo {
pub rank: String,
pub rank_key: String,
pub current: u32,
pub next_threshold: Option<u32>,
pub progress: f64,
pub new_field: String, // Added in v2
}// shared/ts/protocol.ts
export const PROTOCOL_VERSION: number = 2;
export interface RankInfo {
rank: string;
rank_key: string;
current: number;
next_threshold: number | null;
progress: number;
new_field: string; // Added in v2
}Symptom: Extension fails to spawn backend
Solution:
# Ensure backend is built
cargo build
# Verify binary exists
ls -la target/debug/akatsuki-backendSymptom: TypeScript compilation errors about missing types
Solution:
cd extension
npm run copy-protocolSymptom: Status bar displays offline indicator
Solutions:
- Check the "Akatsuki Git" output channel for errors
- Enable debug logging: set
RUST_LOG=akatsuki_backend=debug - Verify backend is running: check Activity Monitor / Task Manager
- Try reloading the window:
Cmd+Shift+P→ "Reload Window"
Symptom: Extension logs "Protocol version mismatch" and deactivates
Solution:
- Ensure
PROTOCOL_VERSIONmatches on both sides - Rebuild backend and extension after protocol changes
- Run
npm run copy-protocolafter TypeScript changes
Symptom: Backend hangs, extension becomes unresponsive
Cause: Accidental stdout print in Rust code
Solution:
- Ensure all logging uses
logmacros (info!,debug!, etc.) - Never use
println!orprint!in backend code - Verify
RUST_LOGgoes to stderr, not stdout
Symptom: SQLite "database is locked" errors
Solutions:
- Check for other processes accessing the database
- Verify WAL mode is enabled: check backend logs
- Ensure
busy_timeoutis set (5000ms default) - Close all Extension Development Host windows and retry
Symptom: Repository analysis fails or shows incorrect counts
Solutions:
- Enable debug logging:
RUST_LOG=akatsuki_backend=debug - Check if repository is a shallow clone:
git rev-parse --is-shallow-repository
- Verify
gitCLI is available (fallback requires it) - Check file permissions for repository access
For local testing, use the existing workflow:
cargo build # Backend
cd extension && npm install && npm run compile # ExtensionCross-platform packaging requires bundling platform-specific binaries:
-
Build backend for each target:
# macOS (Intel) cargo build --release --target x86_64-apple-darwin # macOS (Apple Silicon) cargo build --release --target aarch64-apple-darwin # Linux cargo build --release --target x86_64-unknown-linux-gnu # Windows cargo build --release --target x86_64-pc-windows-msvc
-
Package extension with
vsce:npm install -g @vscode/vsce # Include platform-specific binary # (This is planned for future implementation) vsce package --target <platform>
Note: Full cross-platform packaging is planned for a future phase. Current development builds reference target/debug/akatsuki-backend directly.
Future steps for publishing to VS Code Marketplace:
- Create publisher account at marketplace.visualstudio.com
- Set
publisherinextension/package.json - Package with
vsce package - Upload via
vsce publish
- TypeScript: Changes recompile automatically (
npm run compile -- --watch) - Rust: Requires manual rebuild (
cargo build), then reload extension host
- Rust: Use
cargo fmtandcargo clippy - TypeScript: Use Prettier (pre-configured in extension)
- Unit tests: Add to
backend/src/*.rswith#[cfg(test)] - Integration tests: Create
backend/tests/*.rs - Extension tests: Use
vscode-testframework (planned)
# Format all Rust code
cargo fmt
# Check for Rust warnings
cargo clippy
# Run Rust tests
cargo test
# Watch TypeScript compilation
cd extension && npm run compile -- --watch
# Clean all build artifacts
cargo clean && rm -rf extension/node_modules extension/outAkatsuki Git ships a platform-specific Rust binary inside the VSIX. There is no universal build — each platform gets its own VSIX tagged with a target, and the Marketplace/Open VSX serve the correct one to each user automatically.
| Target | Runner (CI) | Rust triple |
|---|---|---|
darwin-arm64 |
macos-14 |
aarch64-apple-darwin |
darwin-x64 |
macos-15-intel |
x86_64-apple-darwin |
linux-x64 |
ubuntu-22.04 |
x86_64-unknown-linux-gnu |
win32-x64 |
windows-latest |
x86_64-pc-windows-msvc |
Linux ARM64 (
aarch64-unknown-linux-gnu) requires cross-compilation tooling and is intentionally omitted for now; add a matrix entry +crossif needed.
cd extension
# Package for the CURRENT platform (release binary bundled into the VSIX):
node scripts/package.mjs --target darwin-arm64 # use your host target
# For another target (requires `rustup target add <triple>`):
node scripts/package.mjs --target linux-x64The script builds the backend for the target, copies it into extension/bin/,
stages README.md/LICENSE from the repo root, runs vsce package --target,
then cleans up. The output is extension/akatsuki-git-<target>-<version>.vsix.
To inspect what a VSIX contains without building it:
cd extension && npx vsce lsYou should see bin/akatsuki-backend, out/**, media/**, README.md,
LICENSE, and package.json.
code --install-extension extension/akatsuki-git-darwin-arm64-0.1.0.vsix.github/workflows/build.yml runs on every push/PR: cargo fmt --check,
cargo clippy --workspace --tests -- -D warnings, cargo test --workspace, and
npm run compile (strict tsc).
The release is tag-driven. Pushing a v* tag triggers
.github/workflows/release.yml, which:
- Builds a VSIX on each platform runner (
build-vsixmatrix). - Publishes every VSIX to the VS Code Marketplace (
vsce publish) and Open VSX (ovsx publish) (publishjob). - Creates a GitHub Release with all VSIXs attached and auto-generated notes.
git tag v0.1.0
git push origin v0.1.0- Choose a
publisherinextension/package.json(currentlyakatsuki). The publisher ID must exist on both marketplaces. - VS Code Marketplace — create a publisher at
https://marketplace.visualstudio.com/manage, generate a Personal Access
Token from Azure DevOps (
Manage Publishing Tokens), and add it as theVSCE_PATrepository secret. - Open VSX — create an Eclipse Access Token at https://open-vsx.org and
add it as the
OVSX_PATrepository secret. - Verify metadata before the first release:
repository,bugs,homepage, andlicenseinextension/package.json(currently pointing atrubyazz/akatsuki-git), and bumpversion. - (Optional) Add an icon: add a 128×128+ PNG at
extension/media/icon.pngand set"icon": "media/icon.png"inpackage.json. Without it the listing uses a generic icon.
If you only want to produce VSIXs for testing without publishing, run the
workflow via workflow_dispatch (defaults to dry_run: true) or call
scripts/package.mjs locally.
- Check the Architecture document for implementation details
- Review the Roadmap for planned features
- Enable debug logging to inspect runtime behavior
- Use VS Code's built-in TypeScript debugging for extension issues
- Use LLDB for backend Rust issues