nexrall-code 0.5.94 → 0.5.95
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/index.js +163 -38
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11654,17 +11654,86 @@ var require_frontmatter = __commonJS({
|
|
|
11654
11654
|
"use strict";
|
|
11655
11655
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
11656
11656
|
exports2.parseFrontmatter = parseFrontmatter;
|
|
11657
|
+
var TOP_LEVEL_KEY = /^([A-Za-z0-9_-]+)\s*:\s*(.*)$/;
|
|
11658
|
+
var BLOCK_SCALAR = /^[|>][+-]?$/;
|
|
11659
|
+
function leadingIndent(line) {
|
|
11660
|
+
const m2 = /^[ \t]*/.exec(line);
|
|
11661
|
+
return m2 ? m2[0].length : 0;
|
|
11662
|
+
}
|
|
11663
|
+
function unquote(v) {
|
|
11664
|
+
return v.trim().replace(/^["']|["']$/g, "");
|
|
11665
|
+
}
|
|
11657
11666
|
function parseFrontmatter(raw) {
|
|
11658
11667
|
const m2 = /^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(raw);
|
|
11659
11668
|
if (!m2)
|
|
11660
|
-
return { meta: {}, body: raw.trim() };
|
|
11669
|
+
return { meta: {}, body: raw.trim(), ok: false };
|
|
11670
|
+
const lines = m2[1].split(/\r?\n/);
|
|
11661
11671
|
const meta = {};
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11672
|
+
let nested;
|
|
11673
|
+
let i2 = 0;
|
|
11674
|
+
while (i2 < lines.length) {
|
|
11675
|
+
const line = lines[i2];
|
|
11676
|
+
if (!line.trim() || leadingIndent(line) > 0) {
|
|
11677
|
+
i2++;
|
|
11678
|
+
continue;
|
|
11679
|
+
}
|
|
11680
|
+
const kv = TOP_LEVEL_KEY.exec(line.trim());
|
|
11681
|
+
if (!kv) {
|
|
11682
|
+
i2++;
|
|
11683
|
+
continue;
|
|
11684
|
+
}
|
|
11685
|
+
const key = kv[1].toLowerCase();
|
|
11686
|
+
const value = kv[2].trim();
|
|
11687
|
+
const continuation = [];
|
|
11688
|
+
let j = i2 + 1;
|
|
11689
|
+
while (j < lines.length && (leadingIndent(lines[j]) > 0 || !lines[j].trim())) {
|
|
11690
|
+
continuation.push(lines[j]);
|
|
11691
|
+
j++;
|
|
11692
|
+
}
|
|
11693
|
+
while (continuation.length && !continuation[continuation.length - 1].trim())
|
|
11694
|
+
continuation.pop();
|
|
11695
|
+
if (BLOCK_SCALAR.test(value)) {
|
|
11696
|
+
const folded = value.startsWith(">");
|
|
11697
|
+
const base = continuation.length ? leadingIndent(continuation.find((l2) => l2.trim()) ?? continuation[0]) : 0;
|
|
11698
|
+
const dedented = continuation.map((l2) => l2.trim() ? l2.slice(Math.min(base, leadingIndent(l2))) : "");
|
|
11699
|
+
meta[key] = folded ? dedented.join(" ").replace(/\s+/g, " ").trim() : dedented.join("\n").trim();
|
|
11700
|
+
} else if (value === "") {
|
|
11701
|
+
const looksNested = continuation.length > 0 && continuation.every((l2) => !l2.trim() || TOP_LEVEL_KEY.test(l2.trim()));
|
|
11702
|
+
if (looksNested && continuation.some((l2) => l2.trim())) {
|
|
11703
|
+
const map = {};
|
|
11704
|
+
for (const l2 of continuation) {
|
|
11705
|
+
const sub = TOP_LEVEL_KEY.exec(l2.trim());
|
|
11706
|
+
if (sub)
|
|
11707
|
+
map[sub[1].toLowerCase()] = unquote(sub[2]);
|
|
11708
|
+
}
|
|
11709
|
+
nested = nested ?? {};
|
|
11710
|
+
nested[key] = map;
|
|
11711
|
+
} else if (continuation.length) {
|
|
11712
|
+
meta[key] = [value, ...continuation.map((l2) => l2.trim())].filter(Boolean).join(" ").trim();
|
|
11713
|
+
} else {
|
|
11714
|
+
meta[key] = "";
|
|
11715
|
+
}
|
|
11716
|
+
} else {
|
|
11717
|
+
const looksNested = continuation.length > 0 && continuation.every((l2) => !l2.trim() || TOP_LEVEL_KEY.test(l2.trim()));
|
|
11718
|
+
if (continuation.length && !looksNested) {
|
|
11719
|
+
meta[key] = unquote([value, ...continuation.map((l2) => l2.trim())].join(" "));
|
|
11720
|
+
} else if (continuation.length && looksNested) {
|
|
11721
|
+
meta[key] = unquote(value);
|
|
11722
|
+
const map = {};
|
|
11723
|
+
for (const l2 of continuation) {
|
|
11724
|
+
const sub = TOP_LEVEL_KEY.exec(l2.trim());
|
|
11725
|
+
if (sub)
|
|
11726
|
+
map[sub[1].toLowerCase()] = unquote(sub[2]);
|
|
11727
|
+
}
|
|
11728
|
+
nested = nested ?? {};
|
|
11729
|
+
nested[key] = map;
|
|
11730
|
+
} else {
|
|
11731
|
+
meta[key] = unquote(value);
|
|
11732
|
+
}
|
|
11733
|
+
}
|
|
11734
|
+
i2 = j;
|
|
11666
11735
|
}
|
|
11667
|
-
return { meta, body: (m2[2] ?? "").trim() };
|
|
11736
|
+
return { meta, body: (m2[2] ?? "").trim(), nested, ok: true };
|
|
11668
11737
|
}
|
|
11669
11738
|
}
|
|
11670
11739
|
});
|
|
@@ -11898,6 +11967,7 @@ var require_skills = __commonJS({
|
|
|
11898
11967
|
};
|
|
11899
11968
|
}();
|
|
11900
11969
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
11970
|
+
exports2.loadSkillsWithWarnings = loadSkillsWithWarnings;
|
|
11901
11971
|
exports2.loadSkills = loadSkills2;
|
|
11902
11972
|
exports2.findSkill = findSkill2;
|
|
11903
11973
|
exports2.autoInvokableSkills = autoInvokableSkills;
|
|
@@ -11910,6 +11980,19 @@ var require_skills = __commonJS({
|
|
|
11910
11980
|
var index_1 = require_plugins();
|
|
11911
11981
|
var loader_1 = require_loader();
|
|
11912
11982
|
var frontmatter_1 = require_frontmatter();
|
|
11983
|
+
var KNOWN_META_KEYS = /* @__PURE__ */ new Set([
|
|
11984
|
+
"name",
|
|
11985
|
+
"description",
|
|
11986
|
+
"model",
|
|
11987
|
+
"mode",
|
|
11988
|
+
"disable-model-invocation",
|
|
11989
|
+
"user-invocable",
|
|
11990
|
+
"license",
|
|
11991
|
+
"compatibility",
|
|
11992
|
+
"metadata",
|
|
11993
|
+
"allowed-tools"
|
|
11994
|
+
]);
|
|
11995
|
+
var SPEC_NAME_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
11913
11996
|
function parseBool(v, fallback) {
|
|
11914
11997
|
if (v === void 0)
|
|
11915
11998
|
return fallback;
|
|
@@ -11920,7 +12003,13 @@ var require_skills = __commonJS({
|
|
|
11920
12003
|
return false;
|
|
11921
12004
|
return fallback;
|
|
11922
12005
|
}
|
|
11923
|
-
function
|
|
12006
|
+
function parseSpaceList(v) {
|
|
12007
|
+
if (!v)
|
|
12008
|
+
return void 0;
|
|
12009
|
+
const items = v.split(/[,\s]+/).map((t2) => t2.trim()).filter(Boolean);
|
|
12010
|
+
return items.length ? items : void 0;
|
|
12011
|
+
}
|
|
12012
|
+
function toSkill(meta, body, name, source2, dir, nested) {
|
|
11924
12013
|
const model = ["turbo", "pro", "ultra"].find((x2) => x2 === (meta.model ?? "").toLowerCase());
|
|
11925
12014
|
return {
|
|
11926
12015
|
name,
|
|
@@ -11931,10 +12020,38 @@ var require_skills = __commonJS({
|
|
|
11931
12020
|
source: source2,
|
|
11932
12021
|
dir,
|
|
11933
12022
|
disableModelInvocation: parseBool(meta["disable-model-invocation"], false),
|
|
11934
|
-
userInvocable: parseBool(meta["user-invocable"], true)
|
|
12023
|
+
userInvocable: parseBool(meta["user-invocable"], true),
|
|
12024
|
+
license: meta.license || void 0,
|
|
12025
|
+
compatibility: meta.compatibility || void 0,
|
|
12026
|
+
metadata: nested?.metadata,
|
|
12027
|
+
allowedTools: parseSpaceList(meta["allowed-tools"])
|
|
11935
12028
|
};
|
|
11936
12029
|
}
|
|
11937
|
-
function
|
|
12030
|
+
function validateSkillMeta(meta, rawName, effectiveName, dirName, file, warnings) {
|
|
12031
|
+
if (!warnings)
|
|
12032
|
+
return;
|
|
12033
|
+
if (!SPEC_NAME_RE.test(rawName)) {
|
|
12034
|
+
warnings.push({
|
|
12035
|
+
file,
|
|
12036
|
+
name: effectiveName,
|
|
12037
|
+
message: `name "${rawName}" does not match the agentskills.io convention (lowercase letters, numbers, and single hyphens only) \u2014 loaded anyway, but other clients reading this skill may warn or reject it.`
|
|
12038
|
+
});
|
|
12039
|
+
} else if (rawName.length > 64) {
|
|
12040
|
+
warnings.push({ file, name: effectiveName, message: `name is ${rawName.length} characters \u2014 the spec caps this at 64. Loaded anyway.` });
|
|
12041
|
+
}
|
|
12042
|
+
if (dirName !== void 0 && meta.name && meta.name.trim().toLowerCase() !== dirName.toLowerCase()) {
|
|
12043
|
+
warnings.push({
|
|
12044
|
+
file,
|
|
12045
|
+
name: effectiveName,
|
|
12046
|
+
message: `frontmatter name "${meta.name}" does not match its directory name "${dirName}" \u2014 the spec requires them to match for cross-client compatibility. Loaded anyway, using the frontmatter name.`
|
|
12047
|
+
});
|
|
12048
|
+
}
|
|
12049
|
+
const strayKeys = Object.keys(meta).filter((k) => !KNOWN_META_KEYS.has(k));
|
|
12050
|
+
if (strayKeys.length) {
|
|
12051
|
+
warnings.push({ file, name: effectiveName, message: `has unrecognised frontmatter key(s): ${strayKeys.join(", ")} \u2014 these are ignored.` });
|
|
12052
|
+
}
|
|
12053
|
+
}
|
|
12054
|
+
function loadFlatCommandDir(dir, source2, into, warnings) {
|
|
11938
12055
|
let files;
|
|
11939
12056
|
try {
|
|
11940
12057
|
files = fs9.readdirSync(dir).filter((f3) => f3.endsWith(".md"));
|
|
@@ -11942,20 +12059,24 @@ var require_skills = __commonJS({
|
|
|
11942
12059
|
return;
|
|
11943
12060
|
}
|
|
11944
12061
|
for (const file of files) {
|
|
12062
|
+
const full = path7.join(dir, file);
|
|
11945
12063
|
try {
|
|
11946
|
-
const raw = fs9.readFileSync(
|
|
12064
|
+
const raw = fs9.readFileSync(full, "utf-8");
|
|
11947
12065
|
const { meta, body } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
11948
|
-
const
|
|
12066
|
+
const rawName = (meta.name || path7.basename(file, ".md")).trim();
|
|
12067
|
+
const name = rawName.toLowerCase();
|
|
11949
12068
|
if (!name)
|
|
11950
12069
|
continue;
|
|
11951
12070
|
if (source2 !== "project" && into.has(name))
|
|
11952
12071
|
continue;
|
|
12072
|
+
validateSkillMeta(meta, rawName, name, void 0, full, warnings);
|
|
11953
12073
|
into.set(name, toSkill(meta, body, name, source2));
|
|
11954
|
-
} catch {
|
|
12074
|
+
} catch (err) {
|
|
12075
|
+
warnings?.push({ file: full, name: path7.basename(file, ".md"), message: `could not be read or parsed (${err.message}) \u2014 skipped.` });
|
|
11955
12076
|
}
|
|
11956
12077
|
}
|
|
11957
12078
|
}
|
|
11958
|
-
function loadSkillDir(root, source2, into) {
|
|
12079
|
+
function loadSkillDir(root, source2, into, warnings) {
|
|
11959
12080
|
let entries;
|
|
11960
12081
|
try {
|
|
11961
12082
|
entries = fs9.readdirSync(root, { withFileTypes: true });
|
|
@@ -11975,14 +12096,17 @@ var require_skills = __commonJS({
|
|
|
11975
12096
|
}
|
|
11976
12097
|
try {
|
|
11977
12098
|
const raw = fs9.readFileSync(skillFile, "utf-8");
|
|
11978
|
-
const { meta, body } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
11979
|
-
const
|
|
12099
|
+
const { meta, body, nested } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
12100
|
+
const rawName = (meta.name || entry.name).trim();
|
|
12101
|
+
const name = rawName.toLowerCase();
|
|
11980
12102
|
if (!name)
|
|
11981
12103
|
continue;
|
|
11982
12104
|
if (source2 !== "project" && into.has(name))
|
|
11983
12105
|
continue;
|
|
11984
|
-
|
|
11985
|
-
|
|
12106
|
+
validateSkillMeta(meta, rawName, name, entry.name, skillFile, warnings);
|
|
12107
|
+
into.set(name, toSkill(meta, body, name, source2, skillDir, nested));
|
|
12108
|
+
} catch (err) {
|
|
12109
|
+
warnings?.push({ file: skillFile, name: entry.name, message: `could not be read or parsed (${err.message}) \u2014 skipped.` });
|
|
11986
12110
|
}
|
|
11987
12111
|
}
|
|
11988
12112
|
}
|
|
@@ -12022,21 +12146,27 @@ var require_skills = __commonJS({
|
|
|
12022
12146
|
].join("\n")
|
|
12023
12147
|
}
|
|
12024
12148
|
];
|
|
12025
|
-
function
|
|
12149
|
+
function loadSkillsWithWarnings(workDir) {
|
|
12026
12150
|
const out = /* @__PURE__ */ new Map();
|
|
12027
|
-
|
|
12028
|
-
loadSkillDir(path7.join(workDir, ".
|
|
12029
|
-
loadFlatCommandDir(path7.join(
|
|
12030
|
-
loadSkillDir(path7.join(
|
|
12151
|
+
const warnings = [];
|
|
12152
|
+
loadSkillDir(path7.join(workDir, ".agents", "skills"), "project", out, warnings);
|
|
12153
|
+
loadFlatCommandDir(path7.join(workDir, ".nexrall", "commands"), "project", out, warnings);
|
|
12154
|
+
loadSkillDir(path7.join(workDir, ".nexrall", "skills"), "project", out, warnings);
|
|
12155
|
+
loadFlatCommandDir(path7.join(os6.homedir(), ".nexrall", "commands"), "global", out, warnings);
|
|
12156
|
+
loadSkillDir(path7.join(os6.homedir(), ".nexrall", "skills"), "global", out, warnings);
|
|
12157
|
+
loadSkillDir(path7.join(os6.homedir(), ".agents", "skills"), "global", out, warnings);
|
|
12031
12158
|
for (const dir of (0, index_1.pluginAssetDirs)(workDir, "commands"))
|
|
12032
|
-
loadFlatCommandDir(dir, "plugin", out);
|
|
12159
|
+
loadFlatCommandDir(dir, "plugin", out, warnings);
|
|
12033
12160
|
for (const dir of (0, index_1.pluginAssetDirs)(workDir, "skills"))
|
|
12034
|
-
loadSkillDir(dir, "plugin", out);
|
|
12161
|
+
loadSkillDir(dir, "plugin", out, warnings);
|
|
12035
12162
|
for (const skill of BUILTIN_SKILLS) {
|
|
12036
12163
|
if (!out.has(skill.name))
|
|
12037
12164
|
out.set(skill.name, skill);
|
|
12038
12165
|
}
|
|
12039
|
-
return [...out.values()];
|
|
12166
|
+
return { skills: [...out.values()], warnings };
|
|
12167
|
+
}
|
|
12168
|
+
function loadSkills2(workDir) {
|
|
12169
|
+
return loadSkillsWithWarnings(workDir).skills;
|
|
12040
12170
|
}
|
|
12041
12171
|
function findSkill2(skills, name) {
|
|
12042
12172
|
const want = name.replace(/^\//, "").trim().toLowerCase();
|
|
@@ -101639,6 +101769,7 @@ var require_agentTypes = __commonJS({
|
|
|
101639
101769
|
var path7 = __importStar(__require("path"));
|
|
101640
101770
|
var os6 = __importStar(__require("os"));
|
|
101641
101771
|
var index_1 = require_plugins();
|
|
101772
|
+
var frontmatter_1 = require_frontmatter();
|
|
101642
101773
|
var VALID_MEMORY_SCOPES = ["project", "user", "local"];
|
|
101643
101774
|
function parseMemoryScope(v) {
|
|
101644
101775
|
const s2 = (v ?? "").trim().toLowerCase();
|
|
@@ -101992,18 +102123,6 @@ var require_agentTypes = __commonJS({
|
|
|
101992
102123
|
"ultra",
|
|
101993
102124
|
"fast"
|
|
101994
102125
|
];
|
|
101995
|
-
function parseFrontmatter(raw) {
|
|
101996
|
-
const m2 = /^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(raw);
|
|
101997
|
-
if (!m2)
|
|
101998
|
-
return { meta: {}, body: raw.trim(), ok: false };
|
|
101999
|
-
const meta = {};
|
|
102000
|
-
for (const line of m2[1].split(/\r?\n/)) {
|
|
102001
|
-
const kv = /^([A-Za-z0-9_-]+)\s*:\s*(.*)$/.exec(line.trim());
|
|
102002
|
-
if (kv)
|
|
102003
|
-
meta[kv[1].toLowerCase()] = kv[2].trim().replace(/^["']|["']$/g, "");
|
|
102004
|
-
}
|
|
102005
|
-
return { meta, body: (m2[2] ?? "").trim(), ok: true };
|
|
102006
|
-
}
|
|
102007
102126
|
function parseModel(v) {
|
|
102008
102127
|
const raw = (v ?? "").trim();
|
|
102009
102128
|
if (!raw)
|
|
@@ -102044,7 +102163,7 @@ var require_agentTypes = __commonJS({
|
|
|
102044
102163
|
warnings.push({ file: full, agent: path7.basename(entry.name, ".md"), message: `could not be read (${err.message}) \u2014 this agent was skipped` });
|
|
102045
102164
|
continue;
|
|
102046
102165
|
}
|
|
102047
|
-
const { meta, body, ok } = parseFrontmatter(raw);
|
|
102166
|
+
const { meta, body, ok } = (0, frontmatter_1.parseFrontmatter)(raw);
|
|
102048
102167
|
const name = (meta.name || path7.basename(entry.name, ".md")).trim();
|
|
102049
102168
|
if (!name)
|
|
102050
102169
|
continue;
|
|
@@ -106956,6 +107075,9 @@ var require_trust = __commonJS({
|
|
|
106956
107075
|
if (exists(".nexrall", "agents")) {
|
|
106957
107076
|
signals.push(".nexrall/agents/ \u2014 custom sub-agent definitions");
|
|
106958
107077
|
}
|
|
107078
|
+
if (exists(".agents", "skills")) {
|
|
107079
|
+
signals.push(".agents/skills/ \u2014 cross-client agent playbooks (agentskills.io convention)");
|
|
107080
|
+
}
|
|
106959
107081
|
return signals;
|
|
106960
107082
|
}
|
|
106961
107083
|
}
|
|
@@ -143340,6 +143462,9 @@ function detectTrustSignals(dir) {
|
|
|
143340
143462
|
if (exists(".nexrall", "agents")) {
|
|
143341
143463
|
signals.push(".nexrall/agents/ \u2014 custom sub-agent definitions");
|
|
143342
143464
|
}
|
|
143465
|
+
if (exists(".agents", "skills")) {
|
|
143466
|
+
signals.push(".agents/skills/ \u2014 cross-client agent playbooks (agentskills.io convention)");
|
|
143467
|
+
}
|
|
143343
143468
|
return signals;
|
|
143344
143469
|
}
|
|
143345
143470
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexrall-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.95",
|
|
4
4
|
"description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"release": "node build.js && node scripts/upload-release.cjs"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@nexrall/code-core": "^1.4.
|
|
44
|
+
"@nexrall/code-core": "^1.4.48",
|
|
45
45
|
"chalk": "^5.3.0",
|
|
46
46
|
"commander": "^12.0.0",
|
|
47
47
|
"diff": "^5.2.0",
|