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:
8
skills/plugins/claude-hud/dist/config-reader.d.ts
vendored
Normal file
8
skills/plugins/claude-hud/dist/config-reader.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface ConfigCounts {
|
||||
claudeMdCount: number;
|
||||
rulesCount: number;
|
||||
mcpCount: number;
|
||||
hooksCount: number;
|
||||
}
|
||||
export declare function countConfigs(cwd?: string): Promise<ConfigCounts>;
|
||||
//# sourceMappingURL=config-reader.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/config-reader.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/config-reader.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"config-reader.d.ts","sourceRoot":"","sources":["../src/config-reader.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAiFD,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAsGtE"}
|
||||
168
skills/plugins/claude-hud/dist/config-reader.js
vendored
Normal file
168
skills/plugins/claude-hud/dist/config-reader.js
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { createDebug } from './debug.js';
|
||||
const debug = createDebug('config');
|
||||
function getMcpServerNames(filePath) {
|
||||
if (!fs.existsSync(filePath))
|
||||
return new Set();
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const config = JSON.parse(content);
|
||||
if (config.mcpServers && typeof config.mcpServers === 'object') {
|
||||
return new Set(Object.keys(config.mcpServers));
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
debug(`Failed to read MCP servers from ${filePath}:`, error);
|
||||
}
|
||||
return new Set();
|
||||
}
|
||||
function getDisabledMcpServers(filePath, key) {
|
||||
if (!fs.existsSync(filePath))
|
||||
return new Set();
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const config = JSON.parse(content);
|
||||
if (Array.isArray(config[key])) {
|
||||
const validNames = config[key].filter((s) => typeof s === 'string');
|
||||
if (validNames.length !== config[key].length) {
|
||||
debug(`${key} in ${filePath} contains non-string values, ignoring them`);
|
||||
}
|
||||
return new Set(validNames);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
debug(`Failed to read ${key} from ${filePath}:`, error);
|
||||
}
|
||||
return new Set();
|
||||
}
|
||||
function countMcpServersInFile(filePath, excludeFrom) {
|
||||
const servers = getMcpServerNames(filePath);
|
||||
if (excludeFrom) {
|
||||
const exclude = getMcpServerNames(excludeFrom);
|
||||
for (const name of exclude) {
|
||||
servers.delete(name);
|
||||
}
|
||||
}
|
||||
return servers.size;
|
||||
}
|
||||
function countHooksInFile(filePath) {
|
||||
if (!fs.existsSync(filePath))
|
||||
return 0;
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const config = JSON.parse(content);
|
||||
if (config.hooks && typeof config.hooks === 'object') {
|
||||
return Object.keys(config.hooks).length;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
debug(`Failed to read hooks from ${filePath}:`, error);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function countRulesInDir(rulesDir) {
|
||||
if (!fs.existsSync(rulesDir))
|
||||
return 0;
|
||||
let count = 0;
|
||||
try {
|
||||
const entries = fs.readdirSync(rulesDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(rulesDir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
count += countRulesInDir(fullPath);
|
||||
}
|
||||
else if (entry.isFile() && entry.name.endsWith('.md')) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
debug(`Failed to read rules from ${rulesDir}:`, error);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
export async function countConfigs(cwd) {
|
||||
let claudeMdCount = 0;
|
||||
let rulesCount = 0;
|
||||
let hooksCount = 0;
|
||||
const homeDir = os.homedir();
|
||||
const claudeDir = path.join(homeDir, '.claude');
|
||||
// Collect all MCP servers across scopes, then subtract disabled ones
|
||||
const userMcpServers = new Set();
|
||||
const projectMcpServers = new Set();
|
||||
// === USER SCOPE ===
|
||||
// ~/.claude/CLAUDE.md
|
||||
if (fs.existsSync(path.join(claudeDir, 'CLAUDE.md'))) {
|
||||
claudeMdCount++;
|
||||
}
|
||||
// ~/.claude/rules/*.md
|
||||
rulesCount += countRulesInDir(path.join(claudeDir, 'rules'));
|
||||
// ~/.claude/settings.json (MCPs and hooks)
|
||||
const userSettings = path.join(claudeDir, 'settings.json');
|
||||
for (const name of getMcpServerNames(userSettings)) {
|
||||
userMcpServers.add(name);
|
||||
}
|
||||
hooksCount += countHooksInFile(userSettings);
|
||||
// ~/.claude.json (additional user-scope MCPs)
|
||||
const userClaudeJson = path.join(homeDir, '.claude.json');
|
||||
for (const name of getMcpServerNames(userClaudeJson)) {
|
||||
userMcpServers.add(name);
|
||||
}
|
||||
// Get disabled user-scope MCPs from ~/.claude.json
|
||||
const disabledUserMcps = getDisabledMcpServers(userClaudeJson, 'disabledMcpServers');
|
||||
for (const name of disabledUserMcps) {
|
||||
userMcpServers.delete(name);
|
||||
}
|
||||
// === PROJECT SCOPE ===
|
||||
if (cwd) {
|
||||
// {cwd}/CLAUDE.md
|
||||
if (fs.existsSync(path.join(cwd, 'CLAUDE.md'))) {
|
||||
claudeMdCount++;
|
||||
}
|
||||
// {cwd}/CLAUDE.local.md
|
||||
if (fs.existsSync(path.join(cwd, 'CLAUDE.local.md'))) {
|
||||
claudeMdCount++;
|
||||
}
|
||||
// {cwd}/.claude/CLAUDE.md (alternative location)
|
||||
if (fs.existsSync(path.join(cwd, '.claude', 'CLAUDE.md'))) {
|
||||
claudeMdCount++;
|
||||
}
|
||||
// {cwd}/.claude/CLAUDE.local.md
|
||||
if (fs.existsSync(path.join(cwd, '.claude', 'CLAUDE.local.md'))) {
|
||||
claudeMdCount++;
|
||||
}
|
||||
// {cwd}/.claude/rules/*.md (recursive)
|
||||
rulesCount += countRulesInDir(path.join(cwd, '.claude', 'rules'));
|
||||
// {cwd}/.mcp.json (project MCP config) - tracked separately for disabled filtering
|
||||
const mcpJsonServers = getMcpServerNames(path.join(cwd, '.mcp.json'));
|
||||
// {cwd}/.claude/settings.json (project settings)
|
||||
const projectSettings = path.join(cwd, '.claude', 'settings.json');
|
||||
for (const name of getMcpServerNames(projectSettings)) {
|
||||
projectMcpServers.add(name);
|
||||
}
|
||||
hooksCount += countHooksInFile(projectSettings);
|
||||
// {cwd}/.claude/settings.local.json (local project settings)
|
||||
const localSettings = path.join(cwd, '.claude', 'settings.local.json');
|
||||
for (const name of getMcpServerNames(localSettings)) {
|
||||
projectMcpServers.add(name);
|
||||
}
|
||||
hooksCount += countHooksInFile(localSettings);
|
||||
// Get disabled .mcp.json servers from settings.local.json
|
||||
const disabledMcpJsonServers = getDisabledMcpServers(localSettings, 'disabledMcpjsonServers');
|
||||
for (const name of disabledMcpJsonServers) {
|
||||
mcpJsonServers.delete(name);
|
||||
}
|
||||
// Add remaining .mcp.json servers to project set
|
||||
for (const name of mcpJsonServers) {
|
||||
projectMcpServers.add(name);
|
||||
}
|
||||
}
|
||||
// Total MCP count = user servers + project servers
|
||||
// Note: Deduplication only occurs within each scope, not across scopes.
|
||||
// A server with the same name in both user and project scope counts as 2 (separate configs).
|
||||
const mcpCount = userMcpServers.size + projectMcpServers.size;
|
||||
return { claudeMdCount, rulesCount, mcpCount, hooksCount };
|
||||
}
|
||||
//# sourceMappingURL=config-reader.js.map
|
||||
1
skills/plugins/claude-hud/dist/config-reader.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/config-reader.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
31
skills/plugins/claude-hud/dist/config.d.ts
vendored
Normal file
31
skills/plugins/claude-hud/dist/config.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
export type LineLayoutType = 'compact' | 'expanded';
|
||||
export type AutocompactBufferMode = 'enabled' | 'disabled';
|
||||
export interface HudConfig {
|
||||
lineLayout: LineLayoutType;
|
||||
showSeparators: boolean;
|
||||
pathLevels: 1 | 2 | 3;
|
||||
gitStatus: {
|
||||
enabled: boolean;
|
||||
showDirty: boolean;
|
||||
showAheadBehind: boolean;
|
||||
showFileStats: boolean;
|
||||
};
|
||||
display: {
|
||||
showModel: boolean;
|
||||
showContextBar: boolean;
|
||||
showConfigCounts: boolean;
|
||||
showDuration: boolean;
|
||||
showTokenBreakdown: boolean;
|
||||
showUsage: boolean;
|
||||
showTools: boolean;
|
||||
showAgents: boolean;
|
||||
showTodos: boolean;
|
||||
autocompactBuffer: AutocompactBufferMode;
|
||||
usageThreshold: number;
|
||||
environmentThreshold: number;
|
||||
};
|
||||
}
|
||||
export declare const DEFAULT_CONFIG: HudConfig;
|
||||
export declare function getConfigPath(): string;
|
||||
export declare function loadConfig(): Promise<HudConfig>;
|
||||
//# sourceMappingURL=config.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/config.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/config.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,CAAC;AAEpD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtB,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,OAAO,EAAE;QACP,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,YAAY,EAAE,OAAO,CAAC;QACtB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,iBAAiB,EAAE,qBAAqB,CAAC;QACzC,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH;AAED,eAAO,MAAM,cAAc,EAAE,SAwB5B,CAAC;AAEF,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AA4GD,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAcrD"}
|
||||
137
skills/plugins/claude-hud/dist/config.js
vendored
Normal file
137
skills/plugins/claude-hud/dist/config.js
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
export const DEFAULT_CONFIG = {
|
||||
lineLayout: 'expanded',
|
||||
showSeparators: false,
|
||||
pathLevels: 1,
|
||||
gitStatus: {
|
||||
enabled: true,
|
||||
showDirty: true,
|
||||
showAheadBehind: false,
|
||||
showFileStats: false,
|
||||
},
|
||||
display: {
|
||||
showModel: true,
|
||||
showContextBar: true,
|
||||
showConfigCounts: true,
|
||||
showDuration: true,
|
||||
showTokenBreakdown: true,
|
||||
showUsage: true,
|
||||
showTools: true,
|
||||
showAgents: true,
|
||||
showTodos: true,
|
||||
autocompactBuffer: 'enabled',
|
||||
usageThreshold: 0,
|
||||
environmentThreshold: 0,
|
||||
},
|
||||
};
|
||||
export function getConfigPath() {
|
||||
const homeDir = os.homedir();
|
||||
return path.join(homeDir, '.claude', 'plugins', 'claude-hud', 'config.json');
|
||||
}
|
||||
function validatePathLevels(value) {
|
||||
return value === 1 || value === 2 || value === 3;
|
||||
}
|
||||
function validateLineLayout(value) {
|
||||
return value === 'compact' || value === 'expanded';
|
||||
}
|
||||
function validateAutocompactBuffer(value) {
|
||||
return value === 'enabled' || value === 'disabled';
|
||||
}
|
||||
function migrateConfig(userConfig) {
|
||||
const migrated = { ...userConfig };
|
||||
if ('layout' in userConfig && !('lineLayout' in userConfig)) {
|
||||
if (userConfig.layout === 'separators') {
|
||||
migrated.lineLayout = 'compact';
|
||||
migrated.showSeparators = true;
|
||||
}
|
||||
else {
|
||||
migrated.lineLayout = 'compact';
|
||||
migrated.showSeparators = false;
|
||||
}
|
||||
delete migrated.layout;
|
||||
}
|
||||
return migrated;
|
||||
}
|
||||
function validateThreshold(value, max = 100) {
|
||||
if (typeof value !== 'number')
|
||||
return 0;
|
||||
return Math.max(0, Math.min(max, value));
|
||||
}
|
||||
function mergeConfig(userConfig) {
|
||||
const migrated = migrateConfig(userConfig);
|
||||
const lineLayout = validateLineLayout(migrated.lineLayout)
|
||||
? migrated.lineLayout
|
||||
: DEFAULT_CONFIG.lineLayout;
|
||||
const showSeparators = typeof migrated.showSeparators === 'boolean'
|
||||
? migrated.showSeparators
|
||||
: DEFAULT_CONFIG.showSeparators;
|
||||
const pathLevels = validatePathLevels(migrated.pathLevels)
|
||||
? migrated.pathLevels
|
||||
: DEFAULT_CONFIG.pathLevels;
|
||||
const gitStatus = {
|
||||
enabled: typeof migrated.gitStatus?.enabled === 'boolean'
|
||||
? migrated.gitStatus.enabled
|
||||
: DEFAULT_CONFIG.gitStatus.enabled,
|
||||
showDirty: typeof migrated.gitStatus?.showDirty === 'boolean'
|
||||
? migrated.gitStatus.showDirty
|
||||
: DEFAULT_CONFIG.gitStatus.showDirty,
|
||||
showAheadBehind: typeof migrated.gitStatus?.showAheadBehind === 'boolean'
|
||||
? migrated.gitStatus.showAheadBehind
|
||||
: DEFAULT_CONFIG.gitStatus.showAheadBehind,
|
||||
showFileStats: typeof migrated.gitStatus?.showFileStats === 'boolean'
|
||||
? migrated.gitStatus.showFileStats
|
||||
: DEFAULT_CONFIG.gitStatus.showFileStats,
|
||||
};
|
||||
const display = {
|
||||
showModel: typeof migrated.display?.showModel === 'boolean'
|
||||
? migrated.display.showModel
|
||||
: DEFAULT_CONFIG.display.showModel,
|
||||
showContextBar: typeof migrated.display?.showContextBar === 'boolean'
|
||||
? migrated.display.showContextBar
|
||||
: DEFAULT_CONFIG.display.showContextBar,
|
||||
showConfigCounts: typeof migrated.display?.showConfigCounts === 'boolean'
|
||||
? migrated.display.showConfigCounts
|
||||
: DEFAULT_CONFIG.display.showConfigCounts,
|
||||
showDuration: typeof migrated.display?.showDuration === 'boolean'
|
||||
? migrated.display.showDuration
|
||||
: DEFAULT_CONFIG.display.showDuration,
|
||||
showTokenBreakdown: typeof migrated.display?.showTokenBreakdown === 'boolean'
|
||||
? migrated.display.showTokenBreakdown
|
||||
: DEFAULT_CONFIG.display.showTokenBreakdown,
|
||||
showUsage: typeof migrated.display?.showUsage === 'boolean'
|
||||
? migrated.display.showUsage
|
||||
: DEFAULT_CONFIG.display.showUsage,
|
||||
showTools: typeof migrated.display?.showTools === 'boolean'
|
||||
? migrated.display.showTools
|
||||
: DEFAULT_CONFIG.display.showTools,
|
||||
showAgents: typeof migrated.display?.showAgents === 'boolean'
|
||||
? migrated.display.showAgents
|
||||
: DEFAULT_CONFIG.display.showAgents,
|
||||
showTodos: typeof migrated.display?.showTodos === 'boolean'
|
||||
? migrated.display.showTodos
|
||||
: DEFAULT_CONFIG.display.showTodos,
|
||||
autocompactBuffer: validateAutocompactBuffer(migrated.display?.autocompactBuffer)
|
||||
? migrated.display.autocompactBuffer
|
||||
: DEFAULT_CONFIG.display.autocompactBuffer,
|
||||
usageThreshold: validateThreshold(migrated.display?.usageThreshold, 100),
|
||||
environmentThreshold: validateThreshold(migrated.display?.environmentThreshold, 100),
|
||||
};
|
||||
return { lineLayout, showSeparators, pathLevels, gitStatus, display };
|
||||
}
|
||||
export async function loadConfig() {
|
||||
const configPath = getConfigPath();
|
||||
try {
|
||||
if (!fs.existsSync(configPath)) {
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
const content = fs.readFileSync(configPath, 'utf-8');
|
||||
const userConfig = JSON.parse(content);
|
||||
return mergeConfig(userConfig);
|
||||
}
|
||||
catch {
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=config.js.map
|
||||
1
skills/plugins/claude-hud/dist/config.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/config.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAgC9B,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,UAAU,EAAE,UAAU;IACtB,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,CAAC;IACb,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,KAAK;KACrB;IACD,OAAO,EAAE;QACP,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,IAAI;QACpB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,IAAI;QAClB,kBAAkB,EAAE,IAAI;QACxB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,SAAS;QAC5B,cAAc,EAAE,CAAC;QACjB,oBAAoB,EAAE,CAAC;KACxB;CACF,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,UAAU,CAAC;AACrD,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAc;IAC/C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,UAAU,CAAC;AACrD,CAAC;AAMD,SAAS,aAAa,CAAC,UAA6C;IAClE,MAAM,QAAQ,GAAG,EAAE,GAAG,UAAU,EAAuC,CAAC;IAExE,IAAI,QAAQ,IAAI,UAAU,IAAI,CAAC,CAAC,YAAY,IAAI,UAAU,CAAC,EAAE,CAAC;QAC5D,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACvC,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC;YAChC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC;YAChC,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC;QAClC,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,GAAG,GAAG,GAAG;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,UAA8B;IACjD,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAE3C,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC;QACxD,CAAC,CAAC,QAAQ,CAAC,UAAU;QACrB,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC;IAE9B,MAAM,cAAc,GAAG,OAAO,QAAQ,CAAC,cAAc,KAAK,SAAS;QACjE,CAAC,CAAC,QAAQ,CAAC,cAAc;QACzB,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC;IAElC,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC;QACxD,CAAC,CAAC,QAAQ,CAAC,UAAU;QACrB,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC;IAE9B,MAAM,SAAS,GAAG;QAChB,OAAO,EAAE,OAAO,QAAQ,CAAC,SAAS,EAAE,OAAO,KAAK,SAAS;YACvD,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO;YAC5B,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO;QACpC,SAAS,EAAE,OAAO,QAAQ,CAAC,SAAS,EAAE,SAAS,KAAK,SAAS;YAC3D,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS;YAC9B,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS;QACtC,eAAe,EAAE,OAAO,QAAQ,CAAC,SAAS,EAAE,eAAe,KAAK,SAAS;YACvE,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe;YACpC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,eAAe;QAC5C,aAAa,EAAE,OAAO,QAAQ,CAAC,SAAS,EAAE,aAAa,KAAK,SAAS;YACnE,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa;YAClC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,aAAa;KAC3C,CAAC;IAEF,MAAM,OAAO,GAAG;QACd,SAAS,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,SAAS;YACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;YAC5B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS;QACpC,cAAc,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS;YACnE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc;YACjC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,cAAc;QACzC,gBAAgB,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,gBAAgB,KAAK,SAAS;YACvE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB;YACnC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,gBAAgB;QAC3C,YAAY,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,YAAY,KAAK,SAAS;YAC/D,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY;YAC/B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,YAAY;QACvC,kBAAkB,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,kBAAkB,KAAK,SAAS;YAC3E,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB;YACrC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,kBAAkB;QAC7C,SAAS,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,SAAS;YACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;YAC5B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS;QACpC,SAAS,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,SAAS;YACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;YAC5B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS;QACpC,UAAU,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,KAAK,SAAS;YAC3D,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;YAC7B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU;QACrC,SAAS,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,SAAS;YACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;YAC5B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS;QACpC,iBAAiB,EAAE,yBAAyB,CAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;YAC/E,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB;YACpC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,iBAAiB;QAC5C,cAAc,EAAE,iBAAiB,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,CAAC;QACxE,oBAAoB,EAAE,iBAAiB,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,CAAC;KACrF,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;QAC7D,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
|
||||
10
skills/plugins/claude-hud/dist/constants.d.ts
vendored
Normal file
10
skills/plugins/claude-hud/dist/constants.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Autocompact buffer percentage.
|
||||
*
|
||||
* NOTE: This value (22.5% = 45k/200k) is empirically derived from community
|
||||
* observations of Claude Code's autocompact behavior. It is NOT officially
|
||||
* documented by Anthropic and may change in future Claude Code versions.
|
||||
* If users report mismatches, this value may need adjustment.
|
||||
*/
|
||||
export declare const AUTOCOMPACT_BUFFER_PERCENT = 0.225;
|
||||
//# sourceMappingURL=constants.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/constants.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/constants.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,QAAQ,CAAC"}
|
||||
10
skills/plugins/claude-hud/dist/constants.js
vendored
Normal file
10
skills/plugins/claude-hud/dist/constants.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Autocompact buffer percentage.
|
||||
*
|
||||
* NOTE: This value (22.5% = 45k/200k) is empirically derived from community
|
||||
* observations of Claude Code's autocompact behavior. It is NOT officially
|
||||
* documented by Anthropic and may change in future Claude Code versions.
|
||||
* If users report mismatches, this value may need adjustment.
|
||||
*/
|
||||
export const AUTOCOMPACT_BUFFER_PERCENT = 0.225;
|
||||
//# sourceMappingURL=constants.js.map
|
||||
1
skills/plugins/claude-hud/dist/constants.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/constants.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,CAAC"}
|
||||
6
skills/plugins/claude-hud/dist/debug.d.ts
vendored
Normal file
6
skills/plugins/claude-hud/dist/debug.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Create a namespaced debug logger
|
||||
* @param namespace - Tag for log messages (e.g., 'config', 'usage')
|
||||
*/
|
||||
export declare function createDebug(namespace: string): (msg: string, ...args: unknown[]) => void;
|
||||
//# sourceMappingURL=debug.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/debug.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/debug.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,IACrB,KAAK,MAAM,EAAE,GAAG,MAAM,OAAO,EAAE,KAAG,IAAI,CAK7D"}
|
||||
15
skills/plugins/claude-hud/dist/debug.js
vendored
Normal file
15
skills/plugins/claude-hud/dist/debug.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Shared debug logging utility
|
||||
// Enable via: DEBUG=claude-hud or DEBUG=*
|
||||
const DEBUG = process.env.DEBUG?.includes('claude-hud') || process.env.DEBUG === '*';
|
||||
/**
|
||||
* Create a namespaced debug logger
|
||||
* @param namespace - Tag for log messages (e.g., 'config', 'usage')
|
||||
*/
|
||||
export function createDebug(namespace) {
|
||||
return function debug(msg, ...args) {
|
||||
if (DEBUG) {
|
||||
console.error(`[claude-hud:${namespace}] ${msg}`, ...args);
|
||||
}
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=debug.js.map
|
||||
1
skills/plugins/claude-hud/dist/debug.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/debug.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,0CAA0C;AAE1C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC;AAErF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,OAAO,SAAS,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,eAAe,SAAS,KAAK,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
||||
16
skills/plugins/claude-hud/dist/git.d.ts
vendored
Normal file
16
skills/plugins/claude-hud/dist/git.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface FileStats {
|
||||
modified: number;
|
||||
added: number;
|
||||
deleted: number;
|
||||
untracked: number;
|
||||
}
|
||||
export interface GitStatus {
|
||||
branch: string;
|
||||
isDirty: boolean;
|
||||
ahead: number;
|
||||
behind: number;
|
||||
fileStats?: FileStats;
|
||||
}
|
||||
export declare function getGitBranch(cwd?: string): Promise<string | null>;
|
||||
export declare function getGitStatus(cwd?: string): Promise<GitStatus | null>;
|
||||
//# sourceMappingURL=git.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/git.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/git.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAavE;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAqD1E"}
|
||||
86
skills/plugins/claude-hud/dist/git.js
vendored
Normal file
86
skills/plugins/claude-hud/dist/git.js
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
import { execFile } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
const execFileAsync = promisify(execFile);
|
||||
export async function getGitBranch(cwd) {
|
||||
if (!cwd)
|
||||
return null;
|
||||
try {
|
||||
const { stdout } = await execFileAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, timeout: 1000, encoding: 'utf8' });
|
||||
return stdout.trim() || null;
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
export async function getGitStatus(cwd) {
|
||||
if (!cwd)
|
||||
return null;
|
||||
try {
|
||||
// Get branch name
|
||||
const { stdout: branchOut } = await execFileAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, timeout: 1000, encoding: 'utf8' });
|
||||
const branch = branchOut.trim();
|
||||
if (!branch)
|
||||
return null;
|
||||
// Check for dirty state and parse file stats
|
||||
let isDirty = false;
|
||||
let fileStats;
|
||||
try {
|
||||
const { stdout: statusOut } = await execFileAsync('git', ['--no-optional-locks', 'status', '--porcelain'], { cwd, timeout: 1000, encoding: 'utf8' });
|
||||
const trimmed = statusOut.trim();
|
||||
isDirty = trimmed.length > 0;
|
||||
if (isDirty) {
|
||||
fileStats = parseFileStats(trimmed);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Ignore errors, assume clean
|
||||
}
|
||||
// Get ahead/behind counts
|
||||
let ahead = 0;
|
||||
let behind = 0;
|
||||
try {
|
||||
const { stdout: revOut } = await execFileAsync('git', ['rev-list', '--left-right', '--count', '@{upstream}...HEAD'], { cwd, timeout: 1000, encoding: 'utf8' });
|
||||
const parts = revOut.trim().split(/\s+/);
|
||||
if (parts.length === 2) {
|
||||
behind = parseInt(parts[0], 10) || 0;
|
||||
ahead = parseInt(parts[1], 10) || 0;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// No upstream or error, keep 0/0
|
||||
}
|
||||
return { branch, isDirty, ahead, behind, fileStats };
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parse git status --porcelain output and count file stats (Starship-compatible format)
|
||||
* Status codes: M=modified, A=added, D=deleted, ??=untracked
|
||||
*/
|
||||
function parseFileStats(porcelainOutput) {
|
||||
const stats = { modified: 0, added: 0, deleted: 0, untracked: 0 };
|
||||
const lines = porcelainOutput.split('\n').filter(Boolean);
|
||||
for (const line of lines) {
|
||||
if (line.length < 2)
|
||||
continue;
|
||||
const index = line[0]; // staged status
|
||||
const worktree = line[1]; // unstaged status
|
||||
if (line.startsWith('??')) {
|
||||
stats.untracked++;
|
||||
}
|
||||
else if (index === 'A') {
|
||||
stats.added++;
|
||||
}
|
||||
else if (index === 'D' || worktree === 'D') {
|
||||
stats.deleted++;
|
||||
}
|
||||
else if (index === 'M' || worktree === 'M' || index === 'R' || index === 'C') {
|
||||
// M=modified, R=renamed (counts as modified), C=copied (counts as modified)
|
||||
stats.modified++;
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
//# sourceMappingURL=git.js.map
|
||||
1
skills/plugins/claude-hud/dist/git.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/git.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
||||
21
skills/plugins/claude-hud/dist/index.d.ts
vendored
Normal file
21
skills/plugins/claude-hud/dist/index.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { readStdin } from './stdin.js';
|
||||
import { parseTranscript } from './transcript.js';
|
||||
import { render } from './render/index.js';
|
||||
import { countConfigs } from './config-reader.js';
|
||||
import { getGitStatus } from './git.js';
|
||||
import { getUsage } from './usage-api.js';
|
||||
import { loadConfig } from './config.js';
|
||||
export type MainDeps = {
|
||||
readStdin: typeof readStdin;
|
||||
parseTranscript: typeof parseTranscript;
|
||||
countConfigs: typeof countConfigs;
|
||||
getGitStatus: typeof getGitStatus;
|
||||
getUsage: typeof getUsage;
|
||||
loadConfig: typeof loadConfig;
|
||||
render: typeof render;
|
||||
now: () => number;
|
||||
log: (...args: unknown[]) => void;
|
||||
};
|
||||
export declare function main(overrides?: Partial<MainDeps>): Promise<void>;
|
||||
export declare function formatSessionDuration(sessionStart?: Date, now?: () => number): string;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/index.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,wBAAsB,IAAI,CAAC,SAAS,GAAE,OAAO,CAAC,QAAQ,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD3E;AAED,wBAAgB,qBAAqB,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,GAAE,MAAM,MAAyB,GAAG,MAAM,CAcvG"}
|
||||
75
skills/plugins/claude-hud/dist/index.js
vendored
Normal file
75
skills/plugins/claude-hud/dist/index.js
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import { readStdin } from './stdin.js';
|
||||
import { parseTranscript } from './transcript.js';
|
||||
import { render } from './render/index.js';
|
||||
import { countConfigs } from './config-reader.js';
|
||||
import { getGitStatus } from './git.js';
|
||||
import { getUsage } from './usage-api.js';
|
||||
import { loadConfig } from './config.js';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
export async function main(overrides = {}) {
|
||||
const deps = {
|
||||
readStdin,
|
||||
parseTranscript,
|
||||
countConfigs,
|
||||
getGitStatus,
|
||||
getUsage,
|
||||
loadConfig,
|
||||
render,
|
||||
now: () => Date.now(),
|
||||
log: console.log,
|
||||
...overrides,
|
||||
};
|
||||
try {
|
||||
const stdin = await deps.readStdin();
|
||||
if (!stdin) {
|
||||
deps.log('[claude-hud] Initializing...');
|
||||
return;
|
||||
}
|
||||
const transcriptPath = stdin.transcript_path ?? '';
|
||||
const transcript = await deps.parseTranscript(transcriptPath);
|
||||
const { claudeMdCount, rulesCount, mcpCount, hooksCount } = await deps.countConfigs(stdin.cwd);
|
||||
const config = await deps.loadConfig();
|
||||
const gitStatus = config.gitStatus.enabled
|
||||
? await deps.getGitStatus(stdin.cwd)
|
||||
: null;
|
||||
// Only fetch usage if enabled in config (replaces env var requirement)
|
||||
const usageData = config.display.showUsage !== false
|
||||
? await deps.getUsage()
|
||||
: null;
|
||||
const sessionDuration = formatSessionDuration(transcript.sessionStart, deps.now);
|
||||
const ctx = {
|
||||
stdin,
|
||||
transcript,
|
||||
claudeMdCount,
|
||||
rulesCount,
|
||||
mcpCount,
|
||||
hooksCount,
|
||||
sessionDuration,
|
||||
gitStatus,
|
||||
usageData,
|
||||
config,
|
||||
};
|
||||
deps.render(ctx);
|
||||
}
|
||||
catch (error) {
|
||||
deps.log('[claude-hud] Error:', error instanceof Error ? error.message : 'Unknown error');
|
||||
}
|
||||
}
|
||||
export function formatSessionDuration(sessionStart, now = () => Date.now()) {
|
||||
if (!sessionStart) {
|
||||
return '';
|
||||
}
|
||||
const ms = now() - sessionStart.getTime();
|
||||
const mins = Math.floor(ms / 60000);
|
||||
if (mins < 1)
|
||||
return '<1m';
|
||||
if (mins < 60)
|
||||
return `${mins}m`;
|
||||
const hours = Math.floor(mins / 60);
|
||||
const remainingMins = mins % 60;
|
||||
return `${hours}h ${remainingMins}m`;
|
||||
}
|
||||
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||
void main();
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
skills/plugins/claude-hud/dist/index.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
||||
3
skills/plugins/claude-hud/dist/render/agents-line.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/agents-line.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../types.js';
|
||||
export declare function renderAgentsLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=agents-line.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/agents-line.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/agents-line.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"agents-line.d.ts","sourceRoot":"","sources":["../../src/render/agents-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,aAAa,CAAC;AAG7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAqBlE"}
|
||||
44
skills/plugins/claude-hud/dist/render/agents-line.js
vendored
Normal file
44
skills/plugins/claude-hud/dist/render/agents-line.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { yellow, green, magenta, dim } from './colors.js';
|
||||
export function renderAgentsLine(ctx) {
|
||||
const { agents } = ctx.transcript;
|
||||
const runningAgents = agents.filter((a) => a.status === 'running');
|
||||
const recentCompleted = agents
|
||||
.filter((a) => a.status === 'completed')
|
||||
.slice(-2);
|
||||
const toShow = [...runningAgents, ...recentCompleted].slice(-3);
|
||||
if (toShow.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const lines = [];
|
||||
for (const agent of toShow) {
|
||||
lines.push(formatAgent(agent));
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
function formatAgent(agent) {
|
||||
const statusIcon = agent.status === 'running' ? yellow('◐') : green('✓');
|
||||
const type = magenta(agent.type);
|
||||
const model = agent.model ? dim(`[${agent.model}]`) : '';
|
||||
const desc = agent.description ? dim(`: ${truncateDesc(agent.description)}`) : '';
|
||||
const elapsed = formatElapsed(agent);
|
||||
return `${statusIcon} ${type}${model ? ` ${model}` : ''}${desc} ${dim(`(${elapsed})`)}`;
|
||||
}
|
||||
function truncateDesc(desc, maxLen = 40) {
|
||||
if (desc.length <= maxLen)
|
||||
return desc;
|
||||
return desc.slice(0, maxLen - 3) + '...';
|
||||
}
|
||||
function formatElapsed(agent) {
|
||||
const now = Date.now();
|
||||
const start = agent.startTime.getTime();
|
||||
const end = agent.endTime?.getTime() ?? now;
|
||||
const ms = end - start;
|
||||
if (ms < 1000)
|
||||
return '<1s';
|
||||
if (ms < 60000)
|
||||
return `${Math.round(ms / 1000)}s`;
|
||||
const mins = Math.floor(ms / 60000);
|
||||
const secs = Math.round((ms % 60000) / 1000);
|
||||
return `${mins}m ${secs}s`;
|
||||
}
|
||||
//# sourceMappingURL=agents-line.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/agents-line.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/agents-line.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"agents-line.js","sourceRoot":"","sources":["../../src/render/agents-line.ts"],"names":[],"mappings":"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"}
|
||||
10
skills/plugins/claude-hud/dist/render/colors.d.ts
vendored
Normal file
10
skills/plugins/claude-hud/dist/render/colors.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export declare const RESET = "\u001B[0m";
|
||||
export declare function green(text: string): string;
|
||||
export declare function yellow(text: string): string;
|
||||
export declare function red(text: string): string;
|
||||
export declare function cyan(text: string): string;
|
||||
export declare function magenta(text: string): string;
|
||||
export declare function dim(text: string): string;
|
||||
export declare function getContextColor(percent: number): string;
|
||||
export declare function coloredBar(percent: number, width?: number): string;
|
||||
//# sourceMappingURL=colors.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/colors.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/colors.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,cAAY,CAAC;AAS/B,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAKtE"}
|
||||
39
skills/plugins/claude-hud/dist/render/colors.js
vendored
Normal file
39
skills/plugins/claude-hud/dist/render/colors.js
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
export const RESET = '\x1b[0m';
|
||||
const DIM = '\x1b[2m';
|
||||
const RED = '\x1b[31m';
|
||||
const GREEN = '\x1b[32m';
|
||||
const YELLOW = '\x1b[33m';
|
||||
const MAGENTA = '\x1b[35m';
|
||||
const CYAN = '\x1b[36m';
|
||||
export function green(text) {
|
||||
return `${GREEN}${text}${RESET}`;
|
||||
}
|
||||
export function yellow(text) {
|
||||
return `${YELLOW}${text}${RESET}`;
|
||||
}
|
||||
export function red(text) {
|
||||
return `${RED}${text}${RESET}`;
|
||||
}
|
||||
export function cyan(text) {
|
||||
return `${CYAN}${text}${RESET}`;
|
||||
}
|
||||
export function magenta(text) {
|
||||
return `${MAGENTA}${text}${RESET}`;
|
||||
}
|
||||
export function dim(text) {
|
||||
return `${DIM}${text}${RESET}`;
|
||||
}
|
||||
export function getContextColor(percent) {
|
||||
if (percent >= 85)
|
||||
return RED;
|
||||
if (percent >= 70)
|
||||
return YELLOW;
|
||||
return GREEN;
|
||||
}
|
||||
export function coloredBar(percent, width = 10) {
|
||||
const filled = Math.round((percent / 100) * width);
|
||||
const empty = width - filled;
|
||||
const color = getContextColor(percent);
|
||||
return `${color}${'█'.repeat(filled)}${DIM}${'░'.repeat(empty)}${RESET}`;
|
||||
}
|
||||
//# sourceMappingURL=colors.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/colors.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/colors.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/render/colors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC;AAE/B,MAAM,GAAG,GAAG,SAAS,CAAC;AACtB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,IAAI,GAAG,UAAU,CAAC;AAExB,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAY;IAC9B,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,OAAO,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAC9B,IAAI,OAAO,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,QAAgB,EAAE;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC;AAC3E,CAAC"}
|
||||
3
skills/plugins/claude-hud/dist/render/index.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/index.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../types.js';
|
||||
export declare function render(ctx: RenderContext): void;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/index.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuFjD,wBAAgB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAuB/C"}
|
||||
83
skills/plugins/claude-hud/dist/render/index.js
vendored
Normal file
83
skills/plugins/claude-hud/dist/render/index.js
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import { renderSessionLine } from './session-line.js';
|
||||
import { renderToolsLine } from './tools-line.js';
|
||||
import { renderAgentsLine } from './agents-line.js';
|
||||
import { renderTodosLine } from './todos-line.js';
|
||||
import { renderIdentityLine, renderProjectLine, renderEnvironmentLine, renderUsageLine, } from './lines/index.js';
|
||||
import { dim, RESET } from './colors.js';
|
||||
function visualLength(str) {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
return str.replace(/\x1b\[[0-9;]*m/g, '').length;
|
||||
}
|
||||
function makeSeparator(length) {
|
||||
return dim('─'.repeat(Math.max(length, 20)));
|
||||
}
|
||||
function collectActivityLines(ctx) {
|
||||
const activityLines = [];
|
||||
const display = ctx.config?.display;
|
||||
if (display?.showTools !== false) {
|
||||
const toolsLine = renderToolsLine(ctx);
|
||||
if (toolsLine) {
|
||||
activityLines.push(toolsLine);
|
||||
}
|
||||
}
|
||||
if (display?.showAgents !== false) {
|
||||
const agentsLine = renderAgentsLine(ctx);
|
||||
if (agentsLine) {
|
||||
activityLines.push(agentsLine);
|
||||
}
|
||||
}
|
||||
if (display?.showTodos !== false) {
|
||||
const todosLine = renderTodosLine(ctx);
|
||||
if (todosLine) {
|
||||
activityLines.push(todosLine);
|
||||
}
|
||||
}
|
||||
return activityLines;
|
||||
}
|
||||
function renderCompact(ctx) {
|
||||
const lines = [];
|
||||
const sessionLine = renderSessionLine(ctx);
|
||||
if (sessionLine) {
|
||||
lines.push(sessionLine);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
function renderExpanded(ctx) {
|
||||
const lines = [];
|
||||
const identityLine = renderIdentityLine(ctx);
|
||||
if (identityLine) {
|
||||
lines.push(identityLine);
|
||||
}
|
||||
const projectLine = renderProjectLine(ctx);
|
||||
if (projectLine) {
|
||||
lines.push(projectLine);
|
||||
}
|
||||
const environmentLine = renderEnvironmentLine(ctx);
|
||||
if (environmentLine) {
|
||||
lines.push(environmentLine);
|
||||
}
|
||||
const usageLine = renderUsageLine(ctx);
|
||||
if (usageLine) {
|
||||
lines.push(usageLine);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
export function render(ctx) {
|
||||
const lineLayout = ctx.config?.lineLayout ?? 'expanded';
|
||||
const showSeparators = ctx.config?.showSeparators ?? false;
|
||||
const headerLines = lineLayout === 'expanded'
|
||||
? renderExpanded(ctx)
|
||||
: renderCompact(ctx);
|
||||
const activityLines = collectActivityLines(ctx);
|
||||
const lines = [...headerLines];
|
||||
if (showSeparators && activityLines.length > 0) {
|
||||
const maxWidth = Math.max(...headerLines.map(visualLength), 20);
|
||||
lines.push(makeSeparator(maxWidth));
|
||||
}
|
||||
lines.push(...activityLines);
|
||||
for (const line of lines) {
|
||||
const outputLine = `${RESET}${line.replace(/ /g, '\u00A0')}`;
|
||||
console.log(outputLine);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/index.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"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"}
|
||||
3
skills/plugins/claude-hud/dist/render/lines/environment.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/lines/environment.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../../types.js';
|
||||
export declare function renderEnvironmentLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=environment.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/environment.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/environment.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/render/lines/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAqCvE"}
|
||||
30
skills/plugins/claude-hud/dist/render/lines/environment.js
vendored
Normal file
30
skills/plugins/claude-hud/dist/render/lines/environment.js
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { dim } from '../colors.js';
|
||||
export function renderEnvironmentLine(ctx) {
|
||||
const display = ctx.config?.display;
|
||||
if (display?.showConfigCounts === false) {
|
||||
return null;
|
||||
}
|
||||
const totalCounts = ctx.claudeMdCount + ctx.rulesCount + ctx.mcpCount + ctx.hooksCount;
|
||||
const threshold = display?.environmentThreshold ?? 0;
|
||||
if (totalCounts === 0 || totalCounts < threshold) {
|
||||
return null;
|
||||
}
|
||||
const parts = [];
|
||||
if (ctx.claudeMdCount > 0) {
|
||||
parts.push(`${ctx.claudeMdCount} CLAUDE.md`);
|
||||
}
|
||||
if (ctx.rulesCount > 0) {
|
||||
parts.push(`${ctx.rulesCount} rules`);
|
||||
}
|
||||
if (ctx.mcpCount > 0) {
|
||||
parts.push(`${ctx.mcpCount} MCPs`);
|
||||
}
|
||||
if (ctx.hooksCount > 0) {
|
||||
parts.push(`${ctx.hooksCount} hooks`);
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return dim(parts.join(' | '));
|
||||
}
|
||||
//# sourceMappingURL=environment.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/environment.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/environment.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/render/lines/environment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,MAAM,UAAU,qBAAqB,CAAC,GAAkB;IACtD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAEpC,IAAI,OAAO,EAAE,gBAAgB,KAAK,KAAK,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC;IACvF,MAAM,SAAS,GAAG,OAAO,EAAE,oBAAoB,IAAI,CAAC,CAAC;IAErD,IAAI,WAAW,KAAK,CAAC,IAAI,WAAW,GAAG,SAAS,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,GAAG,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,aAAa,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAChC,CAAC"}
|
||||
3
skills/plugins/claude-hud/dist/render/lines/identity.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/lines/identity.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../../types.js';
|
||||
export declare function renderIdentityLine(ctx: RenderContext): string;
|
||||
//# sourceMappingURL=identity.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/identity.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/identity.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/render/lines/identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMpD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA6C7D"}
|
||||
53
skills/plugins/claude-hud/dist/render/lines/identity.js
vendored
Normal file
53
skills/plugins/claude-hud/dist/render/lines/identity.js
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import { getContextPercent, getBufferedPercent, getModelName } from '../../stdin.js';
|
||||
import { coloredBar, cyan, dim, getContextColor, RESET } from '../colors.js';
|
||||
const DEBUG = process.env.DEBUG?.includes('claude-hud') || process.env.DEBUG === '*';
|
||||
export function renderIdentityLine(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 display = ctx.config?.display;
|
||||
const parts = [];
|
||||
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}`);
|
||||
}
|
||||
if (display?.showDuration !== false && ctx.sessionDuration) {
|
||||
parts.push(dim(`⏱️ ${ctx.sessionDuration}`));
|
||||
}
|
||||
let line = parts.join(' | ');
|
||||
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();
|
||||
}
|
||||
//# sourceMappingURL=identity.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/identity.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/identity.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/render/lines/identity.ts"],"names":[],"mappings":"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"}
|
||||
5
skills/plugins/claude-hud/dist/render/lines/index.d.ts
vendored
Normal file
5
skills/plugins/claude-hud/dist/render/lines/index.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export { renderIdentityLine } from './identity.js';
|
||||
export { renderProjectLine } from './project.js';
|
||||
export { renderEnvironmentLine } from './environment.js';
|
||||
export { renderUsageLine } from './usage.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/index.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/lines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
||||
5
skills/plugins/claude-hud/dist/render/lines/index.js
vendored
Normal file
5
skills/plugins/claude-hud/dist/render/lines/index.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export { renderIdentityLine } from './identity.js';
|
||||
export { renderProjectLine } from './project.js';
|
||||
export { renderEnvironmentLine } from './environment.js';
|
||||
export { renderUsageLine } from './usage.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/index.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/lines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
||||
3
skills/plugins/claude-hud/dist/render/lines/project.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/lines/project.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../../types.js';
|
||||
export declare function renderProjectLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=project.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/project.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/project.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/render/lines/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CA6CnE"}
|
||||
44
skills/plugins/claude-hud/dist/render/lines/project.js
vendored
Normal file
44
skills/plugins/claude-hud/dist/render/lines/project.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { cyan, magenta, yellow } from '../colors.js';
|
||||
export function renderProjectLine(ctx) {
|
||||
if (!ctx.stdin.cwd) {
|
||||
return null;
|
||||
}
|
||||
const segments = ctx.stdin.cwd.split(/[/\\]/).filter(Boolean);
|
||||
const pathLevels = ctx.config?.pathLevels ?? 1;
|
||||
const projectPath = segments.length > 0 ? segments.slice(-pathLevels).join('/') : '/';
|
||||
let gitPart = '';
|
||||
const gitConfig = ctx.config?.gitStatus;
|
||||
const showGit = gitConfig?.enabled ?? true;
|
||||
if (showGit && ctx.gitStatus) {
|
||||
const gitParts = [ctx.gitStatus.branch];
|
||||
if ((gitConfig?.showDirty ?? true) && ctx.gitStatus.isDirty) {
|
||||
gitParts.push('*');
|
||||
}
|
||||
if (gitConfig?.showAheadBehind) {
|
||||
if (ctx.gitStatus.ahead > 0) {
|
||||
gitParts.push(` ↑${ctx.gitStatus.ahead}`);
|
||||
}
|
||||
if (ctx.gitStatus.behind > 0) {
|
||||
gitParts.push(` ↓${ctx.gitStatus.behind}`);
|
||||
}
|
||||
}
|
||||
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(')')}`;
|
||||
}
|
||||
return `${yellow(projectPath)}${gitPart}`;
|
||||
}
|
||||
//# sourceMappingURL=project.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/project.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/project.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/render/lines/project.ts"],"names":[],"mappings":"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"}
|
||||
3
skills/plugins/claude-hud/dist/render/lines/usage.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/lines/usage.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../../types.js';
|
||||
export declare function renderUsageLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=usage.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/usage.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/usage.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/render/lines/usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CA2CjE"}
|
||||
59
skills/plugins/claude-hud/dist/render/lines/usage.js
vendored
Normal file
59
skills/plugins/claude-hud/dist/render/lines/usage.js
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import { isLimitReached } from '../../types.js';
|
||||
import { red, yellow, dim, getContextColor, RESET } from '../colors.js';
|
||||
export function renderUsageLine(ctx) {
|
||||
const display = ctx.config?.display;
|
||||
if (display?.showUsage === false) {
|
||||
return null;
|
||||
}
|
||||
if (!ctx.usageData?.planName) {
|
||||
return null;
|
||||
}
|
||||
if (ctx.usageData.apiUnavailable) {
|
||||
return yellow(`usage: ⚠`);
|
||||
}
|
||||
if (isLimitReached(ctx.usageData)) {
|
||||
const resetTime = ctx.usageData.fiveHour === 100
|
||||
? formatResetTime(ctx.usageData.fiveHourResetAt)
|
||||
: formatResetTime(ctx.usageData.sevenDayResetAt);
|
||||
return red(`⚠ Limit reached${resetTime ? ` (resets ${resetTime})` : ''}`);
|
||||
}
|
||||
const threshold = display?.usageThreshold ?? 0;
|
||||
const fiveHour = ctx.usageData.fiveHour;
|
||||
const sevenDay = ctx.usageData.sevenDay;
|
||||
const effectiveUsage = Math.max(fiveHour ?? 0, sevenDay ?? 0);
|
||||
if (effectiveUsage < threshold) {
|
||||
return null;
|
||||
}
|
||||
const fiveHourDisplay = formatUsagePercent(ctx.usageData.fiveHour);
|
||||
const fiveHourReset = formatResetTime(ctx.usageData.fiveHourResetAt);
|
||||
const fiveHourPart = fiveHourReset
|
||||
? `5h: ${fiveHourDisplay} (${fiveHourReset})`
|
||||
: `5h: ${fiveHourDisplay}`;
|
||||
if (sevenDay !== null && sevenDay >= 80) {
|
||||
const sevenDayDisplay = formatUsagePercent(sevenDay);
|
||||
return `${fiveHourPart} | 7d: ${sevenDayDisplay}`;
|
||||
}
|
||||
return fiveHourPart;
|
||||
}
|
||||
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=usage.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/lines/usage.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/lines/usage.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/render/lines/usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,UAAU,eAAe,CAAC,GAAkB;IAChD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAEpC,IAAI,OAAO,EAAE,SAAS,KAAK,KAAK,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,KAAK,GAAG;YAC9C,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC;YAChD,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACnD,OAAO,GAAG,CAAC,kBAAkB,SAAS,CAAC,CAAC,CAAC,YAAY,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,cAAc,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC;IAExC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC;IAC9D,IAAI,cAAc,GAAG,SAAS,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,aAAa;QAChC,CAAC,CAAC,OAAO,eAAe,KAAK,aAAa,GAAG;QAC7C,CAAC,CAAC,OAAO,eAAe,EAAE,CAAC;IAE7B,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACrD,OAAO,GAAG,YAAY,UAAU,eAAe,EAAE,CAAC;IACpD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAsB;IAChD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,eAAe,CAAC,OAAoB;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IACjD,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IAC3C,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,GAAG,QAAQ,GAAG,CAAC;IAEzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,QAAQ,GAAG,EAAE,CAAC;IAC3B,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;AACvD,CAAC"}
|
||||
7
skills/plugins/claude-hud/dist/render/session-line.d.ts
vendored
Normal file
7
skills/plugins/claude-hud/dist/render/session-line.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { RenderContext } from '../types.js';
|
||||
/**
|
||||
* Renders the full session line (model + context bar + project + git + counts + usage + duration).
|
||||
* Used for compact layout mode.
|
||||
*/
|
||||
export declare function renderSessionLine(ctx: RenderContext): string;
|
||||
//# sourceMappingURL=session-line.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/session-line.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/session-line.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"session-line.d.ts","sourceRoot":"","sources":["../../src/render/session-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA6J5D"}
|
||||
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
|
||||
1
skills/plugins/claude-hud/dist/render/session-line.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/session-line.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
3
skills/plugins/claude-hud/dist/render/todos-line.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/todos-line.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../types.js';
|
||||
export declare function renderTodosLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=todos-line.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/todos-line.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/todos-line.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"todos-line.d.ts","sourceRoot":"","sources":["../../src/render/todos-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAsBjE"}
|
||||
25
skills/plugins/claude-hud/dist/render/todos-line.js
vendored
Normal file
25
skills/plugins/claude-hud/dist/render/todos-line.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { yellow, green, dim } from './colors.js';
|
||||
export function renderTodosLine(ctx) {
|
||||
const { todos } = ctx.transcript;
|
||||
if (!todos || todos.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const inProgress = todos.find((t) => t.status === 'in_progress');
|
||||
const completed = todos.filter((t) => t.status === 'completed').length;
|
||||
const total = todos.length;
|
||||
if (!inProgress) {
|
||||
if (completed === total && total > 0) {
|
||||
return `${green('✓')} All todos complete ${dim(`(${completed}/${total})`)}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const content = truncateContent(inProgress.content);
|
||||
const progress = dim(`(${completed}/${total})`);
|
||||
return `${yellow('▸')} ${content} ${progress}`;
|
||||
}
|
||||
function truncateContent(content, maxLen = 50) {
|
||||
if (content.length <= maxLen)
|
||||
return content;
|
||||
return content.slice(0, maxLen - 3) + '...';
|
||||
}
|
||||
//# sourceMappingURL=todos-line.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/todos-line.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/todos-line.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"todos-line.js","sourceRoot":"","sources":["../../src/render/todos-line.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,UAAU,eAAe,CAAC,GAAkB;IAChD,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC;IAEjC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,SAAS,KAAK,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,uBAAuB,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC9E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,GAAG,CAAC,CAAC;IAEhD,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,SAAiB,EAAE;IAC3D,IAAI,OAAO,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IAC7C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC9C,CAAC"}
|
||||
3
skills/plugins/claude-hud/dist/render/tools-line.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/render/tools-line.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { RenderContext } from '../types.js';
|
||||
export declare function renderToolsLine(ctx: RenderContext): string | null;
|
||||
//# sourceMappingURL=tools-line.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/render/tools-line.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/tools-line.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"tools-line.d.ts","sourceRoot":"","sources":["../../src/render/tools-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAoCjE"}
|
||||
43
skills/plugins/claude-hud/dist/render/tools-line.js
vendored
Normal file
43
skills/plugins/claude-hud/dist/render/tools-line.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import { yellow, green, cyan, dim } from './colors.js';
|
||||
export function renderToolsLine(ctx) {
|
||||
const { tools } = ctx.transcript;
|
||||
if (tools.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const parts = [];
|
||||
const runningTools = tools.filter((t) => t.status === 'running');
|
||||
const completedTools = tools.filter((t) => t.status === 'completed' || t.status === 'error');
|
||||
for (const tool of runningTools.slice(-2)) {
|
||||
const target = tool.target ? truncatePath(tool.target) : '';
|
||||
parts.push(`${yellow('◐')} ${cyan(tool.name)}${target ? dim(`: ${target}`) : ''}`);
|
||||
}
|
||||
const toolCounts = new Map();
|
||||
for (const tool of completedTools) {
|
||||
const count = toolCounts.get(tool.name) ?? 0;
|
||||
toolCounts.set(tool.name, count + 1);
|
||||
}
|
||||
const sortedTools = Array.from(toolCounts.entries())
|
||||
.sort((a, b) => b[1] - a[1])
|
||||
.slice(0, 4);
|
||||
for (const [name, count] of sortedTools) {
|
||||
parts.push(`${green('✓')} ${name} ${dim(`×${count}`)}`);
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return parts.join(' | ');
|
||||
}
|
||||
function truncatePath(path, maxLen = 20) {
|
||||
// Normalize Windows backslashes to forward slashes for consistent display
|
||||
const normalizedPath = path.replace(/\\/g, '/');
|
||||
if (normalizedPath.length <= maxLen)
|
||||
return normalizedPath;
|
||||
// Split by forward slash (already normalized)
|
||||
const parts = normalizedPath.split('/');
|
||||
const filename = parts.pop() || normalizedPath;
|
||||
if (filename.length >= maxLen) {
|
||||
return filename.slice(0, maxLen - 3) + '...';
|
||||
}
|
||||
return '.../' + filename;
|
||||
}
|
||||
//# sourceMappingURL=tools-line.js.map
|
||||
1
skills/plugins/claude-hud/dist/render/tools-line.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/render/tools-line.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"tools-line.js","sourceRoot":"","sources":["../../src/render/tools-line.ts"],"names":[],"mappings":"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"}
|
||||
6
skills/plugins/claude-hud/dist/stdin.d.ts
vendored
Normal file
6
skills/plugins/claude-hud/dist/stdin.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { StdinData } from './types.js';
|
||||
export declare function readStdin(): Promise<StdinData | null>;
|
||||
export declare function getContextPercent(stdin: StdinData): number;
|
||||
export declare function getBufferedPercent(stdin: StdinData): number;
|
||||
export declare function getModelName(stdin: StdinData): string;
|
||||
//# sourceMappingURL=stdin.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/stdin.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/stdin.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"stdin.d.ts","sourceRoot":"","sources":["../src/stdin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,wBAAsB,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAoB3D;AAuBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAe1D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAiB3D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAErD"}
|
||||
72
skills/plugins/claude-hud/dist/stdin.js
vendored
Normal file
72
skills/plugins/claude-hud/dist/stdin.js
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
import { AUTOCOMPACT_BUFFER_PERCENT } from './constants.js';
|
||||
export async function readStdin() {
|
||||
if (process.stdin.isTTY) {
|
||||
return null;
|
||||
}
|
||||
const chunks = [];
|
||||
try {
|
||||
process.stdin.setEncoding('utf8');
|
||||
for await (const chunk of process.stdin) {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
const raw = chunks.join('');
|
||||
if (!raw.trim()) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function getTotalTokens(stdin) {
|
||||
const usage = stdin.context_window?.current_usage;
|
||||
return ((usage?.input_tokens ?? 0) +
|
||||
(usage?.cache_creation_input_tokens ?? 0) +
|
||||
(usage?.cache_read_input_tokens ?? 0));
|
||||
}
|
||||
/**
|
||||
* Get native percentage from Claude Code v2.1.6+ if available.
|
||||
* Returns null if not available or invalid, triggering fallback to manual calculation.
|
||||
*/
|
||||
function getNativePercent(stdin) {
|
||||
const nativePercent = stdin.context_window?.used_percentage;
|
||||
if (typeof nativePercent === 'number' && !Number.isNaN(nativePercent)) {
|
||||
return Math.min(100, Math.max(0, Math.round(nativePercent)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function getContextPercent(stdin) {
|
||||
// Prefer native percentage (v2.1.6+) - accurate and matches /context
|
||||
const native = getNativePercent(stdin);
|
||||
if (native !== null) {
|
||||
return native;
|
||||
}
|
||||
// Fallback: manual calculation without buffer
|
||||
const size = stdin.context_window?.context_window_size;
|
||||
if (!size || size <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const totalTokens = getTotalTokens(stdin);
|
||||
return Math.min(100, Math.round((totalTokens / size) * 100));
|
||||
}
|
||||
export function getBufferedPercent(stdin) {
|
||||
// Prefer native percentage (v2.1.6+) - accurate and matches /context
|
||||
// Native percentage already accounts for context correctly, no buffer needed
|
||||
const native = getNativePercent(stdin);
|
||||
if (native !== null) {
|
||||
return native;
|
||||
}
|
||||
// Fallback: manual calculation with buffer for older Claude Code versions
|
||||
const size = stdin.context_window?.context_window_size;
|
||||
if (!size || size <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const totalTokens = getTotalTokens(stdin);
|
||||
const buffer = size * AUTOCOMPACT_BUFFER_PERCENT;
|
||||
return Math.min(100, Math.round(((totalTokens + buffer) / size) * 100));
|
||||
}
|
||||
export function getModelName(stdin) {
|
||||
return stdin.model?.display_name ?? stdin.model?.id ?? 'Unknown';
|
||||
}
|
||||
//# sourceMappingURL=stdin.js.map
|
||||
1
skills/plugins/claude-hud/dist/stdin.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/stdin.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../src/stdin.ts"],"names":[],"mappings":"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"}
|
||||
3
skills/plugins/claude-hud/dist/transcript.d.ts
vendored
Normal file
3
skills/plugins/claude-hud/dist/transcript.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { TranscriptData } from './types.js';
|
||||
export declare function parseTranscript(transcriptPath: string): Promise<TranscriptData>;
|
||||
//# sourceMappingURL=transcript.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/transcript.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/transcript.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,YAAY,CAAC;AAkBlF,wBAAsB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAyCrF"}
|
||||
113
skills/plugins/claude-hud/dist/transcript.js
vendored
Normal file
113
skills/plugins/claude-hud/dist/transcript.js
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import * as fs from 'fs';
|
||||
import * as readline from 'readline';
|
||||
export async function parseTranscript(transcriptPath) {
|
||||
const result = {
|
||||
tools: [],
|
||||
agents: [],
|
||||
todos: [],
|
||||
};
|
||||
if (!transcriptPath || !fs.existsSync(transcriptPath)) {
|
||||
return result;
|
||||
}
|
||||
const toolMap = new Map();
|
||||
const agentMap = new Map();
|
||||
let latestTodos = [];
|
||||
try {
|
||||
const fileStream = fs.createReadStream(transcriptPath);
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
});
|
||||
for await (const line of rl) {
|
||||
if (!line.trim())
|
||||
continue;
|
||||
try {
|
||||
const entry = JSON.parse(line);
|
||||
processEntry(entry, toolMap, agentMap, latestTodos, result);
|
||||
}
|
||||
catch {
|
||||
// Skip malformed lines
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Return partial results on error
|
||||
}
|
||||
result.tools = Array.from(toolMap.values()).slice(-20);
|
||||
result.agents = Array.from(agentMap.values()).slice(-10);
|
||||
result.todos = latestTodos;
|
||||
return result;
|
||||
}
|
||||
function processEntry(entry, toolMap, agentMap, latestTodos, result) {
|
||||
const timestamp = entry.timestamp ? new Date(entry.timestamp) : new Date();
|
||||
if (!result.sessionStart && entry.timestamp) {
|
||||
result.sessionStart = timestamp;
|
||||
}
|
||||
const content = entry.message?.content;
|
||||
if (!content || !Array.isArray(content))
|
||||
return;
|
||||
for (const block of content) {
|
||||
if (block.type === 'tool_use' && block.id && block.name) {
|
||||
const toolEntry = {
|
||||
id: block.id,
|
||||
name: block.name,
|
||||
target: extractTarget(block.name, block.input),
|
||||
status: 'running',
|
||||
startTime: timestamp,
|
||||
};
|
||||
if (block.name === 'Task') {
|
||||
const input = block.input;
|
||||
const agentEntry = {
|
||||
id: block.id,
|
||||
type: input?.subagent_type ?? 'unknown',
|
||||
model: input?.model ?? undefined,
|
||||
description: input?.description ?? undefined,
|
||||
status: 'running',
|
||||
startTime: timestamp,
|
||||
};
|
||||
agentMap.set(block.id, agentEntry);
|
||||
}
|
||||
else if (block.name === 'TodoWrite') {
|
||||
const input = block.input;
|
||||
if (input?.todos && Array.isArray(input.todos)) {
|
||||
latestTodos.length = 0;
|
||||
latestTodos.push(...input.todos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
toolMap.set(block.id, toolEntry);
|
||||
}
|
||||
}
|
||||
if (block.type === 'tool_result' && block.tool_use_id) {
|
||||
const tool = toolMap.get(block.tool_use_id);
|
||||
if (tool) {
|
||||
tool.status = block.is_error ? 'error' : 'completed';
|
||||
tool.endTime = timestamp;
|
||||
}
|
||||
const agent = agentMap.get(block.tool_use_id);
|
||||
if (agent) {
|
||||
agent.status = 'completed';
|
||||
agent.endTime = timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function extractTarget(toolName, input) {
|
||||
if (!input)
|
||||
return undefined;
|
||||
switch (toolName) {
|
||||
case 'Read':
|
||||
case 'Write':
|
||||
case 'Edit':
|
||||
return input.file_path ?? input.path;
|
||||
case 'Glob':
|
||||
return input.pattern;
|
||||
case 'Grep':
|
||||
return input.pattern;
|
||||
case 'Bash':
|
||||
const cmd = input.command;
|
||||
return cmd?.slice(0, 30) + (cmd?.length > 30 ? '...' : '');
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
//# sourceMappingURL=transcript.js.map
|
||||
1
skills/plugins/claude-hud/dist/transcript.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/transcript.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"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"}
|
||||
75
skills/plugins/claude-hud/dist/types.d.ts
vendored
Normal file
75
skills/plugins/claude-hud/dist/types.d.ts
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { HudConfig } from './config.js';
|
||||
import type { GitStatus } from './git.js';
|
||||
export interface StdinData {
|
||||
transcript_path?: string;
|
||||
cwd?: string;
|
||||
model?: {
|
||||
id?: string;
|
||||
display_name?: string;
|
||||
};
|
||||
context_window?: {
|
||||
context_window_size?: number;
|
||||
current_usage?: {
|
||||
input_tokens?: number;
|
||||
cache_creation_input_tokens?: number;
|
||||
cache_read_input_tokens?: number;
|
||||
} | null;
|
||||
used_percentage?: number | null;
|
||||
remaining_percentage?: number | null;
|
||||
};
|
||||
}
|
||||
export interface ToolEntry {
|
||||
id: string;
|
||||
name: string;
|
||||
target?: string;
|
||||
status: 'running' | 'completed' | 'error';
|
||||
startTime: Date;
|
||||
endTime?: Date;
|
||||
}
|
||||
export interface AgentEntry {
|
||||
id: string;
|
||||
type: string;
|
||||
model?: string;
|
||||
description?: string;
|
||||
status: 'running' | 'completed';
|
||||
startTime: Date;
|
||||
endTime?: Date;
|
||||
}
|
||||
export interface TodoItem {
|
||||
content: string;
|
||||
status: 'pending' | 'in_progress' | 'completed';
|
||||
}
|
||||
/** Usage window data from the OAuth API */
|
||||
export interface UsageWindow {
|
||||
utilization: number | null;
|
||||
resetAt: Date | null;
|
||||
}
|
||||
export interface UsageData {
|
||||
planName: string | null;
|
||||
fiveHour: number | null;
|
||||
sevenDay: number | null;
|
||||
fiveHourResetAt: Date | null;
|
||||
sevenDayResetAt: Date | null;
|
||||
apiUnavailable?: boolean;
|
||||
}
|
||||
/** Check if usage limit is reached (either window at 100%) */
|
||||
export declare function isLimitReached(data: UsageData): boolean;
|
||||
export interface TranscriptData {
|
||||
tools: ToolEntry[];
|
||||
agents: AgentEntry[];
|
||||
todos: TodoItem[];
|
||||
sessionStart?: Date;
|
||||
}
|
||||
export interface RenderContext {
|
||||
stdin: StdinData;
|
||||
transcript: TranscriptData;
|
||||
claudeMdCount: number;
|
||||
rulesCount: number;
|
||||
mcpCount: number;
|
||||
hooksCount: number;
|
||||
sessionDuration: string;
|
||||
gitStatus: GitStatus | null;
|
||||
usageData: UsageData | null;
|
||||
config: HudConfig;
|
||||
}
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/types.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/types.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,cAAc,CAAC,EAAE;QACf,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,aAAa,CAAC,EAAE;YACd,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;YACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;SAClC,GAAG,IAAI,CAAC;QAET,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACtC,CAAC;CACH;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;IAC1C,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;IAChC,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;CACjD;AAED,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEvD;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,YAAY,CAAC,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,cAAc,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,SAAS,CAAC;CACnB"}
|
||||
5
skills/plugins/claude-hud/dist/types.js
vendored
Normal file
5
skills/plugins/claude-hud/dist/types.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/** Check if usage limit is reached (either window at 100%) */
|
||||
export function isLimitReached(data) {
|
||||
return data.fiveHour === 100 || data.sevenDay === 100;
|
||||
}
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
skills/plugins/claude-hud/dist/types.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/types.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA8DA,8DAA8D;AAC9D,MAAM,UAAU,cAAc,CAAC,IAAe;IAC5C,OAAO,IAAI,CAAC,QAAQ,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC;AACxD,CAAC"}
|
||||
32
skills/plugins/claude-hud/dist/usage-api.d.ts
vendored
Normal file
32
skills/plugins/claude-hud/dist/usage-api.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import type { UsageData } from './types.js';
|
||||
export type { UsageData } from './types.js';
|
||||
interface UsageApiResponse {
|
||||
five_hour?: {
|
||||
utilization?: number;
|
||||
resets_at?: string;
|
||||
};
|
||||
seven_day?: {
|
||||
utilization?: number;
|
||||
resets_at?: string;
|
||||
};
|
||||
}
|
||||
export type UsageApiDeps = {
|
||||
homeDir: () => string;
|
||||
fetchApi: (accessToken: string) => Promise<UsageApiResponse | null>;
|
||||
now: () => number;
|
||||
readKeychain: (now: number, homeDir: string) => {
|
||||
accessToken: string;
|
||||
subscriptionType: string;
|
||||
} | null;
|
||||
};
|
||||
/**
|
||||
* Get OAuth usage data from Anthropic API.
|
||||
* Returns null if user is an API user (no OAuth credentials) or credentials are expired.
|
||||
* Returns { apiUnavailable: true, ... } if API call fails (to show warning in HUD).
|
||||
*
|
||||
* Uses file-based cache since HUD runs as a new process each render (~300ms).
|
||||
* Cache TTL: 60s for success, 15s for failures.
|
||||
*/
|
||||
export declare function getUsage(overrides?: Partial<UsageApiDeps>): Promise<UsageData | null>;
|
||||
export declare function clearCache(homeDir?: string): void;
|
||||
//# sourceMappingURL=usage-api.d.ts.map
|
||||
1
skills/plugins/claude-hud/dist/usage-api.d.ts.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/usage-api.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"usage-api.d.ts","sourceRoot":"","sources":["../src/usage-api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAe5C,UAAU,gBAAgB;IACxB,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AA8DD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACpE,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC1G,CAAC;AASF;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAkE/F;AA8PD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAWjD"}
|
||||
370
skills/plugins/claude-hud/dist/usage-api.js
vendored
Normal file
370
skills/plugins/claude-hud/dist/usage-api.js
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as https from 'https';
|
||||
import { execFileSync } from 'child_process';
|
||||
import { createDebug } from './debug.js';
|
||||
const debug = createDebug('usage');
|
||||
// File-based cache (HUD runs as new process each render, so in-memory cache won't persist)
|
||||
const CACHE_TTL_MS = 60_000; // 60 seconds
|
||||
const CACHE_FAILURE_TTL_MS = 15_000; // 15 seconds for failed requests
|
||||
const KEYCHAIN_TIMEOUT_MS = 5000;
|
||||
const KEYCHAIN_BACKOFF_MS = 60_000; // Backoff on keychain failures to avoid re-prompting
|
||||
function getCachePath(homeDir) {
|
||||
return path.join(homeDir, '.claude', 'plugins', 'claude-hud', '.usage-cache.json');
|
||||
}
|
||||
function readCache(homeDir, now) {
|
||||
try {
|
||||
const cachePath = getCachePath(homeDir);
|
||||
if (!fs.existsSync(cachePath))
|
||||
return null;
|
||||
const content = fs.readFileSync(cachePath, 'utf8');
|
||||
const cache = JSON.parse(content);
|
||||
// Check TTL - use shorter TTL for failure results
|
||||
const ttl = cache.data.apiUnavailable ? CACHE_FAILURE_TTL_MS : CACHE_TTL_MS;
|
||||
if (now - cache.timestamp >= ttl)
|
||||
return null;
|
||||
// JSON.stringify converts Date to ISO string, so we need to reconvert on read.
|
||||
// new Date() handles both Date objects and ISO strings safely.
|
||||
const data = cache.data;
|
||||
if (data.fiveHourResetAt) {
|
||||
data.fiveHourResetAt = new Date(data.fiveHourResetAt);
|
||||
}
|
||||
if (data.sevenDayResetAt) {
|
||||
data.sevenDayResetAt = new Date(data.sevenDayResetAt);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function writeCache(homeDir, data, timestamp) {
|
||||
try {
|
||||
const cachePath = getCachePath(homeDir);
|
||||
const cacheDir = path.dirname(cachePath);
|
||||
if (!fs.existsSync(cacheDir)) {
|
||||
fs.mkdirSync(cacheDir, { recursive: true });
|
||||
}
|
||||
const cache = { data, timestamp };
|
||||
fs.writeFileSync(cachePath, JSON.stringify(cache), 'utf8');
|
||||
}
|
||||
catch {
|
||||
// Ignore cache write failures
|
||||
}
|
||||
}
|
||||
const defaultDeps = {
|
||||
homeDir: () => os.homedir(),
|
||||
fetchApi: fetchUsageApi,
|
||||
now: () => Date.now(),
|
||||
readKeychain: readKeychainCredentials,
|
||||
};
|
||||
/**
|
||||
* Get OAuth usage data from Anthropic API.
|
||||
* Returns null if user is an API user (no OAuth credentials) or credentials are expired.
|
||||
* Returns { apiUnavailable: true, ... } if API call fails (to show warning in HUD).
|
||||
*
|
||||
* Uses file-based cache since HUD runs as a new process each render (~300ms).
|
||||
* Cache TTL: 60s for success, 15s for failures.
|
||||
*/
|
||||
export async function getUsage(overrides = {}) {
|
||||
const deps = { ...defaultDeps, ...overrides };
|
||||
const now = deps.now();
|
||||
const homeDir = deps.homeDir();
|
||||
// Check file-based cache first
|
||||
const cached = readCache(homeDir, now);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
try {
|
||||
const credentials = readCredentials(homeDir, now, deps.readKeychain);
|
||||
if (!credentials) {
|
||||
return null;
|
||||
}
|
||||
const { accessToken, subscriptionType } = credentials;
|
||||
// Determine plan name from subscriptionType
|
||||
const planName = getPlanName(subscriptionType);
|
||||
if (!planName) {
|
||||
// API user, no usage limits to show
|
||||
return null;
|
||||
}
|
||||
// Fetch usage from API
|
||||
const apiResponse = await deps.fetchApi(accessToken);
|
||||
if (!apiResponse) {
|
||||
// API call failed, cache the failure to prevent retry storms
|
||||
const failureResult = {
|
||||
planName,
|
||||
fiveHour: null,
|
||||
sevenDay: null,
|
||||
fiveHourResetAt: null,
|
||||
sevenDayResetAt: null,
|
||||
apiUnavailable: true,
|
||||
};
|
||||
writeCache(homeDir, failureResult, now);
|
||||
return failureResult;
|
||||
}
|
||||
// Parse response - API returns 0-100 percentage directly
|
||||
// Clamp to 0-100 and handle NaN/Infinity
|
||||
const fiveHour = parseUtilization(apiResponse.five_hour?.utilization);
|
||||
const sevenDay = parseUtilization(apiResponse.seven_day?.utilization);
|
||||
const fiveHourResetAt = parseDate(apiResponse.five_hour?.resets_at);
|
||||
const sevenDayResetAt = parseDate(apiResponse.seven_day?.resets_at);
|
||||
const result = {
|
||||
planName,
|
||||
fiveHour,
|
||||
sevenDay,
|
||||
fiveHourResetAt,
|
||||
sevenDayResetAt,
|
||||
};
|
||||
// Write to file cache
|
||||
writeCache(homeDir, result, now);
|
||||
return result;
|
||||
}
|
||||
catch (error) {
|
||||
debug('getUsage failed:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get path for keychain failure backoff cache.
|
||||
* Separate from usage cache to track keychain-specific failures.
|
||||
*/
|
||||
function getKeychainBackoffPath(homeDir) {
|
||||
return path.join(homeDir, '.claude', 'plugins', 'claude-hud', '.keychain-backoff');
|
||||
}
|
||||
/**
|
||||
* Check if we're in keychain backoff period (recent failure/timeout).
|
||||
* Prevents re-prompting user on every render cycle.
|
||||
*/
|
||||
function isKeychainBackoff(homeDir, now) {
|
||||
try {
|
||||
const backoffPath = getKeychainBackoffPath(homeDir);
|
||||
if (!fs.existsSync(backoffPath))
|
||||
return false;
|
||||
const timestamp = parseInt(fs.readFileSync(backoffPath, 'utf8'), 10);
|
||||
return now - timestamp < KEYCHAIN_BACKOFF_MS;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Record keychain failure for backoff.
|
||||
*/
|
||||
function recordKeychainFailure(homeDir, now) {
|
||||
try {
|
||||
const backoffPath = getKeychainBackoffPath(homeDir);
|
||||
const dir = path.dirname(backoffPath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(backoffPath, String(now), 'utf8');
|
||||
}
|
||||
catch {
|
||||
// Ignore write failures
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Read credentials from macOS Keychain.
|
||||
* Claude Code 2.x stores OAuth credentials in the macOS Keychain under "Claude Code-credentials".
|
||||
* Returns null if not on macOS or credentials not found.
|
||||
*
|
||||
* Security: Uses execFileSync with absolute path to avoid shell injection and PATH hijacking.
|
||||
*/
|
||||
function readKeychainCredentials(now, homeDir) {
|
||||
// Only available on macOS
|
||||
if (process.platform !== 'darwin') {
|
||||
return null;
|
||||
}
|
||||
// Check backoff to avoid re-prompting on every render after a failure
|
||||
if (isKeychainBackoff(homeDir, now)) {
|
||||
debug('Keychain in backoff period, skipping');
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// Read from macOS Keychain using security command
|
||||
// Security: Use execFileSync with absolute path and args array (no shell)
|
||||
const keychainData = execFileSync('/usr/bin/security', ['find-generic-password', '-s', 'Claude Code-credentials', '-w'], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], timeout: KEYCHAIN_TIMEOUT_MS }).trim();
|
||||
if (!keychainData) {
|
||||
return null;
|
||||
}
|
||||
const data = JSON.parse(keychainData);
|
||||
return parseCredentialsData(data, now);
|
||||
}
|
||||
catch (error) {
|
||||
// Security: Only log error message, not full error object (may contain stdout/stderr with tokens)
|
||||
const message = error instanceof Error ? error.message : 'unknown error';
|
||||
debug('Failed to read from macOS Keychain:', message);
|
||||
// Record failure for backoff to avoid re-prompting
|
||||
recordKeychainFailure(homeDir, now);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Read credentials from file (legacy method).
|
||||
* Older versions of Claude Code stored credentials in ~/.claude/.credentials.json
|
||||
*/
|
||||
function readFileCredentials(homeDir, now) {
|
||||
const credentialsPath = path.join(homeDir, '.claude', '.credentials.json');
|
||||
if (!fs.existsSync(credentialsPath)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const content = fs.readFileSync(credentialsPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
return parseCredentialsData(data, now);
|
||||
}
|
||||
catch (error) {
|
||||
debug('Failed to read credentials file:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parse and validate credentials data from either Keychain or file.
|
||||
*/
|
||||
function parseCredentialsData(data, now) {
|
||||
const accessToken = data.claudeAiOauth?.accessToken;
|
||||
const subscriptionType = data.claudeAiOauth?.subscriptionType ?? '';
|
||||
if (!accessToken) {
|
||||
return null;
|
||||
}
|
||||
// Check if token is expired (expiresAt is Unix ms timestamp)
|
||||
// Use != null to handle expiresAt=0 correctly (would be expired)
|
||||
const expiresAt = data.claudeAiOauth?.expiresAt;
|
||||
if (expiresAt != null && expiresAt <= now) {
|
||||
debug('OAuth token expired');
|
||||
return null;
|
||||
}
|
||||
return { accessToken, subscriptionType };
|
||||
}
|
||||
/**
|
||||
* Read OAuth credentials, trying macOS Keychain first (Claude Code 2.x),
|
||||
* then falling back to file-based credentials (older versions).
|
||||
*
|
||||
* Token priority: Keychain token is authoritative (Claude Code 2.x stores current token there).
|
||||
* SubscriptionType: Can be supplemented from file if keychain lacks it (display-only field).
|
||||
*/
|
||||
function readCredentials(homeDir, now, readKeychain) {
|
||||
// Try macOS Keychain first (Claude Code 2.x)
|
||||
const keychainCreds = readKeychain(now, homeDir);
|
||||
if (keychainCreds) {
|
||||
if (keychainCreds.subscriptionType) {
|
||||
debug('Using credentials from macOS Keychain');
|
||||
return keychainCreds;
|
||||
}
|
||||
// Keychain has token but no subscriptionType - try to supplement from file
|
||||
const fileCreds = readFileCredentials(homeDir, now);
|
||||
if (fileCreds?.subscriptionType) {
|
||||
debug('Using keychain token with file subscriptionType');
|
||||
return {
|
||||
accessToken: keychainCreds.accessToken,
|
||||
subscriptionType: fileCreds.subscriptionType,
|
||||
};
|
||||
}
|
||||
// No subscriptionType available - use keychain token anyway
|
||||
debug('Using keychain token without subscriptionType');
|
||||
return keychainCreds;
|
||||
}
|
||||
// Fall back to file-based credentials (older versions or non-macOS)
|
||||
const fileCreds = readFileCredentials(homeDir, now);
|
||||
if (fileCreds) {
|
||||
debug('Using credentials from file');
|
||||
return fileCreds;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getPlanName(subscriptionType) {
|
||||
const lower = subscriptionType.toLowerCase();
|
||||
if (lower.includes('max'))
|
||||
return 'Max';
|
||||
if (lower.includes('pro'))
|
||||
return 'Pro';
|
||||
if (lower.includes('team'))
|
||||
return 'Team';
|
||||
// API users don't have subscriptionType or have 'api'
|
||||
if (!subscriptionType || lower.includes('api'))
|
||||
return null;
|
||||
// Unknown subscription type - show it capitalized
|
||||
return subscriptionType.charAt(0).toUpperCase() + subscriptionType.slice(1);
|
||||
}
|
||||
/** Parse utilization value, clamping to 0-100 and handling NaN/Infinity */
|
||||
function parseUtilization(value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
if (!Number.isFinite(value))
|
||||
return null; // Handles NaN and Infinity
|
||||
return Math.round(Math.max(0, Math.min(100, value)));
|
||||
}
|
||||
/** Parse ISO date string safely, returning null for invalid dates */
|
||||
function parseDate(dateStr) {
|
||||
if (!dateStr)
|
||||
return null;
|
||||
const date = new Date(dateStr);
|
||||
// Check for Invalid Date
|
||||
if (isNaN(date.getTime())) {
|
||||
debug('Invalid date string:', dateStr);
|
||||
return null;
|
||||
}
|
||||
return date;
|
||||
}
|
||||
function fetchUsageApi(accessToken) {
|
||||
return new Promise((resolve) => {
|
||||
const options = {
|
||||
hostname: 'api.anthropic.com',
|
||||
path: '/api/oauth/usage',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
'anthropic-beta': 'oauth-2025-04-20',
|
||||
'User-Agent': 'claude-hud/1.0',
|
||||
},
|
||||
timeout: 5000,
|
||||
};
|
||||
const req = https.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => {
|
||||
data += chunk.toString();
|
||||
});
|
||||
res.on('end', () => {
|
||||
if (res.statusCode !== 200) {
|
||||
debug('API returned non-200 status:', res.statusCode);
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
resolve(parsed);
|
||||
}
|
||||
catch (error) {
|
||||
debug('Failed to parse API response:', error);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
req.on('error', (error) => {
|
||||
debug('API request error:', error);
|
||||
resolve(null);
|
||||
});
|
||||
req.on('timeout', () => {
|
||||
debug('API request timeout');
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
});
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
// Export for testing
|
||||
export function clearCache(homeDir) {
|
||||
if (homeDir) {
|
||||
try {
|
||||
const cachePath = getCachePath(homeDir);
|
||||
if (fs.existsSync(cachePath)) {
|
||||
fs.unlinkSync(cachePath);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=usage-api.js.map
|
||||
1
skills/plugins/claude-hud/dist/usage-api.js.map
vendored
Normal file
1
skills/plugins/claude-hud/dist/usage-api.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user