/**
 * System prompt construction and project context loading
 */
import { getDocsPath, getExamplesPath, getReadmePath } from "../config.js";
import { toPosixPath } from "../utils/path-display.js";
import { formatSkillsForPrompt } from "./skills.js";
/** Tool descriptions for system prompt */
const toolDescriptions = {
    read: "Read file contents",
    bash: "Execute bash commands (ls, grep, find, etc.)",
    edit: "Make surgical edits to files (find exact text and replace)",
    write: "Create or overwrite files",
    grep: "Search file contents for patterns (respects .gitignore)",
    find: "Find files by glob pattern (respects .gitignore)",
    ls: "List directory contents",
    lsp: "Code intelligence via Language Server Protocol (go-to-definition, references, diagnostics, hover, rename, symbols)",
};
/** Build the system prompt with tools, guidelines, and context */
export function buildSystemPrompt(options = {}) {
    const { customPrompt, selectedTools, toolSnippets, promptGuidelines, appendSystemPrompt, cwd, contextFiles: providedContextFiles, skills: providedSkills, } = options;
    const resolvedCwd = toPosixPath(cwd ?? process.cwd());
    const now = new Date();
    const dateTime = now.toLocaleString("en-US", {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        timeZoneName: "short",
    });
    const appendSection = appendSystemPrompt ? `\n\n${appendSystemPrompt}` : "";
    const contextFiles = providedContextFiles ?? [];
    const skills = providedSkills ?? [];
    if (customPrompt) {
        let prompt = customPrompt;
        if (appendSection) {
            prompt += appendSection;
        }
        // Append project context files
        if (contextFiles.length > 0) {
            prompt += "\n\n# Project Context\n\n";
            prompt += "Project-specific instructions and guidelines:\n\n";
            for (const { path: filePath, content } of contextFiles) {
                prompt += `## ${filePath}\n\n${content}\n\n`;
            }
        }
        // Append skills section (if read or Skill tool is available)
        const customPromptHasSkillAccess = !selectedTools || selectedTools.includes("read") || selectedTools.includes("Skill");
        if (customPromptHasSkillAccess && skills.length > 0) {
            prompt += formatSkillsForPrompt(skills);
        }
        // Add date/time and working directory last
        prompt += `\nCurrent date and time: ${dateTime}`;
        prompt += `\nCurrent working directory: ${resolvedCwd}`;
        // Append promptGuidelines from extension-registered tools.
        // Without this, tools registered via pi.registerTool() with promptGuidelines
        // have their definitions reach the API but the model has no guidance on when
        // to use them (#1184).
        if (promptGuidelines && promptGuidelines.length > 0) {
            prompt += "\n\n";
            for (const guideline of promptGuidelines) {
                prompt += guideline + "\n";
            }
        }
        return prompt;
    }
    // Get absolute paths to documentation and examples
    const readmePath = getReadmePath();
    const docsPath = getDocsPath();
    const examplesPath = getExamplesPath();
    // Build tools list based on selected tools.
    // Built-ins use toolDescriptions. Custom tools can provide one-line snippets.
    const tools = selectedTools || ["read", "bash", "edit", "write"];
    const toolsList = tools.length > 0
        ? tools
            .map((name) => {
            const snippet = toolSnippets?.[name] ?? toolDescriptions[name] ?? name;
            return `- ${name}: ${snippet}`;
        })
            .join("\n")
        : "(none)";
    // Build guidelines based on which tools are actually available
    const guidelinesList = [];
    const guidelinesSet = new Set();
    const addGuideline = (guideline) => {
        if (guidelinesSet.has(guideline)) {
            return;
        }
        guidelinesSet.add(guideline);
        guidelinesList.push(guideline);
    };
    const hasBash = tools.includes("bash");
    const hasEdit = tools.includes("edit");
    const hasWrite = tools.includes("write");
    const hasGrep = tools.includes("grep");
    const hasFind = tools.includes("find");
    const hasLs = tools.includes("ls");
    const hasRead = tools.includes("read");
    const hasLsp = tools.includes("lsp");
    // File exploration guidelines
    if (hasBash && !hasGrep && !hasFind && !hasLs) {
        addGuideline("Use bash for file operations like ls, rg, find");
    }
    else if (hasBash && (hasGrep || hasFind || hasLs)) {
        addGuideline("Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)");
    }
    // Read before edit guideline
    if (hasRead && hasEdit) {
        addGuideline("Use read to examine files before editing. You must use this tool instead of cat or sed.");
    }
    // Edit guideline
    if (hasEdit) {
        addGuideline("Use edit for precise changes (old text must match exactly)");
    }
    // Write guideline
    if (hasWrite) {
        addGuideline("Use write only for new files or complete rewrites");
    }
    // LSP guideline
    if (hasLsp) {
        addGuideline(`Use lsp as the primary tool for code navigation in typed codebases:
- Navigation: definition, type_definition, implementation, references, incoming_calls, outgoing_calls
- Understanding: hover (types + docs), signature (parameter info), symbols (file/workspace search)
- Refactoring: rename (project-wide), code_actions (quick-fixes, imports, refactors), format (formatter)
- Verification: diagnostics after edits to catch type errors immediately
- Never grep for a symbol definition when lsp can resolve it semantically
- Never shell out to a formatter when lsp format is available`);
    }
    // Output guideline (only when actually writing or executing)
    if (hasEdit || hasWrite) {
        addGuideline("When summarizing your actions, output plain text directly - do NOT use cat or bash to display what you did");
    }
    for (const guideline of promptGuidelines ?? []) {
        const normalized = guideline.trim();
        if (normalized.length > 0) {
            addGuideline(normalized);
        }
    }
    // Always include these
    addGuideline("Be concise in your responses");
    addGuideline("Show file paths clearly when working with files");
    const guidelines = guidelinesList.map((g) => `- ${g}`).join("\n");
    let prompt = `You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.

Available tools:
${toolsList}

In addition to the tools above, you may have access to other custom tools depending on the project.

Guidelines:
${guidelines}

Pi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI):
- Main documentation: ${readmePath}
- Additional docs: ${docsPath}
- Examples: ${examplesPath} (extensions, custom tools, SDK)
- When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md)
- When working on pi topics, read the docs and examples, and follow .md cross-references before implementing
- Always read pi .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;
    if (appendSection) {
        prompt += appendSection;
    }
    // Append project context files
    if (contextFiles.length > 0) {
        prompt += "\n\n# Project Context\n\n";
        prompt += "Project-specific instructions and guidelines:\n\n";
        for (const { path: filePath, content } of contextFiles) {
            prompt += `## ${filePath}\n\n${content}\n\n`;
        }
    }
    // Append skills section (if read or Skill tool is available)
    const hasSkill = tools.includes("Skill");
    if ((hasRead || hasSkill) && skills.length > 0) {
        prompt += formatSkillsForPrompt(skills);
    }
    // Add date/time and working directory last
    prompt += `\nCurrent date and time: ${dateTime}`;
    prompt += `\nCurrent working directory: ${resolvedCwd}`;
    return prompt;
}
//# sourceMappingURL=system-prompt.js.map