@rubytech/create-maxy-code 0.1.47 → 0.1.49
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/__tests__/premium-mcp-discover.test.js +85 -0
- package/dist/index.js +17 -0
- package/dist/lib/premium-mcp-discover.js +34 -0
- package/package.json +1 -1
- package/payload/platform/plugins/docs/references/deployment.md +2 -0
- package/payload/server/public/assets/admin-DBuCWSPS.js +216 -0
- package/payload/server/public/assets/{data-DwQ7ZEyy.js → data-BeblX4m4.js} +1 -1
- package/payload/server/public/assets/{graph-CwZkD6GX.js → graph-ZuBiYril.js} +1 -1
- package/payload/server/public/assets/graph-labels-CnbJR6cp.js +1 -0
- package/payload/server/public/assets/{page-SOCqJGlV.js → page-DDyny08O.js} +2 -2
- package/payload/server/public/assets/{page-CQ7ELqGs.js → page-nAY64ID7.js} +1 -1
- package/payload/server/public/data.html +3 -3
- package/payload/server/public/graph.html +3 -3
- package/payload/server/public/index.html +4 -4
- package/payload/server/public/assets/admin-SyUHjvNs.js +0 -216
- package/payload/server/public/assets/graph-labels-CVkmOHhw.js +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Pure unit tests for the premium-MCP discovery loop. Real tmp dir, no mocks —
|
|
2
|
+
// the discovery function is fs-bound and a mock would just re-state the schema.
|
|
3
|
+
//
|
|
4
|
+
// Tests are ephemeral per the sprint workflow.
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { findPremiumMcpDirs } from "../lib/premium-mcp-discover.js";
|
|
11
|
+
function makeTree(installDir, files) {
|
|
12
|
+
for (const [rel, contents] of Object.entries(files)) {
|
|
13
|
+
const full = join(installDir, rel);
|
|
14
|
+
mkdirSync(join(full, ".."), { recursive: true });
|
|
15
|
+
writeFileSync(full, contents);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
test("findPremiumMcpDirs: returns empty when premium-plugins/ is absent", () => {
|
|
19
|
+
const dir = mkdtempSync(join(tmpdir(), "premium-mcp-"));
|
|
20
|
+
try {
|
|
21
|
+
assert.deepEqual(findPremiumMcpDirs(dir), []);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
rmSync(dir, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
test("findPremiumMcpDirs: discovers loop MCP under real-agent bundle", () => {
|
|
28
|
+
const dir = mkdtempSync(join(tmpdir(), "premium-mcp-"));
|
|
29
|
+
try {
|
|
30
|
+
makeTree(dir, {
|
|
31
|
+
"premium-plugins/real-agent/plugins/loop/mcp/package.json": "{}",
|
|
32
|
+
});
|
|
33
|
+
assert.deepEqual(findPremiumMcpDirs(dir), [
|
|
34
|
+
join(dir, "premium-plugins/real-agent/plugins/loop/mcp"),
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
rmSync(dir, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
test("findPremiumMcpDirs: ignores plugin dir with no mcp/package.json", () => {
|
|
42
|
+
const dir = mkdtempSync(join(tmpdir(), "premium-mcp-"));
|
|
43
|
+
try {
|
|
44
|
+
makeTree(dir, {
|
|
45
|
+
"premium-plugins/real-agent/plugins/loop/mcp/package.json": "{}",
|
|
46
|
+
"premium-plugins/real-agent/plugins/no-mcp/README.md": "noop",
|
|
47
|
+
});
|
|
48
|
+
assert.deepEqual(findPremiumMcpDirs(dir), [
|
|
49
|
+
join(dir, "premium-plugins/real-agent/plugins/loop/mcp"),
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
rmSync(dir, { recursive: true, force: true });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
test("findPremiumMcpDirs: covers multiple bundles and plugins by construction", () => {
|
|
57
|
+
const dir = mkdtempSync(join(tmpdir(), "premium-mcp-"));
|
|
58
|
+
try {
|
|
59
|
+
makeTree(dir, {
|
|
60
|
+
"premium-plugins/real-agent/plugins/loop/mcp/package.json": "{}",
|
|
61
|
+
"premium-plugins/real-agent/plugins/other/mcp/package.json": "{}",
|
|
62
|
+
"premium-plugins/another-bundle/plugins/foo/mcp/package.json": "{}",
|
|
63
|
+
});
|
|
64
|
+
assert.deepEqual(findPremiumMcpDirs(dir), [
|
|
65
|
+
join(dir, "premium-plugins/another-bundle/plugins/foo/mcp"),
|
|
66
|
+
join(dir, "premium-plugins/real-agent/plugins/loop/mcp"),
|
|
67
|
+
join(dir, "premium-plugins/real-agent/plugins/other/mcp"),
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
rmSync(dir, { recursive: true, force: true });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
test("findPremiumMcpDirs: skips bundle missing plugins/ subdir", () => {
|
|
75
|
+
const dir = mkdtempSync(join(tmpdir(), "premium-mcp-"));
|
|
76
|
+
try {
|
|
77
|
+
makeTree(dir, {
|
|
78
|
+
"premium-plugins/empty-bundle/README.md": "noop",
|
|
79
|
+
});
|
|
80
|
+
assert.deepEqual(findPremiumMcpDirs(dir), []);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
rmSync(dir, { recursive: true, force: true });
|
|
84
|
+
}
|
|
85
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { parseSwVers, isSupportedMacosVersion } from "./macos-version.js";
|
|
|
14
14
|
import { decideChromiumAction, isSnapConfinedPath } from "./snap-chromium.js";
|
|
15
15
|
import { classifyPortHolder } from "./preflight-port-classifier.js";
|
|
16
16
|
import { parsePluginList, computeInstallActions, computeConfigureActions, parseExternalPlugins, } from "./lib/plugin-install.js";
|
|
17
|
+
import { findPremiumMcpDirs } from "./lib/premium-mcp-discover.js";
|
|
17
18
|
import { pickLanInterface, mergeSmbConf, formatSambaMarker, } from "./samba-provision.js";
|
|
18
19
|
import { networkInterfaces } from "node:os";
|
|
19
20
|
const PAYLOAD_DIR = resolve(import.meta.dirname, "../payload");
|
|
@@ -2046,6 +2047,22 @@ function buildPlatform() {
|
|
|
2046
2047
|
console.log(` Installing claude-session-manager dependencies (${csmDir})...`);
|
|
2047
2048
|
shellRetry("npm", ["install", "--omit=dev", ...NPM_NET_FLAGS], { cwd: csmDir }, 3, 15);
|
|
2048
2049
|
}
|
|
2050
|
+
// Premium-plugin MCP servers (e.g. real-agent/loop) ship dist/ + package.json
|
|
2051
|
+
// in the payload but no node_modules — npm pack strips them, same reason as
|
|
2052
|
+
// server/. Discover every <installDir>/premium-plugins/<bundle>/plugins/<plugin>/mcp
|
|
2053
|
+
// and install --omit=dev there. dirs=0 in the summary line is itself a signal
|
|
2054
|
+
// when a brand ships premium plugins but the discovery glob is broken.
|
|
2055
|
+
const premiumMcpDirs = findPremiumMcpDirs(INSTALL_DIR);
|
|
2056
|
+
console.log(` [install] premium-mcp-install dirs=${premiumMcpDirs.length}`);
|
|
2057
|
+
for (const mcpDir of premiumMcpDirs) {
|
|
2058
|
+
const mcpNodeModules = join(mcpDir, "node_modules");
|
|
2059
|
+
if (existsSync(mcpNodeModules)) {
|
|
2060
|
+
console.log(` Wiping previous ${mcpDir}/node_modules for a clean reinstall...`);
|
|
2061
|
+
rmSync(mcpNodeModules, { recursive: true, force: true });
|
|
2062
|
+
}
|
|
2063
|
+
console.log(` Installing premium plugin MCP dependencies (${mcpDir})...`);
|
|
2064
|
+
shellRetry("npm", ["install", "--omit=dev", ...NPM_NET_FLAGS], { cwd: mcpDir }, 3, 15);
|
|
2065
|
+
}
|
|
2049
2066
|
}
|
|
2050
2067
|
function setupVncViewer() {
|
|
2051
2068
|
if (!isLinux())
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Pure premium-plugin MCP directory discovery.
|
|
2
|
+
//
|
|
3
|
+
// Schema (exact, two levels under premium-plugins):
|
|
4
|
+
//
|
|
5
|
+
// <installDir>/premium-plugins/<bundle>/plugins/<plugin>/mcp/package.json
|
|
6
|
+
//
|
|
7
|
+
// Recursive walks would match nested dirs that aren't real MCP plugins;
|
|
8
|
+
// the explicit walk eliminates that class of false positive. Each level
|
|
9
|
+
// is gated on isDirectory() before descending, so a stray file at any
|
|
10
|
+
// level is ignored.
|
|
11
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
export function findPremiumMcpDirs(installDir) {
|
|
14
|
+
const root = join(installDir, "premium-plugins");
|
|
15
|
+
if (!existsSync(root))
|
|
16
|
+
return [];
|
|
17
|
+
const out = [];
|
|
18
|
+
for (const bundle of readdirSync(root, { withFileTypes: true })) {
|
|
19
|
+
if (!bundle.isDirectory())
|
|
20
|
+
continue;
|
|
21
|
+
const pluginsRoot = join(root, bundle.name, "plugins");
|
|
22
|
+
if (!existsSync(pluginsRoot))
|
|
23
|
+
continue;
|
|
24
|
+
for (const plugin of readdirSync(pluginsRoot, { withFileTypes: true })) {
|
|
25
|
+
if (!plugin.isDirectory())
|
|
26
|
+
continue;
|
|
27
|
+
const mcpDir = join(pluginsRoot, plugin.name, "mcp");
|
|
28
|
+
if (!existsSync(join(mcpDir, "package.json")))
|
|
29
|
+
continue;
|
|
30
|
+
out.push(mcpDir);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return out.sort();
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -227,6 +227,8 @@ Skills, agents, hooks, and commands directories at the plugin root are auto-disc
|
|
|
227
227
|
|
|
228
228
|
**Diagnostic path** — `grep "\[plugin-install\]" ~/.<brand>/logs/install-*.log | tail -50`; compare row count against `cat brand.json | jq '.externalPlugins | length'` plus the on-disk plugin count under `<INSTALL_DIR>/platform/plugins/` and `<INSTALL_DIR>/premium-plugins/`.
|
|
229
229
|
|
|
230
|
+
**Premium MCP dependency install** — Premium-plugin MCP servers ship `dist/` + `package.json` in the bundle but not `node_modules` (npm pack strips them, same as `server/`). `buildPlatform()` discovers every `<INSTALL_DIR>/premium-plugins/<bundle>/plugins/<plugin>/mcp/package.json` and runs `npm install --omit=dev` there, wiping any prior `node_modules` first. The summary log line `[install] premium-mcp-install dirs=<n>` is emitted before the loop runs, so `dirs=0` is itself a regression signal when a brand ships premium plugins.
|
|
231
|
+
|
|
230
232
|
## Running multiple brands on one device
|
|
231
233
|
|
|
232
234
|
A single Pi or laptop can host more than one brand (for example Maxy and Real Agent) side by side. Each brand runs as its own service on its own port, with its own install directory and its own data. Installing one brand does not touch the other.
|