Skip to main content
Glama
commit.command.ts4.31 kB
/** * @fileoverview Commit Command - Create commit with enhanced message generation */ import { CommitMessageGenerator, GitAdapter, createTmCore } from '@tm/core'; import { Command } from 'commander'; import { getProjectRoot } from '../../utils/project-root.js'; import { AutopilotBaseOptions, OutputFormatter } from './shared.js'; type CommitOptions = AutopilotBaseOptions; /** * Commit Command - Create commit using enhanced message generator */ export class CommitCommand extends Command { constructor() { super('commit'); this.description('Create a commit for the completed GREEN phase').action( async (options: CommitOptions) => { await this.execute(options); } ); } private async execute(options: CommitOptions): Promise<void> { // Inherit parent options const parentOpts = this.parent?.opts() as AutopilotBaseOptions; const mergedOptions: CommitOptions = { ...parentOpts, ...options, projectRoot: getProjectRoot( options.projectRoot || parentOpts?.projectRoot ) }; const formatter = new OutputFormatter(mergedOptions.json || false); try { const projectRoot = mergedOptions.projectRoot!; // Initialize TmCore facade const tmCore = await createTmCore({ projectPath: projectRoot }); // Check if workflow exists if (!(await tmCore.workflow.hasWorkflow())) { formatter.error('No active workflow', { suggestion: 'Start a workflow with: autopilot start <taskId>' }); process.exit(1); } // Resume workflow await tmCore.workflow.resume(); const status = tmCore.workflow.getStatus(); const workflowContext = tmCore.workflow.getContext(); // Verify in COMMIT phase if (status.tddPhase !== 'COMMIT') { formatter.error('Not in COMMIT phase', { currentPhase: status.tddPhase || status.phase, suggestion: 'Complete RED and GREEN phases first' }); process.exit(1); } // Verify there's an active subtask if (!status.currentSubtask) { formatter.error('No current subtask'); process.exit(1); } // Initialize git adapter const gitAdapter = new GitAdapter(projectRoot); await gitAdapter.ensureGitRepository(); // Check for staged changes const hasStagedChanges = await gitAdapter.hasStagedChanges(); if (!hasStagedChanges) { // Stage all changes formatter.info('No staged changes, staging all changes...'); await gitAdapter.stageFiles(['.']); } // Get changed files for scope detection const gitStatus = await gitAdapter.getStatus(); const changedFiles = [...gitStatus.staged, ...gitStatus.modified]; // Generate commit message const messageGenerator = new CommitMessageGenerator(); const testResults = workflowContext.lastTestResults; const commitMessage = messageGenerator.generateMessage({ type: 'feat', description: status.currentSubtask.title, changedFiles, taskId: status.taskId, phase: status.tddPhase, tag: (workflowContext.metadata.tag as string) || undefined, testsPassing: testResults?.passed, testsFailing: testResults?.failed, coveragePercent: undefined // Could be added if available }); // Create commit with metadata await gitAdapter.createCommit(commitMessage, { metadata: { taskId: status.taskId, subtaskId: status.currentSubtask.id, phase: 'COMMIT', tddCycle: 'complete' } }); // Get commit info const lastCommit = await gitAdapter.getLastCommit(); // Complete COMMIT phase and advance workflow // Status updates (subtask → done) are handled internally by WorkflowService const newStatus = await tmCore.workflow.commit(); const isComplete = newStatus.phase === 'COMPLETE'; // Output success formatter.success('Commit created', { commitHash: lastCommit.hash.substring(0, 7), message: commitMessage.split('\n')[0], // First line only subtask: { id: status.currentSubtask.id, title: status.currentSubtask.title }, progress: newStatus.progress, nextAction: isComplete ? 'All subtasks complete. Run: autopilot status' : 'Start next subtask with RED phase' }); } catch (error) { formatter.error((error as Error).message); if (mergedOptions.verbose) { console.error((error as Error).stack); } process.exit(1); } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/eyaltoledano/claude-task-master'

If you have feedback or need assistance with the MCP directory API, please join our Discord server