@gtkx/mcp 1.0.0-rc.3 → 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/dist/reference.js CHANGED
@@ -2,12 +2,18 @@ import { loadApiReference, resolveGirPath, resolveLibraries } from "@gtkx/codege
2
2
  import { loadConfig } from "@gtkx/config";
3
3
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
5
- import { statSync } from "node:fs";
6
- import { resolve } from "node:path";
5
+ import { existsSync, statSync } from "node:fs";
6
+ import { dirname, join, resolve } from "node:path";
7
7
  import { z } from "zod";
8
8
  import { defineTool, textContent, textError } from "./tool.js";
9
9
  const FRESHNESS_INTERVAL_MS = 2000;
10
10
  const FAILURE_RETRY_MS = 5000;
11
+ const CONFIG_EXTENSIONS = ["ts", "mts", "cts", "js", "mjs", "cjs", "json"];
12
+ const PROJECT_SOURCE_LABELS = {
13
+ argument: "requested with `projectRoot`",
14
+ workingDirectory: "found from the working directory",
15
+ app: "taken from a connected app; pass `projectRoot` to document another project",
16
+ };
11
17
  const SYMBOL_KIND = z.enum([
12
18
  "element",
13
19
  "class",
@@ -21,19 +27,28 @@ const SYMBOL_KIND = z.enum([
21
27
  ]);
22
28
  const SYMBOL_DESCRIPTION = "Qualified symbol name (`Gtk.Button`, `Gtk.Orientation`, `GLib.idleAdd`), JSX element name (`GtkButton`), " +
23
29
  "or bare symbol name when unambiguous (`Button`).";
30
+ const PROJECT_ROOT_DESCRIPTION = "Directory of the GTKX project whose bindings to document, absolute or relative to the working directory. " +
31
+ "Any directory inside the project works; its `gtkx.config.ts` decides the documented libraries. Omit to use " +
32
+ "the project containing the working directory, falling back to a connected app's project.";
33
+ const projectRootShape = {
34
+ projectRoot: z.string().optional().describe(PROJECT_ROOT_DESCRIPTION),
35
+ };
24
36
  const listApiShape = {
37
+ ...projectRootShape,
25
38
  namespace: z
26
39
  .string()
27
40
  .optional()
28
41
  .describe("Namespace to list (e.g. `Gtk`, `Adw`, `Gio`). Omit for an overview of all namespaces."),
29
42
  };
30
43
  const searchApiShape = {
44
+ ...projectRootShape,
31
45
  query: z.string().describe("Case-insensitive substring of a symbol name, e.g. `headerbar` or `orientation`."),
32
46
  namespace: z.string().optional().describe("Restrict matches to one namespace (e.g. `Gtk`)."),
33
47
  kind: SYMBOL_KIND.optional().describe("Restrict matches to one symbol kind."),
34
48
  limit: z.number().int().min(1).optional().describe("Maximum number of results (default: 20)."),
35
49
  };
36
50
  const apiDocsShape = {
51
+ ...projectRootShape,
37
52
  symbol: z.string().describe(SYMBOL_DESCRIPTION),
38
53
  kind: SYMBOL_KIND.optional().describe("Disambiguate when several kinds share the symbol name."),
39
54
  };
@@ -50,11 +65,38 @@ const isFresh = (loaded) => loaded.watched.every((file) => {
50
65
  const current = watchFile(file.path);
51
66
  return current.mtimeMs === file.mtimeMs && current.size === file.size;
52
67
  });
53
- const loadReference = async (root) => {
54
- const { config, configFile } = await loadConfig(root);
68
+ const hasConfigFile = (directory) => CONFIG_EXTENSIONS.some((extension) => existsSync(join(directory, `gtkx.config.${extension}`)));
69
+ const findProjectRoot = (start) => {
70
+ const current = resolve(start);
71
+ const parent = dirname(current);
72
+ if (hasConfigFile(current)) {
73
+ return current;
74
+ }
75
+ return parent === current ? undefined : findProjectRoot(parent);
76
+ };
77
+ const projectAt = (candidate, source) => ({
78
+ root: findProjectRoot(candidate) ?? resolve(candidate),
79
+ source,
80
+ });
81
+ const resolveProject = (workingDirectory, getAppRoot, projectRoot) => {
82
+ if (projectRoot !== undefined) {
83
+ return projectAt(projectRoot, "argument");
84
+ }
85
+ const discovered = findProjectRoot(workingDirectory);
86
+ if (discovered !== undefined) {
87
+ return { root: discovered, source: "workingDirectory" };
88
+ }
89
+ const appRoot = getAppRoot();
90
+ return appRoot === undefined
91
+ ? { root: resolve(workingDirectory), source: "workingDirectory" }
92
+ : projectAt(appRoot, "app");
93
+ };
94
+ const loadReference = async (requestedRoot) => {
95
+ const { config, configFile, root } = await loadConfig(requestedRoot);
55
96
  if (config.codegen === false) {
56
97
  throw new Error(`codegen is disabled for the project at ${root}, so there are no generated bindings to document. ` +
57
- "Remove `codegen: false` from gtkx.config.ts to use the API reference.");
98
+ "Remove `codegen: false` from gtkx.config.ts to use the API reference, or point the `projectRoot` " +
99
+ "argument at another project.");
58
100
  }
59
101
  const girPath = resolveGirPath(config.girPath);
60
102
  if (girPath.length === 0) {
@@ -65,7 +107,7 @@ const loadReference = async (root) => {
65
107
  const libraries = resolveLibraries(config.libraries, girPath);
66
108
  const reference = loadApiReference({ libraries, girPath });
67
109
  const watched = [watchFile(resolve(root, configFile)), ...reference.girFiles.map((file) => watchFile(file))];
68
- return { reference, watched };
110
+ return { reference, root, watched };
69
111
  };
70
112
  const markFailed = async (entry) => {
71
113
  try {
@@ -94,20 +136,41 @@ const currentReference = async (cache, root) => {
94
136
  const entry = resolveEntry(cache, root);
95
137
  const loaded = await entry.pending;
96
138
  if (Date.now() - entry.verifiedAt < FRESHNESS_INTERVAL_MS) {
97
- return loaded.reference;
139
+ return loaded;
98
140
  }
99
141
  if (isFresh(loaded)) {
100
142
  entry.verifiedAt = Date.now();
101
- return loaded.reference;
143
+ return loaded;
102
144
  }
103
- const revalidated = await revalidate(cache, root, entry).pending;
104
- return revalidated.reference;
145
+ return revalidate(cache, root, entry).pending;
105
146
  };
106
- const createReferenceProvider = (resolveRoot) => {
147
+ const defaultWorkingDirectory = () => process.cwd();
148
+ const createReferenceProvider = (options) => {
107
149
  const cache = new Map();
108
- return {
109
- get: () => currentReference(cache, resolve(resolveRoot())),
150
+ const getWorkingDirectory = options.getWorkingDirectory ?? defaultWorkingDirectory;
151
+ const resolve = (projectRoot) => resolveProject(getWorkingDirectory(), options.getAppRoot, projectRoot);
152
+ const load = async (project) => {
153
+ const loaded = await currentReference(cache, project.root);
154
+ return { reference: loaded.reference, root: loaded.root, source: project.source };
110
155
  };
156
+ const get = (projectRoot) => load(resolve(projectRoot));
157
+ return { get, load, resolve };
158
+ };
159
+ const projectNote = (project) => `Project: ${project.root} (${PROJECT_SOURCE_LABELS[project.source]})`;
160
+ const withProjectNote = (result, note) => ({
161
+ ...result,
162
+ content: [...result.content, { type: "text", text: note }],
163
+ });
164
+ const scopedResult = async (provider, projectRoot, render) => {
165
+ const resolved = provider.resolve(projectRoot);
166
+ try {
167
+ const scoped = await provider.load(resolved);
168
+ return withProjectNote(render(scoped.reference), projectNote(scoped));
169
+ }
170
+ catch (error) {
171
+ const message = error instanceof Error ? error.message : String(error);
172
+ return withProjectNote(textError(message), projectNote(resolved));
173
+ }
111
174
  };
112
175
  const formatCandidates = (candidates) => candidates.map((candidate) => `- ${candidate.namespace}.${candidate.name} (${candidate.kind})`).join("\n");
113
176
  const buildSearchOptions = (args) => {
@@ -123,6 +186,38 @@ const buildSearchOptions = (args) => {
123
186
  }
124
187
  return options;
125
188
  };
189
+ const listApiResult = (reference, namespace) => {
190
+ if (namespace === undefined) {
191
+ return textContent(reference.overview());
192
+ }
193
+ const overview = reference.namespaceOverview(namespace);
194
+ if (overview === undefined) {
195
+ const names = reference
196
+ .namespaces()
197
+ .map((summary) => summary.name)
198
+ .join(", ");
199
+ return textError(`Unknown namespace "${namespace}". Available namespaces: ${names}`);
200
+ }
201
+ return textContent(overview);
202
+ };
203
+ const searchApiResult = (reference, args) => {
204
+ const results = reference.search(buildSearchOptions(args));
205
+ if (results.length === 0) {
206
+ return textContent(`No symbols matched "${args.query}". Try a shorter substring or \`gtkx_list_api\`.`);
207
+ }
208
+ return textContent(JSON.stringify(results, null, 2));
209
+ };
210
+ const apiDocsResult = (reference, args) => {
211
+ const result = reference.lookup(args.symbol, args.kind);
212
+ if (result.outcome === "notFound") {
213
+ return textError(`No symbol named "${args.symbol}". Use \`gtkx_search_api\` to find the right name.`);
214
+ }
215
+ if (result.outcome === "ambiguous") {
216
+ return textError(`"${args.symbol}" matches several symbols. Pass a qualified name or a kind:\n` +
217
+ formatCandidates(result.candidates));
218
+ }
219
+ return textContent(result.markdown);
220
+ };
126
221
  const listApiTool = (provider) => defineTool({
127
222
  name: "gtkx_list_api",
128
223
  title: "List API reference",
@@ -130,21 +225,7 @@ const listApiTool = (provider) => defineTool({
130
225
  description: "List the project's generated GTK4 bindings API (`@gtkx/gi` and `@gtkx/jsx`). Without a namespace, " +
131
226
  "returns every namespace with symbol counts; with a namespace, lists all of its symbols grouped by kind.",
132
227
  inputSchema: listApiShape,
133
- handler: async ({ namespace }) => {
134
- const reference = await provider.get();
135
- if (namespace === undefined) {
136
- return textContent(reference.overview());
137
- }
138
- const overview = reference.namespaceOverview(namespace);
139
- if (overview === undefined) {
140
- const names = reference
141
- .namespaces()
142
- .map((summary) => summary.name)
143
- .join(", ");
144
- return textError(`Unknown namespace "${namespace}". Available namespaces: ${names}`);
145
- }
146
- return textContent(overview);
147
- },
228
+ handler: ({ namespace, projectRoot }) => scopedResult(provider, projectRoot, (reference) => listApiResult(reference, namespace)),
148
229
  });
149
230
  const searchApiTool = (provider) => defineTool({
150
231
  name: "gtkx_search_api",
@@ -153,14 +234,7 @@ const searchApiTool = (provider) => defineTool({
153
234
  description: "Search the project's generated GTK4 bindings API by symbol name. Returns matching symbols with " +
154
235
  "their namespace, kind, and a one-line summary; fetch full pages with `gtkx_get_api_docs`.",
155
236
  inputSchema: searchApiShape,
156
- handler: async (args) => {
157
- const reference = await provider.get();
158
- const results = reference.search(buildSearchOptions(args));
159
- if (results.length === 0) {
160
- return textContent(`No symbols matched "${args.query}". Try a shorter substring or \`gtkx_list_api\`.`);
161
- }
162
- return textContent(JSON.stringify(results, null, 2));
163
- },
237
+ handler: (args) => scopedResult(provider, args.projectRoot, (reference) => searchApiResult(reference, args)),
164
238
  });
165
239
  const getApiDocsTool = (provider) => defineTool({
166
240
  name: "gtkx_get_api_docs",
@@ -170,18 +244,7 @@ const getApiDocsTool = (provider) => defineTool({
170
244
  "(props, signals, methods) or `@gtkx/gi` classes, interfaces, records, enums, callbacks, aliases, " +
171
245
  "functions, and constants.",
172
246
  inputSchema: apiDocsShape,
173
- handler: async ({ symbol, kind }) => {
174
- const reference = await provider.get();
175
- const result = reference.lookup(symbol, kind);
176
- if (result.outcome === "notFound") {
177
- return textError(`No symbol named "${symbol}". Use \`gtkx_search_api\` to find the right name.`);
178
- }
179
- if (result.outcome === "ambiguous") {
180
- return textError(`"${symbol}" matches several symbols. Pass a qualified name or a kind:\n` +
181
- formatCandidates(result.candidates));
182
- }
183
- return textContent(result.markdown);
184
- },
247
+ handler: (args) => scopedResult(provider, args.projectRoot, (reference) => apiDocsResult(reference, args)),
185
248
  });
186
249
  const buildReferenceTools = (provider) => [
187
250
  listApiTool(provider),
@@ -200,25 +263,21 @@ const withLoadFallback = async (load, fallback) => {
200
263
  return fallback;
201
264
  }
202
265
  };
203
- const namespaceCompleter = (provider) => (value) => withLoadFallback(async () => {
204
- const reference = await provider.get();
205
- return reference
206
- .namespaces()
207
- .map((summary) => summary.name)
208
- .filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));
266
+ const namesStartingWith = (names, value) => names.filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));
267
+ const completeNames = (provider, value, collect) => withLoadFallback(async () => {
268
+ const { reference } = await provider.get();
269
+ return namesStartingWith(collect(reference), value);
209
270
  }, []);
210
- const completeSymbol = async (provider, namespace, value) => {
271
+ const namespaceCompleter = (provider) => (value) => completeNames(provider, value, (reference) => reference.namespaces().map((summary) => summary.name));
272
+ const completeSymbol = (provider, namespace, value) => {
211
273
  if (namespace.length === 0) {
212
- return [];
274
+ return Promise.resolve([]);
213
275
  }
214
- return withLoadFallback(async () => {
215
- const reference = await provider.get();
216
- return reference.symbolNames(namespace).filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));
217
- }, []);
276
+ return completeNames(provider, value, (reference) => reference.symbolNames(namespace));
218
277
  };
219
278
  const resourceNotFound = (message) => new McpError(ErrorCode.InvalidParams, message);
220
279
  const symbolPage = async (uri, provider, namespace, symbol) => {
221
- const reference = await provider.get();
280
+ const { reference } = await provider.get();
222
281
  const result = reference.lookup(`${namespace}.${symbol}`);
223
282
  if (result.outcome === "page") {
224
283
  return markdownResource(uri, result.markdown);
@@ -234,14 +293,14 @@ const registerIndexResource = (server, provider) => {
234
293
  description: "Namespaces of the project's generated GTK4 bindings, with symbol and JSX element counts.",
235
294
  mimeType: "text/markdown",
236
295
  }, async (uri) => {
237
- const reference = await provider.get();
296
+ const { reference } = await provider.get();
238
297
  return markdownResource(uri, reference.overview());
239
298
  });
240
299
  };
241
300
  const registerNamespaceResource = (server, provider) => {
242
301
  server.registerResource("gtkx-api-namespace", new ResourceTemplate("gtkx://reference/{namespace}", {
243
302
  list: () => withLoadFallback(async () => {
244
- const reference = await provider.get();
303
+ const { reference } = await provider.get();
245
304
  return {
246
305
  resources: reference.namespaces().map((summary) => ({
247
306
  uri: `gtkx://reference/${summary.name}`,
@@ -259,7 +318,7 @@ const registerNamespaceResource = (server, provider) => {
259
318
  mimeType: "text/markdown",
260
319
  }, async (uri, variables) => {
261
320
  const namespace = variableValue(variables.namespace);
262
- const reference = await provider.get();
321
+ const { reference } = await provider.get();
263
322
  const overview = reference.namespaceOverview(namespace);
264
323
  if (overview === undefined) {
265
324
  throw resourceNotFound(`Unknown namespace "${namespace}"`);
@@ -1 +1 @@
1
- {"version":3,"file":"reference.js","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ApiReference, type ApiSymbol, loadApiReference, resolveGirPath, resolveLibraries } from \"@gtkx/codegen\";\nimport { loadConfig } from \"@gtkx/config\";\nimport { type McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ErrorCode, McpError, type ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool, textContent, textError, type Tool, type ToolArgs } from \"./tool.js\";\n\ntype ReferenceApi = Pick<\n ApiReference,\n \"lookup\" | \"namespaceOverview\" | \"namespaces\" | \"overview\" | \"search\" | \"symbolNames\"\n>;\n\ntype ReferenceProvider = {\n get(): Promise<ReferenceApi>;\n};\n\ntype WatchedFile = {\n path: string;\n mtimeMs: number;\n size: number;\n};\n\ntype LoadedReference = {\n reference: ApiReference;\n watched: WatchedFile[];\n};\n\ntype CacheEntry = {\n pending: Promise<LoadedReference>;\n verifiedAt: number;\n failedAt: number | undefined;\n};\n\ntype ReferenceCache = Map<string, CacheEntry>;\ntype SearchOptions = Parameters<ReferenceApi[\"search\"]>[0];\ntype ResourceServer = Pick<McpServer, \"registerResource\">;\n\nconst FRESHNESS_INTERVAL_MS = 2000;\nconst FAILURE_RETRY_MS = 5000;\n\nconst SYMBOL_KIND = z.enum([\n \"element\",\n \"class\",\n \"interface\",\n \"record\",\n \"enum\",\n \"callback\",\n \"alias\",\n \"function\",\n \"constant\",\n]);\n\nconst SYMBOL_DESCRIPTION =\n \"Qualified symbol name (`Gtk.Button`, `Gtk.Orientation`, `GLib.idleAdd`), JSX element name (`GtkButton`), \" +\n \"or bare symbol name when unambiguous (`Button`).\";\n\nconst listApiShape = {\n namespace: z\n .string()\n .optional()\n .describe(\"Namespace to list (e.g. `Gtk`, `Adw`, `Gio`). Omit for an overview of all namespaces.\"),\n};\n\nconst searchApiShape = {\n query: z.string().describe(\"Case-insensitive substring of a symbol name, e.g. `headerbar` or `orientation`.\"),\n namespace: z.string().optional().describe(\"Restrict matches to one namespace (e.g. `Gtk`).\"),\n kind: SYMBOL_KIND.optional().describe(\"Restrict matches to one symbol kind.\"),\n limit: z.number().int().min(1).optional().describe(\"Maximum number of results (default: 20).\"),\n};\n\nconst apiDocsShape = {\n symbol: z.string().describe(SYMBOL_DESCRIPTION),\n kind: SYMBOL_KIND.optional().describe(\"Disambiguate when several kinds share the symbol name.\"),\n};\n\nconst watchFile = (path: string): WatchedFile => {\n try {\n const stats = statSync(path);\n\n return { path, mtimeMs: stats.mtimeMs, size: stats.size };\n } catch {\n return { path, mtimeMs: -1, size: -1 };\n }\n};\n\nconst isFresh = (loaded: LoadedReference): boolean =>\n loaded.watched.every((file) => {\n const current = watchFile(file.path);\n\n return current.mtimeMs === file.mtimeMs && current.size === file.size;\n });\n\nconst loadReference = async (root: string): Promise<LoadedReference> => {\n const { config, configFile } = await loadConfig(root);\n\n if (config.codegen === false) {\n throw new Error(\n `codegen is disabled for the project at ${root}, so there are no generated bindings to document. ` +\n \"Remove `codegen: false` from gtkx.config.ts to use the API reference.\",\n );\n }\n\n const girPath = resolveGirPath(config.girPath);\n\n if (girPath.length === 0) {\n throw new Error(\n \"No GIR search paths available. Install gobject-introspection \" +\n \"(Linux: `sudo dnf install gobject-introspection-devel` or `sudo apt install libgirepository1.0-dev`), \" +\n \"or set `girPath` in gtkx.config.ts.\",\n );\n }\n\n const libraries = resolveLibraries(config.libraries, girPath);\n const reference = loadApiReference({ libraries, girPath });\n const watched = [watchFile(resolve(root, configFile)), ...reference.girFiles.map((file) => watchFile(file))];\n\n return { reference, watched };\n};\n\nconst markFailed = async (entry: CacheEntry): Promise<void> => {\n try {\n await entry.pending;\n } catch {\n entry.failedAt = Date.now();\n }\n};\n\nconst startLoad = (cache: ReferenceCache, root: string): CacheEntry => {\n const entry: CacheEntry = { pending: loadReference(root), verifiedAt: Date.now(), failedAt: undefined };\n void markFailed(entry);\n cache.set(root, entry);\n\n return entry;\n};\n\nconst isRetryDue = (entry: CacheEntry): boolean =>\n entry.failedAt !== undefined && Date.now() - entry.failedAt >= FAILURE_RETRY_MS;\n\nconst resolveEntry = (cache: ReferenceCache, root: string): CacheEntry => {\n const entry = cache.get(root) ?? startLoad(cache, root);\n\n return isRetryDue(entry) ? startLoad(cache, root) : entry;\n};\n\nconst revalidate = (cache: ReferenceCache, root: string, entry: CacheEntry): CacheEntry => {\n const current = cache.get(root);\n\n return current === undefined || current === entry ? startLoad(cache, root) : current;\n};\n\nconst currentReference = async (cache: ReferenceCache, root: string): Promise<ReferenceApi> => {\n const entry = resolveEntry(cache, root);\n const loaded = await entry.pending;\n\n if (Date.now() - entry.verifiedAt < FRESHNESS_INTERVAL_MS) {\n return loaded.reference;\n }\n\n if (isFresh(loaded)) {\n entry.verifiedAt = Date.now();\n\n return loaded.reference;\n }\n\n const revalidated = await revalidate(cache, root, entry).pending;\n\n return revalidated.reference;\n};\n\nconst createReferenceProvider = (resolveRoot: () => string): ReferenceProvider => {\n const cache: ReferenceCache = new Map();\n\n return {\n get: () => currentReference(cache, resolve(resolveRoot())),\n };\n};\n\nconst formatCandidates = (candidates: ApiSymbol[]): string =>\n candidates.map((candidate) => `- ${candidate.namespace}.${candidate.name} (${candidate.kind})`).join(\"\\n\");\n\nconst buildSearchOptions = (args: ToolArgs<typeof searchApiShape>): SearchOptions => {\n const options: SearchOptions = { query: args.query };\n\n if (args.namespace !== undefined) {\n options.namespace = args.namespace;\n }\n\n if (args.kind !== undefined) {\n options.kinds = [args.kind];\n }\n\n if (args.limit !== undefined) {\n options.limit = args.limit;\n }\n\n return options;\n};\n\nconst listApiTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_list_api\",\n title: \"List API reference\",\n kind: \"readOnly\",\n description:\n \"List the project's generated GTK4 bindings API (`@gtkx/gi` and `@gtkx/jsx`). Without a namespace, \" +\n \"returns every namespace with symbol counts; with a namespace, lists all of its symbols grouped by kind.\",\n inputSchema: listApiShape,\n handler: async ({ namespace }) => {\n const reference = await provider.get();\n\n if (namespace === undefined) {\n return textContent(reference.overview());\n }\n\n const overview = reference.namespaceOverview(namespace);\n\n if (overview === undefined) {\n const names = reference\n .namespaces()\n .map((summary) => summary.name)\n .join(\", \");\n\n return textError(`Unknown namespace \"${namespace}\". Available namespaces: ${names}`);\n }\n\n return textContent(overview);\n },\n });\n\nconst searchApiTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_search_api\",\n title: \"Search API reference\",\n kind: \"readOnly\",\n description:\n \"Search the project's generated GTK4 bindings API by symbol name. Returns matching symbols with \" +\n \"their namespace, kind, and a one-line summary; fetch full pages with `gtkx_get_api_docs`.\",\n inputSchema: searchApiShape,\n handler: async (args) => {\n const reference = await provider.get();\n const results = reference.search(buildSearchOptions(args));\n\n if (results.length === 0) {\n return textContent(`No symbols matched \"${args.query}\". Try a shorter substring or \\`gtkx_list_api\\`.`);\n }\n\n return textContent(JSON.stringify(results, null, 2));\n },\n });\n\nconst getApiDocsTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_get_api_docs\",\n title: \"Get API docs\",\n kind: \"readOnly\",\n description:\n \"Get the full reference page for one symbol of the project's generated GTK4 bindings: JSX elements \" +\n \"(props, signals, methods) or `@gtkx/gi` classes, interfaces, records, enums, callbacks, aliases, \" +\n \"functions, and constants.\",\n inputSchema: apiDocsShape,\n handler: async ({ symbol, kind }) => {\n const reference = await provider.get();\n const result = reference.lookup(symbol, kind);\n\n if (result.outcome === \"notFound\") {\n return textError(`No symbol named \"${symbol}\". Use \\`gtkx_search_api\\` to find the right name.`);\n }\n\n if (result.outcome === \"ambiguous\") {\n return textError(\n `\"${symbol}\" matches several symbols. Pass a qualified name or a kind:\\n` +\n formatCandidates(result.candidates),\n );\n }\n\n return textContent(result.markdown);\n },\n });\n\nconst buildReferenceTools = (provider: ReferenceProvider): Tool[] => [\n listApiTool(provider),\n searchApiTool(provider),\n getApiDocsTool(provider),\n];\n\nconst markdownResource = (uri: URL, text: string): ReadResourceResult => ({\n contents: [{ uri: uri.href, mimeType: \"text/markdown\", text }],\n});\n\nconst variableValue = (value: string | string[] | undefined): string =>\n Array.isArray(value) ? (value[0] ?? \"\") : (value ?? \"\");\n\nconst withLoadFallback = async <T>(load: () => Promise<T>, fallback: T): Promise<T> => {\n try {\n return await load();\n } catch {\n return fallback;\n }\n};\n\nconst namespaceCompleter =\n (provider: ReferenceProvider) =>\n (value: string): Promise<string[]> =>\n withLoadFallback(async () => {\n const reference = await provider.get();\n\n return reference\n .namespaces()\n .map((summary) => summary.name)\n .filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));\n }, []);\n\nconst completeSymbol = async (provider: ReferenceProvider, namespace: string, value: string): Promise<string[]> => {\n if (namespace.length === 0) {\n return [];\n }\n\n return withLoadFallback(async () => {\n const reference = await provider.get();\n\n return reference.symbolNames(namespace).filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));\n }, []);\n};\n\nconst resourceNotFound = (message: string): McpError => new McpError(ErrorCode.InvalidParams, message);\n\nconst symbolPage = async (\n uri: URL,\n provider: ReferenceProvider,\n namespace: string,\n symbol: string,\n): Promise<ReadResourceResult> => {\n const reference = await provider.get();\n const result = reference.lookup(`${namespace}.${symbol}`);\n\n if (result.outcome === \"page\") {\n return markdownResource(uri, result.markdown);\n }\n\n if (result.outcome === \"ambiguous\") {\n throw resourceNotFound(\n `\"${namespace}.${symbol}\" matches several symbols:\\n${formatCandidates(result.candidates)}`,\n );\n }\n\n throw resourceNotFound(`No symbol named \"${namespace}.${symbol}\"`);\n};\n\nconst registerIndexResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-reference\",\n \"gtkx://reference/index\",\n {\n title: \"GTKX API reference index\",\n description: \"Namespaces of the project's generated GTK4 bindings, with symbol and JSX element counts.\",\n mimeType: \"text/markdown\",\n },\n async (uri) => {\n const reference = await provider.get();\n\n return markdownResource(uri, reference.overview());\n },\n );\n};\n\nconst registerNamespaceResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-namespace\",\n new ResourceTemplate(\"gtkx://reference/{namespace}\", {\n list: () =>\n withLoadFallback(\n async () => {\n const reference = await provider.get();\n\n return {\n resources: reference.namespaces().map((summary) => ({\n uri: `gtkx://reference/${summary.name}`,\n name: `${summary.name} namespace reference`,\n mimeType: \"text/markdown\",\n })),\n };\n },\n { resources: [] },\n ),\n complete: {\n namespace: namespaceCompleter(provider),\n },\n }),\n {\n title: \"GTKX namespace reference\",\n description: \"All symbols of one namespace of the project's generated GTK4 bindings, grouped by kind.\",\n mimeType: \"text/markdown\",\n },\n async (uri, variables) => {\n const namespace = variableValue(variables.namespace);\n const reference = await provider.get();\n const overview = reference.namespaceOverview(namespace);\n\n if (overview === undefined) {\n throw resourceNotFound(`Unknown namespace \"${namespace}\"`);\n }\n\n return markdownResource(uri, overview);\n },\n );\n};\n\nconst registerSymbolResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-symbol\",\n new ResourceTemplate(\"gtkx://reference/{namespace}/{symbol}\", {\n list: undefined,\n complete: {\n namespace: namespaceCompleter(provider),\n symbol: (value, context) =>\n completeSymbol(provider, variableValue(context?.arguments?.namespace), value),\n },\n }),\n {\n title: \"GTKX symbol reference\",\n description:\n \"Reference page for one symbol of the project's generated GTK4 bindings: a JSX element or a \" +\n \"class, interface, record, enum, callback, alias, function, or constant.\",\n mimeType: \"text/markdown\",\n },\n (uri, variables) =>\n symbolPage(uri, provider, variableValue(variables.namespace), variableValue(variables.symbol)),\n );\n};\n\nconst registerReferenceResources = (server: ResourceServer, provider: ReferenceProvider): void => {\n registerIndexResource(server, provider);\n registerNamespaceResource(server, provider);\n registerSymbolResource(server, provider);\n};\n\nexport {\n createReferenceProvider,\n buildReferenceTools,\n registerReferenceResources,\n type ReferenceApi,\n type ReferenceProvider,\n};\n"]}
1
+ {"version":3,"file":"reference.js","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ApiReference, type ApiSymbol, loadApiReference, resolveGirPath, resolveLibraries } from \"@gtkx/codegen\";\nimport { loadConfig } from \"@gtkx/config\";\nimport { type McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { type CallToolResult, ErrorCode, McpError, type ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool, textContent, textError, type Tool, type ToolArgs } from \"./tool.js\";\n\ntype ReferenceApi = Pick<\n ApiReference,\n \"lookup\" | \"namespaceOverview\" | \"namespaces\" | \"overview\" | \"search\" | \"symbolNames\"\n>;\n\ntype ProjectSource = \"argument\" | \"workingDirectory\" | \"app\";\n\ntype ResolvedProject = {\n root: string;\n source: ProjectSource;\n};\n\ntype ScopedReference = ResolvedProject & {\n reference: ReferenceApi;\n};\n\ntype ReferenceProviderOptions = {\n getAppRoot: () => string | undefined;\n getWorkingDirectory?: () => string;\n};\n\ntype ReferenceProvider = {\n get(projectRoot?: string): Promise<ScopedReference>;\n load(project: ResolvedProject): Promise<ScopedReference>;\n resolve(projectRoot?: string): ResolvedProject;\n};\n\ntype WatchedFile = {\n path: string;\n mtimeMs: number;\n size: number;\n};\n\ntype LoadedReference = {\n reference: ApiReference;\n root: string;\n watched: WatchedFile[];\n};\n\ntype CacheEntry = {\n pending: Promise<LoadedReference>;\n verifiedAt: number;\n failedAt: number | undefined;\n};\n\ntype ReferenceCache = Map<string, CacheEntry>;\ntype SearchOptions = Parameters<ReferenceApi[\"search\"]>[0];\ntype ResourceServer = Pick<McpServer, \"registerResource\">;\n\nconst FRESHNESS_INTERVAL_MS = 2000;\nconst FAILURE_RETRY_MS = 5000;\nconst CONFIG_EXTENSIONS = [\"ts\", \"mts\", \"cts\", \"js\", \"mjs\", \"cjs\", \"json\"];\n\nconst PROJECT_SOURCE_LABELS: Record<ProjectSource, string> = {\n argument: \"requested with `projectRoot`\",\n workingDirectory: \"found from the working directory\",\n app: \"taken from a connected app; pass `projectRoot` to document another project\",\n};\n\nconst SYMBOL_KIND = z.enum([\n \"element\",\n \"class\",\n \"interface\",\n \"record\",\n \"enum\",\n \"callback\",\n \"alias\",\n \"function\",\n \"constant\",\n]);\n\nconst SYMBOL_DESCRIPTION =\n \"Qualified symbol name (`Gtk.Button`, `Gtk.Orientation`, `GLib.idleAdd`), JSX element name (`GtkButton`), \" +\n \"or bare symbol name when unambiguous (`Button`).\";\n\nconst PROJECT_ROOT_DESCRIPTION =\n \"Directory of the GTKX project whose bindings to document, absolute or relative to the working directory. \" +\n \"Any directory inside the project works; its `gtkx.config.ts` decides the documented libraries. Omit to use \" +\n \"the project containing the working directory, falling back to a connected app's project.\";\n\nconst projectRootShape = {\n projectRoot: z.string().optional().describe(PROJECT_ROOT_DESCRIPTION),\n};\n\nconst listApiShape = {\n ...projectRootShape,\n namespace: z\n .string()\n .optional()\n .describe(\"Namespace to list (e.g. `Gtk`, `Adw`, `Gio`). Omit for an overview of all namespaces.\"),\n};\n\nconst searchApiShape = {\n ...projectRootShape,\n query: z.string().describe(\"Case-insensitive substring of a symbol name, e.g. `headerbar` or `orientation`.\"),\n namespace: z.string().optional().describe(\"Restrict matches to one namespace (e.g. `Gtk`).\"),\n kind: SYMBOL_KIND.optional().describe(\"Restrict matches to one symbol kind.\"),\n limit: z.number().int().min(1).optional().describe(\"Maximum number of results (default: 20).\"),\n};\n\nconst apiDocsShape = {\n ...projectRootShape,\n symbol: z.string().describe(SYMBOL_DESCRIPTION),\n kind: SYMBOL_KIND.optional().describe(\"Disambiguate when several kinds share the symbol name.\"),\n};\n\nconst watchFile = (path: string): WatchedFile => {\n try {\n const stats = statSync(path);\n\n return { path, mtimeMs: stats.mtimeMs, size: stats.size };\n } catch {\n return { path, mtimeMs: -1, size: -1 };\n }\n};\n\nconst isFresh = (loaded: LoadedReference): boolean =>\n loaded.watched.every((file) => {\n const current = watchFile(file.path);\n\n return current.mtimeMs === file.mtimeMs && current.size === file.size;\n });\n\nconst hasConfigFile = (directory: string): boolean =>\n CONFIG_EXTENSIONS.some((extension) => existsSync(join(directory, `gtkx.config.${extension}`)));\n\nconst findProjectRoot = (start: string): string | undefined => {\n const current = resolve(start);\n const parent = dirname(current);\n\n if (hasConfigFile(current)) {\n return current;\n }\n\n return parent === current ? undefined : findProjectRoot(parent);\n};\n\nconst projectAt = (candidate: string, source: ProjectSource): ResolvedProject => ({\n root: findProjectRoot(candidate) ?? resolve(candidate),\n source,\n});\n\nconst resolveProject = (\n workingDirectory: string,\n getAppRoot: () => string | undefined,\n projectRoot: string | undefined,\n): ResolvedProject => {\n if (projectRoot !== undefined) {\n return projectAt(projectRoot, \"argument\");\n }\n\n const discovered = findProjectRoot(workingDirectory);\n\n if (discovered !== undefined) {\n return { root: discovered, source: \"workingDirectory\" };\n }\n\n const appRoot = getAppRoot();\n\n return appRoot === undefined\n ? { root: resolve(workingDirectory), source: \"workingDirectory\" }\n : projectAt(appRoot, \"app\");\n};\n\nconst loadReference = async (requestedRoot: string): Promise<LoadedReference> => {\n const { config, configFile, root } = await loadConfig(requestedRoot);\n\n if (config.codegen === false) {\n throw new Error(\n `codegen is disabled for the project at ${root}, so there are no generated bindings to document. ` +\n \"Remove `codegen: false` from gtkx.config.ts to use the API reference, or point the `projectRoot` \" +\n \"argument at another project.\",\n );\n }\n\n const girPath = resolveGirPath(config.girPath);\n\n if (girPath.length === 0) {\n throw new Error(\n \"No GIR search paths available. Install gobject-introspection \" +\n \"(Linux: `sudo dnf install gobject-introspection-devel` or `sudo apt install libgirepository1.0-dev`), \" +\n \"or set `girPath` in gtkx.config.ts.\",\n );\n }\n\n const libraries = resolveLibraries(config.libraries, girPath);\n const reference = loadApiReference({ libraries, girPath });\n const watched = [watchFile(resolve(root, configFile)), ...reference.girFiles.map((file) => watchFile(file))];\n\n return { reference, root, watched };\n};\n\nconst markFailed = async (entry: CacheEntry): Promise<void> => {\n try {\n await entry.pending;\n } catch {\n entry.failedAt = Date.now();\n }\n};\n\nconst startLoad = (cache: ReferenceCache, root: string): CacheEntry => {\n const entry: CacheEntry = { pending: loadReference(root), verifiedAt: Date.now(), failedAt: undefined };\n void markFailed(entry);\n cache.set(root, entry);\n\n return entry;\n};\n\nconst isRetryDue = (entry: CacheEntry): boolean =>\n entry.failedAt !== undefined && Date.now() - entry.failedAt >= FAILURE_RETRY_MS;\n\nconst resolveEntry = (cache: ReferenceCache, root: string): CacheEntry => {\n const entry = cache.get(root) ?? startLoad(cache, root);\n\n return isRetryDue(entry) ? startLoad(cache, root) : entry;\n};\n\nconst revalidate = (cache: ReferenceCache, root: string, entry: CacheEntry): CacheEntry => {\n const current = cache.get(root);\n\n return current === undefined || current === entry ? startLoad(cache, root) : current;\n};\n\nconst currentReference = async (cache: ReferenceCache, root: string): Promise<LoadedReference> => {\n const entry = resolveEntry(cache, root);\n const loaded = await entry.pending;\n\n if (Date.now() - entry.verifiedAt < FRESHNESS_INTERVAL_MS) {\n return loaded;\n }\n\n if (isFresh(loaded)) {\n entry.verifiedAt = Date.now();\n\n return loaded;\n }\n\n return revalidate(cache, root, entry).pending;\n};\n\nconst defaultWorkingDirectory = (): string => process.cwd();\n\nconst createReferenceProvider = (options: ReferenceProviderOptions): ReferenceProvider => {\n const cache: ReferenceCache = new Map();\n const getWorkingDirectory = options.getWorkingDirectory ?? defaultWorkingDirectory;\n\n const resolve = (projectRoot?: string): ResolvedProject =>\n resolveProject(getWorkingDirectory(), options.getAppRoot, projectRoot);\n\n const load = async (project: ResolvedProject): Promise<ScopedReference> => {\n const loaded = await currentReference(cache, project.root);\n\n return { reference: loaded.reference, root: loaded.root, source: project.source };\n };\n\n const get = (projectRoot?: string): Promise<ScopedReference> => load(resolve(projectRoot));\n\n return { get, load, resolve };\n};\n\nconst projectNote = (project: ResolvedProject): string =>\n `Project: ${project.root} (${PROJECT_SOURCE_LABELS[project.source]})`;\n\nconst withProjectNote = (result: CallToolResult, note: string): CallToolResult => ({\n ...result,\n content: [...result.content, { type: \"text\", text: note }],\n});\n\nconst scopedResult = async (\n provider: ReferenceProvider,\n projectRoot: string | undefined,\n render: (reference: ReferenceApi) => CallToolResult,\n): Promise<CallToolResult> => {\n const resolved = provider.resolve(projectRoot);\n\n try {\n const scoped = await provider.load(resolved);\n\n return withProjectNote(render(scoped.reference), projectNote(scoped));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n return withProjectNote(textError(message), projectNote(resolved));\n }\n};\n\nconst formatCandidates = (candidates: ApiSymbol[]): string =>\n candidates.map((candidate) => `- ${candidate.namespace}.${candidate.name} (${candidate.kind})`).join(\"\\n\");\n\nconst buildSearchOptions = (args: ToolArgs<typeof searchApiShape>): SearchOptions => {\n const options: SearchOptions = { query: args.query };\n\n if (args.namespace !== undefined) {\n options.namespace = args.namespace;\n }\n\n if (args.kind !== undefined) {\n options.kinds = [args.kind];\n }\n\n if (args.limit !== undefined) {\n options.limit = args.limit;\n }\n\n return options;\n};\n\nconst listApiResult = (reference: ReferenceApi, namespace: string | undefined): CallToolResult => {\n if (namespace === undefined) {\n return textContent(reference.overview());\n }\n\n const overview = reference.namespaceOverview(namespace);\n\n if (overview === undefined) {\n const names = reference\n .namespaces()\n .map((summary) => summary.name)\n .join(\", \");\n\n return textError(`Unknown namespace \"${namespace}\". Available namespaces: ${names}`);\n }\n\n return textContent(overview);\n};\n\nconst searchApiResult = (reference: ReferenceApi, args: ToolArgs<typeof searchApiShape>): CallToolResult => {\n const results = reference.search(buildSearchOptions(args));\n\n if (results.length === 0) {\n return textContent(`No symbols matched \"${args.query}\". Try a shorter substring or \\`gtkx_list_api\\`.`);\n }\n\n return textContent(JSON.stringify(results, null, 2));\n};\n\nconst apiDocsResult = (reference: ReferenceApi, args: ToolArgs<typeof apiDocsShape>): CallToolResult => {\n const result = reference.lookup(args.symbol, args.kind);\n\n if (result.outcome === \"notFound\") {\n return textError(`No symbol named \"${args.symbol}\". Use \\`gtkx_search_api\\` to find the right name.`);\n }\n\n if (result.outcome === \"ambiguous\") {\n return textError(\n `\"${args.symbol}\" matches several symbols. Pass a qualified name or a kind:\\n` +\n formatCandidates(result.candidates),\n );\n }\n\n return textContent(result.markdown);\n};\n\nconst listApiTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_list_api\",\n title: \"List API reference\",\n kind: \"readOnly\",\n description:\n \"List the project's generated GTK4 bindings API (`@gtkx/gi` and `@gtkx/jsx`). Without a namespace, \" +\n \"returns every namespace with symbol counts; with a namespace, lists all of its symbols grouped by kind.\",\n inputSchema: listApiShape,\n handler: ({ namespace, projectRoot }) =>\n scopedResult(provider, projectRoot, (reference) => listApiResult(reference, namespace)),\n });\n\nconst searchApiTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_search_api\",\n title: \"Search API reference\",\n kind: \"readOnly\",\n description:\n \"Search the project's generated GTK4 bindings API by symbol name. Returns matching symbols with \" +\n \"their namespace, kind, and a one-line summary; fetch full pages with `gtkx_get_api_docs`.\",\n inputSchema: searchApiShape,\n handler: (args) => scopedResult(provider, args.projectRoot, (reference) => searchApiResult(reference, args)),\n });\n\nconst getApiDocsTool = (provider: ReferenceProvider): Tool =>\n defineTool({\n name: \"gtkx_get_api_docs\",\n title: \"Get API docs\",\n kind: \"readOnly\",\n description:\n \"Get the full reference page for one symbol of the project's generated GTK4 bindings: JSX elements \" +\n \"(props, signals, methods) or `@gtkx/gi` classes, interfaces, records, enums, callbacks, aliases, \" +\n \"functions, and constants.\",\n inputSchema: apiDocsShape,\n handler: (args) => scopedResult(provider, args.projectRoot, (reference) => apiDocsResult(reference, args)),\n });\n\nconst buildReferenceTools = (provider: ReferenceProvider): Tool[] => [\n listApiTool(provider),\n searchApiTool(provider),\n getApiDocsTool(provider),\n];\n\nconst markdownResource = (uri: URL, text: string): ReadResourceResult => ({\n contents: [{ uri: uri.href, mimeType: \"text/markdown\", text }],\n});\n\nconst variableValue = (value: string | string[] | undefined): string =>\n Array.isArray(value) ? (value[0] ?? \"\") : (value ?? \"\");\n\nconst withLoadFallback = async <T>(load: () => Promise<T>, fallback: T): Promise<T> => {\n try {\n return await load();\n } catch {\n return fallback;\n }\n};\n\nconst namesStartingWith = (names: string[], value: string): string[] =>\n names.filter((name) => name.toLowerCase().startsWith(value.toLowerCase()));\n\nconst completeNames = (\n provider: ReferenceProvider,\n value: string,\n collect: (reference: ReferenceApi) => string[],\n): Promise<string[]> =>\n withLoadFallback(async () => {\n const { reference } = await provider.get();\n\n return namesStartingWith(collect(reference), value);\n }, []);\n\nconst namespaceCompleter =\n (provider: ReferenceProvider) =>\n (value: string): Promise<string[]> =>\n completeNames(provider, value, (reference) => reference.namespaces().map((summary) => summary.name));\n\nconst completeSymbol = (provider: ReferenceProvider, namespace: string, value: string): Promise<string[]> => {\n if (namespace.length === 0) {\n return Promise.resolve([]);\n }\n\n return completeNames(provider, value, (reference) => reference.symbolNames(namespace));\n};\n\nconst resourceNotFound = (message: string): McpError => new McpError(ErrorCode.InvalidParams, message);\n\nconst symbolPage = async (\n uri: URL,\n provider: ReferenceProvider,\n namespace: string,\n symbol: string,\n): Promise<ReadResourceResult> => {\n const { reference } = await provider.get();\n const result = reference.lookup(`${namespace}.${symbol}`);\n\n if (result.outcome === \"page\") {\n return markdownResource(uri, result.markdown);\n }\n\n if (result.outcome === \"ambiguous\") {\n throw resourceNotFound(\n `\"${namespace}.${symbol}\" matches several symbols:\\n${formatCandidates(result.candidates)}`,\n );\n }\n\n throw resourceNotFound(`No symbol named \"${namespace}.${symbol}\"`);\n};\n\nconst registerIndexResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-reference\",\n \"gtkx://reference/index\",\n {\n title: \"GTKX API reference index\",\n description: \"Namespaces of the project's generated GTK4 bindings, with symbol and JSX element counts.\",\n mimeType: \"text/markdown\",\n },\n async (uri) => {\n const { reference } = await provider.get();\n\n return markdownResource(uri, reference.overview());\n },\n );\n};\n\nconst registerNamespaceResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-namespace\",\n new ResourceTemplate(\"gtkx://reference/{namespace}\", {\n list: () =>\n withLoadFallback(\n async () => {\n const { reference } = await provider.get();\n\n return {\n resources: reference.namespaces().map((summary) => ({\n uri: `gtkx://reference/${summary.name}`,\n name: `${summary.name} namespace reference`,\n mimeType: \"text/markdown\",\n })),\n };\n },\n { resources: [] },\n ),\n complete: {\n namespace: namespaceCompleter(provider),\n },\n }),\n {\n title: \"GTKX namespace reference\",\n description: \"All symbols of one namespace of the project's generated GTK4 bindings, grouped by kind.\",\n mimeType: \"text/markdown\",\n },\n async (uri, variables) => {\n const namespace = variableValue(variables.namespace);\n const { reference } = await provider.get();\n const overview = reference.namespaceOverview(namespace);\n\n if (overview === undefined) {\n throw resourceNotFound(`Unknown namespace \"${namespace}\"`);\n }\n\n return markdownResource(uri, overview);\n },\n );\n};\n\nconst registerSymbolResource = (server: ResourceServer, provider: ReferenceProvider): void => {\n server.registerResource(\n \"gtkx-api-symbol\",\n new ResourceTemplate(\"gtkx://reference/{namespace}/{symbol}\", {\n list: undefined,\n complete: {\n namespace: namespaceCompleter(provider),\n symbol: (value, context) =>\n completeSymbol(provider, variableValue(context?.arguments?.namespace), value),\n },\n }),\n {\n title: \"GTKX symbol reference\",\n description:\n \"Reference page for one symbol of the project's generated GTK4 bindings: a JSX element or a \" +\n \"class, interface, record, enum, callback, alias, function, or constant.\",\n mimeType: \"text/markdown\",\n },\n (uri, variables) =>\n symbolPage(uri, provider, variableValue(variables.namespace), variableValue(variables.symbol)),\n );\n};\n\nconst registerReferenceResources = (server: ResourceServer, provider: ReferenceProvider): void => {\n registerIndexResource(server, provider);\n registerNamespaceResource(server, provider);\n registerSymbolResource(server, provider);\n};\n\nexport {\n createReferenceProvider,\n buildReferenceTools,\n registerReferenceResources,\n type ReferenceApi,\n type ReferenceProvider,\n type ResolvedProject,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAsBjF,KAAK,sBAAsB,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAOF,QAAA,MAAM,GAAG,EAAE,MAA4B,CAAC;AA8OxC,QAAA,MAAM,eAAe,GAAI,SAAS,sBAAsB,KAAG,eA8C1D,CAAC;AAEF,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAQnC;AAED,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AA8BjF,KAAK,sBAAsB,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAeF,QAAA,MAAM,GAAG,EAAE,MAA4B,CAAC;AAgVxC,QAAA,MAAM,eAAe,GAAI,SAAS,sBAAsB,KAAG,eAsB1D,CAAC;AAEF,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAQnC;AAED,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC"}