cc-proficiency 0.2.3 → 0.2.5

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.
Files changed (146) hide show
  1. package/README.md +23 -0
  2. package/dist/cli/commands/achievements.d.ts +2 -0
  3. package/dist/cli/commands/achievements.d.ts.map +1 -0
  4. package/dist/cli/commands/achievements.js +52 -0
  5. package/dist/cli/commands/achievements.js.map +1 -0
  6. package/dist/cli/commands/analyze.d.ts +2 -0
  7. package/dist/cli/commands/analyze.d.ts.map +1 -0
  8. package/dist/cli/commands/analyze.js +32 -0
  9. package/dist/cli/commands/analyze.js.map +1 -0
  10. package/dist/cli/commands/badge.d.ts +2 -0
  11. package/dist/cli/commands/badge.d.ts.map +1 -0
  12. package/dist/cli/commands/badge.js +25 -0
  13. package/dist/cli/commands/badge.js.map +1 -0
  14. package/dist/cli/commands/config.d.ts +2 -0
  15. package/dist/cli/commands/config.d.ts.map +1 -0
  16. package/dist/cli/commands/config.js +43 -0
  17. package/dist/cli/commands/config.js.map +1 -0
  18. package/dist/cli/commands/explain.d.ts +2 -0
  19. package/dist/cli/commands/explain.d.ts.map +1 -0
  20. package/dist/cli/commands/explain.js +44 -0
  21. package/dist/cli/commands/explain.js.map +1 -0
  22. package/dist/cli/commands/init.d.ts +2 -0
  23. package/dist/cli/commands/init.d.ts.map +1 -0
  24. package/dist/cli/commands/init.js +69 -0
  25. package/dist/cli/commands/init.js.map +1 -0
  26. package/dist/cli/commands/leaderboard.d.ts +2 -0
  27. package/dist/cli/commands/leaderboard.d.ts.map +1 -0
  28. package/dist/cli/commands/leaderboard.js +58 -0
  29. package/dist/cli/commands/leaderboard.js.map +1 -0
  30. package/dist/cli/commands/process.d.ts +2 -0
  31. package/dist/cli/commands/process.d.ts.map +1 -0
  32. package/dist/cli/commands/process.js +84 -0
  33. package/dist/cli/commands/process.js.map +1 -0
  34. package/dist/cli/commands/push.d.ts +2 -0
  35. package/dist/cli/commands/push.d.ts.map +1 -0
  36. package/dist/cli/commands/push.js +8 -0
  37. package/dist/cli/commands/push.js.map +1 -0
  38. package/dist/cli/commands/share.d.ts +2 -0
  39. package/dist/cli/commands/share.d.ts.map +1 -0
  40. package/dist/cli/commands/share.js +129 -0
  41. package/dist/cli/commands/share.js.map +1 -0
  42. package/dist/cli/commands/status.d.ts +2 -0
  43. package/dist/cli/commands/status.d.ts.map +1 -0
  44. package/dist/cli/commands/status.js +54 -0
  45. package/dist/cli/commands/status.js.map +1 -0
  46. package/dist/cli/commands/uninstall.d.ts +2 -0
  47. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  48. package/dist/cli/commands/uninstall.js +27 -0
  49. package/dist/cli/commands/uninstall.js.map +1 -0
  50. package/dist/cli/index.d.ts +3 -0
  51. package/dist/cli/index.d.ts.map +1 -0
  52. package/dist/cli/index.js +108 -0
  53. package/dist/cli/index.js.map +1 -0
  54. package/dist/cli/services/hooks.d.ts +3 -0
  55. package/dist/cli/services/hooks.d.ts.map +1 -0
  56. package/dist/cli/services/hooks.js +68 -0
  57. package/dist/cli/services/hooks.js.map +1 -0
  58. package/dist/cli/services/leaderboard.d.ts +11 -0
  59. package/dist/cli/services/leaderboard.d.ts.map +1 -0
  60. package/dist/cli/services/leaderboard.js +120 -0
  61. package/dist/cli/services/leaderboard.js.map +1 -0
  62. package/dist/cli/services/publishing.d.ts +18 -0
  63. package/dist/cli/services/publishing.d.ts.map +1 -0
  64. package/dist/cli/services/publishing.js +112 -0
  65. package/dist/cli/services/publishing.js.map +1 -0
  66. package/dist/cli/services/sessions.d.ts +11 -0
  67. package/dist/cli/services/sessions.d.ts.map +1 -0
  68. package/dist/cli/services/sessions.js +80 -0
  69. package/dist/cli/services/sessions.js.map +1 -0
  70. package/dist/cli/utils/formatting.d.ts +5 -0
  71. package/dist/cli/utils/formatting.d.ts.map +1 -0
  72. package/dist/cli/utils/formatting.js +66 -0
  73. package/dist/cli/utils/formatting.js.map +1 -0
  74. package/dist/cli/utils/locale.d.ts +3 -0
  75. package/dist/cli/utils/locale.d.ts.map +1 -0
  76. package/dist/cli/utils/locale.js +14 -0
  77. package/dist/cli/utils/locale.js.map +1 -0
  78. package/dist/cli/utils/update-check.d.ts +7 -0
  79. package/dist/cli/utils/update-check.d.ts.map +1 -0
  80. package/dist/cli/utils/update-check.js +122 -0
  81. package/dist/cli/utils/update-check.js.map +1 -0
  82. package/dist/gist/registry.d.ts +26 -0
  83. package/dist/gist/registry.d.ts.map +1 -0
  84. package/dist/gist/registry.js +101 -0
  85. package/dist/gist/registry.js.map +1 -0
  86. package/dist/gist/uploader.d.ts +9 -1
  87. package/dist/gist/uploader.d.ts.map +1 -1
  88. package/dist/gist/uploader.js +47 -1
  89. package/dist/gist/uploader.js.map +1 -1
  90. package/dist/hooks/session-end.js +3 -2
  91. package/dist/i18n/locales.d.ts.map +1 -1
  92. package/dist/i18n/locales.js +2 -1
  93. package/dist/i18n/locales.js.map +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +3 -1
  97. package/dist/index.js.map +1 -1
  98. package/dist/parsers/config-detectors.d.ts +29 -0
  99. package/dist/parsers/config-detectors.d.ts.map +1 -0
  100. package/dist/parsers/config-detectors.js +367 -0
  101. package/dist/parsers/config-detectors.js.map +1 -0
  102. package/dist/parsers/config-parser.d.ts +7 -2
  103. package/dist/parsers/config-parser.d.ts.map +1 -1
  104. package/dist/parsers/config-parser.js +36 -228
  105. package/dist/parsers/config-parser.js.map +1 -1
  106. package/dist/renderer/svg.d.ts.map +1 -1
  107. package/dist/renderer/svg.js +3 -1
  108. package/dist/renderer/svg.js.map +1 -1
  109. package/dist/scoring/engine.d.ts +1 -1
  110. package/dist/scoring/engine.d.ts.map +1 -1
  111. package/dist/scoring/engine.js +30 -8
  112. package/dist/scoring/engine.js.map +1 -1
  113. package/dist/scoring/feature-scores.d.ts +27 -0
  114. package/dist/scoring/feature-scores.d.ts.map +1 -0
  115. package/dist/scoring/feature-scores.js +63 -0
  116. package/dist/scoring/feature-scores.js.map +1 -0
  117. package/dist/scoring/rule-engine.d.ts.map +1 -1
  118. package/dist/scoring/rule-engine.js.map +1 -1
  119. package/dist/scoring/rules.d.ts.map +1 -1
  120. package/dist/scoring/rules.js +12 -0
  121. package/dist/scoring/rules.js.map +1 -1
  122. package/dist/scoring/signals.js +4 -2
  123. package/dist/scoring/signals.js.map +1 -1
  124. package/dist/store/achievements.d.ts.map +1 -1
  125. package/dist/store/achievements.js +8 -0
  126. package/dist/store/achievements.js.map +1 -1
  127. package/dist/store/local-store.d.ts +3 -1
  128. package/dist/store/local-store.d.ts.map +1 -1
  129. package/dist/store/local-store.js +21 -3
  130. package/dist/store/local-store.js.map +1 -1
  131. package/dist/store/public-profile.d.ts +12 -0
  132. package/dist/store/public-profile.d.ts.map +1 -0
  133. package/dist/store/public-profile.js +50 -0
  134. package/dist/store/public-profile.js.map +1 -0
  135. package/dist/store/queue.js +1 -1
  136. package/dist/store/queue.js.map +1 -1
  137. package/dist/store/remote-store.d.ts.map +1 -1
  138. package/dist/types.d.ts +54 -0
  139. package/dist/types.d.ts.map +1 -1
  140. package/hooks/session-end.ts +4 -3
  141. package/package.json +8 -3
  142. package/dist/cli.d.ts +0 -3
  143. package/dist/cli.d.ts.map +0 -1
  144. package/dist/cli.js +0 -722
  145. package/dist/cli.js.map +0 -1
  146. package/skills/proficiency/SKILL.md +0 -15
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeAndPush = mergeAndPush;
4
+ exports.pushToGist = pushToGist;
5
+ const svg_js_1 = require("../../renderer/svg.js");
6
+ const local_store_js_1 = require("../../store/local-store.js");
7
+ const uploader_js_1 = require("../../gist/uploader.js");
8
+ const remote_store_js_1 = require("../../store/remote-store.js");
9
+ const achievements_js_1 = require("../../store/achievements.js");
10
+ const public_profile_js_1 = require("../../store/public-profile.js");
11
+ const locale_js_1 = require("../utils/locale.js");
12
+ /**
13
+ * Read remote store, merge local data, check achievements, re-render badge,
14
+ * and push SVG + JSON atomically. Used by both cmdPush and cmdProcess.
15
+ */
16
+ function mergeAndPush(store, result, gistId, username, verbose = false) {
17
+ const remoteJson = (0, uploader_js_1.readGistFile)(gistId, "cc-proficiency.json");
18
+ let remote = remoteJson ? (0, remote_store_js_1.parseRemoteStore)(remoteJson) : null;
19
+ if (!remote)
20
+ remote = (0, remote_store_js_1.emptyRemoteStore)(username);
21
+ const avgHours = result.features.totalHours / Math.max(store.processedSessionIds.length, 1);
22
+ const localSessions = store.processedSessionIds.map((id) => {
23
+ const snap = store.snapshots.find((s) => s.sessionId === id);
24
+ return {
25
+ id,
26
+ date: snap ? (0, remote_store_js_1.getUTCDate)(snap.timestamp) : new Date().toISOString().slice(0, 10),
27
+ hours: avgHours,
28
+ };
29
+ });
30
+ const merged = (0, remote_store_js_1.mergeIntoRemote)(remote, localSessions, result);
31
+ const totals = (0, remote_store_js_1.getTotalStats)(merged);
32
+ const cfg = (0, local_store_js_1.loadConfig)();
33
+ const ctx = {
34
+ totalSessions: totals.sessions,
35
+ totalHours: totals.hours,
36
+ totalProjects: totals.projects,
37
+ domains: merged.domains,
38
+ streak: merged.streak,
39
+ features: result.features,
40
+ activeDates: merged.streak.activeDates,
41
+ leaderboard: cfg.leaderboard ?? false,
42
+ };
43
+ const newAchievements = (0, achievements_js_1.checkAchievements)(ctx, merged.achievements.map((a) => a.id));
44
+ for (const id of newAchievements) {
45
+ merged.achievements.push({ id, unlockedAt: new Date().toISOString() });
46
+ const def = (0, achievements_js_1.getAchievementDef)(id);
47
+ if (def && verbose)
48
+ console.log(` \uD83C\uDFC6 Achievement unlocked: ${def.icon} ${def.name}`);
49
+ }
50
+ const thisWeek = (0, remote_store_js_1.getWeekMonday)(new Date().toISOString());
51
+ const localTrend = {
52
+ week: thisWeek,
53
+ domains: Object.fromEntries(result.domains.map((d) => [d.id, d.score])),
54
+ hours: result.features.totalHours,
55
+ sessions: result.sessionCount,
56
+ };
57
+ merged.weeklyTrends = (0, remote_store_js_1.mergeWeeklyTrends)(merged.weeklyTrends, [localTrend]);
58
+ result.streak = merged.streak.current;
59
+ result.achievementCount = merged.achievements.length;
60
+ const finalSvg = (0, svg_js_1.renderBadge)(result, (0, locale_js_1.getConfigLocale)());
61
+ (0, local_store_js_1.saveBadge)(finalSvg);
62
+ const pushResult = (0, uploader_js_1.pushGistFiles)(gistId, {
63
+ "cc-proficiency.svg": finalSvg,
64
+ "cc-proficiency.json": JSON.stringify(merged, null, 2),
65
+ });
66
+ if (!pushResult.success) {
67
+ return { success: false, error: pushResult.error };
68
+ }
69
+ if (verbose) {
70
+ const rawUrl = (0, uploader_js_1.getGistRawUrl)(username, gistId);
71
+ console.log("\u2713 Badge + data pushed to Gist");
72
+ console.log(` ${rawUrl}`);
73
+ console.log(` ${totals.sessions} sessions \u00B7 ${totals.hours.toFixed(1)}h \u00B7 ${merged.achievements.length} achievements \u00B7 \uD83D\uDD25 ${merged.streak.current}d streak`);
74
+ }
75
+ // Auto-update public profile if leaderboard is enabled
76
+ if (cfg.leaderboard && cfg.publicGistId) {
77
+ const publicProfile = (0, public_profile_js_1.buildPublicProfile)(merged);
78
+ const publicResult = (0, uploader_js_1.pushGistFiles)(cfg.publicGistId, {
79
+ "cc-proficiency-public.json": JSON.stringify(publicProfile, null, 2),
80
+ });
81
+ if (!publicResult.success) {
82
+ (0, local_store_js_1.logError)(`Public profile update failed: ${publicResult.error}`);
83
+ }
84
+ }
85
+ return { success: true, merged, totals };
86
+ }
87
+ function pushToGist() {
88
+ const config = (0, local_store_js_1.loadConfig)();
89
+ const store = (0, local_store_js_1.loadStore)();
90
+ if (!store.lastResult) {
91
+ console.log("No analysis data. Run 'cc-proficiency analyze' first.");
92
+ return;
93
+ }
94
+ const svg = (0, svg_js_1.renderBadge)(store.lastResult, (0, locale_js_1.getConfigLocale)());
95
+ (0, local_store_js_1.saveBadge)(svg);
96
+ if (!(0, uploader_js_1.isGhAuthenticated)() || !config.gistId) {
97
+ if (!(0, uploader_js_1.isGhAuthenticated)()) {
98
+ console.log("\u26A0 GitHub CLI not authenticated.");
99
+ console.log("To enable: gh auth login && cc-proficiency init");
100
+ }
101
+ if (!config.gistId) {
102
+ console.log("No Gist configured. Run 'cc-proficiency init' first.");
103
+ }
104
+ console.log("Badge saved locally to: " + (0, local_store_js_1.getBadgePath)());
105
+ return;
106
+ }
107
+ const result = mergeAndPush(store, store.lastResult, config.gistId, config.username ?? "unknown", true);
108
+ if (!result.success) {
109
+ console.log(`\u2717 Push failed: ${result.error}`);
110
+ }
111
+ }
112
+ //# sourceMappingURL=publishing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publishing.js","sourceRoot":"","sources":["../../../src/cli/services/publishing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { computeProficiency } from "../../scoring/engine.js";
2
+ import { loadStore } from "../../store/local-store.js";
3
+ import type { ParsedSession } from "../../types.js";
4
+ import type { ConfigSignals } from "../../parsers/config-parser.js";
5
+ export declare function gatherData(full: boolean): Promise<{
6
+ sessions: ParsedSession[];
7
+ config: ConfigSignals;
8
+ }>;
9
+ export declare function gatherAllProcessedSessions(store: ReturnType<typeof loadStore>): Promise<ParsedSession[]>;
10
+ export declare function runAnalysis(sessions: ParsedSession[], config: ConfigSignals, username: string): ReturnType<typeof computeProficiency>;
11
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/cli/services/sessions.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAsB,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAIpE,wBAAsB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,CAmC7G;AAED,wBAAsB,0BAA0B,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAuB9G;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,GACf,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAGvC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gatherData = gatherData;
4
+ exports.gatherAllProcessedSessions = gatherAllProcessedSessions;
5
+ exports.runAnalysis = runAnalysis;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const node_os_1 = require("node:os");
9
+ const transcript_parser_js_1 = require("../../parsers/transcript-parser.js");
10
+ const config_parser_js_1 = require("../../parsers/config-parser.js");
11
+ const engine_js_1 = require("../../scoring/engine.js");
12
+ const local_store_js_1 = require("../../store/local-store.js");
13
+ const CLAUDE_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".claude");
14
+ async function gatherData(full) {
15
+ const realStore = (0, local_store_js_1.loadStore)();
16
+ const knownCwds = [...new Set([process.cwd(), ...(realStore.knownProjectCwds ?? [])])];
17
+ const config = (0, config_parser_js_1.parseClaudeConfig)(knownCwds);
18
+ const sessions = [];
19
+ const store = full ? { processedSessionIds: [] } : realStore;
20
+ const projectsDir = (0, node_path_1.join)(CLAUDE_DIR, "projects");
21
+ if (!(0, node_fs_1.existsSync)(projectsDir))
22
+ return { sessions, config };
23
+ const projects = (0, node_fs_1.readdirSync)(projectsDir);
24
+ for (const proj of projects) {
25
+ const projDir = (0, node_path_1.join)(projectsDir, proj);
26
+ try {
27
+ const files = (0, node_fs_1.readdirSync)(projDir).filter((f) => f.endsWith(".jsonl"));
28
+ for (const file of files) {
29
+ const sessionId = file.replace(".jsonl", "");
30
+ if (!full && (0, local_store_js_1.isSessionProcessed)(store, sessionId)) {
31
+ continue;
32
+ }
33
+ try {
34
+ const session = await (0, transcript_parser_js_1.parseTranscript)((0, node_path_1.join)(projDir, file));
35
+ if (session.events.length > 0) {
36
+ sessions.push(session);
37
+ }
38
+ }
39
+ catch {
40
+ // skip unreadable files
41
+ }
42
+ }
43
+ }
44
+ catch {
45
+ // skip unreadable project dirs
46
+ }
47
+ }
48
+ return { sessions, config };
49
+ }
50
+ async function gatherAllProcessedSessions(store) {
51
+ const sessions = [];
52
+ const projectsDir = (0, node_path_1.join)(CLAUDE_DIR, "projects");
53
+ if (!(0, node_fs_1.existsSync)(projectsDir))
54
+ return sessions;
55
+ const projects = (0, node_fs_1.readdirSync)(projectsDir);
56
+ for (const proj of projects) {
57
+ const projDir = (0, node_path_1.join)(projectsDir, proj);
58
+ try {
59
+ const files = (0, node_fs_1.readdirSync)(projDir).filter((f) => f.endsWith(".jsonl"));
60
+ for (const file of files) {
61
+ const sessionId = file.replace(".jsonl", "");
62
+ if (store.processedSessionIds.includes(sessionId)) {
63
+ try {
64
+ const session = await (0, transcript_parser_js_1.parseTranscript)((0, node_path_1.join)(projDir, file));
65
+ if (session.events.length > 0)
66
+ sessions.push(session);
67
+ }
68
+ catch { /* skip */ }
69
+ }
70
+ }
71
+ }
72
+ catch { /* skip */ }
73
+ }
74
+ return sessions;
75
+ }
76
+ function runAnalysis(sessions, config, username) {
77
+ const setupChecklist = (0, config_parser_js_1.buildSetupChecklist)(config);
78
+ return (0, engine_js_1.computeProficiency)(sessions, config, username, setupChecklist);
79
+ }
80
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/cli/services/sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ProficiencyResult, SetupChecklist } from "../../types.js";
2
+ export declare function progressBar(score: number, width: number): string;
3
+ export declare function printResult(result: ProficiencyResult): void;
4
+ export declare function printSetupChecklist(cl: SetupChecklist): void;
5
+ //# sourceMappingURL=formatting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/formatting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CA4C3D;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAgB5D"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.progressBar = progressBar;
4
+ exports.printResult = printResult;
5
+ exports.printSetupChecklist = printSetupChecklist;
6
+ function progressBar(score, width) {
7
+ const filled = Math.round((score / 100) * width);
8
+ const empty = width - filled;
9
+ return "\u2588".repeat(filled) + "\u2591".repeat(empty);
10
+ }
11
+ function printResult(result) {
12
+ console.log(` Claude Code Proficiency \u2014 @${result.username}`);
13
+ console.log(" " + "\u2500".repeat(40));
14
+ if (result.phase === "calibrating") {
15
+ const needed = Math.max(0, 3 - result.sessionCount);
16
+ console.log(` \u23F3 Calibrating... (${result.sessionCount} sessions, need ${needed} more)`);
17
+ console.log("");
18
+ printSetupChecklist(result.setupChecklist);
19
+ return;
20
+ }
21
+ for (const d of result.domains) {
22
+ const bar = progressBar(d.score, 20);
23
+ const conf = d.confidence === "high" ? "\u25CF" : d.confidence === "medium" ? "\u25D0" : "\u25CB";
24
+ console.log(` ${d.label.padEnd(14)} ${bar} ${String(d.score).padStart(3)} ${conf}`);
25
+ }
26
+ console.log(" " + "\u2500".repeat(40));
27
+ const f = result.features;
28
+ if (f.hooks.length > 0) {
29
+ const shown = f.hooks.slice(0, 3).map((h) => `${h.name} (${h.count}x)`).join(", ");
30
+ const more = f.hooks.length > 3 ? ` +${f.hooks.length - 3}` : "";
31
+ console.log(` Hooks ${shown}${more}`);
32
+ }
33
+ if (f.skills.length > 0) {
34
+ const shown = f.skills.slice(0, 3).map((s) => `${s.name} (${s.count}x)`).join(", ");
35
+ const more = f.skills.length > 3 ? ` +${f.skills.length - 3}` : "";
36
+ console.log(` Skills ${shown}${more}`);
37
+ }
38
+ if (f.mcpServers.length > 0) {
39
+ console.log(` MCP ${f.mcpServers.join(", ")}`);
40
+ }
41
+ const toolSummary = f.topTools.slice(0, 4).map((t) => `${t.name} ${t.count}`).join(" \u00B7 ");
42
+ console.log(` Tools ${toolSummary} (+${f.uniqueToolCount - Math.min(4, f.topTools.length)} more)`);
43
+ console.log(" " + "\u2500".repeat(40));
44
+ const hrs = result.features.totalHours >= 1000 ? (result.features.totalHours / 1000).toFixed(1) + "kh" : result.features.totalHours + "h";
45
+ console.log(` ${hrs} \u00B7 ${result.sessionCount} sessions \u00B7 ${result.projectCount} projects`);
46
+ if (result.phase === "early") {
47
+ console.log(` (early results \u2014 stabilizes at 10 sessions)`);
48
+ }
49
+ }
50
+ function printSetupChecklist(cl) {
51
+ const items = [
52
+ ["CLAUDE.md", cl.hasClaudeMd],
53
+ ["Hooks", cl.hasHooks],
54
+ ["Plugins", cl.hasPlugins],
55
+ ["MCP Servers", cl.hasMcpServers],
56
+ ["Memory", cl.hasMemory],
57
+ ["Rules", cl.hasRules],
58
+ ["Agents", cl.hasAgents],
59
+ ["Skills", cl.hasSkills],
60
+ ];
61
+ console.log(" Setup:");
62
+ for (const [label, ok] of items) {
63
+ console.log(` ${ok ? "\u2713" : "\u2717"} ${label}`);
64
+ }
65
+ }
66
+ //# sourceMappingURL=formatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../../src/cli/utils/formatting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type Locale } from "../../i18n/locales.js";
2
+ export declare function getConfigLocale(): Locale;
3
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/locale.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAElE,wBAAgB,eAAe,IAAI,MAAM,CAKxC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getConfigLocale = getConfigLocale;
4
+ const local_store_js_1 = require("../../store/local-store.js");
5
+ const locales_js_1 = require("../../i18n/locales.js");
6
+ function getConfigLocale() {
7
+ const config = (0, local_store_js_1.loadConfig)();
8
+ if (config.locale === "zh-CN")
9
+ return "zh-CN";
10
+ if (config.locale === "en")
11
+ return "en";
12
+ return (0, locales_js_1.detectLocale)();
13
+ }
14
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/cli/utils/locale.ts"],"names":[],"mappings":";;AAGA,0CAKC;AARD,+DAAwD;AACxD,sDAAkE;AAElE,SAAgB,eAAe;IAC7B,MAAM,MAAM,GAAG,IAAA,2BAAU,GAAE,CAAC;IAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,IAAA,yBAAY,GAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Check for updates and print a notice if a newer version is available.
3
+ * Non-blocking: fetches in background, resolves quickly from cache.
4
+ * Call after CLI output is complete.
5
+ */
6
+ export declare function checkForUpdates(currentVersion: string): Promise<void>;
7
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/update-check.ts"],"names":[],"mappings":"AAwFA;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B3E"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkForUpdates = checkForUpdates;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const node_os_1 = require("node:os");
7
+ const node_https_1 = require("node:https");
8
+ const queue_js_1 = require("../../store/queue.js");
9
+ const STORE_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".cc-proficiency");
10
+ const CACHE_FILE = (0, node_path_1.join)(STORE_DIR, "version-check.json");
11
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
12
+ const FETCH_TIMEOUT_MS = 3000; // 3 seconds
13
+ function loadCache() {
14
+ if (!(0, node_fs_1.existsSync)(CACHE_FILE))
15
+ return null;
16
+ try {
17
+ return JSON.parse((0, node_fs_1.readFileSync)(CACHE_FILE, "utf-8"));
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ function saveCache(cache) {
24
+ (0, queue_js_1.ensureStoreDir)();
25
+ try {
26
+ (0, node_fs_1.writeFileSync)(CACHE_FILE, JSON.stringify(cache), "utf-8");
27
+ }
28
+ catch {
29
+ // non-critical
30
+ }
31
+ }
32
+ function compareVersions(a, b) {
33
+ // Strip prerelease/build metadata, compare major.minor.patch only
34
+ const pa = a.split("-")[0].split(".").map(Number);
35
+ const pb = b.split("-")[0].split(".").map(Number);
36
+ for (let i = 0; i < 3; i++) {
37
+ const va = pa[i] ?? 0;
38
+ const vb = pb[i] ?? 0;
39
+ if (isNaN(va) || isNaN(vb))
40
+ return 0; // can't compare, skip
41
+ if (va !== vb)
42
+ return va - vb;
43
+ }
44
+ return 0;
45
+ }
46
+ function fetchLatestVersion() {
47
+ return new Promise((resolve) => {
48
+ let resolved = false;
49
+ const done = (val) => {
50
+ if (resolved)
51
+ return;
52
+ resolved = true;
53
+ clearTimeout(timer);
54
+ resolve(val);
55
+ };
56
+ const timer = setTimeout(() => {
57
+ req.destroy();
58
+ done(null);
59
+ }, FETCH_TIMEOUT_MS);
60
+ const req = (0, node_https_1.get)("https://registry.npmjs.org/cc-proficiency/latest", {
61
+ headers: { "Accept": "application/json" },
62
+ timeout: FETCH_TIMEOUT_MS,
63
+ }, (res) => {
64
+ if (res.statusCode !== 200) {
65
+ res.resume();
66
+ done(null);
67
+ return;
68
+ }
69
+ let data = "";
70
+ res.on("data", (chunk) => { data += chunk.toString(); });
71
+ res.on("end", () => {
72
+ try {
73
+ const pkg = JSON.parse(data);
74
+ done(typeof pkg.version === "string" ? pkg.version : null);
75
+ }
76
+ catch {
77
+ done(null);
78
+ }
79
+ });
80
+ });
81
+ req.on("error", () => done(null));
82
+ req.on("timeout", () => { req.destroy(); done(null); });
83
+ });
84
+ }
85
+ /**
86
+ * Check for updates and print a notice if a newer version is available.
87
+ * Non-blocking: fetches in background, resolves quickly from cache.
88
+ * Call after CLI output is complete.
89
+ */
90
+ async function checkForUpdates(currentVersion) {
91
+ // Skip in non-interactive contexts
92
+ if (process.env.CC_PROFICIENCY_NO_UPDATE_CHECK === "1")
93
+ return;
94
+ if (process.env.CI)
95
+ return;
96
+ if (!process.stdout.isTTY)
97
+ return;
98
+ const cache = loadCache();
99
+ // Use cache if fresh
100
+ if (cache) {
101
+ const age = Date.now() - new Date(cache.checkedAt).getTime();
102
+ if (age >= 0 && age < CHECK_INTERVAL_MS) {
103
+ if (compareVersions(cache.latestVersion, currentVersion) > 0) {
104
+ printNotice(currentVersion, cache.latestVersion);
105
+ }
106
+ return;
107
+ }
108
+ }
109
+ // Fetch in background — don't block
110
+ const latest = await fetchLatestVersion();
111
+ if (!latest)
112
+ return;
113
+ saveCache({ latestVersion: latest, checkedAt: new Date().toISOString() });
114
+ if (compareVersions(latest, currentVersion) > 0) {
115
+ printNotice(currentVersion, latest);
116
+ }
117
+ }
118
+ function printNotice(current, latest) {
119
+ console.log(`\n Update available: v${current} \u2192 v${latest}`);
120
+ console.log(" Run: npm update -g cc-proficiency\n");
121
+ }
122
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../../src/cli/utils/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { LeaderboardRegistry, PublicProfile } from "../types.js";
2
+ /**
3
+ * Read the leaderboard registry from the owner's public gist.
4
+ */
5
+ export declare function readRegistry(): LeaderboardRegistry | null;
6
+ /**
7
+ * Read a public profile from a user's public gist.
8
+ */
9
+ export declare function readPublicProfileFromGist(publicGistId: string): PublicProfile | null;
10
+ /**
11
+ * Open a GitHub Issue to join the leaderboard.
12
+ */
13
+ export declare function openJoinIssue(username: string, publicGistId: string): {
14
+ success: boolean;
15
+ issueUrl?: string;
16
+ error?: string;
17
+ };
18
+ /**
19
+ * Open a GitHub Issue to leave the leaderboard.
20
+ */
21
+ export declare function openLeaveIssue(username: string): {
22
+ success: boolean;
23
+ issueUrl?: string;
24
+ error?: string;
25
+ };
26
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/gist/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUtE;;GAEG;AACH,wBAAgB,YAAY,IAAI,mBAAmB,GAAG,IAAI,CAUzD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAIpF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,GACf;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAyBzD"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readRegistry = readRegistry;
4
+ exports.readPublicProfileFromGist = readPublicProfileFromGist;
5
+ exports.openJoinIssue = openJoinIssue;
6
+ exports.openLeaveIssue = openLeaveIssue;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const uploader_js_1 = require("./uploader.js");
9
+ const public_profile_js_1 = require("../store/public-profile.js");
10
+ // Must match vars.REGISTRY_GIST_ID in .github/workflows/leaderboard-registration.yml
11
+ const REGISTRY_GIST_ID = "ce1b434355768cfa36c68e5dbe5aa982";
12
+ const BOARD_REPO = "Z-M-Huang/cc-proficiency";
13
+ // Known limitation: public profiles are trust-based. A user could handcraft a gist
14
+ // with fake scores. Server-side verification or signed profiles would be needed to
15
+ // prevent this. Acceptable for v1 community leaderboard.
16
+ /**
17
+ * Read the leaderboard registry from the owner's public gist.
18
+ */
19
+ function readRegistry() {
20
+ const json = (0, uploader_js_1.readGistFile)(REGISTRY_GIST_ID, "cc-proficiency-registry.json");
21
+ if (!json)
22
+ return null;
23
+ try {
24
+ const data = JSON.parse(json);
25
+ if (data?.version !== "1.0.0" || !Array.isArray(data.entries))
26
+ return null;
27
+ return data;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Read a public profile from a user's public gist.
35
+ */
36
+ function readPublicProfileFromGist(publicGistId) {
37
+ const json = (0, uploader_js_1.readGistFile)(publicGistId, "cc-proficiency-public.json");
38
+ if (!json)
39
+ return null;
40
+ return (0, public_profile_js_1.parsePublicProfile)(json);
41
+ }
42
+ /**
43
+ * Open a GitHub Issue to join the leaderboard.
44
+ */
45
+ function openJoinIssue(username, publicGistId) {
46
+ try {
47
+ const title = `[leaderboard] join @${username}`;
48
+ const body = [
49
+ `**Username:** ${username}`,
50
+ `**Public Gist ID:** ${publicGistId}`,
51
+ "",
52
+ "This issue was automatically created by `cc-proficiency share`.",
53
+ "A GitHub Action will validate and add this entry to the leaderboard registry.",
54
+ ].join("\n");
55
+ const result = (0, node_child_process_1.execFileSync)("gh", [
56
+ "issue", "create",
57
+ "--repo", BOARD_REPO,
58
+ "--title", title,
59
+ "--body", body,
60
+ "--label", "leaderboard",
61
+ ], {
62
+ encoding: "utf-8",
63
+ stdio: ["pipe", "pipe", "pipe"],
64
+ timeout: 30_000,
65
+ });
66
+ return { success: true, issueUrl: result.trim() };
67
+ }
68
+ catch (err) {
69
+ return { success: false, error: String(err) };
70
+ }
71
+ }
72
+ /**
73
+ * Open a GitHub Issue to leave the leaderboard.
74
+ */
75
+ function openLeaveIssue(username) {
76
+ try {
77
+ const title = `[leaderboard] leave @${username}`;
78
+ const body = [
79
+ `**Username:** ${username}`,
80
+ "",
81
+ "This issue was automatically created by `cc-proficiency share --remove`.",
82
+ "A GitHub Action will remove this entry from the leaderboard registry.",
83
+ ].join("\n");
84
+ const result = (0, node_child_process_1.execFileSync)("gh", [
85
+ "issue", "create",
86
+ "--repo", BOARD_REPO,
87
+ "--title", title,
88
+ "--body", body,
89
+ "--label", "leaderboard",
90
+ ], {
91
+ encoding: "utf-8",
92
+ stdio: ["pipe", "pipe", "pipe"],
93
+ timeout: 30_000,
94
+ });
95
+ return { success: true, issueUrl: result.trim() };
96
+ }
97
+ catch (err) {
98
+ return { success: false, error: String(err) };
99
+ }
100
+ }
101
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/gist/registry.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,15 @@ export declare function findExistingGist(): string | null;
30
30
  /**
31
31
  * Push multiple files to a Gist atomically via gh api PATCH.
32
32
  */
33
- export declare function pushGistFiles(gistId: string, files: Record<string, string>): GistResult;
33
+ export declare function pushGistFiles(gistId: string, files: Record<string, string | null>): GistResult;
34
+ /**
35
+ * Create a new public Gist with a public profile JSON.
36
+ */
37
+ export declare function createPublicGist(content: string): GistResult;
38
+ /**
39
+ * Delete a Gist by ID.
40
+ */
41
+ export declare function deleteGist(gistId: string): GistResult;
34
42
  /**
35
43
  * Get the raw URL for a gist file.
36
44
  */