@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.
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/builtin.d.ts +20 -0
- package/dist/builtin.d.ts.map +1 -0
- package/dist/builtin.js +25 -0
- package/dist/builtin.js.map +1 -0
- package/dist/copy.d.ts +30 -0
- package/dist/copy.d.ts.map +1 -0
- package/dist/copy.js +73 -0
- package/dist/copy.js.map +1 -0
- package/dist/discovery/discovery.d.ts +40 -0
- package/dist/discovery/discovery.d.ts.map +1 -0
- package/dist/discovery/discovery.js +111 -0
- package/dist/discovery/discovery.js.map +1 -0
- package/dist/discovery/frontmatter.d.ts +27 -0
- package/dist/discovery/frontmatter.d.ts.map +1 -0
- package/dist/discovery/frontmatter.js +123 -0
- package/dist/discovery/frontmatter.js.map +1 -0
- package/dist/discovery/index.d.ts +4 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +3 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validator.d.ts +14 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +2 -0
- package/dist/validator.js.map +1 -0
- package/dist/validators/index.d.ts +2 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +2 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/node.d.ts +9 -0
- package/dist/validators/node.d.ts.map +1 -0
- package/dist/validators/node.js +43 -0
- package/dist/validators/node.js.map +1 -0
- package/package.json +58 -0
- package/skills/git/SKILL.md +87 -0
- package/skills/github/SKILL.md +54 -0
- package/skills/skill-creator/SKILL.md +73 -0
- package/skills/tmux/SKILL.md +76 -0
- package/skills/weather/SKILL.md +39 -0
- 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 @@
|
|
|
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 @@
|
|
|
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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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`
|