@hanfour.huang/caliber 0.1.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.
Files changed (55) hide show
  1. package/README.md +667 -0
  2. package/dist/analyzers/section.d.ts +9 -0
  3. package/dist/analyzers/section.d.ts.map +1 -0
  4. package/dist/analyzers/section.js +503 -0
  5. package/dist/analyzers/section.js.map +1 -0
  6. package/dist/analyzers/usage.d.ts +3 -0
  7. package/dist/analyzers/usage.d.ts.map +1 -0
  8. package/dist/analyzers/usage.js +141 -0
  9. package/dist/analyzers/usage.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +295 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config.d.ts +19 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +156 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/data-quality.d.ts +3 -0
  19. package/dist/data-quality.d.ts.map +1 -0
  20. package/dist/data-quality.js +54 -0
  21. package/dist/data-quality.js.map +1 -0
  22. package/dist/extractors/claude-code.d.ts +6 -0
  23. package/dist/extractors/claude-code.d.ts.map +1 -0
  24. package/dist/extractors/claude-code.js +216 -0
  25. package/dist/extractors/claude-code.js.map +1 -0
  26. package/dist/extractors/codex.d.ts +5 -0
  27. package/dist/extractors/codex.d.ts.map +1 -0
  28. package/dist/extractors/codex.js +184 -0
  29. package/dist/extractors/codex.js.map +1 -0
  30. package/dist/i18n.d.ts +53 -0
  31. package/dist/i18n.d.ts.map +1 -0
  32. package/dist/i18n.js +163 -0
  33. package/dist/i18n.js.map +1 -0
  34. package/dist/period.d.ts +5 -0
  35. package/dist/period.d.ts.map +1 -0
  36. package/dist/period.js +25 -0
  37. package/dist/period.js.map +1 -0
  38. package/dist/reporters/report.d.ts +7 -0
  39. package/dist/reporters/report.d.ts.map +1 -0
  40. package/dist/reporters/report.js +440 -0
  41. package/dist/reporters/report.js.map +1 -0
  42. package/dist/standard.d.ts +5 -0
  43. package/dist/standard.d.ts.map +1 -0
  44. package/dist/standard.js +98 -0
  45. package/dist/standard.js.map +1 -0
  46. package/dist/types.d.ts +216 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +3 -0
  49. package/dist/types.js.map +1 -0
  50. package/dist/utils.d.ts +3 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +17 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +59 -0
  55. package/templates/eval-standard.json +174 -0
