Skip to content

Latest commit

 

History

History
487 lines (339 loc) · 17.7 KB

File metadata and controls

487 lines (339 loc) · 17.7 KB

Contributing to Copilot Token Tracker

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.

Table of Contents

Development Environment Setup

You have two options for setting up your development environment:

  1. Using the DevContainer (Recommended for AI-assisted development)
  2. Manual local setup

Prerequisites

Using the DevContainer (Recommended)

Quick Start

  1. Clone the repository:

    git clone https://github.com/rajbos/github-copilot-token-usage.git
    cd github-copilot-token-usage
  2. Open in VS Code:

    code .
  3. Reopen in Container:

    • When prompted, click "Reopen in Container"
    • Or use the Command Palette (F1) and select Dev Containers: Reopen in Container
  4. 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
  5. Start developing:

    • Run npm run watch to start the TypeScript compiler in watch mode
    • Press F5 to launch the Extension Development Host

What's Included in the DevContainer?

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

Why Use a DevContainer for AI-Assisted Development?

The devcontainer is especially valuable when working with AI coding assistants like GitHub Copilot or other AI agents. Here's why:

🛡️ Isolation and Safety

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

🤖 AI Freedom Without Fear

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

🔄 Consistency Across Development

  • 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

🚀 Faster Onboarding for AI

  • 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 postCreateCommand ensures dependencies are always up-to-date

💡 Real-World Scenario

Imagine this workflow with AI assistance:

  1. You ask: "Add support for tracking a new model type"
  2. AI suggests: Code changes + a new npm package dependency
  3. AI executes: npm install <new-package> directly in the container
  4. AI tests: Runs the extension and verifies it works
  5. 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

Manual Local Setup

If you prefer not to use the devcontainer, you can set up the extension locally:

Prerequisites

Setup Steps

  1. Clone the repository:

    git clone https://github.com/rajbos/github-copilot-token-usage.git
    cd github-copilot-token-usage
  2. Install dependencies:

    npm install

    Note: The project uses package-lock.json for reproducible builds. The .npmrc file ensures consistent behavior across different npm versions and environments. CI/CD workflows use npm ci to ensure exact dependency versions are installed.

  3. Build the extension:

    npm run compile
  4. Start developing:

    • Run npm run watch for auto-rebuild on changes
    • Press F5 to launch the Extension Development Host

Development Workflow

Build and Compile

# One-time build
npm run compile

# Watch mode (auto-rebuild on changes)
npm run watch

# Production build
npm run package

Running the Extension

To test and debug the extension in a local VS Code environment:

  1. Install dependencies (if not already done):

    npm install
  2. Start watch mode (automatically recompiles on file changes):

    npm run watch
  3. Press F5 in 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
  4. 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
  5. 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.log output from the extension

Creating a VSIX Package

To create an installable VSIX package:

npx vsce package

Debugging

  • Set breakpoints in src/extension.ts or other TypeScript files
  • Press F5 to start debugging
  • Open Developer Tools in the Extension Development Host: Help > Toggle Developer Tools
  • View console output in the Debug Console

Available Scripts

  • npm run lint - Run ESLint to check code quality
  • npm run lint:css - Run Stylelint to check CSS code quality
  • npm run lint:json - Validate all JSON files in the repository
  • npm run check-types - Run TypeScript type checking
  • npm 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 mode
  • npm run watch:esbuild - esbuild bundler in watch mode
  • npm test - Run tests (requires VS Code)
  • npm run watch-tests - Run tests in watch mode

NPM and Dependency Management

The project uses package-lock.json for reproducible builds and dependency consistency across all environments.

Key Files

  • .npmrc: Configures npm behavior (use save-exact=true, etc.)
  • package-lock.json: Lockfile that pins exact dependency versions (committed to the repository)
  • package.json: Defines project dependencies and scripts

Installation Commands

RECOMMENDED for day-to-day development:

  • npm ci: Clean install from lockfile
    • Requires package-lock.json to exist
    • Installs exact versions from the lockfile (no modifications)
    • Deletes node_modules before 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

Only when adding/updating dependencies:

  • npm install: Install/update dependencies
    • Respects package-lock.json and 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.json and package-lock.json

Best Practices

  1. Use npm ci for routine development - This prevents accidental lockfile changes and ensures you have the exact dependency versions
  2. Only use npm install when intentionally changing dependencies - This makes dependency updates explicit and trackable
  3. Always commit both files together - When you modify dependencies, commit both package.json and package-lock.json in the same commit
  4. Don't manually edit package-lock.json - Let npm manage it automatically

