Merge pull request #569 from bjesuiter/ui-build-default-to-relative-path

fix(ui): default to relative paths for control UI assets
This commit is contained in:
Peter Steinberger
2026-01-09 14:47:46 +00:00
committed by GitHub
7 changed files with 58 additions and 3 deletions

View File

@@ -16,7 +16,7 @@ jobs:
command: pnpm lint
- runtime: node
task: test
command: pnpm test
command: node scripts/ci-sanitize-output.mjs pnpm test
- runtime: node
task: build
command: pnpm build
@@ -104,7 +104,7 @@ jobs:
command: pnpm lint
- runtime: node
task: test
command: pnpm test
command: node scripts/ci-sanitize-output.mjs pnpm test
- runtime: node
task: build
command: pnpm build

View File

@@ -45,6 +45,7 @@
- WhatsApp: group `/model list` output by provider for scannability. (#456) - thanks @mcinteerj
- Hooks: allow per-hook model overrides for webhook/Gmail runs (e.g. GPT 5 Mini).
- Control UI: logs tab opens at the newest entries (bottom).
- Control UI: default to relative paths for control UI assets. (#569) — thanks @bjesuiter
- Control UI: add Docs link, remove chat composer divider, and add New session button.
- Control UI: link sessions list to chat view. (#471) — thanks @HazAT
- Sessions: support session `label` in store/list/UI and allow `sessions_send` lookup by label. (#570) — thanks @azade-c

View File

@@ -0,0 +1,37 @@
import { spawn } from "node:child_process";
function sanitizeBuffer(input) {
const out = Buffer.allocUnsafe(input.length);
for (let i = 0; i < input.length; i++) {
const b = input[i];
// Keep: tab/newline/carriage return + printable ASCII; replace everything else.
out[i] = b === 9 || b === 10 || b === 13 || (b >= 32 && b <= 126) ? b : 63;
}
return out;
}
const [command, ...args] = process.argv.slice(2);
if (!command) {
process.stderr.write(
"Usage: node scripts/ci-sanitize-output.mjs <cmd> [args...]\n",
);
process.exit(2);
}
const child = spawn(command, args, {
stdio: ["ignore", "pipe", "pipe"],
shell: process.platform === "win32",
});
child.stdout.on("data", (chunk) => {
process.stdout.write(sanitizeBuffer(Buffer.from(chunk)));
});
child.stderr.on("data", (chunk) => {
process.stderr.write(sanitizeBuffer(Buffer.from(chunk)));
});
child.on("exit", (code, signal) => {
if (signal) process.exit(1);
process.exit(code ?? 1);
});

View File

@@ -53,13 +53,27 @@ vi.mock("../web/session.js", () => webMocks);
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
const base = await fs.mkdtemp(join(tmpdir(), "clawdbot-triggers-"));
const previousHome = process.env.HOME;
const previousUserProfile = process.env.USERPROFILE;
const previousHomeDrive = process.env.HOMEDRIVE;
const previousHomePath = process.env.HOMEPATH;
process.env.HOME = base;
if (process.platform === "win32") {
process.env.USERPROFILE = base;
const driveMatch = base.match(/^([A-Za-z]:)(.*)$/);
if (driveMatch) {
process.env.HOMEDRIVE = driveMatch[1];
process.env.HOMEPATH = driveMatch[2] || "\\";
}
}
try {
vi.mocked(runEmbeddedPiAgent).mockClear();
vi.mocked(abortEmbeddedPiRun).mockClear();
return await fn(base);
} finally {
process.env.HOME = previousHome;
process.env.USERPROFILE = previousUserProfile;
process.env.HOMEDRIVE = previousHomeDrive;
process.env.HOMEPATH = previousHomePath;
await fs.rm(base, { recursive: true, force: true });
}
}

View File

@@ -582,6 +582,7 @@ export async function getReplyFromConfig(
directives,
effectiveModelDirective,
cfg,
agentDir,
sessionEntry,
sessionStore,
sessionKey,

View File

@@ -976,6 +976,7 @@ export async function persistInlineDirectives(params: {
directives: InlineDirectives;
effectiveModelDirective?: string;
cfg: ClawdbotConfig;
agentDir?: string;
sessionEntry?: SessionEntry;
sessionStore?: Record<string, SessionEntry>;
sessionKey?: string;
@@ -1009,6 +1010,7 @@ export async function persistInlineDirectives(params: {
formatModelSwitchEvent,
agentCfg,
} = params;
const { agentDir } = params;
let { provider, model } = params;
const activeAgentId = sessionKey
? resolveAgentIdFromSessionKey(sessionKey)

View File

@@ -14,7 +14,7 @@ function normalizeBase(input: string): string {
export default defineConfig(({ command }) => {
const envBase = process.env.CLAWDBOT_CONTROL_UI_BASE_PATH?.trim();
const base = envBase ? normalizeBase(envBase) : "/";
const base = envBase ? normalizeBase(envBase) : "./";
return {
base,
publicDir: path.resolve(here, "public"),