import type { Router } from "./router.js";
import type { ProviderName } from "../eval/llm.js";
interface DetectedLayout {
    layout: 1 | 2 | 3 | 4;
    label: string;
    pathTemplate: string;
    existingPlugins: string[];
}
interface ProjectLayoutResponse {
    root: string;
    detectedLayouts: DetectedLayout[];
    suggestedLayout: 1 | 2 | 3;
    existingSkills: Array<{
        plugin: string;
        skill: string;
    }>;
}
/**
 * Authoring engine for the skill (0734). Three first-class peer choices:
 *   - "vskill" (default): VSkill skill-builder, cross-universal across 8 agents.
 *   - "anthropic-skill-creator": Anthropic's built-in plugin, richer Claude-native
 *     schema, Claude-only. Requires the `skill-creator` plugin installed locally.
 *   - "none": skip engine assistance, emit the request body verbatim. The
 *     `metadata.engine` frontmatter key is omitted entirely.
 *
 * Anthropic and VSkill are peer engines, NOT a fallback chain — the trade-off
 * is "richer Claude-native expressiveness" vs. "portable cross-tool output".
 */
export type CreateSkillEngine = "vskill" | "anthropic-skill-creator" | "none";
export interface PluginSuggestion {
    plugin: string;
    layout: 1 | 2;
    confidence: "high" | "medium" | "low";
    reason: string;
}
/**
 * 0772 US-005 — Probe whether the project has a `.git` directory and a
 * GitHub `origin` remote. Used by `GET /api/project/github-status` to drive
 * the publish-readiness hint card on the Skill Overview tab.
 *
 * Returns a deterministic three-state result:
 *   - `no-git`     → no `.git` found by walking up from `root` (12 levels max)
 *   - `non-github` → `.git` exists but `origin` is missing or not on github.com
 *   - `github`     → `.git` exists and `origin` resolves to a github.com URL
 *
 * Uses `spawnSync` with a 250ms timeout — same pattern as the onboarding
 * detection. Any failure short-circuits to `no-git` (safe default; the UI
 * shows the bootstrap hint instead of crashing).
 */
export interface ProjectGitHubStatus {
    hasGit: boolean;
    githubOrigin: string | null;
    status: "no-git" | "non-github" | "github";
}
export declare function detectProjectGitHubStatus(root: string): ProjectGitHubStatus;
/** Detect project layout — mirrors scanSkills() logic from skill-scanner.ts */
export declare function detectProjectLayout(root: string): ProjectLayoutResponse;
export interface BuildSkillMdInput {
    name: string;
    plugin: string;
    layout: 1 | 2 | 3;
    description: string;
    /** Frontmatter `version:`. Defaults to "1.0.0" when omitted or empty. */
    version?: string;
    /** 0734: authoring engine emitted under metadata.engine. */
    engine?: CreateSkillEngine;
    model?: string;
    allowedTools?: string;
    body: string;
    tags?: string[];
    targetAgents?: string[];
}
/**
 * Public alias of the private `buildSkillMd` emitter for tests and lint scripts.
 * The underlying function is the source of truth; this export exists so
 * golden-file tests and the CI validator can exercise the emitter without
 * touching the HTTP route.
 *
 * @internal — tests must import from `__tests__/helpers/skill-md-test-helpers.ts`,
 *   not from this module. Production code MUST NOT call this.
 */
export declare function buildSkillMdForTest(data: BuildSkillMdInput): string;
/**
 * Minimal YAML frontmatter parser for test assertions — supports the shape
 * emitted by `buildSkillMd`:
 *   - top-level scalars (quoted or unquoted)
 *   - `metadata:` block with `tags:` and `target-agents:` list children
 *
 * This is intentionally narrow. For general YAML, callers should use a real
 * parser. Exported solely to avoid adding a YAML dep to the test target.
 *
 * @internal — production reads MUST go through `parseSkillFrontmatter`
 *   in api-routes.ts. Tests must import this via
 *   `__tests__/helpers/skill-md-test-helpers.ts`.
 */
export declare function parseFrontmatterForTest(content: string): Record<string, unknown> & {
    metadata: Record<string, unknown>;
};
export interface SpawnResultLike {
    status: number | null;
    stdout: string;
    stderr: string;
    error: (NodeJS.ErrnoException | Error) | undefined;
}
export interface ValidatorOptions {
    strict: boolean;
}
export interface ValidatorOutcome {
    ok: boolean;
    exitCode: 0 | 1;
    kind: "success" | "warning" | "error" | "missing-binary";
    messages: string[];
    skillPath: string;
}
/**
 * Interpret a `spawnSync("skills-ref", ["validate", path])` result into a
 * structured outcome. Pure function — no side effects, no I/O.
 */