Why We Use package-lock.json

  1. Reproducible Builds: Ensures all developers and CI/CD get identical dependency versions
  2. Consistency: Prevents "works on my machine" issues caused by different dependency versions
  3. Security: Locks down transitive dependencies to prevent supply chain attacks
  4. Performance: CI/CD can cache dependencies more effectively with a lockfile

About Peer Dependencies and "peer": true

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 ci for routine development (doesn't modify the lockfile)
  • Only use npm install when you're intentionally adding or updating dependencies
  • If you accidentally modify the lockfile, run git checkout package-lock.json to restore it

Code Guidelines

Project Structure

  • All extension logic is in src/extension.ts in the CopilotTokenTracker class
  • Data files are in JSON format: tokenEstimators.json, modelPricing.json, toolNames.json
  • Webview code is in src/webview/ organized by feature
  • See src/README.md for detailed guidance on updating JSON data files

Development Principles

  1. Minimal Changes: Only modify files directly needed for your changes
  2. Focused Modifications: Make surgical, precise changes
  3. Preserve Structure: Maintain existing code organization
  4. Follow Conventions: See .github/copilot-instructions.md for extension-specific patterns

Before Submitting

Always run a full build to ensure code quality:

npm run compile

This will:

  • Lint your code with ESLint
  • Type-check with TypeScript
  • Build the extension with esbuild

JSON File Validation

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:json

Note: JSON validation is automatically run in CI/CD pipelines to catch syntax errors early.

Testing

  • 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 test to execute automated tests
  • Ensure all tests pass before submitting changes

CI/CD

The project includes comprehensive GitHub Actions workflows:

Build Pipeline

  • Platforms: Tests on Ubuntu, Windows, and macOS
  • Node Versions: 18.x and 20.x
  • Checks: Linting, type checking, compilation, and packaging
  • Badge: Build

What Gets Tested

  1. JSON Validation: All JSON and JSONC files are validated for correct syntax
  2. Linting: ESLint checks for code quality issues
  3. Type Checking: TypeScript validates all types
  4. Compilation: esbuild creates the production bundle
  5. Packaging: VSIX package is created and validated
  6. Extension Tests: VS Code extension tests run in CI

All builds must pass these checks before merging.

Pre-Release Checklist

Run npm run pre-release to validate the version and compile.

  • Version bumped in package.json
  • npm run compile completed 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.

Release Process

The project uses a fully automated release pipeline via GitHub Actions.

One-Step Release (Recommended)

  1. Update the version in package.json
  2. Commit and push to the main branch
  3. Go to GitHub Actions → Release workflow → Run workflow

The workflow inputs:

  • create_tag — Creates a git tag from the package.json version (default: true)
  • publish_marketplace — Publishes to the VS Code Marketplace (default: true)

The workflow automatically:

  1. Creates a version tag (e.g., v0.0.19)
  2. Generates release notes from merged PRs (using .github/release.yml categories)
  3. Updates CHANGELOG.md in the VSIX package so the extension ships with current notes
  4. Runs the full build pipeline (lint, type-check, compile, test)
  5. Creates a GitHub Release with the VSIX attached
  6. Publishes to the VS Code Marketplace (using the VSCE_PAT secret)
  7. Opens a PR to sync CHANGELOG.md in the repository

Security: Only users with repository write access can trigger the workflow_dispatch. The VSCE_PAT secret must be configured in repository settings (Settings → Secrets and variables → Actions). Create a PAT at https://dev.azure.com with the "Marketplace (Publish)" scope.

Tag-Based Release (Build Only)

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.

Manual Changelog Sync

To manually sync the changelog with all GitHub release notes:

npm run sync-changelog

Or trigger the Sync Release Notes workflow from the Actions tab.

Manual Publish (Fallback)

If you need to re-publish manually (e.g., after a marketplace upload failure):

.\publish.ps1 -VsixPath ".\copilot-token-tracker-0.0.19.vsix"

Submitting Changes

  1. Fork the repository on GitHub
  2. Create a feature branch from main
  3. Make your changes in the devcontainer
  4. Test thoroughly using the Extension Development Host
  5. Run npm run compile to ensure everything builds
  6. Commit with clear messages describing your changes
  7. Push to your fork and create a Pull Request

Pull Request Guidelines

  • 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

Questions or Issues?

  • 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

Additional Resources


Thank you for contributing! Your efforts help make token tracking better for the entire GitHub Copilot community. 🚀