@sweny-ai/core 0.1.88 → 0.1.89
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/skill.d.ts +29 -2
- package/dist/cli/skill.js +21 -13
- package/dist/schema.d.ts +4 -4
- package/dist/skills/custom-loader.js +2 -2
- package/dist/types.d.ts +10 -2
- package/dist/types.js +9 -0
- package/package.json +1 -1
package/dist/cli/skill.d.ts
CHANGED
|
@@ -14,14 +14,41 @@
|
|
|
14
14
|
* and `../skills/index.js`; this CLI is a thin authoring shell over them.
|
|
15
15
|
*/
|
|
16
16
|
import { Command } from "commander";
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
import { type SkillCategory } from "../types.js";
|
|
18
|
+
declare const HARNESS_DIRS: {
|
|
19
|
+
readonly claude: ".claude/skills";
|
|
20
|
+
readonly sweny: ".sweny/skills";
|
|
21
|
+
readonly agents: ".agents/skills";
|
|
22
|
+
readonly gemini: ".gemini/skills";
|
|
23
|
+
};
|
|
24
|
+
type HarnessKey = keyof typeof HARNESS_DIRS;
|
|
19
25
|
/** Build the SKILL.md body for a fresh scaffold. Exported for tests. */
|
|
20
26
|
export declare function renderSkillTemplate(opts: {
|
|
21
27
|
id: string;
|
|
22
28
|
description: string;
|
|
23
29
|
category: SkillCategory;
|
|
24
30
|
}): string;
|
|
31
|
+
interface NewOptions {
|
|
32
|
+
description?: string;
|
|
33
|
+
category?: string;
|
|
34
|
+
harness?: HarnessKey;
|
|
35
|
+
force?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Action handler for `sweny skill new`. Exported for unit tests; production
|
|
39
|
+
* code goes through `registerSkillCommand`. `cwd` defaults to `process.cwd()`
|
|
40
|
+
* so the CLI works as expected; tests pass a tmp dir for isolation.
|
|
41
|
+
*/
|
|
42
|
+
export declare function runSkillNew(idArg: string, options: NewOptions, cwd?: string): void;
|
|
43
|
+
interface ListOptions {
|
|
44
|
+
json?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Action handler for `sweny skill list`. Exported for unit tests; production
|
|
48
|
+
* code goes through `registerSkillCommand`. `cwd` and `env` injection lets
|
|
49
|
+
* tests exercise the configured-badge logic without polluting global state.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runSkillList(options: ListOptions, cwd?: string, env?: Record<string, string | undefined>): void;
|
|
25
52
|
/** Register the `sweny skill` subcommand group on the parent program. */
|
|
26
53
|
export declare function registerSkillCommand(program: Command): void;
|
|
27
54
|
export {};
|
package/dist/cli/skill.js
CHANGED
|
@@ -18,9 +18,9 @@ import * as path from "node:path";
|
|
|
18
18
|
import chalk from "chalk";
|
|
19
19
|
import { builtinSkills } from "../skills/index.js";
|
|
20
20
|
import { configuredSkillsWithDiagnostics, discoverSkillsWithDiagnostics } from "../skills/custom-loader.js";
|
|
21
|
+
import { SKILL_CATEGORIES } from "../types.js";
|
|
21
22
|
// Mirror of the loader's regex so authoring-side validation matches discovery.
|
|
22
23
|
const VALID_SKILL_ID = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
23
|
-
const VALID_CATEGORIES = ["general", "git", "tasks", "notification", "observability", "data"];
|
|
24
24
|
const HARNESS_DIRS = {
|
|
25
25
|
claude: ".claude/skills",
|
|
26
26
|
sweny: ".sweny/skills",
|
|
@@ -80,7 +80,12 @@ export function renderSkillTemplate(opts) {
|
|
|
80
80
|
lines.push("");
|
|
81
81
|
return lines.join("\n");
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Action handler for `sweny skill new`. Exported for unit tests; production
|
|
85
|
+
* code goes through `registerSkillCommand`. `cwd` defaults to `process.cwd()`
|
|
86
|
+
* so the CLI works as expected; tests pass a tmp dir for isolation.
|
|
87
|
+
*/
|
|
88
|
+
export function runSkillNew(idArg, options, cwd = process.cwd()) {
|
|
84
89
|
const id = idArg.toLowerCase();
|
|
85
90
|
if (!VALID_SKILL_ID.test(id) || id.includes("--") || id.length > 64) {
|
|
86
91
|
console.error(chalk.red(` Invalid skill id "${idArg}".\n Skill ids must be lowercase alphanumeric + hyphens (no consecutive hyphens), max 64 chars.`));
|
|
@@ -89,8 +94,8 @@ function runSkillNew(idArg, options) {
|
|
|
89
94
|
}
|
|
90
95
|
const description = (options.description ?? `Custom ${id} skill`).trim();
|
|
91
96
|
const category = (options.category ?? "general");
|
|
92
|
-
if (!
|
|
93
|
-
console.error(chalk.red(` Invalid category "${category}".\n Allowed: ${
|
|
97
|
+
if (!SKILL_CATEGORIES.includes(category)) {
|
|
98
|
+
console.error(chalk.red(` Invalid category "${category}".\n Allowed: ${SKILL_CATEGORIES.join(", ")}`));
|
|
94
99
|
process.exit(2);
|
|
95
100
|
return;
|
|
96
101
|
}
|
|
@@ -101,7 +106,6 @@ function runSkillNew(idArg, options) {
|
|
|
101
106
|
process.exit(2);
|
|
102
107
|
return;
|
|
103
108
|
}
|
|
104
|
-
const cwd = process.cwd();
|
|
105
109
|
const skillDir = path.join(cwd, baseDir, id);
|
|
106
110
|
const skillFile = path.join(skillDir, "SKILL.md");
|
|
107
111
|
if (fs.existsSync(skillFile) && !options.force) {
|
|
@@ -121,16 +125,20 @@ function runSkillNew(idArg, options) {
|
|
|
121
125
|
console.log(chalk.dim(` 5. Run \`sweny skill list\` to confirm it discovers correctly.`));
|
|
122
126
|
console.log();
|
|
123
127
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Action handler for `sweny skill list`. Exported for unit tests; production
|
|
130
|
+
* code goes through `registerSkillCommand`. `cwd` and `env` injection lets
|
|
131
|
+
* tests exercise the configured-badge logic without polluting global state.
|
|
132
|
+
*/
|
|
133
|
+
export function runSkillList(options, cwd = process.cwd(), env = process.env) {
|
|
134
|
+
// We want the FULL list (built-in + custom) even when env vars aren't set.
|
|
135
|
+
// configuredSkills filters by env, which hides authoring-time skills the
|
|
136
|
+
// user just scaffolded, so combine sources directly.
|
|
129
137
|
const { skills: customSkills, warnings: customWarnings } = discoverSkillsWithDiagnostics(cwd);
|
|
130
138
|
const customIds = new Set(customSkills.map((s) => s.id));
|
|
131
139
|
const builtinList = builtinSkills.filter((s) => !customIds.has(s.id));
|
|
132
|
-
// Configured map drives the "configured?" badge
|
|
133
|
-
const configuredIds = new Set(configuredSkillsWithDiagnostics(
|
|
140
|
+
// Configured map drives the "configured?" badge: required env vars present.
|
|
141
|
+
const configuredIds = new Set(configuredSkillsWithDiagnostics(env, cwd).skills.map((s) => s.id));
|
|
134
142
|
if (options.json) {
|
|
135
143
|
const data = [
|
|
136
144
|
...builtinList.map((s) => ({
|
|
@@ -188,7 +196,7 @@ export function registerSkillCommand(program) {
|
|
|
188
196
|
.command("new <id>")
|
|
189
197
|
.description("Scaffold a new SKILL.md in .claude/skills/<id>/")
|
|
190
198
|
.option("-d, --description <text>", "One-line description (required field in frontmatter)")
|
|
191
|
-
.option("-c, --category <category>", `Skill category (${
|
|
199
|
+
.option("-c, --category <category>", `Skill category (${SKILL_CATEGORIES.join("|")})`, "general")
|
|
192
200
|
.option("--harness <harness>", `Where to place the skill (${Object.keys(HARNESS_DIRS).join("|")})`, "claude")
|
|
193
201
|
.option("--force", "Overwrite an existing SKILL.md")
|
|
194
202
|
.action((id, options) => runSkillNew(id, options));
|
package/dist/schema.d.ts
CHANGED
|
@@ -241,7 +241,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
241
241
|
id: string;
|
|
242
242
|
name: string;
|
|
243
243
|
description: string;
|
|
244
|
-
category: "
|
|
244
|
+
category: "general" | "git" | "tasks" | "notification" | "observability";
|
|
245
245
|
config: Record<string, {
|
|
246
246
|
description: string;
|
|
247
247
|
required?: boolean | undefined;
|
|
@@ -266,7 +266,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
266
266
|
id: string;
|
|
267
267
|
name: string;
|
|
268
268
|
description: string;
|
|
269
|
-
category: "
|
|
269
|
+
category: "general" | "git" | "tasks" | "notification" | "observability";
|
|
270
270
|
instruction?: string | undefined;
|
|
271
271
|
mcp?: {
|
|
272
272
|
url?: string | undefined;
|
|
@@ -291,7 +291,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
291
291
|
id: string;
|
|
292
292
|
name: string;
|
|
293
293
|
description: string;
|
|
294
|
-
category: "
|
|
294
|
+
category: "general" | "git" | "tasks" | "notification" | "observability";
|
|
295
295
|
config: Record<string, {
|
|
296
296
|
description: string;
|
|
297
297
|
required?: boolean | undefined;
|
|
@@ -316,7 +316,7 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
316
316
|
id: string;
|
|
317
317
|
name: string;
|
|
318
318
|
description: string;
|
|
319
|
-
category: "
|
|
319
|
+
category: "general" | "git" | "tasks" | "notification" | "observability";
|
|
320
320
|
instruction?: string | undefined;
|
|
321
321
|
mcp?: {
|
|
322
322
|
url?: string | undefined;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { readdirSync, readFileSync, existsSync } from "node:fs";
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import YAML from "yaml";
|
|
14
|
+
import { SKILL_CATEGORIES } from "../types.js";
|
|
14
15
|
import { builtinSkills, isSkillConfigured } from "./index.js";
|
|
15
16
|
/** Directories to scan, in ascending priority order. Last match wins. */
|
|
16
17
|
const SKILL_DIRS = [".gemini/skills", ".agents/skills", ".claude/skills", ".sweny/skills"];
|
|
@@ -99,8 +100,7 @@ function parseSkillMd(content, path) {
|
|
|
99
100
|
}
|
|
100
101
|
// Narrow the loosely-typed YAML output into the fields we expect
|
|
101
102
|
const fm = raw;
|
|
102
|
-
const
|
|
103
|
-
const category = typeof fm.category === "string" && VALID_CATEGORIES.includes(fm.category)
|
|
103
|
+
const category = typeof fm.category === "string" && SKILL_CATEGORIES.includes(fm.category)
|
|
104
104
|
? fm.category
|
|
105
105
|
: "general";
|
|
106
106
|
const id = String(fm.name);
|
package/dist/types.d.ts
CHANGED
|
@@ -22,8 +22,16 @@ export interface ConfigField {
|
|
|
22
22
|
/** Default environment variable to read from */
|
|
23
23
|
env?: string;
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Skill categories: used for per-node validation and grouping.
|
|
27
|
+
*
|
|
28
|
+
* Single source of truth for runtime + compile-time. The `as const` tuple
|
|
29
|
+
* lets the CLI iterate it for help text and the loader use it for runtime
|
|
30
|
+
* validation; `SkillCategory` is derived so adding a category requires
|
|
31
|
+
* only this line.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SKILL_CATEGORIES: readonly ["general", "git", "tasks", "notification", "observability", "data"];
|
|
34
|
+
export type SkillCategory = (typeof SKILL_CATEGORIES)[number];
|
|
27
35
|
/** A skill groups related tools with shared config requirements */
|
|
28
36
|
export interface Skill {
|
|
29
37
|
id: string;
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill categories: used for per-node validation and grouping.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for runtime + compile-time. The `as const` tuple
|
|
5
|
+
* lets the CLI iterate it for help text and the loader use it for runtime
|
|
6
|
+
* validation; `SkillCategory` is derived so adding a category requires
|
|
7
|
+
* only this line.
|
|
8
|
+
*/
|
|
9
|
+
export const SKILL_CATEGORIES = ["general", "git", "tasks", "notification", "observability", "data"];
|
|
1
10
|
export const consoleLogger = {
|
|
2
11
|
info: (msg, data) => console.log(`[info] ${msg}`, data ?? ""),
|
|
3
12
|
warn: (msg, data) => console.warn(`[warn] ${msg}`, data ?? ""),
|