@rosh100yx/outlier 0.4.10 → 0.4.15

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/README.md CHANGED
@@ -18,8 +18,26 @@
18
18
  </p>
19
19
 
20
20
  <br/>
21
- <img src="https://raw.githubusercontent.com/rosh100yx/outlier/main/assets/cli-demo.png" alt="Outlier CLI Demo" width="800" />
22
- <br/>
21
+
22
+ ```text
23
+ ┌────────────────────────────────────────────────────────┐
24
+ │ █▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█ :: THERMAL AUDIT RECEIPT │
25
+ │ █▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄ :: TIMESTAMP: 2026-06-23 │
26
+ ├────────────────────────────────────────────────────────┤
27
+ │ [ COGNITIVE BUDGET ] │
28
+ │ AI Authorship ................. ▇▇▇▇░░░░░░ 40% │
29
+ │ Human Sovereignty ................. ▇▇▇▇▇▇░░░░ 60% │
30
+ │ │
31
+ │ ↳ Verdict: (=^ ◡ ^=) CENTAUR │
32
+ │ Healthy symbiosis. You orchestrate agents │
33
+ │ but maintain architectural authority. │
34
+ ├────────────────────────────────────────────────────────┤
35
+ │ [ FINANCIAL & COMPUTE TOLL ] │
36
+ │ Tokens Burnt ................. 3.12M vs Human │
37
+ │ Cache Bloat ................. ▇▇▇▇▇▇▇▇░░ 80% │
38
+ │ Regional Grid ................. 1.54 kgCO2 │
39
+ └────────────────────────────────────────────────────────┘
40
+ ```
23
41
  </div>
24
42
 
25
43
  ## How It Works
@@ -50,13 +68,28 @@
50
68
  ## Commands
51
69
  | Command | Purpose |
52
70
  |---------|---------|
53
- | `outlier` | Start the interactive Onboarding Wizard (Recommended for first-timers) |
54
- | `outlier --help` | View the CLI help menu and all available commands |
55
- | `outlier status` | Run the full AI reliance & capability audit (Generates the Thermal Receipt) |
56
- | `outlier authorship` | Scan git history for AI co-authorship ratio and Hallucination Risk |
71
+ | `outlier` | Start the interactive Interactive Menu |
72
+ | `outlier status` | Run the full AI reliance & capability audit |
73
+ | `outlier authorship` | Scan git history for AI co-authorship ratio |
57
74
  | `outlier carbon` | Scan local logs for context waste & token costs |
75
+ | `outlier capabilities` | Audit active MCPs, skills, and orchestrations |
58
76
  | `outlier policy` | Configure Personal, Team, or Enterprise guardrails in CI |
59
- | `outlier confessional` | Submit qualitative feedback or feature requests directly from the terminal |
77
+
78
+ ### Interactive Menu
79
+ If you run `outlier` directly, you'll be greeted with our frictionless UX:
80
+ ```text
81
+ ? Select outlier governance module:
82
+ ── AUDIT ──
83
+ ❯ Status Full audit (reliance + carbon + capabilities)
84
+ Authorship Human vs AI, per commit
85
+ Carbon Token waste + regional cost
86
+ Capabilities What your agents can reach
87
+ Policy Set guardrails / install the gate
88
+ ── LEARN ──
89
+ Impact What happens over the next 5-10 years
90
+ Literature The academic foundation
91
+ Participate Contribute to the research
92
+ ```
60
93
 
61
94
  ## Quickstart: Your First Audit
62
95
 
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.10",
168
+ version: "0.4.15",
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"
@@ -177,7 +177,7 @@ var require_package = __commonJS((exports, module) => {
177
177
  "data"
178
178
  ],
179
179
  scripts: {
180
- build: "bun build ./src/cli.ts --target=node --outfile bin/outlier.js",
180
+ build: "bunx tsc --noEmit && bun build ./src/cli.ts --target=node --outfile bin/outlier.js",
181
181
  test: "bun test",
182
182
  start: "bun run src/cli.ts",
183
183
  postinstall: "node bin/postinstall.js"
@@ -218,6 +218,9 @@ var require_package = __commonJS((exports, module) => {
218
218
  };
219
219
  });
220
220
 
221
+ // src/cli.ts
222
+ import os from "os";
223
+
221
224
  // node_modules/@clack/core/dist/index.mjs
222
225
  import { styleText } from "node:util";
223
226
  import { stdout, stdin } from "node:process";
@@ -940,34 +943,16 @@ var T$1 = class T extends V {
940
943
  }
941
944
  }
