stay-fresh-lsp-proxy 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,25 @@
1
+ {
2
+ "name": "stay-fresh-lsp-proxy",
3
+ "description": "LSP proxy plugins that filter diagnostic noise from Claude Code",
4
+ "owner": { "name": "acreeger" },
5
+ "plugins": [
6
+ {
7
+ "name": "stay-fresh-typescript",
8
+ "source": "./plugins/stay-fresh-typescript",
9
+ "description": "TypeScript/JavaScript LSP with diagnostic filtering",
10
+ "version": "0.1.0"
11
+ },
12
+ {
13
+ "name": "stay-fresh-python",
14
+ "source": "./plugins/stay-fresh-python",
15
+ "description": "Python (Pyright) LSP with diagnostic filtering",
16
+ "version": "0.1.0"
17
+ },
18
+ {
19
+ "name": "stay-fresh-rust",
20
+ "source": "./plugins/stay-fresh-rust",
21
+ "description": "Rust LSP with diagnostic filtering",
22
+ "version": "0.1.0"
23
+ }
24
+ ]
25
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 iloom-ai
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,198 @@
1
+ # stay-fresh-lsp-proxy
2
+
3
+ Stop stale LSP diagnostics from derailing your Claude Code sessions.
4
+
5
+ > **Note:** This is a temporary workaround for issues with how Claude Code handles LSP diagnostics. Once the underlying problems are fixed upstream, this plugin will no longer be necessary. Relevant issues:
6
+ >
7
+ > - [LSP output displays stale diagnostics after file changes (#17979)](https://github.com/anthropics/claude-code/issues/17979)
8
+ > - [pyright-lsp plugin promotes hint-level DiagnosticTag.Unnecessary into conversation context (#26634)](https://github.com/anthropics/claude-code/issues/26634)
9
+ > - [TypeScript LSP plugin scans file paths in user prompt text, injecting unwanted diagnostics (#28562)](https://github.com/anthropics/claude-code/issues/28562)
10
+
11
+ ## The Problem
12
+
13
+ Claude Code's LSP plugins fire `textDocument/publishDiagnostics` after every edit. The diagnostics arrive from the previous state of the file — not the current one. Claude sees these stale errors, thinks the code is broken, and tries to "fix" problems that don't exist. This leads to:
14
+
15
+ - **Unnecessary reverts** — Claude undoes correct work because a stale diagnostic says there's an error
16
+ - **Fix loops** — Claude chases phantom type errors that would resolve on their own after the next save
17
+ - **Wasted turns** — every edit triggers a round of outdated warnings that Claude has to reason about
18
+
19
+ The root cause is a timing issue: diagnostics lag behind edits, so Claude is always reacting to the *previous* state of your code.
20
+
21
+ ## How It Works
22
+
23
+ stay-fresh-lsp-proxy sits between Claude Code and your LSP server. It forwards everything normally (go-to-definition, hover, references, completions) but intercepts `textDocument/publishDiagnostics` notifications and filters them before they reach Claude. No stale diagnostics, no confused AI.
24
+
25
+ ## Quick Install
26
+
27
+ ```bash
28
+ npx stay-fresh-lsp-proxy setup --typescript --python --rust
29
+ ```
30
+
31
+ Pick only the languages you need:
32
+
33
+ ```bash
34
+ npx stay-fresh-lsp-proxy setup --typescript # Just TypeScript/JS
35
+ npx stay-fresh-lsp-proxy setup --typescript --python # TypeScript + Python
36
+ npx stay-fresh-lsp-proxy setup --rust # Just Rust
37
+ ```
38
+
39
+ This will:
40
+ 1. Install the `stay-fresh-lsp-proxy` binary globally
41
+ 2. Register the plugin marketplace with Claude Code
42
+ 3. Install per-language plugins and disable conflicting official LSP plugins
43
+ 4. Enable the LSP tool in Claude Code settings
44
+
45
+ ## Supported Languages
46
+
47
+ | Language | LSP Server | Install the server |
48
+ |----------|-----------|-------------------|
49
+ | TypeScript/JS | `typescript-language-server` | `npm i -g typescript-language-server typescript` |
50
+ | Python | `pyright-langserver` | `npm i -g pyright` |
51
+ | Rust | `rust-analyzer` | `rustup component add rust-analyzer` |
52
+
53
+ The setup script will warn you if the required LSP server binary is not found in your PATH.
54
+
55
+ ## Configuration
56
+
57
+ Control filtering behavior with environment variables. Set them in `~/.claude/settings.json` under `env`:
58
+
59
+ ```json
60
+ {
61
+ "env": {
62
+ "STAY_FRESH_DROP_DIAGNOSTICS": "true",
63
+ "STAY_FRESH_MIN_SEVERITY": "1",
64
+ "STAY_FRESH_LOG": "false"
65
+ }
66
+ }
67
+ ```
68
+
69
+ ### Configuration Reference
70
+
71
+ | Variable | Default | Description |
72
+ |----------|---------|-------------|
73
+ | `STAY_FRESH_DROP_DIAGNOSTICS` | `true` | Drop all diagnostics. Set to `false` to use severity filtering instead. |
74
+ | `STAY_FRESH_MIN_SEVERITY` | `1` | When not dropping all, the maximum severity level to keep. `1` = only errors, `2` = errors + warnings, `3` = errors + warnings + info, `4` = everything (same as no filter). |
75
+ | `STAY_FRESH_LOG` | `false` | Enable debug logging to `$TMPDIR/stay-fresh-lsp-proxy/`. |
76
+
77
+ ### Recipes
78
+
79
+ **Drop everything (default)** — The nuclear option. Eliminates all stale diagnostics completely. Claude keeps full LSP intelligence (go-to-definition, hover, etc.) but never gets misleading error reports mid-edit.
80
+
81
+ ```json
82
+ {
83
+ "env": {
84
+ "STAY_FRESH_DROP_DIAGNOSTICS": "true"
85
+ }
86
+ }
87
+ ```
88
+
89
+ **Errors only** — Let genuine errors through (type mismatches, missing imports, syntax errors) but suppress warnings, hints, and info. Good if you want Claude to catch real breakage while ignoring the noise.
90
+
91
+ ```json
92
+ {
93
+ "env": {
94
+ "STAY_FRESH_DROP_DIAGNOSTICS": "false",
95
+ "STAY_FRESH_MIN_SEVERITY": "1"
96
+ }
97
+ }
98
+ ```
99
+
100
+ **Errors + Warnings** — Also keep warnings (unused variables, deprecated APIs) but drop hints and info. You'll still get some stale notifications, but you're trading that off against Claude occasionally catching real issues it wouldn't otherwise notice.
101
+
102
+ ```json
103
+ {
104
+ "env": {
105
+ "STAY_FRESH_DROP_DIAGNOSTICS": "false",
106
+ "STAY_FRESH_MIN_SEVERITY": "2"
107
+ }
108
+ }
109
+ ```
110
+
111
+ **Everything except hints** — Only drop hint-level diagnostics (like pyright's "unnecessary" markers that prompted [#26634](https://github.com/anthropics/claude-code/issues/26634)). Closest to stock behavior with the worst offenders removed.
112
+
113
+ ```json
114
+ {
115
+ "env": {
116
+ "STAY_FRESH_DROP_DIAGNOSTICS": "false",
117
+ "STAY_FRESH_MIN_SEVERITY": "3"
118
+ }
119
+ }
120
+ ```
121
+
122
+ **Debug mode** — Combine with any of the above. Logs every intercepted diagnostic to `$TMPDIR/stay-fresh-lsp-proxy/` so you can verify the proxy is running and see exactly what it's dropping.
123
+
124
+ ```json
125
+ {
126
+ "env": {
127
+ "STAY_FRESH_LOG": "true"
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### LSP Severity Levels
133
+
134
+ | Level | Meaning | Examples |
135
+ |-------|---------|---------|
136
+ | 1 — Error | Code is broken | Type errors, missing imports, syntax errors |
137
+ | 2 — Warning | Likely problems | Unused variables, deprecated API usage |
138
+ | 3 — Info | Informational | Suggested refactors, style improvements |
139
+ | 4 — Hint | Subtle suggestions | Unnecessary casts, removable parentheses |
140
+
141
+ ## Manual Install
142
+
143
+ If you prefer to set things up manually instead of using the setup script:
144
+
145
+ 1. Install the proxy globally:
146
+ ```bash
147
+ npm install -g stay-fresh-lsp-proxy
148
+ ```
149
+
150
+ 2. Add the marketplace:
151
+ ```bash
152
+ claude plugin marketplace add iloom-ai/stay-fresh-lsp-proxy
153
+ ```
154
+
155
+ 3. Install the plugin(s) you want:
156
+ ```bash
157
+ claude plugin install stay-fresh-typescript@stay-fresh-lsp-proxy
158
+ claude plugin install stay-fresh-python@stay-fresh-lsp-proxy
159
+ claude plugin install stay-fresh-rust@stay-fresh-lsp-proxy
160
+ ```
161
+
162
+ 4. Disable conflicting official plugins:
163
+ ```bash
164
+ claude plugin disable typescript-lsp@claude-plugins-official
165
+ claude plugin disable pyright-lsp@claude-plugins-official
166
+ claude plugin disable rust-analyzer-lsp@claude-plugins-official
167
+ ```
168
+
169
+ 5. Enable the LSP tool in `~/.claude/settings.json`:
170
+ ```json
171
+ {
172
+ "env": {
173
+ "ENABLE_LSP_TOOL": "1"
174
+ }
175
+ }
176
+ ```
177
+
178
+ 6. Restart Claude Code.
179
+
180
+ ## Uninstall
181
+
182
+ ```bash
183
+ npx stay-fresh-lsp-proxy setup --uninstall
184
+ ```
185
+
186
+ This removes all stay-fresh plugins, the marketplace registration, the `ENABLE_LSP_TOOL` setting, and the global package.
187
+
188
+ ## Built by iloom
189
+
190
+ [iloom](https://iloom.ai) is an AI development control plane for Claude Code. Decompose work into issues, swarm parallel agents across a dependency graph, and ship with full reasoning trails for every decision. Free to use — just bring your Claude Code subscription.
191
+
192
+ [CLI](https://github.com/iloom-ai/iloom-cli) | [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=iloom-ai.iloom)
193
+
194
+ ![iloom VS Code](https://github.com/iloom-ai/iloom-vscode-support/raw/HEAD/assets/iloom-vscode-screenshot-4.png)
195
+
196
+ ## License
197
+
198
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { main as setupMain } from "./setup.js";
3
+ import { startProxy } from "./proxy.js";
4
+ const firstArg = process.argv[2];
5
+ if (firstArg === "setup") {
6
+ // Remove "setup" from argv so setup's parseArgs sees the flags directly
7
+ process.argv.splice(2, 1);
8
+ setupMain();
9
+ }
10
+ else {
11
+ startProxy();
12
+ }
13
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEjC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;IACzB,wEAAwE;IACxE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,SAAS,EAAE,CAAC;AACd,CAAC;KAAM,CAAC;IACN,UAAU,EAAE,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function startProxy(): void;
package/dist/proxy.js ADDED
@@ -0,0 +1,136 @@
1
+ import { spawn } from "node:child_process";
2
+ import { appendFileSync, mkdirSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ const CONTENT_LENGTH_HEADER = "Content-Length: ";
6
+ const logDir = join(tmpdir(), "stay-fresh-lsp-proxy");
7
+ const logFile = join(logDir, `proxy-${Date.now()}.log`);
8
+ const config = {
9
+ dropAll: process.env.STAY_FRESH_DROP_DIAGNOSTICS !== "false",
10
+ minSeverity: parseInt(process.env.STAY_FRESH_MIN_SEVERITY || "1", 10),
11
+ debug: process.env.STAY_FRESH_LOG === "true",
12
+ };
13
+ if (config.debug) {
14
+ mkdirSync(logDir, { recursive: true });
15
+ }
16
+ function log(...args) {
17
+ if (config.debug) {
18
+ const timestamp = new Date().toISOString();
19
+ appendFileSync(logFile, `[${timestamp}] ${args.join(" ")}\n`);
20
+ }
21
+ }
22
+ function encodeMessage(msg) {
23
+ const body = Buffer.from(JSON.stringify(msg), "utf-8");
24
+ const header = `${CONTENT_LENGTH_HEADER}${body.length}\r\n\r\n`;
25
+ return Buffer.concat([Buffer.from(header, "ascii"), body]);
26
+ }
27
+ function filterDiagnostics(msg) {
28
+ if (msg.method !== "textDocument/publishDiagnostics") {
29
+ return msg;
30
+ }
31
+ if (config.dropAll) {
32
+ log(`Dropping diagnostics for ${msg.params?.uri}`);
33
+ return null;
34
+ }
35
+ const params = msg.params;
36
+ const filtered = params.diagnostics.filter((d) => {
37
+ const severity = d.severity ?? 1;
38
+ return severity <= config.minSeverity;
39
+ });
40
+ log(`Filtered diagnostics for ${params.uri}: ${params.diagnostics.length} → ${filtered.length}`);
41
+ return {
42
+ ...msg,
43
+ params: { ...params, diagnostics: filtered },
44
+ };
45
+ }
46
+ /**
47
+ * Parses LSP messages from a raw byte stream.
48
+ * LSP uses Content-Length headers followed by JSON-RPC bodies.
49
+ */
50
+ class MessageParser {
51
+ buffer = Buffer.alloc(0);
52
+ contentLength = null;
53
+ feed(chunk, onMessage) {
54
+ this.buffer = Buffer.concat([this.buffer, chunk]);
55
+ this.drain(onMessage);
56
+ }
57
+ drain(onMessage) {
58
+ while (true) {
59
+ if (this.contentLength === null) {
60
+ const headerEnd = this.buffer.indexOf("\r\n\r\n");
61
+ if (headerEnd === -1)
62
+ return;
63
+ const headerBlock = this.buffer.subarray(0, headerEnd).toString("ascii");
64
+ const match = headerBlock.match(/Content-Length:\s*(\d+)/i);
65
+ if (!match) {
66
+ log("Malformed header, skipping:", headerBlock);
67
+ this.buffer = this.buffer.subarray(headerEnd + 4);
68
+ continue;
69
+ }
70
+ this.contentLength = parseInt(match[1], 10);
71
+ this.buffer = this.buffer.subarray(headerEnd + 4);
72
+ }
73
+ if (this.buffer.length < this.contentLength)
74
+ return;
75
+ const body = this.buffer.subarray(0, this.contentLength).toString("utf-8");
76
+ this.buffer = this.buffer.subarray(this.contentLength);
77
+ this.contentLength = null;
78
+ try {
79
+ onMessage(JSON.parse(body));
80
+ }
81
+ catch (e) {
82
+ log("Failed to parse JSON:", body.substring(0, 200));
83
+ }
84
+ }
85
+ }
86
+ }
87
+ export function startProxy() {
88
+ const [command, ...args] = process.argv.slice(2);
89
+ if (!command) {
90
+ process.stderr.write("Usage: stay-fresh-lsp-proxy <lsp-command> [args...]\n" +
91
+ "\n" +
92
+ "Environment variables:\n" +
93
+ " STAY_FRESH_DROP_DIAGNOSTICS=true Drop all diagnostics (default: true)\n" +
94
+ " STAY_FRESH_MIN_SEVERITY=1 Min severity to keep (1=Error..4=Hint)\n" +
95
+ " STAY_FRESH_LOG=true Debug logging to $TMPDIR/stay-fresh-lsp-proxy/\n");
96
+ process.exit(1);
97
+ }
98
+ log(`Starting proxy for: ${command} ${args.join(" ")}`);
99
+ log(`Config: dropAll=${config.dropAll}, minSeverity=${config.minSeverity}`);
100
+ const child = spawn(command, args, {
101
+ stdio: ["pipe", "pipe", "pipe"],
102
+ });
103
+ child.on("error", (err) => {
104
+ process.stderr.write(`Failed to start LSP server: ${err.message}\n`);
105
+ process.exit(1);
106
+ });
107
+ child.on("exit", (code) => {
108
+ log(`LSP server exited with code ${code}`);
109
+ process.exit(code ?? 0);
110
+ });
111
+ // Client → Server: forward stdin transparently
112
+ process.stdin.on("data", (chunk) => {
113
+ child.stdin.write(chunk);
114
+ });
115
+ process.stdin.on("end", () => {
116
+ child.stdin.end();
117
+ });
118
+ // Server → Client: intercept and filter diagnostics
119
+ const parser = new MessageParser();
120
+ child.stdout.on("data", (chunk) => {
121
+ parser.feed(chunk, (msg) => {
122
+ const filtered = filterDiagnostics(msg);
123
+ if (filtered) {
124
+ process.stdout.write(encodeMessage(filtered));
125
+ }
126
+ });
127
+ });
128
+ // Forward stderr from LSP server
129
+ if (child.stderr) {
130
+ child.stderr.pipe(process.stderr);
131
+ }
132
+ // Clean shutdown
133
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
134
+ process.on("SIGINT", () => child.kill("SIGINT"));
135
+ }
136
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAwCjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;AACtD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAExD,MAAM,MAAM,GAAG;IACb,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,OAAO;IAC5D,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,GAAG,EAAE,EAAE,CAAC;IACrE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM;CAC7C,CAAC;AAEF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,GAAG,CAAC,GAAG,IAAe;IAC7B,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,cAAc,CAAC,OAAO,EAAE,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAe;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,GAAG,qBAAqB,GAAG,IAAI,CAAC,MAAM,UAAU,CAAC;IAChE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAe;IACxC,IAAI,GAAG,CAAC,MAAM,KAAK,iCAAiC,EAAE,CAAC;QACrD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,GAAG,CAAC,4BAA6B,GAAG,CAAC,MAAmC,EAAE,GAAG,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,MAAkC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/C,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;QACjC,OAAO,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,GAAG,CACD,4BAA4B,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,WAAW,CAAC,MAAM,MAAM,QAAQ,CAAC,MAAM,EAAE,CAC5F,CAAC;IAEF,OAAO;QACL,GAAG,GAAG;QACN,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE;KAC7C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,aAAa;IACT,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,aAAa,GAAkB,IAAI,CAAC;IAE5C,IAAI,CAAC,KAAa,EAAE,SAAoC;QACtD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,SAAoC;QAChD,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAClD,IAAI,SAAS,KAAK,CAAC,CAAC;oBAAE,OAAO;gBAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACzE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;gBAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,GAAG,CAAC,6BAA6B,EAAE,WAAW,CAAC,CAAC;oBAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;oBAClD,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC5C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa;gBAAE,OAAO;YAEpD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACvD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAE1B,IAAI,CAAC;gBACH,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,GAAG,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uDAAuD;YACrD,IAAI;YACJ,0BAA0B;YAC1B,6EAA6E;YAC7E,+EAA+E;YAC/E,uFAAuF,CAC1F,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,uBAAuB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxD,GAAG,CAAC,mBAAmB,MAAM,CAAC,OAAO,iBAAiB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAE5E,MAAM,KAAK,GAAiB,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;QAC/C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,GAAG,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACzC,KAAK,CAAC,KAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QAC3B,KAAK,CAAC,KAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,oDAAoD;IACpD,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IAEnC,KAAK,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;YAChD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,iCAAiC;IACjC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,iBAAiB;IACjB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function main(): void;
package/dist/setup.js ADDED
@@ -0,0 +1,315 @@
1
+ import { parseArgs } from "node:util";
2
+ import { execSync } from "node:child_process";
3
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { homedir } from "node:os";
6
+ const MARKETPLACE_ID = "iloom-ai/stay-fresh-lsp-proxy";
7
+ const MARKETPLACE_NAME = "stay-fresh-lsp-proxy";
8
+ const LANGUAGES = {
9
+ typescript: {
10
+ flag: "--typescript",
11
+ plugin: "stay-fresh-typescript",
12
+ lspBinary: "typescript-language-server",
13
+ conflicts: "typescript-lsp@claude-plugins-official",
14
+ installHint: "npm i -g typescript-language-server typescript",
15
+ },
16
+ python: {
17
+ flag: "--python",
18
+ plugin: "stay-fresh-python",
19
+ lspBinary: "pyright-langserver",
20
+ conflicts: "pyright-lsp@claude-plugins-official",
21
+ installHint: "npm i -g pyright",
22
+ },
23
+ rust: {
24
+ flag: "--rust",
25
+ plugin: "stay-fresh-rust",
26
+ lspBinary: "rust-analyzer",
27
+ conflicts: "rust-analyzer-lsp@claude-plugins-official",
28
+ installHint: "rustup component add rust-analyzer",
29
+ },
30
+ };
31
+ function printUsage() {
32
+ console.log(`
33
+ stay-fresh-lsp-proxy setup — Install stay-fresh LSP proxy plugins for Claude Code
34
+
35
+ Usage:
36
+ npx stay-fresh-lsp-proxy setup --typescript --python --rust
37
+ npx stay-fresh-lsp-proxy setup --uninstall
38
+
39
+ Options:
40
+ --typescript Install TypeScript/JavaScript LSP proxy
41
+ --python Install Python (Pyright) LSP proxy
42
+ --rust Install Rust LSP proxy
43
+ --uninstall Remove all stay-fresh plugins and cleanup
44
+ --help Show this help message
45
+
46
+ Examples:
47
+ npx stay-fresh-lsp-proxy setup --typescript # Just TypeScript
48
+ npx stay-fresh-lsp-proxy setup --typescript --python # TypeScript + Python
49
+ npx stay-fresh-lsp-proxy setup --typescript --python --rust # All languages
50
+ npx stay-fresh-lsp-proxy setup --uninstall # Remove everything
51
+ `);
52
+ }
53
+ function run(cmd, options) {
54
+ try {
55
+ const result = execSync(cmd, { encoding: "utf-8", stdio: "pipe", ...options });
56
+ return result.trim();
57
+ }
58
+ catch (e) {
59
+ const err = e;
60
+ const stderr = typeof err.stderr === "string" ? err.stderr.trim() : undefined;
61
+ throw new Error(stderr || err.message || `Command failed: ${cmd}`);
62
+ }
63
+ }
64
+ function runQuiet(cmd) {
65
+ try {
66
+ execSync(cmd, { encoding: "utf-8", stdio: "pipe" });
67
+ return true;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ function isBinaryInPath(binary) {
74
+ return runQuiet(`which ${binary}`);
75
+ }
76
+ function isClaudeInstalled() {
77
+ return isBinaryInPath("claude");
78
+ }
79
+ function ensureEnableLspTool() {
80
+ const settingsPath = join(homedir(), ".claude", "settings.json");
81
+ let settings = {};
82
+ if (existsSync(settingsPath)) {
83
+ try {
84
+ settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
85
+ }
86
+ catch {
87
+ console.warn(" Warning: Could not parse ~/.claude/settings.json, creating fresh");
88
+ settings = {};
89
+ }
90
+ }
91
+ else {
92
+ const dir = join(homedir(), ".claude");
93
+ if (!existsSync(dir)) {
94
+ mkdirSync(dir, { recursive: true });
95
+ }
96
+ }
97
+ const env = (settings.env || {});
98
+ if (env.ENABLE_LSP_TOOL === "1") {
99
+ console.log(" ENABLE_LSP_TOOL already set");
100
+ return;
101
+ }
102
+ env.ENABLE_LSP_TOOL = "1";
103
+ settings.env = env;
104
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
105
+ console.log(" Set ENABLE_LSP_TOOL=1 in ~/.claude/settings.json");
106
+ }
107
+ function removeEnableLspTool() {
108
+ const settingsPath = join(homedir(), ".claude", "settings.json");
109
+ if (!existsSync(settingsPath))
110
+ return;
111
+ let settings;
112
+ try {
113
+ settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
114
+ }
115
+ catch {
116
+ return;
117
+ }
118
+ const env = settings.env;
119
+ if (!env || !("ENABLE_LSP_TOOL" in env))
120
+ return;
121
+ delete env.ENABLE_LSP_TOOL;
122
+ if (Object.keys(env).length === 0) {
123
+ delete settings.env;
124
+ }
125
+ else {
126
+ settings.env = env;
127
+ }
128
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
129
+ console.log(" Removed ENABLE_LSP_TOOL from ~/.claude/settings.json");
130
+ }
131
+ function install(requested) {
132
+ console.log("\nstay-fresh-setup: Installing LSP proxy plugins\n");
133
+ // Step 1: Install the proxy binary globally
134
+ console.log("Step 1: Installing stay-fresh-lsp-proxy globally...");
135
+ if (isBinaryInPath("stay-fresh-lsp-proxy")) {
136
+ console.log(" stay-fresh-lsp-proxy already installed");
137
+ }
138
+ else {
139
+ try {
140
+ run("npm install -g stay-fresh-lsp-proxy");
141
+ console.log(" Installed stay-fresh-lsp-proxy globally");
142
+ }
143
+ catch {
144
+ // Package may not be on npm yet — try GitHub install
145
+ try {
146
+ run("npm install -g github:iloom-ai/stay-fresh-lsp-proxy");
147
+ console.log(" Installed stay-fresh-lsp-proxy globally (from GitHub)");
148
+ }
149
+ catch (e2) {
150
+ const err = e2;
151
+ console.error(` Error installing globally: ${err.message}`);
152
+ console.error(" You may need to run with sudo or fix your npm prefix");
153
+ process.exit(1);
154
+ }
155
+ }
156
+ }
157
+ // Step 2: Check for LSP server binaries
158
+ console.log("\nStep 2: Checking LSP server binaries...");
159
+ const warnings = [];
160
+ for (const lang of requested) {
161
+ const config = LANGUAGES[lang];
162
+ if (isBinaryInPath(config.lspBinary)) {
163
+ console.log(` ${config.lspBinary} found`);
164
+ }
165
+ else {
166
+ const msg = `${config.lspBinary} not found. Install with: ${config.installHint}`;
167
+ warnings.push(msg);
168
+ console.warn(` Warning: ${msg}`);
169
+ }
170
+ }
171
+ // Step 3: Add marketplace
172
+ console.log("\nStep 3: Adding stay-fresh marketplace...");
173
+ try {
174
+ run(`claude plugin marketplace add ${MARKETPLACE_ID}`);
175
+ console.log(" Marketplace added");
176
+ }
177
+ catch (e) {
178
+ const err = e;
179
+ // Marketplace might already be added
180
+ if (err.message.includes("already")) {
181
+ console.log(" Marketplace already added");
182
+ }
183
+ else {
184
+ console.error(` Error adding marketplace: ${err.message}`);
185
+ process.exit(1);
186
+ }
187
+ }
188
+ // Step 4: Install plugins and disable conflicts
189
+ console.log("\nStep 4: Installing plugins...");
190
+ const installed = [];
191
+ for (const lang of requested) {
192
+ const config = LANGUAGES[lang];
193
+ const pluginRef = `${config.plugin}@${MARKETPLACE_NAME}`;
194
+ try {
195
+ run(`claude plugin install ${pluginRef}`);
196
+ console.log(` Installed ${pluginRef}`);
197
+ installed.push(lang);
198
+ }
199
+ catch (e) {
200
+ const err = e;
201
+ if (err.message.includes("already")) {
202
+ console.log(` ${pluginRef} already installed`);
203
+ installed.push(lang);
204
+ }
205
+ else {
206
+ console.error(` Error installing ${pluginRef}: ${err.message}`);
207
+ }
208
+ }
209
+ // Disable conflicting official plugin
210
+ try {
211
+ run(`claude plugin disable ${config.conflicts}`);
212
+ console.log(` Disabled conflicting ${config.conflicts}`);
213
+ }
214
+ catch {
215
+ // Official plugin might not be installed — that's fine
216
+ }
217
+ }
218
+ // Step 5: Enable LSP tool
219
+ console.log("\nStep 5: Enabling LSP tool...");
220
+ ensureEnableLspTool();
221
+ // Summary
222
+ console.log("\n--- Setup Complete ---");
223
+ if (installed.length > 0) {
224
+ console.log(`Installed plugins: ${installed.join(", ")}`);
225
+ }
226
+ if (warnings.length > 0) {
227
+ console.log("\nWarnings:");
228
+ for (const w of warnings) {
229
+ console.log(` - ${w}`);
230
+ }
231
+ }
232
+ console.log("\nRestart Claude Code for changes to take effect.");
233
+ }
234
+ function uninstall() {
235
+ console.log("\nstay-fresh-setup: Uninstalling LSP proxy plugins\n");
236
+ // Step 1: Uninstall all language plugins
237
+ console.log("Step 1: Removing plugins...");
238
+ for (const [, config] of Object.entries(LANGUAGES)) {
239
+ const pluginRef = `${config.plugin}@${MARKETPLACE_NAME}`;
240
+ try {
241
+ run(`claude plugin uninstall ${pluginRef}`);
242
+ console.log(` Removed ${pluginRef}`);
243
+ }
244
+ catch {
245
+ console.log(` ${pluginRef} not installed (skipping)`);
246
+ }
247
+ }
248
+ // Step 2: Remove marketplace
249
+ console.log("\nStep 2: Removing marketplace...");
250
+ try {
251
+ run(`claude plugin marketplace rm ${MARKETPLACE_NAME}`);
252
+ console.log(" Marketplace removed");
253
+ }
254
+ catch {
255
+ console.log(" Marketplace not found (skipping)");
256
+ }
257
+ // Step 3: Remove ENABLE_LSP_TOOL
258
+ console.log("\nStep 3: Cleaning up settings...");
259
+ removeEnableLspTool();
260
+ // Step 4: Uninstall global package
261
+ console.log("\nStep 4: Removing global package...");
262
+ if (isBinaryInPath("stay-fresh-lsp-proxy")) {
263
+ try {
264
+ run("npm uninstall -g stay-fresh-lsp-proxy");
265
+ console.log(" Removed stay-fresh-lsp-proxy globally");
266
+ }
267
+ catch {
268
+ console.log(" Could not remove global package (may need manual removal)");
269
+ }
270
+ }
271
+ else {
272
+ console.log(" Global package not found (skipping)");
273
+ }
274
+ console.log("\n--- Uninstall Complete ---");
275
+ console.log("Restart Claude Code for changes to take effect.");
276
+ }
277
+ export function main() {
278
+ const { values } = parseArgs({
279
+ options: {
280
+ typescript: { type: "boolean", default: false },
281
+ python: { type: "boolean", default: false },
282
+ rust: { type: "boolean", default: false },
283
+ uninstall: { type: "boolean", default: false },
284
+ help: { type: "boolean", short: "h", default: false },
285
+ },
286
+ strict: true,
287
+ });
288
+ if (values.help) {
289
+ printUsage();
290
+ process.exit(0);
291
+ }
292
+ if (!isClaudeInstalled()) {
293
+ console.error("Error: 'claude' CLI not found in PATH.");
294
+ console.error("Install Claude Code first: https://docs.anthropic.com/en/docs/claude-code");
295
+ process.exit(1);
296
+ }
297
+ if (values.uninstall) {
298
+ uninstall();
299
+ return;
300
+ }
301
+ const requested = [];
302
+ if (values.typescript)
303
+ requested.push("typescript");
304
+ if (values.python)
305
+ requested.push("python");
306
+ if (values.rust)
307
+ requested.push("rust");
308
+ if (requested.length === 0) {
309
+ console.error("Error: No languages specified.\n");
310
+ printUsage();
311
+ process.exit(1);
312
+ }
313
+ install(requested);
314
+ }
315
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAwB,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,cAAc,GAAG,+BAA+B,CAAC;AACvD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAUhD,MAAM,SAAS,GAAmC;IAChD,UAAU,EAAE;QACV,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,uBAAuB;QAC/B,SAAS,EAAE,4BAA4B;QACvC,SAAS,EAAE,wCAAwC;QACnD,WAAW,EAAE,gDAAgD;KAC9D;IACD,MAAM,EAAE;QACN,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,mBAAmB;QAC3B,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,qCAAqC;QAChD,WAAW,EAAE,kBAAkB;KAChC;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,iBAAiB;QACzB,SAAS,EAAE,eAAe;QAC1B,SAAS,EAAE,2CAA2C;QACtD,WAAW,EAAE,oCAAoC;KAClD;CACF,CAAC;AAEF,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBb,CAAC,CAAC;AACH,CAAC;AAED,SAAS,GAAG,CAAC,GAAW,EAAE,OAAyB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC/E,OAAQ,MAAiB,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAA0C,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,mBAAmB,GAAG,EAAE,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,QAAQ,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACjE,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAE3C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;YACnF,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAA2B,CAAC;IAC3D,IAAI,GAAG,CAAC,eAAe,KAAK,GAAG,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC;IAC1B,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO;IAEtC,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAyC,CAAC;IAC/D,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,iBAAiB,IAAI,GAAG,CAAC;QAAE,OAAO;IAEhD,OAAO,GAAG,CAAC,eAAe,CAAC;IAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC,GAAG,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;IACrB,CAAC;IAED,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,OAAO,CAAC,SAAmB;IAClC,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAElE,4CAA4C;IAC5C,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,IAAI,cAAc,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,GAAG,CAAC,qCAAqC,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;YACrD,IAAI,CAAC;gBACH,GAAG,CAAC,qDAAqD,CAAC,CAAC;gBAC3D,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACzE,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,MAAM,GAAG,GAAG,EAAW,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7D,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,SAAS,QAAQ,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,SAAS,6BAA6B,MAAM,CAAC,WAAW,EAAE,CAAC;YACjF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,GAAG,CAAC,iCAAiC,cAAc,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAU,CAAC;QACvB,qCAAqC;QACrC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAC;QAEzD,IAAI,CAAC;YACH,GAAG,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAU,CAAC;YACvB,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,oBAAoB,CAAC,CAAC;gBAChD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC;YACH,GAAG,CAAC,yBAAyB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,mBAAmB,EAAE,CAAC;IAEtB,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,sBAAsB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IAEpE,yCAAyC;IACzC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACnD,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,GAAG,CAAC,2BAA2B,SAAS,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,2BAA2B,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,GAAG,CAAC,gCAAgC,gBAAgB,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;IAED,iCAAiC;IACjC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,mBAAmB,EAAE,CAAC;IAEtB,mCAAmC;IACnC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,IAAI,cAAc,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,GAAG,CAAC,uCAAuC,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,OAAO,EAAE;YACP,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YAC/C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YAC3C,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YACzC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YAC9C,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;SACtD;QACD,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,UAAU;QAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,IAAI;QAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,SAAS,CAAC,CAAC;AACrB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "stay-fresh-lsp-proxy",
3
+ "version": "0.1.0",
4
+ "description": "A Claude Code plugin that proxies any LSP server and filters stale/noisy diagnostics from conversation context",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "bin": {
8
+ "stay-fresh-lsp-proxy": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "plugins/",
13
+ ".claude-plugin/"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "test": "vitest"
19
+ },
20
+ "keywords": [
21
+ "claude-code",
22
+ "lsp",
23
+ "proxy",
24
+ "diagnostics",
25
+ "plugin"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/iloom-ai/stay-fresh-lsp-proxy.git"
30
+ },
31
+ "homepage": "https://github.com/iloom-ai/stay-fresh-lsp-proxy#readme",
32
+ "bugs": {
33
+ "url": "https://github.com/iloom-ai/stay-fresh-lsp-proxy/issues"
34
+ },
35
+ "author": "acreeger",
36
+ "license": "MIT",
37
+ "packageManager": "pnpm@10.28.2",
38
+ "devDependencies": {
39
+ "@types/node": "^25.3.3",
40
+ "typescript": "^5.9.3",
41
+ "vitest": "^4.0.18"
42
+ }
43
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "stay-fresh-python",
3
+ "description": "Python (Pyright) LSP with diagnostic filtering via stay-fresh proxy",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "acreeger"
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "python": {
3
+ "command": "stay-fresh-lsp-proxy",
4
+ "args": ["pyright-langserver", "--stdio"],
5
+ "extensionToLanguage": {
6
+ ".py": "python"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "stay-fresh-rust",
3
+ "description": "Rust LSP with diagnostic filtering via stay-fresh proxy",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "acreeger"
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "rust": {
3
+ "command": "stay-fresh-lsp-proxy",
4
+ "args": ["rust-analyzer"],
5
+ "extensionToLanguage": {
6
+ ".rs": "rust"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "stay-fresh-typescript",
3
+ "description": "TypeScript/JavaScript LSP with diagnostic filtering via stay-fresh proxy",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "acreeger"
7
+ }
8
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "typescript": {
3
+ "command": "stay-fresh-lsp-proxy",
4
+ "args": ["typescript-language-server", "--stdio"],
5
+ "extensionToLanguage": {
6
+ ".ts": "typescript",
7
+ ".tsx": "typescriptreact",
8
+ ".js": "javascript",
9
+ ".jsx": "javascriptreact"
10
+ }
11
+ }
12
+ }