'use strict';

var chunkAR7VSXHH_cjs = require('./chunk-AR7VSXHH.cjs');
var chunkHDIYJI2Z_cjs = require('./chunk-HDIYJI2Z.cjs');
var chunkHXICAUTW_cjs = require('./chunk-HXICAUTW.cjs');
var chunkDRDVJ35H_cjs = require('./chunk-DRDVJ35H.cjs');
var chunkZ7LCIYK7_cjs = require('./chunk-Z7LCIYK7.cjs');
var chunkN54Q3AQR_cjs = require('./chunk-N54Q3AQR.cjs');
var chunk64ITUOXI_cjs = require('./chunk-64ITUOXI.cjs');
var v4 = require('zod/v4');

var builderRegistryEntrySchema = v4.z.object({
  id: v4.z.literal("skills-sh").describe("Stable registry identifier"),
  enabled: v4.z.boolean().describe("Whether this registry is enabled in the running deployment"),
  label: v4.z.string().describe("Human-readable registry name")
});
var builderRegistriesResponseSchema = v4.z.object({
  registries: v4.z.array(builderRegistryEntrySchema)
});
var builderRegistryPathParams = v4.z.object({
  registryId: v4.z.string().describe('Registry identifier (e.g. "skills-sh")')
});
var builderRegistrySearchQuerySchema = v4.z.object({
  q: v4.z.string().describe("Search query"),
  limit: v4.z.coerce.number().int().min(1).max(100).optional().default(10).describe("Maximum number of results (1-100)")
});
var builderRegistryPopularQuerySchema = v4.z.object({
  limit: v4.z.coerce.number().int().min(1).max(100).optional().default(10).describe("Maximum number of results (1-100)"),
  offset: v4.z.coerce.number().int().min(0).optional().default(0).describe("Offset for pagination (must be a multiple of `limit`)")
}).refine((args) => args.offset % args.limit === 0, {
  message: "offset must be a multiple of limit (the upstream registry pages by `limit`)",
  path: ["offset"]
});
var builderRegistryPreviewQuerySchema = v4.z.object({
  owner: v4.z.string().describe("GitHub repository owner"),
  repo: v4.z.string().describe("GitHub repository name"),
  path: v4.z.string().describe("Skill name within repo")
});
var builderRegistryInstallBodySchema = v4.z.object({
  owner: v4.z.string().describe("GitHub repository owner"),
  repo: v4.z.string().describe("GitHub repository name"),
  skillName: v4.z.string().describe("Skill name from the registry"),
  visibility: v4.z.enum(["private", "public"]).optional().describe("Visibility for the new stored skill")
});
var builderRegistryInstallResponseSchema = v4.z.object({
  storedSkillId: v4.z.string().describe("Id of the newly created stored skill"),
  name: v4.z.string().describe("Resolved skill name"),
  filesWritten: v4.z.number().describe("Number of files materialized into the skill version snapshot")
});

