codex-relay 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src.js +76 -7
- package/package.json +1 -1
package/dist/src.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
import qrcode from "qrcode-terminal";
|
|
5
5
|
import { execFile, spawn } from "node:child_process";
|
|
6
6
|
import fs, { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
7
|
-
import { access, appendFile, copyFile, mkdir, open, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
7
|
+
import { access, appendFile, copyFile, mkdir, open, readFile, readdir, realpath, stat, writeFile } from "node:fs/promises";
|
|
8
8
|
import path, { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
import { z } from "zod";
|
|
@@ -728,8 +728,17 @@ async function listAvailableSkills(options) {
|
|
|
728
728
|
}
|
|
729
729
|
async function findSkillFiles(root) {
|
|
730
730
|
const found = [];
|
|
731
|
+
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
731
732
|
async function walk(path, depth) {
|
|
732
733
|
if (depth < 0) return;
|
|
734
|
+
let realDirectoryPath;
|
|
735
|
+
try {
|
|
736
|
+
realDirectoryPath = await realpath(path);
|
|
737
|
+
} catch {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
if (visitedDirectories.has(realDirectoryPath)) return;
|
|
741
|
+
visitedDirectories.add(realDirectoryPath);
|
|
733
742
|
let entries;
|
|
734
743
|
try {
|
|
735
744
|
entries = await readdir(path, { withFileTypes: true });
|
|
@@ -738,20 +747,34 @@ async function findSkillFiles(root) {
|
|
|
738
747
|
}
|
|
739
748
|
for (const entry of entries) {
|
|
740
749
|
const entryPath = join(path, entry.name);
|
|
741
|
-
|
|
750
|
+
const kind = await directoryEntryKind(entry, entryPath);
|
|
751
|
+
if (kind === "file" && entry.name === "SKILL.md") {
|
|
742
752
|
found.push({
|
|
743
753
|
...root,
|
|
744
754
|
path: entryPath
|
|
745
755
|
});
|
|
746
756
|
continue;
|
|
747
757
|
}
|
|
748
|
-
if (
|
|
758
|
+
if (kind !== "directory" || entry.name === "node_modules") continue;
|
|
749
759
|
await walk(entryPath, depth - 1);
|
|
750
760
|
}
|
|
751
761
|
}
|
|
752
762
|
await walk(root.path, root.maxDepth);
|
|
753
763
|
return found;
|
|
754
764
|
}
|
|
765
|
+
async function directoryEntryKind(entry, entryPath) {
|
|
766
|
+
if (entry.isFile()) return "file";
|
|
767
|
+
if (entry.isDirectory()) return "directory";
|
|
768
|
+
if (!entry.isSymbolicLink()) return null;
|
|
769
|
+
try {
|
|
770
|
+
const target = await stat(entryPath);
|
|
771
|
+
if (target.isFile()) return "file";
|
|
772
|
+
if (target.isDirectory()) return "directory";
|
|
773
|
+
} catch {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
755
778
|
async function readSkill(entry) {
|
|
756
779
|
let markdown;
|
|
757
780
|
try {
|
|
@@ -777,7 +800,7 @@ async function readSkill(entry) {
|
|
|
777
800
|
}
|
|
778
801
|
function parseSkillMarkdown(markdown) {
|
|
779
802
|
const frontmatter = parseFrontmatter(markdown);
|
|
780
|
-
const heading =
|
|
803
|
+
const heading = firstMarkdownHeading(markdownBody(markdown));
|
|
781
804
|
return {
|
|
782
805
|
description: frontmatter.description,
|
|
783
806
|
displayName: heading ? cleanHeading(heading) : void 0,
|
|
@@ -789,13 +812,59 @@ function parseFrontmatter(markdown) {
|
|
|
789
812
|
const end = markdown.indexOf("\n---", 4);
|
|
790
813
|
if (end < 0) return {};
|
|
791
814
|
const fields = {};
|
|
792
|
-
|
|
793
|
-
|
|
815
|
+
const lines = markdown.slice(4, end).split("\n");
|
|
816
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
817
|
+
const match = lines[index].match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
794
818
|
if (!match) continue;
|
|
795
|
-
|
|
819
|
+
const key = match[1];
|
|
820
|
+
const value = match[2].trim();
|
|
821
|
+
if (isBlockScalar(value)) {
|
|
822
|
+
const blockLines = [];
|
|
823
|
+
while (index + 1 < lines.length && (lines[index + 1].trim() === "" || /^\s/.test(lines[index + 1]))) {
|
|
824
|
+
index += 1;
|
|
825
|
+
blockLines.push(lines[index].replace(/^\s+/, ""));
|
|
826
|
+
}
|
|
827
|
+
fields[key] = formatBlockScalar(value, blockLines);
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
fields[key] = unquoteYamlScalar(value);
|
|
796
831
|
}
|
|
797
832
|
return fields;
|
|
798
833
|
}
|
|
834
|
+
function isBlockScalar(value) {
|
|
835
|
+
return [
|
|
836
|
+
"|",
|
|
837
|
+
"|-",
|
|
838
|
+
"|+",
|
|
839
|
+
">",
|
|
840
|
+
">-",
|
|
841
|
+
">+"
|
|
842
|
+
].includes(value);
|
|
843
|
+
}
|
|
844
|
+
function formatBlockScalar(marker, lines) {
|
|
845
|
+
const trimmedLines = lines.map((line) => line.trimEnd());
|
|
846
|
+
if (marker.startsWith("|")) return trimmedLines.join("\n").trim();
|
|
847
|
+
return trimmedLines.map((line) => line.trim()).filter(Boolean).join(" ");
|
|
848
|
+
}
|
|
849
|
+
function markdownBody(markdown) {
|
|
850
|
+
if (!markdown.startsWith("---\n")) return markdown;
|
|
851
|
+
const end = markdown.indexOf("\n---", 4);
|
|
852
|
+
if (end < 0) return markdown;
|
|
853
|
+
return markdown.slice(end + 4).replace(/^\r?\n/, "");
|
|
854
|
+
}
|
|
855
|
+
function firstMarkdownHeading(markdown) {
|
|
856
|
+
let fence;
|
|
857
|
+
for (const line of markdown.split("\n")) {
|
|
858
|
+
const fenceMatch = line.match(/^\s*(```|~~~)/);
|
|
859
|
+
if (fenceMatch) {
|
|
860
|
+
fence = fence ? void 0 : fenceMatch[1];
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
if (fence) continue;
|
|
864
|
+
const heading = line.match(/^#\s+(.+)$/)?.[1]?.trim();
|
|
865
|
+
if (heading) return heading;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
799
868
|
function unquoteYamlScalar(value) {
|
|
800
869
|
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
|
|
801
870
|
return value;
|