import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { runUserPromptSubmitHook } from "../src/codex-hook.js"; import { ULTRAWORK_DIRECTIVE } from "../src/directive.js"; import { buildUltraworkAdditionalContext, buildUltraworkSkillPointer } from "../src/skill-pointer.js"; import { parseHookOutput } from "./codex-hook-test-helpers.js"; const POINTER_MAX_BYTES = 4096; const tempDirectories: string[] = []; function makeTempDirectory(): string { const directory = mkdtempSync(join(tmpdir(), "ultrawork-skill-")); tempDirectories.push(directory); return directory; } function writeSkillFile(): string { const skillFilePath = join(makeTempDirectory(), "SKILL.md"); writeFileSync(skillFilePath, "---\nname: ultrawork\n---\n\n\ndirective body\n\n"); return skillFilePath; } afterEach(() => { for (const directory of tempDirectories.splice(0)) { rmSync(directory, { recursive: true, force: true }); } }); describe("ultrawork skill pointer", () => { it("#given an existing skill file #when context is built #then emits the compact pointer with the absolute path", () => { // given const skillFilePath = writeSkillFile(); // when const context = buildUltraworkAdditionalContext({ skillFilePath }); // then expect(context).toBe(buildUltraworkSkillPointer(skillFilePath)); expect(context.startsWith("")).toBe(true); expect(context).toContain(skillFilePath); expect(context).toContain("First user-visible line this turn MUST be exactly:"); expect(context).toContain("create_goal"); expect(context).not.toContain("Tier triage"); expect(Buffer.byteLength(context, "utf8")).toBeLessThan(POINTER_MAX_BYTES); }); it("#given a missing skill file #when context is built #then falls back to the full directive", () => { // given const missingSkillFilePath = join(makeTempDirectory(), "SKILL.md"); // when const context = buildUltraworkAdditionalContext({ skillFilePath: missingSkillFilePath }); // then expect(context).toBe(ULTRAWORK_DIRECTIVE); }); it("#given a null skill path #when context is built #then falls back to the full directive", () => { expect(buildUltraworkAdditionalContext({ skillFilePath: null })).toBe(ULTRAWORK_DIRECTIVE); }); it("#given the hook runs with a skill file #when prompt is ulw #then hook JSON carries the pointer", () => { // given const skillFilePath = writeSkillFile(); // when const output = runUserPromptSubmitHook( { hook_event_name: "UserPromptSubmit", prompt: "ulw this change" }, { skillFilePath }, ); const parsed = parseHookOutput(output); // then expect(parsed.hookSpecificOutput.hookEventName).toBe("UserPromptSubmit"); expect(parsed.hookSpecificOutput.additionalContext).toMatch(/^/); expect(parsed.hookSpecificOutput.additionalContext).toContain(skillFilePath); }); });