alnilam-cli
Version:
Git-native AI career coach that converts multi-year ambitions into weekly execution
120 lines (119 loc) • 5.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.evidenceCommand = void 0;
const commander_1 = require("commander");
const api_1 = require("../lib/api");
const evidenceCommand = new commander_1.Command('evidence');
exports.evidenceCommand = evidenceCommand;
evidenceCommand
.description('Manage evidence tracking')
.addCommand(new commander_1.Command('add')
.description('Add evidence of progress')
.requiredOption('--type <type>', 'Evidence type (commit|pr|time|note)')
.requiredOption('--message <message>', 'Description of the evidence')
.option('--goal-id <goal-id>', 'Link evidence to a specific goal')
.option('--source <source>', 'Source information (branch name, PR URL, etc.)')
.option('--minutes <minutes>', 'Time spent in minutes (for time entries)', parseInt)
.option('--metadata <metadata>', 'Additional metadata as JSON string')
.option('--date <date>', 'Evidence date in YYYY-MM-DD format (UTC, defaults to today)')
.option('--json', 'Output as JSON')
.action(async (options) => {
try {
// Validate evidence type
const validTypes = ['commit', 'pr', 'time', 'note'];
if (!validTypes.includes(options.type)) {
console.error('Error: Invalid type. Must be one of:', validTypes.join(', '));
process.exit(1);
}
// Validate and process date if provided
let evidenceDate;
if (options.date) {
// Validate date format (YYYY-MM-DD)
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(options.date)) {
console.error('Error: Invalid date format. Use YYYY-MM-DD');
process.exit(1);
}
evidenceDate = new Date(options.date + 'T00:00:00.000Z');
if (isNaN(evidenceDate.getTime())) {
console.error('Error: Invalid date. Use YYYY-MM-DD');
process.exit(1);
}
// Prevent future dating (compare in UTC)
const todayUTC = new Date();
const todayEndUTC = new Date(Date.UTC(todayUTC.getUTCFullYear(), todayUTC.getUTCMonth(), todayUTC.getUTCDate(), 23, 59, 59, 999));
if (evidenceDate > todayEndUTC) {
console.error('Error: Evidence date cannot be in the future');
process.exit(1);
}
// Prevent dates too far in the past (before 2020)
const earliestDate = new Date('2020-01-01T00:00:00.000Z');
if (evidenceDate < earliestDate) {
console.error('Error: Evidence date cannot be before 2020-01-01');
process.exit(1);
}
}
// Build metadata object
let metadata = {};
// Add minutes for time entries
if (options.minutes !== undefined) {
if (options.type !== 'time') {
console.error('Error: --minutes can only be used with --type time');
process.exit(1);
}
if (options.minutes <= 0) {
console.error('Error: Minutes must be positive');
process.exit(1);
}
metadata.minutes = options.minutes;
}
// Parse additional metadata if provided
if (options.metadata) {
try {
const additionalMetadata = JSON.parse(options.metadata);
metadata = { ...metadata, ...additionalMetadata };
}
catch (error) {
console.error('Error: Invalid JSON in --metadata option');
process.exit(1);
}
}
const evidenceData = {
type: options.type,
message: options.message,
goal_id: options.goalId,
source: options.source,
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
created_at: evidenceDate ? evidenceDate.toISOString() : undefined,
};
const evidence = await (0, api_1.addEvidence)(evidenceData);
if (options.json) {
console.log(JSON.stringify(evidence, null, 2));
}
else {
console.log(`✅ Evidence added successfully`);
console.log(` ID: ${evidence.id}`);
console.log(` Type: ${evidence.type}`);
console.log(` Message: ${evidence.message}`);
if (evidence.goal_id) {
console.log(` Linked to Goal: ${evidence.goal_id}`);
}
if (evidence.source) {
console.log(` Source: ${evidence.source}`);
}
if (evidence.metadata) {
if (evidence.metadata.minutes) {
console.log(` Time Spent: ${evidence.metadata.minutes} minutes`);
}
if (evidence.metadata.lines_added || evidence.metadata.lines_deleted) {
console.log(` Code Changes: +${evidence.metadata.lines_added || 0}/-${evidence.metadata.lines_deleted || 0} lines`);
}
}
console.log(` Created: ${new Date(evidence.created_at).toLocaleString()}`);
}
}
catch (error) {
console.error('Error adding evidence:', error instanceof Error ? error.message : error);
process.exit(1);
}
}));