@rosh100yx/outlier 0.3.1 → 0.4.0
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 +12 -5
- package/bin/outlier +0 -0
- package/package.json +3 -4
- package/src/cli.ts +104 -22
- package/bin/outlier.js +0 -14
package/README.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
<h1>outlier</h1>
|
|
4
4
|
<p><b>The Governance & Policy Engine for AI Engineering</b></p>
|
|
5
5
|
<p><i>Measure AI adoption. Enforce Zero-Trust. Protect Human Mastery.</i></p>
|
|
6
|
+
<br/>
|
|
7
|
+
<a href="https://github.com/rosh100yx/outlier/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.md&title=%5BFEATURE%5D+">
|
|
8
|
+
<img src="https://img.shields.io/badge/%E2%9C%A8_Feature_Request-Submit_an_idea-blueviolet?style=for-the-badge&logo=github" alt="Feature Request" />
|
|
9
|
+
</a>
|
|
6
10
|
|
|
7
11
|
<p>
|
|
8
12
|
<img src="https://img.shields.io/badge/Compliance-Strict-blue?style=for-the-badge" />
|
|
@@ -63,10 +67,13 @@
|
|
|
63
67
|
## Commands
|
|
64
68
|
| Command | Purpose |
|
|
65
69
|
|---------|---------|
|
|
66
|
-
| `outlier
|
|
67
|
-
| `outlier
|
|
68
|
-
| `outlier
|
|
69
|
-
| `outlier
|
|
70
|
+
| `outlier` | Start the interactive Onboarding Wizard (Recommended for first-timers) |
|
|
71
|
+
| `outlier --help` | View the CLI help menu and all available commands |
|
|
72
|
+
| `outlier status` | Run the full AI reliance & capability audit (Generates the Thermal Receipt) |
|
|
73
|
+
| `outlier authorship` | Scan git history for AI co-authorship ratio and Hallucination Risk |
|
|
74
|
+
| `outlier carbon` | Scan local logs for context waste & token costs |
|
|
75
|
+
| `outlier policy` | Configure Personal, Team, or Enterprise guardrails in CI |
|
|
76
|
+
| `outlier confessional` | Submit qualitative feedback or feature requests directly from the terminal |
|
|
70
77
|
|
|
71
78
|
## Quickstart: Your First Audit
|
|
72
79
|
|
|
@@ -100,7 +107,7 @@
|
|
|
100
107
|
## FAQ
|
|
101
108
|
|
|
102
109
|
**Does this send my code or prompts to the cloud?**
|
|
103
|
-
|
|
110
|
+
**Absolutely not.** `outlier` is built on a strict **Zero-Trust, Local-First Architecture**. It runs native parsing commands against your `.git/` history and your local `~/.claude/` session logs. It never calls an API, it never extracts your proprietary data, and it never phones home. Your research, your code, and your prompts stay 100% on your machine. We believe in open-source integrity.
|
|
104
111
|
|
|
105
112
|
**Do I need to be using a specific IDE?**
|
|
106
113
|
`outlier` is IDE-agnostic. It works by parsing standard `Co-Authored-By` Git trailers, meaning it supports Claude Code, Cursor, Aider, and manual generation.
|
package/bin/outlier
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rosh100yx/outlier",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
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
|
-
"outlier": "bin/outlier
|
|
6
|
+
"outlier": "bin/outlier"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
|
-
"bin/outlier
|
|
9
|
+
"bin/outlier",
|
|
10
10
|
"src",
|
|
11
11
|
"data"
|
|
12
12
|
],
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@clack/prompts": "^1.6.0",
|
|
45
|
-
"commander": "^15.0.0",
|
|
46
45
|
"picocolors": "^1.1.1"
|
|
47
46
|
}
|
|
48
47
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { intro, outro, select, spinner, isCancel, cancel, note } from '@clack/prompts';
|
|
2
|
+
import { intro, outro, select, spinner, isCancel, cancel, note, text } from '@clack/prompts';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import { getAuthorshipStats } from './git';
|
|
5
5
|
import { getCarbonStats } from './carbon';
|
|
6
6
|
import { getCapabilitiesStats } from './capabilities';
|
|
7
7
|
import { writeFileSync, chmodSync, existsSync } from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
+
import { execSync } from 'child_process';
|
|
9
10
|
|
|
10
11
|
const ASCII_LOGO = `
|
|
11
12
|
____ _ _ _____ _ ___ _____ ____
|
|
@@ -78,10 +79,22 @@ The results will assign you a "vibe" and evaluate if you are at risk of deskilli
|
|
|
78
79
|
async function main() {
|
|
79
80
|
console.clear();
|
|
80
81
|
console.log(pc.cyan(ASCII_LOGO));
|
|
81
|
-
console.log(pc.dim(' Outlier v0.
|
|
82
|
+
console.log(pc.dim(' Outlier v0.4.0 · AI Code Reliance & Telemetry Engine\n'));
|
|
82
83
|
|
|
83
84
|
let action = process.argv[2] as any;
|
|
84
85
|
|
|
86
|
+
if (action === '--help' || action === '-h' || action === 'help') {
|
|
87
|
+
console.log(pc.bold('\nCOMMANDS:'));
|
|
88
|
+
console.log(` ${pc.cyan('outlier')} Interactive menu (Onboarding for first-timers)`);
|
|
89
|
+
console.log(` ${pc.cyan('outlier status')} Run full AI reliance & capability audit`);
|
|
90
|
+
console.log(` ${pc.cyan('outlier authorship')} Scan git history for AI co-authorship ratio`);
|
|
91
|
+
console.log(` ${pc.cyan('outlier carbon')} Scan local logs for token waste & carbon cost`);
|
|
92
|
+
console.log(` ${pc.cyan('outlier policy')} Configure CI/CD guardrails and thresholds`);
|
|
93
|
+
console.log(` ${pc.cyan('outlier confessional')} Submit qualitative feedback or feature requests`);
|
|
94
|
+
console.log('\n' + pc.dim('Run without arguments to start the interactive wizard.'));
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
const configPath = join(os.homedir(), '.outlier_config');
|
|
86
99
|
if (!existsSync(configPath) && !action) {
|
|
87
100
|
await runOnboarding();
|
|
@@ -99,7 +112,8 @@ async function main() {
|
|
|
99
112
|
{ value: 'capabilities', label: 'Capabilities Map', hint: 'Audit active MCPs, skills, and orchestrations' },
|
|
100
113
|
{ value: 'authorship', label: 'Code Durability', hint: 'Scan git history for AI Code Reliance & Hallucination Risk' },
|
|
101
114
|
{ value: 'carbon', label: 'Cache Bloat', hint: 'Scan local logs for context waste & token costs' },
|
|
102
|
-
{ value: 'policy', label: 'Policy Profiles', hint: 'Set Personal, Team, or Enterprise guardrails in CI' }
|
|
115
|
+
{ value: 'policy', label: 'Policy Profiles', hint: 'Set Personal, Team, or Enterprise guardrails in CI' },
|
|
116
|
+
{ value: 'confessional', label: 'Confessional', hint: 'Tell us how AI is really affecting your job (Feature Requests)' }
|
|
103
117
|
],
|
|
104
118
|
});
|
|
105
119
|
|
|
@@ -137,15 +151,13 @@ Ratio: ~31x carbon penalty on coal-heavy grid`,
|
|
|
137
151
|
s.stop('Audit failed');
|
|
138
152
|
console.error(pc.red(e.message));
|
|
139
153
|
}
|
|
140
|
-
} else if (action === 'authorship'
|
|
141
|
-
s.start('Scanning local git history
|
|
142
|
-
|
|
154
|
+
} else if (action === 'authorship') {
|
|
155
|
+
s.start('Scanning local git history...');
|
|
143
156
|
try {
|
|
144
157
|
const gitStats = await getAuthorshipStats().catch(() => null);
|
|
145
|
-
const carbon = await getCarbonStats().catch(() => null);
|
|
146
158
|
s.stop('Audit complete');
|
|
147
159
|
|
|
148
|
-
if (
|
|
160
|
+
if (gitStats) {
|
|
149
161
|
const pct = (gitStats.ratio * 100).toFixed(1);
|
|
150
162
|
const nmPct = (gitStats.ratioNoMerges * 100).toFixed(1);
|
|
151
163
|
|
|
@@ -169,14 +181,53 @@ AI Co-Authored: ${gitStats.aiNoMerges}
|
|
|
169
181
|
Conservative Floor: ${color(nmPct + '%')}`,
|
|
170
182
|
'Git Authorship Breakdown'
|
|
171
183
|
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
184
|
+
}
|
|
185
|
+
} catch (e: any) {
|
|
186
|
+
s.stop('Audit failed');
|
|
187
|
+
console.error(pc.red(e.message));
|
|
188
|
+
}
|
|
189
|
+
} else if (action === 'status') {
|
|
190
|
+
const isStrict = process.argv.includes('--strict');
|
|
191
|
+
|
|
192
|
+
let gitStats: any = null;
|
|
193
|
+
let carbon: any = null;
|
|
194
|
+
let capabilities: any = null;
|
|
195
|
+
|
|
196
|
+
if (!isStrict) {
|
|
197
|
+
s.start('[SYSTEM] Booting local-first sandbox...');
|
|
198
|
+
await new Promise(r => setTimeout(r, 800));
|
|
199
|
+
s.message(`↳ Guarantee: No API calls. Your code and logs never leave this machine.`);
|
|
200
|
+
await new Promise(r => setTimeout(r, 1200));
|
|
201
|
+
|
|
202
|
+
s.message('[GIT] Scanning your commit history...');
|
|
203
|
+
gitStats = await getAuthorshipStats().catch(() => null);
|
|
204
|
+
await new Promise(r => setTimeout(r, 600));
|
|
205
|
+
s.message(`↳ Check: Are you writing the code, or just reviewing what the AI wrote?`);
|
|
206
|
+
await new Promise(r => setTimeout(r, 1200));
|
|
207
|
+
|
|
208
|
+
s.message('[TOKENS] Parsing local AI logs (~/.claude/)...');
|
|
209
|
+
carbon = await getCarbonStats().catch(() => null);
|
|
210
|
+
await new Promise(r => setTimeout(r, 600));
|
|
211
|
+
s.message(`↳ Check: How much API waste is your workflow generating locally?`);
|
|
212
|
+
await new Promise(r => setTimeout(r, 1200));
|
|
213
|
+
|
|
214
|
+
s.message('[ANALYSIS] Calculating your mastery score...');
|
|
215
|
+
capabilities = await getCapabilitiesStats().catch(() => null);
|
|
216
|
+
await new Promise(r => setTimeout(r, 600));
|
|
217
|
+
s.message(`↳ Warning: Heavy AI use creates the 'Illusion of Competence'. Don't lose your edge.`);
|
|
218
|
+
await new Promise(r => setTimeout(r, 1200));
|
|
219
|
+
|
|
220
|
+
s.message('[PRINT] Generating Thermal Receipt...');
|
|
221
|
+
await new Promise(r => setTimeout(r, 600));
|
|
222
|
+
} else {
|
|
223
|
+
s.start('Running outlier telemetry audit...');
|
|
224
|
+
gitStats = await getAuthorshipStats().catch(() => null);
|
|
225
|
+
carbon = await getCarbonStats().catch(() => null);
|
|
226
|
+
capabilities = await getCapabilitiesStats().catch(() => null);
|
|
227
|
+
}
|
|
228
|
+
s.stop('Audit complete');
|
|
229
|
+
|
|
230
|
+
try {
|
|
180
231
|
let authPct = '0%';
|
|
181
232
|
let ruleFailures = 0;
|
|
182
233
|
let authWarning = '';
|
|
@@ -231,7 +282,6 @@ ${costIcon}${pc.dim('[3] Tokenomics & Cost')} ${pc.magenta('▰▰▰▰▰▰
|
|
|
231
282
|
${pc.bold('Governance:')} ${ruleFailures > 0 ? pc.red(`${failIcon} ${ruleFailures + 1} policy failures`) : pc.green(`${passIcon} All clear`)}`,
|
|
232
283
|
`${pc.bold('[outlier]')} ${5 - (ruleFailures+1)}/5 policies • ${authWarning || pc.green(`${passIcon} safe surface`)} • ${co2Str}`
|
|
233
284
|
);
|
|
234
|
-
}
|
|
235
285
|
} catch (e: any) {
|
|
236
286
|
s.stop('Audit failed');
|
|
237
287
|
console.error(pc.red(e.message));
|
|
@@ -304,8 +354,8 @@ ${caps.skills.length > 5 ? pc.red('⚠ High Surface Area: Ensure strict authorsh
|
|
|
304
354
|
|
|
305
355
|
const isStrict = process.argv.includes('--strict');
|
|
306
356
|
const bouncerMsg = isStrict
|
|
307
|
-
? `echo "
|
|
308
|
-
: `echo "
|
|
357
|
+
? `echo "⚠️ outlier policy warning: AI authorship ($CURRENT_RATIO%) exceeds threshold ($MAX_RATIO%)"`
|
|
358
|
+
: `echo "🛡️ Outlier Bouncer: Repository AI-generation ($CURRENT_RATIO%) exceeds your defined mastery threshold ($MAX_RATIO%)."\n echo "Take a moment to review your recent architectural decisions. Ensure you still understand the system."`;
|
|
309
359
|
|
|
310
360
|
const hookPath = join(gitDir, 'hooks', 'pre-commit');
|
|
311
361
|
if (existsSync(hookPath)) {
|
|
@@ -323,10 +373,11 @@ if [ "$TOTAL" -eq 0 ]; then exit 0; fi
|
|
|
323
373
|
CURRENT_RATIO=$(awk "BEGIN {print ($AI / $TOTAL) * 100}")
|
|
324
374
|
MAX_RATIO=${maxAuthorship}
|
|
325
375
|
|
|
326
|
-
OVER_LIMIT=$(awk "BEGIN {
|
|
376
|
+
OVER_LIMIT=$(awk "BEGIN {print ($CURRENT_RATIO > $MAX_RATIO) ? 1 : 0}")
|
|
327
377
|
if [ "$OVER_LIMIT" -eq 1 ]; then
|
|
328
378
|
${bouncerMsg}
|
|
329
|
-
|
|
379
|
+
# Warn instead of hard-blocking the commit, protecting human iterations
|
|
380
|
+
exit 0
|
|
330
381
|
fi
|
|
331
382
|
echo "✅ Governance Policy OK"
|
|
332
383
|
`;
|
|
@@ -348,7 +399,7 @@ Enforcement: ${pc.cyan('Local pre-commit hook installed (backup created)')}`,
|
|
|
348
399
|
await new Promise(resolve => setTimeout(resolve, 1200));
|
|
349
400
|
|
|
350
401
|
const reportPath = join(process.cwd(), 'outlier-audit-report.jsonl');
|
|
351
|
-
writeFileSync(reportPath, JSON.stringify({ timestamp: new Date().toISOString(), status: '
|
|
402
|
+
writeFileSync(reportPath, JSON.stringify({ timestamp: new Date().toISOString(), status: 'PREVIEW', policy: 'Decree 142', simulatedOversight: true }) + '\n');
|
|
352
403
|
s.stop('Audit Generated');
|
|
353
404
|
|
|
354
405
|
note(
|
|
@@ -359,6 +410,37 @@ Artifact: ${pc.cyan(reportPath)}`,
|
|
|
359
410
|
'Regulatory Compliance'
|
|
360
411
|
);
|
|
361
412
|
}
|
|
413
|
+
} else if (action === 'confessional') {
|
|
414
|
+
s.start('Connecting to the human element...');
|
|
415
|
+
await new Promise(resolve => setTimeout(resolve, 600));
|
|
416
|
+
s.stop('Secure connection established.');
|
|
417
|
+
|
|
418
|
+
const feedback = await text({
|
|
419
|
+
message: pc.cyan('What is AI actually doing to your codebase? Are you a 10x dev or a 10x reviewer now?\n(Note: This will draft a public GitHub issue)'),
|
|
420
|
+
placeholder: 'Honestly, I just let the agent write the regex...',
|
|
421
|
+
validate(value) {
|
|
422
|
+
if (!value || value.length === 0) return `C'mon, confess something!`;
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
if (isCancel(feedback)) {
|
|
427
|
+
cancel('Confession aborted.');
|
|
428
|
+
process.exit(0);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
note(
|
|
432
|
+
`${pc.italic(`"${feedback}"`)}\n\nYour confession is safe with us. But if you want to make it official (and help us build what you need), we've generated a secure transmission link for you.`,
|
|
433
|
+
'The Confessional'
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
const url = `https://github.com/rosh100yx/outlier/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.md&title=%5BConfessional%5D+Feedback&body=${encodeURIComponent(feedback.toString())}`;
|
|
437
|
+
console.log(`\n${pc.bold('Submit here:')} ${pc.underline(pc.cyan(url))}\n`);
|
|
438
|
+
|
|
439
|
+
try {
|
|
440
|
+
if (process.platform === 'darwin') {
|
|
441
|
+
execSync(`open "${url}"`);
|
|
442
|
+
}
|
|
443
|
+
} catch(e) {}
|
|
362
444
|
}
|
|
363
445
|
|
|
364
446
|
outro('Local telemetry run completed. No data left your machine.');
|
package/bin/outlier.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from 'child_process';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
9
|
-
const cliPath = path.join(__dirname, '../src/cli.ts');
|
|
10
|
-
const result = spawnSync('bun', ['run', cliPath, ...process.argv.slice(2)], {
|
|
11
|
-
stdio: 'inherit'
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
process.exit(result.status || 0);
|