export declare function interpretValidatorResult(skillPath: string, res: SpawnResultLike, opts: ValidatorOptions): ValidatorOutcome;
/**
 * Render a `ValidatorOutcome` to a human-readable string for CLI / server
 * log surfaces. Empty string on success (silent). Pure function.
 *
 * Color handling is deliberately omitted here — callers that want ANSI
 * colors wrap the returned string with their own formatter. That keeps the
 * helper trivially testable.
 */
export declare function formatValidatorReport(outcome: ValidatorOutcome): string;
/** Compute target directory for a new skill based on layout */
export declare function resolveSafe(base: string, relPath: string): string;
/**
 * Build a `.env.example` body from a list of secret env-var names. Each line
 * is `NAME=` with no value — the file ships placeholders only, never real
 * secrets. Caller is responsible for including a leading comment if desired.
 */
export declare function buildEnvExample(secrets: string[]): string;
/**
 * Check if a resolved path is strictly within a root directory.
 * Uses trailing separator to prevent prefix collision (e.g., /project vs /project-evil).
 */
export declare function isDraftWithinRoot(draftPath: string, root: string): boolean;
/**
 * Match a newly generated skill against existing plugins by tag/keyword overlap.
 * Returns the best-matching plugin if score exceeds threshold, or null.
 */
