mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-11 08:42:11 +00:00
Merge branch 'bb/gui' of github.com:NousResearch/hermes-agent into bb/gui
This commit is contained in:
commit
ddf83e95b0
3 changed files with 94 additions and 1 deletions
|
|
@ -4,7 +4,7 @@
|
|||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"sync-assets": "rm -rf public/fonts public/ds-assets && cp -r node_modules/@nous-research/ui/dist/fonts public/fonts && cp -r node_modules/@nous-research/ui/dist/assets public/ds-assets",
|
||||
"sync-assets": "node scripts/sync-assets.cjs",
|
||||
"predev": "npm run sync-assets",
|
||||
"prebuild": "npm run sync-assets",
|
||||
"dev": "vite",
|
||||
|
|
|
|||
46
apps/dashboard/scripts/sync-assets.cjs
Normal file
46
apps/dashboard/scripts/sync-assets.cjs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Copy font and asset folders from @nous-research/ui into public/ for Vite.
|
||||
*
|
||||
* Locates @nous-research/ui by walking up from this script looking for
|
||||
* node_modules/@nous-research/ui — works whether the dep is co-located
|
||||
* (non-workspace layout) or hoisted to the repo root (npm workspaces).
|
||||
*/
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const DASHBOARD_ROOT = path.resolve(__dirname, '..')
|
||||
|
||||
function locateUiPackage() {
|
||||
let dir = DASHBOARD_ROOT
|
||||
const { root } = path.parse(dir)
|
||||
while (true) {
|
||||
const candidate = path.join(dir, 'node_modules', '@nous-research', 'ui')
|
||||
if (fs.existsSync(path.join(candidate, 'package.json'))) {
|
||||
return candidate
|
||||
}
|
||||
if (dir === root) break
|
||||
dir = path.dirname(dir)
|
||||
}
|
||||
throw new Error(
|
||||
'@nous-research/ui not found. Run `npm install` from the repo root.'
|
||||
)
|
||||
}
|
||||
|
||||
const uiRoot = locateUiPackage()
|
||||
const distRoot = path.join(uiRoot, 'dist')
|
||||
|
||||
const mappings = [
|
||||
['fonts', path.join(DASHBOARD_ROOT, 'public', 'fonts')],
|
||||
['assets', path.join(DASHBOARD_ROOT, 'public', 'ds-assets')],
|
||||
]
|
||||
|
||||
for (const [srcName, destPath] of mappings) {
|
||||
const srcPath = path.join(distRoot, srcName)
|
||||
if (!fs.existsSync(srcPath)) {
|
||||
throw new Error(`Missing ${srcPath} in @nous-research/ui — rebuild that package.`)
|
||||
}
|
||||
fs.rmSync(destPath, { recursive: true, force: true })
|
||||
fs.cpSync(srcPath, destPath, { recursive: true })
|
||||
console.log(`synced ${path.relative(DASHBOARD_ROOT, destPath)}`)
|
||||
}
|
||||
|
|
@ -1118,9 +1118,56 @@ function installMediaPermissions() {
|
|||
})
|
||||
}
|
||||
|
||||
function resolveRemoteBackend() {
|
||||
const rawUrl = process.env.HERMES_DESKTOP_REMOTE_URL
|
||||
const rawToken = process.env.HERMES_DESKTOP_REMOTE_TOKEN
|
||||
if (!rawUrl) return null
|
||||
if (!rawToken) {
|
||||
throw new Error(
|
||||
'HERMES_DESKTOP_REMOTE_URL is set but HERMES_DESKTOP_REMOTE_TOKEN is not. ' +
|
||||
'Both must be provided to connect to a remote Hermes backend.'
|
||||
)
|
||||
}
|
||||
|
||||
let parsed
|
||||
try {
|
||||
parsed = new URL(rawUrl)
|
||||
} catch (error) {
|
||||
throw new Error(`HERMES_DESKTOP_REMOTE_URL is not a valid URL: ${error.message}`)
|
||||
}
|
||||
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
||||
throw new Error(`HERMES_DESKTOP_REMOTE_URL must be http:// or https://, got ${parsed.protocol}`)
|
||||
}
|
||||
|
||||
const baseUrl = `${parsed.protocol}//${parsed.host}`
|
||||
const wsScheme = parsed.protocol === 'https:' ? 'wss' : 'ws'
|
||||
const wsUrl = `${wsScheme}://${parsed.host}/api/ws?token=${encodeURIComponent(rawToken)}`
|
||||
|
||||
return { baseUrl, token: rawToken, wsUrl }
|
||||
}
|
||||
|
||||
async function startHermes() {
|
||||
if (connectionPromise) return connectionPromise
|
||||
|
||||
const remote = resolveRemoteBackend()
|
||||
if (remote) {
|
||||
connectionPromise = (async () => {
|
||||
rememberLog(`Using remote Hermes backend at ${remote.baseUrl}`)
|
||||
await waitForHermes(remote.baseUrl, remote.token)
|
||||
return {
|
||||
baseUrl: remote.baseUrl,
|
||||
token: remote.token,
|
||||
wsUrl: remote.wsUrl,
|
||||
logs: hermesLog.slice(-80),
|
||||
windowButtonPosition: getWindowButtonPosition()
|
||||
}
|
||||
})().catch(error => {
|
||||
connectionPromise = null
|
||||
throw error
|
||||
})
|
||||
return connectionPromise
|
||||
}
|
||||
|
||||
connectionPromise = (async () => {
|
||||
const port = await pickPort()
|
||||
const token = crypto.randomBytes(32).toString('base64url')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue