the platform stops knowing what VNC is
Desktop is a plugin as of today, and this is the half that leaves. sidecar/vnc/, api/desktop/ and apps/Desktop/ are gone from src/, along with the vocabulary that was the real problem. sidecar/protocol.ts had a VNC section: vnc:start, vnc:ensure-password, vnc:stop, four reply variants and two types. sidecar-registry.ts had startVnc, ensureVncPassword, stopVnc, isVncConnected. Four functions and a dozen message types in the platform, describing a feature that is not the platform's — the rule CLAUDE.md states most plainly, and its clearest breach. What replaced them is generic. sendSidecarCommand(kind, cmd) and isSidecarConnected(kind) know that a command has a type and an id and that a reply carries the same id. A plugin's sidecar speaks whatever it likes through them and nothing here has to be edited when it adds a message. The desktop PERMISSION leaves too, and that is the interesting part: it was kind: 'execution', a kind a plugin permission cannot have and never will, because a permission nobody can delegate is a contradiction. The plugin expresses the same refusal as ownerOnly: ['/'] — every path under it denied to anyone but the owner. Verified: /api/desktop, /api/desktop/vnc-password and a path that does not exist all resolve owner-only. registry.test.ts records the round trip rather than just dropping the key from its list. Also gone: the app store's `vnc` entry, which would have offered an older second way to install the same thing against a process PM2 no longer has, and four commented-out mounts left from 2026-08-13. The disconnect-scope test used startVnc as its stand-in for "another sidecar's long-running request". It now uses the generic door, which is the better instrument — that file is about the blast radius of a disconnect and never had anything to do with VNC. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,7 +111,7 @@ describe('member provisioning is declared for every entry', () => {
|
||||
// against an API that does not exist. Transmission was an example until 2026-08-18 and slskd until
|
||||
// 2026-08-19, when they became `plugins/transmission/` and `plugins/soulseek/` — hence the list
|
||||
// rather than a single id: it must stay non-empty, or this assertion passes by iterating nothing.
|
||||
for (const id of ['vnc', 'notify']) expect(byId(id)!.members).toBe('none');
|
||||
for (const id of ['notify']) expect(byId(id)!.members).toBe('none');
|
||||
});
|
||||
|
||||
// A test asserting the vault is invite-only lived here until 2026-08-18, when it left to become
|
||||
|
||||
@@ -239,20 +239,9 @@ export const CATALOGUE: CatalogueEntry[] = [
|
||||
permission: 'notify',
|
||||
configFields: [],
|
||||
},
|
||||
{
|
||||
id: 'vnc',
|
||||
ui: { name: 'Desktop', icon: 'MonitorSmartphone', color: '#ec4899', rootRoute: '/desktop', routes: ['/desktop'] },
|
||||
process: 'officer-vnc',
|
||||
label: 'Desktop',
|
||||
summary: 'Mirror this machine’s display in the browser',
|
||||
members: 'none',
|
||||
modes: ['config'],
|
||||
permission: 'desktop',
|
||||
// x11vnc against an Xorg display. There is nothing to mirror on a headless box or on macOS, so the
|
||||
// store should say so rather than install something that starts and immediately fails.
|
||||
requires: 'linux-display',
|
||||
configFields: [],
|
||||
},
|
||||
// The `vnc` entry left with the desktop plugin on 2026-08-21. The app store predates the marketplace,
|
||||
// and a plugin is installed through that now — an entry here would offer a second, older way to install
|
||||
// the same thing, against a process PM2 no longer has.
|
||||
];
|
||||
|
||||
export const byId = (id: string): CatalogueEntry | undefined => CATALOGUE.find((e) => e.id === id);
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('what adding a member would do', () => {
|
||||
it('predicts the outcome per service without contacting anything', () => {
|
||||
expect(plannedOutcome(byId('memos')!)).toBe('provisioned');
|
||||
expect(plannedOutcome(inviteOnly)).toBe('invited');
|
||||
expect(plannedOutcome(byId('vnc')!)).toBe('not-applicable');
|
||||
expect(plannedOutcome(byId('notify')!)).toBe('not-applicable');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('which installed services have work to do', () => {
|
||||
// two. It has been re-pointed five times as services left — jellyfin, invoiceshelf and slskd to
|
||||
// `plugins/`, caldav to CORE — and memos is the last one standing. If memos ever leaves too, this
|
||||
// wants a literal fixture like `installer.test.ts` has, not a sixth re-point.
|
||||
const ids = servicesNeedingMemberProvision(['memos', 'vnc']).map((e) => e.id);
|
||||
const ids = servicesNeedingMemberProvision(['memos', 'notify']).map((e) => e.id);
|
||||
expect(ids.sort()).toEqual(['memos']);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user