942
945
  };
943
-
944
- class r extends V {
945
- get cursor() {
946
- return this.value ? 0 : 1;
947
- }
948
- get _value() {
949
- return this.cursor === 0;
950
- }
951
- constructor(t2) {
952
- super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
953
- this.value = this._value;
954
- }), this.on("confirm", (i) => {
955
- this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
956
- }), this.on("cursor", () => {
957
- this.value = !this.value;
958
- });
959
- }
960
- }
961
946
  var _ = {
962
947
  Y: { type: "year", len: 4 },
963
948
  M: { type: "month", len: 2 },
964
949
  D: { type: "day", len: 2 }
965
950
  };
966
- function M(r2) {
967
- return [...r2].map((t2) => _[t2]);
951
+ function M(r) {
952
+ return [...r].map((t2) => _[t2]);
968
953
  }
969
- function P(r2) {
970
- const i = new Intl.DateTimeFormat(r2, {
954
+ function P(r) {
955
+ const i = new Intl.DateTimeFormat(r, {
971
956
  year: "numeric",
972
957
  month: "2-digit",
973
958
  day: "2-digit"
@@ -977,32 +962,32 @@ function P(r2) {
977
962
  e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
978
963
  return { segments: s, separator: n };
979
964
  }
980
- function p(r2) {
981
- return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
965
+ function p(r) {
966
+ return Number.parseInt((r || "0").replace(/_/g, "0"), 10) || 0;
982
967
  }
983
- function f(r2) {
968
+ function f(r) {
984
969
  return {
985
- year: p(r2.year),
986
- month: p(r2.month),
987
- day: p(r2.day)
970
+ year: p(r.year),
971
+ month: p(r.month),
972
+ day: p(r.day)
988
973
  };
989
974
  }
990
- function c(r2, t2) {
991
- return new Date(r2 || 2001, t2 || 1, 0).getDate();
975
+ function c(r, t2) {
976
+ return new Date(r || 2001, t2 || 1, 0).getDate();
992
977
  }
993
- function b(r2) {
994
- const { year: t2, month: i, day: s } = f(r2);
978
+ function b(r) {
979
+ const { year: t2, month: i, day: s } = f(r);
995
980
  if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
996
981
  return;
997
982
  const n = new Date(Date.UTC(t2, i - 1, s));
998
983
  if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
999
984
  return { year: t2, month: i, day: s };
1000
985
  }
1001
- function C(r2) {
1002
- const t2 = b(r2);
986
+ function C(r) {
987
+ const t2 = b(r);
1003
988
  return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
1004
989
  }
1005
- function T2(r2, t2, i, s) {
990
+ function T2(r, t2, i, s) {
1006
991
  const n = i ? {
1007
992
  year: i.getUTCFullYear(),
1008
993
  month: i.getUTCMonth() + 1,
@@ -1012,7 +997,7 @@ function T2(r2, t2, i, s) {
1012
997
  month: s.getUTCMonth() + 1,
1013
998
  day: s.getUTCDate()
1014
999
  } : null;
1015
- return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
1000
+ return r === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r === "month" ? {
1016
1001
  min: n && t2.year === n.year ? n.month : 1,
1017
1002
  max: e && t2.year === e.year ? e.month : 12
1018
1003
  } : {
@@ -1185,26 +1170,26 @@ var u$1 = class u extends V {
1185
1170
  cursor = 0;
1186
1171
  #t;
1187
1172
  getGroupItems(t2) {
1188
- return this.options.filter((r2) => r2.group === t2);
1173
+ return this.options.filter((r) => r.group === t2);
1189
1174
  }
1190
1175
  isGroupSelected(t2) {
1191
- const r2 = this.getGroupItems(t2), e = this.value;
1192
- return e === undefined ? false : r2.every((s) => e.includes(s.value));
1176
+ const r = this.getGroupItems(t2), e = this.value;
1177
+ return e === undefined ? false : r.every((s) => e.includes(s.value));
1193
1178
  }
1194
1179
  toggleValue() {
1195
1180
  const t2 = this.options[this.cursor];
1196
1181
  if (this.value === undefined && (this.value = []), t2.group === true) {
1197
- const r2 = t2.value, e = this.getGroupItems(r2);
1198
- this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
1182
+ const r = t2.value, e = this.getGroupItems(r);
1183
+ this.isGroupSelected(r) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
1199
1184
  } else {
1200
- const r2 = this.value.includes(t2.value);
1201
- this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1185
+ const r = this.value.includes(t2.value);
1186
+ this.value = r ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1202
1187
  }
1203
1188
  }
1204
1189
  constructor(t2) {
1205
1190
  super(t2, false);
1206
- const { options: r2 } = t2;
1207
- this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
1191
+ const { options: r } = t2;
1192
+ this.#t = t2.selectableGroups !== false, this.options = Object.entries(r).flatMap(([e, s]) => [
1208
1193
  { value: e, group: true, label: e },
1209
1194
  ...s.map((i) => ({ ...i, group: e }))
1210
1195
  ]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
@@ -1242,10 +1227,10 @@ class h extends V {
1242
1227
  const t2 = this.userInput;
1243
1228
  if (this.cursor >= t2.length)
1244
1229
  return `${t2}█`;
1245
- const s = t2.slice(0, this.cursor), r2 = t2[this.cursor], i = t2.slice(this.cursor + 1);
1246
- return r2 === `
1230
+ const s = t2.slice(0, this.cursor), r = t2[this.cursor], i = t2.slice(this.cursor + 1);
1231
+ return r === `
1247
1232
  ` ? `${s}█
1248
- ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1233
+ ${i}` : `${s}${styleText("inverse", r)}${i}`;
1249
1234
  }
1250
1235
  get cursor() {
1251
1236
  return this._cursor;
@@ -1278,8 +1263,8 @@ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1278
1263
  if (this.#s)
1279
1264
  return this.focused === "submit" ? true : (this.#r(`
1280
1265
  `), this._cursor++, false);
1281
- const r2 = this.#t;
1282
- return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1266
+ const r = this.#t;
1267
+ return this.#t = true, r && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1283
1268
  ` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
1284
1269
  `), this._cursor++, false);
1285
1270
  }
@@ -1288,12 +1273,12 @@ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1288
1273
  super({
1289
1274
  ...t2,
1290
1275
  initialUserInput: s
1291
- }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
1276
+ }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r, i) => {
1292
1277
  if (i?.name && o$1.has(i.name)) {
1293
1278
  this.#t = false, this.#i(i.name);
1294
1279
  return;
1295
1280
  }
1296
- if (r2 === "\t" && this.#s) {
1281
+ if (r === "\t" && this.#s) {
1297
1282
  this.focused = this.focused === "editor" ? "submit" : "editor";
1298
1283
  return;
1299
1284
  }
@@ -1306,10 +1291,10 @@ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1306
1291
  this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
1307
1292
  return;
1308
1293
  }
1309
- r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
1294
+ r && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r ?? ""), this._cursor++);
1310
1295
  }
1311
- }), this.on("userInput", (r2) => {
1312
- this._setValue(r2);
1296
+ }), this.on("userInput", (r) => {
1297
+ this._setValue(r);
1313
1298
  }), this.on("finalize", () => {
1314
1299
  this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
1315
1300
  });
@@ -1349,8 +1334,8 @@ class n extends V {
1349
1334
  const t2 = this.userInput;
1350
1335
  if (this.cursor >= t2.length)
1351
1336
  return `${this.userInput}█`;
1352
- const e = t2.slice(0, this.cursor), [s, ...r2] = t2.slice(this.cursor);
1353
- return `${e}${styleText("inverse", s)}${r2.join("")}`;
1337
+ const e = t2.slice(0, this.cursor), [s, ...r] = t2.slice(this.cursor);
1338
+ return `${e}${styleText("inverse", s)}${r.join("")}`;
1354
1339
  }
1355
1340
  get cursor() {
1356
1341
  return this._cursor;
@@ -1484,41 +1469,6 @@ var limitOptions = ({
1484
1469
  b2.push(n2);
1485
1470
  return u3 && b2.push(C2), b2;
1486
1471
  };
1487
- var confirm = (i) => {
1488
- const a2 = i.active ?? "Yes", s = i.inactive ?? "No";
1489
- return new r({
1490
- active: a2,
1491
- inactive: s,
1492
- signal: i.signal,
1493
- input: i.input,
1494
- output: i.output,
1495
- initialValue: i.initialValue ?? true,
1496
- render() {
1497
- const e = i.withGuide ?? settings.withGuide, u3 = `${symbol(this.state)} `, l2 = e ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(i.output, i.message, l2, u3), o2 = `${e ? `${styleText2("gray", S_BAR)}
1498
- ` : ""}${f2}
1499
- `, c2 = this.value ? a2 : s;
1500
- switch (this.state) {
1501
- case "submit": {
1502
- const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1503
- return `${o2}${r2}${styleText2("dim", c2)}`;
1504
- }
1505
- case "cancel": {
1506
- const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1507
- return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
1508
- ${styleText2("gray", S_BAR)}` : ""}`;
1509
- }
1510
- default: {
1511
- const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
1512
- return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${i.vertical ? e ? `
1513
- ${styleText2("cyan", S_BAR)} ` : `
1514
- ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
1515
- ${g2}
1516
- `;
1517
- }
1518
- }
1519
- }
1520
- }).prompt();
1521
- };
1522
1472
  var MULTISELECT_INSTRUCTIONS = [
1523
1473
  `${styleText2("dim", "↑/↓")} to navigate`,
1524
1474
  `${styleText2("dim", "Space:")} select`,
@@ -1941,7 +1891,6 @@ async function getCapabilitiesStats(repoPath = process.cwd(), homeDirPath = home
1941
1891
  // src/cli.ts
1942
1892
  import { writeFileSync, chmodSync, existsSync as existsSync2 } from "fs";
1943
1893
  import { join as join3 } from "path";
1944
- import os from "os";
1945
1894
  var ASCII_LOGO = `
1946
1895
  ____ _ _ _____ _ ___ _____ ____
1947
1896
  / __ \\| | | |_ _| | |_ _| ___| _ \\
@@ -1950,39 +1899,15 @@ var ASCII_LOGO = `
1950
1899
  | |__| | _ | | | | _ || || |___| | \\ \\
1951
1900
  \\____/|_| |_| |_| |_| |_|___|_____|_| \\_\\
1952
1901
  `;
1902
+ var finalReceipt = "";
1953
1903
  async function runOnboarding() {
1954
1904
  console.clear();
1955
1905
  console.log(import_picocolors.default.cyan(ASCII_LOGO));
1956
1906
  intro(import_picocolors.default.inverse(" outlier: Welcome "));
1957
- note(`Outlier is a local-first Policy Engine & Governance Framework for AI Engineering.
1958
-
1959
- Our mission is AI Safety for developers:
1960
- As agents (Cursor, Copilot, Claude) write more of our code, we lose visibility into:
1961
- 1. Deskilling Risk (Are we becoming spectators in our own codebase?)
1962
- 2. Carbon Cost (What is the true regional energy cost of token caching?)
1963
- 3. Capability Drift (What hidden skills and external tools are our agents using?)
1964
-
1965
- We built Outlier to enforce Zero-Trust and protect Human Mastery. You are in control.`, "The Problem: AI Safety in Development");
1966
1907
  note(`Outlier operates entirely on your machine.
1967
1908
  - Local Only: No API keys. No cloud telemetry. No data leaves your machine.
1968
- - Native Auditing: We only read your local \`~/.claude\` logs and \`.git/\` commit history.
1969
- - Actionable Policies: We enforce rules locally via terminal or Git pre-commit hooks.`, "Privacy & Zero-Trust Principles");
1970
- note(`Available Commands:
1971
- - status: Run a full system audit (Reliance, Carbon, Capabilities)
1972
- - policy: Configure team/enterprise guardrails and CLI blockers
1973
- - carbon: View isolated token caching metrics and regional counterfactuals
1974
- - authorship: View Git authorship ratio (Human vs AI)`, "How it is used");
1975
- note(`When you start the audit, Outlier will locally parse your Git commits to identify AI co-authorship and cross-reference your agent logs to calculate token waste.
1976
-
1977
- The results will assign you a "vibe" and evaluate if you are at risk of deskilling.`, "What to Expect");
1978
- const ready = await confirm({
1979
- message: "Are you ready to run your first Governance Audit and measure your AI reliance?",
1980
- initialValue: true
1981
- });
1982
- if (isCancel(ready) || !ready) {
1983
- cancel("Onboarding paused. Run outlier again when you are ready.");
1984
- process.exit(0);
1985
- }
1909
+ - Native Auditing: We read your local \`~/.claude\` logs and \`.git/\` commit history.
1910
+ - Actionable Policies: Enforce rules locally via terminal or Git hooks.`, "Privacy & Zero-Trust Principles");
1986
1911
  const configPath = join3(os.homedir(), ".outlier_config");
1987
1912
  writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
1988
1913
  }
@@ -2015,27 +1940,7 @@ COMMANDS:`));
2015
1940
  }
2016
1941
  intro(import_picocolors.default.inverse(" outlier "));
2017
1942
  if (!action || action === "audit") {
2018
- if (action !== "audit") {
2019
- action = await select({
2020
- message: "Select outlier governance module:",
2021
- options: [
2022
- { value: "status", label: "Status Report", hint: "Run full AI reliance and capability audit" },
2023
- { value: "capabilities", label: "Capabilities Map", hint: "Audit active MCPs, skills, and orchestrations" },
2024
- { value: "authorship", label: "Code Durability", hint: "Scan git history for AI Code Reliance & Hallucination Risk" },
2025
- { value: "carbon", label: "Cache Bloat", hint: "Scan local logs for context waste & token costs" },
2026
- { value: "policy", label: "Policy Profiles", hint: "Set Personal, Team, or Enterprise guardrails in CI" },
2027
- { value: "impact", label: "Impact Horizon", hint: "What do you lose and gain in the next 5-10 years?" },
2028
- { value: "knowledge", label: "Literature Base", hint: "Explore references and the core academic foundation" },
2029
- { value: "participate", label: "Participate", hint: "Contribute to the literature on AI deskilling" }
2030
- ]
2031
- });
2032
- if (isCancel(action)) {
2033
- cancel("Operation cancelled.");
2034
- process.exit(0);
2035
- }
2036
- } else {
2037
- action = "status";
2038
- }
1943
+ action = "status";
2039
1944
  }
2040
1945
  const s = spinner();
2041
1946
  if (action === "carbon") {
@@ -2202,7 +2107,7 @@ ${import_picocolors.default.bold("Governance:")} ${ruleFailures > 0 ? import_pic
2202
2107
  const dateStr = new Date().toLocaleDateString("en-US", { month: "short", day: "2-digit", year: "numeric" }).toUpperCase();
2203
2108
  const timeStr = new Date().toLocaleTimeString("en-US", { hour12: false });
2204
2109
  const repoName = process.cwd().split("/").pop() || "Unknown";
2205
- console.log(`
2110
+ finalReceipt = `
2206
2111
  ${import_picocolors.default.dim("┌────────────────────────────────────────────────────────")}
2207
2112
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█")} ${import_picocolors.default.bold(":: THERMAL AUDIT RECEIPT")}
2208
2113
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.cyan("█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄")} ${import_picocolors.default.dim(`:: TIMESTAMP: ${dateStr}`)}
@@ -2236,7 +2141,7 @@ ${import_picocolors.default.bold("Governance:")} ${ruleFailures > 0 ? import_pic
2236
2141
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.italic(import_picocolors.default.dim("human mastery is the only true moat."))}
2237
2142
  ${import_picocolors.default.dim("│")}
2238
2143
  ${import_picocolors.default.dim("│")} ${import_picocolors.default.bold(import_picocolors.default.cyan("***STAY VIGILANT***"))}
2239
- ${import_picocolors.default.dim("└────────────────────────────────────────────────────────")}`);
2144
+ ${import_picocolors.default.dim("└────────────────────────────────────────────────────────")}`;
2240
2145
  } else {
2241
2146
  note(`status: ${authPct} AI Reliance | ${cachePct}% Cache Bloat | ${co2Str}`, `${import_picocolors.default.bold("[outlier]")} CI/CD Audit`);
2242
2147
  }
@@ -2429,12 +2334,22 @@ Read the full academic foundation at: ${import_picocolors.default.underline("htt
2429
2334
  `);
2430
2335
  }
2431
2336
  outro("Local telemetry run completed. No data left your machine.");
2432
- console.log(import_picocolors.default.dim(`└ Share your audit: https://x.com/intent/tweet?text=${encodeURIComponent(`I just audited my codebase for AI reliance and deskilling risk. What does your repo score?
2337
+ if (typeof finalReceipt !== "undefined" && finalReceipt) {
2338
+ console.log(finalReceipt);
2339
+ }
2340
+ if (action === "status") {
2341
+ console.log("");
2342
+ console.log(import_picocolors.default.bold(" Explore Outlier:"));
2343
+ console.log(import_picocolors.default.dim(" ────────────────────────────────────────────────────────────"));
2344
+ console.log(` ${import_picocolors.default.cyan("outlier policy")} Configure CI/CD guardrails and thresholds`);
2345
+ console.log(` ${import_picocolors.default.cyan("outlier capabilities")} Audit active MCPs, skills, and orchestrations`);
2346
+ console.log(` ${import_picocolors.default.cyan("outlier impact")} See the compounding horizon of AI Deskilling`);
2347
+ console.log(` ${import_picocolors.default.cyan("outlier participate")} Help build the academic literature`);
2348
+ console.log(import_picocolors.default.dim(` ────────────────────────────────────────────────────────────
2349
+ `));
2350
+ console.log(import_picocolors.default.bold(import_picocolors.default.green(" └ Prove Your Mastery: ")) + import_picocolors.default.underline(`https://x.com/intent/tweet?text=${encodeURIComponent(`I just audited my codebase for AI reliance and deskilling risk. What does your repo score?
2433
2351
 
2434
2352
  \uD83D\uDCCF #Outlier`)}`));
2435
- if (action === "status") {
2436
- console.log(import_picocolors.default.dim(`└ Have thoughts on AI deskilling? Tell us: `) + import_picocolors.default.cyan(`outlier participate`));
2437
- console.log(import_picocolors.default.dim(`└ Keep your local policies updated: `) + import_picocolors.default.cyan(`outlier update`));
2438
2353
  }
2439
2354
  }
2440
2355
  main().catch(console.error);
@@ -9,9 +9,12 @@ console.log(dim('─────────────────────
9
9
  console.log('To start the interactive wizard and audit your codebase, type:\n');
10
10
  console.log(` ${cyan('outlier')}\n`);
11
11
  console.log('Available Commands:');
12
- console.log(` ${cyan('outlier status')} Print your Thermal Audit Receipt`);
13
- console.log(` ${cyan('outlier impact')} See the compounding horizon of AI Deskilling (What you lose/gain)`);
12
+ console.log(` ${cyan('outlier status')} Run full AI reliance & capability audit`);
13
+ console.log(` ${cyan('outlier authorship')} Scan git history for AI co-authorship ratio`);
14
+ console.log(` ${cyan('outlier carbon')} Scan local logs for token waste & carbon cost`);
15
+ console.log(` ${cyan('outlier capabilities')} Audit active MCPs, skills, and orchestrations`);
16
+ console.log(` ${cyan('outlier policy')} Configure CI/CD guardrails and thresholds`);
17
+ console.log(` ${cyan('outlier impact')} See the compounding horizon of AI Deskilling`);
14
18
  console.log(` ${cyan('outlier knowledge')} Explore core literature and METR references`);
15
19
  console.log(` ${cyan('outlier participate')} Help build the literature on AI deskilling`);
16
- console.log(` ${cyan('outlier help')} See all available commands`);
17
20
  console.log(dim('────────────────────────────────────────────────────────────\n'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosh100yx/outlier",
3
- "version": "0.4.10",
3
+ "version": "0.4.15",
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"
@@ -12,7 +12,7 @@
12
12
  "data"
13
13
  ],
14
14
  "scripts": {
15
- "build": "bun build ./src/cli.ts --target=node --outfile bin/outlier.js",
15
+ "build": "bunx tsc --noEmit && bun build ./src/cli.ts --target=node --outfile bin/outlier.js",
16
16
  "test": "bun test",
17
17
  "start": "bun run src/cli.ts",
18
18
  "postinstall": "node bin/postinstall.js"
package/src/cli.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import os from 'os';
2
3
  import { intro, outro, select, spinner, isCancel, cancel, note, text, confirm } from '@clack/prompts';
3
4
  import pc from 'picocolors';
4
5
  import { getAuthorshipStats } from './git';
@@ -6,7 +7,6 @@ import { getCarbonStats } from './carbon';
6
7
  import { getCapabilitiesStats } from './capabilities';
7
8
  import { writeFileSync, chmodSync, existsSync } from 'fs';
8
9
  import { join } from 'path';
9
- import { execSync } from 'child_process';
10
10
 
11
11
  const ASCII_LOGO = `
12
12
  ____ _ _ _____ _ ___ _____ ____
@@ -17,61 +17,21 @@ const ASCII_LOGO = `
17
17
  \\____/|_| |_| |_| |_| |_|___|_____|_| \\_\\
18
18
  `;
19
19
 
20
- import os from 'os';
21
- import { confirm } from '@clack/prompts';
20
+ let finalReceipt = '';
22
21
 
23
22
  async function runOnboarding() {
24
23
  console.clear();
25
24
  console.log(pc.cyan(ASCII_LOGO));
26
25
  intro(pc.inverse(' outlier: Welcome '));
27
26
 
28
- note(
29
- `Outlier is a local-first Policy Engine & Governance Framework for AI Engineering.
30
-
31
- Our mission is AI Safety for developers:
32
- As agents (Cursor, Copilot, Claude) write more of our code, we lose visibility into:
33
- 1. Deskilling Risk (Are we becoming spectators in our own codebase?)
34
- 2. Carbon Cost (What is the true regional energy cost of token caching?)
35
- 3. Capability Drift (What hidden skills and external tools are our agents using?)
36
-
37
- We built Outlier to enforce Zero-Trust and protect Human Mastery. You are in control.`,
38
- 'The Problem: AI Safety in Development'
39
- );
40
-
41
27
  note(
42
28
  `Outlier operates entirely on your machine.
43
29
  - Local Only: No API keys. No cloud telemetry. No data leaves your machine.
44
- - Native Auditing: We only read your local \`~/.claude\` logs and \`.git/\` commit history.
45
- - Actionable Policies: We enforce rules locally via terminal or Git pre-commit hooks.`,
30
+ - Native Auditing: We read your local \`~/.claude\` logs and \`.git/\` commit history.
31
+ - Actionable Policies: Enforce rules locally via terminal or Git hooks.`,
46
32
  'Privacy & Zero-Trust Principles'
47
33
  );
48
34
 
49
- note(
50
- `Available Commands:
51
- - status: Run a full system audit (Reliance, Carbon, Capabilities)
52
- - policy: Configure team/enterprise guardrails and CLI blockers
53
- - carbon: View isolated token caching metrics and regional counterfactuals
54
- - authorship: View Git authorship ratio (Human vs AI)`,
55
- 'How it is used'
56
- );
57
-
58
- note(
59
- `When you start the audit, Outlier will locally parse your Git commits to identify AI co-authorship and cross-reference your agent logs to calculate token waste.
60
-
61
- The results will assign you a "vibe" and evaluate if you are at risk of deskilling.`,
62
- 'What to Expect'
63
- );
64
-
65
- const ready = await confirm({
66
- message: 'Are you ready to run your first Governance Audit and measure your AI reliance?',
67
- initialValue: true,
68
- });
69
-
70
- if (isCancel(ready) || !ready) {
71
- cancel('Onboarding paused. Run outlier again when you are ready.');
72
- process.exit(0);
73
- }
74
-
75
35
  const configPath = join(os.homedir(), '.outlier_config');
76
36
  writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
77
37
  }
@@ -107,28 +67,7 @@ async function main() {
107
67
  intro(pc.inverse(' outlier '));
108
68
 
109
69
  if (!action || action === 'audit') {
110
- if (action !== 'audit') {
111
- action = await select({
112
- message: 'Select outlier governance module:',
113
- options: [
114
- { value: 'status', label: 'Status Report', hint: 'Run full AI reliance and capability audit' },
115
- { value: 'capabilities', label: 'Capabilities Map', hint: 'Audit active MCPs, skills, and orchestrations' },
116
- { value: 'authorship', label: 'Code Durability', hint: 'Scan git history for AI Code Reliance & Hallucination Risk' },
117
- { value: 'carbon', label: 'Cache Bloat', hint: 'Scan local logs for context waste & token costs' },
118
- { value: 'policy', label: 'Policy Profiles', hint: 'Set Personal, Team, or Enterprise guardrails in CI' },
119
- { value: 'impact', label: 'Impact Horizon', hint: 'What do you lose and gain in the next 5-10 years?' },
120
- { value: 'knowledge', label: 'Literature Base', hint: 'Explore references and the core academic foundation' },
121
- { value: 'participate', label: 'Participate', hint: 'Contribute to the literature on AI deskilling' }
122
- ],
123
- });
124
-
125
- if (isCancel(action)) {
126
- cancel('Operation cancelled.');
127
- process.exit(0);
128
- }
129
- } else {
130
- action = 'status'; // Map the 'audit' alias directly to status for CI
131
- }
70
+ action = 'status'; // Auto-run the main audit loop for highest TTV
132
71
  }
133
72
 
134
73
  const s = spinner();
@@ -323,7 +262,7 @@ ${pc.bold('Governance:')} ${ruleFailures > 0 ? pc.red(`${failIcon} ${ruleFailure
323
262
  const timeStr = new Date().toLocaleTimeString('en-US', { hour12: false });
324
263
  const repoName = process.cwd().split('/').pop() || 'Unknown';
325
264
 
326
- console.log(`
265
+ finalReceipt = `
327
266
  ${pc.dim('┌────────────────────────────────────────────────────────')}
328
267
  ${pc.dim('│')} ${pc.cyan('█▀█ █░█ ▀█▀ █░░ █ █▀▀ █▀█')} ${pc.bold(':: THERMAL AUDIT RECEIPT')}
329
268
  ${pc.dim('│')} ${pc.cyan('█▄█ █▄█ ░█░ █▄▄ █ ██▄ █▀▄')} ${pc.dim(`:: TIMESTAMP: ${dateStr}`)}
@@ -353,7 +292,7 @@ ${pc.bold('Governance:')} ${ruleFailures > 0 ? pc.red(`${failIcon} ${ruleFailure
353
292
  ${pc.dim('│')} ${pc.italic(pc.dim('human mastery is the only true moat.'))}
354
293
  ${pc.dim('│')}
355
294
  ${pc.dim('│')} ${pc.bold(pc.cyan('***STAY VIGILANT***'))}
356
- ${pc.dim('└────────────────────────────────────────────────────────')}`);
295
+ ${pc.dim('└────────────────────────────────────────────────────────')}`;
357
296
  } else {
358
297
  note(
359
298
  `status: ${authPct} AI Reliance | ${cachePct}% Cache Bloat | ${co2Str}`,
@@ -558,22 +497,22 @@ Artifact: ${pc.cyan(reportPath)}`,
558
497
 
559
498
  outro('Local telemetry run completed. No data left your machine.');
560
499
 
561
- // (Old artifact storytelling block removed to unify receipt UX)
562
-
563
- console.log(
564
- pc.dim(
565
- `└ Share your audit: https://x.com/intent/tweet?text=${encodeURIComponent(
566
- 'I just audited my codebase for AI reliance and deskilling risk. What does your repo score?\n\n📏 #Outlier'
567
- )}`
568
- )
569
- );
500
+ if (typeof finalReceipt !== 'undefined' && finalReceipt) {
501
+ console.log(finalReceipt);
502
+ }
570
503
 
571
504
  if (action === 'status') {
505
+ console.log('');
506
+ console.log(pc.bold(' Explore Outlier:'));
507
+ console.log(pc.dim(' ────────────────────────────────────────────────────────────'));
508
+ console.log(` ${pc.cyan('outlier policy')} Configure CI/CD guardrails and thresholds`);
509
+ console.log(` ${pc.cyan('outlier capabilities')} Audit active MCPs, skills, and orchestrations`);
510
+ console.log(` ${pc.cyan('outlier impact')} See the compounding horizon of AI Deskilling`);
511
+ console.log(` ${pc.cyan('outlier participate')} Help build the academic literature`);
512
+ console.log(pc.dim(' ────────────────────────────────────────────────────────────\n'));
513
+
572
514
  console.log(
573
- pc.dim(`└ Have thoughts on AI deskilling? Tell us: `) + pc.cyan(`outlier participate`)
574
- );
575
- console.log(
576
- pc.dim(`└ Keep your local policies updated: `) + pc.cyan(`outlier update`)
515
+ pc.bold(pc.green(' Prove Your Mastery: ')) + pc.underline(`https://x.com/intent/tweet?text=${encodeURIComponent('I just audited my codebase for AI reliance and deskilling risk. What does your repo score?\n\n📏 #Outlier')}`)
577
516
  );
578
517
  }
579
518
  }