mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 03:16:53 +00:00
feat(tui): infer workspace agent when launching TUI (#39591)
Merged via squash.
Prepared head SHA: 23533e24c4
Co-authored-by: arceus77-7 <261276524+arceus77-7@users.noreply.github.com>
Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com>
Reviewed-by: @altaywtf
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveAgentModelFallbackValues } from "../config/model-input.js";
|
||||
@@ -270,6 +271,62 @@ export function resolveAgentWorkspaceDir(cfg: OpenClawConfig, agentId: string) {
|
||||
return stripNullBytes(path.join(stateDir, `workspace-${id}`));
|
||||
}
|
||||
|
||||
function normalizePathForComparison(input: string): string {
|
||||
const resolved = path.resolve(stripNullBytes(resolveUserPath(input)));
|
||||
let normalized = resolved;
|
||||
// Prefer realpath when available to normalize aliases/symlinks (for example /tmp -> /private/tmp)
|
||||
// and canonical path case without forcing case-folding on case-sensitive macOS volumes.
|
||||
try {
|
||||
normalized = fs.realpathSync.native(resolved);
|
||||
} catch {
|
||||
// Keep lexical path for non-existent directories.
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
return normalized.toLowerCase();
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function isPathWithinRoot(candidatePath: string, rootPath: string): boolean {
|
||||
const relative = path.relative(rootPath, candidatePath);
|
||||
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
||||
}
|
||||
|
||||
export function resolveAgentIdsByWorkspacePath(
|
||||
cfg: OpenClawConfig,
|
||||
workspacePath: string,
|
||||
): string[] {
|
||||
const normalizedWorkspacePath = normalizePathForComparison(workspacePath);
|
||||
const ids = listAgentIds(cfg);
|
||||
const matches: Array<{ id: string; workspaceDir: string; order: number }> = [];
|
||||
|
||||
for (let index = 0; index < ids.length; index += 1) {
|
||||
const id = ids[index];
|
||||
const workspaceDir = normalizePathForComparison(resolveAgentWorkspaceDir(cfg, id));
|
||||
if (!isPathWithinRoot(normalizedWorkspacePath, workspaceDir)) {
|
||||
continue;
|
||||
}
|
||||
matches.push({ id, workspaceDir, order: index });
|
||||
}
|
||||
|
||||
matches.sort((left, right) => {
|
||||
const workspaceLengthDelta = right.workspaceDir.length - left.workspaceDir.length;
|
||||
if (workspaceLengthDelta !== 0) {
|
||||
return workspaceLengthDelta;
|
||||
}
|
||||
return left.order - right.order;
|
||||
});
|
||||
|
||||
return matches.map((entry) => entry.id);
|
||||
}
|
||||
|
||||
export function resolveAgentIdByWorkspacePath(
|
||||
cfg: OpenClawConfig,
|
||||
workspacePath: string,
|
||||
): string | undefined {
|
||||
return resolveAgentIdsByWorkspacePath(cfg, workspacePath)[0];
|
||||
}
|
||||
|
||||
export function resolveAgentDir(cfg: OpenClawConfig, agentId: string) {
|
||||
const id = normalizeAgentId(agentId);
|
||||
const configured = resolveAgentConfig(cfg, id)?.agentDir?.trim();
|
||||
|
||||
Reference in New Issue
Block a user