mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Follow-ups on top of #66911's salvaged commit: - hermes:fs:desktopPluginsRoot now resolves the ACTIVE desktop profile (readActiveDesktopProfile) so named profiles keep their own profiles/<name>/desktop-plugins root instead of sharing the global one (profile-scope concern raised on the PR thread). - startDirWatch in runtime-loader.ts was a third sibling site still deriving the watch path from the backend's hermes_home (added by the later fs-watch commit); routed through the same Electron-local resolver, with regression coverage.
77 lines
2.8 KiB
TypeScript
77 lines
2.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import type { HermesReadDirResult } from '@/global'
|
|
import type * as HermesModule from '@/hermes'
|
|
|
|
import { discoverRuntimePlugins, watchRuntimePlugins } from './runtime-loader'
|
|
|
|
// getStatus would supply the connected backend's hermes_home — a REMOTE path in
|
|
// remote mode. The disk scanner must NOT derive the plugin root from it (#66899).
|
|
const getStatus = vi.fn(async () => ({ hermes_home: '/remote/box/.hermes' }))
|
|
|
|
vi.mock('@/hermes', async importActual => ({
|
|
...(await importActual<typeof HermesModule>()),
|
|
getStatus: () => getStatus()
|
|
}))
|
|
|
|
const desktopPluginsRoot = vi.fn<() => Promise<string>>()
|
|
const readDir = vi.fn<(path: string) => Promise<HermesReadDirResult>>()
|
|
const watchDirectory = vi.fn<(path: string) => Promise<{ id: string }>>()
|
|
const onPreviewFileChanged = vi.fn()
|
|
|
|
beforeEach(() => {
|
|
desktopPluginsRoot.mockReset()
|
|
readDir.mockReset()
|
|
watchDirectory.mockReset()
|
|
onPreviewFileChanged.mockReset()
|
|
getStatus.mockClear()
|
|
;(window as unknown as { hermesDesktop: unknown }).hermesDesktop = {
|
|
desktopPluginsRoot,
|
|
onPreviewFileChanged,
|
|
readDir,
|
|
watchDirectory
|
|
}
|
|
})
|
|
|
|
afterEach(() => {
|
|
delete (window as unknown as { hermesDesktop?: unknown }).hermesDesktop
|
|
})
|
|
|
|
describe('scanDiskPlugins (#66899)', () => {
|
|
it('scans the Electron-resolved local root, never the backend hermes_home', async () => {
|
|
desktopPluginsRoot.mockResolvedValue('/local/.hermes/desktop-plugins')
|
|
readDir.mockResolvedValue({ entries: [] })
|
|
|
|
await discoverRuntimePlugins()
|
|
|
|
expect(desktopPluginsRoot).toHaveBeenCalled()
|
|
expect(readDir).toHaveBeenCalledWith('/local/.hermes/desktop-plugins')
|
|
// The remote backend's hermes_home must never feed the local plugin scan.
|
|
expect(getStatus).not.toHaveBeenCalled()
|
|
expect(readDir).not.toHaveBeenCalledWith('/remote/box/.hermes/desktop-plugins')
|
|
})
|
|
|
|
it('no-ops when the resolver yields no local root', async () => {
|
|
desktopPluginsRoot.mockResolvedValue('')
|
|
|
|
await discoverRuntimePlugins()
|
|
|
|
expect(readDir).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('watchRuntimePlugins dir watch (#66899)', () => {
|
|
it('watches the Electron-resolved local root, never the backend hermes_home', async () => {
|
|
desktopPluginsRoot.mockResolvedValue('/local/.hermes/desktop-plugins')
|
|
readDir.mockResolvedValue({ entries: [] })
|
|
watchDirectory.mockResolvedValue({ id: 'watch-1' })
|
|
|
|
watchRuntimePlugins()
|
|
// Drain the async scan + startDirWatch chains.
|
|
await vi.waitFor(() => expect(watchDirectory).toHaveBeenCalled())
|
|
|
|
expect(watchDirectory).toHaveBeenCalledWith('/local/.hermes/desktop-plugins')
|
|
expect(watchDirectory).not.toHaveBeenCalledWith('/remote/box/.hermes/desktop-plugins')
|
|
expect(getStatus).not.toHaveBeenCalled()
|
|
})
|
|
})
|