@gjsify/devtools-protocol 0.8.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @gjsify/devtools-protocol
2
+
3
+ The **transport-agnostic contract** for the gjsify devtools control plane — pure TypeScript, no platform imports, no side effects. It defines the method surface, the pause classification, the JSON envelope, the server/client transport interfaces, instance routing, and the well-known DBus interface name.
4
+
5
+ Every adapter and bridge imports it so they always agree:
6
+
7
+ - [`@gjsify/devtools`](../devtools) — the in-app **DBus** adapter (GTK/GJS).
8
+ - [`@gjsify/devtools-mcp`](../devtools-mcp) — the **MCP bridge** an agent talks to.
9
+ - A future `@gjsify/devtools-web` — a **WebSocket** adapter for web apps.
10
+
11
+ Because it is pure, browser web apps can import it too — the same envelope maps 1:1 onto WebSocket-JSON-RPC.
12
+
13
+ ## The contract
14
+
15
+ The surface is **commands + state + introspection**, not "GActions" — so it is toolkit-neutral.
16
+
17
+ ```ts
18
+ import { DEVTOOLS_INTERFACE, GENERIC_METHODS, type MethodKind } from '@gjsify/devtools-protocol';
19
+
20
+ DEVTOOLS_INTERFACE; // 'org.gjsify.Devtools' — constant across apps; each app uses its own bus name + path
21
+ ```
22
+
23
+ ### Generic methods and the pause policy
24
+
25
+ Each method carries a **kind** that the pause guard enforces. When a host pauses external control, `mutating` methods are rejected; `read-only` and `presence` always pass.
26
+
27
+ | Kind | Meaning | While paused |
28
+ |---|---|---|
29
+ | `read-only` | Observation / diagnostics (`GetStatus`, `Screenshot`, `DumpTree`, …) | allowed |
30
+ | `presence` | An external driver's own awareness channel (cursor / label) | allowed |
31
+ | `mutating` | Edits app state or the user's UI (`ActivateAction`, `SetProperty`, `SwapCss`, …) | rejected |
32
+
33
+ `GENERIC_METHODS` is the toolkit-neutral baseline (core control + full introspection). Adapters implement the subset they support; the bridge advertises only the implemented ones. App-specific methods are added via extensions with their own kinds — **the registry rejects an unclassified method name**, so a new method cannot silently bypass the pause policy.
34
+
35
+ ## Exports
36
+
37
+ - `DEVTOOLS_INTERFACE` — the well-known interface name.
38
+ - `GENERIC_METHODS`, `MethodKind`, `GenericMethodName` — the method surface + classification.
39
+ - `DevtoolsServerTransport` / `DevtoolsClientTransport` — the app-side (`serve(handler)` / `close()`) and bridge-side (`connect()` / `request(req)` / `close()`) transport seams, plus the `DevtoolsHandler` type.
40
+ - envelope + error types, the method registry, instance-routing helpers, and shared introspection types.
41
+
42
+ ## Build / test
43
+
44
+ ```bash
45
+ gjsify workspace @gjsify/devtools-protocol build
46
+ gjsify workspace @gjsify/devtools-protocol test
47
+ ```
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{resolveBusAddress as e,sanitizeInstanceId as t}from"./routing.js";import{DevtoolsError as n,formatDbusErrorMessage as r,parseDbusErrorMessage as i,toErrorPayload as a}from"./errors.js";import{DEVTOOLS_INTERFACE as o}from"./constants.js";import{GENERIC_METHODS as s}from"./methods.js";import{errResponse as c,okResponse as l}from"./envelope.js";import"./transport.js";import{MethodRegistry as u}from"./registry.js";import"./types.js";export{o as DEVTOOLS_INTERFACE,n as DevtoolsError,s as GENERIC_METHODS,u as MethodRegistry,c as errResponse,r as formatDbusErrorMessage,l as okResponse,i as parseDbusErrorMessage,e as resolveBusAddress,t as sanitizeInstanceId,a as toErrorPayload};
1
+ import{DEVTOOLS_INTERFACE as e}from"./constants.js";import{errResponse as t,okResponse as n}from"./envelope.js";import{DevtoolsError as r,formatDbusErrorMessage as i,parseDbusErrorMessage as a,toErrorPayload as o}from"./errors.js";import{GENERIC_METHODS as s}from"./methods.js";import"./transport.js";import{MethodRegistry as c}from"./registry.js";import{resolveBusAddress as l,sanitizeInstanceId as u}from"./routing.js";import"./types.js";export{e as DEVTOOLS_INTERFACE,r as DevtoolsError,s as GENERIC_METHODS,c as MethodRegistry,t as errResponse,i as formatDbusErrorMessage,n as okResponse,a as parseDbusErrorMessage,l as resolveBusAddress,u as sanitizeInstanceId,o as toErrorPayload};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{toErrorPayload as e}from"./errors.js";import{errResponse as t,okResponse as n}from"./envelope.js";var MethodRegistry=class{constructor(){this._methods=new Map}register(e){if(this._methods.has(e.name))throw Error(`Devtools method '${e.name}' is already registered`);this._methods.set(e.name,e)}has(e){return this._methods.has(e)}list(){return[...this._methods.values()].map(({name:e,kind:t})=>({name:e,kind:t}))}async dispatch(r,i={}){let a=this._methods.get(r.method);if(!a)return t({code:`not-found`,message:`unknown devtools method '${r.method}'`},r.id);if(i.paused&&a.kind===`mutating`)return t({code:`paused`,message:`${r.method} rejected — external control is paused. Read-only methods keep working.`},r.id);try{return n(await a.handler(r.params??{}),r.id)}catch(n){return t(e(n),r.id)}}};export{MethodRegistry};
1
+ import"./_virtual/_rolldown/runtime.js";import{errResponse as e,okResponse as t}from"./envelope.js";import{toErrorPayload as n}from"./errors.js";var MethodRegistry=class{constructor(){this._methods=new Map}register(e){if(this._methods.has(e.name))throw Error(`Devtools method '${e.name}' is already registered`);this._methods.set(e.name,e)}has(e){return this._methods.has(e)}list(){return[...this._methods.values()].map(({name:e,kind:t})=>({name:e,kind:t}))}async dispatch(r,i={}){let a=this._methods.get(r.method);if(!a)return e({code:`not-found`,message:`unknown devtools method '${r.method}'`},r.id);if(i.paused&&a.kind===`mutating`)return e({code:`paused`,message:`${r.method} rejected — external control is paused. Read-only methods keep working.`},r.id);try{return t(await a.handler(r.params??{}),r.id)}catch(t){return e(n(t),r.id)}}};export{MethodRegistry};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/devtools-protocol",
3
- "version": "0.8.0",
3
+ "version": "0.12.0",
4
4
  "description": "Transport-agnostic devtools contract (methods, JSON envelope, method-kinds, transport interface) shared by every gjsify devtools adapter and the MCP bridge",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -35,8 +35,8 @@
35
35
  ],
36
36
  "dependencies": {},
37
37
  "devDependencies": {
38
- "@gjsify/cli": "^0.8.0",
39
- "@gjsify/unit": "^0.8.0",
38
+ "@gjsify/cli": "^0.12.0",
39
+ "@gjsify/unit": "^0.12.0",
40
40
  "@types/node": "^25.9.2",
41
41
  "typescript": "^6.0.3"
42
42
  },
@@ -45,7 +45,7 @@
45
45
  "gjs": "polyfill",
46
46
  "node": "none",
47
47
  "browser": "none",
48
- "nativescript": "none"
48
+ "nativescript": "polyfill"
49
49
  }
50
50
  },
51
51
  "license": "MIT",