// src/server/handlers/builder-registry.ts
var REGISTRY_LABELS = {
  "skills-sh": "skills.sh"
};
async function resolveRegistries(mastra) {
  const editor = mastra.getEditor();
  if (!editor || typeof editor.resolveBuilder !== "function") {
    return [{ id: "skills-sh", enabled: false, label: REGISTRY_LABELS["skills-sh"] }];
  }
  const builder = await editor.resolveBuilder();
  const registries = builder?.getRegistries?.();
  return [
    {
      id: "skills-sh",
      enabled: registries?.skillsSh?.enabled === true,
      label: REGISTRY_LABELS["skills-sh"]
    }
  ];
}
async function requireEnabledRegistry(mastra, registryId) {
  const list = await resolveRegistries(mastra);
  const match = list.find((r) => r.id === registryId);
  if (!match || !match.enabled) {
    throw new chunk64ITUOXI_cjs.HTTPException(404, { message: "Registry not found" });
  }
}
function buildFileTree(files) {
  const root = [];
  for (const file of files) {
    const safePath = chunkAR7VSXHH_cjs.assertSafeFilePath(file.path);
    const segments = safePath.split("/").filter(Boolean);
    if (segments.length === 0) continue;
    let cursor = root;
    for (let i = 0; i < segments.length - 1; i++) {
      const segment = segments[i];
      let folder = cursor.find((node) => node.type === "folder" && node.name === segment);
      if (!folder) {
        folder = { name: segment, type: "folder", children: [] };
        cursor.push(folder);
      }
      if (!folder.children) folder.children = [];
      cursor = folder.children;
    }
    const fileName = segments[segments.length - 1];
    const content = file.encoding === "base64" ? Buffer.from(file.content, "base64").toString("utf-8") : file.content;
    cursor.push({ name: fileName, type: "file", content });
  }
  return root;
}
function parseSkillSnapshot(files) {
  const skillMd = files.find((f) => f.path === "SKILL.md");
  if (!skillMd) return null;
  const raw = skillMd.encoding === "base64" ? Buffer.from(skillMd.content, "base64").toString("utf-8") : skillMd.content;
  const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
  if (!fmMatch) {
    return { instructions: raw.trim() };
  }
  const fmBlock = fmMatch[1] ?? "";
  const body = fmMatch[2] ?? "";
  const frontmatter = {};
  for (const line of fmBlock.split(/\r?\n/)) {
    const m = line.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
    if (!m) continue;
    const key = m[1];
    const value = m[2] ?? "";
    if (!key) continue;
    frontmatter[key] = value.trim().replace(/^["'](.*)["']$/, "$1");
  }
  return {
    name: frontmatter.name,
    description: frontmatter.description,
    instructions: body.trim()
  };
}
var LIST_BUILDER_REGISTRIES_ROUTE = chunkN54Q3AQR_cjs.createRoute({
  method: "GET",
  path: "/editor/builder/registries",
  responseType: "json",
  responseSchema: builderRegistriesResponseSchema,
  summary: "List available skill registries",
  description: "Returns the configured external skill registries and their enabled state.",
  tags: ["Editor"],
  requiresAuth: true,
  requiresPermission: "stored-skills:read",
  handler: async ({ mastra }) => {
    try {
      const registries = await resolveRegistries(mastra);
      return { registries };
    } catch (error) {
      return chunkZ7LCIYK7_cjs.handleError(error, "Error listing builder registries");
    }
  }
});
var BUILDER_REGISTRY_SEARCH_ROUTE = chunkN54Q3AQR_cjs.createRoute({
  method: "GET",
  path: "/editor/builder/registries/:registryId/search",
  responseType: "json",
  pathParamSchema: builderRegistryPathParams,
  queryParamSchema: builderRegistrySearchQuerySchema,
  responseSchema: chunkHXICAUTW_cjs.skillsShSearchResponseSchema,
  summary: "Search skills in a registry",
  description: "Proxies a search request to the configured registry to avoid CORS issues.",
  tags: ["Editor", "Skills"],
  requiresAuth: true,
  requiresPermission: "stored-skills:read",
  handler: async ({ mastra, registryId, q, limit }) => {
    try {
      await requireEnabledRegistry(mastra, registryId);
      return await chunkAR7VSXHH_cjs.searchSkillsSh({ q, limit });
    } catch (error) {
      if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error;
      return chunkZ7LCIYK7_cjs.handleError(error, "Error searching registry");
    }
  }
});
var BUILDER_REGISTRY_POPULAR_ROUTE = chunkN54Q3AQR_cjs.createRoute({
  method: "GET",
  path: "/editor/builder/registries/:registryId/popular",
  responseType: "json",
  pathParamSchema: builderRegistryPathParams,
  queryParamSchema: builderRegistryPopularQuerySchema,
  responseSchema: chunkHXICAUTW_cjs.skillsShListResponseSchema,
  summary: "Get popular skills from a registry",
  description: "Proxies a popular-skills request to the configured registry to avoid CORS issues.",
  tags: ["Editor", "Skills"],
  requiresAuth: true,
  requiresPermission: "stored-skills:read",
  handler: async ({ mastra, registryId, limit, offset }) => {
    try {
      await requireEnabledRegistry(mastra, registryId);
      return await chunkAR7VSXHH_cjs.getPopularSkillsSh({ limit, offset });
    } catch (error) {
      if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error;
      return chunkZ7LCIYK7_cjs.handleError(error, "Error fetching popular skills");
    }
  }
});
var BUILDER_REGISTRY_PREVIEW_ROUTE = chunkN54Q3AQR_cjs.createRoute({
  method: "GET",
  path: "/editor/builder/registries/:registryId/preview",
  responseType: "json",
  pathParamSchema: builderRegistryPathParams,
  queryParamSchema: builderRegistryPreviewQuerySchema,
  responseSchema: chunkHXICAUTW_cjs.skillsShPreviewResponseSchema,
  summary: "Preview a skill from a registry",
  description: "Fetches the SKILL.md content for a single skill in the configured registry.",
  tags: ["Editor", "Skills"],
  requiresAuth: true,
  requiresPermission: "stored-skills:read",
  handler: async ({ mastra, registryId, owner, repo, path: skillName }) => {
    try {
      await requireEnabledRegistry(mastra, registryId);
      return await chunkAR7VSXHH_cjs.previewSkillsSh({ owner, repo, skillName });
    } catch (error) {
      if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error;
      return chunkZ7LCIYK7_cjs.handleError(error, "Error fetching skill preview");
    }
  }
});
var BUILDER_REGISTRY_INSTALL_ROUTE = chunkN54Q3AQR_cjs.createRoute({
  method: "POST",
  path: "/editor/builder/registries/:registryId/install",
  responseType: "json",
  pathParamSchema: builderRegistryPathParams,
  bodySchema: builderRegistryInstallBodySchema,
  responseSchema: builderRegistryInstallResponseSchema,
  summary: "Install a registry skill into stored skills",
  description: "Fetches a skill from the configured registry and persists it as a new stored skill.",
  tags: ["Editor", "Skills"],
  requiresAuth: true,
  requiresPermission: "stored-skills:write",
  handler: async ({ mastra, requestContext, registryId, owner, repo, skillName, visibility: bodyVisibility }) => {
    try {
      await requireEnabledRegistry(mastra, registryId);
      const storage = mastra.getStorage();
      if (!storage) {
        throw new chunk64ITUOXI_cjs.HTTPException(500, { message: "Storage is not configured" });
      }
      const skillStore = await storage.getStore("skills");
      if (!skillStore) {
        throw new chunk64ITUOXI_cjs.HTTPException(500, { message: "Skills storage domain is not available" });
      }
      const result = await chunkAR7VSXHH_cjs.fetchSkillFiles(owner, repo, skillName);
      if (!result || result.files.length === 0) {
        throw new chunk64ITUOXI_cjs.HTTPException(404, {
          message: `Could not find skill "${skillName}" in ${owner}/${repo}.`
        });
      }
      const safeSkillId = chunkAR7VSXHH_cjs.assertSafeSkillName(result.skillId);
      const files = buildFileTree(result.files);
      const snapshot = parseSkillSnapshot(result.files);
      const resolvedName = snapshot?.name ?? safeSkillId;
      const description = snapshot?.description ?? `Imported from ${owner}/${repo}`;
      const id = chunkDRDVJ35H_cjs.toSlug(resolvedName) || safeSkillId;
      if (!id) {
        throw new chunk64ITUOXI_cjs.HTTPException(400, {
          message: "Could not derive skill ID from registry skill metadata."
        });
      }
      const existing = await skillStore.getById(id);
      if (existing) {
        throw new chunk64ITUOXI_cjs.HTTPException(409, {
          message: `Skill with id "${id}" already exists.`,
          // Surface the existing id so the client can deep-link.
          cause: { storedSkillId: id }
        });
      }
      const authorId = chunkHDIYJI2Z_cjs.getCallerAuthorId(requestContext) ?? void 0;
      const visibility = authorId ? bodyVisibility ?? "private" : "public";
      const instructions = snapshot?.instructions?.trim() ? snapshot.instructions : description;
      await skillStore.create({
        skill: {
          id,
          authorId,
          visibility,
          name: resolvedName,
          description,
          instructions,
          files,
          metadata: {
            origin: {
              type: "skills-sh",
              owner,
              repo,
              skillName
            }
          }
        }
      });
      return {
        storedSkillId: id,
        name: resolvedName,
        filesWritten: result.files.length
      };
    } catch (error) {
      if (error instanceof chunk64ITUOXI_cjs.HTTPException) throw error;
      return chunkZ7LCIYK7_cjs.handleError(error, "Error installing registry skill");
    }
  }
});

exports.BUILDER_REGISTRY_INSTALL_ROUTE = BUILDER_REGISTRY_INSTALL_ROUTE;
exports.BUILDER_REGISTRY_POPULAR_ROUTE = BUILDER_REGISTRY_POPULAR_ROUTE;
exports.BUILDER_REGISTRY_PREVIEW_ROUTE = BUILDER_REGISTRY_PREVIEW_ROUTE;
exports.BUILDER_REGISTRY_SEARCH_ROUTE = BUILDER_REGISTRY_SEARCH_ROUTE;
exports.LIST_BUILDER_REGISTRIES_ROUTE = LIST_BUILDER_REGISTRIES_ROUTE;
//# sourceMappingURL=chunk-4ATFZDHI.cjs.map
//# sourceMappingURL=chunk-4ATFZDHI.cjs.map