@rosh100yx/outlier 0.4.15 → 0.4.16

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
@@ -13,8 +13,7 @@
13
13
 
14
14
  <p>
15
15
  <b>Get Started Instantly:</b><br/>
16
- <code>npm install -g @rosh100yx/outlier</code><br/>
17
- <code>outlier status</code>
16
+ <code>npx @rosh100yx/outlier@latest</code>
18
17
  </p>
19
18
 
20
19
  <br/>
@@ -68,27 +67,26 @@
68
67
  ## Commands
69
68
  | Command | Purpose |
70
69
  |---------|---------|
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 |
74
- | `outlier carbon` | Scan local logs for context waste & token costs |
75
- | `outlier capabilities` | Audit active MCPs, skills, and orchestrations |
76
- | `outlier policy` | Configure Personal, Team, or Enterprise guardrails in CI |
77
-
78
- ### Interactive Menu
79
- If you run `outlier` directly, you'll be greeted with our frictionless UX:
70
+ | `npx @rosh100yx/outlier` | Run the full AI reliance & capability audit |
71
+ | `npx @rosh100yx/outlier authorship` | Scan git history for AI co-authorship ratio |
72
+ | `npx @rosh100yx/outlier carbon` | Scan local logs for context waste & token costs |
73
+ | `npx @rosh100yx/outlier capabilities` | Audit active MCPs, skills, and orchestrations |
74
+ | `npx @rosh100yx/outlier policy` | Configure Personal, Team, or Enterprise guardrails in CI |
75
+
76
+ ### The UX Flow
77
+ If you run `npx @rosh100yx/outlier` directly, you'll instantly get your Thermal Receipt and a simple list of follow-up commands:
80
78
  ```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
79
+ └────────────────────────────────────────────────────────┘
80
+
81
+ Explore Outlier:
82
+ ────────────────────────────────────────────────────────────
83
+ outlier policy Configure CI/CD guardrails and thresholds
84
+ outlier capabilities Audit active MCPs, skills, and orchestrations
85
+ outlier impact See the compounding horizon of AI Deskilling
86
+ outlier participate Help build the academic literature
87
+ ────────────────────────────────────────────────────────────
88
+
89
+ Prove Your Mastery: https://x.com/intent/tweet?...
92
90
  ```
93
91
 
94
92
  ## Quickstart: Your First Audit
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.15",
168
+ version: "0.4.16",
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"
@@ -943,16 +943,34 @@ var T$1 = class T extends V {
943
943
  }
944
944
  }
945
945
  };
946
+
947
+ class r extends V {
948
+ get cursor() {
949
+ return this.value ? 0 : 1;
950
+ }
951
+ get _value() {
952
+ return this.cursor === 0;
953
+ }
954
+ constructor(t2) {
955
+ super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
956
+ this.value = this._value;
957
+ }), this.on("confirm", (i) => {
958
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
959
+ }), this.on("cursor", () => {
960
+ this.value = !this.value;
961
+ });
962
+ }
963
+ }
946
964
  var _ = {
947
965
  Y: { type: "year", len: 4 },
948
966
  M: { type: "month", len: 2 },
949
967
  D: { type: "day", len: 2 }
950
968
  };
