@devxiyang/agent-skill 0.0.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -0
  3. package/dist/builtin.d.ts +20 -0
  4. package/dist/builtin.d.ts.map +1 -0
  5. package/dist/builtin.js +25 -0
  6. package/dist/builtin.js.map +1 -0
  7. package/dist/copy.d.ts +30 -0
  8. package/dist/copy.d.ts.map +1 -0
  9. package/dist/copy.js +73 -0
  10. package/dist/copy.js.map +1 -0
  11. package/dist/discovery/discovery.d.ts +40 -0
  12. package/dist/discovery/discovery.d.ts.map +1 -0
  13. package/dist/discovery/discovery.js +111 -0
  14. package/dist/discovery/discovery.js.map +1 -0
  15. package/dist/discovery/frontmatter.d.ts +27 -0
  16. package/dist/discovery/frontmatter.d.ts.map +1 -0
  17. package/dist/discovery/frontmatter.js +123 -0
  18. package/dist/discovery/frontmatter.js.map +1 -0
  19. package/dist/discovery/index.d.ts +4 -0
  20. package/dist/discovery/index.d.ts.map +1 -0
  21. package/dist/discovery/index.js +3 -0
  22. package/dist/discovery/index.js.map +1 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +5 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/types.d.ts +38 -0
  28. package/dist/types.d.ts.map +1 -0
  29. package/dist/types.js +2 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/validator.d.ts +14 -0
  32. package/dist/validator.d.ts.map +1 -0
  33. package/dist/validator.js +2 -0
  34. package/dist/validator.js.map +1 -0
  35. package/dist/validators/index.d.ts +2 -0
  36. package/dist/validators/index.d.ts.map +1 -0
  37. package/dist/validators/index.js +2 -0
  38. package/dist/validators/index.js.map +1 -0
  39. package/dist/validators/node.d.ts +9 -0
  40. package/dist/validators/node.d.ts.map +1 -0
  41. package/dist/validators/node.js +43 -0
  42. package/dist/validators/node.js.map +1 -0
  43. package/package.json +58 -0
  44. package/skills/git/SKILL.md +87 -0
  45. package/skills/github/SKILL.md +54 -0
  46. package/skills/skill-creator/SKILL.md +73 -0
  47. package/skills/tmux/SKILL.md +76 -0
  48. package/skills/weather/SKILL.md +39 -0
  49. package/skills/web/SKILL.md +50 -0
