mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-22 23:41:07 +00:00
99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../../../config/config.js";
|
|
import { makeTempWorkspace, writeWorkspaceFile } from "../../../test-helpers/workspace.js";
|
|
import type { AgentBootstrapHookContext } from "../../hooks.js";
|
|
import { createHookEvent } from "../../hooks.js";
|
|
import handler from "./handler.js";
|
|
|
|
function createBootstrapExtraConfig(paths: string[]): OpenClawConfig {
|
|
return {
|
|
hooks: {
|
|
internal: {
|
|
entries: {
|
|
"bootstrap-extra-files": {
|
|
enabled: true,
|
|
paths,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
async function createBootstrapContext(params: {
|
|
workspaceDir: string;
|
|
cfg: OpenClawConfig;
|
|
sessionKey: string;
|
|
rootFiles: Array<{ name: string; content: string }>;
|
|
}): Promise<AgentBootstrapHookContext> {
|
|
const bootstrapFiles = await Promise.all(
|
|
params.rootFiles.map(async (file) => ({
|
|
name: file.name,
|
|
path: await writeWorkspaceFile({
|
|
dir: params.workspaceDir,
|
|
name: file.name,
|
|
content: file.content,
|
|
}),
|
|
content: file.content,
|
|
missing: false,
|
|
})),
|
|
);
|
|
return {
|
|
workspaceDir: params.workspaceDir,
|
|
bootstrapFiles,
|
|
cfg: params.cfg,
|
|
sessionKey: params.sessionKey,
|
|
};
|
|
}
|
|
|
|
describe("bootstrap-extra-files hook", () => {
|
|
it("appends extra bootstrap files from configured patterns", async () => {
|
|
const tempDir = await makeTempWorkspace("openclaw-bootstrap-extra-");
|
|
const extraDir = path.join(tempDir, "packages", "core");
|
|
await fs.mkdir(extraDir, { recursive: true });
|
|
await fs.writeFile(path.join(extraDir, "AGENTS.md"), "extra agents", "utf-8");
|
|
|
|
const cfg = createBootstrapExtraConfig(["packages/*/AGENTS.md"]);
|
|
const context = await createBootstrapContext({
|
|
workspaceDir: tempDir,
|
|
cfg,
|
|
sessionKey: "agent:main:main",
|
|
rootFiles: [{ name: "AGENTS.md", content: "root agents" }],
|
|
});
|
|
|
|
const event = createHookEvent("agent", "bootstrap", "agent:main:main", context);
|
|
await handler(event);
|
|
|
|
const injected = context.bootstrapFiles.filter((f) => f.name === "AGENTS.md");
|
|
expect(injected).toHaveLength(2);
|
|
expect(injected.some((f) => f.path.endsWith(path.join("packages", "core", "AGENTS.md")))).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it("re-applies subagent bootstrap allowlist after extras are added", async () => {
|
|
const tempDir = await makeTempWorkspace("openclaw-bootstrap-extra-subagent-");
|
|
const extraDir = path.join(tempDir, "packages", "persona");
|
|
await fs.mkdir(extraDir, { recursive: true });
|
|
await fs.writeFile(path.join(extraDir, "SOUL.md"), "evil", "utf-8");
|
|
|
|
const cfg = createBootstrapExtraConfig(["packages/*/SOUL.md"]);
|
|
const context = await createBootstrapContext({
|
|
workspaceDir: tempDir,
|
|
cfg,
|
|
sessionKey: "agent:main:subagent:abc",
|
|
rootFiles: [
|
|
{ name: "AGENTS.md", content: "root agents" },
|
|
{ name: "TOOLS.md", content: "root tools" },
|
|
],
|
|
});
|
|
|
|
const event = createHookEvent("agent", "bootstrap", "agent:main:subagent:abc", context);
|
|
await handler(event);
|
|
|
|
expect(context.bootstrapFiles.map((f) => f.name).toSorted()).toEqual(["AGENTS.md", "TOOLS.md"]);
|
|
});
|
|
});
|