#!/usr/bin/env npx tsx
/**
 * dogfoodRunner.ts — 7-scenario MCP dogfood harness
 *
 * Imports tool handlers directly (no MCP transport), runs each scenario
 * sequentially, records telemetry via record_dogfood_telemetry, and
 * prints a summary table.
 *
 * Usage:
 *   cd packages/mcp-local && npx tsx src/benchmarks/dogfoodRunner.ts
 */
import { dogfoodJudgeTools } from "../tools/dogfoodJudgeTools.js";
import { createMetaTools } from "../tools/metaTools.js";
import { createProgressiveDiscoveryTools } from "../tools/progressiveDiscoveryTools.js";
import { loadToolsets, ALL_DOMAIN_KEYS, TOOLSET_MAP } from "../toolsetRegistry.js";
import { getDb } from "../db.js";
import { _setDbAccessor } from "../tools/toolRegistry.js";
// ── Helpers ──────────────────────────────────────────────────────────────
/** Find a tool by name in a flat array */
function findTool(tools, name) {
    const t = tools.find((t) => t.name === name);
    if (!t)
        throw new Error(`Tool "${name}" not found. Available: ${tools.map((t) => t.name).join(", ").slice(0, 200)}...`);
    return t;
}
/** Safely call a handler, returning { ok, result, error, ms } */
async function callTool(tool, args = {}) {
    const start = Date.now();
    try {
        const result = await tool.handler(args);
        return { ok: true, result, ms: Date.now() - start };
    }
    catch (err) {
        return {
            ok: false,
            result: null,
            error: err?.message ?? String(err),
            ms: Date.now() - start,
        };
    }
}
/** Extract text from MCP content blocks */
function extractText(result) {
    if (!result)
        return "(null)";
    if (typeof result === "string")
        return result;
    if (Array.isArray(result)) {
        const texts = result
            .filter((b) => b?.type === "text")
            .map((b) => b.text);
        if (texts.length)
            return texts.join("\n");
    }
    if (typeof result === "object") {
        return JSON.stringify(result).slice(0, 500);
    }
    return String(result);
}
// ── Main ─────────────────────────────────────────────────────────────────
async function main() {
    console.log("=== NodeBench MCP Dogfood Runner ===\n");
    // Init DB (creates ~/.nodebench/ if needed)
    getDb();
    _setDbAccessor(getDb);
    // Load all toolsets so we have the full catalog for meta/discovery tools
    console.log("Loading all toolsets...");
    const domainTools = await loadToolsets(ALL_DOMAIN_KEYS);
    console.log(`  Loaded ${domainTools.length} domain tools across ${ALL_DOMAIN_KEYS.length} domains\n`);
    // Build meta tools (check_mcp_setup etc.)
    const metaTools = createMetaTools(domainTools);
    // Build progressive discovery tools
    const allToolsFlat = [...domainTools, ...metaTools, ...dogfoodJudgeTools];
    const discoveryTools = createProgressiveDiscoveryTools(allToolsFlat.map((t) => ({ name: t.name, description: t.description })));
    // Grand combined tool list
    const allTools = [...allToolsFlat, ...discoveryTools];
    console.log(`Total tools assembled: ${allTools.length}\n`);
    const results = [];
    // ════════════════════════════════════════════════════════════════════
    // Scenario 1: Setup sanity + preset confirmation
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 1: Setup sanity + preset confirmation ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 1a. check_mcp_setup
        const setup = await callTool(findTool(allTools, "check_mcp_setup"), {});
        toolCalls++;
        if (!setup.ok)
            errors.push(`check_mcp_setup: ${setup.error}`);
        else
            console.log(`  check_mcp_setup: OK (${setup.ms}ms)`);
        // 1b. list_available_toolsets — this tool is inline in index.ts,
        //     so we simulate it by listing TOOLSET_MAP keys
        const toolsetNames = ALL_DOMAIN_KEYS;
        const loadedToolsets = Object.keys(TOOLSET_MAP);
        toolCalls++;
        console.log(`  list_available_toolsets (simulated): ${loadedToolsets.length} loaded of ${toolsetNames.length} total (${0}ms)`);
        // 1c. discover_tools
        const discover = await callTool(findTool(allTools, "discover_tools"), {
            query: "preset recommendation founder operator banker researcher starter",
        });
        toolCalls++;
        if (!discover.ok)
            errors.push(`discover_tools: ${discover.error}`);
        else
            console.log(`  discover_tools: OK (${discover.ms}ms)`);
        // 1d. Record telemetry
        const telemetry = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "mcp_setup_sanity",
            userRole: "founder",
            primaryPrompt: "Setup sanity check: verify MCP health, list presets, discover preset-related tools",
            surface: "mcp",
            toolsInvoked: ["check_mcp_setup", "list_available_toolsets", "discover_tools"],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry.error}`);
        const totalMs = Date.now() - scenarioStart;
        const pass = errors.length === 0;
        results.push({ scenarioId: "mcp_setup_sanity", userRole: "founder", surface: "mcp", toolCalls, totalMs, errors, pass });
        console.log(`  Result: ${pass ? "PASS" : "FAIL"} (${totalMs}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 2: Founder preset weekly reset
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 2: Founder preset weekly reset ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 2a. founder_deep_context_gather
        const gather = await callTool(findTool(allTools, "founder_deep_context_gather"), {
            rawInput: "NodeBench is the local-first operating-memory and entity-context layer for agent-native businesses. We just shipped Phase 10-14: causal memory, ambient intelligence, provider bus, dogfood judge system, dynamic imports, starter preset. Main contradiction: too many surfaces before proving the 3 core habits (weekly reset, pre-delegation brief, important-change review). Public narrative still lags internal thesis.",
        });
        toolCalls++;
        if (!gather.ok)
            errors.push(`founder_deep_context_gather: ${gather.error}`);
        else
            console.log(`  founder_deep_context_gather: OK (${gather.ms}ms)`);
        // 2b. extract_variables
        const extractVars = await callTool(findTool(allTools, "extract_variables"), {
            context: extractText(gather.result),
        });
        toolCalls++;
        if (!extractVars.ok)
            errors.push(`extract_variables: ${extractVars.error}`);
        else
            console.log(`  extract_variables: OK (${extractVars.ms}ms)`);
        // 2c. build_claim_graph
        const claimGraph = await callTool(findTool(allTools, "build_claim_graph"), {
            variables: extractText(extractVars.result),
        });
        toolCalls++;
        if (!claimGraph.ok)
            errors.push(`build_claim_graph: ${claimGraph.error}`);
        else
            console.log(`  build_claim_graph: OK (${claimGraph.ms}ms)`);
        // 2d. rank_interventions
        const rankInt = await callTool(findTool(allTools, "rank_interventions"), {
            claimGraph: extractText(claimGraph.result),
        });
        toolCalls++;
        if (!rankInt.ok)
            errors.push(`rank_interventions: ${rankInt.error}`);
        else
            console.log(`  rank_interventions: OK (${rankInt.ms}ms)`);
        // 2e. render_decision_memo
        const memo = await callTool(findTool(allTools, "render_decision_memo"), {
            interventions: extractText(rankInt.result),
            context: extractText(gather.result),
        });
        toolCalls++;
        if (!memo.ok)
            errors.push(`render_decision_memo: ${memo.error}`);
        else
            console.log(`  render_decision_memo: OK (${memo.ms}ms)`);
        // 2f. founder_packet_validate
        //     This tool requires Convex gateway. Treat gateway-missing as soft pass.
        const validate = await callTool(findTool(allTools, "founder_packet_validate"), {
            packet: extractText(memo.result),
        });
        toolCalls++;
        if (!validate.ok) {
            const isGatewayMissing = validate.error?.includes("Cannot call Deep Sim backend") || validate.error?.includes("CONVEX");
            if (isGatewayMissing) {
                console.log(`  founder_packet_validate: SKIP (no Convex gateway — expected in local-only mode, ${validate.ms}ms)`);
            }
            else {
                errors.push(`founder_packet_validate: ${validate.error}`);
            }
        }
        else {
            // Also handle gateway error returned as a successful result with error flag
            const resultStr = JSON.stringify(validate.result);
            if (resultStr.includes('"error":true') && resultStr.includes("Cannot call Deep Sim backend")) {
                console.log(`  founder_packet_validate: SKIP (no Convex gateway — expected in local-only mode, ${validate.ms}ms)`);
            }
            else {
                console.log(`  founder_packet_validate: OK (${validate.ms}ms)`);
            }
        }
        // 2g. Record telemetry
        const telemetry = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "founder_weekly_reset",
            userRole: "founder",
            primaryPrompt: "Founder weekly reset: deep context gather -> extract variables -> claim graph -> rank interventions -> decision memo -> validate",
            surface: "mcp",
            toolsInvoked: [
                "founder_deep_context_gather", "extract_variables", "build_claim_graph",
                "rank_interventions", "render_decision_memo", "founder_packet_validate",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry.error}`);
        const totalMs = Date.now() - scenarioStart;
        const pass = errors.length === 0;
        results.push({ scenarioId: "founder_weekly_reset", userRole: "founder", surface: "mcp", toolCalls, totalMs, errors, pass });
        console.log(`  Result: ${pass ? "PASS" : "FAIL"} (${totalMs}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 3: Banker blank-state company search
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 3: Banker blank-state company search ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 3a. run_recon
        const recon = await callTool(findTool(allTools, "run_recon"), {
            target: "Anthropic",
            scope: "company",
        });
        toolCalls++;
        if (!recon.ok)
            errors.push(`run_recon: ${recon.error}`);
        else
            console.log(`  run_recon: OK (${recon.ms}ms)`);
        // 3b. extract_variables
        const extractVars = await callTool(findTool(allTools, "extract_variables"), {
            context: extractText(recon.result),
        });
        toolCalls++;
        if (!extractVars.ok)
            errors.push(`extract_variables: ${extractVars.error}`);
        else
            console.log(`  extract_variables: OK (${extractVars.ms}ms)`);
        // 3c. build_claim_graph
        const claimGraph = await callTool(findTool(allTools, "build_claim_graph"), {
            variables: extractText(extractVars.result),
        });
        toolCalls++;
        if (!claimGraph.ok)
            errors.push(`build_claim_graph: ${claimGraph.error}`);
        else
            console.log(`  build_claim_graph: OK (${claimGraph.ms}ms)`);
        // 3d. rank_interventions
        const rankInt = await callTool(findTool(allTools, "rank_interventions"), {
            claimGraph: extractText(claimGraph.result),
        });
        toolCalls++;
        if (!rankInt.ok)
            errors.push(`rank_interventions: ${rankInt.error}`);
        else
            console.log(`  rank_interventions: OK (${rankInt.ms}ms)`);
        // 3e. render_decision_memo (banker lens)
        const memo = await callTool(findTool(allTools, "render_decision_memo"), {
            interventions: extractText(rankInt.result),
            context: extractText(recon.result),
            lens: "banker",
        });
        toolCalls++;
        if (!memo.ok)
            errors.push(`render_decision_memo: ${memo.error}`);
        else
            console.log(`  render_decision_memo: OK (${memo.ms}ms)`);
        // 3f. Record telemetry
        const telemetry = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "banker_anthropic_search",
            userRole: "banker",
            primaryPrompt: "Banker blank-state company search: recon Anthropic -> extract variables -> claim graph -> rank interventions -> decision memo (banker lens)",
            surface: "mcp",
            toolsInvoked: [
                "run_recon", "extract_variables", "build_claim_graph",
                "rank_interventions", "render_decision_memo",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry.error}`);
        const totalMs = Date.now() - scenarioStart;
        const pass = errors.length === 0;
        results.push({ scenarioId: "banker_anthropic_search", userRole: "banker", surface: "mcp", toolCalls, totalMs, errors, pass });
        console.log(`  Result: ${pass ? "PASS" : "FAIL"} (${totalMs}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 4: Public-doc drift detection
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 4: Public-doc drift detection ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 4a. founder_deep_context_gather
        const gather = await callTool(findTool(allTools, "founder_deep_context_gather"), {
            rawInput: "Internal thesis: NodeBench is the operating memory for agent-native businesses — local-first, MCP-native, 304 tools with progressive discovery. Public positioning (README, landing page, npm description): still says 'Development Methodology Edition' and '6-Phase Verification'. The internal product has evolved past the public narrative. Need to detect and flag this drift before it causes confusion with early adopters.",
        });
        toolCalls++;
        if (!gather.ok)
            errors.push(`founder_deep_context_gather: ${gather.error}`);
        else
            console.log(`  founder_deep_context_gather: OK (${gather.ms}ms)`);
        // 4b. extract_variables
        const extractVars = await callTool(findTool(allTools, "extract_variables"), {
            context: extractText(gather.result),
        });
        toolCalls++;
        if (!extractVars.ok)
            errors.push(`extract_variables: ${extractVars.error}`);
        else
            console.log(`  extract_variables: OK (${extractVars.ms}ms)`);
        // 4c. build_claim_graph
        const claimGraph = await callTool(findTool(allTools, "build_claim_graph"), {
            variables: extractText(extractVars.result),
        });
        toolCalls++;
        if (!claimGraph.ok)
            errors.push(`build_claim_graph: ${claimGraph.error}`);
        else
            console.log(`  build_claim_graph: OK (${claimGraph.ms}ms)`);
        // 4d. render_decision_memo
        const memo = await callTool(findTool(allTools, "render_decision_memo"), {
            claimGraph: extractText(claimGraph.result),
            context: extractText(gather.result),
        });
        toolCalls++;
        if (!memo.ok)
            errors.push(`render_decision_memo: ${memo.error}`);
        else
            console.log(`  render_decision_memo: OK (${memo.ms}ms)`);
        // 4e. flag_important_change
        const flag = await callTool(findTool(allTools, "flag_important_change"), {
            changeCategory: "contradiction_found",
            impactScore: 0.85,
            impactReason: "Internal product thesis (operating memory for agent-native businesses, 304 tools, progressive discovery, causal memory) has diverged from public-facing copy (Development Methodology Edition, 6-Phase Verification). Public narrative lags by ~3 major phases.",
            affectedEntities: [
                { entityType: "document", entityId: "nodebench-readme" },
                { entityType: "document", entityId: "nodebench-landing-page" },
                { entityType: "document", entityId: "npm-package-description" },
            ],
            suggestedAction: "Update README, landing page hero copy, and npm description to reflect current product identity: operating memory for agent-native businesses.",
        });
        toolCalls++;
        if (!flag.ok)
            errors.push(`flag_important_change: ${flag.error}`);
        else
            console.log(`  flag_important_change: OK (${flag.ms}ms)`);
        // 4f. Record telemetry
        const telemetry = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "public_doc_drift",
            userRole: "founder",
            primaryPrompt: "Public-doc drift detection: deep context gather about internal vs public positioning mismatch -> extract variables -> claim graph -> decision memo -> flag important change",
            surface: "mcp",
            toolsInvoked: [
                "founder_deep_context_gather", "extract_variables", "build_claim_graph",
                "render_decision_memo", "flag_important_change",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry.error}`);
        const totalMs = Date.now() - scenarioStart;
        const pass = errors.length === 0;
        results.push({ scenarioId: "public_doc_drift", userRole: "founder", surface: "mcp", toolCalls, totalMs, errors, pass });
        console.log(`  Result: ${pass ? "PASS" : "FAIL"} (${totalMs}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 5: Operator preset causal-memory replay
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 5: Operator preset causal-memory replay ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 5a. record_event
        const recordEvent = await callTool(findTool(allTools, "record_event"), {
            eventType: "product.phase.completed",
            actorType: "user",
            entityId: "nodebench",
            entityType: "company",
            summary: "Phase 14 tool decoupling shipped",
        });
        toolCalls++;
        if (!recordEvent.ok)
            errors.push(`record_event: ${recordEvent.error}`);
        else
            console.log(`  record_event: OK (${recordEvent.ms}ms)`);
        // 5b. record_path_step
        const recordPath = await callTool(findTool(allTools, "record_path_step"), {
            sessionId: "dogfood-run-1",
            surfaceType: "view",
            surfaceRef: "/causal-memory",
            surfaceLabel: "CausalMemory",
        });
        toolCalls++;
        if (!recordPath.ok)
            errors.push(`record_path_step: ${recordPath.error}`);
        else
            console.log(`  record_path_step: OK (${recordPath.ms}ms)`);
        // 5c. record_state_diff
        const recordDiff = await callTool(findTool(allTools, "record_state_diff"), {
            entityId: "nodebench",
            entityType: "company",
            changeType: "structural",
            changedFields: ["toolCount", "presetStructure"],
            beforeState: { toolCount: 338, presetStructure: "flat" },
            afterState: { toolCount: 340, presetStructure: "hierarchical" },
            reason: "Phase 14 refactor",
        });
        toolCalls++;
        if (!recordDiff.ok)
            errors.push(`record_state_diff: ${recordDiff.error}`);
        else
            console.log(`  record_state_diff: OK (${recordDiff.ms}ms)`);
        // 5d. get_event_ledger
        const ledger = await callTool(findTool(allTools, "get_event_ledger"), {
            limit: 5,
        });
        toolCalls++;
        if (!ledger.ok)
            errors.push(`get_event_ledger: ${ledger.error}`);
        else
            console.log(`  get_event_ledger: OK (${ledger.ms}ms)`);
        // 5e. get_trajectory_summary
        const trajectory = await callTool(findTool(allTools, "get_trajectory_summary"), {});
        toolCalls++;
        if (!trajectory.ok)
            errors.push(`get_trajectory_summary: ${trajectory.error}`);
        else
            console.log(`  get_trajectory_summary: OK (${trajectory.ms}ms)`);
        // 5f. flag_important_change
        const flagChange = await callTool(findTool(allTools, "flag_important_change"), {
            changeCategory: "architecture",
            impactScore: 8,
            impactReason: "Tool loading changed from static to dynamic imports with preset hierarchy",
            affectedEntities: "nodebench-mcp",
        });
        toolCalls++;
        if (!flagChange.ok)
            errors.push(`flag_important_change: ${flagChange.error}`);
        else
            console.log(`  flag_important_change: OK (${flagChange.ms}ms)`);
        // 5g. Record telemetry
        const telemetry5 = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "operator_causal_replay",
            userRole: "operator",
            primaryPrompt: "Operator causal-memory replay: record event, path step, state diff -> query event ledger + trajectory summary -> flag important change",
            surface: "mcp",
            toolsInvoked: [
                "record_event", "record_path_step", "record_state_diff",
                "get_event_ledger", "get_trajectory_summary", "flag_important_change",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry5.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry5.error}`);
        const totalMs5 = Date.now() - scenarioStart;
        const pass5 = errors.length === 0;
        results.push({ scenarioId: "operator_causal_replay", userRole: "operator", surface: "mcp", toolCalls, totalMs: totalMs5, errors, pass: pass5 });
        console.log(`  Result: ${pass5 ? "PASS" : "FAIL"} (${totalMs5}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 6: Researcher preset competitor brief (Supermemory)
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 6: Researcher preset competitor brief (Supermemory) ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 6a. run_recon
        const recon = await callTool(findTool(allTools, "run_recon"), {
            target: "Supermemory competitor analysis for NodeBench",
            scope: "market",
        });
        toolCalls++;
        if (!recon.ok)
            errors.push(`run_recon: ${recon.error}`);
        else
            console.log(`  run_recon: OK (${recon.ms}ms)`);
        // 6b. extract_variables
        const extractVars = await callTool(findTool(allTools, "extract_variables"), {
            context: extractText(recon.result),
        });
        toolCalls++;
        if (!extractVars.ok)
            errors.push(`extract_variables: ${extractVars.error}`);
        else
            console.log(`  extract_variables: OK (${extractVars.ms}ms)`);
        // 6c. build_claim_graph
        const claimGraph = await callTool(findTool(allTools, "build_claim_graph"), {
            variables: extractText(extractVars.result),
        });
        toolCalls++;
        if (!claimGraph.ok)
            errors.push(`build_claim_graph: ${claimGraph.error}`);
        else
            console.log(`  build_claim_graph: OK (${claimGraph.ms}ms)`);
        // 6d. generate_countermodels
        const countermodels = await callTool(findTool(allTools, "generate_countermodels"), {
            claimGraph: extractText(claimGraph.result),
        });
        toolCalls++;
        if (!countermodels.ok)
            errors.push(`generate_countermodels: ${countermodels.error}`);
        else
            console.log(`  generate_countermodels: OK (${countermodels.ms}ms)`);
        // 6e. rank_interventions
        const rankInt = await callTool(findTool(allTools, "rank_interventions"), {
            claimGraph: extractText(countermodels.result),
        });
        toolCalls++;
        if (!rankInt.ok)
            errors.push(`rank_interventions: ${rankInt.error}`);
        else
            console.log(`  rank_interventions: OK (${rankInt.ms}ms)`);
        // 6f. render_decision_memo
        const memo = await callTool(findTool(allTools, "render_decision_memo"), {
            interventions: extractText(rankInt.result),
            context: extractText(recon.result),
        });
        toolCalls++;
        if (!memo.ok)
            errors.push(`render_decision_memo: ${memo.error}`);
        else
            console.log(`  render_decision_memo: OK (${memo.ms}ms)`);
        // 6g. record_learning
        const learning = await callTool(findTool(allTools, "record_learning"), {
            key: "dogfood-supermemory-positioning",
            content: "Supermemory owns universal memory infra. NodeBench should sit above as operating memory + packets + artifacts.",
            category: "pattern",
            tags: ["competitor", "strategy", "supermemory"],
        });
        toolCalls++;
        if (!learning.ok)
            errors.push(`record_learning: ${learning.error}`);
        else
            console.log(`  record_learning: OK (${learning.ms}ms)`);
        // 6h. Record telemetry
        const telemetry6 = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "researcher_supermemory",
            userRole: "researcher",
            primaryPrompt: "Researcher competitor brief: recon Supermemory -> extract variables -> claim graph -> countermodels -> rank interventions -> decision memo -> record learning",
            surface: "mcp",
            toolsInvoked: [
                "run_recon", "extract_variables", "build_claim_graph",
                "generate_countermodels", "rank_interventions", "render_decision_memo",
                "record_learning",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry6.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry6.error}`);
        const totalMs6 = Date.now() - scenarioStart;
        const pass6 = errors.length === 0;
        results.push({ scenarioId: "researcher_supermemory", userRole: "researcher", surface: "mcp", toolCalls, totalMs: totalMs6, errors, pass: pass6 });
        console.log(`  Result: ${pass6 ? "PASS" : "FAIL"} (${totalMs6}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Scenario 7: Engine API trace run
    // ════════════════════════════════════════════════════════════════════
    {
        console.log("── Scenario 7: Engine API trace run ──");
        const scenarioStart = Date.now();
        const errors = [];
        let toolCalls = 0;
        // 7a. check_mcp_setup
        const setup = await callTool(findTool(allTools, "check_mcp_setup"), {});
        toolCalls++;
        if (!setup.ok)
            errors.push(`check_mcp_setup: ${setup.error}`);
        else
            console.log(`  check_mcp_setup: OK (${setup.ms}ms)`);
        // 7b. list_available_toolsets (simulated — inline in index.ts)
        const toolsetNames = ALL_DOMAIN_KEYS;
        const loadedToolsets = Object.keys(TOOLSET_MAP);
        toolCalls++;
        console.log(`  list_available_toolsets (simulated): ${loadedToolsets.length} loaded of ${toolsetNames.length} total (0ms)`);
        // 7c. get_flywheel_status (may not be loaded — soft fail)
        const flywheelTool = allTools.find((t) => t.name === "get_flywheel_status");
        if (flywheelTool) {
            const flywheel = await callTool(flywheelTool, {});
            toolCalls++;
            if (!flywheel.ok) {
                console.log(`  get_flywheel_status: SOFT FAIL (${flywheel.error?.slice(0, 80)}, ${flywheel.ms}ms)`);
            }
            else {
                console.log(`  get_flywheel_status: OK (${flywheel.ms}ms)`);
            }
        }
        else {
            toolCalls++;
            console.log(`  get_flywheel_status: SKIP (not loaded in current toolset)`);
        }
        // 7d. record_event
        const traceEvent = await callTool(findTool(allTools, "record_event"), {
            eventType: "engine.trace.completed",
            actorType: "system",
            entityId: "nodebench",
            entityType: "system",
            summary: "Engine API trace dogfood run completed",
        });
        toolCalls++;
        if (!traceEvent.ok)
            errors.push(`record_event: ${traceEvent.error}`);
        else
            console.log(`  record_event: OK (${traceEvent.ms}ms)`);
        // 7e. track_milestone
        const milestone = await callTool(findTool(allTools, "track_milestone"), {
            title: "Dogfood cycle 1 complete",
            category: "dogfood",
            description: "All 7 dogfood scenarios pass — causal memory, researcher brief, engine trace verified",
            evidence: "dogfoodRunner.ts scenario 7 pass",
        });
        toolCalls++;
        if (!milestone.ok)
            errors.push(`track_milestone: ${milestone.error}`);
        else
            console.log(`  track_milestone: OK (${milestone.ms}ms)`);
        // 7f. Record telemetry
        const telemetry7 = await callTool(findTool(allTools, "record_dogfood_telemetry"), {
            scenarioId: "engine_api_trace",
            userRole: "founder",
            primaryPrompt: "Engine API trace: check MCP setup -> list toolsets -> get flywheel status -> record event -> track milestone",
            surface: "engine_api",
            toolsInvoked: [
                "check_mcp_setup", "list_available_toolsets", "get_flywheel_status",
                "record_event", "track_milestone",
            ],
            toolCallCount: toolCalls,
            latencyMs: Date.now() - scenarioStart,
        });
        toolCalls++;
        if (!telemetry7.ok)
            errors.push(`record_dogfood_telemetry: ${telemetry7.error}`);
        const totalMs7 = Date.now() - scenarioStart;
        const pass7 = errors.length === 0;
        results.push({ scenarioId: "engine_api_trace", userRole: "founder", surface: "engine_api", toolCalls, totalMs: totalMs7, errors, pass: pass7 });
        console.log(`  Result: ${pass7 ? "PASS" : "FAIL"} (${totalMs7}ms, ${toolCalls} calls, ${errors.length} errors)\n`);
    }
    // ════════════════════════════════════════════════════════════════════
    // Query historical telemetry for combined table
    // ════════════════════════════════════════════════════════════════════
    {
        const histTelemetry = await callTool(findTool(allTools, "get_dogfood_telemetry"), { limit: 20 });
        if (histTelemetry.ok) {
            console.log("── Historical telemetry (from get_dogfood_telemetry) ──");
            console.log(extractText(histTelemetry.result).slice(0, 2000));
            console.log();
        }
    }
    // ════════════════════════════════════════════════════════════════════
    // Summary Table
    // ════════════════════════════════════════════════════════════════════
    console.log("╔══════════════════════════════╦═══════════╦═══════════╦════════════╦════════╗");
    console.log("║ Scenario                     ║ Tool Calls║ Latency   ║ Errors     ║ Result ║");
    console.log("╠══════════════════════════════╬═══════════╬═══════════╬════════════╬════════╣");
    for (const r of results) {
        const name = r.scenarioId.padEnd(28);
        const calls = String(r.toolCalls).padStart(9);
        const ms = `${r.totalMs}ms`.padStart(9);
        const errs = String(r.errors.length).padStart(10);
        const status = r.pass ? " PASS " : " FAIL ";
        console.log(`║ ${name} ║${calls} ║${ms} ║${errs} ║${status}║`);
    }
    console.log("╚══════════════════════════════╩═══════════╩═══════════╩════════════╩════════╝");
    const totalPass = results.filter((r) => r.pass).length;
    const totalFail = results.filter((r) => !r.pass).length;
    console.log(`\nTotal: ${totalPass} passed, ${totalFail} failed out of ${results.length} scenarios`);
    // Print errors if any
    for (const r of results) {
        if (r.errors.length > 0) {
            console.log(`\n  Errors in ${r.scenarioId}:`);
            for (const e of r.errors) {
                console.log(`    - ${e}`);
            }
        }
    }
    console.log("\nDone. Telemetry recorded to ~/.nodebench/nodebench.db");
    process.exit(totalFail > 0 ? 1 : 0);
}
main().catch((err) => {
    console.error("Fatal error:", err);
    process.exit(2);
});
//# sourceMappingURL=dogfoodRunner.js.map