951
- function M(r) {
952
- return [...r].map((t2) => _[t2]);
969
+ function M(r2) {
970
+ return [...r2].map((t2) => _[t2]);
953
971
  }
954
- function P(r) {
955
- const i = new Intl.DateTimeFormat(r, {
972
+ function P(r2) {
973
+ const i = new Intl.DateTimeFormat(r2, {
956
974
  year: "numeric",
957
975
  month: "2-digit",
958
976
  day: "2-digit"
@@ -962,32 +980,32 @@ function P(r) {
962
980
  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 });
963
981
  return { segments: s, separator: n };
964
982
  }
965
- function p(r) {
966
- return Number.parseInt((r || "0").replace(/_/g, "0"), 10) || 0;
983
+ function p(r2) {
984
+ return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
967
985
  }
968
- function f(r) {
986
+ function f(r2) {
969
987
  return {
970
- year: p(r.year),
971
- month: p(r.month),
972
- day: p(r.day)
988
+ year: p(r2.year),
989
+ month: p(r2.month),
990
+ day: p(r2.day)
973
991
  };
974
992
  }
975
- function c(r, t2) {
976
- return new Date(r || 2001, t2 || 1, 0).getDate();
993
+ function c(r2, t2) {
994
+ return new Date(r2 || 2001, t2 || 1, 0).getDate();
977
995
  }
978
- function b(r) {
979
- const { year: t2, month: i, day: s } = f(r);
996
+ function b(r2) {
997
+ const { year: t2, month: i, day: s } = f(r2);
980
998
  if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
981
999
  return;
982
1000
  const n = new Date(Date.UTC(t2, i - 1, s));
983
1001
  if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
984
1002
  return { year: t2, month: i, day: s };
985
1003
  }
986
- function C(r) {
987
- const t2 = b(r);
1004
+ function C(r2) {
1005
+ const t2 = b(r2);
988
1006
  return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
989
1007
  }
990
- function T2(r, t2, i, s) {
1008
+ function T2(r2, t2, i, s) {
991
1009
  const n = i ? {
992
1010
  year: i.getUTCFullYear(),
993
1011
  month: i.getUTCMonth() + 1,
@@ -997,7 +1015,7 @@ function T2(r, t2, i, s) {
997
1015
  month: s.getUTCMonth() + 1,
998
1016
  day: s.getUTCDate()
999
1017
  } : null;
1000
- return r === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r === "month" ? {
1018
+ return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
1001
1019
  min: n && t2.year === n.year ? n.month : 1,
1002
1020
  max: e && t2.year === e.year ? e.month : 12
1003
1021
  } : {
@@ -1170,26 +1188,26 @@ var u$1 = class u extends V {
1170
1188
  cursor = 0;
1171
1189
  #t;
1172
1190
  getGroupItems(t2) {
1173
- return this.options.filter((r) => r.group === t2);
1191
+ return this.options.filter((r2) => r2.group === t2);
1174
1192
  }
1175
1193
  isGroupSelected(t2) {
1176
- const r = this.getGroupItems(t2), e = this.value;
1177
- return e === undefined ? false : r.every((s) => e.includes(s.value));
1194
+ const r2 = this.getGroupItems(t2), e = this.value;
1195
+ return e === undefined ? false : r2.every((s) => e.includes(s.value));
1178
1196
  }
1179
1197
  toggleValue() {
1180
1198
  const t2 = this.options[this.cursor];
1181
1199
  if (this.value === undefined && (this.value = []), t2.group === true) {
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));
1200
+ const r2 = t2.value, e = this.getGroupItems(r2);
1201
+ 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));
1184
1202
  } else {
1185
- const r = this.value.includes(t2.value);
1186
- this.value = r ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1203
+ const r2 = this.value.includes(t2.value);
1204
+ this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1187
1205
  }
1188
1206
  }
1189
1207
  constructor(t2) {
1190
1208
  super(t2, false);
1191
- const { options: r } = t2;
1192
- this.#t = t2.selectableGroups !== false, this.options = Object.entries(r).flatMap(([e, s]) => [
1209
+ const { options: r2 } = t2;
1210
+ this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
1193
1211
  { value: e, group: true, label: e },
1194
1212
  ...s.map((i) => ({ ...i, group: e }))
1195
1213
  ]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
@@ -1227,10 +1245,10 @@ class h extends V {
1227
1245
  const t2 = this.userInput;
1228
1246
  if (this.cursor >= t2.length)
1229
1247
  return `${t2}█`;
1230
- const s = t2.slice(0, this.cursor), r = t2[this.cursor], i = t2.slice(this.cursor + 1);
1231
- return r === `
1248
+ const s = t2.slice(0, this.cursor), r2 = t2[this.cursor], i = t2.slice(this.cursor + 1);
1249
+ return r2 === `
1232
1250
  ` ? `${s}█
1233
- ${i}` : `${s}${styleText("inverse", r)}${i}`;
1251
+ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1234
1252
  }
1235
1253
  get cursor() {
1236
1254
  return this._cursor;
@@ -1263,8 +1281,8 @@ ${i}` : `${s}${styleText("inverse", r)}${i}`;
1263
1281
  if (this.#s)
1264
1282
  return this.focused === "submit" ? true : (this.#r(`
1265
1283
  `), this._cursor++, false);
1266
- const r = this.#t;
1267
- return this.#t = true, r && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1284
+ const r2 = this.#t;
1285
+ return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1268
1286
  ` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
1269
1287
  `), this._cursor++, false);
1270
1288
  }
@@ -1273,12 +1291,12 @@ ${i}` : `${s}${styleText("inverse", r)}${i}`;
1273
1291
  super({
1274
1292
  ...t2,
1275
1293
  initialUserInput: s
1276
- }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r, i) => {
1294
+ }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
1277
1295
  if (i?.name && o$1.has(i.name)) {
1278
1296
  this.#t = false, this.#i(i.name);
1279
1297
  return;
1280
1298
  }
1281
- if (r === "\t" && this.#s) {
1299
+ if (r2 === "\t" && this.#s) {
1282
1300
  this.focused = this.focused === "editor" ? "submit" : "editor";
1283
1301
  return;
1284
1302
  }
@@ -1291,10 +1309,10 @@ ${i}` : `${s}${styleText("inverse", r)}${i}`;
1291
1309
  this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
1292
1310
  return;
1293
1311
  }
1294
- r && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r ?? ""), this._cursor++);
1312
+ r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
1295
1313
  }
1296
- }), this.on("userInput", (r) => {
1297
- this._setValue(r);
1314
+ }), this.on("userInput", (r2) => {
1315
+ this._setValue(r2);
1298
1316
  }), this.on("finalize", () => {
1299
1317
  this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
1300
1318
  });
@@ -1334,8 +1352,8 @@ class n extends V {
1334
1352
  const t2 = this.userInput;
1335
1353
  if (this.cursor >= t2.length)
1336
1354
  return `${this.userInput}█`;
1337
- const e = t2.slice(0, this.cursor), [s, ...r] = t2.slice(this.cursor);
1338
- return `${e}${styleText("inverse", s)}${r.join("")}`;
1355
+ const e = t2.slice(0, this.cursor), [s, ...r2] = t2.slice(this.cursor);
1356
+ return `${e}${styleText("inverse", s)}${r2.join("")}`;
1339
1357
  }
1340
1358
  get cursor() {
1341
1359
  return this._cursor;
@@ -1469,6 +1487,41 @@ var limitOptions = ({
1469
1487
  b2.push(n2);
1470
1488
  return u3 && b2.push(C2), b2;
1471
1489
  };
1490
+ var confirm = (i) => {
1491
+ const a2 = i.active ?? "Yes", s = i.inactive ?? "No";
1492
+ return new r({
1493
+ active: a2,
1494
+ inactive: s,
1495
+ signal: i.signal,
1496
+ input: i.input,
1497
+ output: i.output,
1498
+ initialValue: i.initialValue ?? true,
1499
+ render() {
1500
+ 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)}
1501
+ ` : ""}${f2}
1502
+ `, c2 = this.value ? a2 : s;
1503
+ switch (this.state) {
1504
+ case "submit": {
1505
+ const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1506
+ return `${o2}${r2}${styleText2("dim", c2)}`;
1507
+ }
1508
+ case "cancel": {
1509
+ const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1510
+ return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
1511
+ ${styleText2("gray", S_BAR)}` : ""}`;
1512
+ }
1513
+ default: {
1514
+ const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
1515
+ return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${i.vertical ? e ? `
1516
+ ${styleText2("cyan", S_BAR)} ` : `
1517
+ ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
1518
+ ${g2}
1519
+ `;
1520
+ }
1521
+ }
1522
+ }
1523
+ }).prompt();
1524
+ };
1472
1525
  var MULTISELECT_INSTRUCTIONS = [
1473
1526
  `${styleText2("dim", "↑/↓")} to navigate`,
1474
1527
  `${styleText2("dim", "Space:")} select`,
@@ -1904,10 +1957,24 @@ async function runOnboarding() {
1904
1957
  console.clear();
1905
1958
  console.log(import_picocolors.default.cyan(ASCII_LOGO));
1906
1959
  intro(import_picocolors.default.inverse(" outlier: Welcome "));
1960
+ note(`Outlier is a local-first Policy Engine & Governance Framework for AI Engineering.
1961
+
1962
+ As agents write more of our code, we lose visibility into:
1963
+ 1. Deskilling Risk (Are we becoming spectators in our own codebase?)
1964
+ 2. Carbon Cost (What is the true regional energy cost of token caching?)
1965
+ 3. Capability Drift (What hidden skills are our agents using?)`, "The Problem: AI Safety in Development");
1907
1966
  note(`Outlier operates entirely on your machine.
1908
1967
  - Local Only: No API keys. No cloud telemetry. No data leaves your machine.
1909
1968
  - Native Auditing: We read your local \`~/.claude\` logs and \`.git/\` commit history.
1910
1969
  - Actionable Policies: Enforce rules locally via terminal or Git hooks.`, "Privacy & Zero-Trust Principles");
1970
+ const ready = await confirm({
1971
+ message: "Are you ready to run your first Governance Audit and generate your Thermal Receipt?",
1972
+ initialValue: true
1973
+ });
1974
+ if (isCancel(ready) || !ready) {
1975
+ cancel("Onboarding paused. Run outlier again when you are ready.");
1976
+ process.exit(0);
1977
+ }
1911
1978
  const configPath = join3(os.homedir(), ".outlier_config");
1912
1979
  writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
1913
1980
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosh100yx/outlier",
3
- "version": "0.4.15",
3
+ "version": "0.4.16",
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/cli.ts CHANGED
@@ -24,6 +24,16 @@ async function runOnboarding() {
24
24
  console.log(pc.cyan(ASCII_LOGO));
25
25
  intro(pc.inverse(' outlier: Welcome '));
26
26
 
27
+ note(
28
+ `Outlier is a local-first Policy Engine & Governance Framework for AI Engineering.
29
+
30
+ As agents write more of our code, we lose visibility into:
31
+ 1. Deskilling Risk (Are we becoming spectators in our own codebase?)
32
+ 2. Carbon Cost (What is the true regional energy cost of token caching?)
33
+ 3. Capability Drift (What hidden skills are our agents using?)`,
34
+ 'The Problem: AI Safety in Development'
35
+ );
36
+
27
37
  note(
28
38
  `Outlier operates entirely on your machine.
29
39
  - Local Only: No API keys. No cloud telemetry. No data leaves your machine.
@@ -32,6 +42,16 @@ async function runOnboarding() {
32
42
  'Privacy & Zero-Trust Principles'
33
43
  );
34
44
 
45
+ const ready = await confirm({
46
+ message: 'Are you ready to run your first Governance Audit and generate your Thermal Receipt?',
47
+ initialValue: true,
48
+ });
49
+
50
+ if (isCancel(ready) || !ready) {
51
+ cancel('Onboarding paused. Run outlier again when you are ready.');
52
+ process.exit(0);
53
+ }
54
+
35
55
  const configPath = join(os.homedir(), '.outlier_config');
36
56
  writeFileSync(configPath, JSON.stringify({ onboarded: true, date: new Date().toISOString() }));
37
57
  }