@gtkx/mcp 2.0.0-beta.10 → 2.0.0-beta.11

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
@@ -1,177 +1,11 @@
1
- <p align="center">
2
- <img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/logo.svg" alt="GTKX" width="100" />
3
- </p>
1
+ # @gtkx/mcp
4
2
 
5
- <h1 align="center">GTKX</h1>
3
+ MCP tools for GTKX documentation and running applications.
6
4
 
7
- <p align="center">
8
- The React framework for Linux.<br />
9
- Write native GNOME applications with React and TypeScript.
10
- Real Adwaita and GTK4 widgets with standard web tooling.
11
- </p>
5
+ Connect a coding agent to generated widget references and the live application tree. Tools inspect widgets, perform interactions, and capture screenshots. Follow the guide to configure the server and attach a development session.
12
6
 
13
- <p align="center">
14
- <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/v/create-gtkx?color=cb3837&logo=npm&label=create-gtkx" alt="npm version" /></a>
15
- <a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/dm/create-gtkx?color=cb3837&logo=npm&label=downloads" alt="npm downloads" /></a>
16
- <img src="https://img.shields.io/badge/node-%E2%89%A526.7-339933?logo=node.js&logoColor=white" alt="Node >= 26.7" />
17
- <a href="https://github.com/gtkx-org/gtkx/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue.svg" alt="License: MPL-2.0" /></a>
18
- <a href="https://github.com/gtkx-org/gtkx/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/gtkx-org/gtkx/ci.yml?branch=main&logo=github&label=CI" alt="CI status" /></a>
19
- <img src="https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white" alt="TypeScript" />
20
- </p>
7
+ [Guide](https://gtkx.dev/v2/guide/mcp) · [GTKX](https://gtkx.dev)
21
8
 
22
- <p align="center">
23
- <a href="https://gtkx.dev">Homepage</a> &middot;
24
- <a href="https://gtkx.dev/guide/getting-started">Documentation</a> &middot;
25
- <a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> &middot;
26
- <a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
27
- </p>
9
+ GTKX runs on Linux with Node.js and system native libraries. See [Getting Started](https://gtkx.dev/v2/guide/getting-started) for supported versions and installation. This README describes the 2.0 beta.
28
10
 
29
- ---
30
-
31
- <p align="center">
32
- <img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/examples/tutorial/assets/screenshot.png" alt="The Tasks app: an Adwaita window with a sidebar of smart views and colored lists on the left, and a boxed task list on the right." />
33
- </p>
34
-
35
- <p align="center">
36
- <em>The Tasks app you build in the <a href="https://gtkx.dev/tutorial/">tutorial</a>.</em>
37
- </p>
38
-
39
- ## Demo
40
-
41
- This app starts with an Adwaita application shell, renders native GTK4 widgets inside it, and uses ordinary React hooks and events:
42
-
43
- ```tsx
44
- import * as Gtk from "@gtkx/gi/gtk";
45
- import { AdwApplication, AdwApplicationWindow, AdwHeaderBar, AdwToolbarView } from "@gtkx/jsx/adw";
46
- import { GtkBox, GtkButton, GtkLabel } from "@gtkx/jsx/gtk";
47
- import { createRoot, quit } from "@gtkx/react";
48
- import { useState } from "react";
49
-
50
- const Counter = () => {
51
- const [count, setCount] = useState(0);
52
-
53
- return (
54
- <AdwApplicationWindow
55
- title="Hello GTKX"
56
- defaultWidth={400}
57
- defaultHeight={300}
58
- onCloseRequest={quit}
59
- >
60
- <AdwToolbarView topBar={<AdwHeaderBar />}>
61
- <GtkBox
62
- orientation={Gtk.Orientation.VERTICAL}
63
- spacing={20}
64
- marginTop={40}
65
- marginBottom={40}
66
- marginStart={40}
67
- marginEnd={40}
68
- valign={Gtk.Align.CENTER}
69
- halign={Gtk.Align.CENTER}
70
- >
71
- <GtkLabel cssClasses={["title-1"]}>Welcome to GTKX!</GtkLabel>
72
- <GtkLabel cssClasses={["title-2"]}>{`Count: ${String(count)}`}</GtkLabel>
73
- <GtkButton
74
- label="Increment"
75
- onClicked={() => setCount((c) => c + 1)}
76
- cssClasses={["suggested-action", "pill"]}
77
- />
78
- </GtkBox>
79
- </AdwToolbarView>
80
- </AdwApplicationWindow>
81
- );
82
- };
83
-
84
- const App = () => (
85
- <AdwApplication>
86
- <Counter />
87
- </AdwApplication>
88
- );
89
-
90
- createRoot().render(<App />);
91
- ```
92
-
93
- This is the [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world) example, with `app.tsx` and `index.tsx` combined into a single snippet. `@gtkx/gi` and `@gtkx/jsx` are per-project bindings generated by the CLI, not packages you install from npm.
94
-
95
- ## Why GTKX
96
-
97
- ### Adwaita-first application development
98
-
99
- GTKX uses Adwaita as the foundation for applications, windows, navigation, dialogs, and adaptive layouts, with the complete GTK4 toolkit underneath. It adds a declarative React layer and an integrated TypeScript toolchain to the GNOME platform:
100
-
101
- - a React reconciler that exposes every GObject as a JSX element,
102
- - a CLI for scaffolding, development, and production builds,
103
- - a dev server with Fast Refresh that patches your running UI in place,
104
- - CSS-in-JS styling, React Hook Form-powered Adwaita controls, gettext-backed react-i18next localization, React Spring animations, React Navigation stack, tab, drawer, and split view navigators, and high-level list, grid, and dialog components,
105
- - a Testing Library-style API for querying and driving your widgets in tests,
106
- - and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
107
-
108
- ### Native GNOME widgets, without a compatibility layer
109
-
110
- React Native and similar frameworks hide the native toolkit so one API can run everywhere. GTKX renders real Adwaita and GTK4 widgets and exposes any other GObject-Introspection library on your system. It is GNOME-native and Linux-only by design.
111
-
112
- ### Why Node.js, and why generated bindings
113
-
114
- GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [Why GTKX guide](https://gtkx.dev/guide/why-gtkx) covers what running on Node.js means day to day.
115
-
116
- GTKX generates the TypeScript types and native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. `Adw-1` is the sole default GIR root; its GIR include pulls in `Gtk-4.0`, so codegen covers both complete API surfaces. Neither belongs in a GTKX 2 `libraries` list.
117
-
118
- At runtime, the native Rust core calls straight into the system Adwaita, GTK4, and GLib libraries through libffi, without loading libgirepository at all.
119
-
120
- ## Quick start
121
-
122
- GTKX is Linux-only and needs Node.js 26.7 or later. See [Requirements](#requirements).
123
-
124
- Scaffold a new app with the `create-gtkx` initializer:
125
-
126
- ```sh
127
- npm create gtkx@beta
128
- ```
129
-
130
- The same command works with other package managers: `pnpm create gtkx@beta` or `yarn create gtkx@beta`.
131
-
132
- Then run your new app:
133
-
134
- ```sh
135
- cd my-app
136
- npm run dev
137
- ```
138
-
139
- To go further, follow the [tutorial](https://gtkx.dev/tutorial/).
140
-
141
- ## Documentation
142
-
143
- The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tutorial that builds a complete GNOME app, from scaffolding to packaging and shipping, plus guides and a full API reference.
144
-
145
- **[Read the docs &rarr;](https://gtkx.dev/guide/why-gtkx)**
146
-
147
- ## Requirements
148
-
149
- GTKX is Linux-only. You need:
150
-
151
- - Linux with the Adwaita (1.8 or later), GTK4 (4.20 or later), and GLib development libraries
152
- - Node.js 26.7 or later
153
-
154
- The `@gtkx/native` addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
155
-
156
- ## Examples
157
-
158
- Explore the [example apps](https://github.com/gtkx-org/gtkx/tree/main/examples):
159
-
160
- - [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world): the Adwaita counter above.
161
- - [`gtk-demo`](https://github.com/gtkx-org/gtkx/tree/main/examples/gtk-demo): the official GTK4 widget showcase in an Adwaita application shell, covering lists, dialogs, gestures, CSS, and OpenGL.
162
- - [`browser`](https://github.com/gtkx-org/gtkx/tree/main/examples/browser): an Adwaita browser built around `WebKitWebView`.
163
- - [`animations`](https://github.com/gtkx-org/gtkx/tree/main/examples/animations): an Adwaita showcase for `@gtkx/animated`, with React Spring animations driven by the GTK frame clock.
164
- - [`navigation`](https://github.com/gtkx-org/gtkx/tree/main/examples/navigation): a tour of `@gtkx/navigation`, React Navigation's stack, tab, and drawer navigators rendered with libadwaita.
165
- - [`tutorial`](https://github.com/gtkx-org/gtkx/tree/main/examples/tutorial): the Tasks app the documentation builds.
166
-
167
- ## Status
168
-
169
- GTKX is stable and ready for production use.
170
-
171
- ## Contributing
172
-
173
- Contributions are welcome. See [CONTRIBUTING.md](https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md), the [Code of Conduct](https://github.com/gtkx-org/gtkx/blob/main/CODE_OF_CONDUCT.md), and the [security policy](https://github.com/gtkx-org/gtkx/blob/main/SECURITY.md). Building the repo needs Node.js 26.7 or later, pnpm, and a Rust toolchain.
174
-
175
- ## License
176
-
177
- GTKX is licensed under [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
11
+ [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
@@ -7,16 +7,12 @@ type RegisteredApp = {
7
7
  connection: ProtocolConnection;
8
8
  };
9
9
  declare class AppRouter extends EventTarget {
10
- private static defaultWaitTimeout;
11
10
  private apps;
12
11
  private connectionToApp;
13
- private requestTimeout;
14
12
  private connections;
15
13
  private pendingAppWaits;
16
14
  private isDisposed;
17
- constructor(connections: AppConnections, options?: {
18
- requestTimeout?: number;
19
- });
15
+ constructor(connections: AppConnections);
20
16
  private resolveTargetApp;
21
17
  private handleRequest;
22
18
  private handleRegister;
@@ -1 +1 @@
1
- {"version":3,"file":"app-router.d.ts","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAazG,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,uBAAuB,CAAC;AAE3E,KAAK,kBAAkB,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAC/C,KAAK,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAGhD,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAoBF,cAAM,SAAU,SAAQ,WAAW;IAC/B,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAE3C,OAAO,CAAC,IAAI,CAAyC;IAErD,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,WAAW,CAAiB;IAEpC,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,UAAU,CAAS;gBAEf,WAAW,EAAE,cAAc,EAAE,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO;IAWlF,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;YAgBH,mBAAmB;IAkCjC,OAAO,IAAI,OAAO,EAAE;IAIpB,gBAAgB,IAAI,OAAO;IAI3B,aAAa,IAAI,aAAa,GAAG,SAAS;IAM1C,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,OAAO,IAAI,IAAI;IAaf,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAAqC,GAAG,OAAO,CAAC,OAAO,CAAC;IAc9F,SAAS,CAAC,CAAC,EACb,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,CAAC,CAAC;CAchB;AAED,OAAO,EAAE,SAAS,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"app-router.d.ts","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAmB,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAazG,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,uBAAuB,CAAC;AAE3E,KAAK,kBAAkB,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAC/C,KAAK,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAGhD,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAqBF,cAAM,SAAU,SAAQ,WAAW;IAC/B,OAAO,CAAC,IAAI,CAAyC;IAErD,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,WAAW,CAAiB;IAEpC,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,UAAU,CAAS;gBAEf,WAAW,EAAE,cAAc;IAUvC,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;YAgBH,mBAAmB;IAkCjC,OAAO,IAAI,OAAO,EAAE;IAIpB,gBAAgB,IAAI,OAAO;IAI3B,aAAa,IAAI,aAAa,GAAG,SAAS;IAM1C,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,OAAO,IAAI,IAAI;IAaf,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAA+B,GAAG,OAAO,CAAC,OAAO,CAAC;IAcxF,SAAS,CAAC,CAAC,EACb,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,CAAC,CAAC;CAchB;AAED,OAAO,EAAE,SAAS,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,CAAC"}
@@ -2,6 +2,7 @@ import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { appNotFoundError, CONNECTION_CLOSED_CODE, connectionWriteFailedError, invalidRequestError, methodNotFoundError, noAppConnectedError, protocolErrorFrom, REQUEST_TIMEOUT_CODE, requestTimeoutError, } from "./protocol/errors.js";
3
3
  import { RegisterParamsSchema } from "./protocol/schemas.js";
4
4
  const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
5
+ const DEFAULT_APP_TIMEOUT_MS = 10_000;
5
6
  const routerStoppedError = () => new Error("GTKX MCP server stopped while waiting for an application");
6
7
  const appWaitTimeoutError = (timeout) => new Error(`Timeout waiting for app registration after ${String(timeout)}ms. ` +
7
8
  "Make sure your GTKX app is running with 'gtkx dev'.");
@@ -12,17 +13,14 @@ function appUnregisteredEvent(applicationId) {
12
13
  return new CustomEvent("appUnregistered", { detail: applicationId });
13
14
  }
14
15
  class AppRouter extends EventTarget {
15
- static defaultWaitTimeout = 10_000;
16
16
  apps = new Map();
17
17
  connectionToApp = new Map();
18
- requestTimeout;
19
18
  connections;
20
19
  pendingAppWaits = new Set();
21
20
  isDisposed = false;
22
- constructor(connections, options = {}) {
21
+ constructor(connections) {
23
22
  super();
24
23
  this.connections = connections;
25
- this.requestTimeout = options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
26
24
  this.connections.onRequest = (connection, request) => this.handleRequest(connection, request);
27
25
  this.connections.addEventListener("disconnection", (event) => {
28
26
  this.removeApp(event.detail);
@@ -57,14 +55,10 @@ class AppRouter extends EventTarget {
57
55
  throw invalidRequestError(parseResult.error.message);
58
56
  }
59
57
  const params = parseResult.data;
60
- const appInfo = {
61
- applicationId: params.applicationId,
62
- pid: params.pid,
63
- ...(params.projectRoot !== undefined && { projectRoot: params.projectRoot }),
64
- };
65
- this.apps.set(params.applicationId, { info: appInfo, connection });
58
+ this.removeApp(connection);
59
+ this.apps.set(params.applicationId, { info: params, connection });
66
60
  this.connectionToApp.set(connection.id, params.applicationId);
67
- this.dispatchEvent(appRegisteredEvent(appInfo));
61
+ this.dispatchEvent(appRegisteredEvent(params));
68
62
  return { success: true };
69
63
  }
70
64
  toAppError(app, error) {
@@ -73,7 +67,7 @@ class AppRouter extends EventTarget {
73
67
  return connectionWriteFailedError(app.info.applicationId);
74
68
  }
75
69
  if (error.code === REQUEST_TIMEOUT_CODE) {
76
- return requestTimeoutError(this.requestTimeout);
70
+ return requestTimeoutError(DEFAULT_REQUEST_TIMEOUT_MS);
77
71
  }
78
72
  return protocolErrorFrom(error);
79
73
  }
@@ -139,7 +133,7 @@ class AppRouter extends EventTarget {
139
133
  pendingWait.reject(error);
140
134
  }
141
135
  }
142
- waitForApp(applicationId, timeout = AppRouter.defaultWaitTimeout) {
136
+ waitForApp(applicationId, timeout = DEFAULT_APP_TIMEOUT_MS) {
143
137
  if (this.isDisposed) {
144
138
  return Promise.reject(routerStoppedError());
145
139
  }
@@ -153,7 +147,7 @@ class AppRouter extends EventTarget {
153
147
  await this.waitForApp(applicationId, waitTimeout);
154
148
  const app = this.resolveTargetApp(applicationId);
155
149
  try {
156
- return await app.connection.send(method, params, this.requestTimeout);
150
+ return await app.connection.send(method, params, DEFAULT_REQUEST_TIMEOUT_MS);
157
151
  }
158
152
  catch (error) {
159
153
  if (error instanceof McpError) {
@@ -1 +1 @@
1
- {"version":3,"file":"app-router.js","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { type JSONRPCRequest, McpError, type Result } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AppConnections, ConnectionEvent, ProtocolConnection, RequestParams } from \"./transport.js\";\nimport {\n appNotFoundError,\n CONNECTION_CLOSED_CODE,\n connectionWriteFailedError,\n invalidRequestError,\n methodNotFoundError,\n noAppConnectedError,\n type ProtocolError,\n protocolErrorFrom,\n REQUEST_TIMEOUT_CODE,\n requestTimeoutError,\n} from \"./protocol/errors.js\";\nimport { type AppInfo, RegisterParamsSchema } from \"./protocol/schemas.js\";\n\ntype AppRegisteredEvent = CustomEvent<AppInfo>;\ntype AppUnregisteredEvent = CustomEvent<string>;\ntype PendingAppWait = { reject: (error: Error) => void };\n\ntype RegisteredApp = {\n info: AppInfo;\n connection: ProtocolConnection;\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n\nconst routerStoppedError = (): Error => new Error(\"GTKX MCP server stopped while waiting for an application\");\n\nconst appWaitTimeoutError = (timeout: number): Error =>\n new Error(\n `Timeout waiting for app registration after ${String(timeout)}ms. ` +\n \"Make sure your GTKX app is running with 'gtkx dev'.\",\n );\n\nfunction appRegisteredEvent(info: AppInfo): AppRegisteredEvent {\n return new CustomEvent(\"appRegistered\", { detail: info });\n}\n\nfunction appUnregisteredEvent(applicationId: string): AppUnregisteredEvent {\n return new CustomEvent(\"appUnregistered\", { detail: applicationId });\n}\n\nclass AppRouter extends EventTarget {\n private static defaultWaitTimeout = 10_000;\n\n private apps: Map<string, RegisteredApp> = new Map();\n\n private connectionToApp: Map<string, string> = new Map();\n\n private requestTimeout: number;\n\n private connections: AppConnections;\n\n private pendingAppWaits: Set<PendingAppWait> = new Set();\n\n private isDisposed = false;\n\n constructor(connections: AppConnections, options: { requestTimeout?: number } = {}) {\n super();\n this.connections = connections;\n this.requestTimeout = options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.connections.onRequest = (connection, request) => this.handleRequest(connection, request);\n\n this.connections.addEventListener(\"disconnection\", (event) => {\n this.removeApp((event as ConnectionEvent).detail);\n });\n }\n\n private resolveTargetApp(applicationId: string | undefined): RegisteredApp {\n const app = applicationId ? this.apps.get(applicationId) : this.getDefaultApp();\n\n if (app) {\n return app;\n }\n\n if (applicationId) {\n throw appNotFoundError(applicationId);\n }\n\n throw noAppConnectedError();\n }\n\n private handleRequest(connection: ProtocolConnection, request: JSONRPCRequest): Promise<Result> {\n if (this.isDisposed) {\n return Promise.reject(routerStoppedError());\n }\n\n if (request.method === \"app.register\") {\n return Promise.resolve(this.handleRegister(connection, request));\n }\n\n if (request.method === \"app.unregister\") {\n this.removeApp(connection);\n\n return Promise.resolve({ success: true });\n }\n\n return Promise.reject(methodNotFoundError(request.method));\n }\n\n private handleRegister(connection: ProtocolConnection, request: JSONRPCRequest): Result {\n const parseResult = RegisterParamsSchema.safeParse(request.params);\n\n if (!parseResult.success) {\n throw invalidRequestError(parseResult.error.message);\n }\n\n const params = parseResult.data;\n\n const appInfo: AppInfo = {\n applicationId: params.applicationId,\n pid: params.pid,\n ...(params.projectRoot !== undefined && { projectRoot: params.projectRoot }),\n };\n\n this.apps.set(params.applicationId, { info: appInfo, connection });\n this.connectionToApp.set(connection.id, params.applicationId);\n this.dispatchEvent(appRegisteredEvent(appInfo));\n\n return { success: true };\n }\n\n private toAppError(app: RegisteredApp, error: McpError): ProtocolError {\n if (error.code === CONNECTION_CLOSED_CODE) {\n this.removeApp(app.connection);\n\n return connectionWriteFailedError(app.info.applicationId);\n }\n\n if (error.code === REQUEST_TIMEOUT_CODE) {\n return requestTimeoutError(this.requestTimeout);\n }\n\n return protocolErrorFrom(error);\n }\n\n private removeApp(connection: ProtocolConnection): void {\n const applicationId = this.connectionToApp.get(connection.id);\n this.connectionToApp.delete(connection.id);\n\n if (applicationId === undefined) {\n return;\n }\n\n if (this.apps.get(applicationId)?.connection !== connection) {\n return;\n }\n\n this.apps.delete(applicationId);\n this.dispatchEvent(appUnregisteredEvent(applicationId));\n }\n\n private async waitForRegistration(applicationId: string | undefined, timeout: number): Promise<AppInfo> {\n const controller = new AbortController();\n const { promise, reject, resolve } = Promise.withResolvers<AppInfo>();\n const rejectWait = (error: Error): void => {\n controller.abort();\n reject(error);\n };\n const pendingWait: PendingAppWait = { reject: rejectWait };\n const timeoutId = setTimeout(() => {\n rejectWait(appWaitTimeoutError(timeout));\n }, timeout);\n\n this.addEventListener(\n \"appRegistered\",\n (event) => {\n const info = (event as AppRegisteredEvent).detail;\n\n if (applicationId === undefined || info.applicationId === applicationId) {\n resolve(info);\n }\n },\n { signal: controller.signal },\n );\n this.pendingAppWaits.add(pendingWait);\n\n try {\n return await promise;\n } finally {\n clearTimeout(timeoutId);\n controller.abort();\n this.pendingAppWaits.delete(pendingWait);\n }\n }\n\n getApps(): AppInfo[] {\n return this.apps.values().map((app) => app.info).toArray();\n }\n\n hasConnectedApps(): boolean {\n return this.apps.size > 0;\n }\n\n getDefaultApp(): RegisteredApp | undefined {\n const first = this.apps.values().next();\n\n return first.done ? undefined : first.value;\n }\n\n getProjectRoot(): string | undefined {\n return this.getDefaultApp()?.info.projectRoot;\n }\n\n dispose(): void {\n if (this.isDisposed) {\n return;\n }\n\n this.isDisposed = true;\n const error = routerStoppedError();\n\n for (const pendingWait of this.pendingAppWaits) {\n pendingWait.reject(error);\n }\n }\n\n waitForApp(applicationId?: string, timeout: number = AppRouter.defaultWaitTimeout): Promise<AppInfo> {\n if (this.isDisposed) {\n return Promise.reject(routerStoppedError());\n }\n\n const app = applicationId === undefined ? this.getDefaultApp() : this.apps.get(applicationId);\n\n if (app) {\n return Promise.resolve(app.info);\n }\n\n return this.waitForRegistration(applicationId, timeout);\n }\n\n async sendToApp<T>(\n applicationId: string | undefined,\n method: string,\n params?: RequestParams,\n waitTimeout?: number,\n ): Promise<T> {\n await this.waitForApp(applicationId, waitTimeout);\n const app = this.resolveTargetApp(applicationId);\n\n try {\n return await app.connection.send<T>(method, params, this.requestTimeout);\n } catch (error) {\n if (error instanceof McpError) {\n throw this.toAppError(app, error);\n }\n\n throw error;\n }\n }\n}\n\nexport { AppRouter, type AppRegisteredEvent, type AppUnregisteredEvent };\n"]}
1
+ {"version":3,"file":"app-router.js","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { type JSONRPCRequest, McpError, type Result } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AppConnections, ConnectionEvent, ProtocolConnection, RequestParams } from \"./transport.js\";\nimport {\n appNotFoundError,\n CONNECTION_CLOSED_CODE,\n connectionWriteFailedError,\n invalidRequestError,\n methodNotFoundError,\n noAppConnectedError,\n type ProtocolError,\n protocolErrorFrom,\n REQUEST_TIMEOUT_CODE,\n requestTimeoutError,\n} from \"./protocol/errors.js\";\nimport { type AppInfo, RegisterParamsSchema } from \"./protocol/schemas.js\";\n\ntype AppRegisteredEvent = CustomEvent<AppInfo>;\ntype AppUnregisteredEvent = CustomEvent<string>;\ntype PendingAppWait = { reject: (error: Error) => void };\n\ntype RegisteredApp = {\n info: AppInfo;\n connection: ProtocolConnection;\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\nconst DEFAULT_APP_TIMEOUT_MS = 10_000;\n\nconst routerStoppedError = (): Error => new Error(\"GTKX MCP server stopped while waiting for an application\");\n\nconst appWaitTimeoutError = (timeout: number): Error =>\n new Error(\n `Timeout waiting for app registration after ${String(timeout)}ms. ` +\n \"Make sure your GTKX app is running with 'gtkx dev'.\",\n );\n\nfunction appRegisteredEvent(info: AppInfo): AppRegisteredEvent {\n return new CustomEvent(\"appRegistered\", { detail: info });\n}\n\nfunction appUnregisteredEvent(applicationId: string): AppUnregisteredEvent {\n return new CustomEvent(\"appUnregistered\", { detail: applicationId });\n}\n\nclass AppRouter extends EventTarget {\n private apps: Map<string, RegisteredApp> = new Map();\n\n private connectionToApp: Map<string, string> = new Map();\n\n private connections: AppConnections;\n\n private pendingAppWaits: Set<PendingAppWait> = new Set();\n\n private isDisposed = false;\n\n constructor(connections: AppConnections) {\n super();\n this.connections = connections;\n this.connections.onRequest = (connection, request) => this.handleRequest(connection, request);\n\n this.connections.addEventListener(\"disconnection\", (event) => {\n this.removeApp((event as ConnectionEvent).detail);\n });\n }\n\n private resolveTargetApp(applicationId: string | undefined): RegisteredApp {\n const app = applicationId ? this.apps.get(applicationId) : this.getDefaultApp();\n\n if (app) {\n return app;\n }\n\n if (applicationId) {\n throw appNotFoundError(applicationId);\n }\n\n throw noAppConnectedError();\n }\n\n private handleRequest(connection: ProtocolConnection, request: JSONRPCRequest): Promise<Result> {\n if (this.isDisposed) {\n return Promise.reject(routerStoppedError());\n }\n\n if (request.method === \"app.register\") {\n return Promise.resolve(this.handleRegister(connection, request));\n }\n\n if (request.method === \"app.unregister\") {\n this.removeApp(connection);\n\n return Promise.resolve({ success: true });\n }\n\n return Promise.reject(methodNotFoundError(request.method));\n }\n\n private handleRegister(connection: ProtocolConnection, request: JSONRPCRequest): Result {\n const parseResult = RegisterParamsSchema.safeParse(request.params);\n\n if (!parseResult.success) {\n throw invalidRequestError(parseResult.error.message);\n }\n\n const params = parseResult.data;\n this.removeApp(connection);\n this.apps.set(params.applicationId, { info: params, connection });\n this.connectionToApp.set(connection.id, params.applicationId);\n this.dispatchEvent(appRegisteredEvent(params));\n\n return { success: true };\n }\n\n private toAppError(app: RegisteredApp, error: McpError): ProtocolError {\n if (error.code === CONNECTION_CLOSED_CODE) {\n this.removeApp(app.connection);\n\n return connectionWriteFailedError(app.info.applicationId);\n }\n\n if (error.code === REQUEST_TIMEOUT_CODE) {\n return requestTimeoutError(DEFAULT_REQUEST_TIMEOUT_MS);\n }\n\n return protocolErrorFrom(error);\n }\n\n private removeApp(connection: ProtocolConnection): void {\n const applicationId = this.connectionToApp.get(connection.id);\n this.connectionToApp.delete(connection.id);\n\n if (applicationId === undefined) {\n return;\n }\n\n if (this.apps.get(applicationId)?.connection !== connection) {\n return;\n }\n\n this.apps.delete(applicationId);\n this.dispatchEvent(appUnregisteredEvent(applicationId));\n }\n\n private async waitForRegistration(applicationId: string | undefined, timeout: number): Promise<AppInfo> {\n const controller = new AbortController();\n const { promise, reject, resolve } = Promise.withResolvers<AppInfo>();\n const rejectWait = (error: Error): void => {\n controller.abort();\n reject(error);\n };\n const pendingWait: PendingAppWait = { reject: rejectWait };\n const timeoutId = setTimeout(() => {\n rejectWait(appWaitTimeoutError(timeout));\n }, timeout);\n\n this.addEventListener(\n \"appRegistered\",\n (event) => {\n const info = (event as AppRegisteredEvent).detail;\n\n if (applicationId === undefined || info.applicationId === applicationId) {\n resolve(info);\n }\n },\n { signal: controller.signal },\n );\n this.pendingAppWaits.add(pendingWait);\n\n try {\n return await promise;\n } finally {\n clearTimeout(timeoutId);\n controller.abort();\n this.pendingAppWaits.delete(pendingWait);\n }\n }\n\n getApps(): AppInfo[] {\n return this.apps.values().map((app) => app.info).toArray();\n }\n\n hasConnectedApps(): boolean {\n return this.apps.size > 0;\n }\n\n getDefaultApp(): RegisteredApp | undefined {\n const first = this.apps.values().next();\n\n return first.done ? undefined : first.value;\n }\n\n getProjectRoot(): string | undefined {\n return this.getDefaultApp()?.info.projectRoot;\n }\n\n dispose(): void {\n if (this.isDisposed) {\n return;\n }\n\n this.isDisposed = true;\n const error = routerStoppedError();\n\n for (const pendingWait of this.pendingAppWaits) {\n pendingWait.reject(error);\n }\n }\n\n waitForApp(applicationId?: string, timeout: number = DEFAULT_APP_TIMEOUT_MS): Promise<AppInfo> {\n if (this.isDisposed) {\n return Promise.reject(routerStoppedError());\n }\n\n const app = applicationId === undefined ? this.getDefaultApp() : this.apps.get(applicationId);\n\n if (app) {\n return Promise.resolve(app.info);\n }\n\n return this.waitForRegistration(applicationId, timeout);\n }\n\n async sendToApp<T>(\n applicationId: string | undefined,\n method: string,\n params?: RequestParams,\n waitTimeout?: number,\n ): Promise<T> {\n await this.waitForApp(applicationId, waitTimeout);\n const app = this.resolveTargetApp(applicationId);\n\n try {\n return await app.connection.send<T>(method, params, DEFAULT_REQUEST_TIMEOUT_MS);\n } catch (error) {\n if (error instanceof McpError) {\n throw this.toAppError(app, error);\n }\n\n throw error;\n }\n }\n}\n\nexport { AppRouter, type AppRegisteredEvent, type AppUnregisteredEvent };\n"]}
@@ -1,7 +1,6 @@
1
1
  import type { Socket } from "node:net";
2
2
  import { type AppConnections, type ConnectionRequestHandler, ProtocolConnection } from "./transport.js";
3
3
  declare class ConnectionRegistry extends EventTarget implements AppConnections {
4
- private connections;
5
4
  private sockets;
6
5
  onRequest: ConnectionRequestHandler;
7
6
  register(socket: Socket): ProtocolConnection;
@@ -1 +1 @@
1
- {"version":3,"file":"connection-registry.d.ts","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EACH,KAAK,cAAc,EAGnB,KAAK,wBAAwB,EAC7B,kBAAkB,EACrB,MAAM,gBAAgB,CAAC;AAExB,cAAM,kBAAmB,SAAQ,WAAY,YAAW,cAAc;IAClE,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,OAAO,CAAkC;IAEjD,SAAS,EAAE,wBAAwB,CAAiF;IAEpH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB;IAiB5C,OAAO,IAAI,IAAI;CAKlB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"connection-registry.d.ts","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EACH,KAAK,cAAc,EAGnB,KAAK,wBAAwB,EAC7B,kBAAkB,EACrB,MAAM,gBAAgB,CAAC;AAExB,cAAM,kBAAmB,SAAQ,WAAY,YAAW,cAAc;IAClE,OAAO,CAAC,OAAO,CAAkC;IAEjD,SAAS,EAAE,wBAAwB,CAAiF;IAEpH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB;IAe5C,OAAO,IAAI,IAAI;CAKlB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,19 +1,16 @@
1
1
  import { methodNotFoundError } from "./protocol/errors.js";
2
2
  import { connectionDisconnectionEvent, connectionErrorEvent, ProtocolConnection, } from "./transport.js";
3
3
  class ConnectionRegistry extends EventTarget {
4
- connections = new Map();
5
4
  sockets = new Map();
6
5
  onRequest = (_connection, request) => Promise.reject(methodNotFoundError(request.method));
7
6
  register(socket) {
8
7
  const connection = ProtocolConnection.fromSocket(socket, {
9
8
  onClose: () => {
10
- this.connections.delete(connection.id);
11
9
  this.sockets.delete(connection.id);
12
10
  this.dispatchEvent(connectionDisconnectionEvent(connection));
13
11
  },
14
12
  onError: (error) => this.dispatchEvent(connectionErrorEvent(error)),
15
13
  });
16
- this.connections.set(connection.id, connection);
17
14
  this.sockets.set(connection.id, socket);
18
15
  connection.fallbackRequestHandler = (request) => this.onRequest(connection, request);
19
16
  return connection;
@@ -1 +1 @@
1
- {"version":3,"file":"connection-registry.js","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEH,4BAA4B,EAC5B,oBAAoB,EAEpB,kBAAkB,GACrB,MAAM,gBAAgB,CAAC;AAExB,MAAM,kBAAmB,SAAQ,WAAW;IAChC,WAAW,GAAoC,IAAI,GAAG,EAAE,CAAC;IACzD,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEjD,SAAS,GAA6B,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpH,QAAQ,CAAC,MAAc;QACnB,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;YACrD,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;SACtE,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAErF,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,OAAO;QACH,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import type { Socket } from \"node:net\";\nimport { methodNotFoundError } from \"./protocol/errors.js\";\nimport {\n type AppConnections,\n connectionDisconnectionEvent,\n connectionErrorEvent,\n type ConnectionRequestHandler,\n ProtocolConnection,\n} from \"./transport.js\";\n\nclass ConnectionRegistry extends EventTarget implements AppConnections {\n private connections: Map<string, ProtocolConnection> = new Map();\n private sockets: Map<string, Socket> = new Map();\n\n onRequest: ConnectionRequestHandler = (_connection, request) => Promise.reject(methodNotFoundError(request.method));\n\n register(socket: Socket): ProtocolConnection {\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.connections.delete(connection.id);\n this.sockets.delete(connection.id);\n this.dispatchEvent(connectionDisconnectionEvent(connection));\n },\n onError: (error) => this.dispatchEvent(connectionErrorEvent(error)),\n });\n\n this.connections.set(connection.id, connection);\n this.sockets.set(connection.id, socket);\n connection.fallbackRequestHandler = (request) => this.onRequest(connection, request);\n\n return connection;\n }\n\n dispose(): void {\n for (const socket of this.sockets.values()) {\n socket.destroy();\n }\n }\n}\n\nexport { ConnectionRegistry };\n"]}
1
+ {"version":3,"file":"connection-registry.js","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEH,4BAA4B,EAC5B,oBAAoB,EAEpB,kBAAkB,GACrB,MAAM,gBAAgB,CAAC;AAExB,MAAM,kBAAmB,SAAQ,WAAW;IAChC,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEjD,SAAS,GAA6B,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpH,QAAQ,CAAC,MAAc;QACnB,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;YACrD,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;SACtE,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAErF,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,OAAO;QACH,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import type { Socket } from \"node:net\";\nimport { methodNotFoundError } from \"./protocol/errors.js\";\nimport {\n type AppConnections,\n connectionDisconnectionEvent,\n connectionErrorEvent,\n type ConnectionRequestHandler,\n ProtocolConnection,\n} from \"./transport.js\";\n\nclass ConnectionRegistry extends EventTarget implements AppConnections {\n private sockets: Map<string, Socket> = new Map();\n\n onRequest: ConnectionRequestHandler = (_connection, request) => Promise.reject(methodNotFoundError(request.method));\n\n register(socket: Socket): ProtocolConnection {\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.sockets.delete(connection.id);\n this.dispatchEvent(connectionDisconnectionEvent(connection));\n },\n onError: (error) => this.dispatchEvent(connectionErrorEvent(error)),\n });\n\n this.sockets.set(connection.id, socket);\n connection.fallbackRequestHandler = (request) => this.onRequest(connection, request);\n\n return connection;\n }\n\n dispose(): void {\n for (const socket of this.sockets.values()) {\n socket.destroy();\n }\n }\n}\n\nexport { ConnectionRegistry };\n"]}
@@ -17,11 +17,7 @@ type SerializedProperty = {
17
17
  widgetId?: string;
18
18
  note?: string;
19
19
  };
20
- type AppInfo = {
21
- applicationId: string;
22
- pid: number;
23
- projectRoot?: string;
24
- };
20
+ type AppInfo = z.output<typeof RegisterParamsSchema>;
25
21
  type ServerRequestParams<Method extends keyof typeof ServerRequestParamsSchemas> = z.infer<(typeof ServerRequestParamsSchemas)[Method]>;
26
22
  type ParamsSchema<Output> = z.ZodType<Output>;
27
23
  type ServerInitiatedMethod = keyof typeof ServerRequestParamsSchemas;
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/protocol/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/protocol/schemas.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/protocol/schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\ntype SerializedWidget = {\n id: string;\n type: string;\n role: string;\n name: string | null;\n text: string | null;\n isSensitive: boolean;\n isVisible: boolean;\n cssClasses: string[];\n children: SerializedWidget[];\n hiddenChildren?: number;\n};\n\ntype SerializedProperty = {\n type: string;\n value: string | number | boolean | string[] | null;\n widgetId?: string;\n note?: string;\n};\n\ntype AppInfo = {\n applicationId: string;\n pid: number;\n projectRoot?: string;\n};\n\ntype ServerRequestParams<Method extends keyof typeof ServerRequestParamsSchemas> = z.infer<\n (typeof ServerRequestParamsSchemas)[Method]\n>;\n\ntype ParamsSchema<Output> = z.ZodType<Output>;\ntype ServerInitiatedMethod = keyof typeof ServerRequestParamsSchemas;\n\nconst RegisterParamsSchema: z.ZodObject<\n {\n applicationId: z.ZodString;\n pid: z.ZodNumber;\n projectRoot: z.ZodOptional<z.ZodString>;\n }\n> = z.object({\n applicationId: z.string(),\n pid: z.number(),\n projectRoot: z.string().optional(),\n});\n\nconst emptyParams: z.ZodObject<Record<string, never>> = z.object({});\n\nconst widgetIdParams: z.ZodObject<{ widgetId: z.ZodString }> = z.object({\n widgetId: z.string(),\n});\n\nconst DEFAULT_SUBTREE_DEPTH = 8;\nconst MAX_SUBTREE_WIDGETS = 30;\n\nconst widgetPropsParams: z.ZodObject<\n {\n widgetId: z.ZodString;\n properties: z.ZodOptional<z.ZodArray<z.ZodString>>;\n maxDepth: z.ZodOptional<z.ZodNumber>;\n }\n> = z.object({\n widgetId: z.string(),\n properties: z.array(z.string()).optional(),\n maxDepth: z.number().int().nonnegative().optional(),\n});\n\nconst treeParams: z.ZodObject<\n { rootId: z.ZodOptional<z.ZodString>; maxDepth: z.ZodOptional<z.ZodNumber> }\n> = z.object({\n rootId: z.string().optional(),\n maxDepth: z.number().int().nonnegative().optional(),\n});\n\nconst queryOptionsSchema: z.ZodObject<\n { name: z.ZodOptional<z.ZodString>; exact: z.ZodOptional<z.ZodBoolean>; timeout: z.ZodOptional<z.ZodNumber> }\n> = z.object({\n name: z.string().optional(),\n exact: z.boolean().optional(),\n timeout: z.number().optional(),\n});\n\nconst queryParams: z.ZodObject<\n {\n by: z.ZodEnum<{ role: \"role\"; text: \"text\"; name: \"name\"; labelText: \"labelText\" }>;\n value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;\n options: z.ZodOptional<typeof queryOptionsSchema>;\n }\n> = z.object({\n by: z.enum([\"role\", \"text\", \"name\", \"labelText\"]),\n value: z.union([z.string(), z.number()]),\n options: queryOptionsSchema.optional(),\n});\n\nconst typeParams: z.ZodObject<\n { widgetId: z.ZodString; text: z.ZodString; clear: z.ZodOptional<z.ZodBoolean> }\n> = z.object({ widgetId: z.string(), text: z.string(), clear: z.boolean().optional() });\n\nconst fireEventParams: z.ZodObject<\n { widgetId: z.ZodString; signal: z.ZodString; args: z.ZodOptional<z.ZodArray<z.ZodUnknown>> }\n> = z.object({ widgetId: z.string(), signal: z.string(), args: z.array(z.unknown()).optional() });\n\nconst screenshotParams: z.ZodObject<\n { windowId: z.ZodOptional<z.ZodString>; path: z.ZodOptional<z.ZodString> }\n> = z.object({\n windowId: z.string().optional(),\n path: z.string().optional(),\n});\n\nconst ServerRequestParamsSchemas: {\n \"app.getWindows\": typeof emptyParams;\n \"widget.getTree\": typeof treeParams;\n \"widget.query\": typeof queryParams;\n \"widget.getProps\": typeof widgetPropsParams;\n \"widget.click\": typeof widgetIdParams;\n \"widget.type\": typeof typeParams;\n \"widget.fireEvent\": typeof fireEventParams;\n \"widget.screenshot\": typeof screenshotParams;\n} = {\n \"app.getWindows\": emptyParams,\n \"widget.getTree\": treeParams,\n \"widget.query\": queryParams,\n \"widget.getProps\": widgetPropsParams,\n \"widget.click\": widgetIdParams,\n \"widget.type\": typeParams,\n \"widget.fireEvent\": fireEventParams,\n \"widget.screenshot\": screenshotParams,\n};\n\nexport {\n DEFAULT_SUBTREE_DEPTH,\n MAX_SUBTREE_WIDGETS,\n RegisterParamsSchema,\n widgetIdParams,\n widgetPropsParams,\n treeParams,\n queryParams,\n typeParams,\n fireEventParams,\n screenshotParams,\n ServerRequestParamsSchemas,\n type SerializedWidget,\n type SerializedProperty,\n type AppInfo,\n type ServerRequestParams,\n type ParamsSchema,\n type ServerInitiatedMethod,\n};\n"]}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/protocol/schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\ntype SerializedWidget = {\n id: string;\n type: string;\n role: string;\n name: string | null;\n text: string | null;\n isSensitive: boolean;\n isVisible: boolean;\n cssClasses: string[];\n children: SerializedWidget[];\n hiddenChildren?: number;\n};\n\ntype SerializedProperty = {\n type: string;\n value: string | number | boolean | string[] | null;\n widgetId?: string;\n note?: string;\n};\n\ntype AppInfo = z.output<typeof RegisterParamsSchema>;\n\ntype ServerRequestParams<Method extends keyof typeof ServerRequestParamsSchemas> = z.infer<\n (typeof ServerRequestParamsSchemas)[Method]\n>;\n\ntype ParamsSchema<Output> = z.ZodType<Output>;\ntype ServerInitiatedMethod = keyof typeof ServerRequestParamsSchemas;\n\nconst RegisterParamsSchema: z.ZodObject<\n {\n applicationId: z.ZodString;\n pid: z.ZodNumber;\n projectRoot: z.ZodOptional<z.ZodString>;\n }\n> = z.object({\n applicationId: z.string(),\n pid: z.number(),\n projectRoot: z.string().optional(),\n});\n\nconst emptyParams: z.ZodObject<Record<string, never>> = z.object({});\n\nconst widgetIdParams: z.ZodObject<{ widgetId: z.ZodString }> = z.object({\n widgetId: z.string(),\n});\n\nconst DEFAULT_SUBTREE_DEPTH = 8;\nconst MAX_SUBTREE_WIDGETS = 30;\n\nconst widgetPropsParams: z.ZodObject<\n {\n widgetId: z.ZodString;\n properties: z.ZodOptional<z.ZodArray<z.ZodString>>;\n maxDepth: z.ZodOptional<z.ZodNumber>;\n }\n> = z.object({\n widgetId: z.string(),\n properties: z.array(z.string()).optional(),\n maxDepth: z.number().int().nonnegative().optional(),\n});\n\nconst treeParams: z.ZodObject<\n { rootId: z.ZodOptional<z.ZodString>; maxDepth: z.ZodOptional<z.ZodNumber> }\n> = z.object({\n rootId: z.string().optional(),\n maxDepth: z.number().int().nonnegative().optional(),\n});\n\nconst queryOptionsSchema: z.ZodObject<\n { name: z.ZodOptional<z.ZodString>; exact: z.ZodOptional<z.ZodBoolean>; timeout: z.ZodOptional<z.ZodNumber> }\n> = z.object({\n name: z.string().optional(),\n exact: z.boolean().optional(),\n timeout: z.number().optional(),\n});\n\nconst queryParams: z.ZodObject<\n {\n by: z.ZodEnum<{ role: \"role\"; text: \"text\"; name: \"name\"; labelText: \"labelText\" }>;\n value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;\n options: z.ZodOptional<typeof queryOptionsSchema>;\n }\n> = z.object({\n by: z.enum([\"role\", \"text\", \"name\", \"labelText\"]),\n value: z.union([z.string(), z.number()]),\n options: queryOptionsSchema.optional(),\n});\n\nconst typeParams: z.ZodObject<\n { widgetId: z.ZodString; text: z.ZodString; clear: z.ZodOptional<z.ZodBoolean> }\n> = z.object({ widgetId: z.string(), text: z.string(), clear: z.boolean().optional() });\n\nconst fireEventParams: z.ZodObject<\n { widgetId: z.ZodString; signal: z.ZodString; args: z.ZodOptional<z.ZodArray<z.ZodUnknown>> }\n> = z.object({ widgetId: z.string(), signal: z.string(), args: z.array(z.unknown()).optional() });\n\nconst screenshotParams: z.ZodObject<\n { windowId: z.ZodOptional<z.ZodString>; path: z.ZodOptional<z.ZodString> }\n> = z.object({\n windowId: z.string().optional(),\n path: z.string().optional(),\n});\n\nconst ServerRequestParamsSchemas: {\n \"app.getWindows\": typeof emptyParams;\n \"widget.getTree\": typeof treeParams;\n \"widget.query\": typeof queryParams;\n \"widget.getProps\": typeof widgetPropsParams;\n \"widget.click\": typeof widgetIdParams;\n \"widget.type\": typeof typeParams;\n \"widget.fireEvent\": typeof fireEventParams;\n \"widget.screenshot\": typeof screenshotParams;\n} = {\n \"app.getWindows\": emptyParams,\n \"widget.getTree\": treeParams,\n \"widget.query\": queryParams,\n \"widget.getProps\": widgetPropsParams,\n \"widget.click\": widgetIdParams,\n \"widget.type\": typeParams,\n \"widget.fireEvent\": fireEventParams,\n \"widget.screenshot\": screenshotParams,\n};\n\nexport {\n DEFAULT_SUBTREE_DEPTH,\n MAX_SUBTREE_WIDGETS,\n RegisterParamsSchema,\n widgetIdParams,\n widgetPropsParams,\n treeParams,\n queryParams,\n typeParams,\n fireEventParams,\n screenshotParams,\n ServerRequestParamsSchemas,\n type SerializedWidget,\n type SerializedProperty,\n type AppInfo,\n type ServerRequestParams,\n type ParamsSchema,\n type ServerInitiatedMethod,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAsE,MAAM,eAAe,CAAC;AAEtH,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAK3F,OAAO,EAAsC,KAAK,IAAI,EAAiB,MAAM,WAAW,CAAC;AAEzF,KAAK,YAAY,GAAG,IAAI,CACpB,YAAY,EACZ,QAAQ,GAAG,mBAAmB,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,CACxF,CAAC;AAEF,KAAK,aAAa,GAAG,UAAU,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAE7D,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,KAAK,eAAe,GAAG,eAAe,GAAG;IACrC,SAAS,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC5B,UAAU,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,MAAM,CAAC;CACtC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACrB,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACzD,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;CAClD,CAAC;AAsBF,KAAK,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAkM1D,QAAA,MAAM,uBAAuB,GAAI,SAAS,wBAAwB,KAAG,iBAgBpE,CAAC;AA2HF,QAAA,MAAM,mBAAmB,GAAI,UAAU,iBAAiB,KAAG,IAAI,EAI9D,CAAC;AAmJF,QAAA,MAAM,0BAA0B,GAAI,QAAQ,cAAc,EAAE,UAAU,iBAAiB,KAAG,IAIzF,CAAC;AAEF,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,0BAA0B,EAC1B,KAAK,iBAAiB,GACzB,CAAC"}
1
+ {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,YAAY,EAMpB,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAK3F,OAAO,EAAsC,KAAK,IAAI,EAAiB,MAAM,WAAW,CAAC;AAEzF,KAAK,YAAY,GAAG,IAAI,CACpB,YAAY,EACZ,QAAQ,GAAG,mBAAmB,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,CACxF,CAAC;AAEF,KAAK,aAAa,GAAG,UAAU,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAE7D,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,KAAK,eAAe,GAAG,eAAe,GAAG;IACrC,SAAS,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC5B,UAAU,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,MAAM,CAAC;CACtC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACrB,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACzD,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;CAClD,CAAC;AAsBF,KAAK,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AA+M1D,QAAA,MAAM,uBAAuB,GAAI,SAAS,wBAAwB,KAAG,iBAgBpE,CAAC;AA2HF,QAAA,MAAM,mBAAmB,GAAI,UAAU,iBAAiB,KAAG,IAAI,EAI9D,CAAC;AAmJF,QAAA,MAAM,0BAA0B,GAAI,QAAQ,cAAc,EAAE,UAAU,iBAAiB,KAAG,IAIzF,CAAC;AAEF,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,0BAA0B,EAC1B,KAAK,iBAAiB,GACzB,CAAC"}
package/dist/reference.js CHANGED
@@ -1,5 +1,7 @@
1
- import { loadApiReference, resolveGirPath, resolveLibraries } from "@gtkx/codegen";
1
+ import { loadApiReference, mergeOmittedProps, resolveGirPath, resolveLibraries, } from "@gtkx/codegen";
2
+ import { readBuiltinElementsForDocs } from "@gtkx/codegen/internal";
2
3
  import { loadConfig } from "@gtkx/config";
4
+ import { CONFIG_EXTENSIONS, configDependenciesFor, resolveAcceptedChildTypes, resolveElementProps, resolveOmittedProps, } from "@gtkx/config/internal";
3
5
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
4
6
  import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
5
7
  import { existsSync, statSync } from "node:fs";
@@ -8,7 +10,7 @@ import { z } from "zod";
8
10
  import { defineTool, textContent, textError } from "./tool.js";
9
11
  const FRESHNESS_INTERVAL_MS = 2000;
10
12
  const FAILURE_RETRY_MS = 5000;
11
- const CONFIG_EXTENSIONS = ["ts", "mts", "js", "mjs", "json"];
13
+ const CONFIG_LOCATIONS = ["gtkx.config", ".config/gtkx", ".config/gtkx.config"];
12
14
  const PROJECT_SOURCE_LABELS = {
13
15
  argument: "requested with `projectRoot`",
14
16
  workingDirectory: "found from the working directory",
@@ -64,8 +66,9 @@ const watchFile = (path) => {
64
66
  const isFresh = (loaded) => loaded.watched.every((file) => {
65
67
  const current = watchFile(file.path);
66
68
  return current.mtimeMs === file.mtimeMs && current.size === file.size;
67
- });
68
- const hasConfigFile = (directory) => CONFIG_EXTENSIONS.some((extension) => existsSync(join(directory, `gtkx.config.${extension}`)));
69
+ }) && loaded.reference.hasFreshInputs();
70
+ const configCandidatePaths = (directory) => CONFIG_LOCATIONS.flatMap((location) => CONFIG_EXTENSIONS.map((extension) => join(directory, `${location}${extension}`)));
71
+ const hasConfigFile = (directory) => configCandidatePaths(directory).some((path) => existsSync(path));
69
72
  const findProjectRoot = (start) => {
70
73
  const current = resolve(start);
71
74
  const parent = dirname(current);
@@ -92,24 +95,34 @@ const resolveProject = (workingDirectory, getAppRoot, projectRoot) => {
92
95
  : projectAt(appRoot, "app");
93
96
  };
94
97
  const loadReference = async (requestedRoot) => {
95
- const { config, configFile, root } = await loadConfig(requestedRoot);
98
+ const loaded = await loadConfig(requestedRoot);
99
+ const { config, root } = loaded;
96
100
  if (config.codegen === false) {
97
101
  throw new Error(`codegen is disabled for the project at ${root}, so there are no generated bindings to document. ` +
98
102
  "Remove `codegen: false` from gtkx.config.ts to use the API reference, or point the `projectRoot` " +
99
103
  "argument at another project.");
100
104
  }
101
- const girPath = resolveGirPath(config.girPath);
105
+ const girPath = resolveGirPath(config.girPath, root);
102
106
  if (girPath.length === 0) {
103
107
  throw new Error("No GIR search paths available. Install gobject-introspection " +
104
108
  "(Linux: `sudo dnf install gobject-introspection-devel` or `sudo apt install libgirepository1.0-dev`), " +
105
109
  "or set `girPath` in gtkx.config.ts.");
106
110
  }
107
111
  const libraries = resolveLibraries(config.libraries);
112
+ const builtin = await readBuiltinElementsForDocs();
108
113
  const reference = loadApiReference({
109
114
  libraries,
110
115
  girPath,
116
+ resolveFrom: root,
117
+ props: { ...builtin.props, ...resolveElementProps(config.elements) },
118
+ omittedProps: mergeOmittedProps(builtin.omittedProps, resolveOmittedProps(config.elements)),
119
+ acceptedChildTypes: { ...builtin.acceptedChildTypes, ...resolveAcceptedChildTypes(config.elements) },
111
120
  });
112
- const watched = [watchFile(resolve(root, configFile)), ...reference.girFiles.map((file) => watchFile(file))];
121
+ const watched = [...new Set([
122
+ ...configDependenciesFor(loaded),
123
+ ...configCandidatePaths(root),
124
+ ...reference.inputFiles,
125
+ ])].map((file) => watchFile(file));
113
126
  return { reference, root, watched };
114
127
  };
115
128
  const startLoad = (cache, root) => {