markdown-lsp 0.2.2 → 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/README.md CHANGED
@@ -6,87 +6,179 @@
6
6
  [![license](https://img.shields.io/npm/l/markdown-lsp.svg?style=flat-square)](https://github.com/Docsbook-io/markdown-lsp/blob/main/LICENSE)
7
7
  [![node](https://img.shields.io/node/v/markdown-lsp.svg?style=flat-square)](https://www.npmjs.com/package/markdown-lsp)
8
8
 
9
- Language Server Protocol implementation for Markdown documentation. Optional AI-powered semantic layer on top.
9
+ CLI and library for querying Markdown documentation graphs. Point it at a folder of `.md` files and get instant full-text search, outline, link analysis, and symbol lookup — all as JSON.
10
10
 
11
- **Status: M1 complete, M2 (AI layer) opt-in.**
11
+ **Status: v1.0.0. CLI is the default interface. LSP stdio mode available as a subcommand.**
12
12
 
13
- ## Two layers
13
+ ---
14
14
 
15
- ### Structural (default, no AI)
15
+ ## Quick Start
16
16
 
17
- Out of the box — like Marksman, but persisted in Postgres and addressable from a service.
18
-
19
- - `textDocument/documentSymbol` — heading outline
20
- - `workspace/symbol` — fuzzy subsequence search across all headings (e.g. `oaf` matches `OAuth flow`)
21
- - `textDocument/definition` — jump from a link to its target document
22
- - `textDocument/references` — find every page linking to the current document
23
- - `textDocument/completion` — wiki-link completion `[[...]]`
24
- - `textDocument/publishDiagnostics` — warnings for unresolved link targets
25
- - `workspace.executeCommand("markdownLsp/reindex")` — force re-index of the workspace
26
- - Incremental indexing via content-hash diff; watched-files cleanup
17
+ ```bash
18
+ # List all pages
19
+ npx markdown-lsp workspace-outline ./docs
27
20
 
28
- This layer is fully deterministic, free, and runs offline against your Postgres.
21
+ # Full-text search (natural-language, ranked)
22
+ npx markdown-lsp search-text ./docs "getting started"
29
23
 
30
- ### Semantic (optional, AI-powered)
24
+ # Fuzzy heading search
25
+ npx markdown-lsp search-symbols ./docs "auth" --limit 10
26
+ ```
31
27
 
32
- Off by default. When enabled, an extract pass identifies canonical concepts per section so that
33
- references survive synonym variation (`auth` ≡ `authentication` ≡ `OAuth` ≡ `login`).
28
+ ---
34
29
 
35
- Enable with:
30
+ ## Installation
36
31
 
37
32
  ```bash
38
- export MARKDOWN_LSP_AI_ENABLED=1
39
- export AI_GATEWAY_API_KEY=... # Vercel AI Gateway
33
+ npm install -g markdown-lsp
34
+ # or per-project
35
+ npm install markdown-lsp
40
36
  ```
41
37
 
42
- If the flag is not set, no AI calls are ever made. The server starts and behaves as a
43
- pure-structural LSP — no key required.
38
+ Node.js >= 20 required.
44
39
 
45
- ## Architecture
40
+ ---
41
+
42
+ ## Subcommands
46
43
 
47
- - LSP over stdio (`vscode-languageserver/node`) works in any editor
48
- - pgvector (Neon serverless) for cosine search on canonical-term embeddings (only when AI layer is enabled)
49
- - Drizzle ORM; all tables prefixed `mdlsp_`
50
- - Vercel AI Gateway (`text-embedding-3-small` for embeddings, `gpt-4o-mini` for extraction) — when AI on
51
- - An optional MCP HTTP facade (M3) over the same handlers — for AI agents like Claude Code
44
+ All subcommands accept a **`--pretty`** flag for indented JSON output (compact by default).
52
45
 
53
- ## Setup
46
+ | Subcommand | Arguments | Description |
47
+ |---|---|---|
48
+ | `workspace-outline` | `<docs-dir> [--prefix p] [--limit n]` | List all pages with metadata |
49
+ | `outline` | `<docs-dir> <page>` | Heading outline of a single page |
50
+ | `search-text` | `<docs-dir> <query> [--mode ranked\|verbatim] [--regex] [--case-sensitive] [--prefix p] [--limit n] [--context n]` | Full-text search |
51
+ | `search-symbols` | `<docs-dir> <query> [--limit n]` | Fuzzy subsequence search across headings |
52
+ | `search-paths` | `<docs-dir> <glob>` | List pages matching a glob pattern |
53
+ | `links-to` | `<docs-dir> <page>` | All pages that link to `<page>` |
54
+ | `links-from` | `<docs-dir> <page>` | All links originating from `<page>` |
55
+ | `resolve-link` | `<docs-dir> <from-page> <link-text>` | Resolve a specific link text from a page |
56
+ | `get-section` | `<docs-dir> <page> <anchor>` | Get a section by anchor slug |
57
+ | `lsp` / `serve` | `[--stdio]` | Start the LSP stdio server |
58
+
59
+ ### search-text modes
60
+
61
+ - **ranked** (default) — tokenizes query, drops stop words, ranks by coverage/heading/proximity. Best for natural-language questions.
62
+ - **verbatim** (`--mode verbatim`) — literal substring match. Use `--regex` for regex.
63
+
64
+ ### Output format
65
+
66
+ All subcommands print JSON to stdout. Use `--pretty` for human-readable output:
54
67
 
55
68
  ```bash
56
- pnpm install
57
- cp .env.example .env.local # fill DATABASE_URL; AI_GATEWAY_API_KEY only if you want the AI layer
58
- pnpm migrate # runs scripts/apply-migration.ts against DATABASE_URL
59
- pnpm build
69
+ markdown-lsp search-text ./docs "authentication" --limit 5 --pretty
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Examples
75
+
76
+ ```bash
77
+ # Workspace overview
78
+ markdown-lsp workspace-outline ./docs --limit 20 --pretty
79
+
80
+ # Find pages about authentication
81
+ markdown-lsp search-text ./docs "authentication flow" --pretty
82
+
83
+ # What links to README.md?
84
+ markdown-lsp links-to ./docs README.md
85
+
86
+ # Glob search: all files under api/
87
+ markdown-lsp search-paths ./docs "api/**"
88
+
89
+ # Outline of a specific page
90
+ markdown-lsp outline ./docs quick-start.md --pretty
91
+
92
+ # Find headings containing "auth"
93
+ markdown-lsp search-symbols ./docs "auth" --limit 10
94
+
95
+ # Resolve a link from a page
96
+ markdown-lsp resolve-link ./docs README.md "Getting Started"
97
+
98
+ # Get a specific section by anchor
99
+ markdown-lsp get-section ./docs overview.md quick-links --pretty
60
100
  ```
61
101
 
62
- ## Run
102
+ ---
103
+
104
+ ## LSP mode (editor integration)
63
105
 
64
- LSP via stdio (for editor integration):
106
+ `markdown-lsp` also works as a Language Server Protocol server for editors (VS Code, Zed, Neovim, etc.).
65
107
 
66
108
  ```bash
67
- node dist/server.js --stdio
109
+ # Recommended (v1.0.0+)
110
+ npx markdown-lsp lsp --stdio
111
+
112
+ # Back-compat — old LSP flag style still works so existing editor configs don't break
113
+ npx markdown-lsp --stdio
68
114
  ```
69
115
 
70
- `bin/markdown-lsp` wraps the same entry point as a CLI.
116
+ The LSP server speaks the standard protocol over stdio. It requires a Postgres database for the structural index (see Setup below).
117
+
118
+ ### Editor configuration example (VS Code)
71
119
 
72
- ## Use from Docsbook
120
+ In your `settings.json`:
121
+
122
+ ```json
123
+ {
124
+ "markdown-lsp.serverPath": "markdown-lsp",
125
+ "markdown-lsp.args": ["lsp", "--stdio"]
126
+ }
127
+ ```
73
128
 
74
- The structural layer is what Docsbook's "Source of Truth" feature wants. Wire it in like this:
129
+ ---
130
+
131
+ ## Use as a library
75
132
 
76
133
  ```ts
77
- import { ensureWorkspace, indexWorkspace } from "@docsbook/markdown-lsp/indexer"
78
- import { getDocumentSymbols, getWorkspaceSymbols } from "@docsbook/markdown-lsp/core"
134
+ import { buildGraph, loadDocsAsFiles } from "markdown-lsp/graph"
135
+ import { searchTextRanked, searchSymbols, listPages } from "markdown-lsp/bridge"
136
+
137
+ const graph = buildGraph("./docs")
138
+ const hits = searchTextRanked(graph, "authentication flow")
139
+ const pages = listPages(graph, { limit: 50 })
140
+ ```
141
+
142
+ Available entry points:
143
+ - `markdown-lsp/bridge` — search functions + `RichDocGraph`, `buildInMemoryGraph`, types
144
+ - `markdown-lsp/graph` — `buildGraph(docsRoot)`, `loadDocsAsFiles(docsRoot)`
145
+ - `markdown-lsp/indexer` — SQLite/Postgres workspace indexer (for LSP use)
146
+ - `markdown-lsp/core` — document symbols and references (for LSP use)
147
+ - `markdown-lsp/parser` — raw Markdown parser
148
+
149
+ ---
150
+
151
+ ## LSP Setup (for editor / structural indexer use)
152
+
153
+ The CLI subcommands work **without any database** — they build an in-memory graph on the fly.
154
+
155
+ The LSP server requires Postgres (for the incremental index):
156
+
157
+ ```bash
158
+ pnpm install
159
+ cp .env.example .env.local # fill DATABASE_URL; AI_GATEWAY_API_KEY only if you want the AI layer
160
+ pnpm migrate # runs scripts/apply-migration.ts against DATABASE_URL
161
+ pnpm build
162
+ ```
79
163
 
80
- // after cloning a workspace repo into ./tmp/<workspace-id>/
81
- const ws = await ensureWorkspace("./tmp/42")
82
- await indexWorkspace(ws)
164
+ Optional AI layer (semantic synonym resolution):
83
165
 
84
- // MCP tools then call:
85
- await getWorkspaceSymbols(ws, "auth")
86
- await findReferencesToDocument(ws, authDocId)
166
+ ```bash
167
+ export MARKDOWN_LSP_AI_ENABLED=1
168
+ export AI_GATEWAY_API_KEY=... # Vercel AI Gateway
87
169
  ```
88
170
 
89
- No AI required.
171
+ ---
172
+
173
+ ## Architecture
174
+
175
+ - **CLI** — `node:util parseArgs`, zero extra deps, reads `.md` files into an in-memory graph
176
+ - **Graph** — pure TypeScript, no DB needed; `buildGraph(docsRoot)` walks the directory tree
177
+ - **LSP** — `vscode-languageserver/node` over stdio; requires Postgres (Drizzle ORM, `mdlsp_` prefix)
178
+ - **AI layer** (opt-in) — pgvector cosine search on canonical-term embeddings; `text-embedding-3-small` via Vercel AI Gateway
179
+ - **Bridge** — pure in-memory search (searchText, searchTextRanked, searchSymbols, searchPaths, listPages)
180
+
181
+ ---
90
182
 
91
183
  ## Tests
92
184
 
@@ -94,17 +186,21 @@ No AI required.
94
186
  pnpm test
95
187
  ```
96
188
 
97
- 27 tests cover the parser, indexer, and core handlers (plus a small suite for the AI feature flag).
189
+ 27 tests cover the parser, indexer, core handlers, and bridge search functions.
190
+
191
+ ---
98
192
 
99
193
  ## Milestones
100
194
 
101
195
  - **M0 — Scaffold** ✅
102
196
  - **M1 — Structural layer** ✅
103
- - M2 — Semantic extract (opt-in, code present, awaiting live AI Gateway credit)
104
- - M3 — MCP HTTP facade
197
+ - **M2 — Semantic extract** (opt-in, code present, awaiting live AI Gateway credit)
198
+ - **M3 — CLI-first interface** ✅ (v1.0.0)
105
199
  - M4 — User overrides for the glossary (merge / split / rename / add_synonym)
106
200
  - M5 — Docsbook integration
107
201
 
202
+ ---
203
+
108
204
  ## License
109
205
 
110
206
  MIT
package/bin/markdown-lsp CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import("../dist/server.js")
2
+ import("../dist/cli.js")
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,265 @@
1
+ import { parseArgs } from "node:util";
2
+ import { buildGraph } from "./graph.js";
3
+ import { listPages, searchText, searchTextRanked, searchSymbols, searchPaths, } from "./bridge/index.js";
4
+ const USAGE = `
5
+ markdown-lsp v1.0.0 — CLI for querying Markdown documentation graphs
6
+
7
+ USAGE
8
+ markdown-lsp <subcommand> [options]
9
+
10
+ SUBCOMMANDS
11
+ workspace-outline <docs-dir> [--prefix <p>] [--limit <n>]
12
+ List all pages in the workspace with metadata.
13
+
14
+ outline <docs-dir> <page>
15
+ Show the heading outline of a single page.
16
+
17
+ search-text <docs-dir> <query> [--mode ranked|verbatim] [--regex]
18
+ [--case-sensitive] [--prefix <p>] [--limit <n>] [--context <n>]
19
+ Full-text search. Default mode: ranked (natural-language). Use
20
+ --mode verbatim (or --regex) for exact/regex matching.
21
+
22
+ search-symbols <docs-dir> <query> [--limit <n>]
23
+ Fuzzy subsequence search across all headings.
24
+
25
+ search-paths <docs-dir> <glob>
26
+ List pages whose paths match a glob pattern (*, **, ?).
27
+
28
+ links-to <docs-dir> <page>
29
+ Show all pages that link to <page>.
30
+
31
+ links-from <docs-dir> <page>
32
+ Show all links that originate from <page>.
33
+
34
+ resolve-link <docs-dir> <from-page> <link-text>
35
+ Resolve a specific link text from a given page.
36
+
37
+ get-section <docs-dir> <page> <anchor>
38
+ Retrieve a section by its anchor slug.
39
+
40
+ lsp [--stdio]
41
+ serve [--stdio]
42
+ Start the LSP stdio server (for editor integration).
43
+ Back-compat: --stdio | --node-ipc | --socket=<n> as first arg also
44
+ starts the LSP server.
45
+
46
+ GLOBAL FLAGS
47
+ --pretty Pretty-print JSON output (default: compact)
48
+ --text Human-readable output (where implemented)
49
+ -h, --help Print this help
50
+
51
+ OUTPUT
52
+ All subcommands print JSON to stdout (compact by default, use --pretty
53
+ for indented output). The LSP subcommand speaks the Language Server Protocol
54
+ over stdio — it does NOT print JSON.
55
+
56
+ EXAMPLES
57
+ markdown-lsp workspace-outline ./docs
58
+ markdown-lsp search-text ./docs "getting started" --pretty
59
+ markdown-lsp outline ./docs introduction.md
60
+ markdown-lsp lsp --stdio
61
+ `.trim();
62
+ function die(msg) {
63
+ process.stderr.write(msg + "\n");
64
+ process.exit(1);
65
+ }
66
+ function out(value, pretty) {
67
+ process.stdout.write((pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value)) + "\n");
68
+ }
69
+ async function startLsp() {
70
+ await import("./lsp.js");
71
+ }
72
+ async function main() {
73
+ const argv = process.argv.slice(2);
74
+ // Back-compat: if the first argument looks like an old LSP flag, start LSP.
75
+ if (argv.length === 0 ||
76
+ argv[0] === "--stdio" ||
77
+ argv[0] === "--node-ipc" ||
78
+ (argv[0] !== undefined && argv[0].startsWith("--socket"))) {
79
+ if (argv.length === 0) {
80
+ // No args: print usage and exit cleanly (not the old LSP crash).
81
+ process.stdout.write(USAGE + "\n");
82
+ process.exit(0);
83
+ }
84
+ // Old LSP invocation style — keep working so editor configs don't break.
85
+ await startLsp();
86
+ return;
87
+ }
88
+ const subcommand = argv[0];
89
+ const rest = argv.slice(1);
90
+ // Help shortcuts
91
+ if (subcommand === "--help" || subcommand === "-h") {
92
+ process.stdout.write(USAGE + "\n");
93
+ process.exit(0);
94
+ }
95
+ // LSP subcommand
96
+ if (subcommand === "lsp" || subcommand === "serve") {
97
+ await startLsp();
98
+ return;
99
+ }
100
+ // Parse global flags from the remaining args
101
+ let pretty = false;
102
+ const filteredRest = [];
103
+ for (const arg of rest) {
104
+ if (arg === "--pretty")
105
+ pretty = true;
106
+ else
107
+ filteredRest.push(arg);
108
+ }
109
+ switch (subcommand) {
110
+ case "workspace-outline": {
111
+ const { values, positionals } = parseArgs({
112
+ args: filteredRest,
113
+ options: {
114
+ prefix: { type: "string" },
115
+ limit: { type: "string" },
116
+ },
117
+ allowPositionals: true,
118
+ });
119
+ const docsDir = positionals[0] ?? die("workspace-outline requires <docs-dir>");
120
+ const graph = buildGraph(docsDir);
121
+ const result = listPages(graph, {
122
+ prefix: values.prefix,
123
+ limit: values.limit !== undefined ? parseInt(values.limit, 10) : undefined,
124
+ });
125
+ out(result, pretty);
126
+ break;
127
+ }
128
+ case "outline": {
129
+ const { positionals } = parseArgs({
130
+ args: filteredRest,
131
+ options: {},
132
+ allowPositionals: true,
133
+ });
134
+ const docsDir = positionals[0] ?? die("outline requires <docs-dir>");
135
+ const page = positionals[1] ?? die("outline requires <page>");
136
+ const graph = buildGraph(docsDir);
137
+ const result = graph.outlineOf(page);
138
+ out(result, pretty);
139
+ break;
140
+ }
141
+ case "search-text": {
142
+ const { values, positionals } = parseArgs({
143
+ args: filteredRest,
144
+ options: {
145
+ mode: { type: "string" },
146
+ regex: { type: "boolean" },
147
+ "case-sensitive": { type: "boolean" },
148
+ prefix: { type: "string" },
149
+ limit: { type: "string" },
150
+ context: { type: "string" },
151
+ },
152
+ allowPositionals: true,
153
+ });
154
+ const docsDir = positionals[0] ?? die("search-text requires <docs-dir>");
155
+ const query = positionals[1] ?? die("search-text requires <query>");
156
+ const graph = buildGraph(docsDir);
157
+ const opts = {
158
+ regex: values.regex,
159
+ caseSensitive: values["case-sensitive"],
160
+ pathPrefix: values.prefix,
161
+ limit: values.limit !== undefined ? parseInt(values.limit, 10) : undefined,
162
+ contextChars: values.context !== undefined ? parseInt(values.context, 10) : undefined,
163
+ };
164
+ const mode = values.mode ?? "ranked";
165
+ const result = mode === "verbatim" || values.regex
166
+ ? searchText(graph, query, opts)
167
+ : searchTextRanked(graph, query, opts);
168
+ out(result, pretty);
169
+ break;
170
+ }
171
+ case "search-symbols": {
172
+ const { values, positionals } = parseArgs({
173
+ args: filteredRest,
174
+ options: {
175
+ limit: { type: "string" },
176
+ },
177
+ allowPositionals: true,
178
+ });
179
+ const docsDir = positionals[0] ?? die("search-symbols requires <docs-dir>");
180
+ const query = positionals[1] ?? die("search-symbols requires <query>");
181
+ const graph = buildGraph(docsDir);
182
+ const limit = values.limit !== undefined ? parseInt(values.limit, 10) : undefined;
183
+ const result = searchSymbols(graph, query, limit);
184
+ out(result, pretty);
185
+ break;
186
+ }
187
+ case "search-paths": {
188
+ const { positionals } = parseArgs({
189
+ args: filteredRest,
190
+ options: {},
191
+ allowPositionals: true,
192
+ });
193
+ const docsDir = positionals[0] ?? die("search-paths requires <docs-dir>");
194
+ const glob = positionals[1] ?? die("search-paths requires <glob>");
195
+ const graph = buildGraph(docsDir);
196
+ const result = searchPaths(graph, glob);
197
+ out(result, pretty);
198
+ break;
199
+ }
200
+ case "links-to": {
201
+ const { positionals } = parseArgs({
202
+ args: filteredRest,
203
+ options: {},
204
+ allowPositionals: true,
205
+ });
206
+ const docsDir = positionals[0] ?? die("links-to requires <docs-dir>");
207
+ const page = positionals[1] ?? die("links-to requires <page>");
208
+ const graph = buildGraph(docsDir);
209
+ const result = graph.incomingLinks(page);
210
+ out(result, pretty);
211
+ break;
212
+ }
213
+ case "links-from": {
214
+ const { positionals } = parseArgs({
215
+ args: filteredRest,
216
+ options: {},
217
+ allowPositionals: true,
218
+ });
219
+ const docsDir = positionals[0] ?? die("links-from requires <docs-dir>");
220
+ const page = positionals[1] ?? die("links-from requires <page>");
221
+ const graph = buildGraph(docsDir);
222
+ const result = graph.outgoingLinks(page);
223
+ out(result, pretty);
224
+ break;
225
+ }
226
+ case "resolve-link": {
227
+ const { positionals } = parseArgs({
228
+ args: filteredRest,
229
+ options: {},
230
+ allowPositionals: true,
231
+ });
232
+ const docsDir = positionals[0] ?? die("resolve-link requires <docs-dir>");
233
+ const fromPage = positionals[1] ?? die("resolve-link requires <from-page>");
234
+ const linkText = positionals[2] ?? die("resolve-link requires <link-text>");
235
+ const graph = buildGraph(docsDir);
236
+ const links = graph.outgoingLinks(fromPage);
237
+ const match = links.find((l) => l.textAtLink === linkText) ?? null;
238
+ out(match, pretty);
239
+ break;
240
+ }
241
+ case "get-section": {
242
+ const { positionals } = parseArgs({
243
+ args: filteredRest,
244
+ options: {},
245
+ allowPositionals: true,
246
+ });
247
+ const docsDir = positionals[0] ?? die("get-section requires <docs-dir>");
248
+ const page = positionals[1] ?? die("get-section requires <page>");
249
+ const anchor = positionals[2] ?? die("get-section requires <anchor>");
250
+ const graph = buildGraph(docsDir);
251
+ const pageObj = graph.pageByPath(page);
252
+ const section = pageObj?.sections.find((s) => s.anchor === anchor) ?? null;
253
+ out(section, pretty);
254
+ break;
255
+ }
256
+ default:
257
+ process.stderr.write(`Unknown subcommand: ${subcommand}\n\n${USAGE}\n`);
258
+ process.exit(1);
259
+ }
260
+ }
261
+ main().catch((err) => {
262
+ process.stderr.write("[markdown-lsp] Fatal error: " + (err instanceof Error ? err.stack ?? err.message : String(err)) + "\n");
263
+ process.exit(1);
264
+ });
265
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -28,9 +28,9 @@ export interface UnresolvedLink {
28
28
  }
29
29
  export declare function findUnresolvedLinks(workspace: WorkspaceRef, forDocPath?: string): Promise<UnresolvedLink[]>;
30
30
  export declare function getDocumentByPath(workspace: WorkspaceRef, relPath: string): Promise<{
31
+ path: string;
31
32
  id: string;
32
33
  workspaceId: string;
33
- path: string;
34
34
  contentHash: string;
35
35
  title: string | null;
36
36
  lastIndexedAt: Date;
@@ -695,7 +695,7 @@ export declare const reindexJobs: import("drizzle-orm/pg-core").PgTableWithColum
695
695
  tableName: "mdlsp_reindex_jobs";
696
696
  dataType: "string";
697
697
  columnType: "PgText";
698
- data: "pending" | "running" | "done" | "failed";
698
+ data: "done" | "pending" | "running" | "failed";
699
699
  driverParam: string;
700
700
  notNull: true;
701
701
  hasDefault: false;
@@ -0,0 +1,4 @@
1
+ import { RichDocGraph, type InMemoryFile } from "./bridge/index.js";
2
+ export declare function loadDocsAsFiles(docsRoot: string): InMemoryFile[];
3
+ export declare function buildGraph(docsRoot: string): RichDocGraph;
4
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EAEZ,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAA;AAc1B,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAKhE;AA4CD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAIzD"}
package/dist/graph.js ADDED
@@ -0,0 +1,70 @@
1
+ import { readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { join, relative, resolve } from "node:path";
3
+ import { RichDocGraph, buildInMemoryGraph, } from "./bridge/index.js";
4
+ const MD_EXTENSIONS = new Set([".md", ".mdx", ".markdown"]);
5
+ const IGNORED_DIRS = new Set([
6
+ "node_modules",
7
+ ".git",
8
+ ".next",
9
+ ".vercel",
10
+ "dist",
11
+ "build",
12
+ ".cache",
13
+ ".turbo",
14
+ ]);
15
+ export function loadDocsAsFiles(docsRoot) {
16
+ const absRoot = resolve(docsRoot);
17
+ const files = [];
18
+ walk(absRoot, absRoot, files);
19
+ return files;
20
+ }
21
+ function walk(absRoot, dir, out) {
22
+ let entries;
23
+ try {
24
+ entries = readdirSync(dir);
25
+ }
26
+ catch {
27
+ return;
28
+ }
29
+ for (const name of entries) {
30
+ if (name.startsWith(".") && name !== ".")
31
+ continue;
32
+ if (IGNORED_DIRS.has(name))
33
+ continue;
34
+ const full = join(dir, name);
35
+ let st;
36
+ try {
37
+ st = statSync(full);
38
+ }
39
+ catch {
40
+ continue;
41
+ }
42
+ if (st.isDirectory()) {
43
+ walk(absRoot, full, out);
44
+ continue;
45
+ }
46
+ if (!st.isFile())
47
+ continue;
48
+ const dotIdx = name.lastIndexOf(".");
49
+ if (dotIdx < 0)
50
+ continue;
51
+ const ext = name.slice(dotIdx).toLowerCase();
52
+ if (!MD_EXTENSIONS.has(ext))
53
+ continue;
54
+ const rel = relative(absRoot, full).split("\\").join("/");
55
+ let content;
56
+ try {
57
+ content = readFileSync(full, "utf8");
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ out.push({ path: rel, content });
63
+ }
64
+ }
65
+ export function buildGraph(docsRoot) {
66
+ const files = loadDocsAsFiles(docsRoot);
67
+ const raw = buildInMemoryGraph(files);
68
+ return new RichDocGraph(raw);
69
+ }
70
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EACL,YAAY,EACZ,kBAAkB,GAEnB,MAAM,mBAAmB,CAAA;AAE1B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;AAC3D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,cAAc;IACd,MAAM;IACN,OAAO;IACP,SAAS;IACT,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;CACT,CAAC,CAAA;AAEF,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjC,MAAM,KAAK,GAAmB,EAAE,CAAA;IAChC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,IAAI,CAAC,OAAe,EAAE,GAAW,EAAE,GAAmB;IAC7D,IAAI,OAAiB,CAAA;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAM;IACR,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG;YAAE,SAAQ;QAClD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAQ;QAEpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAC5B,IAAI,EAAE,CAAA;QACN,IAAI,CAAC;YACH,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QAED,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;YACxB,SAAQ;QACV,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,SAAQ;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QACpC,IAAI,MAAM,GAAG,CAAC;YAAE,SAAQ;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC5C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAQ;QAErC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzD,IAAI,OAAe,CAAA;QACnB,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;IAClC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAA;IACvC,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IACrC,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,CAAA;AAC9B,CAAC"}
package/dist/lsp.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lsp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":""}
package/dist/lsp.js ADDED
@@ -0,0 +1,343 @@
1
+ import { config as loadEnv } from "dotenv";
2
+ import { resolve as pathResolve } from "node:path";
3
+ import { fileURLToPath as fileToPath } from "node:url";
4
+ const __filename = fileToPath(import.meta.url);
5
+ const __dirname = pathResolve(__filename, "..");
6
+ loadEnv({ path: pathResolve(__dirname, "..", ".env.local") });
7
+ loadEnv({ path: pathResolve(__dirname, "..", ".env") });
8
+ loadEnv();
9
+ process.on("uncaughtException", (e) => {
10
+ console.error("[markdown-lsp] uncaughtException:", e instanceof Error ? e.stack || e.message : e);
11
+ });
12
+ process.on("unhandledRejection", (e) => {
13
+ console.error("[markdown-lsp] unhandledRejection:", e instanceof Error ? e.stack || e.message : e);
14
+ });
15
+ import { createConnection, ProposedFeatures, TextDocuments, TextDocumentSyncKind, SymbolKind, Location, Range, Position, DiagnosticSeverity, CompletionItemKind, TextEdit, } from "vscode-languageserver/node.js";
16
+ import { TextDocument } from "vscode-languageserver-textdocument";
17
+ import { URI } from "vscode-uri";
18
+ import { fileURLToPath } from "node:url";
19
+ import { relative, resolve, dirname, join } from "node:path";
20
+ import { readdir } from "node:fs/promises";
21
+ import { ensureWorkspace, indexFile, indexWorkspace, removeFile, resolveLinkTargets, } from "./indexer/indexer.js";
22
+ import { parseMarkdown } from "./indexer/parseMarkdown.js";
23
+ import { getDocumentSymbols, getWorkspaceSymbols } from "./core/documentSymbols.js";
24
+ import { findReferencesToDocument, findUnresolvedLinks, getDocumentByPath, resolveLinkByTarget } from "./core/findReferences.js";
25
+ import { db } from "./db/client.js";
26
+ import { documents } from "./db/schema.js";
27
+ import { eq } from "drizzle-orm";
28
+ const connection = createConnection(ProposedFeatures.all);
29
+ const docs = new TextDocuments(TextDocument);
30
+ let workspace = null;
31
+ function uriToPath(uri) {
32
+ return fileURLToPath(uri);
33
+ }
34
+ function pathToUri(p) {
35
+ return URI.file(p).toString();
36
+ }
37
+ function relPath(absolute) {
38
+ if (!workspace)
39
+ return absolute;
40
+ return relative(workspace.rootPath, absolute);
41
+ }
42
+ function rangeToLsp(r) {
43
+ return Range.create(Position.create(r.startLine, r.startCol), Position.create(r.endLine, r.endCol));
44
+ }
45
+ function symbolKindForLevel(level) {
46
+ if (level <= 1)
47
+ return SymbolKind.File;
48
+ if (level === 2)
49
+ return SymbolKind.Namespace;
50
+ if (level === 3)
51
+ return SymbolKind.Class;
52
+ return SymbolKind.Field;
53
+ }
54
+ connection.onInitialize(async (params) => {
55
+ const folders = params.workspaceFolders ?? [];
56
+ if (folders.length === 0 && params.rootUri) {
57
+ folders.push({ uri: params.rootUri, name: "root" });
58
+ }
59
+ if (folders.length > 0) {
60
+ const root = uriToPath(folders[0].uri);
61
+ try {
62
+ workspace = await ensureWorkspace(root, folders[0].name);
63
+ connection.console.info(`Workspace initialized: ${workspace.rootPath} (id=${workspace.id})`);
64
+ }
65
+ catch (e) {
66
+ const msg = e instanceof Error ? e.message : String(e);
67
+ connection.console.error(`Failed to initialize workspace: ${msg}`);
68
+ connection.window.showErrorMessage(`Markdown LSP: ${msg}`);
69
+ }
70
+ }
71
+ else {
72
+ connection.console.warn("No workspace folder provided");
73
+ }
74
+ return {
75
+ capabilities: {
76
+ textDocumentSync: TextDocumentSyncKind.Incremental,
77
+ documentSymbolProvider: true,
78
+ workspaceSymbolProvider: true,
79
+ definitionProvider: true,
80
+ referencesProvider: true,
81
+ hoverProvider: false,
82
+ completionProvider: { triggerCharacters: ["[", "(", "#"] },
83
+ renameProvider: false,
84
+ executeCommandProvider: { commands: ["markdownLsp/reindex"] },
85
+ },
86
+ serverInfo: { name: "markdown-lsp", version: "0.0.1" },
87
+ };
88
+ });
89
+ connection.onInitialized(async () => {
90
+ if (!workspace)
91
+ return;
92
+ connection.console.info("Starting initial workspace index…");
93
+ try {
94
+ const result = await indexWorkspace(workspace);
95
+ connection.console.info(`Index complete: ${result.filesIndexed} indexed, ${result.filesUnchanged} unchanged, ${result.filesRemoved} removed`);
96
+ await publishWorkspaceDiagnostics();
97
+ }
98
+ catch (e) {
99
+ connection.console.error(`Index failed: ${e instanceof Error ? e.message : String(e)}`);
100
+ }
101
+ });
102
+ async function publishWorkspaceDiagnostics() {
103
+ if (!workspace)
104
+ return;
105
+ const unresolved = await findUnresolvedLinks(workspace);
106
+ const byDoc = new Map();
107
+ for (const u of unresolved) {
108
+ const arr = byDoc.get(u.fromDocumentPath) ?? [];
109
+ arr.push(u);
110
+ byDoc.set(u.fromDocumentPath, arr);
111
+ }
112
+ for (const [docPath, list] of byDoc) {
113
+ const absolute = workspace ? resolve(workspace.rootPath, docPath) : docPath;
114
+ const diagnostics = list.map((u) => ({
115
+ severity: DiagnosticSeverity.Warning,
116
+ range: Range.create(0, 0, 0, 1),
117
+ message: `Unresolved link target: ${u.toPath}`,
118
+ source: "markdown-lsp",
119
+ code: "unresolved-link",
120
+ }));
121
+ connection.sendDiagnostics({ uri: pathToUri(absolute), diagnostics });
122
+ }
123
+ }
124
+ docs.onDidChangeContent(async (event) => {
125
+ if (!workspace)
126
+ return;
127
+ const absolute = uriToPath(event.document.uri);
128
+ if (!absolute.startsWith(workspace.rootPath))
129
+ return;
130
+ try {
131
+ await indexFile(workspace, absolute, event.document.getText());
132
+ await resolveLinkTargets(workspace);
133
+ await publishDocumentDiagnostics(absolute);
134
+ }
135
+ catch (e) {
136
+ connection.console.error(`indexFile failed for ${absolute}: ${e instanceof Error ? e.message : e}`);
137
+ }
138
+ });
139
+ docs.onDidClose((event) => {
140
+ connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
141
+ });
142
+ async function publishDocumentDiagnostics(absolute) {
143
+ if (!workspace)
144
+ return;
145
+ const rel = relPath(absolute);
146
+ const unresolved = await findUnresolvedLinks(workspace, rel);
147
+ const diagnostics = unresolved.map((u) => ({
148
+ severity: DiagnosticSeverity.Warning,
149
+ range: Range.create(0, 0, 0, 1),
150
+ message: `Unresolved link target: ${u.toPath}`,
151
+ source: "markdown-lsp",
152
+ code: "unresolved-link",
153
+ }));
154
+ connection.sendDiagnostics({ uri: pathToUri(absolute), diagnostics });
155
+ }
156
+ connection.onDocumentSymbol(async (params) => {
157
+ if (!workspace)
158
+ return [];
159
+ const absolute = uriToPath(params.textDocument.uri);
160
+ const nodes = await getDocumentSymbols(workspace, relPath(absolute));
161
+ const toLsp = (n) => ({
162
+ name: n.name,
163
+ kind: symbolKindForLevel(n.level),
164
+ range: rangeToLsp(n.range),
165
+ selectionRange: rangeToLsp(n.selectionRange),
166
+ children: n.children.map(toLsp),
167
+ });
168
+ return nodes.map(toLsp);
169
+ });
170
+ connection.onWorkspaceSymbol(async (params) => {
171
+ if (!workspace)
172
+ return [];
173
+ const hits = await getWorkspaceSymbols(workspace, params.query ?? "", 100);
174
+ return hits.map((h) => ({
175
+ name: h.name,
176
+ kind: SymbolKind.String,
177
+ location: Location.create(pathToUri(resolve(workspace.rootPath, h.documentPath)), rangeToLsp(h.range)),
178
+ containerName: h.containerName ?? undefined,
179
+ }));
180
+ });
181
+ connection.onDefinition(async (params) => {
182
+ if (!workspace)
183
+ return null;
184
+ const absolute = uriToPath(params.textDocument.uri);
185
+ const doc = docs.get(params.textDocument.uri);
186
+ if (!doc)
187
+ return null;
188
+ const parsed = parseMarkdown(doc.getText());
189
+ const line = params.position.line;
190
+ const col = params.position.character;
191
+ const hit = parsed.links.find((l) => l.positionStartLine <= line &&
192
+ l.positionEndLine >= line &&
193
+ (l.positionStartLine !== line || l.positionStartCol <= col) &&
194
+ (l.positionEndLine !== line || l.positionEndCol >= col));
195
+ if (!hit)
196
+ return null;
197
+ if (hit.kind === "wiki") {
198
+ const resolved = await resolveLinkByTarget(workspace, hit.toPath);
199
+ if (!resolved)
200
+ return null;
201
+ const targetAbs = resolve(workspace.rootPath, resolved.documentPath);
202
+ return Location.create(pathToUri(targetAbs), Range.create(0, 0, 0, 0));
203
+ }
204
+ const fromDir = dirname(relPath(absolute));
205
+ const candidates = [
206
+ hit.toPath,
207
+ hit.toPath.replace(/^\.\//, ""),
208
+ join(fromDir, hit.toPath),
209
+ join(fromDir, hit.toPath.replace(/^\.\//, "")),
210
+ ];
211
+ for (const c of candidates) {
212
+ const normalized = c.replace(/\.(md|mdx|markdown)$/i, "");
213
+ const doc = await db
214
+ .select()
215
+ .from(documents)
216
+ .where(eq(documents.workspaceId, workspace.id));
217
+ const match = doc.find((d) => d.path === c || d.path.replace(/\.(md|mdx|markdown)$/i, "") === normalized);
218
+ if (match) {
219
+ const targetAbs = resolve(workspace.rootPath, match.path);
220
+ return Location.create(pathToUri(targetAbs), Range.create(0, 0, 0, 0));
221
+ }
222
+ }
223
+ return null;
224
+ });
225
+ connection.onReferences(async (params) => {
226
+ if (!workspace)
227
+ return [];
228
+ const absolute = uriToPath(params.textDocument.uri);
229
+ let targetDocId = null;
230
+ const liveDoc = docs.get(params.textDocument.uri);
231
+ if (liveDoc) {
232
+ const parsed = parseMarkdown(liveDoc.getText());
233
+ const line = params.position.line;
234
+ const col = params.position.character;
235
+ const hit = parsed.links.find((l) => l.positionStartLine <= line &&
236
+ l.positionEndLine >= line &&
237
+ (l.positionStartLine !== line || l.positionStartCol <= col) &&
238
+ (l.positionEndLine !== line || l.positionEndCol >= col));
239
+ if (hit) {
240
+ if (hit.kind === "wiki") {
241
+ const resolved = await resolveLinkByTarget(workspace, hit.toPath);
242
+ if (resolved) {
243
+ const target = await getDocumentByPath(workspace, resolved.documentPath);
244
+ if (target)
245
+ targetDocId = target.id;
246
+ }
247
+ }
248
+ else {
249
+ const fromDir = dirname(relPath(absolute));
250
+ const candidates = [
251
+ hit.toPath,
252
+ hit.toPath.replace(/^\.\//, ""),
253
+ join(fromDir, hit.toPath),
254
+ join(fromDir, hit.toPath.replace(/^\.\//, "")),
255
+ ];
256
+ const allDocs = await db.select().from(documents).where(eq(documents.workspaceId, workspace.id));
257
+ for (const c of candidates) {
258
+ const normalized = c.replace(/\.(md|mdx|markdown)$/i, "");
259
+ const match = allDocs.find((d) => d.path === c || d.path.replace(/\.(md|mdx|markdown)$/i, "") === normalized);
260
+ if (match) {
261
+ targetDocId = match.id;
262
+ break;
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ if (!targetDocId) {
269
+ const doc = await getDocumentByPath(workspace, relPath(absolute));
270
+ if (!doc)
271
+ return [];
272
+ targetDocId = doc.id;
273
+ }
274
+ const hits = await findReferencesToDocument(workspace, targetDocId);
275
+ return hits.map((h) => Location.create(pathToUri(resolve(workspace.rootPath, h.documentPath)), rangeToLsp(h.range)));
276
+ });
277
+ connection.onCompletion(async (params) => {
278
+ if (!workspace)
279
+ return [];
280
+ const doc = docs.get(params.textDocument.uri);
281
+ if (!doc)
282
+ return [];
283
+ const line = doc.getText({
284
+ start: Position.create(params.position.line, 0),
285
+ end: params.position,
286
+ });
287
+ const wikiMatch = line.match(/\[\[([^\]]*)$/);
288
+ if (!wikiMatch)
289
+ return [];
290
+ const prefix = wikiMatch[1].toLowerCase();
291
+ const allDocs = await db.select().from(documents).where(eq(documents.workspaceId, workspace.id));
292
+ return allDocs
293
+ .filter((d) => {
294
+ const base = (d.path.split("/").pop() ?? "").replace(/\.(md|mdx|markdown)$/i, "").toLowerCase();
295
+ return base.startsWith(prefix) || (d.title?.toLowerCase().startsWith(prefix) ?? false);
296
+ })
297
+ .slice(0, 50)
298
+ .map((d) => {
299
+ const base = (d.path.split("/").pop() ?? "").replace(/\.(md|mdx|markdown)$/i, "");
300
+ return {
301
+ label: base,
302
+ kind: CompletionItemKind.File,
303
+ detail: d.path,
304
+ insertText: base,
305
+ };
306
+ });
307
+ });
308
+ connection.onExecuteCommand(async (params) => {
309
+ if (params.command === "markdownLsp/reindex" && workspace) {
310
+ connection.console.info("Manual reindex requested");
311
+ const result = await indexWorkspace(workspace);
312
+ await publishWorkspaceDiagnostics();
313
+ return result;
314
+ }
315
+ return null;
316
+ });
317
+ connection.onDidChangeWatchedFiles(async (params) => {
318
+ if (!workspace)
319
+ return;
320
+ for (const change of params.changes) {
321
+ const absolute = uriToPath(change.uri);
322
+ if (!absolute.startsWith(workspace.rootPath))
323
+ continue;
324
+ if (change.type === 3) {
325
+ await removeFile(workspace, absolute);
326
+ }
327
+ else {
328
+ try {
329
+ await indexFile(workspace, absolute);
330
+ }
331
+ catch (e) {
332
+ connection.console.error(`watched file index error ${absolute}: ${e instanceof Error ? e.message : e}`);
333
+ }
334
+ }
335
+ }
336
+ await resolveLinkTargets(workspace);
337
+ await publishWorkspaceDiagnostics();
338
+ });
339
+ void readdir;
340
+ void TextEdit;
341
+ docs.listen(connection);
342
+ connection.listen();
343
+ //# sourceMappingURL=lsp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.js","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,22 +1,23 @@
1
1
  {
2
2
  "name": "markdown-lsp",
3
- "version": "0.2.2",
3
+ "version": "1.0.0",
4
4
  "description": "Language Server Protocol implementation for Markdown with optional AI-canonicalized glossary that resolves synonyms across docs",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "markdown-lsp": "./bin/markdown-lsp"
8
8
  },
9
- "main": "./dist/server.js",
9
+ "main": "./dist/lsp.js",
10
10
  "exports": {
11
- ".": "./dist/server.js",
11
+ ".": "./dist/lsp.js",
12
12
  "./bridge": "./dist/bridge/index.js",
13
13
  "./indexer": "./dist/indexer/indexer.js",
14
14
  "./core": "./dist/core/index.js",
15
- "./parser": "./dist/indexer/parseMarkdown.js"
15
+ "./parser": "./dist/indexer/parseMarkdown.js",
16
+ "./graph": "./dist/graph.js"
16
17
  },
17
18
  "scripts": {
18
19
  "build": "tsc",
19
- "dev": "tsx src/server.ts --stdio",
20
+ "dev": "tsx src/lsp.ts --stdio",
20
21
  "migrate": "tsx scripts/apply-migration.ts",
21
22
  "test": "vitest run",
22
23
  "test:fast": "vitest run test/parseMarkdown.test.ts test/bridge.test.ts test/ai-disabled.test.ts",