@ai-matrx/desktop-protocol 0.21.45 → 0.21.47
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/CHANGELOG.md +27 -1
- package/README.md +1 -1
- package/dist/client.cjs +42 -8
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +5 -5
- package/dist/client.d.ts +5 -5
- package/dist/client.js +42 -8
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +73 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1724 -1487
- package/dist/index.d.ts +1724 -1487
- package/dist/index.js +73 -9
- package/dist/index.js.map +1 -1
- package/dist/{models-BFAtNMgx.d.cts → models-Di-SL_jw.d.cts} +254 -107
- package/dist/{models-BFAtNMgx.d.ts → models-Di-SL_jw.d.ts} +254 -107
- package/dist/react.cjs +9 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +52 -5
- package/dist/react.d.ts +52 -5
- package/dist/react.js +9 -0
- package/dist/react.js.map +1 -1
- package/generated/desktop-protocol.schema.json +147 -1
- package/package.json +5 -5
package/dist/react.d.cts
CHANGED
|
@@ -1772,6 +1772,20 @@ declare const OPS: {
|
|
|
1772
1772
|
created: z.ZodBoolean;
|
|
1773
1773
|
running: z.ZodBoolean;
|
|
1774
1774
|
open_chats: z.ZodInt;
|
|
1775
|
+
remote_control: z.ZodOptional<z.ZodObject<{
|
|
1776
|
+
setting: z.ZodEnum<{
|
|
1777
|
+
default: "default";
|
|
1778
|
+
on: "on";
|
|
1779
|
+
off: "off";
|
|
1780
|
+
unreadable: "unreadable";
|
|
1781
|
+
}>;
|
|
1782
|
+
serving: z.ZodNullable<z.ZodBoolean>;
|
|
1783
|
+
pending: z.ZodNullable<z.ZodEnum<{
|
|
1784
|
+
on: "on";
|
|
1785
|
+
off: "off";
|
|
1786
|
+
}>>;
|
|
1787
|
+
problem: z.ZodOptional<z.ZodString>;
|
|
1788
|
+
}, z.core.$strict>>;
|
|
1775
1789
|
}, z.core.$strict>>;
|
|
1776
1790
|
}, z.core.$strict>;
|
|
1777
1791
|
readonly kind: "unary";
|
|
@@ -1815,6 +1829,37 @@ declare const OPS: {
|
|
|
1815
1829
|
readonly since: "1.10";
|
|
1816
1830
|
readonly errors: readonly ["NOT_FOUND", "CONFLICT", "TIMEOUT", "PLATFORM_UNSUPPORTED", "INTERNAL"];
|
|
1817
1831
|
};
|
|
1832
|
+
readonly "apps.windows.set_remote_control": {
|
|
1833
|
+
readonly params: z.ZodObject<{
|
|
1834
|
+
app_key: z.ZodString;
|
|
1835
|
+
window: z.ZodString;
|
|
1836
|
+
enabled: z.ZodBoolean;
|
|
1837
|
+
}, z.core.$strict>;
|
|
1838
|
+
readonly result: z.ZodObject<{
|
|
1839
|
+
message: z.ZodString;
|
|
1840
|
+
when: z.ZodEnum<{
|
|
1841
|
+
now: "now";
|
|
1842
|
+
next_close: "next_close";
|
|
1843
|
+
}>;
|
|
1844
|
+
remote_control: z.ZodObject<{
|
|
1845
|
+
setting: z.ZodEnum<{
|
|
1846
|
+
default: "default";
|
|
1847
|
+
on: "on";
|
|
1848
|
+
off: "off";
|
|
1849
|
+
unreadable: "unreadable";
|
|
1850
|
+
}>;
|
|
1851
|
+
serving: z.ZodNullable<z.ZodBoolean>;
|
|
1852
|
+
pending: z.ZodNullable<z.ZodEnum<{
|
|
1853
|
+
on: "on";
|
|
1854
|
+
off: "off";
|
|
1855
|
+
}>>;
|
|
1856
|
+
problem: z.ZodOptional<z.ZodString>;
|
|
1857
|
+
}, z.core.$strict>;
|
|
1858
|
+
}, z.core.$strict>;
|
|
1859
|
+
readonly kind: "unary";
|
|
1860
|
+
readonly since: "1.50";
|
|
1861
|
+
readonly errors: readonly ["NOT_FOUND", "CONFLICT", "PLATFORM_UNSUPPORTED", "INTERNAL"];
|
|
1862
|
+
};
|
|
1818
1863
|
readonly "apps.windows.refresh_usage": {
|
|
1819
1864
|
readonly params: z.ZodObject<{
|
|
1820
1865
|
app_key: z.ZodString;
|
|
@@ -1885,6 +1930,7 @@ declare const OPS: {
|
|
|
1885
1930
|
readonly "apps.instances.list": {
|
|
1886
1931
|
readonly params: z.ZodObject<{
|
|
1887
1932
|
app_key: z.ZodString;
|
|
1933
|
+
fresh: z.ZodOptional<z.ZodBoolean>;
|
|
1888
1934
|
}, z.core.$strict>;
|
|
1889
1935
|
readonly result: z.ZodObject<{
|
|
1890
1936
|
app_key: z.ZodString;
|
|
@@ -1918,6 +1964,8 @@ declare const OPS: {
|
|
|
1918
1964
|
first_launch_ms: z.ZodNullable<z.ZodInt>;
|
|
1919
1965
|
}, z.core.$strict>>;
|
|
1920
1966
|
problem: z.ZodOptional<z.ZodString>;
|
|
1967
|
+
as_of_ms: z.ZodOptional<z.ZodInt>;
|
|
1968
|
+
refreshing: z.ZodOptional<z.ZodBoolean>;
|
|
1921
1969
|
}, z.core.$strict>;
|
|
1922
1970
|
readonly kind: "unary";
|
|
1923
1971
|
readonly since: "1.47";
|
|
@@ -1926,6 +1974,7 @@ declare const OPS: {
|
|
|
1926
1974
|
readonly "apps.accounts.list": {
|
|
1927
1975
|
readonly params: z.ZodObject<{
|
|
1928
1976
|
app_key: z.ZodString;
|
|
1977
|
+
fresh: z.ZodOptional<z.ZodBoolean>;
|
|
1929
1978
|
}, z.core.$strict>;
|
|
1930
1979
|
readonly result: z.ZodObject<{
|
|
1931
1980
|
app_key: z.ZodString;
|
|
@@ -1960,6 +2009,8 @@ declare const OPS: {
|
|
|
1960
2009
|
}>>;
|
|
1961
2010
|
}, z.core.$strict>>;
|
|
1962
2011
|
problem: z.ZodOptional<z.ZodString>;
|
|
2012
|
+
as_of_ms: z.ZodOptional<z.ZodInt>;
|
|
2013
|
+
refreshing: z.ZodOptional<z.ZodBoolean>;
|
|
1963
2014
|
}, z.core.$strict>;
|
|
1964
2015
|
readonly kind: "unary";
|
|
1965
2016
|
readonly since: "1.47";
|
|
@@ -7576,14 +7627,10 @@ interface UseDesktopRequestOptions extends Omit<RequestOptions, "signal"> {
|
|
|
7576
7627
|
/** Default true. False = do not run until refetch() or enabled flips true. */
|
|
7577
7628
|
enabled?: boolean;
|
|
7578
7629
|
/** Re-run every `refreshMs` while the page is visible, and at once when it becomes visible
|
|
7579
|
-
* again. A hidden window never polls. Default: no refresh. */
|
|
7630
|
+
* again or its window comes to the front. A hidden window never polls. Default: no refresh. */
|
|
7580
7631
|
refreshMs?: number;
|
|
7581
7632
|
client?: DesktopClient;
|
|
7582
7633
|
}
|
|
7583
|
-
/**
|
|
7584
|
-
* Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and
|
|
7585
|
-
* after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.
|
|
7586
|
-
*/
|
|
7587
7634
|
declare function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options?: UseDesktopRequestOptions): DesktopRequestState<N>;
|
|
7588
7635
|
interface DesktopActionState {
|
|
7589
7636
|
/** Run one or more ops as one action; resolves true when it finished without an error. */
|
package/dist/react.d.ts
CHANGED
|
@@ -1772,6 +1772,20 @@ declare const OPS: {
|
|
|
1772
1772
|
created: z.ZodBoolean;
|
|
1773
1773
|
running: z.ZodBoolean;
|
|
1774
1774
|
open_chats: z.ZodInt;
|
|
1775
|
+
remote_control: z.ZodOptional<z.ZodObject<{
|
|
1776
|
+
setting: z.ZodEnum<{
|
|
1777
|
+
default: "default";
|
|
1778
|
+
on: "on";
|
|
1779
|
+
off: "off";
|
|
1780
|
+
unreadable: "unreadable";
|
|
1781
|
+
}>;
|
|
1782
|
+
serving: z.ZodNullable<z.ZodBoolean>;
|
|
1783
|
+
pending: z.ZodNullable<z.ZodEnum<{
|
|
1784
|
+
on: "on";
|
|
1785
|
+
off: "off";
|
|
1786
|
+
}>>;
|
|
1787
|
+
problem: z.ZodOptional<z.ZodString>;
|
|
1788
|
+
}, z.core.$strict>>;
|
|
1775
1789
|
}, z.core.$strict>>;
|
|
1776
1790
|
}, z.core.$strict>;
|
|
1777
1791
|
readonly kind: "unary";
|
|
@@ -1815,6 +1829,37 @@ declare const OPS: {
|
|
|
1815
1829
|
readonly since: "1.10";
|
|
1816
1830
|
readonly errors: readonly ["NOT_FOUND", "CONFLICT", "TIMEOUT", "PLATFORM_UNSUPPORTED", "INTERNAL"];
|
|
1817
1831
|
};
|
|
1832
|
+
readonly "apps.windows.set_remote_control": {
|
|
1833
|
+
readonly params: z.ZodObject<{
|
|
1834
|
+
app_key: z.ZodString;
|
|
1835
|
+
window: z.ZodString;
|
|
1836
|
+
enabled: z.ZodBoolean;
|
|
1837
|
+
}, z.core.$strict>;
|
|
1838
|
+
readonly result: z.ZodObject<{
|
|
1839
|
+
message: z.ZodString;
|
|
1840
|
+
when: z.ZodEnum<{
|
|
1841
|
+
now: "now";
|
|
1842
|
+
next_close: "next_close";
|
|
1843
|
+
}>;
|
|
1844
|
+
remote_control: z.ZodObject<{
|
|
1845
|
+
setting: z.ZodEnum<{
|
|
1846
|
+
default: "default";
|
|
1847
|
+
on: "on";
|
|
1848
|
+
off: "off";
|
|
1849
|
+
unreadable: "unreadable";
|
|
1850
|
+
}>;
|
|
1851
|
+
serving: z.ZodNullable<z.ZodBoolean>;
|
|
1852
|
+
pending: z.ZodNullable<z.ZodEnum<{
|
|
1853
|
+
on: "on";
|
|
1854
|
+
off: "off";
|
|
1855
|
+
}>>;
|
|
1856
|
+
problem: z.ZodOptional<z.ZodString>;
|
|
1857
|
+
}, z.core.$strict>;
|
|
1858
|
+
}, z.core.$strict>;
|
|
1859
|
+
readonly kind: "unary";
|
|
1860
|
+
readonly since: "1.50";
|
|
1861
|
+
readonly errors: readonly ["NOT_FOUND", "CONFLICT", "PLATFORM_UNSUPPORTED", "INTERNAL"];
|
|
1862
|
+
};
|
|
1818
1863
|
readonly "apps.windows.refresh_usage": {
|
|
1819
1864
|
readonly params: z.ZodObject<{
|
|
1820
1865
|
app_key: z.ZodString;
|
|
@@ -1885,6 +1930,7 @@ declare const OPS: {
|
|
|
1885
1930
|
readonly "apps.instances.list": {
|
|
1886
1931
|
readonly params: z.ZodObject<{
|
|
1887
1932
|
app_key: z.ZodString;
|
|
1933
|
+
fresh: z.ZodOptional<z.ZodBoolean>;
|
|
1888
1934
|
}, z.core.$strict>;
|
|
1889
1935
|
readonly result: z.ZodObject<{
|
|
1890
1936
|
app_key: z.ZodString;
|
|
@@ -1918,6 +1964,8 @@ declare const OPS: {
|
|
|
1918
1964
|
first_launch_ms: z.ZodNullable<z.ZodInt>;
|
|
1919
1965
|
}, z.core.$strict>>;
|
|
1920
1966
|
problem: z.ZodOptional<z.ZodString>;
|
|
1967
|
+
as_of_ms: z.ZodOptional<z.ZodInt>;
|
|
1968
|
+
refreshing: z.ZodOptional<z.ZodBoolean>;
|
|
1921
1969
|
}, z.core.$strict>;
|
|
1922
1970
|
readonly kind: "unary";
|
|
1923
1971
|
readonly since: "1.47";
|
|
@@ -1926,6 +1974,7 @@ declare const OPS: {
|
|
|
1926
1974
|
readonly "apps.accounts.list": {
|
|
1927
1975
|
readonly params: z.ZodObject<{
|
|
1928
1976
|
app_key: z.ZodString;
|
|
1977
|
+
fresh: z.ZodOptional<z.ZodBoolean>;
|
|
1929
1978
|
}, z.core.$strict>;
|
|
1930
1979
|
readonly result: z.ZodObject<{
|
|
1931
1980
|
app_key: z.ZodString;
|
|
@@ -1960,6 +2009,8 @@ declare const OPS: {
|
|
|
1960
2009
|
}>>;
|
|
1961
2010
|
}, z.core.$strict>>;
|
|
1962
2011
|
problem: z.ZodOptional<z.ZodString>;
|
|
2012
|
+
as_of_ms: z.ZodOptional<z.ZodInt>;
|
|
2013
|
+
refreshing: z.ZodOptional<z.ZodBoolean>;
|
|
1963
2014
|
}, z.core.$strict>;
|
|
1964
2015
|
readonly kind: "unary";
|
|
1965
2016
|
readonly since: "1.47";
|
|
@@ -7576,14 +7627,10 @@ interface UseDesktopRequestOptions extends Omit<RequestOptions, "signal"> {
|
|
|
7576
7627
|
/** Default true. False = do not run until refetch() or enabled flips true. */
|
|
7577
7628
|
enabled?: boolean;
|
|
7578
7629
|
/** Re-run every `refreshMs` while the page is visible, and at once when it becomes visible
|
|
7579
|
-
* again. A hidden window never polls. Default: no refresh. */
|
|
7630
|
+
* again or its window comes to the front. A hidden window never polls. Default: no refresh. */
|
|
7580
7631
|
refreshMs?: number;
|
|
7581
7632
|
client?: DesktopClient;
|
|
7582
7633
|
}
|
|
7583
|
-
/**
|
|
7584
|
-
* Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and
|
|
7585
|
-
* after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.
|
|
7586
|
-
*/
|
|
7587
7634
|
declare function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options?: UseDesktopRequestOptions): DesktopRequestState<N>;
|
|
7588
7635
|
interface DesktopActionState {
|
|
7589
7636
|
/** Run one or more ops as one action; resolves true when it finished without an error. */
|
package/dist/react.js
CHANGED
|
@@ -82,6 +82,7 @@ function useDesktopConnection(client) {
|
|
|
82
82
|
}, [c]);
|
|
83
83
|
return state;
|
|
84
84
|
}
|
|
85
|
+
var FOCUS_CATCH_UP_MS = 5e3;
|
|
85
86
|
function useDesktopRequest(op, params, options = {}) {
|
|
86
87
|
const c = useDesktopClient(options.client);
|
|
87
88
|
const enabled = options.enabled ?? true;
|
|
@@ -142,11 +143,19 @@ function useDesktopRequest(op, params, options = {}) {
|
|
|
142
143
|
start();
|
|
143
144
|
} else stop();
|
|
144
145
|
};
|
|
146
|
+
let lastFocus = 0;
|
|
147
|
+
const onFocus = () => {
|
|
148
|
+
if (Date.now() - lastFocus < FOCUS_CATCH_UP_MS) return;
|
|
149
|
+
lastFocus = Date.now();
|
|
150
|
+
void run();
|
|
151
|
+
};
|
|
145
152
|
if (document.visibilityState === "visible") start();
|
|
146
153
|
document.addEventListener("visibilitychange", onVisibility);
|
|
154
|
+
window.addEventListener("focus", onFocus);
|
|
147
155
|
return () => {
|
|
148
156
|
stop();
|
|
149
157
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
158
|
+
window.removeEventListener("focus", onFocus);
|
|
150
159
|
};
|
|
151
160
|
}, [enabled, refreshMs, run]);
|
|
152
161
|
const status = useSyncExternalStore(c.subscribe, () => c.getState().status, () => c.getState().status);
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts","../src/client/wake.ts","../src/error.ts"],"sourcesContent":["/**\n * `@ai-matrx/desktop-protocol/react` — hooks over the client: provider, connection state, typed\n * one-shot requests, events. The client owns every hard part (reconnect, reattach, credits); these\n * hooks only bind it to React's lifecycle.\n */\nimport { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport type { Context, ReactNode } from \"react\";\nimport type { DesktopClient, DesktopClientState, EventHandler, EventName, RequestOptions } from \"./client/types\";\nimport { bindDesktopWake } from \"./client/wake\";\nimport { DesktopProtocolError } from \"./error\";\nimport type { OpName, OpParams, OpResult } from \"./schema/registry\";\n\n// The context lives on globalThis: an ESM and a CJS copy of this entry in one app (Next.js\n// does this) would otherwise create two contexts and a provider the hooks cannot see.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.desktop-protocol.client-context\");\nfunction clientContext(): Context<DesktopClient | null> {\n const slot = globalThis as { [CONTEXT_SLOT]?: Context<DesktopClient | null> };\n return (slot[CONTEXT_SLOT] ??= createContext<DesktopClient | null>(null));\n}\n\nexport function DesktopClientProvider(props: { client: DesktopClient; children?: ReactNode }): ReactNode {\n return createElement(clientContext().Provider, { value: props.client }, props.children);\n}\n\n/** The client from the nearest provider (or the one passed in). Throws when there is neither. */\nexport function useDesktopClient(client?: DesktopClient): DesktopClient {\n const fromContext = useContext(clientContext());\n const resolved = client ?? fromContext;\n if (!resolved) throw new Error(\"useDesktopClient: wrap the tree in <DesktopClientProvider client={…}> or pass a client\");\n return resolved;\n}\n\n/** Live connection state (status, welcome, attempts, retryInMs, lastError). Connects on mount when idle. */\nexport function useDesktopConnection(client?: DesktopClient): DesktopClientState {\n const c = useDesktopClient(client);\n const state = useSyncExternalStore(c.subscribe, c.getState, c.getState);\n useEffect(() => {\n if (c.getState().status === \"idle\") c.connect();\n }, [c]);\n return state;\n}\n\nexport interface DesktopRequestState<N extends OpName> {\n data: OpResult<N> | undefined;\n error: DesktopProtocolError | undefined;\n loading: boolean;\n /** Re-run now; resolves with the fresh result. */\n refetch: () => Promise<OpResult<N> | undefined>;\n}\n\nexport interface UseDesktopRequestOptions extends Omit<RequestOptions, \"signal\"> {\n /** Default true. False = do not run until refetch() or enabled flips true. */\n enabled?: boolean;\n /** Re-run every `refreshMs` while the page is visible, and at once when it becomes visible\n * again. A hidden window never polls. Default: no refresh. */\n refreshMs?: number;\n client?: DesktopClient;\n}\n\n/**\n * Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and\n * after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.\n */\nexport function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options: UseDesktopRequestOptions = {}): DesktopRequestState<N> {\n const c = useDesktopClient(options.client);\n const enabled = options.enabled ?? true;\n const key = JSON.stringify(params);\n const [data, setData] = useState<OpResult<N> | undefined>(undefined);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const [loading, setLoading] = useState<boolean>(enabled);\n const paramsRef = useRef(params);\n paramsRef.current = params;\n const runRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const timeoutMs = options.timeoutMs;\n\n const run = useCallback(async (): Promise<OpResult<N> | undefined> => {\n const runId = ++runRef.current;\n abortRef.current?.abort();\n const abort = new AbortController();\n abortRef.current = abort;\n setLoading(true);\n try {\n const result = await c.request(op, paramsRef.current, timeoutMs === undefined ? { signal: abort.signal } : { signal: abort.signal, timeoutMs });\n if (runId === runRef.current) {\n setData(result);\n setError(undefined);\n }\n return result;\n } catch (caught) {\n const err = DesktopProtocolError.from(caught);\n if (runId === runRef.current && err.code !== \"CANCELLED\") setError(err);\n return undefined;\n } finally {\n if (runId === runRef.current) setLoading(false);\n }\n // `key` stands for the params' content: a new object with equal JSON is not a new request.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [c, op, key, timeoutMs]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n void run();\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, run]);\n\n // Live data: poll while visible, catch up the moment the window is visible again.\n const refreshMs = options.refreshMs;\n useEffect(() => {\n if (!enabled || !refreshMs || typeof document === \"undefined\") return;\n let timer: ReturnType<typeof setInterval> | null = null;\n const start = () => {\n if (timer === null) timer = setInterval(() => void run(), refreshMs);\n };\n const stop = () => {\n if (timer !== null) clearInterval(timer);\n timer = null;\n };\n const onVisibility = () => {\n if (document.visibilityState === \"visible\") {\n void run();\n start();\n } else stop();\n };\n if (document.visibilityState === \"visible\") start();\n document.addEventListener(\"visibilitychange\", onVisibility);\n return () => {\n stop();\n document.removeEventListener(\"visibilitychange\", onVisibility);\n };\n }, [enabled, refreshMs, run]);\n\n // A retryable failure (device offline, connection lost) re-runs once the client is open again.\n const status = useSyncExternalStore(c.subscribe, () => c.getState().status, () => c.getState().status);\n useEffect(() => {\n if (enabled && status === \"open\" && error?.retryable) void run();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n return { data, error, loading, refetch: run };\n}\n\nexport interface DesktopActionState {\n /** Run one or more ops as one action; resolves true when it finished without an error. */\n run: (work: (client: DesktopClient) => Promise<unknown>) => Promise<boolean>;\n /** An action is in flight (disable its controls). */\n busy: boolean;\n /** The last action's error, until the next action or `clearError()`. */\n error: DesktopProtocolError | undefined;\n clearError: () => void;\n}\n\n/**\n * Actions (create, save, remove, open): one busy flag and one error for a screen's writes, with the\n * same error type as reads. `onDone` runs after every successful action (refetch what it changed).\n */\nexport function useDesktopAction(options: { client?: DesktopClient; onDone?: () => unknown } = {}): DesktopActionState {\n const c = useDesktopClient(options.client);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const onDoneRef = useRef(options.onDone);\n onDoneRef.current = options.onDone;\n const run = useCallback(\n async (work: (client: DesktopClient) => Promise<unknown>): Promise<boolean> => {\n setBusy(true);\n setError(undefined);\n try {\n await work(c);\n await onDoneRef.current?.();\n return true;\n } catch (caught) {\n const err = DesktopProtocolError.from(caught);\n // A cancelled action (the person pressed Stop) is not a failure to show.\n if (err.code !== \"CANCELLED\") setError(err);\n return false;\n } finally {\n setBusy(false);\n }\n },\n [c],\n );\n const clearError = useCallback(() => setError(undefined), []);\n return { run, busy, error, clearError };\n}\n\n/** Subscribe to one protocol event (fs.changed, exec.exited, relay.device_status, …) for the component's life. */\nexport function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options: { client?: DesktopClient } = {}): void {\n const c = useDesktopClient(options.client);\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n useEffect(() => c.on(name, ((payload, resourceId) => handlerRef.current(payload, resourceId)) as EventHandler<E>), [c, name]);\n}\n\n/**\n * Reconnect the moment the person is back: page visible again, a bfcache restore, the network\n * returning, window focus. Each calls `client.wake()` — dial now if reconnecting, probe if open.\n */\nexport function useDesktopWake(client?: DesktopClient, options: { probeMs?: number } = {}): void {\n const c = useDesktopClient(client);\n const probeMs = options.probeMs;\n useEffect(() => bindDesktopWake(c, probeMs === undefined ? {} : { probeMs }), [c, probeMs]);\n}\n","/**\n * Wire a client's wake() to the browser events that mean \"the person is back\": the page becomes\n * visible again (iOS Safari suspends a background tab's sockets), a back/forward-cache restore\n * (`pageshow` with persisted), and the network returning (`online`). Framework-free; the React\n * binding is `useDesktopWake` in `./react`.\n */\nimport type { DesktopClient, WakeOptions } from \"./types\";\n\n/** The subset of window/document the binding listens on — injectable for tests and non-DOM hosts. */\nexport interface WakeTargets {\n window: Pick<Window, \"addEventListener\" | \"removeEventListener\">;\n document: Pick<Document, \"addEventListener\" | \"removeEventListener\" | \"visibilityState\">;\n}\n\nexport function bindDesktopWake(client: Pick<DesktopClient, \"wake\">, options: WakeOptions & { targets?: WakeTargets } = {}): () => void {\n const targets: WakeTargets | null =\n options.targets ?? (typeof window !== \"undefined\" && typeof document !== \"undefined\" ? { window, document } : null);\n if (!targets) return () => undefined;\n const wakeOptions: WakeOptions = options.probeMs === undefined ? {} : { probeMs: options.probeMs };\n const onVisibility = () => {\n if (targets.document.visibilityState === \"visible\") client.wake(wakeOptions);\n };\n const onWake = () => client.wake(wakeOptions);\n targets.document.addEventListener(\"visibilitychange\", onVisibility);\n targets.window.addEventListener(\"pageshow\", onWake);\n targets.window.addEventListener(\"online\", onWake);\n targets.window.addEventListener(\"focus\", onWake);\n return () => {\n targets.document.removeEventListener(\"visibilitychange\", onVisibility);\n targets.window.removeEventListener(\"pageshow\", onWake);\n targets.window.removeEventListener(\"online\", onWake);\n targets.window.removeEventListener(\"focus\", onWake);\n };\n}\n","/**\n * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a\n * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on\n * purpose: `./frame` (the relay hot path) throws it without pulling the schema graph.\n */\nimport type { ErrorCodeName, ErrorData } from \"./types\";\n\nexport class DesktopProtocolError extends Error {\n readonly code: ErrorCodeName;\n readonly retryable: boolean;\n readonly data: ErrorData | undefined;\n\n constructor(code: ErrorCodeName, message: string, options: { retryable?: boolean; data?: ErrorData; cause?: unknown } = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"DesktopProtocolError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.data = options.data;\n }\n\n /**\n * Any thrown value as a DesktopProtocolError, keeping its code, message and data. Each built entry\n * (`.`, `./client`, `./react`) carries its own copy of this class, so `instanceof` alone misses an\n * error thrown by a sibling entry and reports a real NOT_FOUND as INTERNAL; this checks the shape.\n */\n static from(caught: unknown): DesktopProtocolError {\n if (caught instanceof DesktopProtocolError) return caught;\n const e = caught as { name?: unknown; code?: unknown; message?: unknown; retryable?: unknown; data?: unknown } | null;\n if (e && typeof e === \"object\" && e.name === \"DesktopProtocolError\" && typeof e.code === \"string\") {\n return new DesktopProtocolError(e.code as ErrorCodeName, typeof e.message === \"string\" ? e.message : String(e.code), {\n retryable: e.retryable === true,\n ...(e.data && typeof e.data === \"object\" ? { data: e.data as ErrorData } : {}),\n cause: caught,\n });\n }\n return new DesktopProtocolError(\"INTERNAL\", caught instanceof Error ? caught.message : String(caught), { cause: caught });\n }\n\n /** The wire body (ProtocolErrorBody) — what a core or relay sends for this error. */\n toBody(): { code: ErrorCodeName; message: string; retryable: boolean; data?: ErrorData } {\n return this.data === undefined\n ? { code: this.code, message: this.message, retryable: this.retryable }\n : { code: this.code, message: this.message, retryable: this.retryable, data: this.data };\n }\n}\n\nexport function isDesktopProtocolError(value: unknown): value is DesktopProtocolError {\n return value instanceof DesktopProtocolError || (value instanceof Error && value.name === \"DesktopProtocolError\" && \"code\" in value);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/react.ts","../src/client/wake.ts","../src/error.ts"],"sourcesContent":["/**\n * `@ai-matrx/desktop-protocol/react` — hooks over the client: provider, connection state, typed\n * one-shot requests, events. The client owns every hard part (reconnect, reattach, credits); these\n * hooks only bind it to React's lifecycle.\n */\nimport { createContext, createElement, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport type { Context, ReactNode } from \"react\";\nimport type { DesktopClient, DesktopClientState, EventHandler, EventName, RequestOptions } from \"./client/types\";\nimport { bindDesktopWake } from \"./client/wake\";\nimport { DesktopProtocolError } from \"./error\";\nimport type { OpName, OpParams, OpResult } from \"./schema/registry\";\n\n// The context lives on globalThis: an ESM and a CJS copy of this entry in one app (Next.js\n// does this) would otherwise create two contexts and a provider the hooks cannot see.\nconst CONTEXT_SLOT = Symbol.for(\"ai-matrx.desktop-protocol.client-context\");\nfunction clientContext(): Context<DesktopClient | null> {\n const slot = globalThis as { [CONTEXT_SLOT]?: Context<DesktopClient | null> };\n return (slot[CONTEXT_SLOT] ??= createContext<DesktopClient | null>(null));\n}\n\nexport function DesktopClientProvider(props: { client: DesktopClient; children?: ReactNode }): ReactNode {\n return createElement(clientContext().Provider, { value: props.client }, props.children);\n}\n\n/** The client from the nearest provider (or the one passed in). Throws when there is neither. */\nexport function useDesktopClient(client?: DesktopClient): DesktopClient {\n const fromContext = useContext(clientContext());\n const resolved = client ?? fromContext;\n if (!resolved) throw new Error(\"useDesktopClient: wrap the tree in <DesktopClientProvider client={…}> or pass a client\");\n return resolved;\n}\n\n/** Live connection state (status, welcome, attempts, retryInMs, lastError). Connects on mount when idle. */\nexport function useDesktopConnection(client?: DesktopClient): DesktopClientState {\n const c = useDesktopClient(client);\n const state = useSyncExternalStore(c.subscribe, c.getState, c.getState);\n useEffect(() => {\n if (c.getState().status === \"idle\") c.connect();\n }, [c]);\n return state;\n}\n\nexport interface DesktopRequestState<N extends OpName> {\n data: OpResult<N> | undefined;\n error: DesktopProtocolError | undefined;\n loading: boolean;\n /** Re-run now; resolves with the fresh result. */\n refetch: () => Promise<OpResult<N> | undefined>;\n}\n\nexport interface UseDesktopRequestOptions extends Omit<RequestOptions, \"signal\"> {\n /** Default true. False = do not run until refetch() or enabled flips true. */\n enabled?: boolean;\n /** Re-run every `refreshMs` while the page is visible, and at once when it becomes visible\n * again or its window comes to the front. A hidden window never polls. Default: no refresh. */\n refreshMs?: number;\n client?: DesktopClient;\n}\n\n/**\n * Run a unary op and keep its latest result. Re-runs when `op` or the params' JSON changes, and\n * after a reconnect if the last attempt failed with a retryable error. Aborts on unmount.\n */\n/** A window focused again within this long of the last catch-up is not read again. */\nconst FOCUS_CATCH_UP_MS = 5_000;\n\nexport function useDesktopRequest<N extends OpName>(op: N, params: OpParams<N>, options: UseDesktopRequestOptions = {}): DesktopRequestState<N> {\n const c = useDesktopClient(options.client);\n const enabled = options.enabled ?? true;\n const key = JSON.stringify(params);\n const [data, setData] = useState<OpResult<N> | undefined>(undefined);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const [loading, setLoading] = useState<boolean>(enabled);\n const paramsRef = useRef(params);\n paramsRef.current = params;\n const runRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const timeoutMs = options.timeoutMs;\n\n const run = useCallback(async (): Promise<OpResult<N> | undefined> => {\n const runId = ++runRef.current;\n abortRef.current?.abort();\n const abort = new AbortController();\n abortRef.current = abort;\n setLoading(true);\n try {\n const result = await c.request(op, paramsRef.current, timeoutMs === undefined ? { signal: abort.signal } : { signal: abort.signal, timeoutMs });\n if (runId === runRef.current) {\n setData(result);\n setError(undefined);\n }\n return result;\n } catch (caught) {\n const err = DesktopProtocolError.from(caught);\n if (runId === runRef.current && err.code !== \"CANCELLED\") setError(err);\n return undefined;\n } finally {\n if (runId === runRef.current) setLoading(false);\n }\n // `key` stands for the params' content: a new object with equal JSON is not a new request.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [c, op, key, timeoutMs]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n void run();\n return () => {\n abortRef.current?.abort();\n };\n }, [enabled, run]);\n\n // Live data: poll while visible, catch up the moment the window is visible again.\n const refreshMs = options.refreshMs;\n useEffect(() => {\n if (!enabled || !refreshMs || typeof document === \"undefined\") return;\n let timer: ReturnType<typeof setInterval> | null = null;\n const start = () => {\n if (timer === null) timer = setInterval(() => void run(), refreshMs);\n };\n const stop = () => {\n if (timer !== null) clearInterval(timer);\n timer = null;\n };\n const onVisibility = () => {\n if (document.visibilityState === \"visible\") {\n void run();\n start();\n } else stop();\n };\n // The window coming to the front again (a desktop app switched back to): catch up at once,\n // at most once every few seconds (a quick switch away and back is not two reads).\n let lastFocus = 0;\n const onFocus = () => {\n if (Date.now() - lastFocus < FOCUS_CATCH_UP_MS) return;\n lastFocus = Date.now();\n void run();\n };\n if (document.visibilityState === \"visible\") start();\n document.addEventListener(\"visibilitychange\", onVisibility);\n window.addEventListener(\"focus\", onFocus);\n return () => {\n stop();\n document.removeEventListener(\"visibilitychange\", onVisibility);\n window.removeEventListener(\"focus\", onFocus);\n };\n }, [enabled, refreshMs, run]);\n\n // A retryable failure (device offline, connection lost) re-runs once the client is open again.\n const status = useSyncExternalStore(c.subscribe, () => c.getState().status, () => c.getState().status);\n useEffect(() => {\n if (enabled && status === \"open\" && error?.retryable) void run();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n return { data, error, loading, refetch: run };\n}\n\nexport interface DesktopActionState {\n /** Run one or more ops as one action; resolves true when it finished without an error. */\n run: (work: (client: DesktopClient) => Promise<unknown>) => Promise<boolean>;\n /** An action is in flight (disable its controls). */\n busy: boolean;\n /** The last action's error, until the next action or `clearError()`. */\n error: DesktopProtocolError | undefined;\n clearError: () => void;\n}\n\n/**\n * Actions (create, save, remove, open): one busy flag and one error for a screen's writes, with the\n * same error type as reads. `onDone` runs after every successful action (refetch what it changed).\n */\nexport function useDesktopAction(options: { client?: DesktopClient; onDone?: () => unknown } = {}): DesktopActionState {\n const c = useDesktopClient(options.client);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<DesktopProtocolError | undefined>(undefined);\n const onDoneRef = useRef(options.onDone);\n onDoneRef.current = options.onDone;\n const run = useCallback(\n async (work: (client: DesktopClient) => Promise<unknown>): Promise<boolean> => {\n setBusy(true);\n setError(undefined);\n try {\n await work(c);\n await onDoneRef.current?.();\n return true;\n } catch (caught) {\n const err = DesktopProtocolError.from(caught);\n // A cancelled action (the person pressed Stop) is not a failure to show.\n if (err.code !== \"CANCELLED\") setError(err);\n return false;\n } finally {\n setBusy(false);\n }\n },\n [c],\n );\n const clearError = useCallback(() => setError(undefined), []);\n return { run, busy, error, clearError };\n}\n\n/** Subscribe to one protocol event (fs.changed, exec.exited, relay.device_status, …) for the component's life. */\nexport function useDesktopEvent<E extends EventName>(name: E, handler: EventHandler<E>, options: { client?: DesktopClient } = {}): void {\n const c = useDesktopClient(options.client);\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n useEffect(() => c.on(name, ((payload, resourceId) => handlerRef.current(payload, resourceId)) as EventHandler<E>), [c, name]);\n}\n\n/**\n * Reconnect the moment the person is back: page visible again, a bfcache restore, the network\n * returning, window focus. Each calls `client.wake()` — dial now if reconnecting, probe if open.\n */\nexport function useDesktopWake(client?: DesktopClient, options: { probeMs?: number } = {}): void {\n const c = useDesktopClient(client);\n const probeMs = options.probeMs;\n useEffect(() => bindDesktopWake(c, probeMs === undefined ? {} : { probeMs }), [c, probeMs]);\n}\n","/**\n * Wire a client's wake() to the browser events that mean \"the person is back\": the page becomes\n * visible again (iOS Safari suspends a background tab's sockets), a back/forward-cache restore\n * (`pageshow` with persisted), and the network returning (`online`). Framework-free; the React\n * binding is `useDesktopWake` in `./react`.\n */\nimport type { DesktopClient, WakeOptions } from \"./types\";\n\n/** The subset of window/document the binding listens on — injectable for tests and non-DOM hosts. */\nexport interface WakeTargets {\n window: Pick<Window, \"addEventListener\" | \"removeEventListener\">;\n document: Pick<Document, \"addEventListener\" | \"removeEventListener\" | \"visibilityState\">;\n}\n\nexport function bindDesktopWake(client: Pick<DesktopClient, \"wake\">, options: WakeOptions & { targets?: WakeTargets } = {}): () => void {\n const targets: WakeTargets | null =\n options.targets ?? (typeof window !== \"undefined\" && typeof document !== \"undefined\" ? { window, document } : null);\n if (!targets) return () => undefined;\n const wakeOptions: WakeOptions = options.probeMs === undefined ? {} : { probeMs: options.probeMs };\n const onVisibility = () => {\n if (targets.document.visibilityState === \"visible\") client.wake(wakeOptions);\n };\n const onWake = () => client.wake(wakeOptions);\n targets.document.addEventListener(\"visibilitychange\", onVisibility);\n targets.window.addEventListener(\"pageshow\", onWake);\n targets.window.addEventListener(\"online\", onWake);\n targets.window.addEventListener(\"focus\", onWake);\n return () => {\n targets.document.removeEventListener(\"visibilitychange\", onVisibility);\n targets.window.removeEventListener(\"pageshow\", onWake);\n targets.window.removeEventListener(\"online\", onWake);\n targets.window.removeEventListener(\"focus\", onWake);\n };\n}\n","/**\n * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a\n * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on\n * purpose: `./frame` (the relay hot path) throws it without pulling the schema graph.\n */\nimport type { ErrorCodeName, ErrorData } from \"./types\";\n\nexport class DesktopProtocolError extends Error {\n readonly code: ErrorCodeName;\n readonly retryable: boolean;\n readonly data: ErrorData | undefined;\n\n constructor(code: ErrorCodeName, message: string, options: { retryable?: boolean; data?: ErrorData; cause?: unknown } = {}) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = \"DesktopProtocolError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.data = options.data;\n }\n\n /**\n * Any thrown value as a DesktopProtocolError, keeping its code, message and data. Each built entry\n * (`.`, `./client`, `./react`) carries its own copy of this class, so `instanceof` alone misses an\n * error thrown by a sibling entry and reports a real NOT_FOUND as INTERNAL; this checks the shape.\n */\n static from(caught: unknown): DesktopProtocolError {\n if (caught instanceof DesktopProtocolError) return caught;\n const e = caught as { name?: unknown; code?: unknown; message?: unknown; retryable?: unknown; data?: unknown } | null;\n if (e && typeof e === \"object\" && e.name === \"DesktopProtocolError\" && typeof e.code === \"string\") {\n return new DesktopProtocolError(e.code as ErrorCodeName, typeof e.message === \"string\" ? e.message : String(e.code), {\n retryable: e.retryable === true,\n ...(e.data && typeof e.data === \"object\" ? { data: e.data as ErrorData } : {}),\n cause: caught,\n });\n }\n return new DesktopProtocolError(\"INTERNAL\", caught instanceof Error ? caught.message : String(caught), { cause: caught });\n }\n\n /** The wire body (ProtocolErrorBody) — what a core or relay sends for this error. */\n toBody(): { code: ErrorCodeName; message: string; retryable: boolean; data?: ErrorData } {\n return this.data === undefined\n ? { code: this.code, message: this.message, retryable: this.retryable }\n : { code: this.code, message: this.message, retryable: this.retryable, data: this.data };\n }\n}\n\nexport function isDesktopProtocolError(value: unknown): value is DesktopProtocolError {\n return value instanceof DesktopProtocolError || (value instanceof Error && value.name === \"DesktopProtocolError\" && \"code\" in value);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -410,6 +410,9 @@
|
|
|
410
410
|
"properties": {
|
|
411
411
|
"app_key": {
|
|
412
412
|
"$ref": "#/$defs/AppKey"
|
|
413
|
+
},
|
|
414
|
+
"fresh": {
|
|
415
|
+
"type": "boolean"
|
|
413
416
|
}
|
|
414
417
|
},
|
|
415
418
|
"required": [
|
|
@@ -443,6 +446,14 @@
|
|
|
443
446
|
"problem": {
|
|
444
447
|
"type": "string",
|
|
445
448
|
"maxLength": 400
|
|
449
|
+
},
|
|
450
|
+
"as_of_ms": {
|
|
451
|
+
"type": "integer",
|
|
452
|
+
"minimum": 0,
|
|
453
|
+
"maximum": 9007199254740991
|
|
454
|
+
},
|
|
455
|
+
"refreshing": {
|
|
456
|
+
"type": "boolean"
|
|
446
457
|
}
|
|
447
458
|
},
|
|
448
459
|
"required": [
|
|
@@ -457,6 +468,9 @@
|
|
|
457
468
|
"properties": {
|
|
458
469
|
"app_key": {
|
|
459
470
|
"$ref": "#/$defs/AppKey"
|
|
471
|
+
},
|
|
472
|
+
"fresh": {
|
|
473
|
+
"type": "boolean"
|
|
460
474
|
}
|
|
461
475
|
},
|
|
462
476
|
"required": [
|
|
@@ -480,6 +494,14 @@
|
|
|
480
494
|
"problem": {
|
|
481
495
|
"type": "string",
|
|
482
496
|
"maxLength": 400
|
|
497
|
+
},
|
|
498
|
+
"as_of_ms": {
|
|
499
|
+
"type": "integer",
|
|
500
|
+
"minimum": 0,
|
|
501
|
+
"maximum": 9007199254740991
|
|
502
|
+
},
|
|
503
|
+
"refreshing": {
|
|
504
|
+
"type": "boolean"
|
|
483
505
|
}
|
|
484
506
|
},
|
|
485
507
|
"required": [
|
|
@@ -13222,6 +13244,9 @@
|
|
|
13222
13244
|
"type": "integer",
|
|
13223
13245
|
"minimum": 0,
|
|
13224
13246
|
"maximum": 9007199254740991
|
|
13247
|
+
},
|
|
13248
|
+
"remote_control": {
|
|
13249
|
+
"$ref": "#/$defs/WindowRemoteControl"
|
|
13225
13250
|
}
|
|
13226
13251
|
},
|
|
13227
13252
|
"required": [
|
|
@@ -13237,6 +13262,95 @@
|
|
|
13237
13262
|
],
|
|
13238
13263
|
"additionalProperties": false
|
|
13239
13264
|
},
|
|
13265
|
+
"WindowRemoteControl": {
|
|
13266
|
+
"type": "object",
|
|
13267
|
+
"properties": {
|
|
13268
|
+
"setting": {
|
|
13269
|
+
"type": "string",
|
|
13270
|
+
"enum": [
|
|
13271
|
+
"on",
|
|
13272
|
+
"off",
|
|
13273
|
+
"default",
|
|
13274
|
+
"unreadable"
|
|
13275
|
+
]
|
|
13276
|
+
},
|
|
13277
|
+
"serving": {
|
|
13278
|
+
"type": [
|
|
13279
|
+
"boolean",
|
|
13280
|
+
"null"
|
|
13281
|
+
]
|
|
13282
|
+
},
|
|
13283
|
+
"pending": {
|
|
13284
|
+
"anyOf": [
|
|
13285
|
+
{
|
|
13286
|
+
"type": "string",
|
|
13287
|
+
"enum": [
|
|
13288
|
+
"on",
|
|
13289
|
+
"off"
|
|
13290
|
+
]
|
|
13291
|
+
},
|
|
13292
|
+
{
|
|
13293
|
+
"type": "null"
|
|
13294
|
+
}
|
|
13295
|
+
]
|
|
13296
|
+
},
|
|
13297
|
+
"problem": {
|
|
13298
|
+
"type": "string",
|
|
13299
|
+
"maxLength": 300
|
|
13300
|
+
}
|
|
13301
|
+
},
|
|
13302
|
+
"required": [
|
|
13303
|
+
"setting",
|
|
13304
|
+
"serving",
|
|
13305
|
+
"pending"
|
|
13306
|
+
],
|
|
13307
|
+
"additionalProperties": false
|
|
13308
|
+
},
|
|
13309
|
+
"AppsWindowsSetRemoteControlParams": {
|
|
13310
|
+
"type": "object",
|
|
13311
|
+
"properties": {
|
|
13312
|
+
"app_key": {
|
|
13313
|
+
"$ref": "#/$defs/AppKey"
|
|
13314
|
+
},
|
|
13315
|
+
"window": {
|
|
13316
|
+
"$ref": "#/$defs/ChatPlace"
|
|
13317
|
+
},
|
|
13318
|
+
"enabled": {
|
|
13319
|
+
"type": "boolean"
|
|
13320
|
+
}
|
|
13321
|
+
},
|
|
13322
|
+
"required": [
|
|
13323
|
+
"app_key",
|
|
13324
|
+
"window",
|
|
13325
|
+
"enabled"
|
|
13326
|
+
],
|
|
13327
|
+
"additionalProperties": false
|
|
13328
|
+
},
|
|
13329
|
+
"AppsWindowsSetRemoteControlResult": {
|
|
13330
|
+
"type": "object",
|
|
13331
|
+
"properties": {
|
|
13332
|
+
"message": {
|
|
13333
|
+
"type": "string",
|
|
13334
|
+
"maxLength": 400
|
|
13335
|
+
},
|
|
13336
|
+
"when": {
|
|
13337
|
+
"type": "string",
|
|
13338
|
+
"enum": [
|
|
13339
|
+
"now",
|
|
13340
|
+
"next_close"
|
|
13341
|
+
]
|
|
13342
|
+
},
|
|
13343
|
+
"remote_control": {
|
|
13344
|
+
"$ref": "#/$defs/WindowRemoteControl"
|
|
13345
|
+
}
|
|
13346
|
+
},
|
|
13347
|
+
"required": [
|
|
13348
|
+
"message",
|
|
13349
|
+
"when",
|
|
13350
|
+
"remote_control"
|
|
13351
|
+
],
|
|
13352
|
+
"additionalProperties": false
|
|
13353
|
+
},
|
|
13240
13354
|
"AccountUsage": {
|
|
13241
13355
|
"type": "object",
|
|
13242
13356
|
"properties": {
|
|
@@ -23055,6 +23169,18 @@
|
|
|
23055
23169
|
"INTERNAL"
|
|
23056
23170
|
]
|
|
23057
23171
|
},
|
|
23172
|
+
"apps.windows.set_remote_control": {
|
|
23173
|
+
"params": "AppsWindowsSetRemoteControlParams",
|
|
23174
|
+
"result": "AppsWindowsSetRemoteControlResult",
|
|
23175
|
+
"kind": "unary",
|
|
23176
|
+
"since": "1.50",
|
|
23177
|
+
"errors": [
|
|
23178
|
+
"NOT_FOUND",
|
|
23179
|
+
"CONFLICT",
|
|
23180
|
+
"PLATFORM_UNSUPPORTED",
|
|
23181
|
+
"INTERNAL"
|
|
23182
|
+
]
|
|
23183
|
+
},
|
|
23058
23184
|
"apps.windows.refresh_usage": {
|
|
23059
23185
|
"params": "AppsWindowsRefreshUsageParams",
|
|
23060
23186
|
"result": "AppsWindowActionResult",
|
|
@@ -25409,6 +25535,26 @@
|
|
|
25409
25535
|
"app": "1.7",
|
|
25410
25536
|
"pid": "1.7"
|
|
25411
25537
|
},
|
|
25538
|
+
"AppWindowInfo": {
|
|
25539
|
+
"remote_control": "1.50"
|
|
25540
|
+
},
|
|
25541
|
+
"WindowRemoteControl": {
|
|
25542
|
+
"problem": "1.52"
|
|
25543
|
+
},
|
|
25544
|
+
"AppsInstancesListParams": {
|
|
25545
|
+
"fresh": "1.51"
|
|
25546
|
+
},
|
|
25547
|
+
"AppsInstancesListResult": {
|
|
25548
|
+
"as_of_ms": "1.51",
|
|
25549
|
+
"refreshing": "1.51"
|
|
25550
|
+
},
|
|
25551
|
+
"AppsAccountsListParams": {
|
|
25552
|
+
"fresh": "1.51"
|
|
25553
|
+
},
|
|
25554
|
+
"AppsAccountsListResult": {
|
|
25555
|
+
"as_of_ms": "1.51",
|
|
25556
|
+
"refreshing": "1.51"
|
|
25557
|
+
},
|
|
25412
25558
|
"AppsChatsListResult": {
|
|
25413
25559
|
"updating": "1.9",
|
|
25414
25560
|
"live": "1.9",
|
|
@@ -25519,5 +25665,5 @@
|
|
|
25519
25665
|
"olderPeersGet": 0
|
|
25520
25666
|
}
|
|
25521
25667
|
},
|
|
25522
|
-
"x-protocol-version": "1.
|
|
25668
|
+
"x-protocol-version": "1.52"
|
|
25523
25669
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/desktop-protocol",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.47",
|
|
4
4
|
"description": "The one wire contract between Matrx 2 (the desktop app) and every client that drives it — phone, web app, extension, server: zod schemas for the envelope and every cap.op, the 16-byte binary frame codec, a reconnecting request/stream/credit/reattach client, React hooks, and a generated JSON Schema + Pydantic twin that CI keeps byte-identical.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
81
|
"zod": "^4.6.5",
|
|
82
|
-
"@ai-matrx/
|
|
83
|
-
"@ai-matrx/
|
|
82
|
+
"@ai-matrx/data": "latest",
|
|
83
|
+
"@ai-matrx/kit": "latest"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -131,11 +131,11 @@
|
|
|
131
131
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
132
132
|
"generate": "tsx scripts/generate.ts",
|
|
133
133
|
"lint": "node scripts/check-schema-source.mjs --self-test && node scripts/check-schema-source.mjs",
|
|
134
|
-
"check:package": "pnpm lint && pnpm generate --check && pnpm build && node ../scripts/check-exports-agreement.mjs && publint && pnpm verify:tarball && node ../scripts/check-tarball-relative-imports.mjs --self-test && node ../scripts/check-tarball-relative-imports.mjs --pack .",
|
|
134
|
+
"check:package": "pnpm lint && pnpm generate --check && pnpm build && node ../scripts/check-exports-agreement.mjs && publint && pnpm verify:tarball && node ../scripts/check-tarball-relative-imports.mjs --self-test && node ../scripts/check-tarball-relative-imports.mjs --pack . && node ../scripts/check-package-rules.mjs --self-test && node ../scripts/check-package-rules.mjs .",
|
|
135
135
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
136
136
|
"test": "vitest run",
|
|
137
137
|
"test:watch": "vitest",
|
|
138
138
|
"verify:tarball": "node ./scripts/verify-tarball.mjs"
|
|
139
139
|
},
|
|
140
|
-
"gitHead": "
|
|
140
|
+
"gitHead": "e6d46f8a90267c8d5649b2424c3288e010d84b3c"
|
|
141
141
|
}
|