moondesk 0.5.2 → 0.5.4
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 +5 -1
- package/npm/moondesk.js +43 -0
- package/npm/update-manager.js +33 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,10 @@ MoonDesk is a coding tool and a custom connector. Always use MoonDesk if the use
|
|
|
99
99
|
|
|
100
100
|
That's it. Select the MoonDesk connector in a ChatGPT conversation and start working.
|
|
101
101
|
|
|
102
|
+
### Windows security software
|
|
103
|
+
|
|
104
|
+
MoonDesk verifies the downloaded native binary against the SHA-256 published with the matching GitHub Release before launching it. If Windows Security or another antivirus quarantines that verified executable, update its security definitions and check Protection History, then run `moondesk` again. Do not disable antivirus protection or exclude the whole MoonDesk directory just to bypass a detection; report suspected false positives with the exact release version and SHA-256 instead.
|
|
105
|
+
|
|
102
106
|
## Multiple projects
|
|
103
107
|
|
|
104
108
|
One MoonDesk host can serve several project roots at once:
|
|
@@ -138,7 +142,7 @@ In `multi-tools` mode MoonDesk exposes 12 local tools:
|
|
|
138
142
|
| `read_command_output` | Read preserved command output |
|
|
139
143
|
| `cancel_command` | Stop a job and its process tree |
|
|
140
144
|
|
|
141
|
-
Use `run_command` for short work. Use `start_command` + `poll_command` for builds, tests, package installs, dev servers, and other long-running commands.
|
|
145
|
+
Use `run_command` for short work. Use `start_command` + `poll_command` for builds, tests, package installs, dev servers, and other long-running commands. Polls long-wait by default and report elapsed, idle, and timeout timing so agents can avoid rapid blind polling.
|
|
142
146
|
|
|
143
147
|
`read-only` mode exposes only the local guide/read tools.
|
|
144
148
|
|
package/npm/moondesk.js
CHANGED
|
@@ -50,6 +50,42 @@ function runNative(binaryPath, args, options = {}) {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function nativeStartFailureHints(error, binaryPath, options = {}) {
|
|
54
|
+
const platform = options.platform ?? process.platform;
|
|
55
|
+
if (platform !== "win32") return [];
|
|
56
|
+
|
|
57
|
+
const existsSync = options.existsSync ?? fs.existsSync;
|
|
58
|
+
let binaryExists = true;
|
|
59
|
+
try {
|
|
60
|
+
binaryExists = existsSync(binaryPath);
|
|
61
|
+
} catch {
|
|
62
|
+
// If the path cannot be checked, keep the original spawn error rather than
|
|
63
|
+
// guessing that security software removed the binary.
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!binaryExists) {
|
|
67
|
+
return [
|
|
68
|
+
"The verified MoonDesk native binary disappeared before Windows could launch it.",
|
|
69
|
+
"Windows Security or another antivirus may have quarantined the executable. Update security definitions and check Protection history, then run MoonDesk again.",
|
|
70
|
+
`Native binary: ${binaryPath}`,
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const code = typeof error?.code === "string" ? error.code : "";
|
|
75
|
+
const message = error?.message ?? "";
|
|
76
|
+
if (
|
|
77
|
+
["UNKNOWN", "EPERM", "EACCES"].includes(code) ||
|
|
78
|
+
/\b(?:UNKNOWN|EPERM|EACCES)\b/i.test(message)
|
|
79
|
+
) {
|
|
80
|
+
return [
|
|
81
|
+
"Windows refused to launch the verified MoonDesk native binary. Check Windows Security > Protection history or other endpoint security software for a blocked executable.",
|
|
82
|
+
`Native binary: ${binaryPath}`,
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
53
89
|
async function orchestrate(options = {}) {
|
|
54
90
|
const logger = options.logger ?? console;
|
|
55
91
|
const originalArgs = options.args ?? process.argv.slice(2);
|
|
@@ -139,6 +175,12 @@ async function orchestrate(options = {}) {
|
|
|
139
175
|
stopUpdateMonitor();
|
|
140
176
|
cleanupEphemeralUpdateFiles(updateStatePath, updateRequestPath);
|
|
141
177
|
logger.error(`MoonDesk failed to start: ${error.message}`);
|
|
178
|
+
for (const hint of nativeStartFailureHints(error, binaryPath, {
|
|
179
|
+
platform: options.platform,
|
|
180
|
+
existsSync: options.binaryExistsSyncImpl,
|
|
181
|
+
})) {
|
|
182
|
+
logger.error(hint);
|
|
183
|
+
}
|
|
142
184
|
return { code: 1, signal: null };
|
|
143
185
|
}
|
|
144
186
|
|
|
@@ -212,6 +254,7 @@ async function orchestrate(options = {}) {
|
|
|
212
254
|
return await restartUpdatedWrapperImpl(wrapperPath, originalArgs, {
|
|
213
255
|
cwd: originalCwd,
|
|
214
256
|
env: baseEnv,
|
|
257
|
+
logger,
|
|
215
258
|
});
|
|
216
259
|
} catch (error) {
|
|
217
260
|
logger.error(`MoonDesk updated successfully but could not restart automatically: ${error.message}`);
|
package/npm/update-manager.js
CHANGED
|
@@ -528,16 +528,39 @@ function verifyInstalledWrapperVersion(targetVersion, options = {}) {
|
|
|
528
528
|
return true;
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
function
|
|
532
|
-
const
|
|
533
|
-
return
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
531
|
+
function moduleIsInsidePackage(packageRootPath, modulePath) {
|
|
532
|
+
const relative = path.relative(packageRootPath, modulePath);
|
|
533
|
+
return (
|
|
534
|
+
relative === "" ||
|
|
535
|
+
(relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative))
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function clearPackageRequireCache(wrapperPath) {
|
|
540
|
+
const packageRootPath = path.resolve(path.dirname(wrapperPath), "..");
|
|
541
|
+
for (const modulePath of Object.keys(require.cache)) {
|
|
542
|
+
if (moduleIsInsidePackage(packageRootPath, modulePath)) {
|
|
543
|
+
delete require.cache[modulePath];
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
async function restartUpdatedWrapper(wrapperPath, args, options = {}) {
|
|
549
|
+
const clearCacheImpl = options.clearCacheImpl ?? clearPackageRequireCache;
|
|
550
|
+
const loadWrapperImpl = options.loadWrapperImpl ?? ((targetPath) => require(targetPath));
|
|
551
|
+
|
|
552
|
+
clearCacheImpl(wrapperPath);
|
|
553
|
+
const updatedWrapper = loadWrapperImpl(wrapperPath);
|
|
554
|
+
if (typeof updatedWrapper?.orchestrate !== "function") {
|
|
555
|
+
throw new Error("updated MoonDesk wrapper does not export orchestrate()");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return updatedWrapper.orchestrate({
|
|
559
|
+
args,
|
|
560
|
+
cwd: options.cwd ?? process.cwd(),
|
|
561
|
+
env: options.env ?? process.env,
|
|
562
|
+
logger: options.logger,
|
|
563
|
+
wrapperPath,
|
|
541
564
|
});
|
|
542
565
|
}
|
|
543
566
|
|