/**
 * What is left of the hand-rolled chat: the tool boundary.
 *
 * This file used to be the interactive agent — an SSE reader, a tool-call
 * assembler, a four-turn budget and the system prompt. Prime Agent does all of
 * that now, and the pieces that were ours have moved to where they belong: the
 * prompt to `agent/prompt.ts`, the session to `agent/session.ts`, the zod-to-
 * harness translation to `agent/tool-bridge.ts`.
 *
 * One thing did not move, because it is not the harness's job. Every tool Piggy
 * is handed must be a PIG application tool, and the check has to live in PIG's
 * own code rather than in a configuration flag whose meaning an upgrade could
 * change underneath us.
 */
import type { PiggyChatContext } from '@pig/core';

// Re-exported so the several call sites that already import the context type
// from here keep working. The definition lives in @pig/core because it crosses
// four process boundaries and two `.strict()` schemas.
export type { PiggyChatContext };

/**
 * The gate that survived the harness swap.
 *
 * `noTools: 'all'` already means a session starts with no bash, no filesystem
 * and no code execution, and the explicit `tools` allowlist means only our names
 * are enabled. This is the gate behind both, and the only one written in PIG's
 * own code: whatever the harness's defaults become across an upgrade, a tool
 * that does not begin `pig_`, or whose name reads like a shell, never reaches
 * the model. It takes only a name, so it holds equally for a zod `AgentTool` on
 * its way through the bridge and for a `ToolDefinition` built directly. It is
 * cheap, it is greppable, and it has no reason ever to be removed.
 */
/**
 * The shapes a tool name may not have, whatever it is prefixed with.
 *
 * The prefix rule is a convention, and a convention alone is not a boundary:
 * the interesting mistake is not a tool called `bash`, it is one called
 * `pig_python_exec`, which reads like house style and passes the prefix. This
 * list therefore names the interpreters and the process-spawning verbs as well
 * as the shell, and it must stay in step with the equivalent list in
 * .gitea/workflows/ci.yml — CI already rejected `pig_python_exec` while this
 * gate, the one that runs in production, waved it through.
 *
 * Deliberately NOT here: `read`, `write`, `list` and their kin. Every PIG tool
 * is a read or a write of the book, `pig_get_record_by_id` is exactly that, and
 * a rule that fires on the words the domain is made of is a rule somebody
 * deletes the first time it is inconvenient.
 */
const FORBIDDEN_TOOL_NAME = /bash|shell|filesystem|file_read|file_write|python|ipython|notebook|subprocess|_exec\b|^pig_exec|process_run|spawn|eval/i;

export function assertPigToolBoundary(tools: readonly { name: string }[]): void {
  for (const tool of tools) {
    if (!tool.name.startsWith('pig_') || FORBIDDEN_TOOL_NAME.test(tool.name)) {
      throw new Error(`Interactive Piggy tool '${tool.name}' is outside the PIG tool boundary.`);
    }
  }
}
