@melaya/runner 1.1.70 → 1.1.72
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/connection.js +6 -1
- package/dist/detect.js +13 -1
- package/dist/hostChannel.d.ts +7 -1
- package/dist/hostChannel.js +8 -0
- package/package.json +1 -1
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/detect.js
CHANGED
|
@@ -111,6 +111,16 @@ async function detectClaudeCode(force = false) {
|
|
|
111
111
|
const names = await fetchClaudeFamilies(oauth.accessToken, force);
|
|
112
112
|
return names.map((name) => ({ provider: "claude_code", name }));
|
|
113
113
|
}
|
|
114
|
+
// The short-lived access token expired but the sign-in is still valid: the
|
|
115
|
+
// CLI only renews it when `claude` runs, and the runtime renews it through
|
|
116
|
+
// the CLI on first use (model.py _refresh_claude_oauth_via_cli). Report the
|
|
117
|
+
// user as signed in (known aliases; no API call with an expired token)
|
|
118
|
+
// instead of "not signed in". Never consume the refresh token here.
|
|
119
|
+
const refreshExpiresAt = Number(oauth.refreshTokenExpiresAt ?? 0);
|
|
120
|
+
if (oauth.accessToken && oauth.refreshToken && (!refreshExpiresAt || Date.now() < refreshExpiresAt)) {
|
|
121
|
+
const cached = networkCacheGet(`claude:${tokenKey(oauth.accessToken)}`, false);
|
|
122
|
+
return (cached ?? CLAUDE_ALIASES_FALLBACK).map((name) => ({ provider: "claude_code", name }));
|
|
123
|
+
}
|
|
114
124
|
}
|
|
115
125
|
catch { /* malformed creds → treat as logged out */ }
|
|
116
126
|
return []; // not logged in / expired → don't advertise models
|
|
@@ -209,8 +219,10 @@ async function detectGithubCopilotWith(gh) {
|
|
|
209
219
|
},
|
|
210
220
|
signal: AbortSignal.timeout(6000),
|
|
211
221
|
});
|
|
222
|
+
// No Copilot seat / revoked token → don't advertise (cached). Anything else
|
|
223
|
+
// (429, 5xx) is transient: null so it is not cached as "not signed in".
|
|
212
224
|
if (!ex.ok)
|
|
213
|
-
return
|
|
225
|
+
return ex.status === 401 || ex.status === 403 || ex.status === 404 ? [] : null;
|
|
214
226
|
const exd = (await ex.json());
|
|
215
227
|
if (!exd.token)
|
|
216
228
|
return [];
|
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);
|