@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 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/cli')
50
+ .name('@opendirectory.dev/skills')
49
51
  .description(chalk_1.default.blue.bold('CLI to install OpenDirectory skills'))
50
- .version('0.1.0');
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/cli install <skill-name> --target <agent>')}\` to install a skill.`));
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/cli list')}\` to see available skills.`));
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 = isGlobal ? `~/.config/opencode/skills/${finalSkillName}` : `./.opencode/skills/${finalSkillName}`;
171
+ targetFolder = `~/.config/opencode/skills/${finalSkillName}`;
172
172
  if (target === 'claude')
173
- targetFolder = isGlobal ? `~/.claude/skills/${finalSkillName}` : `./.claude/skills/${finalSkillName}`;
173
+ targetFolder = `~/.claude/skills/${finalSkillName}`;
174
174
  if (target === 'codex')
175
- targetFolder = isGlobal ? `~/.codex/skills/${finalSkillName}` : `./.codex/skills/${finalSkillName}`;
175
+ targetFolder = `~/.codex/skills/${finalSkillName}`;
176
176
  if (target === 'gemini')
177
- targetFolder = isGlobal ? `~/.gemini/skills/${finalSkillName}` : `./.gemini/skills/${finalSkillName}`;
177
+ targetFolder = `~/.gemini/skills/${finalSkillName}`;
178
178
  if (target === 'anti-gravity')
179
- targetFolder = isGlobal ? `~/.gemini/antigravity/skills/${finalSkillName}` : `./.agent/skills/${finalSkillName}`;
179
+ targetFolder = `~/.gemini/antigravity/skills/${finalSkillName}`;
180
180
  if (target === 'openclaw')
181
- targetFolder = isGlobal ? `~/.openclaw/skills/${finalSkillName}` : `./.openclaw/skills/${finalSkillName}`;
181
+ targetFolder = `~/.openclaw/skills/${finalSkillName}`;
182
182
  if (target === 'hermes')
183
- targetFolder = isGlobal ? `~/.hermes/skills/${finalSkillName}` : `./.hermes/skills/${finalSkillName}`;
184
- const { resolvePath, updateHermesConfig } = require('./fs-adapters');
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:')} ${isGlobal ? 'Global' : 'Local Project'}`);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendirectory.dev/skills",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "bin": {
package/registry.json CHANGED
@@ -1,10 +1,10 @@
1
1
  [
2
2
  {
3
- "name": "blog-cover-image-cli",
4
- "description": "A skill for blog-cover-image-cli",
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": "OpenDirectory",
7
- "version": "1.0.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": "google-trends-api-skills",
52
- "description": "A skill for google-trends-api-skills",
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": "OpenDirectory",
55
- "version": "1.0.0",
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": "A skill for luma-attendees-scraper",
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": "OpenDirectory",
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-skill",
108
- "description": "A skill for meta-ads-skill",
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": "OpenDirectory",
111
- "version": "1.0.0",
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": "A skill for position-me",
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": "OpenDirectory",
143
- "version": "1.0.0",
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": "A skill for stargazer",
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": "OpenDirectory",
199
- "version": "1.0.0",
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-skill",
212
- "description": "A skill for twitter-GTM-find-skill",
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": "OpenDirectory",
215
- "version": "1.0.0",
214
+ "author": "Unknown",
215
+ "version": "0.0.1",
216
216
  "path": "skills/twitter-GTM-find-skill"
217
217
  },
218
218
  {
219
- "name": "yc-intent-radar-skill",
220
- "description": "A skill for yc-intent-radar-skill",
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": "OpenDirectory",
223
- "version": "1.0.0",
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: A skill for luma-attendees-scraper
4
- author: OpenDirectory
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/cli')
18
+ .name('@opendirectory.dev/skills')
16
19
  .description(chalk.blue.bold('CLI to install OpenDirectory skills'))
17
- .version('0.1.0');
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/cli install <skill-name> --target <agent>')}\` to install a skill.`));
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/cli list')}\` to see available skills.`));
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 = isGlobal ? `~/.config/opencode/skills/${finalSkillName}` : `./.opencode/skills/${finalSkillName}`;
147
- if (target === 'claude') targetFolder = isGlobal ? `~/.claude/skills/${finalSkillName}` : `./.claude/skills/${finalSkillName}`;
148
- if (target === 'codex') targetFolder = isGlobal ? `~/.codex/skills/${finalSkillName}` : `./.codex/skills/${finalSkillName}`;
149
- if (target === 'gemini') targetFolder = isGlobal ? `~/.gemini/skills/${finalSkillName}` : `./.gemini/skills/${finalSkillName}`;
150
- if (target === 'anti-gravity') targetFolder = isGlobal ? `~/.gemini/antigravity/skills/${finalSkillName}` : `./.agent/skills/${finalSkillName}`;
151
- if (target === 'openclaw') targetFolder = isGlobal ? `~/.openclaw/skills/${finalSkillName}` : `./.openclaw/skills/${finalSkillName}`;
152
- if (target === 'hermes') targetFolder = isGlobal ? `~/.hermes/skills/${finalSkillName}` : `./.hermes/skills/${finalSkillName}`;
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, updateHermesConfig } = require('./fs-adapters');
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:')} ${isGlobal ? 'Global' : 'Local Project'}`);
163
+ console.log(` ${chalk.cyan('Scope:')} Global`);
167
164
  console.log(` ${chalk.cyan('Path:')} ${targetFolder}\n`);
168
165
  } else {
169
166
  spinner.stop();