@rosh100yx/outlier 0.4.23 → 0.4.24
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/bin/outlier.js +49 -45
- package/package.json +1 -1
- package/src/carbon.ts +25 -8
- package/src/cli.ts +34 -36
package/bin/outlier.js
CHANGED
|
@@ -165,7 +165,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
165
165
|
var require_package = __commonJS((exports, module) => {
|
|
166
166
|
module.exports = {
|
|
167
167
|
name: "@rosh100yx/outlier",
|
|
168
|
-
version: "0.4.
|
|
168
|
+
version: "0.4.24",
|
|
169
169
|
description: "AI Code Governance & Capability Auditing for the Terminal. Measures AI reliance, context waste, and enforces local CI/CD policies.",
|
|
170
170
|
bin: {
|
|
171
171
|
outlier: "bin/outlier.js"
|
|
@@ -1821,12 +1821,12 @@ class ClaudeLogParser {
|
|
|
1821
1821
|
try {
|
|
1822
1822
|
await access(logPath);
|
|
1823
1823
|
} catch {
|
|
1824
|
-
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
1824
|
+
return { total: 0, output: 0, cache: 0, sessions: 0, cost: 0 };
|
|
1825
1825
|
}
|
|
1826
1826
|
const text2 = await readFile(logPath, "utf-8");
|
|
1827
1827
|
const lines = text2.trim().split(`
|
|
1828
1828
|
`).filter((l2) => l2.length > 0);
|
|
1829
|
-
let total = 0, output = 0, cache = 0;
|
|
1829
|
+
let total = 0, output = 0, cache = 0, cost = 0;
|
|
1830
1830
|
const sessions = new Set;
|
|
1831
1831
|
for (const line of lines) {
|
|
1832
1832
|
try {
|
|
@@ -1834,19 +1834,24 @@ class ClaudeLogParser {
|
|
|
1834
1834
|
total += data.total_tokens || 0;
|
|
1835
1835
|
output += data.output_tokens || 0;
|
|
1836
1836
|
cache += data.cache_read || 0;
|
|
1837
|
+
cost += data.cost_usd || 0;
|
|
1837
1838
|
if (data.session_id)
|
|
1838
1839
|
sessions.add(data.session_id);
|
|
1839
1840
|
} catch (e) {}
|
|
1840
1841
|
}
|
|
1841
|
-
return { total, output, cache, sessions: sessions.size };
|
|
1842
|
+
return { total, output, cache, sessions: sessions.size, cost };
|
|
1842
1843
|
}
|
|
1843
1844
|
}
|
|
1844
1845
|
|
|
1845
1846
|
class CursorLogParser {
|
|
1846
1847
|
async parse() {
|
|
1847
|
-
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
1848
|
+
return { total: 0, output: 0, cache: 0, sessions: 0, cost: 0 };
|
|
1848
1849
|
}
|
|
1849
1850
|
}
|
|
1851
|
+
function estimateUsd(output, cacheRead, total) {
|
|
1852
|
+
const otherInput = Math.max(0, total - output - cacheRead);
|
|
1853
|
+
return output / 1e6 * 9 + cacheRead / 1e6 * 0.3 + otherInput / 1e6 * 3;
|
|
1854
|
+
}
|
|
1850
1855
|
function getLocalGridFactor() {
|
|
1851
1856
|
try {
|
|
1852
1857
|
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
@@ -1865,16 +1870,19 @@ function getLocalGridFactor() {
|
|
|
1865
1870
|
}
|
|
1866
1871
|
async function getCarbonStats() {
|
|
1867
1872
|
const parsers = [new ClaudeLogParser, new CursorLogParser];
|
|
1868
|
-
let totalTokens = 0, outputTokens = 0, cacheReadTokens = 0, sessions = 0;
|
|
1873
|
+
let totalTokens = 0, outputTokens = 0, cacheReadTokens = 0, sessions = 0, loggedCost = 0;
|
|
1869
1874
|
for (const parser of parsers) {
|
|
1870
1875
|
const stats = await parser.parse();
|
|
1871
1876
|
totalTokens += stats.total;
|
|
1872
1877
|
outputTokens += stats.output;
|
|
1873
1878
|
cacheReadTokens += stats.cache;
|
|
1874
1879
|
sessions += stats.sessions;
|
|
1880
|
+
loggedCost += stats.cost;
|
|
1875
1881
|
}
|
|
1876
1882
|
const energyKwh = outputTokens / 1e6 * 0.662;
|
|
1877
1883
|
const localGrid = getLocalGridFactor();
|
|
1884
|
+
const costIsReal = loggedCost > 0;
|
|
1885
|
+
const estUsd = costIsReal ? loggedCost : estimateUsd(outputTokens, cacheReadTokens, totalTokens);
|
|
1878
1886
|
return {
|
|
1879
1887
|
totalTokens,
|
|
1880
1888
|
outputTokens,
|
|
@@ -1884,7 +1892,9 @@ async function getCarbonStats() {
|
|
|
1884
1892
|
co2KgFrance: energyKwh * grid_factors_default.france / 1000,
|
|
1885
1893
|
localCo2Kg: energyKwh * localGrid.factor / 1000,
|
|
1886
1894
|
localRegion: localGrid.region,
|
|
1887
|
-
sessions
|
|
1895
|
+
sessions,
|
|
1896
|
+
estUsd,
|
|
1897
|
+
costIsReal
|
|
1888
1898
|
};
|
|
1889
1899
|
}
|
|
1890
1900
|
|
|
@@ -2244,23 +2254,22 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
|
|
|
2244
2254
|
regionStr = carbon.localRegion;
|
|
2245
2255
|
}
|
|
2246
2256
|
const isDanger = gitStats && gitStats.ratio > 0.7;
|
|
2247
|
-
const verdictZone = isDanger ? import_picocolors.default.red("
|
|
2248
|
-
const verdictText = isDanger ? `
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
Your human judgement remains the primary driver
|
|
2252
|
-
of logic in this system.`;
|
|
2257
|
+
const verdictZone = isDanger ? import_picocolors.default.red("Mostly AI") : import_picocolors.default.green("You're driving");
|
|
2258
|
+
const verdictText = isDanger ? `AI wrote most of this. Read it through so you can
|
|
2259
|
+
still debug it yourself when the agent isn't around.` : `You're still writing the core of this. Good —
|
|
2260
|
+
that's how you keep the skill.`;
|
|
2253
2261
|
const isInefficient = parseFloat(cachePct) > 40;
|
|
2254
|
-
const cacheVerdict = isInefficient ? import_picocolors.default.yellow("
|
|
2255
|
-
const cacheText = isInefficient ? `
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
const policyStatus = ruleFailures > 0 ? import_picocolors.default.red("
|
|
2259
|
-
const policyAction = ruleFailures > 0 ? "
|
|
2262
|
+
const cacheVerdict = isInefficient ? import_picocolors.default.yellow("Lots of re-reads") : import_picocolors.default.green("Lean");
|
|
2263
|
+
const cacheText = isInefficient ? `Most of your tokens just re-send old context.
|
|
2264
|
+
It's normal for agents, but it's most of the bill.` : `Little wasted context. Your spend is mostly
|
|
2265
|
+
real work.`;
|
|
2266
|
+
const policyStatus = ruleFailures > 0 ? import_picocolors.default.red("Over your limit") : import_picocolors.default.green("Within limit");
|
|
2267
|
+
const policyAction = ruleFailures > 0 ? "Heads up only — nothing was blocked." : "Nothing to do.";
|
|
2260
2268
|
const fmtTokens = (n2) => n2 >= 1e9 ? (n2 / 1e9).toFixed(1) + "B" : n2 >= 1e6 ? (n2 / 1e6).toFixed(1) + "M" : n2 >= 1000 ? (n2 / 1000).toFixed(1) + "k" : String(n2);
|
|
2261
2269
|
const totalTokensStr = carbon ? fmtTokens(carbon.totalTokens) : "0";
|
|
2262
|
-
const
|
|
2263
|
-
const
|
|
2270
|
+
const estUsdStr = carbon ? "$" + carbon.estUsd.toFixed(2) + (carbon.costIsReal ? "" : import_picocolors.default.dim(" (rough)")) : import_picocolors.default.dim("n/a");
|
|
2271
|
+
const humanSov = gitStats ? ((1 - gitStats.ratio) * 100).toFixed(0) + "%" : "100%";
|
|
2272
|
+
const authorshipStr = import_picocolors.default.bold(authPct) + (isDanger ? import_picocolors.default.red(" AI-written") : import_picocolors.default.green(" AI-written"));
|
|
2264
2273
|
const getProgressBar = (pct, length = 10) => {
|
|
2265
2274
|
const filled = Math.max(0, Math.min(length, Math.round(pct / 100 * length)));
|
|
2266
2275
|
return "▰".repeat(filled) + "▱".repeat(length - filled);
|
|
@@ -2275,38 +2284,33 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
|
|
|
2275
2284
|
const repoName = process.cwd().split("/").pop() || "Unknown";
|
|
2276
2285
|
finalReceipt = `
|
|
2277
2286
|
${import_picocolors.default.dim("┌────────────────────────────────────────────────────────")}
|
|
2278
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█")} ${import_picocolors.default.bold("::
|
|
2279
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄")} ${import_picocolors.default.dim(`::
|
|
2287
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█")} ${import_picocolors.default.bold(":: CODE AUDIT")}
|
|
2288
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄")} ${import_picocolors.default.dim(`:: ${repoName} · ${dateStr}`)}
|
|
2280
2289
|
${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
|
|
2281
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgBlue("
|
|
2282
|
-
${import_picocolors.default.dim("│")} AI
|
|
2283
|
-
${import_picocolors.default.dim("│")}
|
|
2290
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgBlue(" WHO WROTE THE CODE "))}
|
|
2291
|
+
${import_picocolors.default.dim("│")} AI ${aiBar} ${authorshipStr}
|
|
2292
|
+
${import_picocolors.default.dim("│")} You ${humanBar} ${import_picocolors.default.bold(humanSov)}
|
|
2284
2293
|
${import_picocolors.default.dim("│")}
|
|
2285
|
-
${import_picocolors.default.dim("│")}
|
|
2286
|
-
${import_picocolors.default.dim("│")} ${verdictText.split(`
|
|
2294
|
+
${import_picocolors.default.dim("│")} ${verdictZone} — ${verdictText.split(`
|
|
2287
2295
|
`).join(`
|
|
2288
|
-
` + import_picocolors.default.dim("│") + "
|
|
2296
|
+
` + import_picocolors.default.dim("│") + " ")}
|
|
2289
2297
|
${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
|
|
2290
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgMagenta("
|
|
2291
|
-
${import_picocolors.default.dim("│")} Tokens
|
|
2292
|
-
${import_picocolors.default.dim("│")}
|
|
2293
|
-
${import_picocolors.default.dim("│")}
|
|
2298
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgMagenta(" WHAT IT COST "))}
|
|
2299
|
+
${import_picocolors.default.dim("│")} Tokens used ${import_picocolors.default.bold(totalTokensStr)}
|
|
2300
|
+
${import_picocolors.default.dim("│")} Est. spend ${import_picocolors.default.bold(estUsdStr)}
|
|
2301
|
+
${import_picocolors.default.dim("│")} Re-used context ${cacheBar} ${import_picocolors.default.bold(cachePct + "%")}
|
|
2302
|
+
${import_picocolors.default.dim("│")} Energy ${import_picocolors.default.bold(co2Str)} ${import_picocolors.default.dim(`(${regionStr} grid, rough)`)}
|
|
2294
2303
|
${import_picocolors.default.dim("│")}
|
|
2295
|
-
${import_picocolors.default.dim("│")}
|
|
2296
|
-
${import_picocolors.default.dim("│")} ${cacheText.split(`
|
|
2304
|
+
${import_picocolors.default.dim("│")} ${cacheVerdict} — ${cacheText.split(`
|
|
2297
2305
|
`).join(`
|
|
2298
|
-
` + import_picocolors.default.dim("│") + "
|
|
2306
|
+
` + import_picocolors.default.dim("│") + " ")}
|
|
2299
2307
|
${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
|
|
2300
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgYellow(import_picocolors.default.black("
|
|
2301
|
-
${import_picocolors.default.dim("│")}
|
|
2302
|
-
${import_picocolors.default.dim("│")}
|
|
2308
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgYellow(import_picocolors.default.black(" YOUR LIMIT ")))}
|
|
2309
|
+
${import_picocolors.default.dim("│")} AI cap ${import_picocolors.default.bold("70%")} ${import_picocolors.default.dim("· change with: outlier policy")}
|
|
2310
|
+
${import_picocolors.default.dim("│")} Status ${policyStatus} ${import_picocolors.default.dim("·")} ${policyAction}
|
|
2303
2311
|
${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
|
|
2304
|
-
${import_picocolors.default.dim("│")}
|
|
2305
|
-
${import_picocolors.default.dim("│")}
|
|
2306
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.italic(import_picocolors.default.dim("code becomes commoditized by algorithms."))}
|
|
2307
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.italic(import_picocolors.default.dim("human mastery is the only true moat."))}
|
|
2308
|
-
${import_picocolors.default.dim("│")}
|
|
2309
|
-
${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.cyan("***STAY VIGILANT***"))}
|
|
2312
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.dim(import_picocolors.default.italic("Run this before you start. Keep the skill while you"))}
|
|
2313
|
+
${import_picocolors.default.dim("│")} ${import_picocolors.default.dim(import_picocolors.default.italic("use the speed."))}
|
|
2310
2314
|
${import_picocolors.default.dim("└────────────────────────────────────────────────────────")}`;
|
|
2311
2315
|
} else {
|
|
2312
2316
|
note(`status: ${authPct} AI Reliance | ${cachePct}% Cache Bloat | ${co2Str}`, `${import_picocolors.default.bold("[outlier]")} CI/CD Audit`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rosh100yx/outlier",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.24",
|
|
4
4
|
"description": "AI Code Governance & Capability Auditing for the Terminal. Measures AI reliance, context waste, and enforces local CI/CD policies.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"outlier": "bin/outlier.js"
|
package/src/carbon.ts
CHANGED
|
@@ -13,10 +13,12 @@ export interface CarbonStats {
|
|
|
13
13
|
localCo2Kg: number;
|
|
14
14
|
localRegion: string;
|
|
15
15
|
sessions: number;
|
|
16
|
+
estUsd: number; // estimated spend in USD
|
|
17
|
+
costIsReal: boolean; // true if summed from the log's own cost field, false if estimated from tokens
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface TokenLogParser {
|
|
19
|
-
parse(): Promise<{ total: number, output: number, cache: number, sessions: number }>;
|
|
21
|
+
parse(): Promise<{ total: number, output: number, cache: number, sessions: number, cost: number }>;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export class ClaudeLogParser implements TokenLogParser {
|
|
@@ -30,13 +32,13 @@ export class ClaudeLogParser implements TokenLogParser {
|
|
|
30
32
|
try {
|
|
31
33
|
await access(logPath);
|
|
32
34
|
} catch {
|
|
33
|
-
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
35
|
+
return { total: 0, output: 0, cache: 0, sessions: 0, cost: 0 };
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const text = await readFile(logPath, 'utf-8');
|
|
37
39
|
const lines = text.trim().split('\n').filter(l => l.length > 0);
|
|
38
|
-
|
|
39
|
-
let total = 0, output = 0, cache = 0;
|
|
40
|
+
|
|
41
|
+
let total = 0, output = 0, cache = 0, cost = 0;
|
|
40
42
|
const sessions = new Set<string>();
|
|
41
43
|
|
|
42
44
|
for (const line of lines) {
|
|
@@ -45,19 +47,27 @@ export class ClaudeLogParser implements TokenLogParser {
|
|
|
45
47
|
total += data.total_tokens || 0;
|
|
46
48
|
output += data.output_tokens || 0;
|
|
47
49
|
cache += data.cache_read || 0;
|
|
50
|
+
cost += data.cost_usd || 0; // present when the log was written with a cost field
|
|
48
51
|
if (data.session_id) sessions.add(data.session_id);
|
|
49
52
|
} catch (e) {}
|
|
50
53
|
}
|
|
51
|
-
return { total, output, cache, sessions: sessions.size };
|
|
54
|
+
return { total, output, cache, sessions: sessions.size, cost };
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
class CursorLogParser implements TokenLogParser {
|
|
56
59
|
async parse() {
|
|
57
|
-
return { total: 0, output: 0, cache: 0, sessions: 0 };
|
|
60
|
+
return { total: 0, output: 0, cache: 0, sessions: 0, cost: 0 };
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
// Rough blended token pricing (USD per 1M tokens) for when the log has no cost field.
|
|
65
|
+
// Conservative mid-points across current models; labeled "rough" in the UI.
|
|
66
|
+
function estimateUsd(output: number, cacheRead: number, total: number): number {
|
|
67
|
+
const otherInput = Math.max(0, total - output - cacheRead);
|
|
68
|
+
return (output / 1e6) * 9 + (cacheRead / 1e6) * 0.3 + (otherInput / 1e6) * 3;
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
function getLocalGridFactor(): { region: string, factor: number } {
|
|
62
72
|
try {
|
|
63
73
|
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
@@ -73,7 +83,7 @@ function getLocalGridFactor(): { region: string, factor: number } {
|
|
|
73
83
|
export async function getCarbonStats(): Promise<CarbonStats> {
|
|
74
84
|
const parsers: TokenLogParser[] = [new ClaudeLogParser(), new CursorLogParser()];
|
|
75
85
|
|
|
76
|
-
let totalTokens = 0, outputTokens = 0, cacheReadTokens = 0, sessions = 0;
|
|
86
|
+
let totalTokens = 0, outputTokens = 0, cacheReadTokens = 0, sessions = 0, loggedCost = 0;
|
|
77
87
|
|
|
78
88
|
for (const parser of parsers) {
|
|
79
89
|
const stats = await parser.parse();
|
|
@@ -81,11 +91,16 @@ export async function getCarbonStats(): Promise<CarbonStats> {
|
|
|
81
91
|
outputTokens += stats.output;
|
|
82
92
|
cacheReadTokens += stats.cache;
|
|
83
93
|
sessions += stats.sessions;
|
|
94
|
+
loggedCost += stats.cost;
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
const energyKwh = (outputTokens / 1_000_000) * 0.662;
|
|
87
98
|
const localGrid = getLocalGridFactor();
|
|
88
99
|
|
|
100
|
+
// Prefer the log's own cost field (accurate); fall back to a rough token estimate.
|
|
101
|
+
const costIsReal = loggedCost > 0;
|
|
102
|
+
const estUsd = costIsReal ? loggedCost : estimateUsd(outputTokens, cacheReadTokens, totalTokens);
|
|
103
|
+
|
|
89
104
|
return {
|
|
90
105
|
totalTokens,
|
|
91
106
|
outputTokens,
|
|
@@ -95,6 +110,8 @@ export async function getCarbonStats(): Promise<CarbonStats> {
|
|
|
95
110
|
co2KgFrance: (energyKwh * gridFactors.france) / 1000,
|
|
96
111
|
localCo2Kg: (energyKwh * localGrid.factor) / 1000,
|
|
97
112
|
localRegion: localGrid.region,
|
|
98
|
-
sessions
|
|
113
|
+
sessions,
|
|
114
|
+
estUsd,
|
|
115
|
+
costIsReal
|
|
99
116
|
};
|
|
100
117
|
}
|
package/src/cli.ts
CHANGED
|
@@ -297,19 +297,19 @@ Conservative Floor: ${color(nmPct + '%')}`,
|
|
|
297
297
|
// (The old @clack dashboard panel was removed: it duplicated the receipt's
|
|
298
298
|
// numbers in a second format, doubling the output on every run.)
|
|
299
299
|
const isDanger = gitStats && gitStats.ratio > 0.7;
|
|
300
|
-
const verdictZone = isDanger ? pc.red('
|
|
301
|
-
const verdictText = isDanger
|
|
302
|
-
? `
|
|
303
|
-
: `You
|
|
304
|
-
|
|
300
|
+
const verdictZone = isDanger ? pc.red('Mostly AI') : pc.green('You\'re driving');
|
|
301
|
+
const verdictText = isDanger
|
|
302
|
+
? `AI wrote most of this. Read it through so you can\n still debug it yourself when the agent isn't around.`
|
|
303
|
+
: `You're still writing the core of this. Good —\n that's how you keep the skill.`;
|
|
304
|
+
|
|
305
305
|
const isInefficient = parseFloat(cachePct) > 40;
|
|
306
|
-
const cacheVerdict = isInefficient ? pc.yellow('
|
|
307
|
-
const cacheText = isInefficient
|
|
308
|
-
? `
|
|
309
|
-
: `
|
|
310
|
-
|
|
311
|
-
const policyStatus = ruleFailures > 0 ? pc.red('
|
|
312
|
-
const policyAction = ruleFailures > 0 ? '
|
|
306
|
+
const cacheVerdict = isInefficient ? pc.yellow('Lots of re-reads') : pc.green('Lean');
|
|
307
|
+
const cacheText = isInefficient
|
|
308
|
+
? `Most of your tokens just re-send old context.\n It's normal for agents, but it's most of the bill.`
|
|
309
|
+
: `Little wasted context. Your spend is mostly\n real work.`;
|
|
310
|
+
|
|
311
|
+
const policyStatus = ruleFailures > 0 ? pc.red('Over your limit') : pc.green('Within limit');
|
|
312
|
+
const policyAction = ruleFailures > 0 ? 'Heads up only — nothing was blocked.' : 'Nothing to do.';
|
|
313
313
|
|
|
314
314
|
const fmtTokens = (n: number) =>
|
|
315
315
|
n >= 1_000_000_000 ? (n / 1_000_000_000).toFixed(1) + 'B'
|
|
@@ -317,8 +317,11 @@ Conservative Floor: ${color(nmPct + '%')}`,
|
|
|
317
317
|
: n >= 1_000 ? (n / 1_000).toFixed(1) + 'k'
|
|
318
318
|
: String(n);
|
|
319
319
|
const totalTokensStr = carbon ? fmtTokens(carbon.totalTokens) : '0';
|
|
320
|
-
const
|
|
321
|
-
|
|
320
|
+
const estUsdStr = carbon
|
|
321
|
+
? '$' + carbon.estUsd.toFixed(2) + (carbon.costIsReal ? '' : pc.dim(' (rough)'))
|
|
322
|
+
: pc.dim('n/a');
|
|
323
|
+
const humanSov = gitStats ? ((1 - gitStats.ratio) * 100).toFixed(0) + '%' : '100%';
|
|
324
|
+
const authorshipStr = pc.bold(authPct) + (isDanger ? pc.red(' AI-written') : pc.green(' AI-written'));
|
|
322
325
|
|
|
323
326
|
const getProgressBar = (pct: number, length = 10) => {
|
|
324
327
|
const filled = Math.max(0, Math.min(length, Math.round((pct / 100) * length)));
|
|
@@ -337,34 +340,29 @@ Conservative Floor: ${color(nmPct + '%')}`,
|
|
|
337
340
|
|
|
338
341
|
finalReceipt = `
|
|
339
342
|
${pc.dim('┌────────────────────────────────────────────────────────')}
|
|
340
|
-
${pc.dim('│')} ${pc.cyan('█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█')} ${pc.bold('::
|
|
341
|
-
${pc.dim('│')} ${pc.cyan('█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄')} ${pc.dim(`::
|
|
343
|
+
${pc.dim('│')} ${pc.cyan('█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█')} ${pc.bold(':: CODE AUDIT')}
|
|
344
|
+
${pc.dim('│')} ${pc.cyan('█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄')} ${pc.dim(`:: ${repoName} · ${dateStr}`)}
|
|
342
345
|
${pc.dim('├────────────────────────────────────────────────────────')}
|
|
343
|
-
${pc.dim('│')} ${pc.bold(pc.bgBlue('
|
|
344
|
-
${pc.dim('│')} AI
|
|
345
|
-
${pc.dim('│')}
|
|
346
|
+
${pc.dim('│')} ${pc.bold(pc.bgBlue(' WHO WROTE THE CODE '))}
|
|
347
|
+
${pc.dim('│')} AI ${aiBar} ${authorshipStr}
|
|
348
|
+
${pc.dim('│')} You ${humanBar} ${pc.bold(humanSov)}
|
|
346
349
|
${pc.dim('│')}
|
|
347
|
-
${pc.dim('│')}
|
|
348
|
-
${pc.dim('│')} ${verdictText.split('\n').join('\n ' + pc.dim('│') + ' ')}
|
|
350
|
+
${pc.dim('│')} ${verdictZone} — ${verdictText.split('\n').join('\n ' + pc.dim('│') + ' ')}
|
|
349
351
|
${pc.dim('├────────────────────────────────────────────────────────')}
|
|
350
|
-
${pc.dim('│')} ${pc.bold(pc.bgMagenta('
|
|
351
|
-
${pc.dim('│')} Tokens
|
|
352
|
-
${pc.dim('│')}
|
|
353
|
-
${pc.dim('│')}
|
|
352
|
+
${pc.dim('│')} ${pc.bold(pc.bgMagenta(' WHAT IT COST '))}
|
|
353
|
+
${pc.dim('│')} Tokens used ${pc.bold(totalTokensStr)}
|
|
354
|
+
${pc.dim('│')} Est. spend ${pc.bold(estUsdStr)}
|
|
355
|
+
${pc.dim('│')} Re-used context ${cacheBar} ${pc.bold(cachePct + '%')}
|
|
356
|
+
${pc.dim('│')} Energy ${pc.bold(co2Str)} ${pc.dim(`(${regionStr} grid, rough)`)}
|
|
354
357
|
${pc.dim('│')}
|
|
355
|
-
${pc.dim('│')}
|
|
356
|
-
${pc.dim('│')} ${cacheText.split('\n').join('\n ' + pc.dim('│') + ' ')}
|
|
358
|
+
${pc.dim('│')} ${cacheVerdict} — ${cacheText.split('\n').join('\n ' + pc.dim('│') + ' ')}
|
|
357
359
|
${pc.dim('├────────────────────────────────────────────────────────')}
|
|
358
|
-
${pc.dim('│')} ${pc.bold(pc.bgYellow(pc.black('
|
|
359
|
-
${pc.dim('│')}
|
|
360
|
-
${pc.dim('│')}
|
|
360
|
+
${pc.dim('│')} ${pc.bold(pc.bgYellow(pc.black(' YOUR LIMIT ')))}
|
|
361
|
+
${pc.dim('│')} AI cap ${pc.bold('70%')} ${pc.dim('· change with: outlier policy')}
|
|
362
|
+
${pc.dim('│')} Status ${policyStatus} ${pc.dim('·')} ${policyAction}
|
|
361
363
|
${pc.dim('├────────────────────────────────────────────────────────')}
|
|
362
|
-
${pc.dim('│')}
|
|
363
|
-
${pc.dim('│')}
|
|
364
|
-
${pc.dim('│')} ${pc.italic(pc.dim('code becomes commoditized by algorithms.'))}
|
|
365
|
-
${pc.dim('│')} ${pc.italic(pc.dim('human mastery is the only true moat.'))}
|
|
366
|
-
${pc.dim('│')}
|
|
367
|
-
${pc.dim('│')} ${pc.bold(pc.cyan('***STAY VIGILANT***'))}
|
|
364
|
+
${pc.dim('│')} ${pc.dim(pc.italic('Run this before you start. Keep the skill while you'))}
|
|
365
|
+
${pc.dim('│')} ${pc.dim(pc.italic('use the speed.'))}
|
|
368
366
|
${pc.dim('└────────────────────────────────────────────────────────')}`;
|
|
369
367
|
} else {
|
|
370
368
|
note(
|