fix: restore ci after rebase drift

This commit is contained in:
Peter Steinberger
2026-04-07 08:40:17 +01:00
parent ce7ef626b8
commit 86361f4fca
15 changed files with 81 additions and 69 deletions

View File

@@ -120,15 +120,7 @@ export type ConfigAuditProcessInfo = {
export type ConfigWriteAuditRecordBase = Omit<
ConfigWriteAuditRecord,
| "result"
| "errorCode"
| "errorMessage"
| "nextDev"
| "nextIno"
| "nextMode"
| "nextNlink"
| "nextUid"
| "nextGid"
"result" | "errorCode" | "errorMessage"
> & {
nextHash: string;
nextBytes: number;
@@ -292,16 +284,34 @@ export function finalizeConfigWriteAuditRecord(params: {
};
}
export async function appendConfigAuditRecord(params: {
type ConfigAuditAppendContext = {
fs: ConfigAuditFs;
env: NodeJS.ProcessEnv;
homedir: () => string;
record: ConfigAuditRecord;
}): Promise<void> {
};
type ConfigAuditAppendParams = ConfigAuditAppendContext &
(
| {
record: ConfigAuditRecord;
}
| ConfigAuditRecord
);
function resolveConfigAuditAppendRecord(params: ConfigAuditAppendParams): ConfigAuditRecord {
if ("record" in params) {
return params.record;
}
const { fs: _fs, env: _env, homedir: _homedir, ...record } = params;
return record as ConfigAuditRecord;
}
export async function appendConfigAuditRecord(params: ConfigAuditAppendParams): Promise<void> {
try {
const auditPath = resolveConfigAuditLogPath(params.env, params.homedir);
const record = resolveConfigAuditAppendRecord(params);
await params.fs.promises.mkdir(path.dirname(auditPath), { recursive: true, mode: 0o700 });
await params.fs.promises.appendFile(auditPath, `${JSON.stringify(params.record)}\n`, {
await params.fs.promises.appendFile(auditPath, `${JSON.stringify(record)}\n`, {
encoding: "utf-8",
mode: 0o600,
});
@@ -310,16 +320,12 @@ export async function appendConfigAuditRecord(params: {
}
}
export function appendConfigAuditRecordSync(params: {
fs: ConfigAuditFs;
env: NodeJS.ProcessEnv;
homedir: () => string;
record: ConfigAuditRecord;
}): void {
export function appendConfigAuditRecordSync(params: ConfigAuditAppendParams): void {
try {
const auditPath = resolveConfigAuditLogPath(params.env, params.homedir);
const record = resolveConfigAuditAppendRecord(params);
params.fs.mkdirSync(path.dirname(auditPath), { recursive: true, mode: 0o700 });
params.fs.appendFileSync(auditPath, `${JSON.stringify(params.record)}\n`, {
params.fs.appendFileSync(auditPath, `${JSON.stringify(record)}\n`, {
encoding: "utf-8",
mode: 0o600,
});

View File

@@ -18,6 +18,7 @@ import {
collectRelevantDoctorPluginIds,
listPluginDoctorLegacyConfigRules,
} from "../plugins/doctor-contract-registry.js";
import { sanitizeTerminalText } from "../terminal/safe-text.js";
import { isRecord } from "../utils.js";
import { VERSION } from "../version.js";
import { DuplicateAgentDirError, findDuplicateAgentDirs } from "./agent-dirs.js";

View File

@@ -27,7 +27,8 @@ vi.mock("./backup-rotation.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./backup-rotation.js")>();
return {
...actual,
maintainConfigBackups: (...args: unknown[]) => mockMaintainConfigBackups(...args),
maintainConfigBackups: (..._args: Parameters<typeof actual.maintainConfigBackups>) =>
mockMaintainConfigBackups(),
};
});

View File

@@ -7,6 +7,7 @@ import {
resolveWriteEnvSnapshotForPath,
unsetPathForWrite,
} from "./io.write-prepare.js";
import type { OpenClawConfig } from "./types.js";
describe("config io write prepare", () => {
it("persists caller changes onto resolved config without leaking runtime defaults", () => {
@@ -61,7 +62,7 @@ describe("config io write prepare", () => {
});
it("does not mutate caller config when unsetting existing config objects", () => {
const input = {
const input: OpenClawConfig = {
gateway: { mode: "local" },
commands: { ownerDisplay: "hash" },
};
@@ -76,14 +77,14 @@ describe("config io write prepare", () => {
});
it("keeps caller arrays immutable when unsetting array entries", () => {
const input = {
const input: OpenClawConfig = {
gateway: { mode: "local" },
tools: { alsoAllow: ["exec", "fetch", "read"] },
};
const next = unsetPathForWrite(input, ["tools", "alsoAllow", "1"]);
expect(input.tools.alsoAllow).toEqual(["exec", "fetch", "read"]);
expect(input.tools!.alsoAllow).toEqual(["exec", "fetch", "read"]);
expect((next.next.tools as { alsoAllow?: string[] } | undefined)?.alsoAllow).toEqual([
"exec",
"read",
@@ -91,7 +92,7 @@ describe("config io write prepare", () => {
});
it("treats missing unset paths as no-op without mutating caller config", () => {
const input = {
const input: OpenClawConfig = {
gateway: { mode: "local" },
commands: { ownerDisplay: "hash" },
};
@@ -107,7 +108,7 @@ describe("config io write prepare", () => {
});
it("ignores blocked prototype-key unset path segments", () => {
const input = {
const input: OpenClawConfig = {
gateway: { mode: "local" },
commands: { ownerDisplay: "hash" },
};
@@ -280,7 +281,7 @@ describe("config io write prepare", () => {
},
};
const runtimeConfig = {
const runtimeConfig: OpenClawConfig = {
gateway: { port: 18789 },
channels: {
bluebubbles: {
@@ -315,7 +316,7 @@ describe("config io write prepare", () => {
});
it("does not reintroduce legacy nested dm.policy defaults in the persisted candidate", () => {
const sourceConfig = {
const sourceConfig: OpenClawConfig = {
channels: {
discord: {
dmPolicy: "pairing",
@@ -330,8 +331,10 @@ describe("config io write prepare", () => {
};
const nextConfig = structuredClone(sourceConfig);
delete nextConfig.channels.discord.dm.policy;
delete nextConfig.channels.slack.dm.policy;
delete (nextConfig.channels?.discord?.dm as { enabled?: boolean; policy?: string } | undefined)
?.policy;
delete (nextConfig.channels?.slack?.dm as { enabled?: boolean; policy?: string } | undefined)
?.policy;
const persisted = resolvePersistCandidateForWrite({
runtimeConfig: sourceConfig,

View File

@@ -145,10 +145,10 @@ export function getToolResult(
function collectActionMediaSourceHints(params: Record<string, unknown>): string[] {
const sources: string[] = [];
for (const key of ["media", "mediaUrl", "path", "filePath", "fileUrl"] as const) {
const value = params[key];
const normalized = typeof value === "string" ? normalizeOptionalString(value) : undefined;
if (normalized) {
sources.push(value);
const source = typeof params[key] === "string" ? params[key] : undefined;
const normalized = normalizeOptionalString(source);
if (normalized && source) {
sources.push(source);
}
}
return sources;