@fro.bot/systematic 2.33.0 → 2.33.1
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/cli.js +1 -1
- package/dist/{index-bwrrk4a8.js → index-vyzhzvap.js} +27 -24
- package/dist/index.js +16 -18
- package/dist/lib/discovered-skills.d.ts +3 -0
- package/dist/lib/skills.d.ts +6 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -515,32 +515,35 @@ function parseDeprecated(data) {
|
|
|
515
515
|
}
|
|
516
516
|
return deprecated;
|
|
517
517
|
}
|
|
518
|
+
function extractFrontmatterFromContent(content) {
|
|
519
|
+
const { data, parseError } = parseFrontmatter(content);
|
|
520
|
+
if (parseError) {
|
|
521
|
+
return { name: "", description: "" };
|
|
522
|
+
}
|
|
523
|
+
const metadata = parseMetadata(data);
|
|
524
|
+
const deprecated = parseDeprecated(data);
|
|
525
|
+
const argumentHintRaw = extractNonEmptyString(data, "argument-hint");
|
|
526
|
+
const argumentHint = argumentHintRaw?.replace(/^["']|["']$/g, "") || undefined;
|
|
527
|
+
return {
|
|
528
|
+
name: extractString(data, "name"),
|
|
529
|
+
description: extractString(data, "description"),
|
|
530
|
+
license: extractNonEmptyString(data, "license"),
|
|
531
|
+
compatibility: extractNonEmptyString(data, "compatibility"),
|
|
532
|
+
metadata,
|
|
533
|
+
deprecated,
|
|
534
|
+
disableModelInvocation: extractBoolean(data, "disable-model-invocation"),
|
|
535
|
+
userInvocable: extractBoolean(data, "user-invocable"),
|
|
536
|
+
subtask: data.context === "fork" ? true : extractBoolean(data, "subtask") ?? undefined,
|
|
537
|
+
agent: extractNonEmptyString(data, "agent"),
|
|
538
|
+
model: extractNonEmptyString(data, "model"),
|
|
539
|
+
argumentHint: argumentHint !== "" ? argumentHint : undefined,
|
|
540
|
+
allowedTools: extractNonEmptyString(data, "allowed-tools")
|
|
541
|
+
};
|
|
542
|
+
}
|
|
518
543
|
function extractFrontmatter(filePath) {
|
|
519
544
|
try {
|
|
520
545
|
const content = fs3.readFileSync(filePath, "utf8");
|
|
521
|
-
|
|
522
|
-
if (parseError) {
|
|
523
|
-
return { name: "", description: "" };
|
|
524
|
-
}
|
|
525
|
-
const metadata = parseMetadata(data);
|
|
526
|
-
const deprecated = parseDeprecated(data);
|
|
527
|
-
const argumentHintRaw = extractNonEmptyString(data, "argument-hint");
|
|
528
|
-
const argumentHint = argumentHintRaw?.replace(/^["']|["']$/g, "") || undefined;
|
|
529
|
-
return {
|
|
530
|
-
name: extractString(data, "name"),
|
|
531
|
-
description: extractString(data, "description"),
|
|
532
|
-
license: extractNonEmptyString(data, "license"),
|
|
533
|
-
compatibility: extractNonEmptyString(data, "compatibility"),
|
|
534
|
-
metadata,
|
|
535
|
-
deprecated,
|
|
536
|
-
disableModelInvocation: extractBoolean(data, "disable-model-invocation"),
|
|
537
|
-
userInvocable: extractBoolean(data, "user-invocable"),
|
|
538
|
-
subtask: data.context === "fork" ? true : extractBoolean(data, "subtask") ?? undefined,
|
|
539
|
-
agent: extractNonEmptyString(data, "agent"),
|
|
540
|
-
model: extractNonEmptyString(data, "model"),
|
|
541
|
-
argumentHint: argumentHint !== "" ? argumentHint : undefined,
|
|
542
|
-
allowedTools: extractNonEmptyString(data, "allowed-tools")
|
|
543
|
-
};
|
|
546
|
+
return extractFrontmatterFromContent(content);
|
|
544
547
|
} catch {
|
|
545
548
|
return { name: "", description: "" };
|
|
546
549
|
}
|
|
@@ -16422,4 +16425,4 @@ function extractCommandFrontmatter(content) {
|
|
|
16422
16425
|
};
|
|
16423
16426
|
}
|
|
16424
16427
|
|
|
16425
|
-
export { parseFrontmatter, isRecord, convertContent, convertFileWithCache, walkDir,
|
|
16428
|
+
export { parseFrontmatter, isRecord, convertContent, convertFileWithCache, walkDir, extractFrontmatterFromContent, findSkillsInDir, exports_external, AgentOverlaySchema, CategoryOverlaySchema, loadConfig, loadConfigWithSources, getConfigPaths, findAgentsInDir, extractAgentFrontmatter, findCommandsInDir, extractCommandFrontmatter };
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
exports_external,
|
|
7
7
|
extractAgentFrontmatter,
|
|
8
8
|
extractCommandFrontmatter,
|
|
9
|
-
|
|
9
|
+
extractFrontmatterFromContent,
|
|
10
10
|
findAgentsInDir,
|
|
11
11
|
findCommandsInDir,
|
|
12
12
|
findSkillsInDir,
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
loadConfigWithSources,
|
|
16
16
|
parseFrontmatter,
|
|
17
17
|
walkDir
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-vyzhzvap.js";
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
import
|
|
21
|
+
import fs6 from "fs";
|
|
22
22
|
import path9 from "path";
|
|
23
23
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
24
24
|
|
|
@@ -240,7 +240,6 @@ ${skillUsage}${catalogSection}
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
// src/lib/config-handler.ts
|
|
243
|
-
import fs5 from "fs";
|
|
244
243
|
import os3 from "os";
|
|
245
244
|
import path7 from "path";
|
|
246
245
|
|
|
@@ -707,15 +706,13 @@ function globSkillFiles(rootDir, subdirNames) {
|
|
|
707
706
|
return results;
|
|
708
707
|
}
|
|
709
708
|
function toDiscoveredSkill(skillPath, rootId) {
|
|
710
|
-
let
|
|
709
|
+
let content;
|
|
711
710
|
try {
|
|
712
|
-
|
|
711
|
+
content = fs3.readFileSync(skillPath, "utf8");
|
|
713
712
|
} catch {
|
|
714
713
|
return;
|
|
715
714
|
}
|
|
716
|
-
|
|
717
|
-
return;
|
|
718
|
-
const frontmatter = extractFrontmatter(skillPath);
|
|
715
|
+
const frontmatter = extractFrontmatterFromContent(content);
|
|
719
716
|
const name = frontmatter.name;
|
|
720
717
|
if (!name || !isValidSkillName(name))
|
|
721
718
|
return;
|
|
@@ -723,6 +720,7 @@ function toDiscoveredSkill(skillPath, rootId) {
|
|
|
723
720
|
name,
|
|
724
721
|
description: frontmatter.description,
|
|
725
722
|
frontmatter,
|
|
723
|
+
body: parseFrontmatter(content).body,
|
|
726
724
|
skillPath,
|
|
727
725
|
root: rootId
|
|
728
726
|
};
|
|
@@ -1226,10 +1224,8 @@ function collectSkillsAsCommands(dir, disabledSkills) {
|
|
|
1226
1224
|
function loadDiscoveredSkillAsCommand(skill) {
|
|
1227
1225
|
const description = formatSkillDescription(skill.description, skill.name);
|
|
1228
1226
|
if (skill.frontmatter.disableModelInvocation === true) {
|
|
1229
|
-
const content = fs5.readFileSync(skill.skillPath, "utf8");
|
|
1230
|
-
const { body } = parseFrontmatter(content);
|
|
1231
1227
|
return {
|
|
1232
|
-
template: wrapSkillTemplate(skill.skillPath, body),
|
|
1228
|
+
template: wrapSkillTemplate(skill.skillPath, skill.body),
|
|
1233
1229
|
description
|
|
1234
1230
|
};
|
|
1235
1231
|
}
|
|
@@ -1245,7 +1241,7 @@ function buildDiscoveredSkillShimTemplate(skillName) {
|
|
|
1245
1241
|
$ARGUMENTS
|
|
1246
1242
|
</user-request>`;
|
|
1247
1243
|
}
|
|
1248
|
-
function collectDiscoveredSkillsAsCommands(startDir, homeDir, configDir, opencodeConfigDirOverride) {
|
|
1244
|
+
function collectDiscoveredSkillsAsCommands(startDir, homeDir, configDir, opencodeConfigDirOverride, disabledCommands) {
|
|
1249
1245
|
const commands = {};
|
|
1250
1246
|
let discovered;
|
|
1251
1247
|
try {
|
|
@@ -1261,6 +1257,8 @@ function collectDiscoveredSkillsAsCommands(startDir, homeDir, configDir, opencod
|
|
|
1261
1257
|
for (const skill of discovered) {
|
|
1262
1258
|
if (skill.frontmatter.userInvocable === false)
|
|
1263
1259
|
continue;
|
|
1260
|
+
if (disabledCommands.includes(skill.name))
|
|
1261
|
+
continue;
|
|
1264
1262
|
try {
|
|
1265
1263
|
commands[skill.name] = loadDiscoveredSkillAsCommand(skill);
|
|
1266
1264
|
} catch {}
|
|
@@ -1296,7 +1294,7 @@ function createConfigHandler(deps) {
|
|
|
1296
1294
|
const resolvedOverlays = resolveAgentOverlaySet(validatedOverlays);
|
|
1297
1295
|
const bundledAgents = collectAgents(bundledAgentsDir2, systematicConfig.disabled_agents, nativeAgents, resolvedOverlays, availabilitySet);
|
|
1298
1296
|
const bundledCommands = collectCommands(bundledCommandsDir, systematicConfig.disabled_commands);
|
|
1299
|
-
const discoveredSkillCommands = systematicConfig.skills_as_commands !== false ? collectDiscoveredSkillsAsCommands(directory, homeDir, opencodeConfigDir, opencodeConfigDirOverride) : {};
|
|
1297
|
+
const discoveredSkillCommands = systematicConfig.skills_as_commands !== false ? collectDiscoveredSkillsAsCommands(directory, homeDir, opencodeConfigDir, opencodeConfigDirOverride, systematicConfig.disabled_commands) : {};
|
|
1300
1298
|
const bundledAgentKeys = new Set(Object.keys(bundledAgents));
|
|
1301
1299
|
config.agent = mergeSystematicEntries(existingAgents, bundledAgents, (key, agent) => bundledAgentKeys.has(key) && isSystematicAgentConfig(agent));
|
|
1302
1300
|
const emittedCommands = {
|
|
@@ -1331,7 +1329,7 @@ function normalizePath(path8) {
|
|
|
1331
1329
|
}
|
|
1332
1330
|
|
|
1333
1331
|
// src/lib/skill-tool.ts
|
|
1334
|
-
import
|
|
1332
|
+
import fs5 from "fs";
|
|
1335
1333
|
import path8 from "path";
|
|
1336
1334
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
1337
1335
|
import { tool } from "@opencode-ai/plugin/tool";
|
|
@@ -1356,7 +1354,7 @@ function discoverSkillFiles(dir, limit = 10) {
|
|
|
1356
1354
|
if (files.length >= limit)
|
|
1357
1355
|
return;
|
|
1358
1356
|
try {
|
|
1359
|
-
const entries =
|
|
1357
|
+
const entries = fs5.readdirSync(currentDir, { withFileTypes: true });
|
|
1360
1358
|
for (const entry of entries) {
|
|
1361
1359
|
if (files.length >= limit)
|
|
1362
1360
|
break;
|
|
@@ -1487,9 +1485,9 @@ var bundledCommandsDir = path9.join(packageRoot2, "commands");
|
|
|
1487
1485
|
var packageJsonPath = path9.join(packageRoot2, "package.json");
|
|
1488
1486
|
var getPackageVersion = () => {
|
|
1489
1487
|
try {
|
|
1490
|
-
if (!
|
|
1488
|
+
if (!fs6.existsSync(packageJsonPath))
|
|
1491
1489
|
return "unknown";
|
|
1492
|
-
const content =
|
|
1490
|
+
const content = fs6.readFileSync(packageJsonPath, "utf8");
|
|
1493
1491
|
const parsed = JSON.parse(content);
|
|
1494
1492
|
return parsed.version ?? "unknown";
|
|
1495
1493
|
} catch {
|
|
@@ -15,6 +15,9 @@ export interface DiscoveredSkill {
|
|
|
15
15
|
name: string;
|
|
16
16
|
description: string;
|
|
17
17
|
frontmatter: SkillFrontmatter;
|
|
18
|
+
/** SKILL.md body (frontmatter stripped), read once at discovery so callers
|
|
19
|
+
* that inline the body don't re-read the file. */
|
|
20
|
+
body: string;
|
|
18
21
|
skillPath: string;
|
|
19
22
|
root: DiscoveryRootId;
|
|
20
23
|
}
|
package/dist/lib/skills.d.ts
CHANGED
|
@@ -37,5 +37,11 @@ export interface SkillInfo {
|
|
|
37
37
|
allowedTools?: string;
|
|
38
38
|
}
|
|
39
39
|
export declare const SKILL_FRONTMATTER_FIELDS: readonly ["name", "description", "argument-hint", "disable-model-invocation", "allowed-tools", "license", "compatibility", "metadata", "deprecated", "user-invocable", "agent", "model", "context", "subtask"];
|
|
40
|
+
/**
|
|
41
|
+
* Parse skill frontmatter from already-read file content. Split out from
|
|
42
|
+
* `extractFrontmatter` so callers that also need the body (e.g. discovered-skill
|
|
43
|
+
* command emission) can read the file once and derive both. Never throws.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractFrontmatterFromContent(content: string): SkillFrontmatter;
|
|
40
46
|
export declare function extractFrontmatter(filePath: string): SkillFrontmatter;
|
|
41
47
|
export declare function findSkillsInDir(dir: string, maxDepth?: number): SkillInfo[];
|