mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
Imports the CodeAtlasWeb companion frontend verbatim from BernhardJackiewicz/CodeAtlasWeb at commit 1825f9c850ac794066e02606012508b9d393c6aa as the new graph-ui and removes the previous React frontend. This is Bernhard Jackiewicz's work, contributed with his agreement and squashed here from his development history (41 commits, cycles W0 through W15). The maintainer only relocates it: every product decision, line of code and test below graph-ui/ is his. The seven galaxy files that originate in this repository's previous graph-ui, and the pinned 3D libraries, are listed in graph-ui/THIRD_PARTY.md. What it is: a local reading IDE on the CBM read surface. A read-only Monaco source reader, a semantic twin that follows the caret, entry, bug-hunt, change-scope and flow reading modes, deterministic source-cited explanations with an optional local-model wording pass (llama-server sidecar, off unless the reader starts one; no model or binary ships), a persistent galaxy with focus following in both directions, a live-agent overlay fed by a loopback bridge, explicit air-gap, provenance and index-limit messaging, and an offline acceptance and browser verification harness. It consumes POST /rpc (the read-only tool allowlist), GET /api/layout, and the atlas routes /api/tree, /api/trace, /api/flows and /api/flow, plus the real ingest_traces store for observed calls; all of these are on feat/atlas-r1 (#1860), which this change stacks on. Not imported: CLAUDE.md (an agent-instruction file, which stays local-only in this repository), and the recorded proof artifacts under graph-ui/verification/, which follow in a separate commit so they can be reviewed and dropped on their own. Build wiring, the dev-proxy port contract, the CSP allowance for the sidecar and bridge ports, and the control surfaces the previous frontend had (project indexing, ADR editor, logs) follow in separate maintainer commits. Design and tracking: #1964. Co-authored-by: Bernhard Jackiewicz <bj@techport.io> Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
82 lines
3.4 KiB
JavaScript
82 lines
3.4 KiB
JavaScript
import { describe, expect, it } from 'vitest';
|
|
import { classifyLine, isLoopbackHost, splitHostPort } from './net-deny-gate.mjs';
|
|
|
|
/*
|
|
* Die Zeilen sind echte Ausgaben von `lsof -a -i -n -P` auf dieser Maschine,
|
|
* woertlich uebernommen. Ohne diese Tests waere "outboundViolations: 0" wertlos:
|
|
* ein Klassifikator, der nie etwas findet, meldet dieselbe Null wie eine saubere
|
|
* Maschine. Hier wird bewiesen, dass er sehr wohl etwas findet.
|
|
*/
|
|
|
|
const LOOPBACK_UDP =
|
|
'postgres 32120 bernhard 10u IPv6 0x833a2aa804e3c858 0t0 UDP [::1]:64649->[::1]:64649';
|
|
const EXTERNAL_TCP =
|
|
'Google 81978 bernhard 30u IPv4 0xe75e15a87b455496 0t0 TCP 192.168.178.32:64257->140.82.121.3:443 (ESTABLISHED)';
|
|
const EXTERNAL_TCP_V6 =
|
|
'sample.ex 3565 bernhard 7u IPv6 0x5917c636b8a90748 0t0 TCP [2a00:1f:9082:3601:3d10:37f5:dd94:87ce]:64021->[2607:6bc0::10]:443 (ESTABLISHED)';
|
|
const LISTEN_LOCAL =
|
|
'mongod 3098 bernhard 9u IPv4 0x1684421c05b3fd5 0t0 TCP 127.0.0.1:27017 (LISTEN)';
|
|
const LISTEN_ANY =
|
|
'ControlCe 652 bernhard 8u IPv4 0x278b381fd868a8bf 0t0 TCP *:7000 (LISTEN)';
|
|
const UDP_UNCONNECTED =
|
|
'sharingd 647 bernhard 4u IPv4 0x9f08eec658eac830 0t0 UDP *:*';
|
|
const LOOPBACK_TCP =
|
|
'node 12345 bernhard 21u IPv4 0x1111111111111111 0t0 TCP 127.0.0.1:53001->127.0.0.1:4200 (ESTABLISHED)';
|
|
|
|
describe('isLoopbackHost', () => {
|
|
it('erkennt die Schreibweisen von localhost', () => {
|
|
for (const host of ['127.0.0.1', '127.0.0.2', 'localhost', '::1', '[::1]', '::ffff:127.0.0.1']) {
|
|
expect(isLoopbackHost(host), host).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('haelt alles andere fuer auswaerts, auch das eigene LAN', () => {
|
|
for (const host of ['192.168.178.32', '10.0.0.1', '140.82.121.3', '[2607:6bc0::10]', '0.0.0.0']) {
|
|
expect(isLoopbackHost(host), host).toBe(false);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('splitHostPort', () => {
|
|
it('trennt IPv4 am letzten Doppelpunkt', () => {
|
|
expect(splitHostPort('140.82.121.3:443')).toEqual({ host: '140.82.121.3', port: '443' });
|
|
});
|
|
|
|
it('haelt die Klammern von IPv6 zusammen', () => {
|
|
expect(splitHostPort('[2607:6bc0::10]:443')).toEqual({ host: '[2607:6bc0::10]', port: '443' });
|
|
});
|
|
});
|
|
|
|
describe('classifyLine', () => {
|
|
it('meldet eine Verbindung nach draussen als nicht loopback', () => {
|
|
const socket = classifyLine(EXTERNAL_TCP);
|
|
expect(socket).not.toBeNull();
|
|
expect(socket.protocol).toBe('TCP');
|
|
expect(socket.remoteHost).toBe('140.82.121.3');
|
|
expect(socket.remotePort).toBe('443');
|
|
expect(socket.loopback).toBe(false);
|
|
expect(socket.pid).toBe(81978);
|
|
});
|
|
|
|
it('meldet auch eine IPv6-Verbindung nach draussen', () => {
|
|
const socket = classifyLine(EXTERNAL_TCP_V6);
|
|
expect(socket.loopback).toBe(false);
|
|
expect(socket.remoteHost).toBe('[2607:6bc0::10]');
|
|
});
|
|
|
|
it('erkennt Loopback-Verbindungen als erlaubt', () => {
|
|
expect(classifyLine(LOOPBACK_TCP).loopback).toBe(true);
|
|
expect(classifyLine(LOOPBACK_UDP).loopback).toBe(true);
|
|
});
|
|
|
|
it('ignoriert lauschende Sockets, die kein Gegenueber haben', () => {
|
|
expect(classifyLine(LISTEN_LOCAL)).toBeNull();
|
|
expect(classifyLine(LISTEN_ANY)).toBeNull();
|
|
expect(classifyLine(UDP_UNCONNECTED)).toBeNull();
|
|
});
|
|
|
|
it('ignoriert die Kopfzeile von lsof', () => {
|
|
expect(classifyLine('COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME')).toBeNull();
|
|
});
|
|
});
|