@rosh100yx/outlier 0.7.0 → 0.10.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/bin/outlier.js CHANGED
@@ -31,6 +31,20 @@ var __toESM = (mod, isNodeMode, target) => {
31
31
  return to;
32
32
  };
33
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
38
+ var __export = (target, all) => {
39
+ for (var name in all)
40
+ __defProp(target, name, {
41
+ get: all[name],
42
+ enumerable: true,
43
+ configurable: true,
44
+ set: __exportSetter.bind(all, name)
45
+ });
46
+ };
47
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
34
48
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
35
49
 
36
50
  // node_modules/sisteransi/src/index.js
@@ -161,11 +175,52 @@ var require_picocolors = __commonJS((exports, module) => {
161
175
  module.exports.createColors = createColors;
162
176
  });
163
177
 
178
+ // src/economics.ts
179
+ var exports_economics = {};
180
+ __export(exports_economics, {
181
+ projectEconomics: () => projectEconomics
182
+ });
183
+ function projectEconomics(input) {
184
+ const team = input.teamSize ?? DEFAULTS.teamSize;
185
+ const days = input.workdaysPerYear ?? DEFAULTS.workdaysPerYear;
186
+ const ai = Math.max(0, Math.min(1, input.aiRatio));
187
+ const annualOutflowPerDev = input.estUsdSession * (days / 30);
188
+ const annualOutflowTeam = annualOutflowPerDev * team;
189
+ const projections = [
190
+ {
191
+ label: "Authorship shift",
192
+ value: `${(ai * 100).toFixed(0)}% of output → AI`,
193
+ note: team > 1 ? `≈ ${(ai * team).toFixed(1)} of ${team} dev-equivalents of authorship now machine-produced.` : "At team scale, this many dev-equivalents move to the machine."
194
+ },
195
+ {
196
+ label: "Value capture (offshore)",
197
+ value: `~$${Math.round(annualOutflowTeam).toLocaleString()}/yr`,
198
+ note: "Hard-currency spend leaving to a foreign AI vendor — value captured offshore, not by the local worker."
199
+ },
200
+ {
201
+ label: "Skill ladder",
202
+ value: ai > 0.7 ? "AT RISK" : ai > 0.4 ? "watch" : "intact",
203
+ note: ai > 0.7 ? "Above ~70%, juniors stop building the skill that makes seniors — premature deprofessionalization." : "Humans still author enough core work to keep building expertise."
204
+ },
205
+ {
206
+ label: "Forex / tax base",
207
+ value: `$${Math.round(annualOutflowPerDev).toLocaleString()}/dev/yr imported`,
208
+ note: "Locally-taxed wages give way to foreign-billed inference: income-tax erosion + a recurring forex import."
209
+ }
210
+ ];
211
+ const assumptions = `Projection only. Assumes: team of ${team}, the local log window ≈ one month of work, ` + `${days} workdays/yr. Spend is your measured/estimated local outflow scaled up — an order-of-magnitude shadow, not an audit.`;
212
+ return { projections, assumptions };
213
+ }
214
+ var DEFAULTS;
215
+ var init_economics = __esm(() => {
216
+ DEFAULTS = { teamSize: 1, workdaysPerYear: 230 };
217
+ });
218
+
164
219
  // package.json