export declare function matchExistingPlugin(skillName: string, skillDescription: string, skillTags: string[], root: string): PluginSuggestion | null;
export declare const BODY_SYSTEM_PROMPT = "You are an expert AI skill engineer in Skill Studio. Given a user's description of what a skill should do, generate the SKILL.md body and metadata (NOT evals).\n\n## Skill Studio Best Practices\n\n### SKILL.md Anatomy\nEvery skill has YAML frontmatter (description required, name/model/allowed-tools optional) and a markdown body with instructions.\n\n### Description Quality (Frontmatter) \u2014 CRITICAL\nThe description is the PRIMARY triggering mechanism. It must be \"pushy\" to combat undertriggering:\n- Use third-person format: \"This skill should be used when the user asks to...\"\n- Include specific trigger phrases users would say (e.g., \"create X\", \"configure Y\", \"fix Z\")\n- Include explicit activation phrases: \"Make sure to use this skill whenever the user mentions...\"\n- Be concrete and specific, not vague or generic\n- BAD: \"Provides guidance for working with X\" (vague, no triggers)\n- GOOD: \"This skill should be used when the user asks to \\\"create X\\\", \\\"configure Y\\\", or \\\"troubleshoot Z\\\". Activate whenever the user mentions X-related tasks.\"\n\n### Writing Style\n- Use imperative/infinitive form (verb-first instructions), NOT second person\n- Use objective, instructional language: \"To accomplish X, do Y\" not \"You should do X\"\n- BAD: \"You should start by reading the file\" / \"You need to validate\"\n- GOOD: \"Start by reading the file\" / \"Validate the input before processing\"\n- Explain the WHY behind rules \u2014 LLMs respond better to reasoning than rigid MUST/NEVER\n\n### Progressive Disclosure\n- Keep SKILL.md lean: 500-2000 words ideal for body, under 500 lines total\n- Core concepts and essential procedures in the body\n- Structure with ## sections: Workflow, Rules, Output Format, Examples\n\n### Content Quality\n- Focus on procedural knowledge non-obvious to an AI assistant\n- Include information that helps another AI instance execute tasks effectively\n- Include concrete examples where helpful\n- Include a clear Workflow section with numbered steps\n\n### Common Mistakes to Avoid\n- Weak trigger descriptions (vague, no specific phrases)\n- Too much content without structure\n- Second-person writing style\n- Missing workflow section\n- Overly generic instructions that don't add value\n\n### Action-First Skills (Bash/tool-execution)\nWhen a skill includes allowed-tools: Bash (or Read, Write, Edit), the skill body MUST:\n- Open with an explicit execution directive: \"Execute each step immediately. Run Bash commands directly \u2014 do not ask for permission or describe plans.\"\n- Use \"Step N \u2014 [action verb]. Run this immediately:\" headers, not \"Step N: [noun] Discovery\"\n- Every step must end with a concrete, complete, copy-pasteable code block \u2014 not prose describing what the code would do\n- Include any variable values (paths, URLs, flags) directly in the code block, not as placeholders\n\n## Output Format\nReturn a JSON object with these fields:\n{\n  \"name\": \"kebab-case-name\",\n  \"description\": \"Third-person trigger description with specific activation phrases\",\n  \"model\": \"\",\n  \"allowedTools\": \"\",\n  \"body\": \"# /skill-name\\n\\nFull system prompt with ## sections\"\n}\n\nField rules:\n- name: kebab-case, concise, descriptive (e.g., \"sql-formatter\", \"api-docs-generator\")\n- description: 1-3 sentences with trigger phrases. Must pass the \"would Claude trigger on this?\" test\n- model: \"\" (any) unless task clearly requires opus-level reasoning or is trivially haiku-suitable\n- allowedTools: comma-separated list (e.g., \"Read, Write, Edit, Bash\") or \"\" for unrestricted. Only restrict when the skill genuinely shouldn't use certain tools\n- body: Complete markdown starting with # /skill-name, structured with ## sections, 500-2000 words\n\nReturn ONLY the JSON object \u2014 no code fences, no preamble.\n\nAfter the JSON, on a new line, write \"---REASONING---\" followed by a brief explanation of your design choices (why this name, why these trigger phrases, what Skill Studio rules you applied).";
export declare const EVAL_SYSTEM_PROMPT = "You are an expert AI skill evaluator. Given a skill's name, description, and purpose, generate eval test cases that verify the skill works correctly.\n\n### Eval Assertions for Action-Oriented Skills (CRITICAL)\nThe eval evaluates the LLM text response \u2014 it cannot run Bash or call tools. Assertions must check for code/commands present IN the response, not whether they were executed.\n- BAD: \"Runs a bash command to discover profiles\" (implies execution \u2014 will always fail)\n- GOOD: \"Response includes a bash code block that lists Chrome profile directories\"\n- BAD: \"Opens https://studio.youtube.com as the target URL\"\n- GOOD: \"Response includes studio.youtube.com as the target URL in a code block or command\"\n- BAD: \"Checks that the file exists before uploading\"\n- GOOD: \"Response includes a bash command checking whether the file exists (e.g., using test -f or ls)\"\n\n### Assertion Quality: Functional Over Formatting (CRITICAL)\nAssert on FUNCTIONAL correctness, not formatting or presentation details. Each assertion should test exactly ONE observable behavior (unit-test style).\n- NEVER assert on: blank lines, paragraph count, whitespace, exact heading levels, bullet formatting, sentence count, or line breaks\n- GOOD: \"The response includes a greeting that contains the name 'Anton'\" (checks functional behavior)\n- BAD: \"The greeting is a single short sentence (not multiple paragraphs)\" (tests formatting, not function)\n- GOOD: \"The response lists at least 3 benefits of TypeScript\" (checks content)\n- BAD: \"The response uses exactly 3 bullet points\" (tests formatting)\nFormatting is stylistic \u2014 it varies between LLM runs and does not indicate skill quality.\n\n## Output Format\nReturn a JSON object with these fields:\n{\n  \"evals\": [\n    {\n      \"id\": 1,\n      \"name\": \"test case name\",\n      \"prompt\": \"realistic user prompt\",\n      \"expected_output\": \"description of correct behavior\",\n      \"assertions\": [\n        { \"id\": \"a1\", \"text\": \"objectively verifiable assertion\", \"type\": \"boolean\" }\n      ]\n    }\n  ]\n}\n\nField rules:\n- evals: 2-3 realistic test cases with objectively verifiable assertions\n- Prompts should be what real users would say, not abstract test inputs\n- Each assertion must be independently verifiable by a judge LLM reading the response text\n- Each assertion should check exactly ONE functional behavior (unit-test granularity)\n\nReturn ONLY the JSON object \u2014 no code fences, no preamble.";
/**
 * Build an agent-aware system prompt by conditionally appending a
 * "## Target Agent Constraints" section when non-Claude agents are targeted.
 *
 * When targetAgents is absent, empty, or only contains "claude-code",
 * the base prompt is returned unchanged (backward compatible).
 */
export declare function buildAgentAwareSystemPrompt(basePrompt: string, targetAgents: string[] | undefined): string;
export interface GenerateSkillRequest {
    prompt: string;
    provider?: ProviderName;
    model?: string;
    targetAgents?: string[];
}
export interface GenerateSkillResult {
    name: string;
    description: string;
    model: string;
    allowedTools: string;
    body: string;
    evals: Array<{
        id: number;
        name: string;
        prompt: string;
        expected_output: string;
        assertions: Array<{
            id: string;
            text: string;
            type: string;
        }>;
    }>;
    reasoning: string;
    warning?: string;
}
export interface BodyResult {
    name: string;
    description: string;
    model: string;
    allowedTools: string;
    body: string;
    reasoning: string;
}
type EvalItem = GenerateSkillResult["evals"][number];
export interface EvalsResult {
    evals: EvalItem[];
}
export declare function parseBodyResponse(raw: string): BodyResult;
export declare function parseEvalsResponse(raw: string): EvalsResult;
export declare function mergeGenerateResults(bodySettled: PromiseSettledResult<BodyResult>, evalsSettled: PromiseSettledResult<EvalsResult>): GenerateSkillResult;
export declare function registerSkillCreateRoutes(router: Router, root: string): void;
export {};
