Thank you for your interest in contributing to the Copilot Token Tracker extension! This guide will help you get started with development, especially when working with AI assistants like GitHub Copilot.
- Development Environment Setup
- Using the DevContainer (Recommended)
- Why Use a DevContainer for AI-Assisted Development?
- Manual Local Setup
- Development Workflow
- Available Scripts
- Code Guidelines
- Testing
- CI/CD
- Pre-Release Checklist
- Release Process
- Submitting Changes
You have two options for setting up your development environment:
- Using the DevContainer (Recommended for AI-assisted development)
- Manual local setup
- Visual Studio Code
- Docker Desktop
- Dev Containers extension for VS Code
-
Clone the repository:
git clone https://github.com/rajbos/github-copilot-token-usage.git cd github-copilot-token-usage -
Open in VS Code:
code . -
Reopen in Container:
- When prompted, click "Reopen in Container"
- Or use the Command Palette (
F1) and select Dev Containers: Reopen in Container
-
Wait for setup:
- The container will build and initialize automatically
- Dependencies will be installed via
npm install(runs automatically) - All required VS Code extensions will be pre-installed
-
Start developing:
- Run
npm run watchto start the TypeScript compiler in watch mode - Press
F5to launch the Extension Development Host
- Run
The devcontainer provides a complete, pre-configured development environment:
- Base Image: Node.js 22 on Debian Bookworm
- Pre-installed Tools:
- Git
- PowerShell (for running build scripts)
- Node.js and npm
- VS Code Extensions:
- ESLint (code linting)
- Prettier (code formatting)
- Extension Test Runner
- TSL Problem Matcher
- GitHub Copilot & Copilot Chat
- Optimized Settings:
- Format on save enabled
- ESLint integration
- TypeScript support
The devcontainer is especially valuable when working with AI coding assistants like GitHub Copilot or other AI agents. Here's why:
When you give AI assistants permission to execute commands, install packages, or make system changes, you want protection:
- Sandboxed Environment: The container runs in complete isolation from your host machine
- No Host System Impact: AI-suggested npm installs, file operations, or scripts can't affect your personal system
- Easy Reset: If something goes wrong, you can rebuild the container in minutes without affecting your machine
- Reproducible State: Every time you rebuild, you get the same clean environment
The devcontainer allows you to confidently let AI assistants:
- Execute Commands Freely: Let AI run
npm install, build scripts, or test commands without worrying about side effects - Install Packages: AI can suggest and install experimental packages without polluting your global environment
- Modify Configuration: Let AI experiment with settings, configs, or tooling versions safely
- Run Tests: Execute test suites that might create temporary files or modify state
- Try Experimental Changes: Let AI make bold refactoring suggestions you can test risk-free
- Identical Environments: Everyone (including AI) works with the exact same Node version, dependencies, and tools
- Version Lock: No "works on my machine" issues caused by different Node or npm versions
- Extension Parity: All developers have the same VS Code extensions and settings
- Reproducible Builds: AI-assisted changes will behave the same way for all contributors
- Zero Configuration: AI can start working immediately without environment setup
- Pre-installed Tools: All required dependencies are ready to go
- Known State: AI agents can make more accurate suggestions knowing the exact environment
- Automatic Setup: The
postCreateCommandensures dependencies are always up-to-date
Imagine this workflow with AI assistance:
- You ask: "Add support for tracking a new model type"
- AI suggests: Code changes + a new npm package dependency
- AI executes:
npm install <new-package>directly in the container - AI tests: Runs the extension and verifies it works
- Result: If something breaks, you simply rebuild the container - your host machine is untouched
Without a devcontainer, you'd need to:
- Manually review every command before execution
- Worry about package conflicts with other projects
- Risk system-level changes
- Potentially need to uninstall packages or revert changes
If you prefer not to use the devcontainer, you can set up the extension locally:
- Node.js 18.x or 20.x
- npm (comes with Node.js)
- Visual Studio Code
- Git
-
Clone the repository:
git clone https://github.com/rajbos/github-copilot-token-usage.git cd github-copilot-token-usage -
Install dependencies:
npm install
Note: The project uses
package-lock.jsonfor reproducible builds. The.npmrcfile ensures consistent behavior across different npm versions and environments. CI/CD workflows usenpm cito ensure exact dependency versions are installed. -
Build the extension:
npm run compile
-
Start developing:
- Run
npm run watchfor auto-rebuild on changes - Press
F5to launch the Extension Development Host
- Run
# One-time build
npm run compile
# Watch mode (auto-rebuild on changes)
npm run watch
# Production build
npm run packageTo test and debug the extension in a local VS Code environment:
-
Install dependencies (if not already done):
npm install
-
Start watch mode (automatically recompiles on file changes):
npm run watch
-
Press
F5in VS Code to launch the Extension Development Host- This opens a new VS Code window with the extension running
- The original window shows debug output and allows you to set breakpoints
-
In the Extension Development Host window:
- The extension will be active and you'll see the token tracker in the status bar
- Any changes you make to the code will be automatically compiled (thanks to watch mode)
- Reload the Extension Development Host window (Ctrl+R or Cmd+R) to see your changes
-
To view console logs and debug information:
- In the Extension Development Host window, open Developer Tools:
Help > Toggle Developer Tools - Check the Console tab for any
console.logoutput from the extension
- In the Extension Development Host window, open Developer Tools:
To create an installable VSIX package:
npx vsce package- Set breakpoints in
src/extension.tsor other TypeScript files - Press
F5to start debugging - Open Developer Tools in the Extension Development Host:
Help > Toggle Developer Tools - View console output in the Debug Console
npm run lint- Run ESLint to check code qualitynpm run lint:css- Run Stylelint to check CSS code qualitynpm run lint:json- Validate all JSON files in the repositorynpm run check-types- Run TypeScript type checkingnpm run compile- Build development version (includes linting and type checking)npm run package- Build production version (optimized)npm run watch- Watch mode for development (auto-recompile on changes)npm run watch:tsc- TypeScript compiler in watch modenpm run watch:esbuild- esbuild bundler in watch modenpm test- Run tests (requires VS Code)npm run watch-tests- Run tests in watch mode
The project uses package-lock.json for reproducible builds and dependency consistency across all environments.
.npmrc: Configures npm behavior (usesave-exact=true, etc.)package-lock.json: Lockfile that pins exact dependency versions (committed to the repository)package.json: Defines project dependencies and scripts
RECOMMENDED for day-to-day development:
npm ci: Clean install from lockfile- Requires
package-lock.jsonto exist - Installs exact versions from the lockfile (no modifications)
- Deletes
node_modulesbefore installing - Use this after pulling changes to avoid lockfile churn
- Used in all CI/CD workflows for reproducible builds
- Faster and more reliable than
npm install
- Requires
Only when adding/updating dependencies:
npm install: Install/update dependencies- Respects
package-lock.jsonand may update it - Use when adding new dependencies:
npm install <package> - Use when updating dependencies:
npm install <package>@latest - After adding dependencies, commit both
package.jsonandpackage-lock.json
- Respects
- Use
npm cifor routine development - This prevents accidental lockfile changes and ensures you have the exact dependency versions - Only use
npm installwhen intentionally changing dependencies - This makes dependency updates explicit and trackable - Always commit both files together - When you modify dependencies, commit both
package.jsonandpackage-lock.jsonin the same commit - Don't manually edit
package-lock.json- Let npm manage it automatically
- Reproducible Builds: Ensures all developers and CI/CD get identical dependency versions
- Consistency: Prevents "works on my machine" issues caused by different dependency versions
- Security: Locks down transitive dependencies to prevent supply chain attacks
- Performance: CI/CD can cache dependencies more effectively with a lockfile
Different npm versions (7+) may add or remove "peer": true properties in package-lock.json when running npm install. This is expected behavior for peer dependencies that aren't satisfied.
Some dependencies (like @vscode/webview-ui-toolkit) declare peer dependencies (e.g., react) that we don't use directly. You may see entries like this in package-lock.json:
"node_modules/react": {
"version": "19.2.3",
"peer": true,
...
}This is normal and doesn't affect functionality. To avoid lockfile churn from these changes:
- Use
npm cifor routine development (doesn't modify the lockfile) - Only use
npm installwhen you're intentionally adding or updating dependencies - If you accidentally modify the lockfile, run
git checkout package-lock.jsonto restore it
- All extension logic is in
src/extension.tsin theCopilotTokenTrackerclass - Data files are in JSON format:
tokenEstimators.json,modelPricing.json,toolNames.json - Webview code is in
src/webview/organized by feature - See
src/README.mdfor detailed guidance on updating JSON data files
- Minimal Changes: Only modify files directly needed for your changes
- Focused Modifications: Make surgical, precise changes
- Preserve Structure: Maintain existing code organization
- Follow Conventions: See
.github/copilot-instructions.mdfor extension-specific patterns
Always run a full build to ensure code quality:
npm run compileThis will:
- Lint your code with ESLint
- Type-check with TypeScript
- Build the extension with esbuild
The repository includes automatic validation of all JSON files. This ensures that:
- All JSON files contain valid JSON syntax
- JSONC files (JSON with Comments) are properly formatted
- Configuration files (tsconfig, VS Code settings) are valid
Validated Files:
- Core JSON data:
src/tokenEstimators.json,src/modelPricing.json,src/toolNames.json,src/customizationPatterns.json - Configuration:
package.json,tsconfig.json,.vscode/*.json,.devcontainer/devcontainer.json - Schemas:
docs/logFilesSchema/*.json
Run JSON validation manually:
npm run lint:jsonNote: JSON validation is automatically run in CI/CD pipelines to catch syntax errors early.
- Test the extension manually in the Extension Development Host (F5)
- Verify token tracking works correctly
- Check that webviews render properly
- Ensure status bar updates as expected
- Run
npm testto execute automated tests - Ensure all tests pass before submitting changes
The project includes comprehensive GitHub Actions workflows:
- Platforms: Tests on Ubuntu, Windows, and macOS
- Node Versions: 18.x and 20.x
- Checks: Linting, type checking, compilation, and packaging
- Badge:
- JSON Validation: All JSON and JSONC files are validated for correct syntax
- Linting: ESLint checks for code quality issues
- Type Checking: TypeScript validates all types
- Compilation: esbuild creates the production bundle
- Packaging: VSIX package is created and validated
- Extension Tests: VS Code extension tests run in CI
All builds must pass these checks before merging.
Run npm run pre-release to validate the version and compile.
- Version bumped in
package.json -
npm run compilecompleted successfully - Commit and push to main branch
- Trigger Release workflow (GitHub UI → Actions → Release → Run workflow)
The workflow handles everything else: tagging, building, testing, creating the GitHub release, publishing to the marketplace, and updating the changelog.
The project uses a fully automated release pipeline via GitHub Actions.
- Update the version in
package.json - Commit and push to the main branch
- Go to GitHub Actions → Release workflow → Run workflow
The workflow inputs:
create_tag— Creates a git tag from thepackage.jsonversion (default: true)publish_marketplace— Publishes to the VS Code Marketplace (default: true)
The workflow automatically:
- Creates a version tag (e.g.,
v0.0.19) - Generates release notes from merged PRs (using
.github/release.ymlcategories) - Updates
CHANGELOG.mdin the VSIX package so the extension ships with current notes - Runs the full build pipeline (lint, type-check, compile, test)
- Creates a GitHub Release with the VSIX attached
- Publishes to the VS Code Marketplace (using the
VSCE_PATsecret) - Opens a PR to sync
CHANGELOG.mdin the repository
Security: Only users with repository write access can trigger the
workflow_dispatch. TheVSCE_PATsecret must be configured in repository settings (Settings → Secrets and variables → Actions). Create a PAT at https://dev.azure.com with the "Marketplace (Publish)" scope.
Pushing a version tag (e.g., git push origin v0.0.19) triggers the build and creates a GitHub release, but does not publish to the marketplace. Use the workflow dispatch for the full pipeline.
To manually sync the changelog with all GitHub release notes:
npm run sync-changelogOr trigger the Sync Release Notes workflow from the Actions tab.
If you need to re-publish manually (e.g., after a marketplace upload failure):
.\publish.ps1 -VsixPath ".\copilot-token-tracker-0.0.19.vsix"- Fork the repository on GitHub
- Create a feature branch from
main - Make your changes in the devcontainer
- Test thoroughly using the Extension Development Host
- Run
npm run compileto ensure everything builds - Commit with clear messages describing your changes
- Push to your fork and create a Pull Request
- Provide a clear description of what your PR does
- Reference any related issues
- Include screenshots/videos for UI changes
- Ensure all checks pass
- Be responsive to code review feedback
- Bug Reports: Open an issue on GitHub Issues
- Feature Requests: Submit as a GitHub issue with the "enhancement" label
- Questions: Ask in the issue comments or discussions
Thank you for contributing! Your efforts help make token tracking better for the entire GitHub Copilot community. 🚀