@@ -0,0 +1,141 @@
1
+ import dayjs from "dayjs";
2
+ function allocateTokensByWeight(totalTokens, weights) {
3
+ if (totalTokens <= 0 || weights.length === 0) {
4
+ return weights.map(() => 0);
5
+ }
6
+ const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
7
+ const normalizedWeights = totalWeight > 0 ? weights : weights.map(() => 1);
8
+ const normalizedTotal = normalizedWeights.reduce((sum, weight) => sum + weight, 0);
9
+ const rawAllocations = normalizedWeights.map((weight) => (totalTokens * weight) / normalizedTotal);
10
+ const allocations = rawAllocations.map((value) => Math.floor(value));
11
+ let remaining = totalTokens - allocations.reduce((sum, value) => sum + value, 0);
12
+ const byFraction = rawAllocations
13
+ .map((value, idx) => ({ idx, fraction: value - Math.floor(value) }))
14
+ .sort((a, b) => b.fraction - a.fraction);
15
+ for (const item of byFraction) {
16
+ if (remaining <= 0)
17
+ break;
18
+ allocations[item.idx] += 1;
19
+ remaining -= 1;
20
+ }
21
+ return allocations;
22
+ }
23
+ export function analyzeUsage(claudeSessions, claudeCosts, codexSessions, since, until) {
24
+ // ── Claude Code aggregation ──
25
+ const ccActiveDays = new Set();
26
+ const ccModels = {};
27
+ const ccProjects = {};
28
+ const ccToolUsage = {};
29
+ const ccDailyActivity = {};
30
+ const claudeSessionTokens = new Map();
31
+ const costRowsBySession = new Map();
32
+ let ccTotalInput = 0;
33
+ let ccTotalOutput = 0;
34
+ let ccTotalDuration = 0;
35
+ for (const s of claudeSessions) {
36
+ const day = dayjs(s.startTime).format("YYYY-MM-DD");
37
+ ccActiveDays.add(day);
38
+ ccTotalInput += s.inputTokens;
39
+ ccTotalOutput += s.outputTokens;
40
+ ccTotalDuration += s.durationMinutes;
41
+ claudeSessionTokens.set(s.sessionId, s.inputTokens + s.outputTokens);
42
+ // Daily activity
43
+ const daily = ccDailyActivity[day] ?? { sessions: 0, tokens: 0 };
44
+ daily.sessions += 1;
45
+ daily.tokens += s.inputTokens + s.outputTokens;
46
+ ccDailyActivity[day] = daily;
47
+ // Project aggregation
48
+ const projName = s.projectPath.split("/").pop() ?? s.projectPath;
49
+ const proj = ccProjects[projName] ?? { sessions: 0, tokens: 0 };
50
+ proj.sessions += 1;
51
+ proj.tokens += s.inputTokens + s.outputTokens;
52
+ ccProjects[projName] = proj;
53
+ // Tool usage aggregation
54
+ for (const [tool, count] of Object.entries(s.toolCounts)) {
55
+ ccToolUsage[tool] = (ccToolUsage[tool] ?? 0) + count;
56
+ }
57
+ }
58
+ // Cost by model from SQLite
59
+ let ccTotalCost = 0;
60
+ const ccModelSessions = new Map();
61
+ for (const c of claudeCosts) {
62
+ ccTotalCost += c.totalCostUsd;
63
+ const model = ccModels[c.model] ?? { sessions: 0, tokens: 0, cost: 0 };
64
+ model.cost += c.totalCostUsd;
65
+ ccModels[c.model] = model;
66
+ const modelSessions = ccModelSessions.get(c.model) ?? new Set();
67
+ modelSessions.add(c.sessionId);
68
+ ccModelSessions.set(c.model, modelSessions);
69
+ const sessionRows = costRowsBySession.get(c.sessionId) ?? [];
70
+ sessionRows.push(c);
71
+ costRowsBySession.set(c.sessionId, sessionRows);
72
+ }
73
+ for (const [model, sessionIds] of ccModelSessions) {
74
+ const usage = ccModels[model];
75
+ usage.sessions = sessionIds.size;
76
+ }
77
+ // Estimate per-model tokens by session using cost share, then message count share as fallback.
78
+ for (const s of claudeSessions) {
79
+ const totalTokens = claudeSessionTokens.get(s.sessionId) ?? 0;
80
+ const sessionCosts = costRowsBySession.get(s.sessionId) ?? [];
81
+ if (sessionCosts.length === 0) {
82
+ const unknown = ccModels.unknown ?? { sessions: 0, tokens: 0, cost: 0 };
83
+ unknown.sessions += 1;
84
+ unknown.tokens += totalTokens;
85
+ ccModels.unknown = unknown;
86
+ continue;
87
+ }
88
+ const weights = sessionCosts.map((row) => row.totalCostUsd > 0 ? row.totalCostUsd : row.messageCount);
89
+ const allocatedTokens = allocateTokensByWeight(totalTokens, weights);
90
+ for (const [idx, row] of sessionCosts.entries()) {
91
+ const model = ccModels[row.model] ?? { sessions: 0, tokens: 0, cost: 0 };
92
+ model.tokens += allocatedTokens[idx];
93
+ ccModels[row.model] = model;
94
+ }
95
+ }
96
+ const topProjects = Object.entries(ccProjects)
97
+ .map(([path, data]) => ({ path, ...data }))
98
+ .sort((a, b) => b.tokens - a.tokens)
99
+ .slice(0, 10);
100
+ // ── Codex aggregation ──
101
+ const cxActiveDays = new Set();
102
+ const cxModels = {};
103
+ const cxDailyActivity = {};
104
+ let cxTotalTokens = 0;
105
+ for (const s of codexSessions) {
106
+ const day = dayjs.unix(s.createdAt).format("YYYY-MM-DD");
107
+ cxActiveDays.add(day);
108
+ cxTotalTokens += s.tokensUsed;
109
+ const model = cxModels[s.model] ?? { sessions: 0, tokens: 0 };
110
+ model.sessions += 1;
111
+ model.tokens += s.tokensUsed;
112
+ cxModels[s.model] = model;
113
+ const daily = cxDailyActivity[day] ?? { sessions: 0, tokens: 0 };
114
+ daily.sessions += 1;
115
+ daily.tokens += s.tokensUsed;
116
+ cxDailyActivity[day] = daily;
117
+ }
118
+ return {
119
+ claudeCode: {
120
+ totalSessions: claudeSessions.length,
121
+ totalInputTokens: ccTotalInput,
122
+ totalOutputTokens: ccTotalOutput,
123
+ totalCostUsd: ccTotalCost,
124
+ totalDurationMinutes: ccTotalDuration,
125
+ activeDays: ccActiveDays.size,
126
+ models: ccModels,
127
+ topProjects,
128
+ toolUsage: ccToolUsage,
129
+ dailyActivity: ccDailyActivity,
130
+ },
131
+ codex: {
132
+ totalSessions: codexSessions.length,
133
+ totalTokensUsed: cxTotalTokens,
134
+ models: cxModels,
135
+ activeDays: cxActiveDays.size,
136
+ dailyActivity: cxDailyActivity,
137
+ },
138
+ period: { since, until },
139
+ };
140
+ }
141
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/analyzers/usage.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import dayjs from "dayjs";
4
+ import { writeFileSync } from "fs";
5
+ import chalk, { Chalk } from "chalk";
6
+ import { extractSessions as extractClaudeSessions, extractFacets, extractCosts, scanConversationSignals, } from "./extractors/claude-code.js";
7
+ import { extractSessions as extractCodexSessions, extractSessionInsights as extractCodexSessionInsights, scanThreadSignals as scanCodexThreadSignals, } from "./extractors/codex.js";
8
+ import { analyzeUsage } from "./analyzers/usage.js";
9
+ import { analyzeSection } from "./analyzers/section.js";
10
+ import { getDefaultStandardTemplateText, loadStandard } from "./standard.js";
11
+ import { renderTextReport, renderJsonReport, renderMarkdownReport, renderHtmlReport, } from "./reporters/report.js";
12
+ import { checkDataQuality } from "./data-quality.js";
13
+ import { resolvePresetPeriod } from "./period.js";
14
+ import { loadConfig, saveConfig, setConfigValue, resetConfig, getConfigPath, getDefaultConfig, } from "./config.js";
15
+ import { localizeHeadline, localizeObservationTokens, localizeOverallAssessment, localizeRecommendations, localizeSectionScoreLine, t, } from "./i18n.js";
16
+ const program = new Command();
17
+ program
18
+ .name("caliber")
19
+ .description("AI Development Performance Evaluator\n" +
20
+ "Analyze Claude Code & Codex usage for technical performance review\n" +
21
+ "以技術績效審核者角色,分析 AI 工具使用狀況並產出評核報告")
22
+ .version("0.1.0");
23
+ // ── Config command ──
24
+ const configCmd = program
25
+ .command("config")
26
+ .description("View or modify settings / 檢視或修改設定");
27
+ configCmd
28
+ .command("show", { isDefault: true })
29
+ .description("Show current configuration / 顯示目前設定")
30
+ .action(() => {
31
+ const config = loadConfig();
32
+ const defaults = getDefaultConfig();
33
+ const dict = t(config.locale);
34
+ console.log("");
35
+ console.log(chalk.bold(dict.configTitle));
36
+ console.log(chalk.dim(`${dict.configFile}: ${getConfigPath()}`));
37
+ console.log("");
38
+ for (const [key, value] of Object.entries(config)) {
39
+ const isDefault = value === defaults[key];
40
+ const label = isDefault ? chalk.dim(dict.defaultLabel) : chalk.green(dict.customLabel);
41
+ console.log(` ${chalk.bold(key)}: ${value} ${label}`);
42
+ }
43
+ console.log("");
44
+ });
45
+ configCmd
46
+ .command("set <key> <value>")
47
+ .description("Set a config value / 設定值")
48
+ .action((key, value) => {
49
+ try {
50
+ const config = loadConfig();
51
+ const dict = t(config.locale);
52
+ const updated = setConfigValue(config, key, value);
53
+ saveConfig(updated);
54
+ console.log(chalk.green(`${dict.setOk} ${key} = ${value}`));
55
+ }
56
+ catch (err) {
57
+ console.error(chalk.red(err instanceof Error ? err.message : String(err)));
58
+ process.exitCode = 1;
59
+ }
60
+ });
61
+ configCmd
62
+ .command("reset")
63
+ .description("Reset all settings to defaults / 重設為預設值")
64
+ .action(() => {
65
+ const config = loadConfig();
66
+ const dict = t(config.locale);
67
+ resetConfig();
68
+ console.log(chalk.green(dict.configReset));
69
+ });
70
+ configCmd
71
+ .command("path")
72
+ .description("Show config file path / 顯示設定檔路徑")
73
+ .action(() => {
74
+ console.log(getConfigPath());
75
+ });
76
+ // ── Report command ──
77
+ program
78
+ .command("report")
79
+ .description("Generate evaluation report / 產出評核報告")
80
+ .option("-s, --since <date>", "Start date (YYYY-MM-DD)")
81
+ .option("-u, --until <date>", "End date (YYYY-MM-DD)")
82
+ .option("-f, --format <format>", "Output format: text, json, markdown, html")
83
+ .option("-o, --output <file>", "Write report to file")
84
+ .option("--standard <path>", "Path to custom evaluation standard JSON (default: built-in OneAD)")
85
+ .option("--engineer <name>", "Engineer name for report identification")
86
+ .option("--department <name>", "Department name for report identification")
87
+ .action((opts, cmd) => {
88
+ const config = loadConfig();
89
+ const resolved = resolveCliOpts(opts, cmd, config);
90
+ runReport(resolved, config);
91
+ });
92
+ // ── Monthly command ──
93
+ program
94
+ .command("monthly")
95
+ .description("Generate monthly KPI report / 產出月度 KPI 評核報告")
96
+ .option("-f, --format <format>", "Output format: text, json, markdown, html")
97
+ .option("-o, --output <file>", "Write report to file")
98
+ .option("--standard <path>", "Path to custom evaluation standard JSON (default: built-in OneAD)")
99
+ .option("--previous", "Use the previous full calendar month")
100
+ .action((opts, cmd) => {
101
+ const config = loadConfig();
102
+ const resolved = resolveCliOpts(opts, cmd, config);
103
+ runReport({
104
+ ...resolved,
105
+ ...resolvePresetPeriod("monthly", opts.previous ?? false),
106
+ }, config);
107
+ });
108
+ // ── Quarterly command ──
109
+ program
110
+ .command("quarterly")
111
+ .description("Generate quarterly KPI report / 產出季度 KPI 評核報告")
112
+ .option("-f, --format <format>", "Output format: text, json, markdown, html")
113
+ .option("-o, --output <file>", "Write report to file")
114
+ .option("--standard <path>", "Path to custom evaluation standard JSON (default: built-in OneAD)")
115
+ .option("--previous", "Use the previous full calendar quarter")
116
+ .action((opts, cmd) => {
117
+ const config = loadConfig();
118
+ const resolved = resolveCliOpts(opts, cmd, config);
119
+ runReport({
120
+ ...resolved,
121
+ ...resolvePresetPeriod("quarterly", opts.previous ?? false),
122
+ }, config);
123
+ });
124
+ // ── Summary command ──
125
+ program
126
+ .command("summary")
127
+ .description("Quick usage summary / 快速使用摘要")
128
+ .option("-s, --since <date>", "Start date (YYYY-MM-DD)")
129
+ .option("-u, --until <date>", "End date (YYYY-MM-DD)")
130
+ .action((opts) => {
131
+ const config = loadConfig();
132
+ const since = opts.since ?? dayjs().subtract(7, "day").format("YYYY-MM-DD");
133
+ const until = opts.until ?? dayjs().format("YYYY-MM-DD");
134
+ runSummary(since, until, config);
135
+ });
136
+ // ── Init-standard command ──
137
+ program
138
+ .command("init-standard")
139
+ .description("Export default evaluation standard as a starting template / 匯出預設評核標準範本")
140
+ .option("-o, --output <file>", "Output file path", "eval-standard.json")
141
+ .action((opts) => {
142
+ const config = loadConfig();
143
+ const dict = t(config.locale);
144
+ writeFileSync(opts.output, getDefaultStandardTemplateText(), "utf-8");
145
+ process.stderr.write(chalk.green(`${dict.defaultStandardExported} ${opts.output}`) + "\n");
146
+ process.stderr.write(chalk.dim(dict.defaultStandardHint) + "\n");
147
+ });
148
+ // Default: show help
149
+ program.action(() => {
150
+ program.help();
151
+ });
152
+ // ── CLI option resolution (config defaults + CLI overrides) ──
153
+ function resolveCliOpts(opts, cmd, config) {
154
+ const isFromCli = (name) => cmd.getOptionValueSource(name) === "cli";
155
+ return {
156
+ ...opts,
157
+ since: isFromCli("since")
158
+ ? opts.since
159
+ : (opts.since ??
160
+ dayjs().subtract(config.defaultPeriodDays, "day").format("YYYY-MM-DD")),
161
+ until: isFromCli("until")
162
+ ? opts.until
163
+ : (opts.until ?? dayjs().format("YYYY-MM-DD")),
164
+ format: isFromCli("format")
165
+ ? opts.format
166
+ : (opts.format ?? config.defaultFormat),
167
+ };
168
+ }
169
+ // ── Report runner ──
170
+ function runReport(opts, config) {
171
+ const { since = dayjs()
172
+ .subtract(config.defaultPeriodDays, "day")
173
+ .format("YYYY-MM-DD"), until = dayjs().format("YYYY-MM-DD"), format = config.defaultFormat, output, standard: standardPath, } = opts;
174
+ const useColor = config.theme !== "no-color";
175
+ const c = useColor ? chalk : new Chalk({ level: 0 });
176
+ const dict = t(config.locale);
177
+ const log = (msg) => process.stderr.write(msg + "\n");
178
+ // Load standard
179
+ const standard = loadStandard(standardPath);
180
+ if (standardPath) {
181
+ log(c.dim(`\nUsing custom standard: ${standardPath}`));
182
+ }
183
+ log(c.dim(`${dict.standardLabel}: ${standard.name}`));
184
+ log(c.dim(`${dict.extractingLabel} ${since} to ${until}...\n`));
185
+ // ── Extract ──
186
+ const claudeSessions = extractClaudeSessions(since, until, config.claudeDir);
187
+ const codexSessions = extractCodexSessions(since, until, config.codexDir);
188
+ const sessionIds = new Set(claudeSessions.map((s) => s.sessionId));
189
+ const facets = extractFacets(sessionIds, config.claudeDir);
190
+ const costs = extractCosts(since, until, config.claudeDir);
191
+ const conversationSignals = scanConversationSignals(sessionIds, standard, 50, config.claudeDir);
192
+ const codexInsights = extractCodexSessionInsights(codexSessions, config.codexDir);
193
+ const codexSignals = scanCodexThreadSignals(codexSessions, codexInsights, standard);
194
+ log(c.dim(` Claude Code: ${claudeSessions.length} sessions, ${facets.size} facets, ${conversationSignals.length} signals`));
195
+ log(c.dim(` Codex: ${codexSessions.length} sessions, ${codexSignals.length} signals`));
196
+ // ── Analyze ──
197
+ const usage = analyzeUsage(claudeSessions, costs, codexSessions, since, until);
198
+ const sections = standard.sections.map((sec) => analyzeSection(sec, claudeSessions, facets, conversationSignals, codexSessions, codexInsights, codexSignals));
199
+ // ── Data quality ──
200
+ const dataWarnings = checkDataQuality(claudeSessions.length, codexSessions.length, facets.size, conversationSignals.length, config.claudeDir, config.codexDir);
201
+ if (dataWarnings.length > 0) {
202
+ log(c.yellow(` ${dict.dataWarningsCount}: ${dataWarnings.length}`));
203
+ }
204
+ // ── Report ──
205
+ const meta = opts.engineer || opts.department
206
+ ? { engineer: opts.engineer, department: opts.department }
207
+ : undefined;
208
+ const report = {
209
+ generatedAt: dayjs().format("YYYY-MM-DD HH:mm:ss"),
210
+ period: { since, until },
211
+ standardName: standard.name,
212
+ locale: config.locale,
213
+ meta,
214
+ usage,
215
+ sections,
216
+ dataWarnings,
217
+ managementSummary: buildManagementSummary(config.locale, sections, usage, since, until),
218
+ };
219
+ let rendered;
220
+ switch (format) {
221
+ case "json":
222
+ rendered = renderJsonReport(report);
223
+ break;
224
+ case "markdown":
225
+ rendered = renderMarkdownReport(report, config.locale);
226
+ break;
227
+ case "html":
228
+ rendered = renderHtmlReport(report, config.locale);
229
+ break;
230
+ default:
231
+ rendered = renderTextReport(report, config.locale);
232
+ break;
233
+ }
234
+ if (output) {
235
+ writeFileSync(output, rendered, "utf-8");
236
+ log(c.green(`\n${dict.reportWritten} ${output}`));
237
+ }
238
+ else {
239
+ process.stdout.write(rendered + "\n");
240
+ }
241
+ }
242
+ function buildManagementSummary(locale, sections, usage, since, until) {
243
+ const superiorCount = sections.filter((section) => section.score > 100).length;
244
+ const headline = localizeHeadline(locale, superiorCount, sections.length);
245
+ const overallAssessment = localizeOverallAssessment(locale, since, until, usage, superiorCount, sections.length);
246
+ const observations = [
247
+ ...localizeObservationTokens(locale, usage),
248
+ ...sections.map((section) => localizeSectionScoreLine(locale, section)),
249
+ ];
250
+ const recommendations = localizeRecommendations(locale, sections);
251
+ return {
252
+ headline,
253
+ overallAssessment,
254
+ observations,
255
+ recommendations,
256
+ };
257
+ }
258
+ function runSummary(since, until, config) {
259
+ const claudeSessions = extractClaudeSessions(since, until, config.claudeDir);
260
+ const codexSessions = extractCodexSessions(since, until, config.codexDir);
261
+ console.log("");
262
+ console.log(chalk.bold("AI Dev Usage Summary"));
263
+ console.log(chalk.dim(`Period: ${since} ~ ${until}`));
264
+ console.log("");
265
+ console.log(chalk.bold.blue("Claude Code"));
266
+ if (claudeSessions.length === 0) {
267
+ console.log(chalk.dim(" No sessions found."));
268
+ }
269
+ else {
270
+ const totalTokens = claudeSessions.reduce((sum, s) => sum + s.inputTokens + s.outputTokens, 0);
271
+ const totalDuration = claudeSessions.reduce((sum, s) => sum + s.durationMinutes, 0);
272
+ const days = new Set(claudeSessions.map((s) => dayjs(s.startTime).format("YYYY-MM-DD")));
273
+ console.log(` Sessions: ${claudeSessions.length}`);
274
+ console.log(` Tokens: ${totalTokens.toLocaleString("en-US")}`);
275
+ console.log(` Duration: ${totalDuration} min`);
276
+ console.log(` Active Days: ${days.size}`);
277
+ }
278
+ console.log("");
279
+ console.log(chalk.bold.green("Codex"));
280
+ if (codexSessions.length === 0) {
281
+ console.log(chalk.dim(" No sessions found."));
282
+ }
283
+ else {
284
+ const totalTokens = codexSessions.reduce((sum, s) => sum + s.tokensUsed, 0);
285
+ const days = new Set(codexSessions.map((s) => dayjs.unix(s.createdAt).format("YYYY-MM-DD")));
286
+ console.log(` Sessions: ${codexSessions.length}`);
287
+ console.log(` Tokens: ${totalTokens.toLocaleString("en-US")}`);
288
+ console.log(` Active Days: ${days.size}`);
289
+ }
290
+ console.log("");
291
+ console.log(chalk.dim("Run `caliber report` for full evaluation report."));
292
+ console.log("");
293
+ }
294
+ program.parse();
295
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export type Locale = "en" | "zh-TW";
2
+ export type Theme = "default" | "minimal" | "no-color";
3
+ export type OutputFormat = "text" | "json" | "markdown" | "html";
4
+ export interface AppConfig {
5
+ readonly locale: Locale;
6
+ readonly theme: Theme;
7
+ readonly defaultFormat: OutputFormat;
8
+ readonly defaultPeriodDays: number;
9
+ readonly claudeDir: string;
10
+ readonly codexDir: string;
11
+ }
12
+ export declare function getDefaultConfig(): AppConfig;
13
+ export declare function getConfigPath(): string;
14
+ export declare function getLegacyConfigPath(): string;
15
+ export declare function loadConfig(): AppConfig;
16
+ export declare function saveConfig(config: AppConfig): void;
17
+ export declare function setConfigValue(config: AppConfig, key: string, value: string): AppConfig;
18
+ export declare function resetConfig(): AppConfig;
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;AACpC,MAAM,MAAM,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAiBD,wBAAgB,gBAAgB,IAAI,SAAS,CAE5C;AAID,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AA+GD,wBAAgB,UAAU,IAAI,SAAS,CAoBtC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAUlD;AAID,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,SAAS,CAIX;AAED,wBAAgB,WAAW,IAAI,SAAS,CAUvC"}
package/dist/config.js ADDED
@@ -0,0 +1,156 @@
1
+ import { readFileSync, writeFileSync, unlinkSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ // ── Defaults ──
5
+ const LOCALES = new Set(["en", "zh-TW"]);
6
+ const THEMES = new Set(["default", "minimal", "no-color"]);
7
+ const FORMATS = new Set(["text", "json", "markdown", "html"]);
8
+ const DEFAULT_CONFIG = Object.freeze({
9
+ locale: "en",
10
+ theme: "default",
11
+ defaultFormat: "text",
12
+ defaultPeriodDays: 30,
13
+ claudeDir: join(homedir(), ".claude"),
14
+ codexDir: join(homedir(), ".codex"),
15
+ });
16
+ export function getDefaultConfig() {
17
+ return { ...DEFAULT_CONFIG };
18
+ }
19
+ // ── Path ──
20
+ export function getConfigPath() {
21
+ return join(homedir(), ".caliber.json");
22
+ }
23
+ export function getLegacyConfigPath() {
24
+ return join(homedir(), ".aide.json");
25
+ }
26
+ // ── Validation ──
27
+ const VALID_KEYS = new Set(Object.keys(DEFAULT_CONFIG));
28
+ function validateKey(key) {
29
+ if (!VALID_KEYS.has(key)) {
30
+ throw new Error(`Unknown config key: '${key}'. Valid keys: ${[...VALID_KEYS].join(", ")}`);
31
+ }
32
+ }
33
+ function validateValue(key, value) {
34
+ switch (key) {
35
+ case "locale":
36
+ if (!LOCALES.has(value)) {
37
+ throw new Error(`Invalid locale: '${value}'. Must be one of: ${[...LOCALES].join(", ")}`);
38
+ }
39
+ return value;
40
+ case "theme":
41
+ if (!THEMES.has(value)) {
42
+ throw new Error(`Invalid theme: '${value}'. Must be one of: ${[...THEMES].join(", ")}`);
43
+ }
44
+ return value;
45
+ case "defaultFormat":
46
+ if (!FORMATS.has(value)) {
47
+ throw new Error(`Invalid defaultFormat: '${value}'. Must be one of: ${[...FORMATS].join(", ")}`);
48
+ }
49
+ return value;
50
+ case "defaultPeriodDays": {
51
+ const num = parseInt(value, 10);
52
+ if (isNaN(num) || num <= 0) {
53
+ throw new Error(`Invalid defaultPeriodDays: '${value}'. Must be a positive integer.`);
54
+ }
55
+ return num;
56
+ }
57
+ case "claudeDir":
58
+ case "codexDir":
59
+ if (!value.trim()) {
60
+ throw new Error(`Invalid ${key}: path must not be empty.`);
61
+ }
62
+ return value;
63
+ }
64
+ }
65
+ // ── Load / Save ──
66
+ function isValidValue(key, value) {
67
+ if (value === undefined || value === null)
68
+ return false;
69
+ try {
70
+ const strValue = key === "defaultPeriodDays" ? String(value) : String(value);
71
+ validateValue(key, strValue);
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ function readConfigFile(configPath) {
79
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
80
+ const validated = {};
81
+ for (const [key, value] of Object.entries(raw)) {
82
+ if (!VALID_KEYS.has(key)) {
83
+ process.stderr.write(`[caliber] config warning: ignoring unknown key '${key}'\n`);
84
+ continue;
85
+ }
86
+ const typedKey = key;
87
+ if (isValidValue(typedKey, value)) {
88
+ validated[key] = value;
89
+ }
90
+ else {
91
+ process.stderr.write(`[caliber] config warning: invalid value for '${key}': ${JSON.stringify(value)}, using default\n`);
92
+ }
93
+ }
94
+ return { ...DEFAULT_CONFIG, ...validated };
95
+ }
96
+ function migrateLegacyConfig(legacyPath, configPath) {
97
+ const config = readConfigFile(legacyPath);
98
+ try {
99
+ saveConfig(config);
100
+ process.stderr.write(`[caliber] config notice: migrated legacy config from ${legacyPath} to ${configPath}\n`);
101
+ }
102
+ catch (err) {
103
+ process.stderr.write(`[caliber] config warning: loaded legacy config from ${legacyPath} but could not write ${configPath}: ${err instanceof Error ? err.message : String(err)}\n`);
104
+ }
105
+ return config;
106
+ }
107
+ export function loadConfig() {
108
+ const configPath = getConfigPath();
109
+ if (existsSync(configPath)) {
110
+ try {
111
+ return readConfigFile(configPath);
112
+ }
113
+ catch {
114
+ return getDefaultConfig();
115
+ }
116
+ }
117
+ const legacyPath = getLegacyConfigPath();
118
+ if (existsSync(legacyPath)) {
119
+ try {
120
+ return migrateLegacyConfig(legacyPath, configPath);
121
+ }
122
+ catch {
123
+ return getDefaultConfig();
124
+ }
125
+ }
126
+ return getDefaultConfig();
127
+ }
128
+ export function saveConfig(config) {
129
+ const configPath = getConfigPath();
130
+ // Only persist values that differ from defaults
131
+ const partial = {};
132
+ for (const key of Object.keys(DEFAULT_CONFIG)) {
133
+ if (config[key] !== DEFAULT_CONFIG[key]) {
134
+ partial[key] = config[key];
135
+ }
136
+ }
137
+ writeFileSync(configPath, JSON.stringify(partial, null, 2) + "\n", "utf-8");
138
+ }
139
+ // ── Mutators (immutable) ──
140
+ export function setConfigValue(config, key, value) {
141
+ validateKey(key);
142
+ const validated = validateValue(key, value);
143
+ return { ...config, [key]: validated };
144
+ }
145
+ export function resetConfig() {
146
+ const configPath = getConfigPath();
147
+ if (existsSync(configPath)) {
148
+ unlinkSync(configPath);
149
+ }
150
+ const legacyPath = getLegacyConfigPath();
151
+ if (existsSync(legacyPath)) {
152
+ unlinkSync(legacyPath);
153
+ }
154
+ return getDefaultConfig();
155
+ }
156
+ //# sourceMappingURL=config.js.map