@melaya/runner 1.1.71 → 1.1.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/computerHelperManifest.d.ts +1 -1
- package/dist/computerHelperManifest.js +5 -5
- package/dist/computerHostCli.d.ts +6 -3
- package/dist/computerHostCli.js +13 -1
- package/dist/connection.js +6 -1
- package/dist/hostChannel.d.ts +7 -1
- package/dist/hostChannel.js +8 -0
- package/package.json +1 -1
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
// Pinned computer helper releases for the runner CLI host (computerHostCli.ts),
|
|
6
6
|
// keyed by `${process.platform}-${process.arch}`. A download is only accepted
|
|
7
7
|
// when its sha256 matches.
|
|
8
|
-
export const COMPUTER_HELPER_VERSION = "1.0
|
|
8
|
+
export const COMPUTER_HELPER_VERSION = "1.2.0";
|
|
9
9
|
export const COMPUTER_HELPER_MANIFEST = {
|
|
10
10
|
"linux-arm64": {
|
|
11
|
-
"url": "https://api.melaya.org/desktop/helpers/1.0
|
|
12
|
-
"sha256": "
|
|
11
|
+
"url": "https://api.melaya.org/desktop/helpers/1.2.0/melaya-computer-linux-aarch64",
|
|
12
|
+
"sha256": "8f1ddb5a4bdcc7bda35439de6ec1aa962e16b199dcb510e52fb48c00782eeef9"
|
|
13
13
|
},
|
|
14
14
|
"linux-x64": {
|
|
15
|
-
"url": "https://api.melaya.org/desktop/helpers/1.0
|
|
16
|
-
"sha256": "
|
|
15
|
+
"url": "https://api.melaya.org/desktop/helpers/1.2.0/melaya-computer-linux-x86_64",
|
|
16
|
+
"sha256": "1431df7dd6f6a5d8412e4120fdadc82c247965a1139b03dd585ce93b21d5e88a"
|
|
17
17
|
}
|
|
18
18
|
};
|
|
@@ -77,10 +77,11 @@ export type ComputerCapabilitiesLike = Record<string, unknown> & {
|
|
|
77
77
|
kinds: string[];
|
|
78
78
|
host?: "desktop" | "cli";
|
|
79
79
|
};
|
|
80
|
-
export declare const COMPUTER_ACTION_KINDS: readonly ["screen", "screenshot", "find", "get_text", "current_app", "list_windows", "list_apps", "list_displays", "clipboard_read", "ocr", "wait", "hover", "move", "scroll", "focus_window", "open_app", "open_url", "open_file", "click", "type", "press", "drag", "select", "set_value", "toggle", "window", "clipboard_write", "file_dialog", "batch", "zoom", "cursor_position", "read_table", "expect", "mouse", "hold_key", "select_text", "quit_app", "save_dialog", "handoff", "keep_awake"];
|
|
80
|
+
export declare const COMPUTER_ACTION_KINDS: readonly ["screen", "screenshot", "find", "get_text", "current_app", "list_windows", "list_apps", "list_displays", "clipboard_read", "ocr", "wait", "hover", "move", "scroll", "focus_window", "open_app", "open_url", "open_file", "click", "type", "press", "drag", "select", "set_value", "toggle", "window", "clipboard_write", "file_dialog", "batch", "zoom", "cursor_position", "read_table", "expect", "mouse", "hold_key", "select_text", "quit_app", "save_dialog", "handoff", "keep_awake", "path"];
|
|
81
81
|
/** Kinds that do not act on an app window: an empty allowlist does not block them. */
|
|
82
82
|
export declare const APP_INDEPENDENT_KINDS: Set<string>;
|
|
83
|
-
|
|
83
|
+
/** Steps per batch: a whole drawing in one call (raised from 100 on 2026-10-23). */
|
|
84
|
+
export declare const COMPUTER_MAX_BATCH_STEPS = 5000;
|
|
84
85
|
/** The lowest app tier that allows this action (same rule as the server and the helpers). */
|
|
85
86
|
export declare function requiredTierOf(action: Record<string, unknown>): ComputerAppTier;
|
|
86
87
|
/**
|
|
@@ -120,7 +121,7 @@ export declare function checkCommand(msg: {
|
|
|
120
121
|
* accepted when its sha256 matches. Empty until the first release: use
|
|
121
122
|
* MELAYA_COMPUTER_HELPER or --computer-helper meanwhile.
|
|
122
123
|
*/
|
|
123
|
-
export declare const HELPER_VERSION = "1.0
|
|
124
|
+
export declare const HELPER_VERSION = "1.2.0";
|
|
124
125
|
export declare const HELPER_MANIFEST: Record<string, {
|
|
125
126
|
url: string;
|
|
126
127
|
sha256: string;
|
|
@@ -184,6 +185,8 @@ export declare class HelperProcess {
|
|
|
184
185
|
* Aborts one command (or every one). A command that has not answered `stopped`
|
|
185
186
|
* within the grace period gets the helper killed; it restarts on the next command.
|
|
186
187
|
*/
|
|
188
|
+
/** Releases every key / button the helper holds (helper 1.2.0+; older helpers ignore the op). */
|
|
189
|
+
release(): void;
|
|
187
190
|
cancel(target?: string): void;
|
|
188
191
|
get running(): boolean;
|
|
189
192
|
dispose(): void;
|
package/dist/computerHostCli.js
CHANGED
|
@@ -56,6 +56,8 @@ export const COMPUTER_ACTION_KINDS = [
|
|
|
56
56
|
"toggle", "window", "clipboard_write", "file_dialog", "batch",
|
|
57
57
|
"zoom", "cursor_position", "read_table", "expect", "mouse", "hold_key", "select_text", "quit_app",
|
|
58
58
|
"save_dialog", "handoff", "keep_awake",
|
|
59
|
+
// helper 1.2.0 (2026-10-23): pointer paths (planned by the server, replayed by the helper)
|
|
60
|
+
"path",
|
|
59
61
|
];
|
|
60
62
|
const READ_KINDS = new Set([
|
|
61
63
|
"screen", "screenshot", "find", "get_text", "current_app", "list_windows", "list_apps",
|
|
@@ -67,7 +69,8 @@ const KIND_SET = new Set(COMPUTER_ACTION_KINDS);
|
|
|
67
69
|
export const APP_INDEPENDENT_KINDS = new Set(["list_apps", "list_displays", "cursor_position", "keep_awake", "handoff"]);
|
|
68
70
|
/** File handles need the desktop app's handle store (it sends `resolved.path`); the CLI has none. */
|
|
69
71
|
const NEEDS_FILE_HANDLES = new Set(["open_file", "file_dialog", "save_dialog"]);
|
|
70
|
-
|
|
72
|
+
/** Steps per batch: a whole drawing in one call (raised from 100 on 2026-10-23). */
|
|
73
|
+
export const COMPUTER_MAX_BATCH_STEPS = 5000;
|
|
71
74
|
const DEFAULT_DEADLINE_MS = 15_000;
|
|
72
75
|
const MAX_DEADLINE_MS = 31 * 60_000;
|
|
73
76
|
const PROTOCOL_VERSION = 1;
|
|
@@ -465,6 +468,10 @@ export class HelperProcess {
|
|
|
465
468
|
* Aborts one command (or every one). A command that has not answered `stopped`
|
|
466
469
|
* within the grace period gets the helper killed; it restarts on the next command.
|
|
467
470
|
*/
|
|
471
|
+
/** Releases every key / button the helper holds (helper 1.2.0+; older helpers ignore the op). */
|
|
472
|
+
release() {
|
|
473
|
+
this.send({ op: "release" });
|
|
474
|
+
}
|
|
468
475
|
cancel(target) {
|
|
469
476
|
this.send(target ? { op: "cancel", target } : { op: "cancel" });
|
|
470
477
|
if (!target || !this.child)
|
|
@@ -734,6 +741,11 @@ export function createCliComputerHost(options = {}) {
|
|
|
734
741
|
const forced = !expectFailed && ["stopped", "timeout", "user_interrupted", "screen_locked", "secure_desktop"].includes(code);
|
|
735
742
|
if (onError || forced) {
|
|
736
743
|
const msg = r.error?.message || "";
|
|
744
|
+
// A batch that did not finish leaves nothing pressed (hold_key / mouse down without their up).
|
|
745
|
+
try {
|
|
746
|
+
helper?.release();
|
|
747
|
+
}
|
|
748
|
+
catch { /* best effort */ }
|
|
737
749
|
return { ok: false, kind: "batch", error: { code, message: `Step ${i + 1} failed: ${msg}` }, steps: results, elapsedMs: Date.now() - started };
|
|
738
750
|
}
|
|
739
751
|
}
|
package/dist/connection.js
CHANGED
|
@@ -48,7 +48,7 @@ import { VAULT_HOST_CAPABILITY, VaultHostProcess, VaultRegistry, VaultService, a
|
|
|
48
48
|
// Local REST API); the REST key stays in ~/.melaya-runner/vaults.
|
|
49
49
|
import { ObsidianAppBridge } from "./obsidianApp.js";
|
|
50
50
|
// Desktop app host channel: state changes for the app's tray and web UI (no-op under npx).
|
|
51
|
-
import { hostStatus, isHosted, hostProgress, sendToHost } from "./hostChannel.js";
|
|
51
|
+
import { hostStatus, isHosted, hostProgress, sendToHost, hostAppVersion } from "./hostChannel.js";
|
|
52
52
|
// Desktop app: files this runner wrote are offered to computer control as handles (no-op under npx).
|
|
53
53
|
import { reportHostFile, reportOutputsSince } from "./hostFiles.js";
|
|
54
54
|
// Computer control: computer:command / computer:stop relayed to the desktop app
|
|
@@ -614,6 +614,11 @@ export async function connect(opts) {
|
|
|
614
614
|
deviceName: hostname(),
|
|
615
615
|
platform: process.platform,
|
|
616
616
|
},
|
|
617
|
+
// Hosted by the Melaya desktop app: say so, with the app's version, so
|
|
618
|
+
// the server keeps that computer's app version current on every start
|
|
619
|
+
// (the token row is minted once) and knows this runner updates with the
|
|
620
|
+
// app, never with a restart command.
|
|
621
|
+
...(isHosted() ? { host: { kind: "desktop", ...(hostAppVersion() ? { appVersion: hostAppVersion() } : {}) } } : {}),
|
|
617
622
|
});
|
|
618
623
|
// Index statuses produced while disconnected (or before this socket).
|
|
619
624
|
for (const ev of vaultService.latestStatuses())
|
package/dist/hostChannel.d.ts
CHANGED
|
@@ -83,9 +83,12 @@ export type RunnerToHostMessage = {
|
|
|
83
83
|
/** Mirror of the contract's HostToRunnerMessage (computer messages kept loose). */
|
|
84
84
|
export type HostToRunnerMessage = {
|
|
85
85
|
type: "stop";
|
|
86
|
-
}
|
|
86
|
+
}
|
|
87
|
+
/** `appVersion`: the desktop app's own version (additive; reported in runner:hello's `host` block). */
|
|
88
|
+
| {
|
|
87
89
|
type: "start";
|
|
88
90
|
token: string;
|
|
91
|
+
appVersion?: string;
|
|
89
92
|
}
|
|
90
93
|
/** Additive: rescan model providers now and publish the list through runner:models. */
|
|
91
94
|
| {
|
|
@@ -114,6 +117,9 @@ export declare function redactReason(s: string): string;
|
|
|
114
117
|
export declare function hostStatus(state: HostedRunnerState, lastError?: string, code?: HostedStatusCode): void;
|
|
115
118
|
/** Background setup progress for the desktop app. No-op outside the app. */
|
|
116
119
|
export declare function hostProgress(state: "running" | "done" | "failed", step?: string, waiting?: boolean): void;
|
|
120
|
+
/** The desktop app's own version, as its start message said; null outside the
|
|
121
|
+
* app and with an app older than the field. */
|
|
122
|
+
export declare function hostAppVersion(): string | null;
|
|
117
123
|
/**
|
|
118
124
|
* Wait for the token from the desktop app. Resolves with the token, or rejects
|
|
119
125
|
* when nothing valid arrives within `timeoutMs`.
|
package/dist/hostChannel.js
CHANGED
|
@@ -88,6 +88,12 @@ export function hostProgress(state, step, waiting) {
|
|
|
88
88
|
...(waiting ? { waiting: true } : {}),
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
+
let _hostAppVersion = null;
|
|
92
|
+
/** The desktop app's own version, as its start message said; null outside the
|
|
93
|
+
* app and with an app older than the field. */
|
|
94
|
+
export function hostAppVersion() {
|
|
95
|
+
return _hostAppVersion;
|
|
96
|
+
}
|
|
91
97
|
/**
|
|
92
98
|
* Wait for the token from the desktop app. Resolves with the token, or rejects
|
|
93
99
|
* when nothing valid arrives within `timeoutMs`.
|
|
@@ -102,6 +108,8 @@ export function waitForHostToken(timeoutMs = 30_000) {
|
|
|
102
108
|
const token = msg.token;
|
|
103
109
|
if (typeof token !== "string" || !token.startsWith("mel_run_"))
|
|
104
110
|
return;
|
|
111
|
+
const appVersion = msg.appVersion;
|
|
112
|
+
_hostAppVersion = typeof appVersion === "string" && /^[0-9A-Za-z.+-]{1,32}$/.test(appVersion) ? appVersion : null;
|
|
105
113
|
clearTimeout(timer);
|
|
106
114
|
off();
|
|
107
115
|
resolve(token);
|