@opendirectory.dev/skills 0.1.0 → 0.1.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/index.js +13 -18
- package/package.json +1 -1
- package/registry.json +29 -29
- package/skills/luma-attendees-scraper/SKILL.md +12 -2
- package/src/index.ts +13 -19
package/dist/index.js
CHANGED
|
@@ -45,9 +45,9 @@ const ora_1 = __importDefault(require("ora"));
|
|
|
45
45
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
46
46
|
const program = new commander_1.Command();
|
|
47
47
|
program
|
|
48
|
-
.name('@opendirectory.dev/
|
|
48
|
+
.name('@opendirectory.dev/skills')
|
|
49
49
|
.description(chalk_1.default.blue.bold('CLI to install OpenDirectory skills'))
|
|
50
|
-
.version('0.1.
|
|
50
|
+
.version('0.1.1');
|
|
51
51
|
const getProjectRoot = () => {
|
|
52
52
|
return path.resolve(__dirname, '..');
|
|
53
53
|
};
|
|
@@ -86,7 +86,7 @@ program
|
|
|
86
86
|
table.push([chalk_1.default.yellow(skill.name), desc]);
|
|
87
87
|
}
|
|
88
88
|
console.log(table.toString());
|
|
89
|
-
console.log(chalk_1.default.gray(`\nRun \`${chalk_1.default.white('npx @opendirectory.dev/
|
|
89
|
+
console.log(chalk_1.default.gray(`\nRun \`${chalk_1.default.white('npx "@opendirectory.dev/skills" install <skill-name> --target <agent>')}\` to install a skill.`));
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
92
|
spinner.stop();
|
|
@@ -98,7 +98,6 @@ program
|
|
|
98
98
|
.command('install <skill>')
|
|
99
99
|
.description('Install a skill for your AI agent')
|
|
100
100
|
.requiredOption('-t, --target <tool>', 'Target agent (opencode, claude, codex, gemini, anti-gravity, openclaw, hermes)')
|
|
101
|
-
.option('-g, --global', 'Install globally for all projects')
|
|
102
101
|
.action(async (skillName, options) => {
|
|
103
102
|
const spinner = (0, ora_1.default)(`Installing ${chalk_1.default.yellow(skillName)}...`).start();
|
|
104
103
|
try {
|
|
@@ -148,7 +147,7 @@ program
|
|
|
148
147
|
catch (dirErr) {
|
|
149
148
|
spinner.stop();
|
|
150
149
|
console.error(chalk_1.default.red(`Error: Repository '${skillName}' not found.`));
|
|
151
|
-
console.log(chalk_1.default.gray(`Try running \`${chalk_1.default.white('npx @opendirectory.dev/
|
|
150
|
+
console.log(chalk_1.default.gray(`Try running \`${chalk_1.default.white('npx "@opendirectory.dev/skills" list')}\` to see available skills.`));
|
|
152
151
|
process.exit(1);
|
|
153
152
|
}
|
|
154
153
|
}
|
|
@@ -163,35 +162,31 @@ program
|
|
|
163
162
|
const actualSkillFolderName = path.basename(skillDir);
|
|
164
163
|
const finalSkillName = actualSkillFolderName === skillName ? skillName : actualSkillFolderName;
|
|
165
164
|
const target = options.target.toLowerCase();
|
|
166
|
-
const isGlobal = options.global;
|
|
167
165
|
const validTargets = ['opencode', 'claude', 'codex', 'gemini', 'anti-gravity', 'openclaw', 'hermes'];
|
|
168
166
|
if (validTargets.includes(target)) {
|
|
169
167
|
let targetFolder = '';
|
|
170
168
|
if (target === 'opencode')
|
|
171
|
-
targetFolder =
|
|
169
|
+
targetFolder = `~/.config/opencode/skills/${finalSkillName}`;
|
|
172
170
|
if (target === 'claude')
|
|
173
|
-
targetFolder =
|
|
171
|
+
targetFolder = `~/.claude/skills/${finalSkillName}`;
|
|
174
172
|
if (target === 'codex')
|
|
175
|
-
targetFolder =
|
|
173
|
+
targetFolder = `~/.codex/skills/${finalSkillName}`;
|
|
176
174
|
if (target === 'gemini')
|
|
177
|
-
targetFolder =
|
|
175
|
+
targetFolder = `~/.gemini/skills/${finalSkillName}`;
|
|
178
176
|
if (target === 'anti-gravity')
|
|
179
|
-
targetFolder =
|
|
177
|
+
targetFolder = `~/.gemini/antigravity/skills/${finalSkillName}`;
|
|
180
178
|
if (target === 'openclaw')
|
|
181
|
-
targetFolder =
|
|
179
|
+
targetFolder = `~/.openclaw/skills/${finalSkillName}`;
|
|
182
180
|
if (target === 'hermes')
|
|
183
|
-
targetFolder =
|
|
184
|
-
const { resolvePath
|
|
181
|
+
targetFolder = `~/.hermes/skills/${finalSkillName}`;
|
|
182
|
+
const { resolvePath } = require('./fs-adapters');
|
|
185
183
|
const resolvedDest = resolvePath(targetFolder);
|
|
186
184
|
await fs.mkdir(resolvedDest, { recursive: true });
|
|
187
185
|
await fs.cp(skillDir, resolvedDest, { recursive: true });
|
|
188
|
-
if (target === 'hermes' && !isGlobal) {
|
|
189
|
-
await updateHermesConfig();
|
|
190
|
-
}
|
|
191
186
|
spinner.stop();
|
|
192
187
|
console.log(chalk_1.default.green(`Successfully installed ${chalk_1.default.bold(finalSkillName)}!`));
|
|
193
188
|
console.log(`\n ${chalk_1.default.cyan('Agent:')} ${target}`);
|
|
194
|
-
console.log(` ${chalk_1.default.cyan('Scope:')}
|
|
189
|
+
console.log(` ${chalk_1.default.cyan('Scope:')} Global`);
|
|
195
190
|
console.log(` ${chalk_1.default.cyan('Path:')} ${targetFolder}\n`);
|
|
196
191
|
}
|
|
197
192
|
else {
|
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
-
"name": "blog-cover-
|
|
4
|
-
"description": "
|
|
3
|
+
"name": "blog-cover-generator",
|
|
4
|
+
"description": "Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.",
|
|
5
5
|
"tags": [],
|
|
6
|
-
"author": "
|
|
7
|
-
"version": "1.0.
|
|
6
|
+
"author": "",
|
|
7
|
+
"version": "1.0.17",
|
|
8
8
|
"path": "skills/blog-cover-image-cli"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"path": "skills/explain-this-pr"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
"name": "
|
|
52
|
-
"description": "
|
|
51
|
+
"name": "seo-keyword-research",
|
|
52
|
+
"description": "SEO keyword research workflow for blog generation using Google Trends data. Use when writing blog posts, planning content calendars, or optimizing articles for search engines. Finds breakout keywords, builds content structure, and generates SEO-optimized blog outlines targeting tech and developer audiences.",
|
|
53
53
|
"tags": [],
|
|
54
|
-
"author": "
|
|
55
|
-
"version": "
|
|
54
|
+
"author": "farizanjum",
|
|
55
|
+
"version": "2.0",
|
|
56
56
|
"path": "skills/google-trends-api-skills"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"name": "luma-attendees-scraper",
|
|
92
|
-
"description": "
|
|
92
|
+
"description": "Browser-console script to export attendee data from a Luma event into a CSV. Use when users ask to scrape or export attendees from a Luma event.",
|
|
93
93
|
"tags": [],
|
|
94
|
-
"author": "
|
|
94
|
+
"author": "Varnan",
|
|
95
95
|
"version": "1.0.0",
|
|
96
96
|
"path": "skills/luma-attendees-scraper"
|
|
97
97
|
},
|
|
@@ -104,11 +104,11 @@
|
|
|
104
104
|
"path": "skills/meeting-brief-generator"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
|
-
"name": "meta-ads-
|
|
108
|
-
"description": "
|
|
107
|
+
"name": "meta-ads-expert",
|
|
108
|
+
"description": "Use when interacting with the Meta Ads MCP server to manage accounts, campaigns, ads, insights, and targeting, or to troubleshoot OAuth token authentication. Act as an Expert Media Buyer.",
|
|
109
109
|
"tags": [],
|
|
110
|
-
"author": "
|
|
111
|
-
"version": "
|
|
110
|
+
"author": "Unknown",
|
|
111
|
+
"version": "0.0.1",
|
|
112
112
|
"path": "skills/meta-ads-skill"
|
|
113
113
|
},
|
|
114
114
|
{
|
|
@@ -137,10 +137,10 @@
|
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"name": "position-me",
|
|
140
|
-
"description": "
|
|
140
|
+
"description": "Elite Website Reviewer Agent for AEO, GEO, SEO, UI/UX Psychology, and Copywriting. Use this skill when asked to review or evaluate a website's positioning. It conducts an EXHAUSTIVE, multi-page, psychologically-driven, and ruthless analysis of the entire website. Produces a massive, comprehensive, scored report with charts and actionable fixes. NO EMOJIS allowed.",
|
|
141
141
|
"tags": [],
|
|
142
|
-
"author": "
|
|
143
|
-
"version": "
|
|
142
|
+
"author": "Unknown",
|
|
143
|
+
"version": "0.0.1",
|
|
144
144
|
"path": "skills/position-me"
|
|
145
145
|
},
|
|
146
146
|
{
|
|
@@ -192,11 +192,11 @@
|
|
|
192
192
|
"path": "skills/show-hn-writer"
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
|
-
"name": "stargazer",
|
|
196
|
-
"description": "
|
|
195
|
+
"name": "stargazer-deep-extractor",
|
|
196
|
+
"description": "Advanced 5-tier OSINT scraper for extracting GitHub stargazer emails. Use this skill when a user wants to scrape, extract, or download stargazers from a GitHub repository.",
|
|
197
197
|
"tags": [],
|
|
198
|
-
"author": "
|
|
199
|
-
"version": "
|
|
198
|
+
"author": "Unknown",
|
|
199
|
+
"version": "0.0.1",
|
|
200
200
|
"path": "skills/stargazer"
|
|
201
201
|
},
|
|
202
202
|
{
|
|
@@ -208,19 +208,19 @@
|
|
|
208
208
|
"path": "skills/tweet-thread-from-blog"
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
|
-
"name": "twitter-GTM-find-
|
|
212
|
-
"description": "
|
|
211
|
+
"name": "twitter-GTM-find-Skill",
|
|
212
|
+
"description": "End-to-end pipeline for scraping Twitter for GTM/DevRel tech startup jobs using Apify, and validating them against an Ideal Customer Profile (ICP) using Gemini's native Google Search Grounding. Use this skill when OpenClaw needs to find developer-first, funded startups actively hiring for GTM, DevRel, or Growth roles.",
|
|
213
213
|
"tags": [],
|
|
214
|
-
"author": "
|
|
215
|
-
"version": "
|
|
214
|
+
"author": "Unknown",
|
|
215
|
+
"version": "0.0.1",
|
|
216
216
|
"path": "skills/twitter-GTM-find-skill"
|
|
217
217
|
},
|
|
218
218
|
{
|
|
219
|
-
"name": "yc-
|
|
220
|
-
"description": "
|
|
219
|
+
"name": "yc-jobs-scraper",
|
|
220
|
+
"description": "Scrape daily job listings from YCombinator's Workatastartup platform without duplicates. Use this skill when asked to scrape YC jobs, update the YC companies list, or retrieve the latest startup jobs. It handles authentication, extracts company slugs via Inertia.js JSON payloads, falls back to public YC job pages when necessary, and maintains a local SQLite database to track historical jobs and prevent duplicates.",
|
|
221
221
|
"tags": [],
|
|
222
|
-
"author": "
|
|
223
|
-
"version": "
|
|
222
|
+
"author": "Unknown",
|
|
223
|
+
"version": "0.0.1",
|
|
224
224
|
"path": "skills/yc-intent-radar-skill"
|
|
225
225
|
}
|
|
226
226
|
]
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: luma-attendees-scraper
|
|
3
|
-
description:
|
|
4
|
-
author:
|
|
3
|
+
description: Browser-console script to export attendee data from a Luma event into a CSV. Use when users ask to scrape or export attendees from a Luma event.
|
|
4
|
+
author: Varnan
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
# Luma Attendees Scraper
|
|
9
|
+
|
|
10
|
+
You have access to a JavaScript script (\luma_attendees_export.js\) that runs in the browser console to extract attendee data from a Luma event URL and saves it as a CSV.
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
1. If the user asks to scrape Luma attendees, instruct them to open the Luma event page in their browser.
|
|
14
|
+
2. Ask them to open their browser's Developer Tools (Console).
|
|
15
|
+
3. Provide them with the contents of \luma_attendees_export.js\.
|
|
16
|
+
4. Instruct them to paste the script into the console and hit Enter.
|
|
17
|
+
5. Explain that they can test it first by setting \sampleLimit: 5\, and then \sampleLimit: Infinity\ for the full list.
|
package/src/index.ts
CHANGED
|
@@ -12,9 +12,9 @@ import Table from 'cli-table3';
|
|
|
12
12
|
const program = new Command();
|
|
13
13
|
|
|
14
14
|
program
|
|
15
|
-
.name('@opendirectory.dev/
|
|
15
|
+
.name('@opendirectory.dev/skills')
|
|
16
16
|
.description(chalk.blue.bold('CLI to install OpenDirectory skills'))
|
|
17
|
-
.version('0.1.
|
|
17
|
+
.version('0.1.1');
|
|
18
18
|
|
|
19
19
|
const getProjectRoot = () => {
|
|
20
20
|
return path.resolve(__dirname, '..');
|
|
@@ -59,7 +59,7 @@ program
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
console.log(table.toString());
|
|
62
|
-
console.log(chalk.gray(`\nRun \`${chalk.white('npx @opendirectory.dev/
|
|
62
|
+
console.log(chalk.gray(`\nRun \`${chalk.white('npx "@opendirectory.dev/skills" install <skill-name> --target <agent>')}\` to install a skill.`));
|
|
63
63
|
|
|
64
64
|
} catch (error) {
|
|
65
65
|
spinner.stop();
|
|
@@ -72,7 +72,6 @@ program
|
|
|
72
72
|
.command('install <skill>')
|
|
73
73
|
.description('Install a skill for your AI agent')
|
|
74
74
|
.requiredOption('-t, --target <tool>', 'Target agent (opencode, claude, codex, gemini, anti-gravity, openclaw, hermes)')
|
|
75
|
-
.option('-g, --global', 'Install globally for all projects')
|
|
76
75
|
.action(async (skillName, options) => {
|
|
77
76
|
const spinner = ora(`Installing ${chalk.yellow(skillName)}...`).start();
|
|
78
77
|
try {
|
|
@@ -120,7 +119,7 @@ program
|
|
|
120
119
|
} catch (dirErr) {
|
|
121
120
|
spinner.stop();
|
|
122
121
|
console.error(chalk.red(`Error: Repository '${skillName}' not found.`));
|
|
123
|
-
console.log(chalk.gray(`Try running \`${chalk.white('npx @opendirectory.dev/
|
|
122
|
+
console.log(chalk.gray(`Try running \`${chalk.white('npx "@opendirectory.dev/skills" list')}\` to see available skills.`));
|
|
124
123
|
process.exit(1);
|
|
125
124
|
}
|
|
126
125
|
}
|
|
@@ -137,33 +136,28 @@ program
|
|
|
137
136
|
const finalSkillName = actualSkillFolderName === skillName ? skillName : actualSkillFolderName;
|
|
138
137
|
|
|
139
138
|
const target = options.target.toLowerCase();
|
|
140
|
-
const isGlobal = options.global;
|
|
141
139
|
|
|
142
140
|
const validTargets = ['opencode', 'claude', 'codex', 'gemini', 'anti-gravity', 'openclaw', 'hermes'];
|
|
143
141
|
|
|
144
142
|
if (validTargets.includes(target)) {
|
|
145
143
|
let targetFolder = '';
|
|
146
|
-
if (target === 'opencode') targetFolder =
|
|
147
|
-
if (target === 'claude') targetFolder =
|
|
148
|
-
if (target === 'codex') targetFolder =
|
|
149
|
-
if (target === 'gemini') targetFolder =
|
|
150
|
-
if (target === 'anti-gravity') targetFolder =
|
|
151
|
-
if (target === 'openclaw') targetFolder =
|
|
152
|
-
if (target === 'hermes') targetFolder =
|
|
144
|
+
if (target === 'opencode') targetFolder = `~/.config/opencode/skills/${finalSkillName}`;
|
|
145
|
+
if (target === 'claude') targetFolder = `~/.claude/skills/${finalSkillName}`;
|
|
146
|
+
if (target === 'codex') targetFolder = `~/.codex/skills/${finalSkillName}`;
|
|
147
|
+
if (target === 'gemini') targetFolder = `~/.gemini/skills/${finalSkillName}`;
|
|
148
|
+
if (target === 'anti-gravity') targetFolder = `~/.gemini/antigravity/skills/${finalSkillName}`;
|
|
149
|
+
if (target === 'openclaw') targetFolder = `~/.openclaw/skills/${finalSkillName}`;
|
|
150
|
+
if (target === 'hermes') targetFolder = `~/.hermes/skills/${finalSkillName}`;
|
|
153
151
|
|
|
154
|
-
const { resolvePath
|
|
152
|
+
const { resolvePath } = require('./fs-adapters');
|
|
155
153
|
const resolvedDest = resolvePath(targetFolder);
|
|
156
154
|
await fs.mkdir(resolvedDest, { recursive: true });
|
|
157
155
|
await fs.cp(skillDir, resolvedDest, { recursive: true });
|
|
158
156
|
|
|
159
|
-
if (target === 'hermes' && !isGlobal) {
|
|
160
|
-
await updateHermesConfig();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
157
|
spinner.stop();
|
|
164
158
|
console.log(chalk.green(`Successfully installed ${chalk.bold(finalSkillName)}!`));
|
|
165
159
|
console.log(`\n ${chalk.cyan('Agent:')} ${target}`);
|
|
166
|
-
console.log(` ${chalk.cyan('Scope:')}
|
|
160
|
+
console.log(` ${chalk.cyan('Scope:')} Global`);
|
|
167
161
|
console.log(` ${chalk.cyan('Path:')} ${targetFolder}\n`);
|
|
168
162
|
} else {
|
|
169
163
|
spinner.stop();
|