Reorganize: Move all skills to skills/ folder
- Created skills/ directory - Moved 272 skills to skills/ subfolder - Kept agents/ at root level - Kept installation scripts and docs at root level Repository structure: - skills/ - All 272 skills from skills.sh - agents/ - Agent definitions - *.sh, *.ps1 - Installation scripts - README.md, etc. - Documentation Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
181
skills/plugins/claude-hud/dist/render/session-line.js
vendored
Normal file
181
skills/plugins/claude-hud/dist/render/session-line.js
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
import { isLimitReached } from '../types.js';
|
||||
import { getContextPercent, getBufferedPercent, getModelName } from '../stdin.js';
|
||||
import { coloredBar, cyan, dim, magenta, red, yellow, getContextColor, RESET } from './colors.js';
|
||||
const DEBUG = process.env.DEBUG?.includes('claude-hud') || process.env.DEBUG === '*';
|
||||
/**
|
||||
* Renders the full session line (model + context bar + project + git + counts + usage + duration).
|
||||
* Used for compact layout mode.
|
||||
*/
|
||||
export function renderSessionLine(ctx) {
|
||||
const model = getModelName(ctx.stdin);
|
||||
const rawPercent = getContextPercent(ctx.stdin);
|
||||
const bufferedPercent = getBufferedPercent(ctx.stdin);
|
||||
const autocompactMode = ctx.config?.display?.autocompactBuffer ?? 'enabled';
|
||||
const percent = autocompactMode === 'disabled' ? rawPercent : bufferedPercent;
|
||||
if (DEBUG && autocompactMode === 'disabled') {
|
||||
console.error(`[claude-hud:context] autocompactBuffer=disabled, showing raw ${rawPercent}% (buffered would be ${bufferedPercent}%)`);
|
||||
}
|
||||
const bar = coloredBar(percent);
|
||||
const parts = [];
|
||||
const display = ctx.config?.display;
|
||||
// Model and context bar (FIRST)
|
||||
// Plan name only shows if showUsage is enabled (respects hybrid toggle)
|
||||
const planName = display?.showUsage !== false ? ctx.usageData?.planName : undefined;
|
||||
const modelDisplay = planName ? `${model} | ${planName}` : model;
|
||||
if (display?.showModel !== false && display?.showContextBar !== false) {
|
||||
parts.push(`${cyan(`[${modelDisplay}]`)} ${bar} ${getContextColor(percent)}${percent}%${RESET}`);
|
||||
}
|
||||
else if (display?.showModel !== false) {
|
||||
parts.push(`${cyan(`[${modelDisplay}]`)} ${getContextColor(percent)}${percent}%${RESET}`);
|
||||
}
|
||||
else if (display?.showContextBar !== false) {
|
||||
parts.push(`${bar} ${getContextColor(percent)}${percent}%${RESET}`);
|
||||
}
|
||||
else {
|
||||
parts.push(`${getContextColor(percent)}${percent}%${RESET}`);
|
||||
}
|
||||
// Project path (SECOND)
|
||||
if (ctx.stdin.cwd) {
|
||||
// Split by both Unix (/) and Windows (\) separators for cross-platform support
|
||||
const segments = ctx.stdin.cwd.split(/[/\\]/).filter(Boolean);
|
||||
const pathLevels = ctx.config?.pathLevels ?? 1;
|
||||
// Always join with forward slash for consistent display
|
||||
// Handle root path (/) which results in empty segments
|
||||
const projectPath = segments.length > 0 ? segments.slice(-pathLevels).join('/') : '/';
|
||||
// Build git status string
|
||||
let gitPart = '';
|
||||
const gitConfig = ctx.config?.gitStatus;
|
||||
const showGit = gitConfig?.enabled ?? true;
|
||||
if (showGit && ctx.gitStatus) {
|
||||
const gitParts = [ctx.gitStatus.branch];
|
||||
// Show dirty indicator
|
||||
if ((gitConfig?.showDirty ?? true) && ctx.gitStatus.isDirty) {
|
||||
gitParts.push('*');
|
||||
}
|
||||
// Show ahead/behind (with space separator for readability)
|
||||
if (gitConfig?.showAheadBehind) {
|
||||
if (ctx.gitStatus.ahead > 0) {
|
||||
gitParts.push(` ↑${ctx.gitStatus.ahead}`);
|
||||
}
|
||||
if (ctx.gitStatus.behind > 0) {
|
||||
gitParts.push(` ↓${ctx.gitStatus.behind}`);
|
||||
}
|
||||
}
|
||||
// Show file stats in Starship-compatible format (!modified +added ✘deleted ?untracked)
|
||||
if (gitConfig?.showFileStats && ctx.gitStatus.fileStats) {
|
||||
const { modified, added, deleted, untracked } = ctx.gitStatus.fileStats;
|
||||
const statParts = [];
|
||||
if (modified > 0)
|
||||
statParts.push(`!${modified}`);
|
||||
if (added > 0)
|
||||
statParts.push(`+${added}`);
|
||||
if (deleted > 0)
|
||||
statParts.push(`✘${deleted}`);
|
||||
if (untracked > 0)
|
||||
statParts.push(`?${untracked}`);
|
||||
if (statParts.length > 0) {
|
||||
gitParts.push(` ${statParts.join(' ')}`);
|
||||
}
|
||||
}
|
||||
gitPart = ` ${magenta('git:(')}${cyan(gitParts.join(''))}${magenta(')')}`;
|
||||
}
|
||||
parts.push(`${yellow(projectPath)}${gitPart}`);
|
||||
}
|
||||
// Config counts (respects environmentThreshold)
|
||||
if (display?.showConfigCounts !== false) {
|
||||
const totalCounts = ctx.claudeMdCount + ctx.rulesCount + ctx.mcpCount + ctx.hooksCount;
|
||||
const envThreshold = display?.environmentThreshold ?? 0;
|
||||
if (totalCounts > 0 && totalCounts >= envThreshold) {
|
||||
if (ctx.claudeMdCount > 0) {
|
||||
parts.push(dim(`${ctx.claudeMdCount} CLAUDE.md`));
|
||||
}
|
||||
if (ctx.rulesCount > 0) {
|
||||
parts.push(dim(`${ctx.rulesCount} rules`));
|
||||
}
|
||||
if (ctx.mcpCount > 0) {
|
||||
parts.push(dim(`${ctx.mcpCount} MCPs`));
|
||||
}
|
||||
if (ctx.hooksCount > 0) {
|
||||
parts.push(dim(`${ctx.hooksCount} hooks`));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Usage limits display (shown when enabled in config, respects usageThreshold)
|
||||
if (display?.showUsage !== false && ctx.usageData?.planName) {
|
||||
if (ctx.usageData.apiUnavailable) {
|
||||
parts.push(yellow(`usage: ⚠`));
|
||||
}
|
||||
else if (isLimitReached(ctx.usageData)) {
|
||||
const resetTime = ctx.usageData.fiveHour === 100
|
||||
? formatResetTime(ctx.usageData.fiveHourResetAt)
|
||||
: formatResetTime(ctx.usageData.sevenDayResetAt);
|
||||
parts.push(red(`⚠ Limit reached${resetTime ? ` (resets ${resetTime})` : ''}`));
|
||||
}
|
||||
else {
|
||||
const usageThreshold = display?.usageThreshold ?? 0;
|
||||
const fiveHour = ctx.usageData.fiveHour;
|
||||
const sevenDay = ctx.usageData.sevenDay;
|
||||
const effectiveUsage = Math.max(fiveHour ?? 0, sevenDay ?? 0);
|
||||
if (effectiveUsage >= usageThreshold) {
|
||||
const fiveHourDisplay = formatUsagePercent(fiveHour);
|
||||
const fiveHourReset = formatResetTime(ctx.usageData.fiveHourResetAt);
|
||||
const fiveHourPart = fiveHourReset
|
||||
? `5h: ${fiveHourDisplay} (${fiveHourReset})`
|
||||
: `5h: ${fiveHourDisplay}`;
|
||||
if (sevenDay !== null && sevenDay >= 80) {
|
||||
const sevenDayDisplay = formatUsagePercent(sevenDay);
|
||||
parts.push(`${fiveHourPart} | 7d: ${sevenDayDisplay}`);
|
||||
}
|
||||
else {
|
||||
parts.push(fiveHourPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Session duration
|
||||
if (display?.showDuration !== false && ctx.sessionDuration) {
|
||||
parts.push(dim(`⏱️ ${ctx.sessionDuration}`));
|
||||
}
|
||||
let line = parts.join(' | ');
|
||||
// Token breakdown at high context
|
||||
if (display?.showTokenBreakdown !== false && percent >= 85) {
|
||||
const usage = ctx.stdin.context_window?.current_usage;
|
||||
if (usage) {
|
||||
const input = formatTokens(usage.input_tokens ?? 0);
|
||||
const cache = formatTokens((usage.cache_creation_input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0));
|
||||
line += dim(` (in: ${input}, cache: ${cache})`);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
function formatTokens(n) {
|
||||
if (n >= 1000000) {
|
||||
return `${(n / 1000000).toFixed(1)}M`;
|
||||
}
|
||||
if (n >= 1000) {
|
||||
return `${(n / 1000).toFixed(0)}k`;
|
||||
}
|
||||
return n.toString();
|
||||
}
|
||||
function formatUsagePercent(percent) {
|
||||
if (percent === null) {
|
||||
return dim('--');
|
||||
}
|
||||
const color = getContextColor(percent);
|
||||
return `${color}${percent}%${RESET}`;
|
||||
}
|
||||
function formatResetTime(resetAt) {
|
||||
if (!resetAt)
|
||||
return '';
|
||||
const now = new Date();
|
||||
const diffMs = resetAt.getTime() - now.getTime();
|
||||
if (diffMs <= 0)
|
||||
return '';
|
||||
const diffMins = Math.ceil(diffMs / 60000);
|
||||
if (diffMins < 60)
|
||||
return `${diffMins}m`;
|
||||
const hours = Math.floor(diffMins / 60);
|
||||
const mins = diffMins % 60;
|
||||
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
||||
}
|
||||
//# sourceMappingURL=session-line.js.map
|
||||
Reference in New Issue
Block a user