






















11import ignore from "ignore";
2-import { parse } from "yaml";
3-import { type ExecutionEnv, type FileInfo, type Result, type Skill, toError } from "./types.js";
2+import {
3+basenameEnvPath,
4+dirnameEnvPath,
5+joinEnvPath,
6+parseFrontmatter,
7+relativeEnvPath,
8+resolveFileInfoKind as resolveKind,
9+} from "./file-loader-utils.js";
10+import { type ExecutionEnv, type Result, type Skill } from "./types.js";
411512const MAX_NAME_LENGTH = 64;
613const MAX_DESCRIPTION_LENGTH = 1024;
@@ -374,90 +381,3 @@ function validateDescription(description: string | undefined): string[] {
374381}
375382return errors;
376383}
377-378-function parseFrontmatter(
379-content: string,
380-): Result<{ frontmatter: Record<string, unknown>; body: string }, Error> {
381-try {
382-const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
383-if (!normalized.startsWith("---")) {
384-return { ok: true, value: { frontmatter: {}, body: normalized } };
385-}
386-const endIndex = normalized.indexOf("\n---", 3);
387-if (endIndex === -1) {
388-return { ok: true, value: { frontmatter: {}, body: normalized } };
389-}
390-const yamlString = normalized.slice(4, endIndex);
391-const body = normalized.slice(endIndex + 4).trim();
392-return {
393-ok: true,
394-value: { frontmatter: (parse(yamlString) ?? {}) as Record<string, unknown>, body },
395-};
396-} catch (error) {
397-return { ok: false, error: toError(error) };
398-}
399-}
400-401-async function resolveKind(
402-env: ExecutionEnv,
403-info: FileInfo,
404-diagnostics: SkillDiagnostic[],
405-): Promise<"file" | "directory" | undefined> {
406-if (info.kind === "file" || info.kind === "directory") {
407-return info.kind;
408-}
409-const canonicalPath = await env.canonicalPath(info.path);
410-if (!canonicalPath.ok) {
411-if (canonicalPath.error.code !== "not_found") {
412-diagnostics.push({
413-type: "warning",
414-code: "file_info_failed",
415-message: canonicalPath.error.message,
416-path: info.path,
417-});
418-}
419-return undefined;
420-}
421-const target = await env.fileInfo(canonicalPath.value);
422-if (!target.ok) {
423-if (target.error.code !== "not_found") {
424-diagnostics.push({
425-type: "warning",
426-code: "file_info_failed",
427-message: target.error.message,
428-path: info.path,
429-});
430-}
431-return undefined;
432-}
433-return target.value.kind === "file" || target.value.kind === "directory"
434- ? target.value.kind
435- : undefined;
436-}
437-438-function joinEnvPath(base: string, child: string): string {
439-return `${base.replace(/\/+$/, "")}/${child.replace(/^\/+/, "")}`;
440-}
441-442-function dirnameEnvPath(path: string): string {
443-const normalized = path.replace(/\/+$/, "");
444-const slashIndex = normalized.lastIndexOf("/");
445-return slashIndex <= 0 ? "/" : normalized.slice(0, slashIndex);
446-}
447-448-function basenameEnvPath(path: string): string {
449-const normalized = path.replace(/\/+$/, "");
450-const slashIndex = normalized.lastIndexOf("/");
451-return slashIndex === -1 ? normalized : normalized.slice(slashIndex + 1);
452-}
453-454-function relativeEnvPath(root: string, path: string): string {
455-const normalizedRoot = root.replace(/\/+$/, "");
456-const normalizedPath = path.replace(/\/+$/, "");
457-if (normalizedPath === normalizedRoot) {
458-return "";
459-}
460-return normalizedPath.startsWith(`${normalizedRoot}/`)
461- ? normalizedPath.slice(normalizedRoot.length + 1)
462- : normalizedPath.replace(/^\/+/, "");
463-}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。