compress-claude 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # compress-claude
2
+
3
+ Compression proxy for Claude Code. Extends sessions and reduces token usage by 60-90%.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g compress-claude
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Generate Context Files
14
+ ```bash
15
+ # Scan your project and generate CLAUDE.md + ai-docs/
16
+ compress-claude
17
+ ```
18
+
19
+ ### Start Compression Proxy
20
+ ```bash
21
+ # Start the proxy (intercepts Claude Code API calls)
22
+ compress-claude --proxy
23
+
24
+ # With custom port
25
+ compress-claude --proxy --port 5000
26
+ ```
27
+
28
+ ### Learn from Sessions
29
+ ```bash
30
+ # Analyze past sessions and extract error-fix patterns
31
+ compress-claude --learn
32
+ ```
33
+
34
+ ### Install Hooks
35
+ ```bash
36
+ # Auto-learn hook + peak hours warning
37
+ compress-claude --hooks
38
+ ```
39
+
40
+ ## What Gets Compressed
41
+
42
+ The proxy compresses verbose tool outputs that waste tokens:
43
+ - npm install/build logs (keeps errors only)
44
+ - Test output (keeps PASS/FAIL summary)
45
+ - Docker build logs (keeps step results)
46
+ - pip install output (keeps errors)
47
+
48
+ **Never compressed:** File reads, grep results, file edits - these need full content.
49
+
50
+ ## Options
51
+
52
+ | Flag | Description |
53
+ |------|-------------|
54
+ | --proxy | Start compression proxy |
55
+ | --port N | Proxy port (default: 4800) |
56
+ | --learn | Analyze sessions for patterns |
57
+ | --hooks | Install Claude Code hooks |
58
+ | --doctor | Diagnose token waste |
59
+ | --force | Overwrite existing files |
60
+ | --dry-run | Preview without writing |
61
+ | --verbose | Detailed output |
62
+ | --help | Show help |
63
+
64
+ ## License
65
+
66
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ export interface CLIOptions {
2
+ force?: boolean;
3
+ dryRun?: boolean;
4
+ config?: boolean;
5
+ learn?: boolean;
6
+ proxy?: boolean;
7
+ hooks?: boolean;
8
+ doctor?: boolean;
9
+ inject?: string;
10
+ license?: string;
11
+ help?: boolean;
12
+ port?: number;
13
+ verbose?: boolean;
14
+ }
15
+ export declare function parseArgs(argv: string[]): CLIOptions;
16
+ export declare function showHelp(): void;
17
+ //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js ADDED
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseArgs = parseArgs;
4
+ exports.showHelp = showHelp;
5
+ const colors_1 = require("./utils/colors");
6
+ function parseArgs(argv) {
7
+ const opts = {};
8
+ opts.force = argv.includes('--force') || argv.includes('-f');
9
+ opts.dryRun = argv.includes('--dry-run');
10
+ opts.config = argv.includes('--config') || argv.includes('-c');
11
+ opts.learn = argv.includes('--learn') || argv.includes('-l');
12
+ opts.proxy = argv.includes('--proxy') || argv.includes('-p');
13
+ opts.hooks = argv.includes('--hooks');
14
+ opts.doctor = argv.includes('--doctor') || argv.includes('-d');
15
+ opts.help = argv.includes('--help') || argv.includes('-h');
16
+ opts.verbose = argv.includes('--verbose') || argv.includes('-v');
17
+ // --inject "text"
18
+ let injectIdx = argv.indexOf('--inject');
19
+ if (injectIdx < 0)
20
+ injectIdx = argv.indexOf('-i');
21
+ if (injectIdx >= 0 && injectIdx + 1 < argv.length) {
22
+ opts.inject = argv[injectIdx + 1];
23
+ }
24
+ // activate <key>
25
+ const activateIdx = argv.indexOf('activate');
26
+ if (activateIdx >= 0 && activateIdx + 1 < argv.length) {
27
+ opts.license = argv[activateIdx + 1];
28
+ }
29
+ // --port <number>
30
+ const portIdx = argv.indexOf('--port');
31
+ if (portIdx >= 0 && portIdx + 1 < argv.length) {
32
+ const parsed = parseInt(argv[portIdx + 1], 10);
33
+ if (!isNaN(parsed)) {
34
+ opts.port = parsed;
35
+ }
36
+ }
37
+ return opts;
38
+ }
39
+ function showHelp() {
40
+ console.log((0, colors_1.bold)('Usage:') + ' npx compress-claude [options]\n');
41
+ console.log((0, colors_1.bold)('Generate context:'));
42
+ console.log(' ' + (0, colors_1.cyan)('(no flags)'.padEnd(22)) + 'Scan project and generate 4-layer context system');
43
+ console.log(' ' + (0, colors_1.cyan)('--force, -f'.padEnd(22)) + 'Overwrite existing files');
44
+ console.log(' ' + (0, colors_1.cyan)('--dry-run'.padEnd(22)) + 'Preview what would be generated');
45
+ console.log(' ' + (0, colors_1.cyan)('--config, -c'.padEnd(22)) + 'Update personal defaults (~/.compress-claude/defaults.json)\n');
46
+ console.log((0, colors_1.bold)('License:'));
47
+ console.log(' ' + (0, colors_1.cyan)('activate <key>'.padEnd(22)) + 'Activate your license key');
48
+ console.log(' ' + (0, colors_1.cyan)('deactivate'.padEnd(22)) + 'Remove license from this machine\n');
49
+ console.log((0, colors_1.bold)('Token saving (built-in, zero dependencies):'));
50
+ console.log(' ' + (0, colors_1.cyan)('--proxy, -p'.padEnd(22)) + 'Start compression proxy (saves 60-90% on tool outputs)');
51
+ console.log(' ' + (0, colors_1.cyan)('--learn, -l'.padEnd(22)) + 'Learn from past sessions, write fixes to CLAUDE.md');
52
+ console.log(' ' + (0, colors_1.cyan)('--learn --all'.padEnd(22)) + 'Learn from ALL projects');
53
+ console.log(' ' + (0, colors_1.cyan)('--stats, -s'.padEnd(22)) + 'Token usage stats for this project');
54
+ console.log(' ' + (0, colors_1.cyan)('--doctor, -d'.padEnd(22)) + 'Diagnose token waste and suggest fixes');
55
+ console.log(' ' + (0, colors_1.cyan)('--inject, -i "text"'.padEnd(22)) + 'Inject a learning Claude will always see');
56
+ console.log(' ' + (0, colors_1.cyan)('--hooks'.padEnd(22)) + 'Install auto-learn hook + peak hours warning');
57
+ console.log(' ' + (0, colors_1.cyan)('--api-proxy'.padEnd(22)) + 'Generate production API proxy (model routing, caching, compression)\n');
58
+ console.log((0, colors_1.bold)('Proxy setup (one-time):'));
59
+ console.log(' ' + (0, colors_1.cyan)('compress-claude activate cc_live_...') + (0, colors_1.gray)(' # activate license'));
60
+ console.log(' ' + (0, colors_1.cyan)('compress-claude --proxy') + (0, colors_1.gray)(' # run in separate terminal'));
61
+ console.log(' ' + (0, colors_1.cyan)('export ANTHROPIC_BASE_URL=http://localhost:8787') + (0, colors_1.gray)(' # add to .bashrc\n'));
62
+ console.log((0, colors_1.bold)('What gets generated:'));
63
+ console.log(' CLAUDE.md Layer 1 -- always loaded (~400 tokens)');
64
+ console.log(' ai-docs/*.md Layer 2 -- domain context, load per session');
65
+ console.log(' ai-docs/PROMPTS.md Layer 3 -- pattern library index');
66
+ console.log(' ai-docs/prompts/*.md Layer 3 -- Build/Verify/Debug per pattern');
67
+ console.log(' ai-docs/skills/*.md Supporting -- role personas (frontend/backend/devops)');
68
+ console.log(' ai-docs/security.md Supporting -- OWASP + STRIDE for your stack');
69
+ console.log(' ai-docs/HANDOVER.md Extra -- resume sessions cheaply');
70
+ console.log(' ai-docs/MISTAKES.md Extra -- never repeat the same error');
71
+ console.log(' ai-docs/TOKEN-RULES.md Extra -- keep Claude lean and direct\n');
72
+ }
73
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,2 @@
1
+ export declare function runDoctor(cwd?: string): Promise<void>;
2
+ //# sourceMappingURL=doctor.d.ts.map
package/dist/doctor.js ADDED
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runDoctor = runDoctor;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const http = __importStar(require("http"));
41
+ const colors_1 = require("./utils/colors");
42
+ const tokens_1 = require("./utils/tokens");
43
+ async function runDoctor(cwd) {
44
+ const dir = cwd || process.cwd();
45
+ console.log('\n' + (0, colors_1.boldCyan)('claude-context --doctor') + '\n');
46
+ const issues = [];
47
+ const suggestions = [];
48
+ // 1. Check if CLAUDE.md exists
49
+ const claudeMdPath = path.join(dir, 'CLAUDE.md');
50
+ if (!fs.existsSync(claudeMdPath)) {
51
+ issues.push({
52
+ severity: 'high',
53
+ text: 'No CLAUDE.md found. Run `npx claude-context` to generate one.',
54
+ });
55
+ }
56
+ else {
57
+ const claudeSize = fs.readFileSync(claudeMdPath, 'utf8').length;
58
+ const claudeTokens = (0, tokens_1.estimateTokens)(fs.readFileSync(claudeMdPath, 'utf8'));
59
+ if (claudeTokens > 2000) {
60
+ issues.push({
61
+ severity: 'medium',
62
+ text: `CLAUDE.md is ${claudeTokens} tokens. Keep it under 1000 for Layer 1 -- move details to ai-docs/.`,
63
+ });
64
+ }
65
+ else {
66
+ suggestions.push(`CLAUDE.md is lean (${claudeTokens} tokens) -- good.`);
67
+ }
68
+ }
69
+ // 2. Check global CLAUDE.md
70
+ const globalClaudeMd = path.join(os.homedir(), '.claude', 'CLAUDE.md');
71
+ if (fs.existsSync(globalClaudeMd)) {
72
+ const globalSize = (0, tokens_1.estimateTokens)(fs.readFileSync(globalClaudeMd, 'utf8'));
73
+ if (globalSize > 3000) {
74
+ issues.push({
75
+ severity: 'medium',
76
+ text: `~/.claude/CLAUDE.md is ${globalSize} tokens. Large global instructions burn tokens in every project.`,
77
+ });
78
+ }
79
+ }
80
+ // 3. Check if proxy is running
81
+ try {
82
+ await new Promise((resolve) => {
83
+ const req = http.get('http://localhost:8787/health', (res) => {
84
+ suggestions.push('Compression proxy is running on :8787 -- tool outputs are being compressed.');
85
+ res.resume();
86
+ resolve();
87
+ });
88
+ req.on('error', () => {
89
+ issues.push({
90
+ severity: 'high',
91
+ text: 'Compression proxy not running. Start it: `npx claude-context --proxy`',
92
+ });
93
+ resolve();
94
+ });
95
+ req.setTimeout(1000, () => {
96
+ req.destroy();
97
+ resolve();
98
+ });
99
+ });
100
+ }
101
+ catch {
102
+ issues.push({
103
+ severity: 'high',
104
+ text: 'Compression proxy not running. Tool outputs are flooding your context.',
105
+ });
106
+ }
107
+ // 4. Check ANTHROPIC_BASE_URL
108
+ if (!process.env.ANTHROPIC_BASE_URL || !process.env.ANTHROPIC_BASE_URL.includes('localhost')) {
109
+ issues.push({
110
+ severity: 'high',
111
+ text: 'ANTHROPIC_BASE_URL not set to localhost. Add to ~/.bashrc: export ANTHROPIC_BASE_URL=http://localhost:8787',
112
+ });
113
+ }
114
+ else {
115
+ suggestions.push('ANTHROPIC_BASE_URL points to proxy -- compression is active.');
116
+ }
117
+ // 5. Peak hours check
118
+ const now = new Date();
119
+ const estHour = parseInt(new Date(now.toLocaleString('en-US', { timeZone: 'America/New_York' })).getHours().toString(), 10);
120
+ if (estHour >= 10 && estHour < 16) {
121
+ issues.push({
122
+ severity: 'low',
123
+ text: `Currently peak hours (${estHour}:00 EST). Anthropic throttles rate limits 10AM-4PM EST. Consider working off-peak for heavy sessions.`,
124
+ });
125
+ }
126
+ else {
127
+ suggestions.push(`Off-peak hours (${estHour}:00 EST) -- rate limits are more generous.`);
128
+ }
129
+ // 6. Check ai-docs exist
130
+ if (!fs.existsSync(path.join(dir, 'ai-docs'))) {
131
+ issues.push({
132
+ severity: 'low',
133
+ text: 'No ai-docs/ directory. Run `npx claude-context` to generate domain docs and pattern library.',
134
+ });
135
+ }
136
+ // 7. Check MISTAKES.md
137
+ if (fs.existsSync(path.join(dir, 'ai-docs', 'MISTAKES.md'))) {
138
+ suggestions.push('MISTAKES.md exists -- Claude checks this before repeating errors.');
139
+ }
140
+ // 8. Check TOKEN-RULES.md
141
+ if (fs.existsSync(path.join(dir, 'ai-docs', 'TOKEN-RULES.md'))) {
142
+ suggestions.push('TOKEN-RULES.md exists -- Claude stays lean and direct.');
143
+ }
144
+ // Display results
145
+ const highCount = issues.filter((i) => i.severity === 'high').length;
146
+ const medCount = issues.filter((i) => i.severity === 'medium').length;
147
+ const lowCount = issues.filter((i) => i.severity === 'low').length;
148
+ if (issues.length === 0) {
149
+ console.log((0, colors_1.boldGreen)('No issues found. Your token setup looks solid.\n'));
150
+ }
151
+ else {
152
+ console.log((0, colors_1.bold)('Issues found: ') +
153
+ (highCount > 0 ? (0, colors_1.red)(`${highCount} critical`) : '') +
154
+ (medCount > 0 ? ' ' + (0, colors_1.yellow)(`${medCount} medium`) : '') +
155
+ (lowCount > 0 ? ' ' + (0, colors_1.gray)(`${lowCount} low`) : '') +
156
+ '\n');
157
+ for (const issue of issues) {
158
+ const icon = issue.severity === 'high'
159
+ ? (0, colors_1.red)('!!')
160
+ : issue.severity === 'medium'
161
+ ? (0, colors_1.yellow)(' !')
162
+ : (0, colors_1.gray)(' -');
163
+ console.log(' ' + icon + ' ' + issue.text);
164
+ }
165
+ }
166
+ if (suggestions.length > 0) {
167
+ console.log('\n' + (0, colors_1.bold)('Status:'));
168
+ for (const suggestion of suggestions) {
169
+ console.log(' ' + (0, colors_1.green)('+') + ' ' + suggestion);
170
+ }
171
+ }
172
+ // Score
173
+ const maxScore = 100;
174
+ let score = maxScore - highCount * 20 - medCount * 10 - lowCount * 5;
175
+ score = Math.max(0, Math.min(100, score));
176
+ const scoreColor = score >= 80 ? colors_1.boldGreen : score >= 50 ? colors_1.boldYellow : colors_1.red;
177
+ console.log('\n' + (0, colors_1.bold)('Token efficiency score: ') + scoreColor(`${score}/100`));
178
+ if (score < 80) {
179
+ console.log('\n' + (0, colors_1.bold)('Quick wins:'));
180
+ if (!process.env.ANTHROPIC_BASE_URL || !process.env.ANTHROPIC_BASE_URL.includes('localhost')) {
181
+ console.log(' 1. ' + (0, colors_1.cyan)('npx claude-context --proxy') + ' (start in separate terminal)');
182
+ console.log(' ' + (0, colors_1.cyan)('export ANTHROPIC_BASE_URL=http://localhost:8787') + ' (add to shell rc)');
183
+ }
184
+ if (!fs.existsSync(claudeMdPath)) {
185
+ console.log(' 2. ' + (0, colors_1.cyan)('npx claude-context') + ' (generate context system)');
186
+ }
187
+ console.log(' 3. ' + (0, colors_1.cyan)('npx claude-context --learn') + ' (learn from past mistakes)');
188
+ }
189
+ console.log('');
190
+ }
191
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1,35 @@
1
+ import { StackInfo } from './scanner';
2
+ export interface GeneratorOptions {
3
+ force?: boolean;
4
+ dryRun?: boolean;
5
+ }
6
+ export interface Answers {
7
+ domains?: string[];
8
+ alwaysDocs?: string[];
9
+ conventions?: string[];
10
+ alwaysUse?: string[];
11
+ preferredOrm?: string;
12
+ deployment?: string;
13
+ gitFlow?: boolean;
14
+ never?: string[];
15
+ [key: string]: unknown;
16
+ }
17
+ interface FileEntry {
18
+ filename: string;
19
+ label: string;
20
+ key?: string;
21
+ }
22
+ declare function claudeMd(stack: StackInfo, answers: Answers): string;
23
+ declare const ALL_DOMAIN_DOCS: FileEntry[];
24
+ declare const SKILL_FILES: FileEntry[];
25
+ declare const EXTRA_FILES: FileEntry[];
26
+ declare function getDomainFiles(stack: StackInfo, answers: Answers): FileEntry[];
27
+ declare function generateDomainDoc(filename: string, stack: StackInfo): string;
28
+ declare function generatePromptFile(filename: string, stack: StackInfo): string;
29
+ declare function getPromptFiles(stack: StackInfo, answers: Answers): FileEntry[];
30
+ declare function generateSkillFile(filename: string): string;
31
+ declare function generateExtraFile(filename: string, stack: StackInfo): string;
32
+ export declare function generateContextFiles(projectDir: string, stack: StackInfo, options: GeneratorOptions, answers?: Answers): void;
33
+ export { claudeMd, generateDomainDoc, getDomainFiles, ALL_DOMAIN_DOCS, generatePromptFile, getPromptFiles, generateSkillFile, SKILL_FILES, generateExtraFile, EXTRA_FILES, };
34
+ export type { FileEntry };
35
+ //# sourceMappingURL=generator.d.ts.map