15 min to read
Copilot CLI Learning Series #6: Project β Build with Copilot CLI
Image credit: GitHub Blog
Project: Build with Copilot CLI
TL;DR: Build a complete CLI tool from scratch using GitHub Copilot CLI in under 90 minutes. Weβll create a productivity tracker CLI app with features like task management, time tracking, and reporting - all using Copilot CLI for code generation, documentation, testing, and deployment. By the end, youβll have a publishable npm package and understand real-world CLI development workflows. (GitHub, 2026)
Welcome to the sixth and final post in the Copilot CLI Learning Series! In this hands-on guide, youβll learn how to build, document, test, and deploy a complete CLI-driven application using GitHub Copilot CLI. Weβll walk through the entire workflow: planning, scaffolding, coding, code review, documentation, testing, and deployment - all while leveraging Copilot CLIβs AI assistance.
What weβre building: A productivity tracker CLI tool called task-cli that helps developers manage tasks and track time directly from the terminal.
Prerequisites:
- Completed Parts 1-5 of this series
- Node.js v18+ installed
- GitHub account with Copilot subscription
- Basic TypeScript/JavaScript knowledge
- 60-90 minutes
[STAT: Developers using Copilot CLI for project scaffolding report 60% faster initial setup and 45% fewer boilerplate errors (GitHub Developer Survey, 2026).]
Table of Contents
- Project Planning
- Scaffolding the CLI App
- Implementing Core Features
- Code Review and Quality
- Documentation and Accessibility
- Testing Strategy
- Deployment
- FAQ
- Summary and Next Steps
Project Planning
Before writing any code, letβs use Copilot CLI to help plan our project structure and requirements.
Step 1: Define Project Requirements
gh copilot -p "Create a project requirements document for a CLI productivity tracker with task management and time tracking features"
Key features weβll implement:
- Add, list, complete, and delete tasks
- Start/stop time tracking for tasks
- Generate productivity reports
- Export data to JSON/CSV
- Configuration management
Step 2: Choose Technology Stack
gh copilot -p "Recommend a tech stack for building a TypeScript CLI tool with these considerations: ease of testing, npm publishing, cross-platform support"
Our stack:
- Language: TypeScript (type safety + tooling)
- CLI Framework: Commander.js (argument parsing)
- Database: Lowdb (JSON file storage)
- Testing: Jest (unit + integration tests)
- Build: esbuild (fast compilation)
Architecture diagram:
User Terminal
β
Commander.js (CLI Interface)
β
Task Manager (Business Logic)
β
Lowdb (Data Persistence)
Scaffolding the CLI App
Letβs use Copilot CLI to scaffold our project structure efficiently.
Step 1: Initialize Project
# Create project directory
mkdir task-cli && cd task-cli
# Use Copilot to generate npm init command with best practices
gh copilot -p "Generate npm init command for a TypeScript CLI tool named task-cli"
# Initialize with suggested values
npm init -y
Step 2: Install Dependencies
# Generate install command for all required packages
gh copilot -p "Generate npm install command for commander.js, lowdb v6, typescript, jest, @types/node, @types/jest, esbuild"
# Execute suggested command
npm install commander lowdb
npm install -D typescript @types/node jest @types/jest ts-jest esbuild @types/commander
Step 3: Project Structure
# Use Copilot to create directory structure
gh copilot -p "Create directory structure for TypeScript CLI: src, tests, dist, with subdirectories for commands, utils, types"
Resulting structure:
task-cli/
βββ src/
β βββ commands/
β β βββ add.ts
β β βββ list.ts
β β βββ complete.ts
β β βββ track.ts
β βββ utils/
β β βββ db.ts
β β βββ reporter.ts
β βββ types/
β β βββ index.ts
β βββ index.ts
βββ tests/
β βββ commands/
βββ dist/
βββ package.json
βββ tsconfig.json
βββ README.md
Step 4: Configuration Files
# Generate tsconfig.json
gh copilot -p "Generate tsconfig.json for a Node.js CLI tool targeting ES2022"
# Generate jest.config.js
gh copilot -p "Generate jest.config.js for TypeScript with ts-jest"
Implementing Core Features
Now letβs build the actual functionality using Copilot CLI to accelerate development.
Step 1: Define Types
// src/types/index.ts
gh copilot -p "Generate TypeScript interfaces for: Task (id, title, description, completed, createdAt, timeSpent), Config (dataPath, defaultView)"
// Copilot suggests:
export interface Task {
id: string;
title: string;
description?: string;
completed: boolean;
createdAt: Date;
timeSpent: number; // in minutes
tags: string[];
}
export interface Config {
dataPath: string;
defaultView: 'all' | 'pending' | 'completed';
timezone: string;
}
Step 2: Database Layer
// src/utils/db.ts
gh copilot -p "Write a database utility class using Lowdb v6 for storing tasks with methods: getTasks, addTask, updateTask, deleteTask"
// Copilot generates:
import { Low } from 'lowdb';
import { JSONFile } from 'lowdb/node';
import { Task } from '../types';
interface Data {
tasks: Task[];
}
export class TaskDatabase {
private db: Low<Data>;
async initialize(filePath: string) {
const adapter = new JSONFile<Data>(filePath);
this.db = new Low(adapter, { tasks: [] });
await this.db.read();
}
async getTasks(): Promise<Task[]> {
await this.db.read();
return this.db.data.tasks;
}
async addTask(task: Omit<Task, 'id'>): Promise<Task> {
const newTask = { ...task, id: crypto.randomUUID() };
this.db.data.tasks.push(newTask);
await this.db.write();
return newTask;
}
// Additional methods generated by Copilot...
}
Step 3: CLI Commands
// src/commands/add.ts
gh copilot -p "Write a Commander.js command to add a task with options for title, description, and tags"
// Copilot generates:
import { Command } from 'commander';
import { TaskDatabase } from '../utils/db';
export const addCommand = new Command('add')
.description('Add a new task')
.argument('<title>', 'Task title')
.option('-d, --description <desc>', 'Task description')
.option('-t, --tags <tags>', 'Comma-separated tags')
.action(async (title, options) => {
const db = new TaskDatabase();
await db.initialize('./tasks.json');
const task = await db.addTask({
title,
description: options.description,
completed: false,
createdAt: new Date(),
timeSpent: 0,
tags: options.tags ? options.tags.split(',') : [],
});
console.log(`β
Task added: ${task.title} (ID: ${task.id})`);
});
Step 4: Time Tracking Feature
// src/commands/track.ts
gh copilot -p "Implement time tracking command that starts/stops a timer for a task and updates timeSpent"
// Copilot generates a sophisticated tracking solution with file-based state management
[INFO-GAIN: Using Copilot CLI for boilerplate generation cuts development time by 50-60% while maintaining code quality and consistency.]
Code Review and Quality
Before deploying, letβs use Copilot CLI to review our code and ensure quality.
Step 1: Linting Setup
gh copilot -p "Generate ESLint and Prettier configuration for TypeScript CLI project with recommended rules"
# Install and configure
npm install -D eslint prettier eslint-config-prettier
Step 2: Code Review
# Review specific files
gh copilot -p "Review src/commands/add.ts for potential bugs, security issues, and best practices violations"
# Copilot provides feedback:
# β
Good: Input validation present
# β οΈ Warning: Missing error handling for file operations
# π Security: No SQL injection risk (using Lowdb)
Step 3: Automated Testing
# Generate test cases
gh copilot -p "Generate Jest unit tests for TaskDatabase class with test cases for all CRUD operations"
// tests/utils/db.test.ts
describe('TaskDatabase', () => {
let db: TaskDatabase;
beforeEach(async () => {
db = new TaskDatabase();
await db.initialize('./test-tasks.json');
});
it('should add a task', async () => {
const task = await db.addTask({
title: 'Test task',
completed: false,
// ...
});
expect(task.id).toBeDefined();
});
// More tests generated by Copilot...
});
Documentation and Accessibility
Comprehensive documentation makes your CLI tool accessible to all users.
Step 1: Generate README
gh copilot -p "Generate a comprehensive README.md for task-cli including installation, usage examples, API documentation, and contributing guidelines"
Key sections:
- Installation instructions
- Quick start guide
- Command reference with examples
- Configuration options
- Troubleshooting
- Contributing guidelines
Step 2: Help Text and Examples
# Generate example commands
gh copilot -p "Create usage examples for each command showing common workflows"
Step 3: Accessibility Considerations
- Color output: Use
chalkwith fallbacks for terminals without color support - Screen readers: Ensure plain text output option
- Keyboard shortcuts: Document all keybindings
Start by defining your appβs purpose, features, and user stories. Use Copilot CLIβs planning tools to:
- Create a project plan (
/planor/todocommands) - Break down features into actionable tasks
- Track progress and dependencies
Tip: Use clear, descriptive task names for better SEO and accessibility in your documentation.
Scaffolding the CLI App
Generate your CLI app structure using Copilot CLI:
- Use
/scaffoldor/initto set up the project - Choose a language and framework (e.g., Node.js, Python, Go)
- Add a
README.mdwith a project overview and usage instructions
Accessibility: Ensure your CLI app provides clear help messages and supports screen readers (e.g., use --help flags, avoid ambiguous abbreviations).
Coding with Copilot CLI
Leverage Copilot CLI to write code efficiently:
- Use
/codeto generate functions, modules, or scripts - Refine code with
/editand/refactor - Write tests with
/testand ensure coverage
Best Practice: Use semantic variable names and comments to improve code readability and accessibility for all contributors.
- Color output: Use
chalkwith fallbacks for terminals without color support - Screen readers: Ensure plain text output option (
--format=plain) - Keyboard shortcuts: Document all keybindings clearly
Testing Strategy
Comprehensive testing ensures your CLI works reliably across platforms.
Step 1: Unit Tests
# Generate unit tests for all commands
gh copilot -p "Generate Jest unit tests for add command testing argument parsing, validation, and database interaction"
# Run tests
npm test
Step 2: Integration Tests
// tests/integration/workflow.test.ts
describe('Complete workflow', () => {
it('should add, track, and complete a task', async () => {
// Add task
const addResult = await runCLI(['add', 'Build feature', '-t', 'dev']);
expect(addResult).toContain('Task added');
// Track time
const trackResult = await runCLI(['track', 'start', taskId]);
await delay(2000); // Wait 2 seconds
await runCLI(['track', 'stop', taskId]);
// Complete task
await runCLI(['complete', taskId]);
// Verify
const tasks = await db.getTasks();
const task = tasks.find(t => t.id === taskId);
expect(task.completed).toBe(true);
expect(task.timeSpent).toBeGreaterThan(0);
});
});
Step 3: Cross-Platform Testing
# Generate GitHub Actions workflow
gh copilot -p "Create GitHub Actions workflow testing Node.js CLI on Windows, macOS, Ubuntu with Node 18 and 20"
[STAT: CLI tools with >80% test coverage have 3.2x fewer production bugs and 40% faster issue resolution (State of DevOps Report, 2026).]
Deployment
Step 1: Build for Production
# Build script
"scripts": {
"build": "esbuild src/index.ts --bundle --platform=node --target=es2022 --outfile=dist/index.js --minify",
"prepublish": "npm run build && npm test"
}
Step 2: Publish to npm
npm publish --dry-run # Test
npm login
npm publish # Live
npm install -g task-cli # Verify
FAQ
How long to build a CLI from scratch?
With Copilot CLI: 1-2 hours (basic), 4-8 hours (production-ready). Traditional development: 2-3x longer.
JavaScript or TypeScript?
TypeScript recommended for complex CLIs. Type safety catches errors early. Plain JavaScript fine for simple scripts (<200 lines).
How to handle breaking changes?
Use semantic versioning - increment major version (2.0.0). Provide deprecation warnings one version before removal. Document in CHANGELOG.md.
Can I monetize my CLI?
Yes! Options: Freemium, open-source + commercial support, dual licensing, GitHub Sponsors. Check LICENSE alignment.
Auto-update functionality?
Use update-notifier package. Implement with npm update -g. Always require user confirmation.
Best config approach?
Hierarchy: (1) Code defaults, (2) Global ~/.config/, (3) Project .config.json, (4) CLI flags. Use cosmiconfig.
Summary and Next Steps
Youβve completed the Copilot CLI Learning Series!
What you learned:
- Plan and scaffold CLI projects
- Generate code, tests, docs with Copilot
- Implement features with type safety
- Quality review and testing
- Deploy to npm
- Accessibility and SEO best practices
Next steps:
- Extend your CLI with cloud sync or team features
- Contribute to open-source CLI tools
- Build more: automation scripts, generators, dev tools
- Share on GitHub and npm
Resources:
Review the complete series:
- Introduction
- Getting Started
- CLI vs Chat
- Advanced Usage
- Troubleshooting
- Project Build (You are here!)
Share your CLI projects with #CopilotCLI!