no-ai-slop 0.1.0 → 0.2.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/cache.d.ts +20 -0
- package/dist/cache.js +59 -0
- package/dist/cache.js.map +1 -0
- package/dist/cost-estimator.d.ts +34 -0
- package/dist/cost-estimator.js +106 -0
- package/dist/cost-estimator.js.map +1 -0
- package/dist/display.d.ts +9 -0
- package/dist/display.js +47 -1
- package/dist/display.js.map +1 -1
- package/dist/index.js +133 -6
- package/dist/index.js.map +1 -1
- package/dist/scanner.d.ts +12 -1
- package/dist/scanner.js +29 -16
- package/dist/scanner.js.map +1 -1
- package/dist/uploader.d.ts +12 -2
- package/dist/uploader.js +101 -7
- package/dist/uploader.js.map +1 -1
- package/package.json +6 -2
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Cache - Local caching for analysis results
|
|
3
|
+
*
|
|
4
|
+
* Saves analysis results to avoid repeated API costs during testing.
|
|
5
|
+
* Cache location: ~/.nomoreaislop/analysis-cache.json
|
|
6
|
+
*/
|
|
7
|
+
import type { AnalysisResult } from './uploader.js';
|
|
8
|
+
/**
|
|
9
|
+
* Save analysis result to cache
|
|
10
|
+
*/
|
|
11
|
+
export declare function saveCache(result: AnalysisResult): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Load analysis result from cache
|
|
14
|
+
* Returns null if cache doesn't exist or is invalid
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadCache(): Promise<AnalysisResult | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Display help message for cache flags
|
|
19
|
+
*/
|
|
20
|
+
export declare function displayCacheHelp(): void;
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Cache - Local caching for analysis results
|
|
3
|
+
*
|
|
4
|
+
* Saves analysis results to avoid repeated API costs during testing.
|
|
5
|
+
* Cache location: ~/.nomoreaislop/analysis-cache.json
|
|
6
|
+
*/
|
|
7
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import pc from 'picocolors';
|
|
11
|
+
const CACHE_DIR = join(homedir(), '.nomoreaislop');
|
|
12
|
+
const CACHE_FILE = join(CACHE_DIR, 'analysis-cache.json');
|
|
13
|
+
/**
|
|
14
|
+
* Save analysis result to cache
|
|
15
|
+
*/
|
|
16
|
+
export async function saveCache(result) {
|
|
17
|
+
await mkdir(CACHE_DIR, { recursive: true });
|
|
18
|
+
const cache = {
|
|
19
|
+
version: 2,
|
|
20
|
+
createdAt: new Date().toISOString(),
|
|
21
|
+
result,
|
|
22
|
+
};
|
|
23
|
+
await writeFile(CACHE_FILE, JSON.stringify(cache, null, 2), 'utf-8');
|
|
24
|
+
console.log(pc.dim(` Cache saved to ${CACHE_FILE}`));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load analysis result from cache
|
|
28
|
+
* Returns null if cache doesn't exist or is invalid
|
|
29
|
+
*/
|
|
30
|
+
export async function loadCache() {
|
|
31
|
+
try {
|
|
32
|
+
const content = await readFile(CACHE_FILE, 'utf-8');
|
|
33
|
+
const cache = JSON.parse(content);
|
|
34
|
+
// Validate version
|
|
35
|
+
if (cache.version !== 2) {
|
|
36
|
+
console.log(pc.yellow(' Cache version mismatch, will analyze fresh'));
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const cacheAge = Date.now() - new Date(cache.createdAt).getTime();
|
|
40
|
+
const ageMinutes = Math.round(cacheAge / 60000);
|
|
41
|
+
console.log(pc.green(` Using cached analysis (${ageMinutes} minutes old)`));
|
|
42
|
+
return cache.result;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Display help message for cache flags
|
|
50
|
+
*/
|
|
51
|
+
export function displayCacheHelp() {
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log(pc.bold('Cache Options:'));
|
|
54
|
+
console.log(' --save-cache Save analysis result to local cache');
|
|
55
|
+
console.log(' --use-cache Use cached analysis result (skip API call)');
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log(pc.dim(`Cache location: ${CACHE_FILE}`));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AACnD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;AAQ1D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAsB;IACpD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAkB;QAC3B,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM;KACP,CAAC;IAEF,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,KAAK,GAAkB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEjD,mBAAmB;QACnB,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,4BAA4B,UAAU,eAAe,CAAC,CAAC,CAAC;QAE7E,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Estimator - Token counting and API cost calculation for CLI
|
|
3
|
+
*
|
|
4
|
+
* Estimates the cost of running analysis based on:
|
|
5
|
+
* - Session content token count
|
|
6
|
+
* - System prompt overhead
|
|
7
|
+
* - Expected output tokens
|
|
8
|
+
* - Model-specific pricing
|
|
9
|
+
*/
|
|
10
|
+
import type { ScanResult } from './scanner.js';
|
|
11
|
+
export interface CostEstimate {
|
|
12
|
+
totalInputTokens: number;
|
|
13
|
+
estimatedOutputTokens: number;
|
|
14
|
+
totalCost: number;
|
|
15
|
+
breakdown: {
|
|
16
|
+
sessionTokens: number;
|
|
17
|
+
systemPromptTokens: number;
|
|
18
|
+
schemaOverhead: number;
|
|
19
|
+
};
|
|
20
|
+
modelName: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Count tokens using character-based heuristics
|
|
24
|
+
* with adjustments for common patterns in JSONL content
|
|
25
|
+
*/
|
|
26
|
+
export declare function countTokensAccurate(text: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* Estimate the cost of running analysis on scanned sessions
|
|
29
|
+
*/
|
|
30
|
+
export declare function estimateAnalysisCost(scanResult: ScanResult): CostEstimate;
|
|
31
|
+
/**
|
|
32
|
+
* Render the cost estimate for terminal display
|
|
33
|
+
*/
|
|
34
|
+
export declare function renderCostEstimate(estimate: CostEstimate, sessionCount: number): string;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Estimator - Token counting and API cost calculation for CLI
|
|
3
|
+
*
|
|
4
|
+
* Estimates the cost of running analysis based on:
|
|
5
|
+
* - Session content token count
|
|
6
|
+
* - System prompt overhead
|
|
7
|
+
* - Expected output tokens
|
|
8
|
+
* - Model-specific pricing
|
|
9
|
+
*/
|
|
10
|
+
import pc from 'picocolors';
|
|
11
|
+
/**
|
|
12
|
+
* Model pricing configuration (per token)
|
|
13
|
+
* Gemini 3 Flash is used for the two-stage analysis pipeline
|
|
14
|
+
*/
|
|
15
|
+
const GEMINI_PRICING = {
|
|
16
|
+
'gemini-3-flash-preview': {
|
|
17
|
+
input: 0.5 / 1_000_000, // $0.50 per 1M tokens
|
|
18
|
+
output: 3.0 / 1_000_000, // $3.00 per 1M tokens
|
|
19
|
+
name: 'Gemini 3 Flash',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Fixed overhead estimates
|
|
24
|
+
*/
|
|
25
|
+
const ESTIMATED_SYSTEM_PROMPT_TOKENS = 2500;
|
|
26
|
+
const ESTIMATED_SCHEMA_OVERHEAD = 1500;
|
|
27
|
+
const ESTIMATED_OUTPUT_TOKENS = 6000;
|
|
28
|
+
/**
|
|
29
|
+
* Count tokens using character-based heuristics
|
|
30
|
+
* with adjustments for common patterns in JSONL content
|
|
31
|
+
*/
|
|
32
|
+
export function countTokensAccurate(text) {
|
|
33
|
+
if (!text)
|
|
34
|
+
return 0;
|
|
35
|
+
// Base estimate: ~4 chars per token for English
|
|
36
|
+
let baseCount = text.length / 4;
|
|
37
|
+
// Adjustments for code (more tokens due to symbols)
|
|
38
|
+
const codeBlockMatches = text.match(/```[\s\S]*?```/g);
|
|
39
|
+
const codeBlockCount = codeBlockMatches ? codeBlockMatches.length : 0;
|
|
40
|
+
baseCount += codeBlockCount * 50; // Code blocks are token-heavy
|
|
41
|
+
// JSON structure overhead
|
|
42
|
+
const jsonBraceMatches = text.match(/[{}[\]]/g);
|
|
43
|
+
const jsonBraceCount = jsonBraceMatches ? jsonBraceMatches.length : 0;
|
|
44
|
+
baseCount += jsonBraceCount * 0.5;
|
|
45
|
+
// Newlines and whitespace
|
|
46
|
+
const newlineMatches = text.match(/\n/g);
|
|
47
|
+
const newlineCount = newlineMatches ? newlineMatches.length : 0;
|
|
48
|
+
baseCount += newlineCount * 0.1;
|
|
49
|
+
// Special characters in code
|
|
50
|
+
const specialCharMatches = text.match(/[<>()=;:,."'`]/g);
|
|
51
|
+
const specialCharCount = specialCharMatches ? specialCharMatches.length : 0;
|
|
52
|
+
baseCount += specialCharCount * 0.1;
|
|
53
|
+
return Math.ceil(baseCount);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Estimate the cost of running analysis on scanned sessions
|
|
57
|
+
*/
|
|
58
|
+
export function estimateAnalysisCost(scanResult) {
|
|
59
|
+
const pricing = GEMINI_PRICING['gemini-3-flash-preview'];
|
|
60
|
+
// Calculate session content tokens from raw JSONL
|
|
61
|
+
let sessionTokens = 0;
|
|
62
|
+
for (const session of scanResult.sessions) {
|
|
63
|
+
sessionTokens += countTokensAccurate(session.content);
|
|
64
|
+
}
|
|
65
|
+
const totalInputTokens = sessionTokens + ESTIMATED_SYSTEM_PROMPT_TOKENS + ESTIMATED_SCHEMA_OVERHEAD;
|
|
66
|
+
const totalCost = totalInputTokens * pricing.input + ESTIMATED_OUTPUT_TOKENS * pricing.output;
|
|
67
|
+
return {
|
|
68
|
+
totalInputTokens,
|
|
69
|
+
estimatedOutputTokens: ESTIMATED_OUTPUT_TOKENS,
|
|
70
|
+
totalCost,
|
|
71
|
+
breakdown: {
|
|
72
|
+
sessionTokens,
|
|
73
|
+
systemPromptTokens: ESTIMATED_SYSTEM_PROMPT_TOKENS,
|
|
74
|
+
schemaOverhead: ESTIMATED_SCHEMA_OVERHEAD,
|
|
75
|
+
},
|
|
76
|
+
modelName: pricing.name,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Render the cost estimate for terminal display
|
|
81
|
+
*/
|
|
82
|
+
export function renderCostEstimate(estimate, sessionCount) {
|
|
83
|
+
const lines = [];
|
|
84
|
+
lines.push('');
|
|
85
|
+
lines.push(pc.bold(pc.cyan(' 💰 Analysis Cost Estimate')));
|
|
86
|
+
lines.push('');
|
|
87
|
+
lines.push(` ${pc.dim('Sessions to analyze:')} ${pc.white(sessionCount.toString())}`);
|
|
88
|
+
lines.push(` ${pc.dim('Model:')} ${pc.white(estimate.modelName)}`);
|
|
89
|
+
lines.push('');
|
|
90
|
+
lines.push(` ${pc.dim('Input tokens:')} ${pc.white(estimate.totalInputTokens.toLocaleString())}`);
|
|
91
|
+
lines.push(` ${pc.dim('├─ Session content:')} ${estimate.breakdown.sessionTokens.toLocaleString()}`);
|
|
92
|
+
lines.push(` ${pc.dim('├─ System prompt:')} ${estimate.breakdown.systemPromptTokens.toLocaleString()}`);
|
|
93
|
+
lines.push(` ${pc.dim('└─ Schema overhead:')} ${estimate.breakdown.schemaOverhead.toLocaleString()}`);
|
|
94
|
+
lines.push(` ${pc.dim('Output tokens (est):')} ${pc.white(estimate.estimatedOutputTokens.toLocaleString())}`);
|
|
95
|
+
lines.push('');
|
|
96
|
+
// Cost box
|
|
97
|
+
const costStr = `$${estimate.totalCost.toFixed(4)}`;
|
|
98
|
+
lines.push(pc.green(` ╔══════════════════════════════════╗`));
|
|
99
|
+
lines.push(pc.green(` ║ ${pc.bold('Estimated Cost:')} ${pc.bold(pc.yellow(costStr.padEnd(15)))} ║`));
|
|
100
|
+
lines.push(pc.green(` ╚══════════════════════════════════╝`));
|
|
101
|
+
lines.push('');
|
|
102
|
+
lines.push(pc.dim(' Note: Actual cost may vary slightly.'));
|
|
103
|
+
lines.push('');
|
|
104
|
+
return lines.join('\n');
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cost-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-estimator.js","sourceRoot":"","sources":["../src/cost-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;;GAGG;AACH,MAAM,cAAc,GAAG;IACrB,wBAAwB,EAAE;QACxB,KAAK,EAAE,GAAG,GAAG,SAAS,EAAE,sBAAsB;QAC9C,MAAM,EAAE,GAAG,GAAG,SAAS,EAAE,sBAAsB;QAC/C,IAAI,EAAE,gBAAgB;KACvB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAC5C,MAAM,yBAAyB,GAAG,IAAI,CAAC;AACvC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAcrC;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IAEpB,gDAAgD;IAChD,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAEhC,oDAAoD;IACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,SAAS,IAAI,cAAc,GAAG,EAAE,CAAC,CAAC,8BAA8B;IAEhE,0BAA0B;IAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,SAAS,IAAI,cAAc,GAAG,GAAG,CAAC;IAElC,0BAA0B;IAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,SAAS,IAAI,YAAY,GAAG,GAAG,CAAC;IAEhC,6BAA6B;IAC7B,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,SAAS,IAAI,gBAAgB,GAAG,GAAG,CAAC;IAEpC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAsB;IACzD,MAAM,OAAO,GAAG,cAAc,CAAC,wBAAwB,CAAC,CAAC;IAEzD,kDAAkD;IAClD,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC1C,aAAa,IAAI,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,gBAAgB,GACpB,aAAa,GAAG,8BAA8B,GAAG,yBAAyB,CAAC;IAE7E,MAAM,SAAS,GACb,gBAAgB,GAAG,OAAO,CAAC,KAAK,GAAG,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9E,OAAO;QACL,gBAAgB;QAChB,qBAAqB,EAAE,uBAAuB;QAC9C,SAAS;QACT,SAAS,EAAE;YACT,aAAa;YACb,kBAAkB,EAAE,8BAA8B;YAClD,cAAc,EAAE,yBAAyB;SAC1C;QACD,SAAS,EAAE,OAAO,CAAC,IAAI;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAsB,EACtB,YAAoB;IAEpB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACvF,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;IACnG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACxG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,kBAAkB,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC3G,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACzG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/G,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,WAAW;IACX,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/display.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Formats and displays analysis results in the terminal
|
|
5
5
|
*/
|
|
6
6
|
import type { AnalysisResult } from './uploader.js';
|
|
7
|
+
import type { SessionWithTokens } from './scanner.js';
|
|
7
8
|
/**
|
|
8
9
|
* Display the analysis results
|
|
9
10
|
*/
|
|
@@ -20,3 +21,11 @@ export declare function displayError(message: string): void;
|
|
|
20
21
|
* Display no sessions found message
|
|
21
22
|
*/
|
|
22
23
|
export declare function displayNoSessions(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Display session list for selection
|
|
26
|
+
*/
|
|
27
|
+
export declare function displaySessionList(sessions: SessionWithTokens[]): void;
|
|
28
|
+
/**
|
|
29
|
+
* Display selection prompt instructions
|
|
30
|
+
*/
|
|
31
|
+
export declare function displaySelectionHelp(): void;
|
package/dist/display.js
CHANGED
|
@@ -65,7 +65,7 @@ export function displayResults(result) {
|
|
|
65
65
|
lines.push(pc.dim('─'.repeat(45)));
|
|
66
66
|
lines.push('');
|
|
67
67
|
// Report link
|
|
68
|
-
lines.push(`📊 ${pc.bold('
|
|
68
|
+
lines.push(`📊 ${pc.bold('Detailed Report:')} ${pc.cyan(pc.underline(result.reportUrl))}`);
|
|
69
69
|
const box = boxen(lines.join('\n'), {
|
|
70
70
|
padding: 1,
|
|
71
71
|
margin: 1,
|
|
@@ -102,4 +102,50 @@ export function displayNoSessions() {
|
|
|
102
102
|
console.log(pc.dim(' ~/.claude/projects/'));
|
|
103
103
|
console.log('');
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Estimate cost for a single session (simplified)
|
|
107
|
+
*/
|
|
108
|
+
function estimateSingleSessionCost(tokenCount) {
|
|
109
|
+
const inputPrice = 0.5 / 1_000_000; // Gemini 3 Flash input
|
|
110
|
+
const outputPrice = 3.0 / 1_000_000; // Gemini 3 Flash output
|
|
111
|
+
const overhead = 400; // Amortized system prompt + schema
|
|
112
|
+
const outputTokens = 600; // Amortized output per session
|
|
113
|
+
return (tokenCount + overhead) * inputPrice + outputTokens * outputPrice;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Display session list for selection
|
|
117
|
+
*/
|
|
118
|
+
export function displaySessionList(sessions) {
|
|
119
|
+
console.log('');
|
|
120
|
+
console.log(pc.bold(pc.cyan(' 📋 Available Sessions (sorted by size)')));
|
|
121
|
+
console.log('');
|
|
122
|
+
// Header
|
|
123
|
+
console.log(pc.dim(' #'.padEnd(6)) +
|
|
124
|
+
pc.dim('Project'.padEnd(22)) +
|
|
125
|
+
pc.dim('Session'.padEnd(14)) +
|
|
126
|
+
pc.dim('Tokens'.padStart(10)) +
|
|
127
|
+
pc.dim('Est. Cost'.padStart(12)));
|
|
128
|
+
console.log(pc.dim(' ' + '─'.repeat(60)));
|
|
129
|
+
// Rows
|
|
130
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
131
|
+
const s = sessions[i];
|
|
132
|
+
const num = pc.bold(pc.white(`${i + 1}.`.padEnd(6)));
|
|
133
|
+
const project = s.metadata.projectName.slice(0, 20).padEnd(22);
|
|
134
|
+
const sessionId = s.metadata.sessionId.slice(0, 12).padEnd(14);
|
|
135
|
+
const tokens = s.tokenCount.toLocaleString().padStart(10);
|
|
136
|
+
const cost = `$${estimateSingleSessionCost(s.tokenCount).toFixed(4)}`.padStart(12);
|
|
137
|
+
console.log(` ${num}${project}${sessionId}${pc.cyan(tokens)}${pc.yellow(cost)}`);
|
|
138
|
+
}
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Display selection prompt instructions
|
|
143
|
+
*/
|
|
144
|
+
export function displaySelectionHelp() {
|
|
145
|
+
console.log(pc.dim(' Selection options:'));
|
|
146
|
+
console.log(pc.dim(' • Enter numbers: 1,3,5 or 1-5 or 1-3,5,7-10'));
|
|
147
|
+
console.log(pc.dim(' • "all" to select all sessions'));
|
|
148
|
+
console.log(pc.dim(' • Press Enter for default (all)'));
|
|
149
|
+
console.log('');
|
|
150
|
+
}
|
|
105
151
|
//# sourceMappingURL=display.js.map
|
package/dist/display.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,33 @@ import pc from 'picocolors';
|
|
|
9
9
|
import ora from 'ora';
|
|
10
10
|
import { scanSessions, hasClaudeProjects } from './scanner.js';
|
|
11
11
|
import { uploadForAnalysis } from './uploader.js';
|
|
12
|
-
import { displayResults, displayPrivacyNotice, displayError, displayNoSessions, } from './display.js';
|
|
12
|
+
import { displayResults, displayPrivacyNotice, displayError, displayNoSessions, displaySessionList, displaySelectionHelp, } from './display.js';
|
|
13
|
+
import { estimateAnalysisCost, renderCostEstimate } from './cost-estimator.js';
|
|
14
|
+
import { saveCache, loadCache } from './cache.js';
|
|
15
|
+
/**
|
|
16
|
+
* Parse CLI arguments
|
|
17
|
+
*/
|
|
18
|
+
function parseArgs() {
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
return {
|
|
21
|
+
saveCache: args.includes('--save-cache'),
|
|
22
|
+
useCache: args.includes('--use-cache'),
|
|
23
|
+
help: args.includes('--help') || args.includes('-h'),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Display help message
|
|
28
|
+
*/
|
|
29
|
+
function displayHelp() {
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log(pc.bold(pc.cyan('Usage:')) + ' npx no-ai-slop [options]');
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(pc.bold('Options:'));
|
|
34
|
+
console.log(' --save-cache Run analysis and save result to local cache');
|
|
35
|
+
console.log(' --use-cache Use cached analysis result (skip API call)');
|
|
36
|
+
console.log(' --help, -h Show this help message');
|
|
37
|
+
console.log('');
|
|
38
|
+
}
|
|
13
39
|
/**
|
|
14
40
|
* Prompt user for confirmation
|
|
15
41
|
*/
|
|
@@ -26,20 +52,87 @@ async function confirm(message) {
|
|
|
26
52
|
});
|
|
27
53
|
});
|
|
28
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Parse session selection string into indices
|
|
57
|
+
* Supports: "1,3,5", "1-5", "1-3,5,7-10"
|
|
58
|
+
*/
|
|
59
|
+
function parseSessionSelection(input, max) {
|
|
60
|
+
const indices = new Set();
|
|
61
|
+
// Split by comma
|
|
62
|
+
const parts = input.split(',').map(p => p.trim());
|
|
63
|
+
for (const part of parts) {
|
|
64
|
+
if (part.includes('-')) {
|
|
65
|
+
// Range: "1-5"
|
|
66
|
+
const [startStr, endStr] = part.split('-');
|
|
67
|
+
const start = parseInt(startStr, 10);
|
|
68
|
+
const end = parseInt(endStr, 10);
|
|
69
|
+
if (!isNaN(start) && !isNaN(end)) {
|
|
70
|
+
for (let i = start; i <= end; i++) {
|
|
71
|
+
if (i >= 1 && i <= max)
|
|
72
|
+
indices.add(i - 1); // Convert to 0-based
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Single number
|
|
78
|
+
const num = parseInt(part, 10);
|
|
79
|
+
if (!isNaN(num) && num >= 1 && num <= max) {
|
|
80
|
+
indices.add(num - 1); // Convert to 0-based
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Array.from(indices).sort((a, b) => a - b);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Prompt user for session selection
|
|
88
|
+
*/
|
|
89
|
+
async function promptSessionSelection(maxSessions) {
|
|
90
|
+
const rl = createInterface({
|
|
91
|
+
input: process.stdin,
|
|
92
|
+
output: process.stdout,
|
|
93
|
+
});
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
rl.question(pc.cyan('Select sessions to analyze: '), (answer) => {
|
|
96
|
+
rl.close();
|
|
97
|
+
const normalized = answer.trim().toLowerCase();
|
|
98
|
+
if (normalized === '' || normalized === 'all') {
|
|
99
|
+
resolve('all');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
resolve(parseSessionSelection(normalized, maxSessions));
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
29
106
|
/**
|
|
30
107
|
* Main CLI entry point
|
|
31
108
|
*/
|
|
32
109
|
async function main() {
|
|
110
|
+
const args = parseArgs();
|
|
111
|
+
// Handle help flag
|
|
112
|
+
if (args.help) {
|
|
113
|
+
displayHelp();
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
33
116
|
console.log('');
|
|
34
117
|
console.log(pc.bold(pc.cyan('🚀 no-ai-slop')) + pc.dim(' - AI Collaboration Style Analyzer'));
|
|
35
118
|
console.log('');
|
|
119
|
+
// Try to use cached analysis result if requested
|
|
120
|
+
if (args.useCache) {
|
|
121
|
+
console.log(pc.dim(' Checking analysis cache...'));
|
|
122
|
+
const cachedResult = await loadCache();
|
|
123
|
+
if (cachedResult) {
|
|
124
|
+
displayResults(cachedResult);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
console.log(pc.dim(' No cached analysis found, running fresh analysis...'));
|
|
128
|
+
}
|
|
36
129
|
// Check if Claude projects directory exists
|
|
37
130
|
const hasProjects = await hasClaudeProjects();
|
|
38
131
|
if (!hasProjects) {
|
|
39
132
|
displayNoSessions();
|
|
40
133
|
process.exit(1);
|
|
41
134
|
}
|
|
42
|
-
// Scan
|
|
135
|
+
// Scan sessions
|
|
43
136
|
const scanSpinner = ora('Scanning Claude Code sessions...').start();
|
|
44
137
|
let scanResult;
|
|
45
138
|
try {
|
|
@@ -55,8 +148,35 @@ async function main() {
|
|
|
55
148
|
displayNoSessions();
|
|
56
149
|
process.exit(1);
|
|
57
150
|
}
|
|
58
|
-
scanSpinner.succeed(`Found ${pc.bold(String(scanResult.sessions.length))} sessions
|
|
59
|
-
|
|
151
|
+
scanSpinner.succeed(`Found ${pc.bold(String(scanResult.sessions.length))} sessions`);
|
|
152
|
+
// Display session list for selection
|
|
153
|
+
displaySessionList(scanResult.sessions);
|
|
154
|
+
displaySelectionHelp();
|
|
155
|
+
// Prompt for selection
|
|
156
|
+
const selection = await promptSessionSelection(scanResult.sessions.length);
|
|
157
|
+
// Filter sessions based on selection
|
|
158
|
+
let selectedSessions;
|
|
159
|
+
if (selection === 'all') {
|
|
160
|
+
selectedSessions = scanResult.sessions;
|
|
161
|
+
console.log(pc.dim(` Selected all ${selectedSessions.length} sessions\n`));
|
|
162
|
+
}
|
|
163
|
+
else if (selection.length === 0) {
|
|
164
|
+
console.log(pc.yellow('\n No valid sessions selected.\n'));
|
|
165
|
+
process.exit(0);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
selectedSessions = selection.map(i => scanResult.sessions[i]);
|
|
169
|
+
console.log(pc.dim(` Selected ${selectedSessions.length} session(s)\n`));
|
|
170
|
+
}
|
|
171
|
+
// Create filtered ScanResult for cost estimation and upload
|
|
172
|
+
const filteredResult = {
|
|
173
|
+
sessions: selectedSessions,
|
|
174
|
+
totalMessages: selectedSessions.reduce((sum, s) => sum + s.metadata.messageCount, 0),
|
|
175
|
+
totalDurationMinutes: selectedSessions.reduce((sum, s) => sum + Math.round(s.metadata.durationSeconds / 60), 0),
|
|
176
|
+
};
|
|
177
|
+
// Estimate and display cost
|
|
178
|
+
const costEstimate = estimateAnalysisCost(filteredResult);
|
|
179
|
+
console.log(renderCostEstimate(costEstimate, selectedSessions.length));
|
|
60
180
|
// Show privacy notice and ask for consent
|
|
61
181
|
displayPrivacyNotice();
|
|
62
182
|
const consent = await confirm('Proceed with analysis?');
|
|
@@ -64,11 +184,18 @@ async function main() {
|
|
|
64
184
|
console.log(pc.dim('\nAnalysis cancelled.'));
|
|
65
185
|
process.exit(0);
|
|
66
186
|
}
|
|
67
|
-
// Upload and analyze
|
|
187
|
+
// Upload and analyze with streaming progress
|
|
68
188
|
const analyzeSpinner = ora('Analyzing your AI collaboration style...').start();
|
|
69
189
|
try {
|
|
70
|
-
const result = await uploadForAnalysis(
|
|
190
|
+
const result = await uploadForAnalysis(filteredResult, (stage, progress, message) => {
|
|
191
|
+
// Update spinner text with progress
|
|
192
|
+
analyzeSpinner.text = `${message} (${progress}%)`;
|
|
193
|
+
});
|
|
71
194
|
analyzeSpinner.succeed('Analysis complete!');
|
|
195
|
+
// Save to cache if requested
|
|
196
|
+
if (args.saveCache) {
|
|
197
|
+
await saveCache(result);
|
|
198
|
+
}
|
|
72
199
|
// Display results
|
|
73
200
|
displayResults(result);
|
|
74
201
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -18,11 +18,22 @@ export interface SessionData {
|
|
|
18
18
|
metadata: SessionMetadata;
|
|
19
19
|
content: string;
|
|
20
20
|
}
|
|
21
|
+
export interface SessionWithTokens extends SessionData {
|
|
22
|
+
tokenCount: number;
|
|
23
|
+
}
|
|
21
24
|
export interface ScanResult {
|
|
22
|
-
sessions:
|
|
25
|
+
sessions: SessionWithTokens[];
|
|
23
26
|
totalMessages: number;
|
|
24
27
|
totalDurationMinutes: number;
|
|
25
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* List all project directories
|
|
31
|
+
*/
|
|
32
|
+
export declare function listProjectDirs(): Promise<string[]>;
|
|
33
|
+
/**
|
|
34
|
+
* List session files in a directory
|
|
35
|
+
*/
|
|
36
|
+
export declare function listSessionFiles(projectDir: string): Promise<string[]>;
|
|
26
37
|
/**
|
|
27
38
|
* Scan all sessions and select the best ones for analysis
|
|
28
39
|
*/
|
package/dist/scanner.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
8
8
|
import { join, basename } from 'node:path';
|
|
9
9
|
import { homedir } from 'node:os';
|
|
10
|
+
import { countTokensAccurate } from './cost-estimator.js';
|
|
10
11
|
export const CLAUDE_PROJECTS_DIR = join(homedir(), '.claude', 'projects');
|
|
11
12
|
/**
|
|
12
13
|
* Decode project path from Claude's encoding
|
|
@@ -43,6 +44,22 @@ function parseJSONLLine(line) {
|
|
|
43
44
|
return null;
|
|
44
45
|
}
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a line is a conversation message (user or assistant)
|
|
49
|
+
*/
|
|
50
|
+
function isConversationLine(parsed) {
|
|
51
|
+
return parsed !== null && (parsed.type === 'user' || parsed.type === 'assistant');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Update timestamp bounds (min/max) with a new timestamp
|
|
55
|
+
*/
|
|
56
|
+
function updateTimestampBounds(timestamp, bounds) {
|
|
57
|
+
const ts = new Date(timestamp);
|
|
58
|
+
if (!bounds.first || ts < bounds.first)
|
|
59
|
+
bounds.first = ts;
|
|
60
|
+
if (!bounds.last || ts > bounds.last)
|
|
61
|
+
bounds.last = ts;
|
|
62
|
+
}
|
|
46
63
|
/**
|
|
47
64
|
* Get metadata for a session file
|
|
48
65
|
*/
|
|
@@ -54,31 +71,26 @@ async function getSessionMetadata(filePath) {
|
|
|
54
71
|
return null;
|
|
55
72
|
const fileName = basename(filePath, '.jsonl');
|
|
56
73
|
let messageCount = 0;
|
|
57
|
-
|
|
58
|
-
let lastTimestamp = null;
|
|
74
|
+
const timestamps = { first: null, last: null };
|
|
59
75
|
for (const line of lines) {
|
|
60
76
|
const parsed = parseJSONLLine(line);
|
|
61
|
-
if (
|
|
77
|
+
if (isConversationLine(parsed)) {
|
|
62
78
|
messageCount++;
|
|
63
|
-
if (parsed
|
|
64
|
-
|
|
65
|
-
if (!firstTimestamp || ts < firstTimestamp)
|
|
66
|
-
firstTimestamp = ts;
|
|
67
|
-
if (!lastTimestamp || ts > lastTimestamp)
|
|
68
|
-
lastTimestamp = ts;
|
|
79
|
+
if (parsed?.timestamp) {
|
|
80
|
+
updateTimestampBounds(parsed.timestamp, timestamps);
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
|
-
if (!
|
|
84
|
+
if (!timestamps.first || !timestamps.last)
|
|
73
85
|
return null;
|
|
74
86
|
const projectDirName = basename(join(filePath, '..'));
|
|
75
87
|
const projectPath = decodeProjectPath(projectDirName);
|
|
76
|
-
const durationSeconds = Math.floor((
|
|
88
|
+
const durationSeconds = Math.floor((timestamps.last.getTime() - timestamps.first.getTime()) / 1000);
|
|
77
89
|
return {
|
|
78
90
|
sessionId: fileName,
|
|
79
91
|
projectPath,
|
|
80
92
|
projectName: getProjectName(projectPath),
|
|
81
|
-
timestamp:
|
|
93
|
+
timestamp: timestamps.first,
|
|
82
94
|
messageCount,
|
|
83
95
|
durationSeconds,
|
|
84
96
|
filePath,
|
|
@@ -91,7 +103,7 @@ async function getSessionMetadata(filePath) {
|
|
|
91
103
|
/**
|
|
92
104
|
* List all project directories
|
|
93
105
|
*/
|
|
94
|
-
async function listProjectDirs() {
|
|
106
|
+
export async function listProjectDirs() {
|
|
95
107
|
try {
|
|
96
108
|
const entries = await readdir(CLAUDE_PROJECTS_DIR);
|
|
97
109
|
const dirs = [];
|
|
@@ -116,7 +128,7 @@ async function listProjectDirs() {
|
|
|
116
128
|
/**
|
|
117
129
|
* List session files in a directory
|
|
118
130
|
*/
|
|
119
|
-
async function listSessionFiles(projectDir) {
|
|
131
|
+
export async function listSessionFiles(projectDir) {
|
|
120
132
|
try {
|
|
121
133
|
const files = await readdir(projectDir);
|
|
122
134
|
return files
|
|
@@ -151,14 +163,15 @@ export async function scanSessions(maxSessions = 10) {
|
|
|
151
163
|
});
|
|
152
164
|
// Select top sessions
|
|
153
165
|
const selected = allMetadata.slice(0, maxSessions);
|
|
154
|
-
// Read content for selected sessions
|
|
166
|
+
// Read content for selected sessions and calculate tokens
|
|
155
167
|
const sessions = [];
|
|
156
168
|
let totalMessages = 0;
|
|
157
169
|
let totalDurationMinutes = 0;
|
|
158
170
|
for (const metadata of selected) {
|
|
159
171
|
try {
|
|
160
172
|
const content = await readFile(metadata.filePath, 'utf-8');
|
|
161
|
-
|
|
173
|
+
const tokenCount = countTokensAccurate(content);
|
|
174
|
+
sessions.push({ metadata, content, tokenCount });
|
|
162
175
|
totalMessages += metadata.messageCount;
|
|
163
176
|
totalDurationMinutes += Math.round(metadata.durationSeconds / 60);
|
|
164
177
|
}
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/uploader.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Server Uploader
|
|
3
3
|
*
|
|
4
4
|
* Handles communication with the NoMoreAISlop server
|
|
5
|
+
* Supports SSE streaming for real-time progress updates
|
|
5
6
|
*/
|
|
6
7
|
import type { ScanResult } from './scanner.js';
|
|
7
8
|
export interface AnalysisResult {
|
|
@@ -23,6 +24,15 @@ export interface UploadError {
|
|
|
23
24
|
message: string;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
+
* Progress callback for UI updates
|
|
27
28
|
*/
|
|
28
|
-
export
|
|
29
|
+
export type ProgressCallback = (stage: string, progress: number, message: string) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Upload session data for analysis with streaming progress
|
|
32
|
+
*/
|
|
33
|
+
export declare function uploadForAnalysis(scanResult: ScanResult, onProgress?: ProgressCallback): Promise<AnalysisResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Legacy upload function (non-streaming)
|
|
36
|
+
* Kept for backward compatibility
|
|
37
|
+
*/
|
|
38
|
+
export declare function uploadForAnalysisLegacy(scanResult: ScanResult): Promise<AnalysisResult>;
|
package/dist/uploader.js
CHANGED
|
@@ -2,12 +2,26 @@
|
|
|
2
2
|
* Server Uploader
|
|
3
3
|
*
|
|
4
4
|
* Handles communication with the NoMoreAISlop server
|
|
5
|
+
* Supports SSE streaming for real-time progress updates
|
|
5
6
|
*/
|
|
6
7
|
const API_BASE_URL = process.env.NOSLOP_API_URL || 'https://www.nomoreaislop.xyz';
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Parse SSE data line
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
+
function parseSSELine(line) {
|
|
12
|
+
if (!line.startsWith('data: '))
|
|
13
|
+
return null;
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(line.slice(6));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Upload session data for analysis with streaming progress
|
|
23
|
+
*/
|
|
24
|
+
export async function uploadForAnalysis(scanResult, onProgress) {
|
|
11
25
|
const payload = {
|
|
12
26
|
sessions: scanResult.sessions.map(s => ({
|
|
13
27
|
sessionId: s.metadata.sessionId,
|
|
@@ -30,10 +44,90 @@ export async function uploadForAnalysis(scanResult) {
|
|
|
30
44
|
const error = await response.json().catch(() => ({}));
|
|
31
45
|
throw new Error(error.message || `Server error: ${response.status}`);
|
|
32
46
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
// Check if response is SSE stream
|
|
48
|
+
const contentType = response.headers.get('content-type') || '';
|
|
49
|
+
if (contentType.includes('text/event-stream')) {
|
|
50
|
+
// Handle SSE streaming response
|
|
51
|
+
return await handleStreamingResponse(response, onProgress);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Handle legacy JSON response (fallback)
|
|
55
|
+
const result = await response.json();
|
|
56
|
+
return {
|
|
57
|
+
...result,
|
|
58
|
+
reportUrl: `${API_BASE_URL}/r/${result.resultId}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Handle SSE streaming response
|
|
64
|
+
*/
|
|
65
|
+
async function handleStreamingResponse(response, onProgress) {
|
|
66
|
+
const reader = response.body?.getReader();
|
|
67
|
+
if (!reader) {
|
|
68
|
+
throw new Error('Response body is not readable');
|
|
69
|
+
}
|
|
70
|
+
const decoder = new TextDecoder();
|
|
71
|
+
let buffer = '';
|
|
72
|
+
let result = null;
|
|
73
|
+
try {
|
|
74
|
+
while (true) {
|
|
75
|
+
const { done, value } = await reader.read();
|
|
76
|
+
if (done)
|
|
77
|
+
break;
|
|
78
|
+
buffer += decoder.decode(value, { stream: true });
|
|
79
|
+
// Process complete lines
|
|
80
|
+
const lines = buffer.split('\n');
|
|
81
|
+
buffer = lines.pop() || ''; // Keep incomplete line in buffer
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
const trimmed = line.trim();
|
|
84
|
+
if (!trimmed)
|
|
85
|
+
continue;
|
|
86
|
+
const event = parseSSELine(trimmed);
|
|
87
|
+
if (!event)
|
|
88
|
+
continue;
|
|
89
|
+
switch (event.type) {
|
|
90
|
+
case 'progress':
|
|
91
|
+
onProgress?.(event.stage, event.progress, event.message);
|
|
92
|
+
break;
|
|
93
|
+
case 'result':
|
|
94
|
+
result = {
|
|
95
|
+
...event.data,
|
|
96
|
+
reportUrl: `${API_BASE_URL}/r/${event.data.resultId}`,
|
|
97
|
+
};
|
|
98
|
+
break;
|
|
99
|
+
case 'error':
|
|
100
|
+
throw new Error(event.message || 'Analysis failed');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Process any remaining buffer
|
|
105
|
+
if (buffer.trim()) {
|
|
106
|
+
const event = parseSSELine(buffer.trim());
|
|
107
|
+
if (event?.type === 'result') {
|
|
108
|
+
result = {
|
|
109
|
+
...event.data,
|
|
110
|
+
reportUrl: `${API_BASE_URL}/r/${event.data.resultId}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
else if (event?.type === 'error') {
|
|
114
|
+
throw new Error(event.message || 'Analysis failed');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (!result) {
|
|
118
|
+
throw new Error('No result received from server');
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
reader.releaseLock();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Legacy upload function (non-streaming)
|
|
128
|
+
* Kept for backward compatibility
|
|
129
|
+
*/
|
|
130
|
+
export async function uploadForAnalysisLegacy(scanResult) {
|
|
131
|
+
return uploadForAnalysis(scanResult);
|
|
38
132
|
}
|
|
39
133
|
//# sourceMappingURL=uploader.js.map
|
package/dist/uploader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "no-ai-slop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Analyze your AI collaboration style with Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
16
|
"start": "node dist/index.js",
|
|
17
|
-
"prepublishOnly": "npm run build"
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
18
|
+
"release": "./scripts/publish.sh",
|
|
19
|
+
"release:patch": "./scripts/publish.sh patch",
|
|
20
|
+
"release:minor": "./scripts/publish.sh minor",
|
|
21
|
+
"release:major": "./scripts/publish.sh major"
|
|
18
22
|
},
|
|
19
23
|
"keywords": [
|
|
20
24
|
"claude",
|