vigiles API reference
    Preparing search index...

    Interface HarnessTestSpec

    interface HarnessTestSpec {
        allowedTools?: readonly string[];
        files?: Record<string, string>;
        model: readonly ModelTurn[];
        outputStyle?: string;
        plugin?: string;
        pluginDir?: string;
        prompt?: string;
        sandbox?: SandboxMode;
        settings?: unknown;
        timeoutMs?: number;
        tools?: readonly string[];
        transcript?: boolean;
    }
    Index

    Properties

    allowedTools?: readonly string[]

    Which tools are PRE-APPROVED (claude --allowedTools), so they do not stop on a permission prompt. Takes permission rules (Bash(git *)). Omitted: Read, Edit, Write and Bash are approved. An explicit list REPLACES that default, so tools: ["Read", "Write"] with allowedTools: ["Skill"] leaves Write unapproved. []: nothing is approved.

    It never removes a tool, and leaving a tool out is not a fence: in headless mode Claude Code refuses only the calls it would have asked about. For Bash that is a command that creates, changes or removes a file (touch, >), inside or outside the working directory; a command with no file effect (ls, printf, id) runs unapproved. So a refused touch proves the file-change guard is live, not that Bash is withheld. To withhold a tool use tools; to forbid its use put a deny rule in the fixture's settings.permissions.deny.

    files?: Record<string, string>

    Fixture files to write in a fresh temp working dir (path → contents).

    model: readonly ModelTurn[]

    The scripted model turns the agent will take.

    outputStyle?: string

    Path to an OUTPUT STYLE file to switch on for this run. The style is written where the harness keeps styles, and selected by the name the harness reads from the file — never by a name you type, because a setting that misses the name loads no style and raises no error.

    The run is then checked: if no model request carried the style, runHarnessTest THROWS instead of returning a trace, so a style that never loaded cannot pass a test. Refused up front on a harness without output styles, or when the fixture's files or settings already decide.

    What it proves is delivery. A scripted model does not read the style, so nothing in this tier shows that a model FOLLOWS it.

    plugin?: string

    Path to a real plugin/repo whose harness (hooks + CLAUDE.md + skills) is loaded into the sandbox, so you test the assembled machine, not a retyped subset. Inline settings/files layer on top. See src/plugin-loader.ts.

    pluginDir?: string

    Path to a plugin dir to install NATIVELY via claude --plugin-dir, so its skills / commands / agents / hooks register and ACTIVATE the real way — a scripted Skill tool_use resolves, and the real model can trigger them. Unlike plugin (which materializes a file subset that does NOT register skills for the Skill tool), this is the real install path, so point it at a COMPLETE plugin (internal references resolve). Inline settings/files and plugin still layer on top. Resolved to an absolute path.

    prompt?: string

    The user prompt. Default: "go".

    sandbox?: SandboxMode

    Confinement policy for the code this run executes (src/sandbox.ts). Default "auto" is safe-by-default: an inline-only spec (you authored it) runs directly, but an external plugin / pluginDir brings in untrusted third-party hooks and is run under bubblewrap — or, if no sandbox is available, the run REFUSES rather than executing unconfined. Pass false to opt out and run unconfined (you audited the code, or trust the outer container); "strict" to force confinement even for trusted code.

    NOTE: confined execution is Linux only (bubblewrap is a Linux tool). On macOS / Windows no sandbox is available, so an untrusted run will REFUSE under "auto"/"strict" — use sandbox: false there if you trust the code.

    settings?: unknown

    .claude/settings.json contents — the hooks/permissions under test.

    timeoutMs?: number

    Per-run wall-clock timeout in ms. Default 60000.

    tools?: readonly string[]

    Which tools EXIST in the session (claude --tools, Claude Code 2.0.31+). A tool left out is not offered at all, so a call to it is "No such tool available". Omitted, every tool exists. This is the field that withholds a tool. Names only: a permission rule such as Bash(git *) is refused (put the rule in allowedTools). [] is refused (an agent with no tools is never served a scripted turn), and a scripted call to a tool the list leaves out throws before the run starts. An MCP tool is not a built-in, so --tools does not withhold it. Codex has no equivalent, so a run there refuses it.

    field Claude Code flag meaning
    tools --tools which tools exist
    allowedTools --allowedTools which are pre-approved
    transcript?: boolean

    Capture the full event transcript (--output-format stream-json) into stdout, instead of just the final result object, so you can assert on what the agent's tools returned — e.g. the body a Skill tool_use resolved. With this on, stdout is newline-delimited JSON events, not a single object.