mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-07-10 02:30:15 +00:00
142 lines
4.4 KiB
TypeScript
142 lines
4.4 KiB
TypeScript
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
|
|
import { tmpdir } from 'os'
|
|
import { join } from 'path'
|
|
import YAML from 'js-yaml'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
describe('Hermes plugin configuration', () => {
|
|
const originalEnv = { ...process.env }
|
|
let tempDir = ''
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules()
|
|
tempDir = mkdtempSync(join(tmpdir(), 'hermes-plugins-config-'))
|
|
process.env = { ...originalEnv }
|
|
process.env.HERMES_HOME = join(tempDir, 'home')
|
|
installFakeHermes()
|
|
})
|
|
|
|
afterEach(() => {
|
|
process.env = { ...originalEnv }
|
|
if (tempDir) rmSync(tempDir, { recursive: true, force: true })
|
|
})
|
|
|
|
function installFakeHermes() {
|
|
const agentRoot = join(tempDir, 'agent')
|
|
const venvBin = join(agentRoot, '.venv', 'bin')
|
|
const hermesCliDir = join(agentRoot, 'hermes_cli')
|
|
const fakePython = join(venvBin, 'python')
|
|
const fakeHermes = join(venvBin, 'hermes')
|
|
|
|
mkdirSync(venvBin, { recursive: true })
|
|
mkdirSync(hermesCliDir, { recursive: true })
|
|
writeFileSync(join(agentRoot, 'run_agent.py'), '')
|
|
writeFileSync(join(hermesCliDir, 'plugins.py'), '')
|
|
writeFileSync(fakePython, [
|
|
'#!/bin/sh',
|
|
'printf "%s\\n" "$PLUGIN_JSON"',
|
|
'',
|
|
].join('\n'))
|
|
chmodSync(fakePython, 0o755)
|
|
writeFileSync(fakeHermes, `#!${fakePython}\n`)
|
|
chmodSync(fakeHermes, 0o755)
|
|
|
|
process.env.HERMES_BIN = fakeHermes
|
|
process.env.PLUGIN_JSON = JSON.stringify({
|
|
plugins: [{
|
|
key: 'local-plugin',
|
|
name: 'local-plugin',
|
|
kind: 'standalone',
|
|
source: 'user',
|
|
configStatus: 'not-enabled',
|
|
effectiveStatus: 'inactive',
|
|
version: '',
|
|
description: '',
|
|
author: '',
|
|
path: join(process.env.HERMES_HOME!, 'plugins', 'local-plugin'),
|
|
providesTools: [],
|
|
providesHooks: [],
|
|
requiresEnv: [],
|
|
}],
|
|
warnings: [],
|
|
metadata: {
|
|
hermesAgentRoot: agentRoot,
|
|
pythonExecutable: fakePython,
|
|
cwd: process.cwd(),
|
|
projectPluginsEnabled: false,
|
|
},
|
|
})
|
|
}
|
|
|
|
function readConfig() {
|
|
return YAML.load(readFileSync(join(process.env.HERMES_HOME!, 'config.yaml'), 'utf-8')) as any
|
|
}
|
|
|
|
it('enables standalone user plugins in the active profile config', async () => {
|
|
mkdirSync(process.env.HERMES_HOME!, { recursive: true })
|
|
writeFileSync(join(process.env.HERMES_HOME!, 'config.yaml'), [
|
|
'plugins:',
|
|
' disabled:',
|
|
' - local-plugin',
|
|
'',
|
|
].join('\n'))
|
|
|
|
const { setHermesPluginEnabled } = await import('../../packages/server/src/services/hermes/plugins')
|
|
await expect(setHermesPluginEnabled(undefined, 'local-plugin', true)).resolves.toEqual({
|
|
key: 'local-plugin',
|
|
enabled: true,
|
|
})
|
|
|
|
expect(readConfig().plugins).toEqual({
|
|
enabled: ['local-plugin'],
|
|
disabled: [],
|
|
})
|
|
})
|
|
|
|
it('disables standalone user plugins in the active profile config', async () => {
|
|
mkdirSync(process.env.HERMES_HOME!, { recursive: true })
|
|
writeFileSync(join(process.env.HERMES_HOME!, 'config.yaml'), [
|
|
'plugins:',
|
|
' enabled:',
|
|
' - local-plugin',
|
|
'',
|
|
].join('\n'))
|
|
|
|
const { setHermesPluginEnabled } = await import('../../packages/server/src/services/hermes/plugins')
|
|
await expect(setHermesPluginEnabled(undefined, 'local-plugin', false)).resolves.toEqual({
|
|
key: 'local-plugin',
|
|
enabled: false,
|
|
})
|
|
|
|
expect(readConfig().plugins).toEqual({
|
|
enabled: [],
|
|
disabled: ['local-plugin'],
|
|
})
|
|
})
|
|
|
|
it('rejects bundled plugins because they are managed by Hermes Agent', async () => {
|
|
process.env.PLUGIN_JSON = JSON.stringify({
|
|
plugins: [{
|
|
key: 'bundled-plugin',
|
|
name: 'bundled-plugin',
|
|
kind: 'standalone',
|
|
source: 'bundled',
|
|
configStatus: 'auto',
|
|
effectiveStatus: 'auto-active',
|
|
version: '',
|
|
description: '',
|
|
author: '',
|
|
path: '',
|
|
providesTools: [],
|
|
providesHooks: [],
|
|
requiresEnv: [],
|
|
}],
|
|
warnings: [],
|
|
metadata: { hermesAgentRoot: '', pythonExecutable: '', cwd: '', projectPluginsEnabled: false },
|
|
})
|
|
|
|
const { setHermesPluginEnabled } = await import('../../packages/server/src/services/hermes/plugins')
|
|
await expect(setHermesPluginEnabled(undefined, 'bundled-plugin', false)).rejects.toThrow('cannot be managed')
|
|
})
|
|
})
|