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.
- package/dist/display.d.ts +22 -0
- package/dist/display.js +105 -0
- package/dist/display.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/scanner.d.ts +33 -0
- package/dist/scanner.js +187 -0
- package/dist/scanner.js.map +1 -0
- package/dist/uploader.d.ts +28 -0
- package/dist/uploader.js +39 -0
- package/dist/uploader.js.map +1 -0
- package/package.json +43 -0
|
@@ -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;
|
package/dist/display.js
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
ADDED
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>;
|
package/dist/scanner.js
ADDED
|
@@ -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>;
|
package/dist/uploader.js
ADDED
|
@@ -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
|
+
}
|