165
220
  var require_package = __commonJS((exports, module) => {
166
221
  module.exports = {
167
222
  name: "@rosh100yx/outlier",
168
- version: "0.7.0",
223
+ version: "0.10.2",
169
224
  description: "AI Code Governance & Capability Auditing for the Terminal. Measures AI reliance, context waste, and enforces local CI/CD policies.",
170
225
  bin: {
171
226
  outlier: "bin/outlier.js"
@@ -2053,6 +2108,33 @@ function estimateUsd(output, cacheRead, total) {
2053
2108
  const otherInput = Math.max(0, total - output - cacheRead);
2054
2109
  return output / 1e6 * 9 + cacheRead / 1e6 * 0.3 + otherInput / 1e6 * 3;
2055
2110
  }
2111
+ function readCodeCarbon(cwd, home) {
2112
+ const { readFileSync, existsSync: existsSync2 } = __require("fs");
2113
+ const { join: join3 } = __require("path");
2114
+ for (const p2 of [join3(cwd, "emissions.csv"), join3(home, ".codecarbon", "emissions.csv")]) {
2115
+ try {
2116
+ if (!existsSync2(p2))
2117
+ continue;
2118
+ const lines = readFileSync(p2, "utf-8").trim().split(`
2119
+ `);
2120
+ if (lines.length < 2)
2121
+ continue;
2122
+ const header = lines[0].split(",");
2123
+ const iEm = header.indexOf("emissions");
2124
+ const iEn = header.indexOf("energy_consumed");
2125
+ if (iEm === -1 && iEn === -1)
2126
+ continue;
2127
+ let co2 = 0, kwh = 0;
2128
+ for (const row of lines.slice(1)) {
2129
+ const cols = row.split(",");
2130
+ co2 += parseFloat(cols[iEm]) || 0;
2131
+ kwh += parseFloat(cols[iEn]) || 0;
2132
+ }
2133
+ return { energyKwh: kwh, co2Kg: co2 };
2134
+ } catch {}
2135
+ }
2136
+ return null;
2137
+ }
2056
2138
  function getLocalGridFactor() {
2057
2139
  try {
2058
2140
  const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -2084,8 +2166,10 @@ async function getCarbonStats() {
2084
2166
  outputByModel[m2] = (outputByModel[m2] || 0) + out;
2085
2167
  }
2086
2168
  }
2087
- const energyKwh = energyKwhByModel(outputByModel);
2088
2169
  const localGrid = getLocalGridFactor();
2170
+ const measured = readCodeCarbon(process.cwd(), homedir2());
2171
+ const energyKwh = measured ? measured.energyKwh : energyKwhByModel(outputByModel);
2172
+ const measuredCo2 = measured ? measured.co2Kg : null;
2089
2173
  const sources = detectSources();
2090
2174
  const costIsReal = loggedCost > 0;
2091
2175
  const estUsd = costIsReal ? loggedCost : estimateUsd(outputTokens, cacheReadTokens, totalTokens);
@@ -2096,8 +2180,8 @@ async function getCarbonStats() {
2096
2180
  energyKwh,
2097
2181
  co2KgVietnam: energyKwh * grid_factors_default.vietnam / 1000,
2098
2182
  co2KgFrance: energyKwh * grid_factors_default.france / 1000,
2099
- localCo2Kg: energyKwh * localGrid.factor / 1000,
2100
- localRegion: localGrid.region,
2183
+ localCo2Kg: measuredCo2 !== null ? measuredCo2 : energyKwh * localGrid.factor / 1000,
2184
+ localRegion: measured ? "CodeCarbon (measured)" : localGrid.region,
2101
2185
  sessions,
2102
2186
  estUsd,
2103
2187
  costIsReal,
@@ -2189,7 +2273,11 @@ async function getCapabilitiesStats(repoPath = process.cwd(), homeDirPath = home
2189
2273
  for (const cfg of [
2190
2274
  join3(homeDirPath, ".claude.json"),
2191
2275
  join3(homeDirPath, ".claude", "settings.json"),
2276
+ join3(homeDirPath, ".cursor", "mcp.json"),
2277
+ join3(homeDirPath, ".gemini", "config", "mcp_config.json"),
2278
+ join3(homeDirPath, ".gemini", "settings.json"),
2192
2279
  join3(repoPath, ".mcp.json"),
2280
+ join3(repoPath, ".cursor", "mcp.json"),
2193
2281
  join3(repoPath, ".claude", "settings.json")
2194
2282
  ]) {
2195
2283
  const j = readJson(cfg);
@@ -2229,23 +2317,134 @@ async function getCapabilitiesStats(repoPath = process.cwd(), homeDirPath = home
2229
2317
  return { mcps, skills, subagents, hooks, hasOrchestration, blastRadius: radius, blastReasons: reasons };
2230
2318
  }
2231
2319
 
2320
+ // src/insights.ts
2321
+ var RANK = { critical: 0, warn: 1, info: 2, good: 3 };
2322
+ function deriveInsights({ authorship, carbon, caps, policyCap = 0.7 }) {
2323
+ const out = [];
2324
+ const ai = authorship ? authorship.ratio : null;
2325
+ const cachePct = carbon && carbon.totalTokens ? carbon.cacheReadTokens / carbon.totalTokens * 100 : null;
2326
+ const blast = caps ? caps.blastRadius : null;
2327
+ const writeOrDeploy = caps ? caps.mcps.filter((m2) => ["money", "exec", "deploy", "write-remote", "write-local"].includes(m2.reach)).length : 0;
2328
+ const heavyTokens = carbon ? carbon.totalTokens > 1e6 : false;
2329
+ if (ai !== null && ai > 0.7 && (blast === "HIGH" || blast === "CRITICAL")) {
2330
+ out.push({
2331
+ severity: "critical",
2332
+ title: "High reliance + high reach",
2333
+ detail: `AI wrote ${(ai * 100).toFixed(0)}% here and your agents can ${writeOrDeploy ? "write/deploy" : "reach external services"}. You may not own code that can ship to prod.`,
2334
+ action: "Review the core paths yourself before delegating more this session."
2335
+ });
2336
+ } else if (ai !== null && ai > 0.7) {
2337
+ out.push({
2338
+ severity: "warn",
2339
+ title: "You are mostly reviewing, not writing",
2340
+ detail: `AI wrote ${(ai * 100).toFixed(0)}% of recent commits — you risk losing the skill to debug it unaided.`,
2341
+ action: "Read the AI-written code through, or hand-write the next core change."
2342
+ });
2343
+ }
2344
+ if (ai !== null && ai < 0.1 && heavyTokens) {
2345
+ out.push({
2346
+ severity: "info",
2347
+ title: "Low AI% may be misleading",
2348
+ detail: "Heavy token use but few AI-tagged commits — your agent probably is not writing Co-Authored-By trailers.",
2349
+ action: "Treat the authorship number as a floor, not the truth, until trailers are on."
2350
+ });
2351
+ }
2352
+ if (caps && (blast === "CRITICAL" || blast === "HIGH")) {
2353
+ out.push({
2354
+ severity: blast === "CRITICAL" ? "critical" : "warn",
2355
+ title: `Blast radius ${blast}`,
2356
+ detail: `If an agent (or a prompt injection) drives your tools, it ${caps.blastReasons.slice(0, 2).join(" and ") || "has broad reach"}.`,
2357
+ action: "Disable the write/deploy MCP tools you do not need this session."
2358
+ });
2359
+ }
2360
+ if (cachePct !== null && cachePct > 80) {
2361
+ out.push({
2362
+ severity: "warn",
2363
+ title: "Most of your spend is re-sent context",
2364
+ detail: `${cachePct.toFixed(0)}% of your tokens just re-read old context — that is most of the bill, not new work.`,
2365
+ action: "Start fresh sessions for new tasks; keep context tight."
2366
+ });
2367
+ }
2368
+ if (ai !== null && ai > policyCap) {
2369
+ out.push({
2370
+ severity: "warn",
2371
+ title: "Over your AI-authorship limit",
2372
+ detail: `AI authorship is ${(ai * 100).toFixed(0)}%, over your ${(policyCap * 100).toFixed(0)}% limit.`,
2373
+ action: "Either raise the cap deliberately, or write the next change yourself."
2374
+ });
2375
+ }
2376
+ if (out.length === 0) {
2377
+ out.push({
2378
+ severity: "good",
2379
+ title: "Low risk",
2380
+ detail: ai !== null ? `You wrote most of this (${(100 - ai * 100).toFixed(0)}%) and your agents have limited reach.` : "No AI logs or git history found to flag.",
2381
+ action: "Carry on — re-run before your next big delegation."
2382
+ });
2383
+ }
2384
+ return out.sort((a2, b2) => RANK[a2.severity] - RANK[b2.severity]);
2385
+ }
2386
+
2232
2387
  // src/cli.ts
2233
- import { writeFileSync, readFileSync as readFileSync3, chmodSync, existsSync as existsSync4 } from "fs";
2234
- import { join as join5 } from "path";
2388
+ init_economics();
2389
+
2390
+ // src/aggregate.ts
2391
+ import { readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
2392
+ import { join as join4 } from "path";
2393
+ var BLAST_ORDER = ["LOW", "MEDIUM", "HIGH", "CRITICAL"];
2394
+ function aggregateDir(dir) {
2395
+ const files = readdirSync2(dir).filter((f2) => f2.endsWith(".json"));
2396
+ const audits = [];
2397
+ for (const f2 of files) {
2398
+ try {
2399
+ const j = JSON.parse(readFileSync2(join4(dir, f2), "utf-8"));
2400
+ if (j?.tool === "outlier")
2401
+ audits.push(j);
2402
+ } catch {}
2403
+ }
2404
+ const aiPcts = audits.map((a2) => a2.authorship?.aiPercent).filter((x) => typeof x === "number");
2405
+ const spends = audits.map((a2) => a2.cost?.estUsd || 0);
2406
+ const blasts = audits.map((a2) => a2.reach?.blastRadius).filter(Boolean);
2407
+ const overs = audits.filter((a2) => a2.policy?.status === "over").length;
2408
+ const writeDeploy = audits.reduce((s, a2) => s + (a2.reach?.writeOrDeployCount || 0), 0);
2409
+ const worst = blasts.reduce((m2, b2) => BLAST_ORDER.indexOf(b2) > BLAST_ORDER.indexOf(m2) ? b2 : m2, "LOW");
2410
+ const notes = [];
2411
+ if (aiPcts.length && Math.max(...aiPcts) > 70)
2412
+ notes.push("At least one developer is over 70% AI authorship.");
2413
+ if (worst === "HIGH" || worst === "CRITICAL")
2414
+ notes.push(`Worst-case agent blast radius across the team is ${worst}.`);
2415
+ if (overs > 0)
2416
+ notes.push(`${overs} developer(s) over their AI-authorship limit.`);
2417
+ if (audits.length === 0)
2418
+ notes.push("No outlier --json files found in this folder.");
2419
+ return {
2420
+ developers: audits.length,
2421
+ avgAiPercent: aiPcts.length ? +(aiPcts.reduce((a2, b2) => a2 + b2, 0) / aiPcts.length).toFixed(1) : null,
2422
+ maxAiPercent: aiPcts.length ? Math.max(...aiPcts) : null,
2423
+ totalEstUsd: +spends.reduce((a2, b2) => a2 + b2, 0).toFixed(2),
2424
+ worstBlastRadius: worst,
2425
+ overLimit: overs,
2426
+ reachWriteDeploy: writeDeploy,
2427
+ notes
2428
+ };
2429
+ }
2430
+
2431
+ // src/cli.ts
2432
+ import { writeFileSync, readFileSync as readFileSync4, chmodSync, existsSync as existsSync4 } from "fs";
2433
+ import { join as join6 } from "path";
2235
2434
 
2236
2435
  // src/agent.ts
2237
2436
  import { spawnSync as spawnSync2 } from "child_process";
2238
- import { readFileSync as readFileSync2, existsSync as existsSync3 } from "fs";
2239
- import { join as join4 } from "path";
2437
+ import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
2438
+ import { join as join5 } from "path";
2240
2439
  import os from "os";
2241
2440
  function detectAgent() {
2242
2441
  const agents = ["claude", "cursor", "aider", "hermes", "cody", "continue", "opencode", "gemini"];
2243
2442
  try {
2244
2443
  const home = os.homedir();
2245
- const historyFiles = [join4(home, ".zsh_history"), join4(home, ".bash_history")];
2444
+ const historyFiles = [join5(home, ".zsh_history"), join5(home, ".bash_history")];
2246
2445
  for (const file of historyFiles) {
2247
2446
  if (existsSync3(file)) {
2248
- const content = readFileSync2(file, "utf8");
2447
+ const content = readFileSync3(file, "utf8");
2249
2448
  const lines = content.split(`
2250
2449
  `).filter(Boolean).slice(-500).reverse();
2251
2450
  for (const line of lines) {
@@ -2282,6 +2481,54 @@ var ASCII_LOGO = `
2282
2481
  \\____/|_| |_| |_| |_| |_|___|_____|_| \\_\\
2283
2482
  `;
2284
2483
  var finalReceipt = "";
2484
+ function closeBox(s, W2 = 66) {
2485
+ const wide = new Set(["⚠", "\uD83D\uDED1", "✈", "\uD83C\uDF31", "\uD83D\uDCF8", "\uD83D\uDD2C", "\uD83D\uDCBE", "\uD83D\uDCA1", "✅", "❌", "\uD83D\uDE3E", "\uD83D\uDE00"]);
2486
+ const chW = (ch) => {
2487
+ const cp = ch.codePointAt(0);
2488
+ return cp >= 126976 || wide.has(ch) ? 2 : 1;
2489
+ };
2490
+ const rail = "\x1B[2m│\x1B[0m";
2491
+ const fit = (line, totalVis) => {
2492
+ const parts = line.split(/(\x1b\[[0-9;]*m)/);
2493
+ let out = "", vis = 0, cut = false;
2494
+ for (const p2 of parts) {
2495
+ if (/^\x1b\[/.test(p2)) {
2496
+ out += p2;
2497
+ continue;
2498
+ }
2499
+ for (const ch of p2) {
2500
+ const w = chW(ch);
2501
+ if (vis + w > totalVis - 1) {
2502
+ cut = true;
2503
+ break;
2504
+ }
2505
+ out += ch;
2506
+ vis += w;
2507
+ }
2508
+ if (cut)
2509
+ break;
2510
+ }
2511
+ if (cut) {
2512
+ out += "…";
2513
+ vis += 1;
2514
+ }
2515
+ return out + " ".repeat(Math.max(0, totalVis - vis)) + "\x1B[0m";
2516
+ };
2517
+ return s.split(`
2518
+ `).map((line) => {
2519
+ const plain = line.replace(/\x1b\[[0-9;]*m/g, "");
2520
+ if (/^\s*┌/.test(plain))
2521
+ return " \x1B[2m┌" + "─".repeat(W2) + "┐\x1B[0m";
2522
+ if (/^\s*├/.test(plain))
2523
+ return " \x1B[2m├" + "─".repeat(W2) + "┤\x1B[0m";
2524
+ if (/^\s*└/.test(plain))
2525
+ return " \x1B[2m└" + "─".repeat(W2) + "┘\x1B[0m";
2526
+ if (/^\s*│/.test(plain))
2527
+ return fit(line, 2 + W2) + rail;
2528
+ return line;
2529
+ }).join(`
2530
+ `);
2531
+ }
2285
2532
  async function emitJson() {
2286
2533
  const pkg = require_package();
2287
2534
  const [gitStats, carbon, caps] = await Promise.all([
@@ -2337,7 +2584,9 @@ async function emitJson() {
2337
2584
  policy: {
2338
2585
  aiCapPercent: cap * 100,
2339
2586
  status: aiRatio > cap ? "over" : "within"
2340
- }
2587
+ },
2588
+ insights: deriveInsights({ authorship: gitStats, carbon, caps, policyCap: cap }),
2589
+ economics: projectEconomics({ aiRatio, estUsdSession: carbon ? carbon.estUsd : 0, teamSize: 1 })
2341
2590
  };
2342
2591
  process.stdout.write(JSON.stringify(out, null, 2) + `
2343
2592
  `);
@@ -2363,18 +2612,18 @@ As agents write more of our code, we lose visibility into:
2363
2612
  cancel("Onboarding paused. Run outlier again when you are ready.");
2364
2613
  process.exit(0);
2365
2614
  }
2366
- const configPath = join5(os2.homedir(), ".outlier_config");
2615
+ const configPath = join6(os2.homedir(), ".outlier_config");
2367
2616
  writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
2368
2617
  }
2369
2618
  async function main() {
2370
2619
  let action = process.argv[2];
2371
2620
  if (action === "daily-greeting") {
2372
- const configPath2 = join5(os2.homedir(), ".outlier_config");
2621
+ const configPath2 = join6(os2.homedir(), ".outlier_config");
2373
2622
  const today = new Date().toISOString().split("T")[0];
2374
2623
  let alreadyRun = false;
2375
2624
  if (existsSync4(configPath2)) {
2376
2625
  try {
2377
- const cfg = JSON.parse(readFileSync3(configPath2, "utf8"));
2626
+ const cfg = JSON.parse(readFileSync4(configPath2, "utf8"));
2378
2627
  if (cfg.lastGreetingDate === today) {
2379
2628
  alreadyRun = true;
2380
2629
  } else {
@@ -2385,7 +2634,13 @@ async function main() {
2385
2634
  }
2386
2635
  if (alreadyRun)
2387
2636
  process.exit(0);
2388
- action = "status";
2637
+ const g2 = await getAuthorshipStats().catch(() => null);
2638
+ const cp = await getCapabilitiesStats().catch(() => null);
2639
+ const aiP = g2 ? (g2.ratio * 100).toFixed(0) + "%" : "—";
2640
+ const br = cp ? cp.blastRadius : "—";
2641
+ const brc = br === "HIGH" || br === "CRITICAL" ? import_picocolors.default.red : br === "MEDIUM" ? import_picocolors.default.yellow : import_picocolors.default.green;
2642
+ console.log(`${import_picocolors.default.dim("[outlier]")} AI authorship ${import_picocolors.default.bold(aiP)} · agent reach ${brc(import_picocolors.default.bold(br))} ${import_picocolors.default.dim("· before you delegate, run: outlier preflight")}`);
2643
+ process.exit(0);
2389
2644
  }
2390
2645
  if (process.argv.includes("--json")) {
2391
2646
  await emitJson();
@@ -2403,6 +2658,7 @@ WHAT OUTLIER DOES`));
2403
2658
  `));
2404
2659
  console.log(import_picocolors.default.bold("COMMANDS:"));
2405
2660
  console.log(` ${import_picocolors.default.cyan("outlier")} Run the audit (the default — same as 'status')`);
2661
+ console.log(` ${import_picocolors.default.cyan("outlier preflight")} Quick briefing BEFORE you start an agent (reach + skill + spend)`);
2406
2662
  console.log(` ${import_picocolors.default.cyan("outlier status")} Full audit: who wrote the code, what it cost, your limit`);
2407
2663
  console.log(` ${import_picocolors.default.cyan("outlier status --save")} Save the audit to ./outlier-audit.txt`);
2408
2664
  console.log(` ${import_picocolors.default.cyan("outlier --json")} Machine-readable audit (for agents, CI, swarms)`);
@@ -2420,7 +2676,7 @@ WHAT OUTLIER DOES`));
2420
2676
  console.log(import_picocolors.default.dim("How it works → https://github.com/rosh100yx/outlier#how-it-works"));
2421
2677
  process.exit(0);
2422
2678
  }
2423
- const configPath = join5(os2.homedir(), ".outlier_config");
2679
+ const configPath = join6(os2.homedir(), ".outlier_config");
2424
2680
  if (!existsSync4(configPath) && !action) {
2425
2681
  await runOnboarding();
2426
2682
  action = "status";
@@ -2432,7 +2688,7 @@ WHAT OUTLIER DOES`));
2432
2688
  if (action === "init" || action === "uninit") {
2433
2689
  const shell = process.env.SHELL || "";
2434
2690
  const rcName = shell.includes("zsh") ? ".zshrc" : ".bashrc";
2435
- const rcPath = join5(os2.homedir(), rcName);
2691
+ const rcPath = join6(os2.homedir(), rcName);
2436
2692
  const START_MARKER = "# --- OUTLIER PRE-FLIGHT RITUAL START ---";
2437
2693
  const END_MARKER = "# --- OUTLIER PRE-FLIGHT RITUAL END ---";
2438
2694
  const BLOCK = `
@@ -2453,7 +2709,7 @@ ${END_MARKER}
2453
2709
  }
2454
2710
  let content = "";
2455
2711
  if (existsSync4(rcPath))
2456
- content = readFileSync3(rcPath, "utf8");
2712
+ content = readFileSync4(rcPath, "utf8");
2457
2713
  if (content.includes(START_MARKER)) {
2458
2714
  note(`Outlier is already initialized in ${rcName}`);
2459
2715
  } else {
@@ -2463,7 +2719,7 @@ ${END_MARKER}
2463
2719
  process.exit(0);
2464
2720
  } else if (action === "uninit") {
2465
2721
  if (existsSync4(rcPath)) {
2466
- let content = readFileSync3(rcPath, "utf8");
2722
+ let content = readFileSync4(rcPath, "utf8");
2467
2723
  if (content.includes(START_MARKER)) {
2468
2724
  const regex = new RegExp(`\\n?${START_MARKER}[\\s\\S]*?${END_MARKER}\\n?`, "g");
2469
2725
  content = content.replace(regex, `
@@ -2532,10 +2788,10 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
2532
2788
  let carbon = null;
2533
2789
  let capabilities = null;
2534
2790
  let skipDelay = false;
2535
- const configPath2 = join5(os2.homedir(), ".outlier_config");
2791
+ const configPath2 = join6(os2.homedir(), ".outlier_config");
2536
2792
  if (existsSync4(configPath2)) {
2537
2793
  try {
2538
- const cfg = JSON.parse(readFileSync3(configPath2, "utf8"));
2794
+ const cfg = JSON.parse(readFileSync4(configPath2, "utf8"));
2539
2795
  if (cfg.seenNarration)
2540
2796
  skipDelay = true;
2541
2797
  } catch (e) {}
@@ -2573,7 +2829,7 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
2573
2829
  await new Promise((r2) => setTimeout(r2, 600));
2574
2830
  if (!skipDelay) {
2575
2831
  try {
2576
- const cfg = existsSync4(configPath2) ? JSON.parse(readFileSync3(configPath2, "utf8")) : {};
2832
+ const cfg = existsSync4(configPath2) ? JSON.parse(readFileSync4(configPath2, "utf8")) : {};
2577
2833
  cfg.seenNarration = true;
2578
2834
  writeFileSync(configPath2, JSON.stringify(cfg));
2579
2835
  } catch (e) {}
@@ -2619,6 +2875,14 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
2619
2875
  const risky = capabilities.mcps.filter((m2) => ["money", "exec", "deploy", "write-remote", "write-local"].includes(m2.reach)).length;
2620
2876
  reachStr = `${col(import_picocolors.default.bold(rc))} · ${capabilities.mcps.length} tools` + (risky ? import_picocolors.default.dim(`, ${risky} can write/deploy`) : "");
2621
2877
  }
2878
+ const insights = deriveInsights({ authorship: gitStats, carbon, caps: capabilities, policyCap: 0.7 });
2879
+ const sevColor = (s2) => s2 === "critical" ? import_picocolors.default.red : s2 === "warn" ? import_picocolors.default.yellow : s2 === "good" ? import_picocolors.default.green : import_picocolors.default.cyan;
2880
+ const sevMark = (s2) => s2 === "critical" ? "✗" : s2 === "warn" ? "⚠" : s2 === "good" ? "✓" : "i";
2881
+ const insightLines = insights.slice(0, 2).map((ins) => ` ${import_picocolors.default.dim("│")} ${sevColor(ins.severity)(sevMark(ins.severity))} ${import_picocolors.default.bold(ins.title)}
2882
+ ` + ` ${import_picocolors.default.dim("│")} ${ins.detail.length > 56 ? ins.detail.slice(0, 55) + "…" : ins.detail}
2883
+ ` + ` ${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("→ " + ins.action)}`).join(`
2884
+ ${import_picocolors.default.dim("│")}
2885
+ `);
2622
2886
  const isDanger = gitStats && gitStats.ratio > 0.7;
2623
2887
  const verdictZone = isDanger ? import_picocolors.default.red("Mostly AI") : import_picocolors.default.green("You're driving");
2624
2888
  const verdictText = isDanger ? `AI wrote most of this. Read it through so you can
@@ -2680,6 +2944,9 @@ Conservative Floor: ${color(nmPct + "%")}`, "Git Authorship Breakdown");
2680
2944
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgYellow(import_picocolors.default.black(" YOUR LIMIT ")))}
2681
2945
  ${import_picocolors.default.dim("│")} AI cap ${import_picocolors.default.bold("70%")} ${import_picocolors.default.dim("· change with: outlier policy")}
2682
2946
  ${import_picocolors.default.dim("│")} Status ${policyStatus} ${import_picocolors.default.dim("·")} ${policyAction}
2947
+ ${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
2948
+ ${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.bgGreen(import_picocolors.default.black(" WHAT TO DO ")))}
2949
+ ${insightLines}
2683
2950
  ${import_picocolors.default.dim("├────────────────────────────────────────────────────────")}
2684
2951
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.dim("Numbers are local estimates — authorship is a proxy and")}
2685
2952
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.dim("carbon is rough. How it works: outlier --help")}
@@ -2733,6 +3000,53 @@ ${import_picocolors.default.dim("This is your attack surface. Fewer write/deploy
2733
3000
  s.stop("Audit failed");
2734
3001
  console.error(import_picocolors.default.red(e.message));
2735
3002
  }
3003
+ } else if (action === "aggregate") {
3004
+ const dir = process.argv[3];
3005
+ if (!dir || !existsSync4(dir)) {
3006
+ console.error(import_picocolors.default.red("Usage: outlier aggregate <folder-of-json-audits>"));
3007
+ console.log(import_picocolors.default.dim(" Each dev: outlier --json > team/<name>.json then: outlier aggregate team/"));
3008
+ process.exit(1);
3009
+ }
3010
+ const r2 = aggregateDir(dir);
3011
+ note(`Developers: ${import_picocolors.default.bold(String(r2.developers))}
3012
+ Avg AI authorship: ${import_picocolors.default.bold(r2.avgAiPercent !== null ? r2.avgAiPercent + "%" : "—")} Max: ${r2.maxAiPercent !== null ? r2.maxAiPercent + "%" : "—"}
3013
+ Over their limit: ${r2.overLimit > 0 ? import_picocolors.default.red(String(r2.overLimit)) : import_picocolors.default.green("0")}
3014
+ Team spend (est): ${import_picocolors.default.bold("$" + r2.totalEstUsd)}
3015
+ Worst blast radius:${" "}${r2.worstBlastRadius === "HIGH" || r2.worstBlastRadius === "CRITICAL" ? import_picocolors.default.red(r2.worstBlastRadius) : import_picocolors.default.yellow(r2.worstBlastRadius)} (${r2.reachWriteDeploy} write/deploy tools across the team)
3016
+ ${r2.notes.length ? `
3017
+ ` + r2.notes.map((n2) => `${import_picocolors.default.yellow("•")} ${n2}`).join(`
3018
+ `) : ""}`, "Team Rollup (local-first — nothing was exported)");
3019
+ } else if (action === "preflight") {
3020
+ s.start("Pre-flight check...");
3021
+ const gitStats = await getAuthorshipStats().catch(() => null);
3022
+ const carbon = await getCarbonStats().catch(() => null);
3023
+ const caps = await getCapabilitiesStats().catch(() => null);
3024
+ s.stop("Ready for take-off");
3025
+ const aiPct = gitStats ? (gitStats.ratio * 100).toFixed(0) : "—";
3026
+ const youPct = gitStats ? (100 - gitStats.ratio * 100).toFixed(0) : "—";
3027
+ const blast = caps ? caps.blastRadius : "UNKNOWN";
3028
+ const blastCol = blast === "CRITICAL" || blast === "HIGH" ? import_picocolors.default.red : blast === "MEDIUM" ? import_picocolors.default.yellow : import_picocolors.default.green;
3029
+ const risky = caps ? caps.mcps.filter((m2) => ["money", "exec", "deploy", "write-remote", "write-local"].includes(m2.reach)).length : 0;
3030
+ const spend = carbon ? `$${carbon.estUsd.toFixed(0)}` : "—";
3031
+ const cachePct = carbon && carbon.totalTokens ? (carbon.cacheReadTokens / carbon.totalTokens * 100).toFixed(0) + "%" : "—";
3032
+ const insights = deriveInsights({ authorship: gitStats, carbon, caps, policyCap: 0.7 });
3033
+ const sevCol = (sv) => sv === "critical" ? import_picocolors.default.red : sv === "warn" ? import_picocolors.default.yellow : sv === "good" ? import_picocolors.default.green : import_picocolors.default.cyan;
3034
+ const sevMk = (sv) => sv === "critical" ? "✗" : sv === "warn" ? "⚠" : sv === "good" ? "✓" : "i";
3035
+ const actionLines = insights.slice(0, 3).map((ins) => ` ${sevCol(ins.severity)(sevMk(ins.severity))} ${import_picocolors.default.cyan("→")} ${ins.action}`).join(`
3036
+ `);
3037
+ console.log("");
3038
+ console.log(import_picocolors.default.bold(import_picocolors.default.cyan(" ✈ PRE-FLIGHT")) + import_picocolors.default.dim(` · ${process.cwd().split("/").pop()}`));
3039
+ console.log(import_picocolors.default.dim(" ────────────────────────────────────────────────────"));
3040
+ console.log(` ${import_picocolors.default.bold("Reach")} ${blastCol(import_picocolors.default.bold(blast))}` + (caps ? import_picocolors.default.dim(` · ${caps.mcps.length} tools, ${risky} can write/deploy`) : ""));
3041
+ console.log(` ${import_picocolors.default.bold("Skill")} AI wrote ${import_picocolors.default.bold(aiPct + "%")} · you own ${import_picocolors.default.bold(youPct + "%")}`);
3042
+ console.log(` ${import_picocolors.default.bold("Spend")} ${import_picocolors.default.bold(spend)} · ${cachePct} re-sent context`);
3043
+ console.log("");
3044
+ console.log(import_picocolors.default.bold(" Before you delegate:"));
3045
+ console.log(actionLines);
3046
+ console.log("");
3047
+ const agent = detectAgent();
3048
+ console.log(import_picocolors.default.bold(import_picocolors.default.magenta(" ✓ Ready? ")) + "Start your session: " + import_picocolors.default.bold(agent || "your AI agent"));
3049
+ console.log("");
2736
3050
  } else if (action === "policy") {
2737
3051
  const tier = await select({
2738
3052
  message: "Select the governance tier to configure:",
@@ -2762,7 +3076,7 @@ ${import_picocolors.default.dim("This is your attack surface. Fewer write/deploy
2762
3076
  process.exit(0);
2763
3077
  }
2764
3078
  s.start(`Applying ${tier} policy guardrails...`);
2765
- const gitDir = join5(process.cwd(), ".git");
3079
+ const gitDir = join6(process.cwd(), ".git");
2766
3080
  const isRepo = existsSync4(gitDir);
2767
3081
  if (!isRepo) {
2768
3082
  console.error(import_picocolors.default.red("Must be run inside a git repository"));
@@ -2771,7 +3085,7 @@ ${import_picocolors.default.dim("This is your attack surface. Fewer write/deploy
2771
3085
  const isStrict = process.argv.includes("--strict");
2772
3086
  const bouncerMsg = isStrict ? `echo "⚠️ outlier policy warning: AI authorship ($CURRENT_RATIO%) exceeds threshold ($MAX_RATIO%)"` : `echo "\uD83D\uDEE1️ Outlier Bouncer: Repository AI-generation ($CURRENT_RATIO%) exceeds your defined mastery threshold ($MAX_RATIO%)."
2773
3087
  echo "Take a moment to review your recent architectural decisions. Ensure you still understand the system."`;
2774
- const hookPath = join5(gitDir, "hooks", "pre-commit");
3088
+ const hookPath = join6(gitDir, "hooks", "pre-commit");
2775
3089
  if (existsSync4(hookPath)) {
2776
3090
  const { copyFileSync } = __require("fs");
2777
3091
  copyFileSync(hookPath, `${hookPath}.backup`);
@@ -2803,16 +3117,31 @@ Rule 1: ${import_picocolors.default.green(`AI Authorship must not exceed $
2803
3117
  Rule 2: ${import_picocolors.default.green("Require human review on consecutive high-AI sprints")}
2804
3118
  Enforcement: ${import_picocolors.default.cyan("Local pre-commit hook installed (backup created)")}`, "Active Governance Policy");
2805
3119
  } else if (tier === "regulatory") {
2806
- s.start("Generating Regulatory Compliance Audit (Decree 142)...");
2807
- await new Promise((resolve) => setTimeout(resolve, 1200));
2808
- const reportPath = join5(process.cwd(), "outlier-audit-report.jsonl");
2809
- writeFileSync(reportPath, JSON.stringify({ timestamp: new Date().toISOString(), status: "PREVIEW", policy: "Decree 142", simulatedOversight: true }) + `
3120
+ s.start("Generating human-oversight audit record (Decree 142)...");
3121
+ const gitStats = await getAuthorshipStats().catch(() => null);
3122
+ const caps = await getCapabilitiesStats().catch(() => null);
3123
+ const humanReviewRate = gitStats ? +(1 - gitStats.ratio).toFixed(3) : null;
3124
+ const oversightOk = humanReviewRate !== null && humanReviewRate >= 0.3;
3125
+ const record = {
3126
+ timestamp: new Date().toISOString(),
3127
+ policy: "Vietnam Decree 142/2026 — human oversight of high-risk AI",
3128
+ repo: process.cwd().split("/").pop(),
3129
+ humanAuthorshipRate: humanReviewRate,
3130
+ aiAuthorshipRate: gitStats ? +gitStats.ratio.toFixed(3) : null,
3131
+ humanOversight: oversightOk ? "present" : "insufficient",
3132
+ agentBlastRadius: caps ? caps.blastRadius : "unknown",
3133
+ dataExported: false,
3134
+ note: "Derived from local git history only. No code, prompts, or citizen data leave the machine. Authorship is a proxy for human oversight."
3135
+ };
3136
+ const reportPath = join6(process.cwd(), "outlier-audit-report.jsonl");
3137
+ writeFileSync(reportPath, JSON.stringify(record) + `
2810
3138
  `);
2811
- s.stop("Audit Generated");
2812
- note(`Jurisdiction: ${import_picocolors.default.bold("Vietnam (Decree 142)")}
2813
- Status: ${import_picocolors.default.green("Compliant - Human oversight logged locally")}
2814
- Privacy: ${import_picocolors.default.green("Preserved - No citizen data exported")}
2815
- Artifact: ${import_picocolors.default.cyan(reportPath)}`, "Regulatory Compliance");
3139
+ s.stop("Audit record written");
3140
+ note(`Jurisdiction: ${import_picocolors.default.bold("Vietnam (Decree 142/2026)")}
3141
+ Human oversight: ${oversightOk ? import_picocolors.default.green("present") : import_picocolors.default.red("insufficient")} ${import_picocolors.default.dim(`(${humanReviewRate !== null ? (humanReviewRate * 100).toFixed(0) + "% human-authored" : "no git history"})`)}
3142
+ Agent reach: ${caps ? caps.blastRadius : "unknown"}
3143
+ Privacy: ${import_picocolors.default.green("preserved — nothing exported")}
3144
+ Artifact: ${import_picocolors.default.cyan(reportPath)}`, "Human-Oversight Audit Record");
2816
3145
  }
2817
3146
  } else if (action === "participate") {
2818
3147
  s.start("Connecting to the Outlier research project...");
@@ -2884,6 +3213,28 @@ ${import_picocolors.default.bold("Submit here (and drop your screenshot!):")} ${
2884
3213
  ■ Next 5-10 Years (The 1M+ LOC Crisis)`));
2885
3214
  console.log(` When an agent introduces a fatal state bug in a monolithic architecture, human reviewers will lack the muscle memory to debug it. Outlier measures this exact sovereignty erosion.
2886
3215
  `);
3216
+ const gitStats = await getAuthorshipStats().catch(() => null);
3217
+ const carbon = await getCarbonStats().catch(() => null);
3218
+ if (gitStats || carbon) {
3219
+ const { projectEconomics: projectEconomics2 } = await Promise.resolve().then(() => (init_economics(), exports_economics));
3220
+ const teamSize = (() => {
3221
+ const i2 = process.argv.indexOf("--team");
3222
+ return i2 > -1 ? parseInt(process.argv[i2 + 1] || "1") || 1 : 1;
3223
+ })();
3224
+ const econ = projectEconomics2({
3225
+ aiRatio: gitStats ? gitStats.ratio : 0,
3226
+ estUsdSession: carbon ? carbon.estUsd : 0,
3227
+ teamSize
3228
+ });
3229
+ console.log(import_picocolors.default.bold(import_picocolors.default.bgMagenta(" THE MACRO SHADOW ")) + import_picocolors.default.dim(` (team of ${teamSize} — set with --team N)`));
3230
+ for (const p2 of econ.projections) {
3231
+ console.log(` ${import_picocolors.default.bold(p2.label.padEnd(20))} ${import_picocolors.default.cyan(p2.value)}`);
3232
+ console.log(` ${import_picocolors.default.dim(" " + p2.note)}`);
3233
+ }
3234
+ console.log(`
3235
+ ` + import_picocolors.default.dim(" " + econ.assumptions) + `
3236
+ `);
3237
+ }
2887
3238
  } else if (action === "knowledge") {
2888
3239
  console.log(`
2889
3240
  ` + import_picocolors.default.bold(import_picocolors.default.bgBlue(" CORE LITERATURE & REFERENCES ")) + `
@@ -2897,12 +3248,13 @@ Read the full academic foundation at: ${import_picocolors.default.underline("htt
2897
3248
  }
2898
3249
  outro("Done — nothing left your machine. (How it works: outlier --help)");
2899
3250
  if (typeof finalReceipt !== "undefined" && finalReceipt) {
2900
- console.log(finalReceipt);
3251
+ const boxed = closeBox(finalReceipt);
3252
+ console.log(boxed);
2901
3253
  if (process.argv.includes("--save")) {
2902
3254
  const stripAnsi = (s2) => s2.replace(/\x1b\[[0-9;]*m/g, "");
2903
- const savePath = join5(process.cwd(), "outlier-audit.txt");
3255
+ const savePath = join6(process.cwd(), "outlier-audit.txt");
2904
3256
  try {
2905
- writeFileSync(savePath, stripAnsi(finalReceipt).trimStart() + `
3257
+ writeFileSync(savePath, stripAnsi(boxed).trimStart() + `
2906
3258
  `);
2907
3259
  console.log(import_picocolors.default.dim(`
2908
3260
  \uD83D\uDCBE Saved to ${savePath}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosh100yx/outlier",
3
- "version": "0.7.0",
3
+ "version": "0.10.2",
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"