mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
Load the God's Eye View panel through the MCP server
Hosts serve panels from their own sites and may refuse other addresses; Codex refuses any address on the user's machine. The panel now never requests the app's server: it loads the app's panel build and data through panel_request, a tool only the panel may call, which requests the path from the app's server. One path in every host; only map providers load directly. npm run build:panel writes the panel build to dist/panel, served at /panel/: one app script, one stylesheet, Cesium's script, and Cesium's workers as one script Cesium runs from memory. Tools may now be marked app-only. The panel CORS rules are gone.
This commit is contained in:
1 parent
b11d54d8b8
commit
996b95eb45
20 files changed
+1265
-437
No files matched your search
@@ -0,0 +1,82 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import test from 'node:test';
|
||||
import * as PANEL_PATHS from '../tools/globePanel.js';
|
||||
import {
|
||||
PANEL_BASE,
|
||||
PANEL_WORKERS_PATH,
|
||||
panelBuildConfig,
|
||||
panelBuildPlugin,
|
||||
workersEntrySource,
|
||||
} from '../../build/panel.js';
|
||||
|
||||
test('the panel loads the paths the panel build writes', () => {
|
||||
assert.equal(PANEL_BASE, PANEL_PATHS.PANEL_BASE);
|
||||
assert.equal(PANEL_WORKERS_PATH, PANEL_PATHS.PANEL_WORKERS_PATH);
|
||||
});
|
||||
|
||||
test('the panel build is one script and one stylesheet under /panel/', () => {
|
||||
const config = panelBuildConfig({
|
||||
plugins: [],
|
||||
build: { chunkSizeWarningLimit: 1500 },
|
||||
});
|
||||
assert.equal(config.base, PANEL_BASE);
|
||||
assert.equal(config.build.outDir, 'dist/panel');
|
||||
assert.equal(config.build.cssCodeSplit, false);
|
||||
assert.equal(config.build.rollupOptions.output.inlineDynamicImports, true);
|
||||
assert.equal(config.build.chunkSizeWarningLimit, 1500);
|
||||
});
|
||||
|
||||
test("Cesium's workers load lazily from one script", () => {
|
||||
const source = workersEntrySource(['createGeometry', 'decodeDraco'], '/w');
|
||||
assert.match(source, /^self\.CesiumWorkers = \{/);
|
||||
assert.match(
|
||||
source,
|
||||
/"createGeometry": \(\) => import\("\/w\/createGeometry\.js"\)/,
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/"decodeDraco": \(\) => import\("\/w\/decodeDraco\.js"\)/,
|
||||
);
|
||||
});
|
||||
|
||||
test('the dev server serves the panel build and nothing outside it', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'panel-build-'));
|
||||
try {
|
||||
await mkdir(join(root, 'out', 'assets'), { recursive: true });
|
||||
await writeFile(join(root, 'out', 'index.html'), '<p>panel</p>');
|
||||
await writeFile(join(root, 'out', 'assets', 'a.js'), 'x');
|
||||
await writeFile(join(root, 'secret.txt'), 'secret');
|
||||
let middleware;
|
||||
panelBuildPlugin({ outDir: 'out' }).configureServer({
|
||||
config: { root },
|
||||
middlewares: { use: (fn) => (middleware = fn) },
|
||||
});
|
||||
const get = (url) =>
|
||||
new Promise((resolve) => {
|
||||
const res = {
|
||||
statusCode: 200,
|
||||
headers: {},
|
||||
setHeader(name, value) {
|
||||
this.headers[name] = value;
|
||||
},
|
||||
end(body) {
|
||||
resolve({ status: this.statusCode, headers: this.headers, body });
|
||||
},
|
||||
};
|
||||
middleware({ url }, res, () => resolve({ passed: true }));
|
||||
});
|
||||
const page = await get('/panel/');
|
||||
assert.equal(String(page.body), '<p>panel</p>');
|
||||
assert.equal(page.headers['Content-Type'], 'text/html');
|
||||
const script = await get('/panel/assets/a.js');
|
||||
assert.equal(script.headers['Content-Type'], 'text/javascript');
|
||||
assert.equal((await get('/panel/missing.js')).status, 404);
|
||||
assert.deepEqual(await get('/panel/..%2Fsecret.txt'), { passed: true });
|
||||
assert.deepEqual(await get('/other'), { passed: true });
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
@@ -12,8 +12,7 @@ test('explicit build inputs preserve browser-only defines, plugin order and loop
|
||||
googleApiKey: 'browser-fixture',
|
||||
cesiumToken: 'ion-fixture',
|
||||
});
|
||||
assert.equal(config.plugins[0].name, 'panel-cors');
|
||||
assert.equal(config.plugins[3], plugin);
|
||||
assert.equal(config.plugins[2], plugin);
|
||||
assert.equal(config.server.host, 'localhost');
|
||||
assert.equal(config.server.port, 4173);
|
||||
assert.deepEqual(config.server.allowedHosts, [
|
||||
@@ -43,45 +42,6 @@ test('explicit build inputs preserve browser-only defines, plugin order and loop
|
||||
);
|
||||
});
|
||||
|
||||
test('panel origins may read every dev server path, other sites may not', () => {
|
||||
let middleware;
|
||||
createBrowserViteConfig().plugins[0].configureServer({
|
||||
middlewares: { use: (fn) => (middleware = fn) },
|
||||
});
|
||||
const request = (origin, method = 'GET') => {
|
||||
const headers = {};
|
||||
let ended = false;
|
||||
let passed = false;
|
||||
middleware(
|
||||
{ method, headers: origin ? { origin } : {} },
|
||||
{
|
||||
setHeader: (name, value) => (headers[name] = value),
|
||||
end: () => (ended = true),
|
||||
},
|
||||
() => (passed = true),
|
||||
);
|
||||
return { headers, ended, passed };
|
||||
};
|
||||
const panel = request('https://abc123.claudemcpcontent.com');
|
||||
assert.equal(
|
||||
panel.headers['Access-Control-Allow-Origin'],
|
||||
'https://abc123.claudemcpcontent.com',
|
||||
);
|
||||
assert.equal(panel.passed, true);
|
||||
assert.equal(
|
||||
request('https://abc123.claudemcpcontent.com', 'OPTIONS').ended,
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
request('codex-sandbox://mcp-app-ab12.web-sandbox.oaiusercontent.com')
|
||||
.headers['Access-Control-Allow-Origin'],
|
||||
'codex-sandbox://mcp-app-ab12.web-sandbox.oaiusercontent.com',
|
||||
);
|
||||
const other = request('https://example.com');
|
||||
assert.deepEqual(other.headers, {});
|
||||
assert.equal(other.passed, true);
|
||||
});
|
||||
|
||||
test('build helper does not discover environment values or construct local providers', () => {
|
||||
const before = process.env.GOOGLE_MAPS_API_KEY;
|
||||
process.env.GOOGLE_MAPS_API_KEY = 'environment-fixture';
|
||||
@@ -92,8 +52,8 @@ test('build helper does not discover environment values or construct local provi
|
||||
undefined,
|
||||
);
|
||||
assert.deepEqual(
|
||||
config.plugins.slice(3).map((plugin) => plugin.name),
|
||||
['embed-framing'],
|
||||
config.plugins.slice(2).map((plugin) => plugin.name),
|
||||
['embed-framing', 'panel-build'],
|
||||
);
|
||||
} finally {
|
||||
if (before === undefined) delete process.env.GOOGLE_MAPS_API_KEY;
|
||||
@@ -106,14 +66,15 @@ test('root config retains existing named exports and standalone provider order',
|
||||
assert.equal(compatibility[name], value, name);
|
||||
const config = standaloneConfig({ mode: 'test' });
|
||||
assert.deepEqual(
|
||||
config.plugins.slice(3, -3).map((plugin) => plugin.name),
|
||||
config.plugins.slice(2, -4).map((plugin) => plugin.name),
|
||||
providers.localProviderPlugins().map((plugin) => plugin.name),
|
||||
);
|
||||
assert.equal(config.plugins.at(-4).name, 'gev-key-setup');
|
||||
assert.equal(config.plugins.at(-5).name, 'gev-key-setup');
|
||||
// The local MCP route follows every provider and precedes the API fallback.
|
||||
assert.equal(config.plugins.at(-3).name, 'local-mcp');
|
||||
assert.equal(config.plugins.at(-2).name, 'api-not-found');
|
||||
assert.equal(config.plugins.at(-1).name, 'embed-framing');
|
||||
assert.equal(config.plugins.at(-4).name, 'local-mcp');
|
||||
assert.equal(config.plugins.at(-3).name, 'api-not-found');
|
||||
assert.equal(config.plugins.at(-2).name, 'embed-framing');
|
||||
assert.equal(config.plugins.at(-1).name, 'panel-build');
|
||||
});
|
||||
|
||||
test('build export resolves in Node and has no browser fallback', async () => {
|
||||
|
||||
Reference in new issue
Block a user