@@ -0,0 +1,123 @@
1
+ import matter from 'gray-matter';
2
+ /**
3
+ * Parses the YAML frontmatter of a SKILL.md file into a normalized structure.
4
+ *
5
+ * Supports two requirement sources:
6
+ * 1. Top-level `requires` field: `bin:git,env:GITHUB_TOKEN`
7
+ * 2. `metadata` field: a JSON string with a namespaced object (`octoii` or `openclaw`)
8
+ * containing `requires`, `bins`, `env`, and `os` keys.
9
+ *
10
+ * Values from both sources are merged and deduplicated.
11
+ */
12
+ export function parseFrontmatter(content) {
13
+ const { data, content: body } = matter(content);
14
+ void body;
15
+ const meta = parseMetadataJson(data.metadata);
16
+ const requires = extractRequirements(data, meta);
17
+ return {
18
+ name: normalizeString(data.name),
19
+ description: normalizeString(data.description),
20
+ always: data.always === true || meta.always === true,
21
+ tags: parseCsv(data.tags ?? meta.tags),
22
+ requiresBins: requires.bins,
23
+ requiresEnvs: requires.envs,
24
+ requiresOs: parseCsv(meta.os),
25
+ };
26
+ }
27
+ /**
28
+ * Strips the frontmatter block from a SKILL.md file and returns the trimmed body.
29
+ * This is the markdown content passed to the agent as skill instructions.
30
+ */
31
+ export function stripFrontmatter(content) {
32
+ return matter(content).content.trim();
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Parses the `metadata` field, which is an embedded JSON string that may contain
37
+ * a scoped namespace (`octoii` or `openclaw`). Returns an empty object on failure.
38
+ */
39
+ function parseMetadataJson(raw) {
40
+ if (typeof raw !== 'string')
41
+ return {};
42
+ try {
43
+ const parsed = JSON.parse(raw);
44
+ if (!isRecord(parsed))
45
+ return {};
46
+ return pickScopedNamespace(parsed);
47
+ }
48
+ catch {
49
+ return {};
50
+ }
51
+ }
52
+ /**
53
+ * If the object has a known namespace key (`octoii`, `openclaw`), returns that
54
+ * nested object. Otherwise returns the object as-is for flat metadata structures.
55
+ */
56
+ function pickScopedNamespace(input) {
57
+ for (const ns of ['octoii', 'openclaw']) {
58
+ if (ns in input && isRecord(input[ns])) {
59
+ return input[ns];
60
+ }
61
+ }
62
+ return input;
63
+ }
64
+ /**
65
+ * Merges `requires` strings and explicit `bins`/`env` lists from both the
66
+ * top-level frontmatter and the metadata namespace, deduplicating results.
67
+ */
68
+ function extractRequirements(data, meta) {
69
+ const bins = new Set();
70
+ const envs = new Set();
71
+ for (const { b, e } of [
72
+ parseRequireString(data.requires),
73
+ parseRequireString(meta.requires),
74
+ ]) {
75
+ b.forEach((v) => bins.add(v));
76
+ e.forEach((v) => envs.add(v));
77
+ }
78
+ parseCsv(meta.bins).forEach((v) => bins.add(v));
79
+ parseCsv(meta.env).forEach((v) => envs.add(v));
80
+ return { bins: [...bins], envs: [...envs] };
81
+ }
82
+ /**
83
+ * Parses a `requires` string of the form `bin:git,env:TOKEN` into separate
84
+ * bin and env arrays. Supports both comma and semicolon as delimiters.
85
+ */
86
+ function parseRequireString(raw) {
87
+ if (typeof raw !== 'string')
88
+ return { b: [], e: [] };
89
+ const b = [];
90
+ const e = [];
91
+ for (const part of raw.split(/[;,]/)) {
92
+ const v = part.trim();
93
+ if (v.startsWith('bin:'))
94
+ b.push(v.slice(4).trim());
95
+ else if (v.startsWith('env:'))
96
+ e.push(v.slice(4).trim());
97
+ }
98
+ return { b, e };
99
+ }
100
+ /**
101
+ * Parses a value that may be a comma-separated string or an array of strings.
102
+ * Returns an empty array for any other type.
103
+ */
104
+ function parseCsv(raw) {
105
+ if (typeof raw === 'string') {
106
+ return raw.split(',').map((v) => v.trim()).filter(Boolean);
107
+ }
108
+ if (Array.isArray(raw)) {
109
+ return raw.filter((v) => typeof v === 'string');
110
+ }
111
+ return [];
112
+ }
113
+ /** Returns the trimmed string, or null if it is empty or not a string. */
114
+ function normalizeString(raw) {
115
+ if (typeof raw !== 'string')
116
+ return null;
117
+ const v = raw.trim();
118
+ return v.length > 0 ? v : null;
119
+ }
120
+ function isRecord(v) {
121
+ return v !== null && typeof v === 'object' && !Array.isArray(v);
122
+ }
123
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/discovery/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { SkillDiscovery } from './discovery.js';
2
+ export { parseFrontmatter } from './frontmatter.js';
3
+ export type { SkillFrontmatter } from './frontmatter.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { SkillDiscovery } from './discovery.js';
2
+ export { parseFrontmatter } from './frontmatter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type { SkillEntry, SkillRoot, SkillScope, SkillMissingReason, SkillMissingReasonKind } from './types.js';
2
+ export type { SkillValidator } from './validator.js';
3
+ export { SkillDiscovery, parseFrontmatter } from './discovery/index.js';
4
+ export type { SkillFrontmatter } from './discovery/index.js';
5
+ export { builtinSkillsRoot } from './builtin.js';
6
+ export { defaultValidator } from './validators/index.js';
7
+ export { copySkills } from './copy.js';
8
+ export type { CopySkillsOptions, CopySkillsResult } from './copy.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAChH,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { SkillDiscovery, parseFrontmatter } from './discovery/index.js';
2
+ export { builtinSkillsRoot } from './builtin.js';
3
+ export { defaultValidator } from './validators/index.js';
4
+ export { copySkills } from './copy.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,38 @@
1
+ /** Whether a skill came from a user-managed directory or a system-provided one. */
2
+ export type SkillScope = 'user' | 'system';
3
+ /** A directory root that SkillDiscovery scans for skill folders. */
4
+ export type SkillRoot = {
5
+ /** Absolute path to the directory containing skill subfolders. */
6
+ path: string;
7
+ /** Metadata tag for the origin of skills found in this root. Does not affect priority. */
8
+ scope: SkillScope;
9
+ };
10
+ /** The category of an unmet dependency. */
11
+ export type SkillMissingReasonKind = 'bin' | 'env' | 'os' | 'invalid';
12
+ /** Describes a single unmet requirement that makes a skill ineligible. */
13
+ export type SkillMissingReason = {
14
+ kind: SkillMissingReasonKind;
15
+ /** The specific value that failed the check (e.g. binary name, env var name). */
16
+ value: string;
17
+ /** Human-readable explanation shown to the user. */
18
+ message: string;
19
+ };
20
+ /** A discovered skill with its metadata and eligibility status. */
21
+ export type SkillEntry = {
22
+ /** Display name from frontmatter, or the folder name if not set. */
23
+ name: string;
24
+ description: string | null;
25
+ /** Absolute path to the skill folder. */
26
+ path: string;
27
+ /** Absolute path to the SKILL.md file inside the skill folder. */
28
+ filePath: string;
29
+ scope: SkillScope;
30
+ /** True when all requires/os constraints are satisfied in the current environment. */
31
+ eligible: boolean;
32
+ /** Unmet requirements; empty when eligible is true. */
33
+ missing: SkillMissingReason[];
34
+ /** When true, this skill should be injected into every agent run automatically. */
35
+ always: boolean;
36
+ tags: string[];
37
+ };
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3C,oEAAoE;AACpE,MAAM,MAAM,SAAS,GAAG;IACtB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC;AAEF,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAEtE,0EAA0E;AAC1E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,UAAU,GAAG;IACvB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,mFAAmF;IACnF,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pluggable interface for environment dependency checks.
3
+ * Implement this to replace the default Node.js-based checks with
4
+ * custom logic (e.g. Electron shell lookups, mocked environments in tests).
5
+ */
6
+ export interface SkillValidator {
7
+ /** Returns true if the named executable is available in the current environment. */
8
+ checkBin(name: string): Promise<boolean>;
9
+ /** Returns true if the named environment variable is set to a non-empty value. */
10
+ checkEnv(name: string): boolean;
11
+ /** Returns true if the current OS matches at least one of the given platform strings. */
12
+ checkOs(platforms: string[]): boolean;
13
+ }
14
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,yFAAyF;IACzF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;CACvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { defaultValidator } from './node.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { defaultValidator } from './node.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { SkillValidator } from '../validator.js';
2
+ /**
3
+ * Default SkillValidator for Node.js environments.
4
+ * - checkBin: walks PATH segments and probes for the executable via fs.access
5
+ * - checkEnv: reads process.env
6
+ * - checkOs: compares against process.platform
7
+ */
8
+ export declare const defaultValidator: SkillValidator;
9
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/validators/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAkC9B,CAAC"}
@@ -0,0 +1,43 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ /**
4
+ * Default SkillValidator for Node.js environments.
5
+ * - checkBin: walks PATH segments and probes for the executable via fs.access
6
+ * - checkEnv: reads process.env
7
+ * - checkOs: compares against process.platform
8
+ */
9
+ export const defaultValidator = {
10
+ /**
11
+ * Checks whether a binary exists somewhere on PATH.
12
+ * On Windows, also probes .exe / .cmd / .bat extensions.
13
+ */
14
+ async checkBin(name) {
15
+ const pathEnv = process.env.PATH;
16
+ if (!pathEnv)
17
+ return false;
18
+ const segments = pathEnv.split(path.delimiter).filter(Boolean);
19
+ const candidates = process.platform === 'win32'
20
+ ? [name, `${name}.exe`, `${name}.cmd`, `${name}.bat`]
21
+ : [name];
22
+ for (const seg of segments) {
23
+ for (const candidate of candidates) {
24
+ try {
25
+ await fs.access(path.join(seg, candidate));
26
+ return true;
27
+ }
28
+ catch { /* not found in this segment, continue */ }
29
+ }
30
+ }
31
+ return false;
32
+ },
33
+ /** Returns true if the env var exists and is not blank. */
34
+ checkEnv(name) {
35
+ const v = process.env[name];
36
+ return typeof v === 'string' && v.trim().length > 0;
37
+ },
38
+ /** Returns true if process.platform is in the allowed list. */
39
+ checkOs(platforms) {
40
+ return platforms.includes(process.platform);
41
+ },
42
+ };
43
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/validators/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QACjC,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,UAAU,GACd,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC1B,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC;YACrD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACb,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;oBAC3C,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC,CAAC,yCAAyC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2DAA2D;IAC3D,QAAQ,CAAC,IAAY;QACnB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,+DAA+D;IAC/D,OAAO,CAAC,SAAmB;QACzB,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;CACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@devxiyang/agent-skill",
3
+ "version": "0.0.1",
4
+ "description": "SDK for skill discovery and registration — integrates into any agent",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/devxiyang/agent.skill.git"
9
+ },
10
+ "keywords": [
11
+ "agent",
12
+ "skill",
13
+ "skill-discovery",
14
+ "skill-registry",
15
+ "llm",
16
+ "sdk",
17
+ "typescript"
18
+ ],
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "type": "module",
23
+ "main": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "skills"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsc -p tsconfig.json",
37
+ "clean": "rm -rf dist",
38
+ "typecheck": "tsc -p tsconfig.json --noEmit",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest"
41
+ },
42
+ "peerDependencies": {
43
+ "@types/node": ">=18"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "@types/node": {
47
+ "optional": true
48
+ }
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^24.0.0",
52
+ "typescript": "^5.8.0",
53
+ "vitest": "^4.0.18"
54
+ },
55
+ "dependencies": {
56
+ "gray-matter": "^4.0.3"
57
+ }
58
+ }
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: git
3
+ description: Local git operations — branching, committing, merging, rebasing, history inspection, and conflict resolution.
4
+ requires: bin:git
5
+ ---
6
+
7
+ # Git Skill
8
+
9
+ ## Common workflow
10
+
11
+ ```bash
12
+ git status
13
+ git diff
14
+ git add <files>
15
+ git commit -m "message"
16
+ ```
17
+
18
+ ## Branching
19
+
20
+ ```bash
21
+ git checkout -b feature/name
22
+ git switch main
23
+ git branch -d feature/name
24
+ ```
25
+
26
+ ## Inspecting history
27
+
28
+ ```bash
29
+ git log --oneline -20
30
+ git log --oneline --graph --all
31
+ git show <commit>
32
+ git diff main...HEAD
33
+ ```
34
+
35
+ ## Undoing changes
36
+
37
+ ```bash
38
+ # Unstage
39
+ git restore --staged <file>
40
+
41
+ # Discard working tree changes
42
+ git restore <file>
43
+
44
+ # Undo last commit (keep changes staged)
45
+ git reset --soft HEAD~1
46
+
47
+ # Interactive rebase to edit recent commits
48
+ git rebase -i HEAD~3
49
+ ```
50
+
51
+ ## Stashing
52
+
53
+ ```bash
54
+ git stash push -m "description"
55
+ git stash list
56
+ git stash pop
57
+ ```
58
+
59
+ ## Merging & rebasing
60
+
61
+ ```bash
62
+ # Merge
63
+ git merge feature/name
64
+
65
+ # Rebase onto main
66
+ git rebase main
67
+
68
+ # Abort on conflict
69
+ git rebase --abort
70
+ git merge --abort
71
+ ```
72
+
73
+ ## Conflict resolution
74
+
75
+ 1. Open conflicting files, look for `<<<<<<<` markers
76
+ 2. Edit to desired state
77
+ 3. `git add <resolved-file>`
78
+ 4. `git rebase --continue` or `git merge --continue`
79
+
80
+ ## Remotes
81
+
82
+ ```bash
83
+ git remote -v
84
+ git fetch origin
85
+ git pull --rebase
86
+ git push -u origin HEAD
87
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: github
3
+ description: Interact with GitHub using the `gh` CLI. Use for issues, pull requests, CI runs, code review, and GitHub API queries.
4
+ requires: bin:gh
5
+ ---
6
+
7
+ # GitHub Skill
8
+
9
+ Use the `gh` CLI to interact with GitHub. Always specify `--repo owner/repo` when not inside a git directory.
10
+
11
+ ## Pull Requests
12
+
13
+ ```bash
14
+ # List open PRs
15
+ gh pr list --repo owner/repo
16
+
17
+ # Check CI status
18
+ gh pr checks <number> --repo owner/repo
19
+
20
+ # View failed logs
21
+ gh run view <run-id> --repo owner/repo --log-failed
22
+
23
+ # Review and approve
24
+ gh pr review <number> --approve --repo owner/repo
25
+ ```
26
+
27
+ ## Issues
28
+
29
+ ```bash
30
+ # List issues
31
+ gh issue list --repo owner/repo --state open
32
+
33
+ # Create issue
34
+ gh issue create --title "Title" --body "Body" --repo owner/repo
35
+
36
+ # Close issue
37
+ gh issue close <number> --repo owner/repo
38
+ ```
39
+
40
+ ## API
41
+
42
+ Use `gh api` for data not available via subcommands:
43
+
44
+ ```bash
45
+ gh api repos/owner/repo/pulls/55 --jq '.title, .state, .user.login'
46
+ ```
47
+
48
+ ## JSON Output
49
+
50
+ Most commands support `--json` + `--jq`:
51
+
52
+ ```bash
53
+ gh issue list --repo owner/repo --json number,title --jq '.[] | "\(.number): \(.title)"'
54
+ ```
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: skill-creator
3
+ description: Create or update skills. Use when designing, structuring, or writing a new skill folder with SKILL.md and optional resources.
4
+ ---
5
+
6
+ # Skill Creator
7
+
8
+ ## What is a skill
9
+
10
+ A skill is a folder that extends an agent's capabilities with specialized knowledge and workflows:
11
+
12
+ ```
13
+ skill-name/
14
+ ├── SKILL.md # required — frontmatter + instructions
15
+ ├── scripts/ # optional — executable scripts
16
+ ├── references/ # optional — docs loaded on demand
17
+ └── assets/ # optional — templates, images, files used in output
18
+ ```
19
+
20
+ ## SKILL.md structure
21
+
22
+ ```markdown
23
+ ---
24
+ name: skill-name
25
+ description: What this skill does and when to use it. Be specific about triggers.
26
+ requires: bin:tool,env:API_KEY # optional
27
+ os: darwin,linux # optional, omit for all platforms
28
+ ---
29
+
30
+ # Skill Name
31
+
32
+ Instructions for the agent...
33
+ ```
34
+
35
+ Only `name` and `description` are required in frontmatter.
36
+
37
+ ## Writing good descriptions
38
+
39
+ The description is the primary trigger. Include:
40
+ - What the skill does
41
+ - When to use it (specific contexts and phrases that should trigger it)
42
+
43
+ Example: `"Create and edit .docx files with tracked changes support. Use when working with Word documents, professional reports, or any .docx task."`
44
+
45
+ ## Body guidelines
46
+
47
+ - Write for another agent instance — include what would be non-obvious
48
+ - Prefer concise examples over verbose explanations
49
+ - Keep under 500 lines; move details to `references/` files
50
+ - Link to reference files explicitly so the agent knows they exist
51
+
52
+ ## Resource types
53
+
54
+ **scripts/** — Deterministic code run repeatedly. Test each script before including.
55
+
56
+ **references/** — Docs loaded on demand. Keep SKILL.md lean; put schemas, API docs, and detailed guides here. Reference them from SKILL.md with a note on when to load.
57
+
58
+ **assets/** — Files used in output (templates, images, fonts). Not loaded into context.
59
+
60
+ ## Progressive disclosure
61
+
62
+ Three loading levels:
63
+ 1. **Name + description** — always in context (~100 tokens)
64
+ 2. **SKILL.md body** — loaded when skill triggers (<5k tokens)
65
+ 3. **references/ and scripts/** — loaded or executed on demand
66
+
67
+ Design each level to be independently useful.
68
+
69
+ ## Naming
70
+
71
+ - Lowercase, hyphens only: `my-skill`, `gh-review`, `pdf-editor`
72
+ - Short and action-oriented
73
+ - Namespace by tool when helpful: `gh-address-comments`