Compare commits
5 Commits
fix/drop-w
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 06ccd3564e | |||
| 2977ab369e | |||
| c8998c6b0d | |||
| 686f2c7cb0 | |||
| 81d40ae63d |
@@ -128,7 +128,9 @@ function register(api: PluginAPI): void {
|
||||
/** Resolve agent ID from env, config, or fallback. */
|
||||
function resolveAgentId(): string {
|
||||
if (process.env.AGENT_ID) return process.env.AGENT_ID;
|
||||
const cfg = api.runtime?.config?.loadConfig?.();
|
||||
// Read from cached `api.config` first — see pushMetaToMonitor for why
|
||||
// the deprecated `api.runtime?.config?.loadConfig?.()` path is heavy.
|
||||
const cfg = (api as any).config ?? api.runtime?.config?.loadConfig?.();
|
||||
return cfg?.agents?.list?.[0]?.id ?? cfg?.agents?.defaults?.id ?? 'unknown';
|
||||
}
|
||||
|
||||
@@ -184,6 +186,25 @@ function register(api: PluginAPI): void {
|
||||
* Push OpenClaw metadata to the Monitor bridge.
|
||||
* This enriches Monitor heartbeats with OpenClaw version/plugin/agent info.
|
||||
* Failures are non-fatal — Monitor continues to work without this data.
|
||||
*
|
||||
* IMPORTANT — read config from the cached `api.config` surface, NOT from
|
||||
* the deprecated `api.runtime?.config?.loadConfig?.()` path. The
|
||||
* deprecated path triggers a full plugin-metadata-snapshot rebuild on
|
||||
* every call: realpathSync walks every plugin's package.json + manifest
|
||||
* + source paths (lstats up the directory tree), `hashWatchedFiles`
|
||||
* fingerprints all watched plugin files, and `discoverInDirectory`
|
||||
* re-scans every `dist/extensions/<plugin>` dir. On t2 with ~100 plugins
|
||||
* each rebuild costs ~6-7s of CPU; with this push firing every 30s
|
||||
* (default reportIntervalSec) the chronic baseline was ~22-25% gateway
|
||||
* CPU even with zero agent activity (V8 profile 2026-05-27 08:14:00 60s:
|
||||
* lstat 44.2%, statSync 6.9%, hashWatchedFiles via memo key 1.7%, all
|
||||
* routed through readPersistedInstalledPluginIndexInstallRecordsSync ->
|
||||
* discoverInDirectory). Switching to `api.config` reads from the
|
||||
* already-loaded snapshot cache; the elsewhere-in-this-file pattern was
|
||||
* already `api.config ?? api.runtime?.config?.loadConfig?.()`.
|
||||
*
|
||||
* Same fix is applied to `resolveAgentId` below — that's read once at
|
||||
* gateway start so the impact is smaller, but it's the same anti-pattern.
|
||||
*/
|
||||
async function pushMetaToMonitor() {
|
||||
const bridgeClient = getBridgeClient();
|
||||
@@ -191,7 +212,7 @@ function register(api: PluginAPI): void {
|
||||
|
||||
let agentNames: string[] = [];
|
||||
try {
|
||||
const cfg = api.runtime?.config?.loadConfig?.();
|
||||
const cfg = (api as any).config ?? api.runtime?.config?.loadConfig?.();
|
||||
const agentsList = cfg?.agents?.list;
|
||||
if (Array.isArray(agentsList)) {
|
||||
agentNames = agentsList
|
||||
|
||||
@@ -31,6 +31,7 @@ const OLD_PLUGIN_NAME = 'harborforge-monitor';
|
||||
const PLUGIN_SRC_DIR = join(__dirname, 'plugin');
|
||||
const SKILLS_SRC_DIR = join(__dirname, 'skills');
|
||||
const MONITOR_REPO_URL = 'https://git.hangman-lab.top/zhi/HarborForge.Monitor.git';
|
||||
const CLI_REPO_URL = 'https://git.hangman-lab.top/zhi/HarborForge.Cli.git';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const options = {
|
||||
@@ -43,6 +44,7 @@ const options = {
|
||||
installCli: args.includes('--install-cli'),
|
||||
installMonitor: 'no',
|
||||
monitorBranch: 'main',
|
||||
cliBranch: 'main',
|
||||
};
|
||||
|
||||
const profileIdx = args.indexOf('--openclaw-profile-path');
|
||||
@@ -60,6 +62,11 @@ if (monitorBranchIdx !== -1 && args[monitorBranchIdx + 1]) {
|
||||
options.monitorBranch = String(args[monitorBranchIdx + 1]);
|
||||
}
|
||||
|
||||
const cliBranchIdx = args.indexOf('--cli-branch');
|
||||
if (cliBranchIdx !== -1 && args[cliBranchIdx + 1]) {
|
||||
options.cliBranch = String(args[cliBranchIdx + 1]);
|
||||
}
|
||||
|
||||
function resolveOpenclawPath() {
|
||||
if (options.openclawProfilePath) return options.openclawProfilePath;
|
||||
if (process.env.OPENCLAW_PATH) return resolve(process.env.OPENCLAW_PATH);
|
||||
@@ -321,34 +328,35 @@ async function installCli() {
|
||||
const binDir = join(openclawPath, 'bin');
|
||||
mkdirSync(binDir, { recursive: true });
|
||||
|
||||
// Find CLI source — look for HarborForge.Cli relative to project root
|
||||
const projectRoot = resolve(__dirname, '..');
|
||||
const cliDir = join(projectRoot, 'HarborForge.Cli');
|
||||
|
||||
if (!existsSync(cliDir)) {
|
||||
// Try parent directory (monorepo layout)
|
||||
const monoCliDir = resolve(projectRoot, '..', 'HarborForge.Cli');
|
||||
if (!existsSync(monoCliDir)) {
|
||||
logErr(`Cannot find HarborForge.Cli at ${cliDir} or ${monoCliDir}`);
|
||||
logWarn('Skipping CLI installation');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const effectiveCliDir = existsSync(cliDir)
|
||||
? cliDir
|
||||
: resolve(projectRoot, '..', 'HarborForge.Cli');
|
||||
|
||||
log(` Building hf from ${effectiveCliDir}...`, 'blue');
|
||||
// Clone CLI repo to /tmp, build there, copy artifact out. Mirrors
|
||||
// installManagedMonitor so the install never depends on a checked-out
|
||||
// sibling repo at a fixed path.
|
||||
const tmpDir = join('/tmp', `harborforge-cli-${Date.now()}`);
|
||||
const hfBinary = join(binDir, 'hf');
|
||||
|
||||
try {
|
||||
const hfBinary = join(binDir, 'hf');
|
||||
exec(`go build -o ${hfBinary} ./cmd/hf`, { cwd: effectiveCliDir, silent: !options.verbose });
|
||||
log(` Cloning ${CLI_REPO_URL} (branch ${options.cliBranch}) → ${tmpDir}...`, 'blue');
|
||||
exec(`git clone --branch ${shellEscape(options.cliBranch)} --depth 1 ${shellEscape(CLI_REPO_URL)} ${shellEscape(tmpDir)}`, { silent: !options.verbose });
|
||||
|
||||
// Stamp the binary with the version string the prod CLI surfaces in
|
||||
// `hf version`. Fall back to a date-only label if rev-parse fails for
|
||||
// any reason (shallow clone shouldn't, but be defensive).
|
||||
let versionLabel = `${new Date().toISOString().slice(0, 10)}+install`;
|
||||
try {
|
||||
const sha = exec(`git rev-parse --short HEAD`, { cwd: tmpDir, silent: true }).trim();
|
||||
if (sha) versionLabel = `${new Date().toISOString().slice(0, 10)}+${options.cliBranch}-${sha}`;
|
||||
} catch { /* keep fallback */ }
|
||||
|
||||
log(` Building hf (version=${versionLabel})...`, 'blue');
|
||||
const ldflags = `-X git.hangman-lab.top/zhi/HarborForge.Cli/internal/commands.Version=${versionLabel}`;
|
||||
exec(`go build -ldflags ${shellEscape(ldflags)} -o ${shellEscape(hfBinary)} ./cmd/hf`, { cwd: tmpDir, silent: !options.verbose });
|
||||
chmodSync(hfBinary, 0o755);
|
||||
logOk(`hf binary → ${hfBinary}`);
|
||||
logOk(`hf binary → ${hfBinary} (branch hint: ${options.cliBranch})`);
|
||||
} catch (err) {
|
||||
logErr(`Failed to build hf CLI: ${err.message}`);
|
||||
logWarn('CLI installation failed, plugin still installed');
|
||||
} finally {
|
||||
rmSync(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user