@opendirectory.dev/skills 0.1.0 → 0.1.2
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 +15 -18
- package/package.json +1 -1
- package/registry.json +29 -29
- package/skills/luma-attendees-scraper/SKILL.md +12 -2
- package/src/index.ts +16 -19
package/dist/index.js
CHANGED
|
@@ -39,15 +39,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
const commander_1 = require("commander");
|
|
41
41
|
const fs = __importStar(require("node:fs/promises"));
|
|
42
|
+
const fsSync = __importStar(require("node:fs"));
|
|
42
43
|
const path = __importStar(require("node:path"));
|
|
43
44
|
const chalk_1 = __importDefault(require("chalk"));
|
|
44
45
|
const ora_1 = __importDefault(require("ora"));
|
|
45
46
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
46
47
|
const program = new commander_1.Command();
|
|
48
|
+
const pkg = JSON.parse(fsSync.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
|
|
47
49
|
program
|
|
48
|
-
.name('@opendirectory.dev/
|
|
50
|
+
.name('@opendirectory.dev/skills')
|
|
49
51
|
.description(chalk_1.default.blue.bold('CLI to install OpenDirectory skills'))
|
|
50
|
-
.version(
|
|
52
|
+
.version(pkg.version);
|
|
51
53
|
const getProjectRoot = () => {
|
|
52
54
|
return path.resolve(__dirname, '..');
|
|
53
55
|
};
|
|
@@ -86,7 +88,7 @@ program
|
|
|
86
88
|
table.push([chalk_1.default.yellow(skill.name), desc]);
|
|
87
89
|
}
|
|
88
90
|
console.log(table.toString());
|
|
89
|
-
console.log(chalk_1.default.gray(`\nRun \`${chalk_1.default.white('npx @opendirectory.dev/
|
|
91
|
+
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
92
|
}
|
|
91
93
|
catch (error) {
|
|
92
94
|
spinner.stop();
|
|
@@ -98,7 +100,6 @@ program
|
|
|
98
100
|
.command('install <skill>')
|
|
99
101
|
.description('Install a skill for your AI agent')
|
|
100
102
|
.requiredOption('-t, --target <tool>', 'Target agent (opencode, claude, codex, gemini, anti-gravity, openclaw, hermes)')
|
|
101
|
-
.option('-g, --global', 'Install globally for all projects')
|
|
102
103
|
.action(async (skillName, options) => {
|
|
103
104
|
const spinner = (0, ora_1.default)(`Installing ${chalk_1.default.yellow(skillName)}...`).start();
|
|
104
105
|
try {
|
|
@@ -148,7 +149,7 @@ program
|
|
|
148
149
|
catch (dirErr) {
|
|
149
150
|
spinner.stop();
|
|
150
151
|
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/
|
|
152
|
+
console.log(chalk_1.default.gray(`Try running \`${chalk_1.default.white('npx "@opendirectory.dev/skills" list')}\` to see available skills.`));
|
|
152
153
|
process.exit(1);
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -163,35 +164,31 @@ program
|
|
|
163
164
|
const actualSkillFolderName = path.basename(skillDir);
|
|
164
165
|
const finalSkillName = actualSkillFolderName === skillName ? skillName : actualSkillFolderName;
|
|
165
166
|
const target = options.target.toLowerCase();
|
|
166
|
-
const isGlobal = options.global;
|
|
167
167
|
const validTargets = ['opencode', 'claude', 'codex', 'gemini', 'anti-gravity', 'openclaw', 'hermes'];
|
|
168
168
|
if (validTargets.includes(target)) {
|
|
169
169
|
let targetFolder = '';
|
|
170
170
|
if (target === 'opencode')
|
|
171
|
-
targetFolder =
|
|
171
|
+
targetFolder = `~/.config/opencode/skills/${finalSkillName}`;
|
|
172
172
|
if (target === 'claude')
|
|
173
|
-
targetFolder =
|
|
173
|
+
targetFolder = `~/.claude/skills/${finalSkillName}`;
|
|
174
174
|
if (target === 'codex')
|
|
175
|
-
targetFolder =
|
|
175
|
+
targetFolder = `~/.codex/skills/${finalSkillName}`;
|
|
176
176
|
if (target === 'gemini')
|
|
177
|
-
targetFolder =
|
|
177
|
+
targetFolder = `~/.gemini/skills/${finalSkillName}`;
|
|
178
178
|
if (target === 'anti-gravity')
|
|
179
|
-
targetFolder =
|
|
179
|
+
targetFolder = `~/.gemini/antigravity/skills/${finalSkillName}`;
|
|
180
180
|
if (target === 'openclaw')
|
|
181
|
-
targetFolder =
|
|
181
|
+
targetFolder = `~/.openclaw/skills/${finalSkillName}`;
|
|
182
182
|
if (target === 'hermes')
|
|
183
|
-
targetFolder =
|
|
184
|
-
const { resolvePath
|
|
183
|
+
targetFolder = `~/.hermes/skills/${finalSkillName}`;
|
|
184
|
+
const { resolvePath } = require('./fs-adapters');
|
|
185
185
|
const resolvedDest = resolvePath(targetFolder);
|
|
186
186
|
await fs.mkdir(resolvedDest, { recursive: true });
|
|
187
187
|
await fs.cp(skillDir, resolvedDest, { recursive: true });
|
|
188
|
-
if (target === 'hermes' && !isGlobal) {
|
|
189
|
-
await updateHermesConfig();
|
|
190
|
-
}
|
|
191
188
|
spinner.stop();
|
|
192
189
|
console.log(chalk_1.default.green(`Successfully installed ${chalk_1.default.bold(finalSkillName)}!`));
|
|
193
190
|
console.log(`\n ${chalk_1.default.cyan('Agent:')} ${target}`);
|
|
194
|
-
console.log(` ${chalk_1.default.cyan('Scope:')}
|
|
191
|
+
console.log(` ${chalk_1.default.cyan('Scope:')} Global`);
|
|
195
192
|
console.log(` ${chalk_1.default.cyan('Path:')} ${targetFolder}\n`);
|
|
196
193
|
}
|
|
197
194
|
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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as fsSync from 'node:fs';
|
|
5
6
|
import * as path from 'node:path';
|
|
6
7
|
import { Skill } from './transformers';
|
|
7
8
|
import { safeWriteFile } from './fs-adapters';
|
|
@@ -11,10 +12,12 @@ import Table from 'cli-table3';
|
|
|
11
12
|
|
|
12
13
|
const program = new Command();
|
|
13
14
|
|
|
15
|
+
const pkg = JSON.parse(fsSync.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
|
|
16
|
+
|
|
14
17
|
program
|
|
15
|
-
.name('@opendirectory.dev/
|
|
18
|
+
.name('@opendirectory.dev/skills')
|
|
16
19
|
.description(chalk.blue.bold('CLI to install OpenDirectory skills'))
|
|
17
|
-
.version(
|
|
20
|
+
.version(pkg.version);
|
|
18
21
|
|
|
19
22
|
const getProjectRoot = () => {
|
|
20
23
|
return path.resolve(__dirname, '..');
|
|
@@ -59,7 +62,7 @@ program
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
console.log(table.toString());
|
|
62
|
-
console.log(chalk.gray(`\nRun \`${chalk.white('npx @opendirectory.dev/
|
|
65
|
+
console.log(chalk.gray(`\nRun \`${chalk.white('npx "@opendirectory.dev/skills" install <skill-name> --target <agent>')}\` to install a skill.`));
|
|
63
66
|
|
|
64
67
|
} catch (error) {
|
|
65
68
|
spinner.stop();
|
|
@@ -72,7 +75,6 @@ program
|
|
|
72
75
|
.command('install <skill>')
|
|
73
76
|
.description('Install a skill for your AI agent')
|
|
74
77
|
.requiredOption('-t, --target <tool>', 'Target agent (opencode, claude, codex, gemini, anti-gravity, openclaw, hermes)')
|
|
75
|
-
.option('-g, --global', 'Install globally for all projects')
|
|
76
78
|
.action(async (skillName, options) => {
|
|
77
79
|
const spinner = ora(`Installing ${chalk.yellow(skillName)}...`).start();
|
|
78
80
|
try {
|
|
@@ -120,7 +122,7 @@ program
|
|
|
120
122
|
} catch (dirErr) {
|
|
121
123
|
spinner.stop();
|
|
122
124
|
console.error(chalk.red(`Error: Repository '${skillName}' not found.`));
|
|
123
|
-
console.log(chalk.gray(`Try running \`${chalk.white('npx @opendirectory.dev/
|
|
125
|
+
console.log(chalk.gray(`Try running \`${chalk.white('npx "@opendirectory.dev/skills" list')}\` to see available skills.`));
|
|
124
126
|
process.exit(1);
|
|
125
127
|
}
|
|
126
128
|
}
|
|
@@ -137,33 +139,28 @@ program
|
|
|
137
139
|
const finalSkillName = actualSkillFolderName === skillName ? skillName : actualSkillFolderName;
|
|
138
140
|
|
|
139
141
|
const target = options.target.toLowerCase();
|
|
140
|
-
const isGlobal = options.global;
|
|
141
142
|
|
|
142
143
|
const validTargets = ['opencode', 'claude', 'codex', 'gemini', 'anti-gravity', 'openclaw', 'hermes'];
|
|
143
144
|
|
|
144
145
|
if (validTargets.includes(target)) {
|
|
145
146
|
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 =
|
|
147
|
+
if (target === 'opencode') targetFolder = `~/.config/opencode/skills/${finalSkillName}`;
|
|
148
|
+
if (target === 'claude') targetFolder = `~/.claude/skills/${finalSkillName}`;
|
|
149
|
+
if (target === 'codex') targetFolder = `~/.codex/skills/${finalSkillName}`;
|
|
150
|
+
if (target === 'gemini') targetFolder = `~/.gemini/skills/${finalSkillName}`;
|
|
151
|
+
if (target === 'anti-gravity') targetFolder = `~/.gemini/antigravity/skills/${finalSkillName}`;
|
|
152
|
+
if (target === 'openclaw') targetFolder = `~/.openclaw/skills/${finalSkillName}`;
|
|
153
|
+
if (target === 'hermes') targetFolder = `~/.hermes/skills/${finalSkillName}`;
|
|
153
154
|
|
|
154
|
-
const { resolvePath
|
|
155
|
+
const { resolvePath } = require('./fs-adapters');
|
|
155
156
|
const resolvedDest = resolvePath(targetFolder);
|
|
156
157
|
await fs.mkdir(resolvedDest, { recursive: true });
|
|
157
158
|
await fs.cp(skillDir, resolvedDest, { recursive: true });
|
|
158
159
|
|
|
159
|
-
if (target === 'hermes' && !isGlobal) {
|
|
160
|
-
await updateHermesConfig();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
160
|
spinner.stop();
|
|
164
161
|
console.log(chalk.green(`Successfully installed ${chalk.bold(finalSkillName)}!`));
|
|
165
162
|
console.log(`\n ${chalk.cyan('Agent:')} ${target}`);
|
|
166
|
-
console.log(` ${chalk.cyan('Scope:')}
|
|
163
|
+
console.log(` ${chalk.cyan('Scope:')} Global`);
|
|
167
164
|
console.log(` ${chalk.cyan('Path:')} ${targetFolder}\n`);
|
|
168
165
|
} else {
|
|
169
166
|
spinner.stop();
|