@lsproxy/cli 0.4.1 → 0.4.2
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/README.md +56 -31
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/program.d.ts +16 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +47 -0
- package/dist/program.js.map +1 -0
- package/package.json +8 -3
- package/skillit-postinstall.cjs +31 -0
- package/skills/cli/SKILL.md +171 -0
- package/skills/cli/references/commands.md +95 -0
- package/skills/lsproxy-cli/SKILL.md +50 -0
- package/skills/lsproxy-cli/references/classes.md +22 -0
- package/skills/lsproxy-cli/references/config.md +46 -0
- package/skills/lsproxy-cli/references/functions.md +58 -0
- package/skills/lsproxy-cli/references/types.md +45 -0
package/README.md
CHANGED
|
@@ -5,6 +5,15 @@ its capabilities as typed subcommands — hover, rename, format, find-references
|
|
|
5
5
|
code actions, and more. The command surface is built at runtime from the server's
|
|
6
6
|
advertised capabilities, so it works with any LSP server out of the box.
|
|
7
7
|
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Semantic refactoring** — project-wide rename, move-file with importer updates, extract symbol
|
|
11
|
+
- **Reference tracking** — find all references, call hierarchy, workspace symbol search
|
|
12
|
+
- **Code actions** — list and apply quick-fixes and refactors at any range
|
|
13
|
+
- **Any LSP server** — TypeScript, Rust, Python, Go, or any LSP-compliant server via `lsp.json`
|
|
14
|
+
- **Proxy daemon** — warm server connections for sub-100ms subsequent invocations
|
|
15
|
+
- **Dry-run preview** — `--dry-run` prints diffs without writing; safe to inspect before committing
|
|
16
|
+
|
|
8
17
|
## Install
|
|
9
18
|
|
|
10
19
|
```bash
|
|
@@ -12,6 +21,25 @@ npx @lsproxy/cli textDocument hover src/foo.ts 12:7 # zero-install
|
|
|
12
21
|
pnpm add -g @lsproxy/cli # or install globally
|
|
13
22
|
```
|
|
14
23
|
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Preview a rename before writing (always do this first)
|
|
28
|
+
lsproxy textDocument rename --dry-run src/auth/login.ts 42:15 "signIn"
|
|
29
|
+
|
|
30
|
+
# Find all references to a symbol
|
|
31
|
+
lsproxy textDocument references src/auth/login.ts 42:15
|
|
32
|
+
|
|
33
|
+
# List available code actions at a range, then apply the chosen one
|
|
34
|
+
lsproxy textDocument codeAction src/foo.ts 12:1-12:20
|
|
35
|
+
|
|
36
|
+
# Send any LSP method directly (useful for probing capabilities)
|
|
37
|
+
lsproxy call workspace/executeCommand --params '{"command":"typescript.reloadProjects"}'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Positions are **1-based** (`line:col`, editor-style).
|
|
41
|
+
Write-side commands apply changes to disk automatically — use `--dry-run` to preview first.
|
|
42
|
+
|
|
15
43
|
## Usage
|
|
16
44
|
|
|
17
45
|
```
|
|
@@ -19,52 +47,49 @@ lsproxy <namespace> <command> [args] [flags]
|
|
|
19
47
|
lsproxy call <method> --params <json>
|
|
20
48
|
```
|
|
21
49
|
|
|
22
|
-
Commands are built from the server's capabilities at startup:
|
|
50
|
+
Commands are built from the server's capabilities at startup. Available namespaces:
|
|
51
|
+
`callHierarchy`, `codeAction`, `codeLens`, `completionItem`, `documentLink`,
|
|
52
|
+
`inlayHint`, `textDocument`, `workspace`, `workspaceSymbol`.
|
|
23
53
|
|
|
24
54
|
```bash
|
|
25
|
-
lsproxy textDocument hover
|
|
26
|
-
lsproxy textDocument rename
|
|
27
|
-
lsproxy textDocument references
|
|
28
|
-
lsproxy textDocument definition
|
|
29
|
-
lsproxy textDocument formatting
|
|
55
|
+
lsproxy textDocument hover src/foo.ts 12:7
|
|
56
|
+
lsproxy textDocument rename src/foo.ts 12:7 newName
|
|
57
|
+
lsproxy textDocument references src/foo.ts 12:7
|
|
58
|
+
lsproxy textDocument definition src/foo.ts 12:7
|
|
59
|
+
lsproxy textDocument formatting src/foo.ts
|
|
30
60
|
lsproxy textDocument rangeFormatting src/foo.ts 1:1-50:1
|
|
31
|
-
lsproxy
|
|
32
|
-
lsproxy workspace symbol MyClass
|
|
61
|
+
lsproxy workspace symbol MyClass
|
|
33
62
|
lsproxy call textDocument/semanticTokens/full --params '{"textDocument":{"uri":"file:///…"}}'
|
|
34
63
|
```
|
|
35
64
|
|
|
36
|
-
Positions are **1-based** (`line:col`, editor-style).
|
|
37
|
-
Write-side commands (`rename`, `formatting`, code actions that produce edits)
|
|
38
|
-
apply changes to disk automatically. Pass `--dry-run` to preview instead.
|
|
39
|
-
|
|
40
65
|
### Code actions
|
|
41
66
|
|
|
42
|
-
`codeAction` returns a JSON array of available fixes and refactors for
|
|
43
|
-
|
|
67
|
+
`codeAction` returns a JSON array of available fixes and refactors for a range.
|
|
68
|
+
When exactly one action carries an edit it is applied automatically; when zero or
|
|
69
|
+
multiple carry edits the array is printed and no files are changed.
|
|
44
70
|
|
|
45
71
|
```bash
|
|
46
|
-
lsproxy textDocument codeAction src/foo.ts 12:1-12:20
|
|
72
|
+
lsproxy textDocument codeAction --dry-run src/foo.ts 12:1-12:20
|
|
47
73
|
```
|
|
48
74
|
|
|
49
|
-
|
|
50
|
-
[
|
|
51
|
-
{ "title": "Add missing import", "kind": "quickfix" },
|
|
52
|
-
{ "title": "Extract to variable", "kind": "refactor.extract.variable" },
|
|
53
|
-
{ "title": "Convert to arrow function","kind": "refactor.rewrite",
|
|
54
|
-
"edit": { "changes": { "file:///src/foo.ts": [ ... ] } } }
|
|
55
|
-
]
|
|
56
|
-
```
|
|
75
|
+
## Troubleshooting
|
|
57
76
|
|
|
58
|
-
**
|
|
59
|
-
|
|
77
|
+
**Commands missing from `--help`** — lsproxy only registers commands for capabilities the
|
|
78
|
+
server actually advertises. If `textDocument rename` doesn't appear, the server doesn't
|
|
79
|
+
support `renameProvider`. Use `lsproxy call initialize --params '{}'` to inspect the
|
|
80
|
+
server's capability response.
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
**Wrong positions** — Positions must be 1-based (`line:col`). Most editors display
|
|
83
|
+
1-based positions; LSP protocol is 0-based internally but lsproxy converts for you.
|
|
84
|
+
Passing 0-based values shifts edits by one line/column.
|
|
85
|
+
|
|
86
|
+
**Server not found** — Without `--server`, lsproxy walks up from `--root` looking for
|
|
87
|
+
`lsp.json`. If it can't find one it will time out. Either add `lsp.json` to the project
|
|
88
|
+
root or pass `--server <cmd>` explicitly.
|
|
64
89
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
**Write commands applied unexpectedly** — `rename`, `formatting`, and code actions that
|
|
91
|
+
produce edits write to disk immediately. Always run with `--dry-run` first on an
|
|
92
|
+
unfamiliar codebase.
|
|
68
93
|
|
|
69
94
|
## Help output
|
|
70
95
|
|
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ export type { SessionOptions } from './session.js';
|
|
|
12
12
|
export { applyWorkspaceEdit, applyTextEdits, planWorkspaceEdit } from './apply.js';
|
|
13
13
|
export type { WorkspaceEdit, LspTextEdit, LspRange, LspPosition, AppliedChange } from './apply.js';
|
|
14
14
|
export type { GlobalFlags } from './io.js';
|
|
15
|
+
export { buildProgram } from './program.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnG,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnG,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Build the full Commander program with all LSP method subcommands populated.
|
|
4
|
+
*
|
|
5
|
+
* Uses a mock {@link ServerCapabilities} where every capability path is truthy
|
|
6
|
+
* so the complete command tree is included regardless of what a live server
|
|
7
|
+
* would actually advertise. Intended for static introspection by tools such as
|
|
8
|
+
* `skillit gen --source cli`; action handlers close over stub values and will
|
|
9
|
+
* error if invoked, so this program is not suitable for real command dispatch.
|
|
10
|
+
*
|
|
11
|
+
* @returns A Commander {@link Command} rooted at `lsproxy` with all known LSP
|
|
12
|
+
* method subcommands registered under their namespace (e.g. `textDocument`,
|
|
13
|
+
* `workspace`) plus the catch-all `call <method>` command.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildProgram(): Command;
|
|
16
|
+
//# sourceMappingURL=program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAqCtC"}
|
package/dist/program.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { buildCommandTree } from './build-commands.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the full Commander program with all LSP method subcommands populated.
|
|
5
|
+
*
|
|
6
|
+
* Uses a mock {@link ServerCapabilities} where every capability path is truthy
|
|
7
|
+
* so the complete command tree is included regardless of what a live server
|
|
8
|
+
* would actually advertise. Intended for static introspection by tools such as
|
|
9
|
+
* `skillit gen --source cli`; action handlers close over stub values and will
|
|
10
|
+
* error if invoked, so this program is not suitable for real command dispatch.
|
|
11
|
+
*
|
|
12
|
+
* @returns A Commander {@link Command} rooted at `lsproxy` with all known LSP
|
|
13
|
+
* method subcommands registered under their namespace (e.g. `textDocument`,
|
|
14
|
+
* `workspace`) plus the catch-all `call <method>` command.
|
|
15
|
+
*/
|
|
16
|
+
export function buildProgram() {
|
|
17
|
+
const program = new Command('lsproxy')
|
|
18
|
+
.description('LSP-driven CLI for project-wide refactoring via any LSP server')
|
|
19
|
+
.option('--server <cmd>', 'LSP server launch command (overrides lsp.json discovery)')
|
|
20
|
+
.option('--root <dir>', 'Project root (default: cwd)')
|
|
21
|
+
.option('--dry-run', 'Print changes; do not write')
|
|
22
|
+
.option('--json', 'Machine-readable JSON on stdout; diagnostics to stderr')
|
|
23
|
+
.option('--wait <ms>', 'Server index wait in ms (default: 15000)')
|
|
24
|
+
.option('--verbose', 'Progress logging to stderr')
|
|
25
|
+
.option('--allow-outside-root', 'Allow file paths outside --root')
|
|
26
|
+
.option('--no-proxy', 'Bypass proxy daemon; connect directly to language server');
|
|
27
|
+
// Proxy that returns itself for any property access so every capability
|
|
28
|
+
// path resolves to a truthy object — all capability-gated method subcommands
|
|
29
|
+
// are included in the tree without needing a live LSP server connection.
|
|
30
|
+
const allCaps = new Proxy({}, {
|
|
31
|
+
get: (_target, _prop, receiver) => receiver
|
|
32
|
+
});
|
|
33
|
+
const stubFlags = {
|
|
34
|
+
server: '',
|
|
35
|
+
root: process.cwd(),
|
|
36
|
+
dryRun: false,
|
|
37
|
+
json: false,
|
|
38
|
+
verbose: false,
|
|
39
|
+
waitMs: 15000,
|
|
40
|
+
allowOutsideRoot: false,
|
|
41
|
+
noProxy: false,
|
|
42
|
+
overwrite: false
|
|
43
|
+
};
|
|
44
|
+
buildCommandTree(program, allCaps, null, stubFlags);
|
|
45
|
+
return program;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;SACnC,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,gBAAgB,EAAE,0DAA0D,CAAC;SACpF,MAAM,CAAC,cAAc,EAAE,6BAA6B,CAAC;SACrD,MAAM,CAAC,WAAW,EAAE,6BAA6B,CAAC;SAClD,MAAM,CAAC,QAAQ,EAAE,wDAAwD,CAAC;SAC1E,MAAM,CAAC,aAAa,EAAE,0CAA0C,CAAC;SACjE,MAAM,CAAC,WAAW,EAAE,4BAA4B,CAAC;SACjD,MAAM,CAAC,sBAAsB,EAAE,iCAAiC,CAAC;SACjE,MAAM,CAAC,YAAY,EAAE,0DAA0D,CAAC,CAAC;IAEpF,wEAAwE;IACxE,6EAA6E;IAC7E,yEAAyE;IACzE,MAAM,OAAO,GAAG,IAAI,KAAK,CACvB,EAAE,EACF;QACE,GAAG,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ;KAC5C,CAC+B,CAAC;IAEnC,MAAM,SAAS,GAAgB;QAC7B,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE;QACnB,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,KAAK;QACb,gBAAgB,EAAE,KAAK;QACvB,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,KAAK;KACjB,CAAC;IAEF,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAkC,EAAE,SAAS,CAAC,CAAC;IAElF,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lsproxy/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Standalone refactor CLI driving any LSP server: project-wide rename, file-move with importer updates, and move-symbol",
|
|
5
5
|
"private": false,
|
|
6
6
|
"keywords": [
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"types": "./dist/index.d.ts",
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
|
-
"README.md"
|
|
41
|
+
"README.md",
|
|
42
|
+
"skills",
|
|
43
|
+
"skillit-postinstall.cjs"
|
|
42
44
|
],
|
|
43
45
|
"publishConfig": {
|
|
44
46
|
"access": "public"
|
|
@@ -51,6 +53,8 @@
|
|
|
51
53
|
"@lspeasy/core": "2.3.0"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
56
|
+
"@skillit/cli": "^0.4.0",
|
|
57
|
+
"typedoc-plugin-skillit": "^1.4.0",
|
|
54
58
|
"typescript": "^6.0.3"
|
|
55
59
|
},
|
|
56
60
|
"engines": {
|
|
@@ -60,6 +64,7 @@
|
|
|
60
64
|
"build": "tsgo --build",
|
|
61
65
|
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
62
66
|
"dev": "tsgo --build --watch",
|
|
63
|
-
"type-check": "tsgo --noEmit"
|
|
67
|
+
"type-check": "tsgo --noEmit",
|
|
68
|
+
"postinstall": "node ./skillit-postinstall.cjs"
|
|
64
69
|
}
|
|
65
70
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
7
|
+
const pkgName = pkg.name;
|
|
8
|
+
const binMap = pkg.bin;
|
|
9
|
+
if (!pkgName || !binMap || typeof binMap !== 'object' || Object.keys(binMap).length === 0) {
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
const binName = Object.keys(binMap)[0];
|
|
13
|
+
const npxPrefix = 'npx ' + pkgName;
|
|
14
|
+
|
|
15
|
+
const skillsDir = path.join(__dirname, 'skills');
|
|
16
|
+
if (!fs.existsSync(skillsDir)) process.exit(0);
|
|
17
|
+
|
|
18
|
+
function walk(dir) {
|
|
19
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
20
|
+
const full = path.join(dir, entry.name);
|
|
21
|
+
if (entry.isDirectory()) {
|
|
22
|
+
walk(full);
|
|
23
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
24
|
+
const content = fs.readFileSync(full, 'utf8');
|
|
25
|
+
const updated = content.replaceAll(npxPrefix, binName);
|
|
26
|
+
if (updated !== content) fs.writeFileSync(full, updated, 'utf8');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
walk(skillsDir);
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: API reference for cli
|
|
3
|
+
name: cli
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# cli
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Semantic refactoring** — project-wide rename, move-file with importer updates, extract symbol
|
|
11
|
+
- **Reference tracking** — find all references, call hierarchy, workspace symbol search
|
|
12
|
+
- **Code actions** — list and apply quick-fixes and refactors at any range
|
|
13
|
+
- **Any LSP server** — TypeScript, Rust, Python, Go, or any LSP-compliant server via `lsp.json`
|
|
14
|
+
- **Proxy daemon** — warm server connections for sub-100ms subsequent invocations
|
|
15
|
+
- **Dry-run preview** — `--dry-run` prints diffs without writing; safe to inspect before committing
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
lsproxy <namespace> <command> [args] [flags]
|
|
21
|
+
lsproxy call <method> --params <json>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Commands are built from the server's capabilities at startup. Available namespaces:
|
|
25
|
+
`callHierarchy`, `codeAction`, `codeLens`, `completionItem`, `documentLink`,
|
|
26
|
+
`inlayHint`, `textDocument`, `workspace`, `workspaceSymbol`.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
lsproxy textDocument hover src/foo.ts 12:7
|
|
30
|
+
lsproxy textDocument rename src/foo.ts 12:7 newName
|
|
31
|
+
lsproxy textDocument references src/foo.ts 12:7
|
|
32
|
+
lsproxy textDocument definition src/foo.ts 12:7
|
|
33
|
+
lsproxy textDocument formatting src/foo.ts
|
|
34
|
+
lsproxy textDocument rangeFormatting src/foo.ts 1:1-50:1
|
|
35
|
+
lsproxy workspace symbol MyClass
|
|
36
|
+
lsproxy call textDocument/semanticTokens/full --params '{"textDocument":{"uri":"file:///…"}}'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Code actions
|
|
40
|
+
|
|
41
|
+
`codeAction` returns a JSON array of available fixes and refactors for a range.
|
|
42
|
+
When exactly one action carries an edit it is applied automatically; when zero or
|
|
43
|
+
multiple carry edits the array is printed and no files are changed.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
lsproxy textDocument codeAction --dry-run src/foo.ts 12:1-12:20
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Troubleshooting
|
|
50
|
+
|
|
51
|
+
**Commands missing from `--help`** — lsproxy only registers commands for capabilities the
|
|
52
|
+
server actually advertises. If `textDocument rename` doesn't appear, the server doesn't
|
|
53
|
+
support `renameProvider`. Use `lsproxy call initialize --params '{}'` to inspect the
|
|
54
|
+
server's capability response.
|
|
55
|
+
|
|
56
|
+
**Wrong positions** — Positions must be 1-based (`line:col`). Most editors display
|
|
57
|
+
1-based positions; LSP protocol is 0-based internally but lsproxy converts for you.
|
|
58
|
+
Passing 0-based values shifts edits by one line/column.
|
|
59
|
+
|
|
60
|
+
**Server not found** — Without `--server`, lsproxy walks up from `--root` looking for
|
|
61
|
+
`lsp.json`. If it can't find one it will time out. Either add `lsp.json` to the project
|
|
62
|
+
root or pass `--server <cmd>` explicitly.
|
|
63
|
+
|
|
64
|
+
**Write commands applied unexpectedly** — `rename`, `formatting`, and code actions that
|
|
65
|
+
produce edits write to disk immediately. Always run with `--dry-run` first on an
|
|
66
|
+
unfamiliar codebase.
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
### callHierarchy
|
|
71
|
+
|
|
72
|
+
callHierarchy operations
|
|
73
|
+
|
|
74
|
+
**Usage:**
|
|
75
|
+
```
|
|
76
|
+
lsproxy callHierarchy [options] [command]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### codeAction
|
|
80
|
+
|
|
81
|
+
codeAction operations
|
|
82
|
+
|
|
83
|
+
**Usage:**
|
|
84
|
+
```
|
|
85
|
+
lsproxy codeAction [options] [command]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### codeLens
|
|
89
|
+
|
|
90
|
+
codeLens operations
|
|
91
|
+
|
|
92
|
+
**Usage:**
|
|
93
|
+
```
|
|
94
|
+
lsproxy codeLens [options] [command]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### completionItem
|
|
98
|
+
|
|
99
|
+
completionItem operations
|
|
100
|
+
|
|
101
|
+
**Usage:**
|
|
102
|
+
```
|
|
103
|
+
lsproxy completionItem [options] [command]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### documentLink
|
|
107
|
+
|
|
108
|
+
documentLink operations
|
|
109
|
+
|
|
110
|
+
**Usage:**
|
|
111
|
+
```
|
|
112
|
+
lsproxy documentLink [options] [command]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### inlayHint
|
|
116
|
+
|
|
117
|
+
inlayHint operations
|
|
118
|
+
|
|
119
|
+
**Usage:**
|
|
120
|
+
```
|
|
121
|
+
lsproxy inlayHint [options] [command]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### textDocument
|
|
125
|
+
|
|
126
|
+
textDocument operations
|
|
127
|
+
|
|
128
|
+
**Usage:**
|
|
129
|
+
```
|
|
130
|
+
lsproxy textDocument [options] [command]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### workspace
|
|
134
|
+
|
|
135
|
+
workspace operations
|
|
136
|
+
|
|
137
|
+
**Usage:**
|
|
138
|
+
```
|
|
139
|
+
lsproxy workspace [options] [command]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### workspaceSymbol
|
|
143
|
+
|
|
144
|
+
workspaceSymbol operations
|
|
145
|
+
|
|
146
|
+
**Usage:**
|
|
147
|
+
```
|
|
148
|
+
lsproxy workspaceSymbol [options] [command]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### call
|
|
152
|
+
|
|
153
|
+
Send any LSP request by method name with raw JSON params
|
|
154
|
+
|
|
155
|
+
**Usage:**
|
|
156
|
+
```
|
|
157
|
+
lsproxy call [options] <method>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Flag | Type | Required | Default | Env | Description |
|
|
161
|
+
| --- | --- | --- | --- | --- | --- |
|
|
162
|
+
| `--params` | `string` | no | — | — | LSP params as JSON |
|
|
163
|
+
|
|
164
|
+
**Arguments:**
|
|
165
|
+
- `method` *(required)*
|
|
166
|
+
|
|
167
|
+
## References
|
|
168
|
+
|
|
169
|
+
Load these on demand — do NOT read all at once:
|
|
170
|
+
|
|
171
|
+
- When using CLI commands → read `references/commands.md` for flags, arguments, and defaults
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
## callHierarchy
|
|
4
|
+
|
|
5
|
+
callHierarchy operations
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
lsproxy callHierarchy [options] [command]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## codeAction
|
|
12
|
+
|
|
13
|
+
codeAction operations
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
lsproxy codeAction [options] [command]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## codeLens
|
|
20
|
+
|
|
21
|
+
codeLens operations
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
lsproxy codeLens [options] [command]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## completionItem
|
|
28
|
+
|
|
29
|
+
completionItem operations
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
lsproxy completionItem [options] [command]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## documentLink
|
|
36
|
+
|
|
37
|
+
documentLink operations
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
lsproxy documentLink [options] [command]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## inlayHint
|
|
44
|
+
|
|
45
|
+
inlayHint operations
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
lsproxy inlayHint [options] [command]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## textDocument
|
|
52
|
+
|
|
53
|
+
textDocument operations
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
lsproxy textDocument [options] [command]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## workspace
|
|
60
|
+
|
|
61
|
+
workspace operations
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
lsproxy workspace [options] [command]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## workspaceSymbol
|
|
68
|
+
|
|
69
|
+
workspaceSymbol operations
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
lsproxy workspaceSymbol [options] [command]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## call
|
|
76
|
+
|
|
77
|
+
Send any LSP request by method name with raw JSON params
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
lsproxy call [options] <method>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Options
|
|
84
|
+
|
|
85
|
+
#### --params
|
|
86
|
+
|
|
87
|
+
LSP params as JSON
|
|
88
|
+
|
|
89
|
+
**Type:** `string`
|
|
90
|
+
|
|
91
|
+
### Arguments
|
|
92
|
+
|
|
93
|
+
#### `method`
|
|
94
|
+
|
|
95
|
+
**Required:** yes
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lsproxy-cli
|
|
3
|
+
description: "`@lspeasy/cli` — programmatic entry point.
|
|
4
|
+
|
|
5
|
+
Exposes the reusable refactor internals (session pipeline + WorkspaceEdit
|
|
6
|
+
applier) so the same machinery can be embedded in scripts, not just invoked
|
|
7
|
+
through the `lspeasy` bin. Also: lsp, language-server-protocol, refactor, rename, codemod, move-symbol, cli."
|
|
8
|
+
license: MIT
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# @lsproxy/cli
|
|
12
|
+
|
|
13
|
+
`@lspeasy/cli` — programmatic entry point.
|
|
14
|
+
|
|
15
|
+
Exposes the reusable refactor internals (session pipeline + WorkspaceEdit
|
|
16
|
+
applier) so the same machinery can be embedded in scripts, not just invoked
|
|
17
|
+
through the `lspeasy` bin.
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
lsproxy <namespace> <command> [args] [flags]
|
|
23
|
+
lsproxy call <method> --params <json>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
**SessionOptions** (6 options — see references/config.md)
|
|
29
|
+
|
|
30
|
+
## Quick Reference
|
|
31
|
+
|
|
32
|
+
**apply:** `applyWorkspaceEdit` (Apply a WorkspaceEdit to disk and return what was changed), `applyTextEdits` (Apply text edits to a string, splicing in reverse offset order so earlier
|
|
33
|
+
edits do not invalidate the offsets of later ones), `planWorkspaceEdit` (Normalize a WorkspaceEdit into an ordered list of changes without
|
|
34
|
+
touching disk), `WorkspaceEdit`, `LspTextEdit`, `LspRange`, `LspPosition`, `AppliedChange` (A single change the apply pipeline performed, for reporting / dry-run output)
|
|
35
|
+
**session:** `RefactorSession`
|
|
36
|
+
**io:** `GlobalFlags`
|
|
37
|
+
|
|
38
|
+
## References
|
|
39
|
+
|
|
40
|
+
Load these on demand — do NOT read all at once:
|
|
41
|
+
|
|
42
|
+
- When calling any function → read `references/functions.md` for full signatures, parameters, and return types
|
|
43
|
+
- When using a class → read `references/classes.md` for properties, methods, and inheritance
|
|
44
|
+
- When defining typed variables or function parameters → read `references/types.md`
|
|
45
|
+
- When configuring options → read `references/config.md` for all settings and defaults
|
|
46
|
+
|
|
47
|
+
## Links
|
|
48
|
+
|
|
49
|
+
- [Repository](https://github.com/pradeepmouli/lspeasy)
|
|
50
|
+
- Author: Pradeep Mouli <pmouli@mac.com> (https://github.com/pradeepmouli)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Classes
|
|
2
|
+
|
|
3
|
+
## session
|
|
4
|
+
|
|
5
|
+
### `RefactorSession`
|
|
6
|
+
```ts
|
|
7
|
+
constructor(opts: SessionOptions): RefactorSession
|
|
8
|
+
```
|
|
9
|
+
**Methods:**
|
|
10
|
+
- `start(): Promise<void>` — Spawn the server (or reuse a pre-built transport) and complete the LSP handshake.
|
|
11
|
+
- `open(anchorFile: string): Promise<void>` — Notify the server that an anchor file is open.
|
|
12
|
+
- `requestWithRetry<R>(run: () => Promise<R | null | undefined>): Promise<R | null>` — Run a request immediately and retry with exponential backoff while the
|
|
13
|
+
server returns null (i.e. it is still indexing). Gives up after
|
|
14
|
+
`indexWaitMs` total elapsed time and returns null.
|
|
15
|
+
|
|
16
|
+
Initial retry delay: 250 ms, doubling each round, capped at 5 s per
|
|
17
|
+
attempt. The first attempt is always immediate so fast servers pay no
|
|
18
|
+
extra latency at all.
|
|
19
|
+
- `takeCapturedEdits(): WorkspaceEdit[]` — Drain ALL edits pushed by the server via `workspace/applyEdit` since the
|
|
20
|
+
last drain, in arrival order. Returns an empty array if none were pushed.
|
|
21
|
+
Callers apply them in order so a multi-applyEdit command is fully honored.
|
|
22
|
+
- `stop(): Promise<void>` — Shut down the client and kill the server process.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
## SessionOptions
|
|
4
|
+
|
|
5
|
+
### Properties
|
|
6
|
+
|
|
7
|
+
#### serverCommand
|
|
8
|
+
|
|
9
|
+
Server launch command, e.g. `typescript-language-server --stdio`. Required unless `transport` is supplied.
|
|
10
|
+
|
|
11
|
+
**Type:** `string`
|
|
12
|
+
|
|
13
|
+
#### root
|
|
14
|
+
|
|
15
|
+
Absolute project root directory.
|
|
16
|
+
|
|
17
|
+
**Type:** `string`
|
|
18
|
+
|
|
19
|
+
**Required:** yes
|
|
20
|
+
|
|
21
|
+
#### languageId
|
|
22
|
+
|
|
23
|
+
languageId for textDocument/didOpen (e.g. 'typescript', 'rust').
|
|
24
|
+
|
|
25
|
+
**Type:** `string`
|
|
26
|
+
|
|
27
|
+
#### indexWaitMs
|
|
28
|
+
|
|
29
|
+
Milliseconds to wait for the server to index before the first request.
|
|
30
|
+
|
|
31
|
+
**Type:** `number`
|
|
32
|
+
|
|
33
|
+
#### verbose
|
|
34
|
+
|
|
35
|
+
Emit `[lsproxy] …` progress lines to stderr.
|
|
36
|
+
|
|
37
|
+
**Type:** `boolean`
|
|
38
|
+
|
|
39
|
+
#### transport
|
|
40
|
+
|
|
41
|
+
Pre-built transport to use instead of spawning a server process.
|
|
42
|
+
|
|
43
|
+
When supplied, `serverCommand` is ignored and no child process is spawned.
|
|
44
|
+
Used by the proxy path to reuse all downstream session logic unchanged.
|
|
45
|
+
|
|
46
|
+
**Type:** `Transport`
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Functions
|
|
2
|
+
|
|
3
|
+
## apply
|
|
4
|
+
|
|
5
|
+
### `applyWorkspaceEdit`
|
|
6
|
+
Apply a WorkspaceEdit to disk and return what was changed.
|
|
7
|
+
|
|
8
|
+
### `documentChanges` — sequential, order significant
|
|
9
|
+
Per the LSP spec the `documentChanges` array order is SIGNIFICANT: each entry
|
|
10
|
+
(text edit or resource op) is applied in the exact order the server emitted
|
|
11
|
+
it. This is the only correct interpretation — e.g. `[rename old→new, textEdit
|
|
12
|
+
on new]` requires the rename to run first so the edit can read `new`. (An
|
|
13
|
+
earlier three-phase model hoisted all resource ops into separate passes,
|
|
14
|
+
which silently reordered a server's ops and broke exactly that shape.)
|
|
15
|
+
|
|
16
|
+
Because order is honored literally, a failure partway through `documentChanges`
|
|
17
|
+
(e.g. a text edit keyed to a not-yet-created path) may leave earlier ops
|
|
18
|
+
applied — that is inherent to respecting server-specified order.
|
|
19
|
+
|
|
20
|
+
### `changes` map — unordered, transactional
|
|
21
|
+
The `changes` map carries no resource ops and no defined ordering, so it is
|
|
22
|
+
applied as a batch: every target is read and its new content computed in
|
|
23
|
+
memory BEFORE any write. If a read fails the function throws before any write,
|
|
24
|
+
so a failed edit never leaves the tree half-applied.
|
|
25
|
+
```ts
|
|
26
|
+
applyWorkspaceEdit(edit: WorkspaceEdit, guard?: BoundaryGuard): AppliedChange[]
|
|
27
|
+
```
|
|
28
|
+
**Parameters:**
|
|
29
|
+
- `edit: WorkspaceEdit`
|
|
30
|
+
- `guard: BoundaryGuard` (optional)
|
|
31
|
+
**Returns:** `AppliedChange[]`
|
|
32
|
+
|
|
33
|
+
### `applyTextEdits`
|
|
34
|
+
Apply text edits to a string, splicing in reverse offset order so earlier
|
|
35
|
+
edits do not invalidate the offsets of later ones.
|
|
36
|
+
|
|
37
|
+
`lineStarts` is computed once from the original `text` and reused for both the
|
|
38
|
+
sort and the splice loop. This is correct because edits apply in reverse
|
|
39
|
+
offset order: a later splice never shifts the line map of an earlier (smaller)
|
|
40
|
+
offset, so the original line map stays valid for every remaining edit.
|
|
41
|
+
```ts
|
|
42
|
+
applyTextEdits(text: string, edits: LspTextEdit[]): string
|
|
43
|
+
```
|
|
44
|
+
**Parameters:**
|
|
45
|
+
- `text: string`
|
|
46
|
+
- `edits: LspTextEdit[]`
|
|
47
|
+
**Returns:** `string`
|
|
48
|
+
|
|
49
|
+
### `planWorkspaceEdit`
|
|
50
|
+
Normalize a WorkspaceEdit into an ordered list of changes without
|
|
51
|
+
touching disk. Useful for `--dry-run` and `--json` reporting.
|
|
52
|
+
```ts
|
|
53
|
+
planWorkspaceEdit(edit: WorkspaceEdit, guard?: BoundaryGuard): AppliedChange[]
|
|
54
|
+
```
|
|
55
|
+
**Parameters:**
|
|
56
|
+
- `edit: WorkspaceEdit`
|
|
57
|
+
- `guard: BoundaryGuard` (optional)
|
|
58
|
+
**Returns:** `AppliedChange[]`
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Types & Enums
|
|
2
|
+
|
|
3
|
+
## apply
|
|
4
|
+
|
|
5
|
+
### `WorkspaceEdit`
|
|
6
|
+
**Properties:**
|
|
7
|
+
- `changes: Record<string, LspTextEdit[]>` (optional)
|
|
8
|
+
- `documentChanges: DocumentChange[]` (optional)
|
|
9
|
+
|
|
10
|
+
### `LspTextEdit`
|
|
11
|
+
**Properties:**
|
|
12
|
+
- `range: LspRange`
|
|
13
|
+
- `newText: string`
|
|
14
|
+
|
|
15
|
+
### `LspRange`
|
|
16
|
+
**Properties:**
|
|
17
|
+
- `start: LspPosition`
|
|
18
|
+
- `end: LspPosition`
|
|
19
|
+
|
|
20
|
+
### `LspPosition`
|
|
21
|
+
**Properties:**
|
|
22
|
+
- `line: number`
|
|
23
|
+
- `character: number`
|
|
24
|
+
|
|
25
|
+
### `AppliedChange`
|
|
26
|
+
A single change the apply pipeline performed, for reporting / dry-run output.
|
|
27
|
+
**Properties:**
|
|
28
|
+
- `kind: "rename" | "create" | "delete" | "edit"`
|
|
29
|
+
- `path: string`
|
|
30
|
+
- `editCount: number` (optional) — For `edit`, the number of text edits applied.
|
|
31
|
+
- `toPath: string` (optional) — For `rename`, the destination path.
|
|
32
|
+
|
|
33
|
+
## io
|
|
34
|
+
|
|
35
|
+
### `GlobalFlags`
|
|
36
|
+
**Properties:**
|
|
37
|
+
- `server: string`
|
|
38
|
+
- `root: string`
|
|
39
|
+
- `dryRun: boolean`
|
|
40
|
+
- `json: boolean`
|
|
41
|
+
- `verbose: boolean`
|
|
42
|
+
- `waitMs: number`
|
|
43
|
+
- `allowOutsideRoot: boolean`
|
|
44
|
+
- `overwrite: boolean` — Permit move-file to replace an existing destination (default: OFF).
|
|
45
|
+
- `noProxy: boolean` — Bypass the proxy daemon and connect directly to the language server.
|