Building SpecTacular
This guide covers building both the CLI tool and VS Code extension from source.
Prerequisites
For CLI Development
- .NET 8 SDK - Download
- Git - For cloning the repository
- PowerShell - For installation scripts (Windows)
For Extension Development
Clone Repository
git clone https://github.com/Tadzesi/SpecTacular.git
cd SpecTacularBuilding the CLI
Development Build
cd spectacular-cli/Spectacular.Cli
dotnet buildOutput: bin/Debug/net8.0/spectacular.exe
Release Build
dotnet build -c ReleaseOutput: bin/Release/net8.0/spectacular.exe
Publish Single-File Executable
dotnet publish -c Release -r win-x64 -o ../publish/win-x64Output: spectacular-cli/publish/win-x64/spectacular.exe
Options:
-c Release- Release configuration-r win-x64- Target Windows x64-o <path>- Output directory--self-contained- Include .NET runtime (already configured)/p:PublishSingleFile=true- Single file (already configured)/p:PublishTrimmed=true- Trim unused code (already configured)
Run Locally
# Run from source
dotnet run -- init --help
# Or run published executable
..\publish\win-x64\spectacular.exe --versionInstall Locally for Testing
cd ..\installer
.\install.ps1 -LocalThis installs from ../publish/win-x64/ instead of downloading from GitHub.
Verify:
spectacular --versionRun Tests
cd .. # Back to spectacular-cli/
dotnet testWith coverage:
dotnet test --collect:"XPlat Code Coverage"Building the VS Code Extension
Install Dependencies
cd spectacular-vscode
npm installThis installs dependencies for both the extension and webview.
Development Build
Watch mode (recommended for development):
npm run watchThis starts two watch processes:
- Extension host compilation (TypeScript)
- Webview compilation (React + Vite)
Single build:
npm run compileBuild Components Separately
Extension host only:
npm run compile:extensionWebview only:
npm run compile:webviewRun Extension in Development
- Open
spectacular-vscode/in VS Code - Press
F5(or Run → Start Debugging) - Extension Development Host window opens
- Test your changes
Hot reload:
- Webview changes hot-reload automatically
- Extension host changes require window reload (
Ctrl+R)
Package Extension
Create a .vsix file for distribution:
npm run packageOutput: spectacular-dashboard-1.6.6.vsix
Install packaged extension:
code --install-extension spectacular-dashboard-1.6.6.vsixRun Tests
Extension tests:
npm testWebview tests:
cd webview
npm testProject Structure
CLI Structure
spectacular-cli/
├── Spectacular.Cli/ # Main project
│ ├── Commands/ # CLI commands
│ │ ├── InitCommand.cs
│ │ └── UpdateCommand.cs
│ ├── Services/ # Business logic
│ │ ├── ScaffoldService.cs
│ │ ├── TemplateService.cs
│ │ └── ConfigService.cs
│ ├── Resources/templates/ # Embedded resources
│ │ ├── .claude/
│ │ ├── .spectacular/
│ │ └── CLAUDE.md
│ ├── Program.cs # Entry point
│ └── Spectacular.Cli.csproj # Project file
├── Spectacular.Cli.Tests/ # Unit tests
│ └── ...
├── publish/ # Build output (gitignored)
└── installer/
└── install.ps1 # Installation scriptExtension Structure
spectacular-vscode/
├── src/ # Extension host (TypeScript)
│ ├── extension.ts # Entry point
│ ├── DashboardPanel.ts # Main webview panel
│ ├── DashboardViewProvider.ts # Sidebar provider
│ ├── SpecsTreeProvider.ts # Tree view
│ ├── TaskStatusService.ts # Auto-status logic
│ ├── FileDecorationProvider.ts # Modified indicators
│ ├── VersionCheckService.ts # Update checker
│ └── fileOperations.ts # File utilities
├── webview/ # React UI
│ ├── src/
│ │ ├── App.tsx # Main React component
│ │ ├── components/ # UI components (13 files)
│ │ ├── hooks/ # Custom hooks (5 files)
│ │ ├── contexts/ # React contexts
│ │ └── utils/ # Utilities
│ ├── public/ # Static assets
│ ├── package.json # Webview dependencies
│ ├── vite.config.ts # Vite configuration
│ └── tsconfig.json # TypeScript config
├── dist/ # Build output (gitignored)
├── package.json # Extension dependencies
├── tsconfig.json # Extension TypeScript config
└── esbuild.js # Build scriptBuild Scripts
CLI Scripts
Defined in: Spectacular.Cli.csproj
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<PublishTrimmed>true</PublishTrimmed>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>Extension Scripts
Defined in: spectacular-vscode/package.json
{
"scripts": {
"compile": "npm run compile:extension && npm run compile:webview",
"compile:extension": "node esbuild.js",
"compile:webview": "cd webview && npm run build",
"watch": "concurrently \"npm run watch:extension\" \"npm run watch:webview\"",
"watch:extension": "node esbuild.js --watch",
"watch:webview": "cd webview && npm run dev",
"package": "vsce package",
"publish": "vsce publish",
"test": "node ./out/test/runTest.js"
}
}Development Workflow
CLI Workflow
- Make changes to source files
- Build:
dotnet build - Test:
dotnet test - Run:
dotnet run -- <command> - Publish:
dotnet publish -c Release -r win-x64 - Install locally:
cd installer && .\install.ps1 -Local - Test installed:
spectacular --version
Extension Workflow
- Start watch mode:
npm run watch - Open in VS Code: Open
spectacular-vscode/folder - Start debugging: Press
F5 - Make changes:
- Extension host: Edit
src/*.ts→ Reload window (Ctrl+R) - Webview: Edit
webview/src/*.tsx→ Auto hot-reload
- Extension host: Edit
- Test changes in Extension Development Host
- Run tests:
npm test - Package:
npm run package
Common Build Issues
CLI Issues
Issue: error NU1101: Unable to find package
Solution:
dotnet restore
dotnet buildIssue: .NET SDK not found
Solution: Install .NET 8 SDK from https://dot.net
Issue: Embedded resource not found
Solution: Check .csproj file:
<ItemGroup>
<EmbeddedResource Include="Resources\templates\**\*" />
</ItemGroup>Extension Issues
Issue: npm install fails
Solution:
rm -rf node_modules package-lock.json
npm installIssue: Webview not loading
Solution:
cd webview
rm -rf node_modules dist
npm install
npm run build
cd ..
npm run compile:extensionIssue: Extension not activating
Solution: Check package.json activation events:
{
"activationEvents": [
"workspaceContains:**/.spectacular",
"workspaceContains:**/specs"
]
}Issue: TypeScript errors
Solution:
# Extension
npm run compile:extension
# Webview
cd webview
npm run buildPerformance Optimization
CLI Optimizations
Build for size:
dotnet publish -c Release -r win-x64 /p:PublishTrimmed=true /p:TrimMode=LinkBuild for speed:
dotnet publish -c Release -r win-x64 /p:PublishReadyToRun=trueExtension Optimizations
Minified build:
# Already configured in vite.config.ts
npm run compile:webviewBundle analysis:
cd webview
npm run build -- --mode analyzeDebugging
Debug CLI
VS Code launch.json:
{
"type": "coreclr",
"request": "launch",
"name": "Debug CLI",
"program": "${workspaceFolder}/spectacular-cli/Spectacular.Cli/bin/Debug/net8.0/spectacular.exe",
"args": ["init", "--name", "TestProject"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}Debug Extension
Built-in debugger:
- Press
F5in VS Code - Set breakpoints in
src/*.ts - Breakpoints hit when extension runs
Debug webview:
- In Extension Development Host: View → Developer Tools
- Console tab shows webview logs
- Sources tab for debugging React code
Debug Tests
CLI tests:
dotnet test --logger "console;verbosity=detailed"Extension tests:
npm test -- --debugContinuous Integration
GitHub Actions (Example)
name: Build and Test
on: [push, pull_request]
jobs:
cli:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- run: cd spectacular-cli && dotnet build
- run: cd spectacular-cli && dotnet test
extension:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: cd spectacular-vscode && npm ci
- run: cd spectacular-vscode && npm run compile
- run: cd spectacular-vscode && npm testNext Steps
- Testing Guide - How to test your changes
- Contributing - Contribution guidelines
- Release Process - How releases are made
- Architecture - Understand the codebase