























@@ -22,7 +22,9 @@ import {
2222 type DiagnosticEventPayload,
2323} from "openclaw/plugin-sdk/diagnostic-runtime";
2424import {
25+ clearInternalHooks,
2526 initializeGlobalHookRunner,
27+ registerInternalHook,
2628 resetGlobalHookRunner,
2729} from "openclaw/plugin-sdk/hook-runtime";
2830import { clearPluginCommands, registerPluginCommand } from "openclaw/plugin-sdk/plugin-runtime";
@@ -646,6 +648,7 @@ function extractRelayIdFromThreadRequest(params: unknown): string {
646648647649describe("runCodexAppServerAttempt", () => {
648650 beforeEach(async () => {
651+ clearInternalHooks();
649652 resetAgentEventsForTest();
650653 resetDiagnosticEventsForTest();
651654 vi.stubEnv("OPENCLAW_TRAJECTORY", "0");
@@ -663,6 +666,7 @@ describe("runCodexAppServerAttempt", () => {
663666 resetAgentEventsForTest();
664667 resetDiagnosticEventsForTest();
665668 resetGlobalHookRunner();
669+ clearInternalHooks();
666670 defaultCodexAppInventoryCache.clear();
667671 vi.useRealTimers();
668672 vi.restoreAllMocks();
@@ -4825,6 +4829,43 @@ describe("runCodexAppServerAttempt", () => {
48254829 });
48264830 });
482748314832+ it("reports hook-supplied bootstrap files that only expose path and content", async () => {
4833+ const sessionFile = path.join(tempDir, "session.jsonl");
4834+ const workspaceDir = path.join(tempDir, "workspace");
4835+ const soulPath = path.join(workspaceDir, "SOUL.md");
4836+ const soulGuidance = "Hook supplied soul guidance.";
4837+ await fs.mkdir(workspaceDir, { recursive: true });
4838+ registerInternalHook("agent:bootstrap", (event) => {
4839+ const context = event.context as {
4840+ bootstrapFiles: Array<{ content: string; missing: boolean; path: string }>;
4841+ };
4842+ context.bootstrapFiles = [
4843+ {
4844+ path: soulPath,
4845+ content: soulGuidance,
4846+ missing: false,
4847+ },
4848+ ];
4849+ });
4850+ const harness = createStartedThreadHarness();
4851+4852+ const run = runCodexAppServerAttempt(createParams(sessionFile, workspaceDir));
4853+ await harness.waitForMethod("turn/start");
4854+ await new Promise<void>((resolve) => setImmediate(resolve));
4855+ await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
4856+ const result = await run;
4857+4858+ expect(result.systemPromptReport?.injectedWorkspaceFiles).toEqual([
4859+ expect.objectContaining({
4860+ name: "SOUL.md",
4861+ path: soulPath,
4862+ rawChars: soulGuidance.length,
4863+ injectedChars: soulGuidance.length,
4864+ truncated: false,
4865+ }),
4866+ ]);
4867+ });
4868+48284869 it("points heartbeat Codex turns at HEARTBEAT.md without injecting its contents", async () => {
48294870 const sessionFile = path.join(tempDir, "session.jsonl");
48304871 const workspaceDir = path.join(tempDir, "workspace");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。