no-ai-slop 0.1.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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * CLI Display
3
+ *
4
+ * Formats and displays analysis results in the terminal
5
+ */
6
+ import type { AnalysisResult } from './uploader.js';
7
+ /**
8
+ * Display the analysis results
9
+ */
10
+ export declare function displayResults(result: AnalysisResult): void;
11
+ /**
12
+ * Display privacy notice
13
+ */
14
+ export declare function displayPrivacyNotice(): void;
15
+ /**
16
+ * Display error message
17
+ */
18
+ export declare function displayError(message: string): void;
19
+ /**
20
+ * Display no sessions found message
21
+ */
22
+ export declare function displayNoSessions(): void;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * CLI Display
3
+ *
4
+ * Formats and displays analysis results in the terminal
5
+ */
6
+ import pc from 'picocolors';
7
+ import boxen from 'boxen';
8
+ const TYPE_COLORS = {
9
+ architect: pc.blue,
10
+ scientist: pc.green,
11
+ collaborator: pc.yellow,
12
+ speedrunner: pc.red,
13
+ craftsman: pc.magenta,
14
+ };
15
+ const TYPE_EMOJIS = {
16
+ architect: '🏛️',
17
+ scientist: '🔬',
18
+ collaborator: '🤝',
19
+ speedrunner: '⚡',
20
+ craftsman: '🔧',
21
+ };
22
+ /**
23
+ * Create a progress bar
24
+ */
25
+ function progressBar(value, width = 10) {
26
+ const filled = Math.round((value / 100) * width);
27
+ const empty = width - filled;
28
+ return pc.green('█'.repeat(filled)) + pc.dim('░'.repeat(empty));
29
+ }
30
+ /**
31
+ * Format the type name for display
32
+ */
33
+ function formatTypeName(type) {
34
+ const colorFn = TYPE_COLORS[type.toLowerCase()] || pc.white;
35
+ const emoji = TYPE_EMOJIS[type.toLowerCase()] || '🎯';
36
+ return `${emoji} ${colorFn(type.toUpperCase())}`;
37
+ }
38
+ /**
39
+ * Display the analysis results
40
+ */
41
+ export function displayResults(result) {
42
+ const lines = [];
43
+ // Header
44
+ lines.push(pc.bold(`Your AI Collaboration Type: ${formatTypeName(result.primaryType)}`));
45
+ lines.push('');
46
+ // Distribution bars
47
+ const types = ['architect', 'scientist', 'collaborator', 'speedrunner', 'craftsman'];
48
+ for (const type of types) {
49
+ const value = result.distribution[type];
50
+ const label = type.charAt(0).toUpperCase() + type.slice(1);
51
+ const bar = progressBar(value);
52
+ lines.push(`${pc.dim(label.padEnd(12))} ${bar} ${pc.dim(`${value}%`)}`);
53
+ }
54
+ lines.push('');
55
+ lines.push(pc.dim('─'.repeat(45)));
56
+ lines.push('');
57
+ // Summary (truncated for CLI)
58
+ const summaryLines = result.personalitySummary.split('\n');
59
+ const truncatedSummary = summaryLines.slice(0, 3).join('\n');
60
+ lines.push(pc.italic(truncatedSummary));
61
+ if (summaryLines.length > 3) {
62
+ lines.push(pc.dim('...'));
63
+ }
64
+ lines.push('');
65
+ lines.push(pc.dim('─'.repeat(45)));
66
+ lines.push('');
67
+ // Report link
68
+ lines.push(`📊 ${pc.bold('Full Report:')} ${pc.cyan(pc.underline(result.reportUrl))}`);
69
+ const box = boxen(lines.join('\n'), {
70
+ padding: 1,
71
+ margin: 1,
72
+ borderStyle: 'round',
73
+ borderColor: 'cyan',
74
+ });
75
+ console.log(box);
76
+ }
77
+ /**
78
+ * Display privacy notice
79
+ */
80
+ export function displayPrivacyNotice() {
81
+ console.log('');
82
+ console.log(pc.dim('🔒 Your data is analyzed and immediately deleted.'));
83
+ console.log(pc.dim(' We only keep the results, never your conversations.'));
84
+ console.log('');
85
+ }
86
+ /**
87
+ * Display error message
88
+ */
89
+ export function displayError(message) {
90
+ console.log('');
91
+ console.log(pc.red(`❌ Error: ${message}`));
92
+ console.log('');
93
+ }
94
+ /**
95
+ * Display no sessions found message
96
+ */
97
+ export function displayNoSessions() {
98
+ console.log('');
99
+ console.log(pc.yellow('⚠️ No Claude Code sessions found.'));
100
+ console.log('');
101
+ console.log(pc.dim(' Make sure you have used Claude Code and have sessions in:'));
102
+ console.log(pc.dim(' ~/.claude/projects/'));
103
+ console.log('');
104
+ }
105
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * no-ai-slop CLI
4
+ *
5
+ * Analyze your AI collaboration style with Claude Code
6
+ */
7
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * no-ai-slop CLI
4
+ *
5
+ * Analyze your AI collaboration style with Claude Code
6
+ */
7
+ import { createInterface } from 'node:readline';
8
+ import pc from 'picocolors';
9
+ import ora from 'ora';
10
+ import { scanSessions, hasClaudeProjects } from './scanner.js';
11
+ import { uploadForAnalysis } from './uploader.js';
12
+ import { displayResults, displayPrivacyNotice, displayError, displayNoSessions, } from './display.js';
13
+ /**
14
+ * Prompt user for confirmation
15
+ */
16
+ async function confirm(message) {
17
+ const rl = createInterface({
18
+ input: process.stdin,
19
+ output: process.stdout,
20
+ });
21
+ return new Promise((resolve) => {
22
+ rl.question(`${message} (Y/n): `, (answer) => {
23
+ rl.close();
24
+ const normalized = answer.trim().toLowerCase();
25
+ resolve(normalized === '' || normalized === 'y' || normalized === 'yes');
26
+ });
27
+ });
28
+ }
29
+ /**
30
+ * Main CLI entry point
31
+ */
32
+ async function main() {
33
+ console.log('');
34
+ console.log(pc.bold(pc.cyan('🚀 no-ai-slop')) + pc.dim(' - AI Collaboration Style Analyzer'));
35
+ console.log('');
36
+ // Check if Claude projects directory exists
37
+ const hasProjects = await hasClaudeProjects();
38
+ if (!hasProjects) {
39
+ displayNoSessions();
40
+ process.exit(1);
41
+ }
42
+ // Scan for sessions
43
+ const scanSpinner = ora('Scanning Claude Code sessions...').start();
44
+ let scanResult;
45
+ try {
46
+ scanResult = await scanSessions(10);
47
+ }
48
+ catch (error) {
49
+ scanSpinner.fail('Failed to scan sessions');
50
+ displayError(error instanceof Error ? error.message : 'Unknown error');
51
+ process.exit(1);
52
+ }
53
+ if (scanResult.sessions.length === 0) {
54
+ scanSpinner.stop();
55
+ displayNoSessions();
56
+ process.exit(1);
57
+ }
58
+ scanSpinner.succeed(`Found ${pc.bold(String(scanResult.sessions.length))} sessions ` +
59
+ `(${pc.dim(`${scanResult.totalMessages} interactions`)})`);
60
+ // Show privacy notice and ask for consent
61
+ displayPrivacyNotice();
62
+ const consent = await confirm('Proceed with analysis?');
63
+ if (!consent) {
64
+ console.log(pc.dim('\nAnalysis cancelled.'));
65
+ process.exit(0);
66
+ }
67
+ // Upload and analyze
68
+ const analyzeSpinner = ora('Analyzing your AI collaboration style...').start();
69
+ try {
70
+ const result = await uploadForAnalysis(scanResult);
71
+ analyzeSpinner.succeed('Analysis complete!');
72
+ // Display results
73
+ displayResults(result);
74
+ }
75
+ catch (error) {
76
+ analyzeSpinner.fail('Analysis failed');
77
+ displayError(error instanceof Error ? error.message : 'Unknown error');
78
+ process.exit(1);
79
+ }
80
+ }
81
+ // Run
82
+ main().catch((error) => {
83
+ displayError(error instanceof Error ? error.message : 'Unknown error');
84
+ process.exit(1);
85
+ });
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Session Scanner
3
+ *
4
+ * Scans ~/.claude/projects/ for Claude Code session logs
5
+ * and extracts data for analysis.
6
+ */
7
+ export declare const CLAUDE_PROJECTS_DIR: string;
8
+ export interface SessionMetadata {
9
+ sessionId: string;
10
+ projectPath: string;
11
+ projectName: string;
12
+ timestamp: Date;
13
+ messageCount: number;
14
+ durationSeconds: number;
15
+ filePath: string;
16
+ }
17
+ export interface SessionData {
18
+ metadata: SessionMetadata;
19
+ content: string;
20
+ }
21
+ export interface ScanResult {
22
+ sessions: SessionData[];
23
+ totalMessages: number;
24
+ totalDurationMinutes: number;
25
+ }
26
+ /**
27
+ * Scan all sessions and select the best ones for analysis
28
+ */
29
+ export declare function scanSessions(maxSessions?: number): Promise<ScanResult>;
30
+ /**
31
+ * Check if Claude projects directory exists
32
+ */
33
+ export declare function hasClaudeProjects(): Promise<boolean>;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Session Scanner
3
+ *
4
+ * Scans ~/.claude/projects/ for Claude Code session logs
5
+ * and extracts data for analysis.
6
+ */
7
+ import { readFile, readdir, stat } from 'node:fs/promises';
8
+ import { join, basename } from 'node:path';
9
+ import { homedir } from 'node:os';
10
+ export const CLAUDE_PROJECTS_DIR = join(homedir(), '.claude', 'projects');
11
+ /**
12
+ * Decode project path from Claude's encoding
13
+ * Claude encodes paths by replacing '/' with '-'
14
+ */
15
+ function decodeProjectPath(encoded) {
16
+ if (encoded.startsWith('-')) {
17
+ return encoded.replace(/-/g, '/');
18
+ }
19
+ return encoded;
20
+ }
21
+ /**
22
+ * Get project name from path
23
+ */
24
+ function getProjectName(projectPath) {
25
+ const parts = projectPath.split('/').filter(Boolean);
26
+ return parts[parts.length - 1] || 'unknown';
27
+ }
28
+ /**
29
+ * Parse a single line of JSONL to extract basic info
30
+ */
31
+ function parseJSONLLine(line) {
32
+ const trimmed = line.trim();
33
+ if (!trimmed)
34
+ return null;
35
+ try {
36
+ const parsed = JSON.parse(trimmed);
37
+ return {
38
+ type: parsed.type,
39
+ timestamp: parsed.timestamp,
40
+ };
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Get metadata for a session file
48
+ */
49
+ async function getSessionMetadata(filePath) {
50
+ try {
51
+ const content = await readFile(filePath, 'utf-8');
52
+ const lines = content.split('\n').filter(l => l.trim());
53
+ if (lines.length === 0)
54
+ return null;
55
+ const fileName = basename(filePath, '.jsonl');
56
+ let messageCount = 0;
57
+ let firstTimestamp = null;
58
+ let lastTimestamp = null;
59
+ for (const line of lines) {
60
+ const parsed = parseJSONLLine(line);
61
+ if (parsed && (parsed.type === 'user' || parsed.type === 'assistant')) {
62
+ messageCount++;
63
+ if (parsed.timestamp) {
64
+ const ts = new Date(parsed.timestamp);
65
+ if (!firstTimestamp || ts < firstTimestamp)
66
+ firstTimestamp = ts;
67
+ if (!lastTimestamp || ts > lastTimestamp)
68
+ lastTimestamp = ts;
69
+ }
70
+ }
71
+ }
72
+ if (!firstTimestamp || !lastTimestamp)
73
+ return null;
74
+ const projectDirName = basename(join(filePath, '..'));
75
+ const projectPath = decodeProjectPath(projectDirName);
76
+ const durationSeconds = Math.floor((lastTimestamp.getTime() - firstTimestamp.getTime()) / 1000);
77
+ return {
78
+ sessionId: fileName,
79
+ projectPath,
80
+ projectName: getProjectName(projectPath),
81
+ timestamp: firstTimestamp,
82
+ messageCount,
83
+ durationSeconds,
84
+ filePath,
85
+ };
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ /**
92
+ * List all project directories
93
+ */
94
+ async function listProjectDirs() {
95
+ try {
96
+ const entries = await readdir(CLAUDE_PROJECTS_DIR);
97
+ const dirs = [];
98
+ for (const entry of entries) {
99
+ const fullPath = join(CLAUDE_PROJECTS_DIR, entry);
100
+ try {
101
+ const stats = await stat(fullPath);
102
+ if (stats.isDirectory()) {
103
+ dirs.push(fullPath);
104
+ }
105
+ }
106
+ catch {
107
+ // Skip inaccessible entries
108
+ }
109
+ }
110
+ return dirs;
111
+ }
112
+ catch {
113
+ return [];
114
+ }
115
+ }
116
+ /**
117
+ * List session files in a directory
118
+ */
119
+ async function listSessionFiles(projectDir) {
120
+ try {
121
+ const files = await readdir(projectDir);
122
+ return files
123
+ .filter(f => f.endsWith('.jsonl'))
124
+ .map(f => join(projectDir, f));
125
+ }
126
+ catch {
127
+ return [];
128
+ }
129
+ }
130
+ /**
131
+ * Scan all sessions and select the best ones for analysis
132
+ */
133
+ export async function scanSessions(maxSessions = 10) {
134
+ const projectDirs = await listProjectDirs();
135
+ const allMetadata = [];
136
+ for (const dir of projectDirs) {
137
+ const files = await listSessionFiles(dir);
138
+ for (const file of files) {
139
+ const metadata = await getSessionMetadata(file);
140
+ if (metadata && metadata.messageCount >= 5) {
141
+ allMetadata.push(metadata);
142
+ }
143
+ }
144
+ }
145
+ // Sort by duration (longer sessions first) then by recency
146
+ allMetadata.sort((a, b) => {
147
+ const durationDiff = b.durationSeconds - a.durationSeconds;
148
+ if (Math.abs(durationDiff) > 60)
149
+ return durationDiff;
150
+ return b.timestamp.getTime() - a.timestamp.getTime();
151
+ });
152
+ // Select top sessions
153
+ const selected = allMetadata.slice(0, maxSessions);
154
+ // Read content for selected sessions
155
+ const sessions = [];
156
+ let totalMessages = 0;
157
+ let totalDurationMinutes = 0;
158
+ for (const metadata of selected) {
159
+ try {
160
+ const content = await readFile(metadata.filePath, 'utf-8');
161
+ sessions.push({ metadata, content });
162
+ totalMessages += metadata.messageCount;
163
+ totalDurationMinutes += Math.round(metadata.durationSeconds / 60);
164
+ }
165
+ catch {
166
+ // Skip unreadable files
167
+ }
168
+ }
169
+ return {
170
+ sessions,
171
+ totalMessages,
172
+ totalDurationMinutes,
173
+ };
174
+ }
175
+ /**
176
+ * Check if Claude projects directory exists
177
+ */
178
+ export async function hasClaudeProjects() {
179
+ try {
180
+ await stat(CLAUDE_PROJECTS_DIR);
181
+ return true;
182
+ }
183
+ catch {
184
+ return false;
185
+ }
186
+ }
187
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Server Uploader
3
+ *
4
+ * Handles communication with the NoMoreAISlop server
5
+ */
6
+ import type { ScanResult } from './scanner.js';
7
+ export interface AnalysisResult {
8
+ resultId: string;
9
+ primaryType: string;
10
+ controlLevel: string;
11
+ distribution: {
12
+ architect: number;
13
+ scientist: number;
14
+ collaborator: number;
15
+ speedrunner: number;
16
+ craftsman: number;
17
+ };
18
+ personalitySummary: string;
19
+ reportUrl: string;
20
+ }
21
+ export interface UploadError {
22
+ code: string;
23
+ message: string;
24
+ }
25
+ /**
26
+ * Upload session data for analysis
27
+ */
28
+ export declare function uploadForAnalysis(scanResult: ScanResult): Promise<AnalysisResult>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Server Uploader
3
+ *
4
+ * Handles communication with the NoMoreAISlop server
5
+ */
6
+ const API_BASE_URL = process.env.NOSLOP_API_URL || 'https://www.nomoreaislop.xyz';
7
+ /**
8
+ * Upload session data for analysis
9
+ */
10
+ export async function uploadForAnalysis(scanResult) {
11
+ const payload = {
12
+ sessions: scanResult.sessions.map(s => ({
13
+ sessionId: s.metadata.sessionId,
14
+ projectName: s.metadata.projectName,
15
+ messageCount: s.metadata.messageCount,
16
+ durationMinutes: Math.round(s.metadata.durationSeconds / 60),
17
+ content: s.content,
18
+ })),
19
+ totalMessages: scanResult.totalMessages,
20
+ totalDurationMinutes: scanResult.totalDurationMinutes,
21
+ };
22
+ const response = await fetch(`${API_BASE_URL}/api/analysis/remote`, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ body: JSON.stringify(payload),
28
+ });
29
+ if (!response.ok) {
30
+ const error = await response.json().catch(() => ({}));
31
+ throw new Error(error.message || `Server error: ${response.status}`);
32
+ }
33
+ const result = await response.json();
34
+ return {
35
+ ...result,
36
+ reportUrl: `${API_BASE_URL}/r/${result.resultId}`,
37
+ };
38
+ }
39
+ //# sourceMappingURL=uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,8BAA8B,CAAC;AAsBlF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAsB;IAC5D,MAAM,OAAO,GAAG;QACd,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACtC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,SAAS;YAC/B,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW;YACnC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,YAAY;YACrC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,GAAG,EAAE,CAAC;YAC5D,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC;QACH,aAAa,EAAE,UAAU,CAAC,aAAa;QACvC,oBAAoB,EAAE,UAAU,CAAC,oBAAoB;KACtD,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,sBAAsB,EAAE;QAClE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAgB,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,iBAAiB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;IAEvD,OAAO;QACL,GAAG,MAAM;QACT,SAAS,EAAE,GAAG,YAAY,MAAM,MAAM,CAAC,QAAQ,EAAE;KAClD,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "no-ai-slop",
3
+ "version": "0.1.0",
4
+ "description": "Analyze your AI collaboration style with Claude Code",
5
+ "type": "module",
6
+ "bin": {
7
+ "no-ai-slop": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsc --watch",
16
+ "start": "node dist/index.js",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "claude",
21
+ "claude-code",
22
+ "ai",
23
+ "collaboration",
24
+ "developer-tools",
25
+ "productivity",
26
+ "analysis",
27
+ "slop"
28
+ ],
29
+ "author": "NoMoreAISlop",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/nomoreaislop/nomoreaislop"
34
+ },
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "dependencies": {
39
+ "picocolors": "^1.1.1",
40
+ "ora": "^8.1.1",
41
+ "boxen": "^8.0.1"
42
+ }
43
+ }