bashstats 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NUL +0 -10
- package/README.md +159 -46
- package/dist/{chunk-4HVDBCTU.js → chunk-YAJO5WNW.js} +1021 -179
- package/dist/chunk-YAJO5WNW.js.map +1 -0
- package/dist/cli.js +103 -40
- package/dist/cli.js.map +1 -1
- package/dist/hooks/{chunk-37VUNTM4.js → chunk-CLSVLWCR.js} +243 -28
- package/dist/hooks/chunk-CLSVLWCR.js.map +1 -0
- package/dist/hooks/notification.js +1 -1
- package/dist/hooks/permission-request.js +1 -1
- package/dist/hooks/post-tool-failure.js +1 -1
- package/dist/hooks/post-tool-use.js +1 -1
- package/dist/hooks/pre-compact.js +1 -1
- package/dist/hooks/pre-tool-use.js +1 -1
- package/dist/hooks/session-start.js +1 -1
- package/dist/hooks/setup.js +1 -1
- package/dist/hooks/stop.js +1 -1
- package/dist/hooks/subagent-start.js +1 -1
- package/dist/hooks/subagent-stop.js +1 -1
- package/dist/hooks/user-prompt-submit.js +1 -1
- package/dist/index.d.ts +145 -17
- package/dist/index.js +31 -5
- package/dist/static/index.html +806 -55
- package/package.json +1 -1
- package/dist/chunk-4HVDBCTU.js.map +0 -1
- package/dist/hooks/chunk-37VUNTM4.js.map +0 -1
package/dist/hooks/setup.js
CHANGED
package/dist/hooks/stop.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -177,6 +177,12 @@ interface AllStats {
|
|
|
177
177
|
sessions: SessionRecords;
|
|
178
178
|
projects: ProjectStats;
|
|
179
179
|
}
|
|
180
|
+
interface AgentBreakdown {
|
|
181
|
+
favoriteAgent: string;
|
|
182
|
+
sessionsPerAgent: Record<string, number>;
|
|
183
|
+
hoursPerAgent: Record<string, number>;
|
|
184
|
+
distinctAgents: number;
|
|
185
|
+
}
|
|
180
186
|
type AgentType = 'claude-code' | 'gemini-cli' | 'copilot-cli' | 'opencode' | 'unknown';
|
|
181
187
|
declare const AGENT_DISPLAY_NAMES: Record<AgentType, string>;
|
|
182
188
|
type BadgeTier = 0 | 1 | 2 | 3 | 4 | 5;
|
|
@@ -185,12 +191,11 @@ interface BadgeDefinition {
|
|
|
185
191
|
name: string;
|
|
186
192
|
icon: string;
|
|
187
193
|
description: string;
|
|
188
|
-
category: 'volume' | 'tool_mastery' | 'time' | 'behavioral' | 'resilience' | 'shipping' | 'multi_agent' | '
|
|
194
|
+
category: 'volume' | 'tool_mastery' | 'time' | 'behavioral' | 'resilience' | 'shipping' | 'multi_agent' | 'wild_card' | 'aspirational' | 'secret' | 'session_behavior' | 'prompt_patterns' | 'error_recovery' | 'tool_combos' | 'project_dedication' | 'token_usage';
|
|
189
195
|
stat: string;
|
|
190
196
|
tiers: [number, number, number, number, number];
|
|
191
197
|
trigger: string;
|
|
192
198
|
secret?: boolean;
|
|
193
|
-
humor?: boolean;
|
|
194
199
|
aspirational?: boolean;
|
|
195
200
|
}
|
|
196
201
|
interface BadgeResult {
|
|
@@ -213,7 +218,8 @@ interface BadgeResult {
|
|
|
213
218
|
}
|
|
214
219
|
interface XPResult {
|
|
215
220
|
totalXP: number;
|
|
216
|
-
|
|
221
|
+
rankNumber: number;
|
|
222
|
+
rankTier: string;
|
|
217
223
|
nextRankXP: number;
|
|
218
224
|
progress: number;
|
|
219
225
|
}
|
|
@@ -223,6 +229,45 @@ interface AchievementsPayload {
|
|
|
223
229
|
xp: XPResult;
|
|
224
230
|
}
|
|
225
231
|
declare const TIER_NAMES: Record<BadgeTier, string>;
|
|
232
|
+
interface WeeklyChallenge {
|
|
233
|
+
id: string;
|
|
234
|
+
description: string;
|
|
235
|
+
stat: string;
|
|
236
|
+
threshold: number;
|
|
237
|
+
xpReward: number;
|
|
238
|
+
weekScoped: boolean;
|
|
239
|
+
}
|
|
240
|
+
interface WeeklyGoalRow {
|
|
241
|
+
week_start: string;
|
|
242
|
+
challenge_id: string;
|
|
243
|
+
completed: number;
|
|
244
|
+
xp_reward: number;
|
|
245
|
+
}
|
|
246
|
+
interface WeeklyXPRow {
|
|
247
|
+
week_start: string;
|
|
248
|
+
base_xp: number;
|
|
249
|
+
multiplier: number;
|
|
250
|
+
bonus_xp: number;
|
|
251
|
+
}
|
|
252
|
+
interface WeeklyGoalsPayload {
|
|
253
|
+
weekStart: string;
|
|
254
|
+
daysActive: number;
|
|
255
|
+
multiplier: number;
|
|
256
|
+
challenges: Array<{
|
|
257
|
+
id: string;
|
|
258
|
+
description: string;
|
|
259
|
+
xpReward: number;
|
|
260
|
+
completed: boolean;
|
|
261
|
+
progress: number;
|
|
262
|
+
threshold: number;
|
|
263
|
+
current: number;
|
|
264
|
+
}>;
|
|
265
|
+
}
|
|
266
|
+
interface RankTierBracket {
|
|
267
|
+
tier: string;
|
|
268
|
+
minRank: number;
|
|
269
|
+
maxRank: number;
|
|
270
|
+
}
|
|
226
271
|
|
|
227
272
|
declare class BashStatsDB {
|
|
228
273
|
private db;
|
|
@@ -271,6 +316,11 @@ declare class BashStatsDB {
|
|
|
271
316
|
markNotified(badgeId: string, tier: number): void;
|
|
272
317
|
setMetadata(key: string, value: string): void;
|
|
273
318
|
getMetadata(key: string): string | null;
|
|
319
|
+
insertWeeklyGoal(weekStart: string, challengeId: string, xpReward: number): void;
|
|
320
|
+
completeWeeklyGoal(weekStart: string, challengeId: string): void;
|
|
321
|
+
getWeeklyGoals(weekStart: string): WeeklyGoalRow[];
|
|
322
|
+
upsertWeeklyXP(weekStart: string, baseXP: number, multiplier: number, bonusXP: number): void;
|
|
323
|
+
getWeeklyXP(weekStart: string): WeeklyXPRow | null;
|
|
274
324
|
prepare(sql: string): Database.Statement;
|
|
275
325
|
}
|
|
276
326
|
|
|
@@ -293,21 +343,33 @@ declare class StatsEngine {
|
|
|
293
343
|
private db;
|
|
294
344
|
constructor(db: BashStatsDB);
|
|
295
345
|
private queryScalar;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
346
|
+
/** Returns a WHERE/AND clause filtering sessions by agent */
|
|
347
|
+
private agentWhere;
|
|
348
|
+
/** Returns a subquery filter for events/prompts tables */
|
|
349
|
+
private agentSessionFilter;
|
|
350
|
+
getLifetimeStats(agent?: string): LifetimeStats;
|
|
351
|
+
getToolBreakdown(agent?: string): ToolBreakdown;
|
|
352
|
+
getTimeStats(agent?: string): TimeStats;
|
|
353
|
+
getSessionRecords(agent?: string): SessionRecords;
|
|
354
|
+
getProjectStats(agent?: string): ProjectStats;
|
|
355
|
+
getAllStats(agent?: string): AllStats;
|
|
356
|
+
getAgentBreakdown(): {
|
|
357
|
+
favoriteAgent: string;
|
|
358
|
+
sessionsPerAgent: Record<string, number>;
|
|
359
|
+
hoursPerAgent: Record<string, number>;
|
|
360
|
+
distinctAgents: number;
|
|
361
|
+
};
|
|
362
|
+
getWeeklyGoalsPayload(): WeeklyGoalsPayload;
|
|
363
|
+
private computeWeeklyStat;
|
|
302
364
|
}
|
|
303
365
|
|
|
304
366
|
declare class AchievementEngine {
|
|
305
367
|
private db;
|
|
306
368
|
private stats;
|
|
307
369
|
constructor(db: BashStatsDB, stats: StatsEngine);
|
|
308
|
-
computeBadges(): BadgeResult[];
|
|
309
|
-
computeXP(): XPResult;
|
|
310
|
-
getAchievementsPayload(): AchievementsPayload;
|
|
370
|
+
computeBadges(agent?: string): BadgeResult[];
|
|
371
|
+
computeXP(agent?: string): XPResult;
|
|
372
|
+
getAchievementsPayload(agent?: string): AchievementsPayload;
|
|
311
373
|
private flattenStats;
|
|
312
374
|
private queryScalar;
|
|
313
375
|
private queryTotalSearches;
|
|
@@ -409,6 +471,71 @@ declare function uninstall(): {
|
|
|
409
471
|
*/
|
|
410
472
|
declare function isInstalled(): boolean;
|
|
411
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Checks if the ~/.gemini/ directory exists, indicating Gemini CLI is available.
|
|
476
|
+
*/
|
|
477
|
+
declare function isGeminiAvailable(): boolean;
|
|
478
|
+
/**
|
|
479
|
+
* Full Gemini installation:
|
|
480
|
+
* - Creates ~/.bashstats/ directory
|
|
481
|
+
* - Initializes the database with metadata
|
|
482
|
+
* - Reads existing ~/.gemini/settings.json
|
|
483
|
+
* - Merges bashstats hooks
|
|
484
|
+
* - Writes settings back
|
|
485
|
+
*/
|
|
486
|
+
declare function installGemini(): {
|
|
487
|
+
success: boolean;
|
|
488
|
+
message: string;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* Removes all bashstats hooks from ~/.gemini/settings.json.
|
|
492
|
+
* Cleans up empty arrays and empty hooks objects.
|
|
493
|
+
*/
|
|
494
|
+
declare function uninstallGemini(): {
|
|
495
|
+
success: boolean;
|
|
496
|
+
message: string;
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Installs bashstats hooks for Copilot by writing bashstats-hooks.json
|
|
501
|
+
* to ~/.copilot/hooks/.
|
|
502
|
+
*/
|
|
503
|
+
declare function installCopilot(): {
|
|
504
|
+
success: boolean;
|
|
505
|
+
message: string;
|
|
506
|
+
};
|
|
507
|
+
/**
|
|
508
|
+
* Uninstalls bashstats hooks for Copilot by deleting bashstats-hooks.json.
|
|
509
|
+
*/
|
|
510
|
+
declare function uninstallCopilot(): {
|
|
511
|
+
success: boolean;
|
|
512
|
+
message: string;
|
|
513
|
+
};
|
|
514
|
+
/**
|
|
515
|
+
* Checks if the `copilot` binary is available on PATH.
|
|
516
|
+
*/
|
|
517
|
+
declare function isCopilotAvailable(): boolean;
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Checks whether OpenCode is available by looking for ~/.config/opencode/.
|
|
521
|
+
*/
|
|
522
|
+
declare function isOpenCodeAvailable(): boolean;
|
|
523
|
+
/**
|
|
524
|
+
* Installs the bashstats plugin into OpenCode's plugins directory.
|
|
525
|
+
* Creates the plugins directory if it does not exist.
|
|
526
|
+
*/
|
|
527
|
+
declare function installOpenCode(): {
|
|
528
|
+
success: boolean;
|
|
529
|
+
message: string;
|
|
530
|
+
};
|
|
531
|
+
/**
|
|
532
|
+
* Removes the bashstats plugin file from OpenCode's plugins directory.
|
|
533
|
+
*/
|
|
534
|
+
declare function uninstallOpenCode(): {
|
|
535
|
+
success: boolean;
|
|
536
|
+
message: string;
|
|
537
|
+
};
|
|
538
|
+
|
|
412
539
|
/**
|
|
413
540
|
* Detect which CLI agent is running based on environment variables and process context.
|
|
414
541
|
* Currently supports Claude Code (default), Gemini CLI, Copilot CLI, and OpenCode.
|
|
@@ -418,13 +545,14 @@ declare function parseHookEvent(input: string): Record<string, unknown> | null;
|
|
|
418
545
|
declare function handleHookEvent(hookType: string): Promise<void>;
|
|
419
546
|
|
|
420
547
|
declare const BADGE_DEFINITIONS: BadgeDefinition[];
|
|
421
|
-
declare const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}[];
|
|
548
|
+
declare const RANK_TIER_BRACKETS: RankTierBracket[];
|
|
549
|
+
declare function xpForRank(rank: number): number;
|
|
550
|
+
declare function rankTierForRank(rank: number): string;
|
|
425
551
|
declare const TIER_XP: number[];
|
|
552
|
+
declare const ACTIVITY_MULTIPLIERS: Record<number, number>;
|
|
553
|
+
declare const WEEKLY_CHALLENGES: WeeklyChallenge[];
|
|
426
554
|
declare const DATA_DIR = ".bashstats";
|
|
427
555
|
declare const DB_FILENAME = "bashstats.db";
|
|
428
556
|
declare const DEFAULT_PORT = 17900;
|
|
429
557
|
|
|
430
|
-
export { AGENT_DISPLAY_NAMES, AchievementEngine, type AchievementUnlockRow, type AchievementsPayload, type AgentType, type AllStats, BADGE_DEFINITIONS, type BadgeDefinition, type BadgeResult, type BadgeTier, BashStatsDB, BashStatsWriter, DATA_DIR, DB_FILENAME, DEFAULT_PORT, type DailyActivityRow, type EventRow, type HookInput, type LifetimeStats, type NotificationInput, type PermissionRequestInput, type PostToolUseInput, type PreCompactInput, type PreToolUseInput, type ProjectStats, type PromptRow,
|
|
558
|
+
export { ACTIVITY_MULTIPLIERS, AGENT_DISPLAY_NAMES, AchievementEngine, type AchievementUnlockRow, type AchievementsPayload, type AgentBreakdown, type AgentType, type AllStats, BADGE_DEFINITIONS, type BadgeDefinition, type BadgeResult, type BadgeTier, BashStatsDB, BashStatsWriter, DATA_DIR, DB_FILENAME, DEFAULT_PORT, type DailyActivityRow, type EventRow, type HookInput, type LifetimeStats, type NotificationInput, type PermissionRequestInput, type PostToolUseInput, type PreCompactInput, type PreToolUseInput, type ProjectStats, type PromptRow, RANK_TIER_BRACKETS, type RankTierBracket, type SessionRecords, type SessionRow, type SessionStartInput, type SetupInput, StatsEngine, type StopInput, type SubagentStartInput, type SubagentStopInput, TIER_NAMES, TIER_XP, type TimeStats, type TokenUsage, type ToolBreakdown, type UserPromptInput, WEEKLY_CHALLENGES, type WeeklyChallenge, type WeeklyGoalRow, type WeeklyGoalsPayload, type WeeklyXPRow, type XPResult, detectAgent, handleHookEvent, install, installCopilot, installGemini, installOpenCode, isCopilotAvailable, isGeminiAvailable, isInstalled, isOpenCodeAvailable, parseHookEvent, rankTierForRank, uninstall, uninstallCopilot, uninstallGemini, uninstallOpenCode, xpForRank };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
ACTIVITY_MULTIPLIERS,
|
|
3
4
|
AGENT_DISPLAY_NAMES,
|
|
4
5
|
AchievementEngine,
|
|
5
6
|
BADGE_DEFINITIONS,
|
|
@@ -8,18 +9,31 @@ import {
|
|
|
8
9
|
DATA_DIR,
|
|
9
10
|
DB_FILENAME,
|
|
10
11
|
DEFAULT_PORT,
|
|
11
|
-
|
|
12
|
+
RANK_TIER_BRACKETS,
|
|
12
13
|
StatsEngine,
|
|
13
14
|
TIER_NAMES,
|
|
14
15
|
TIER_XP,
|
|
16
|
+
WEEKLY_CHALLENGES,
|
|
15
17
|
detectAgent,
|
|
16
18
|
handleHookEvent,
|
|
17
19
|
install,
|
|
20
|
+
installCopilot,
|
|
21
|
+
installGemini,
|
|
22
|
+
installOpenCode,
|
|
23
|
+
isCopilotAvailable,
|
|
24
|
+
isGeminiAvailable,
|
|
18
25
|
isInstalled,
|
|
26
|
+
isOpenCodeAvailable,
|
|
19
27
|
parseHookEvent,
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
rankTierForRank,
|
|
29
|
+
uninstall,
|
|
30
|
+
uninstallCopilot,
|
|
31
|
+
uninstallGemini,
|
|
32
|
+
uninstallOpenCode,
|
|
33
|
+
xpForRank
|
|
34
|
+
} from "./chunk-YAJO5WNW.js";
|
|
22
35
|
export {
|
|
36
|
+
ACTIVITY_MULTIPLIERS,
|
|
23
37
|
AGENT_DISPLAY_NAMES,
|
|
24
38
|
AchievementEngine,
|
|
25
39
|
BADGE_DEFINITIONS,
|
|
@@ -28,15 +42,27 @@ export {
|
|
|
28
42
|
DATA_DIR,
|
|
29
43
|
DB_FILENAME,
|
|
30
44
|
DEFAULT_PORT,
|
|
31
|
-
|
|
45
|
+
RANK_TIER_BRACKETS,
|
|
32
46
|
StatsEngine,
|
|
33
47
|
TIER_NAMES,
|
|
34
48
|
TIER_XP,
|
|
49
|
+
WEEKLY_CHALLENGES,
|
|
35
50
|
detectAgent,
|
|
36
51
|
handleHookEvent,
|
|
37
52
|
install,
|
|
53
|
+
installCopilot,
|
|
54
|
+
installGemini,
|
|
55
|
+
installOpenCode,
|
|
56
|
+
isCopilotAvailable,
|
|
57
|
+
isGeminiAvailable,
|
|
38
58
|
isInstalled,
|
|
59
|
+
isOpenCodeAvailable,
|
|
39
60
|
parseHookEvent,
|
|
40
|
-
|
|
61
|
+
rankTierForRank,
|
|
62
|
+
uninstall,
|
|
63
|
+
uninstallCopilot,
|
|
64
|
+
uninstallGemini,
|
|
65
|
+
uninstallOpenCode,
|
|
66
|
+
xpForRank
|
|
41
67
|
};
|
|
42
68
|
//# sourceMappingURL=index.js.map
|