alnilam-cli
Version:
Git-native AI career coach that converts multi-year ambitions into weekly execution
185 lines (184 loc) ⢠8.56 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.statusCommand = exports.dashboardCommand = void 0;
const commander_1 = require("commander");
const api_js_1 = require("../lib/api.js");
const asciichart_1 = __importDefault(require("asciichart"));
const dashboardCommand = new commander_1.Command('dashboard');
exports.dashboardCommand = dashboardCommand;
dashboardCommand
.description('Visual dashboard with progress tracking')
.option('--refresh', 'Refresh and display latest data')
.option('--compact', 'Compact display for smaller terminals')
.option('--json', 'Output as JSON')
.action(async (options) => {
try {
console.log('šļø ALNILAM DASHBOARD - BORDERLANDS EDITION šļø');
console.log('ā'.repeat(60));
// Fetch dashboard data
console.log('š Loading dashboard data...');
const [goalsRes, evidenceRes, evaluationRes, summariesRes, nudgesRes] = await Promise.all([
api_js_1.restClient.get('/goals', { params: { select: '*', order: 'created_at.desc', limit: 10 } }),
api_js_1.restClient.get('/evidence', { params: { select: '*', order: 'created_at.desc', limit: 20 } }),
api_js_1.restClient.get('/evaluations', { params: { select: '*', order: 'week_start.desc', limit: 1 } }),
api_js_1.restClient.get('/summaries', { params: { select: 'date,content,evidence_count', order: 'date.desc', limit: 7 } }),
api_js_1.restClient.get('/nudges', { params: { select: '*', 'requires_approval': 'eq.true', 'approved': 'eq.false', limit: 5 } })
]);
const data = {
goals: goalsRes.data || [],
recentEvidence: evidenceRes.data || [],
latestEvaluation: evaluationRes.data?.[0] || null,
recentSummaries: summariesRes.data || [],
pendingNudges: nudgesRes.data || []
};
if (options.json) {
console.log(JSON.stringify(data, null, 2));
return;
}
// Calculate stats
const stats = {
totalGoals: data.goals.length,
activeGoals: data.goals.filter(g => g.status === 'active').length,
completedGoals: data.goals.filter(g => g.status === 'completed').length,
weeklyEvidence: data.recentEvidence.filter(e => {
const weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
return new Date(e.created_at) > weekAgo;
}).length,
currentMomentum: data.latestEvaluation?.momentum_score || 0,
pendingApprovals: data.pendingNudges.length
};
// Quick Stats Overview
console.log('\nš Quick Stats');
console.log('ā'.repeat(30));
console.log(`šÆ Goals: ${stats.activeGoals}/${stats.totalGoals} active`);
console.log(`ā
Completed: ${stats.completedGoals}`);
console.log(`š Weekly Evidence: ${stats.weeklyEvidence}`);
console.log(`ā” Current Momentum: ${stats.currentMomentum}/100`);
console.log(`ā³ Pending Approvals: ${stats.pendingApprovals}`);
// Momentum Gauge
if (stats.currentMomentum > 0) {
console.log('\nšÆ Momentum Score');
console.log('ā'.repeat(30));
const barLength = options.compact ? 20 : 40;
const filled = Math.round((stats.currentMomentum / 100) * barLength);
const gauge = 'ā'.repeat(filled) + 'ā'.repeat(barLength - filled);
const scoreColor = stats.currentMomentum >= 80 ? 'š¢' :
stats.currentMomentum >= 60 ? 'š”' :
stats.currentMomentum >= 40 ? 'šµ' : 'š“';
console.log(`[${gauge}] ${stats.currentMomentum}/100 ${scoreColor}`);
if (data.latestEvaluation?.summary) {
console.log(`\nš ${data.latestEvaluation.summary.substring(0, 100)}...`);
}
}
// Goals by Horizon
if (data.goals.length > 0) {
console.log('\nš Goals by Horizon');
console.log('ā'.repeat(30));
const horizonCounts = data.goals.reduce((acc, goal) => {
if (!acc[goal.horizon])
acc[goal.horizon] = { active: 0, total: 0 };
if (goal.status === 'active')
acc[goal.horizon].active++;
acc[goal.horizon].total++;
return acc;
}, {});
['weekly', 'quarterly', 'annual', 'multi-year'].forEach(horizon => {
const count = horizonCounts[horizon];
if (count) {
const emoji = horizon === 'weekly' ? 'š
' :
horizon === 'quarterly' ? 'š' :
horizon === 'annual' ? 'šļø' : 'š';
console.log(`${emoji} ${horizon}: ${count.active}/${count.total}`);
}
});
}
// Recent Activity
if (data.recentEvidence.length > 0) {
console.log('\nš Recent Activity');
console.log('ā'.repeat(30));
data.recentEvidence.slice(0, 5).forEach(evidence => {
const emoji = evidence.type === 'commit' ? 'š¾' :
evidence.type === 'pr' ? 'š' :
evidence.type === 'time' ? 'ā±ļø' : 'š';
const timeAgo = getTimeAgo(evidence.created_at);
console.log(`${emoji} ${evidence.message.substring(0, 40)}... (${timeAgo})`);
});
}
// Pending Approvals
if (data.pendingNudges.length > 0) {
console.log('\nā³ Pending Approvals');
console.log('ā'.repeat(30));
data.pendingNudges.forEach(nudge => {
const emoji = nudge.type === 'weekly_plan' ? 'š' : 'š”';
console.log(`${emoji} ${nudge.content}`);
});
console.log('\nš” Review plans with: alnl plan list');
}
// Trend Analysis (if we have evaluation history)
if (data.latestEvaluation) {
console.log('\nš Momentum Trend (simulated)');
console.log('ā'.repeat(30));
// Generate sample trend data for demonstration
const trendData = [45, 52, 48, 65, 72, 68, stats.currentMomentum];
const chart = asciichart_1.default.plot(trendData, {
height: 6,
width: options.compact ? 30 : 50,
format: (x) => x.toFixed(0)
});
console.log(chart);
console.log('Last 7 weeks momentum progression');
}
console.log('\n' + 'ā'.repeat(60));
console.log('š” Commands: alnl evaluate | alnl plan | alnl goal list');
console.log(`š Last updated: ${new Date().toLocaleTimeString()}`);
}
catch (error) {
console.error('ā Dashboard error:', error.message);
process.exit(1);
}
});
// Helper function for relative time
function getTimeAgo(dateString) {
const date = new Date(dateString);
const now = new Date();
const diffMs = now.getTime() - date.getTime();
const diffMins = Math.floor(diffMs / (1000 * 60));
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffMins < 1)
return 'just now';
if (diffMins < 60)
return `${diffMins}m ago`;
if (diffHours < 24)
return `${diffHours}h ago`;
return `${diffDays}d ago`;
}
// Simple status command
const statusCommand = new commander_1.Command('status');
exports.statusCommand = statusCommand;
statusCommand
.description('Quick status overview')
.option('--visual', 'Show visual indicators')
.action(async (options) => {
try {
if (options.visual) {
console.log('šÆ Alnilam Status');
console.log('ā'.repeat(40));
console.log('š For full dashboard: alnl dashboard');
console.log('š For momentum: alnl evaluate');
console.log('š For planning: alnl plan');
console.log('šÆ For goals: alnl goal list');
}
else {
console.log('Use --visual for enhanced display');
}
}
catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
});