openclaudia 0.1.0

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 (2) hide show
  1. package/index.mjs +162 -0
  2. package/package.json +23 -0
package/index.mjs ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from "node:child_process";
4
+ import { existsSync, mkdirSync, cpSync, rmSync } from "node:fs";
5
+ import { readdirSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { homedir, tmpdir } from "node:os";
8
+
9
+ const REPO = "https://github.com/OpenClaudia/openclaudia-skills.git";
10
+ const SKILLS_DIR = join(homedir(), ".claude", "skills");
11
+
12
+ const args = process.argv.slice(2);
13
+ const command = args[0];
14
+
15
+ function printHelp() {
16
+ console.log(`
17
+ openclaudia - Marketing skills for Claude Code
18
+
19
+ Usage:
20
+ npx openclaudia install --all Install all skills
21
+ npx openclaudia install <skill-name> Install a specific skill
22
+ npx openclaudia list List available skills
23
+ npx openclaudia remove <skill-name> Remove a skill
24
+ npx openclaudia remove --all Remove all OpenClaudia skills
25
+
26
+ Examples:
27
+ npx openclaudia install --all
28
+ npx openclaudia install seo-audit
29
+ npx openclaudia install write-blog keyword-research
30
+ npx openclaudia list
31
+
32
+ Website: https://openclaudia.com
33
+ GitHub: https://github.com/OpenClaudia/openclaudia-skills
34
+ `);
35
+ }
36
+
37
+ function cloneRepo() {
38
+ const tmpDir = join(tmpdir(), `openclaudia-${Date.now()}`);
39
+ console.log("Fetching skills from GitHub...");
40
+ execSync(`git clone --depth 1 ${REPO} ${tmpDir}`, { stdio: "pipe" });
41
+ return tmpDir;
42
+ }
43
+
44
+ function getAvailableSkills(repoDir) {
45
+ const skillsDir = join(repoDir, "skills");
46
+ return readdirSync(skillsDir).filter((f) => {
47
+ return existsSync(join(skillsDir, f, "SKILL.md"));
48
+ });
49
+ }
50
+
51
+ function installSkills(skillNames) {
52
+ const tmpDir = cloneRepo();
53
+ const repoSkillsDir = join(tmpDir, "skills");
54
+ const available = getAvailableSkills(tmpDir);
55
+
56
+ if (!existsSync(SKILLS_DIR)) {
57
+ mkdirSync(SKILLS_DIR, { recursive: true });
58
+ }
59
+
60
+ let installed = 0;
61
+ for (const name of skillNames) {
62
+ if (!available.includes(name)) {
63
+ console.log(` ! Skill "${name}" not found. Skipping.`);
64
+ continue;
65
+ }
66
+ const src = join(repoSkillsDir, name);
67
+ const dest = join(SKILLS_DIR, name);
68
+ if (existsSync(dest)) {
69
+ console.log(` ~ ${name} (updated)`);
70
+ } else {
71
+ console.log(` + ${name}`);
72
+ }
73
+ cpSync(src, dest, { recursive: true });
74
+ installed++;
75
+ }
76
+
77
+ rmSync(tmpDir, { recursive: true, force: true });
78
+ return installed;
79
+ }
80
+
81
+ if (!command || command === "help" || command === "--help" || command === "-h") {
82
+ printHelp();
83
+ process.exit(0);
84
+ }
85
+
86
+ if (command === "list") {
87
+ const tmpDir = cloneRepo();
88
+ const skills = getAvailableSkills(tmpDir);
89
+ console.log(`\n ${skills.length} available skills:\n`);
90
+ for (const s of skills.sort()) {
91
+ const installed = existsSync(join(SKILLS_DIR, s));
92
+ console.log(` ${installed ? "[installed]" : " "} ${s}`);
93
+ }
94
+ console.log();
95
+ rmSync(tmpDir, { recursive: true, force: true });
96
+ process.exit(0);
97
+ }
98
+
99
+ if (command === "install") {
100
+ const targets = args.slice(1);
101
+
102
+ if (targets.length === 0) {
103
+ console.log("Usage: npx openclaudia install --all | <skill-name> ...");
104
+ process.exit(1);
105
+ }
106
+
107
+ if (targets.includes("--all")) {
108
+ const tmpDir = cloneRepo();
109
+ const all = getAvailableSkills(tmpDir);
110
+ rmSync(tmpDir, { recursive: true, force: true });
111
+ console.log(`\nInstalling all ${all.length} skills to ${SKILLS_DIR}...\n`);
112
+ const count = installSkills(all);
113
+ console.log(`\nDone! ${count} skills installed.`);
114
+ console.log(`Skills directory: ${SKILLS_DIR}`);
115
+ console.log(`\nRun "claude" and try /write-blog or /seo-audit to get started.\n`);
116
+ } else {
117
+ console.log(`\nInstalling ${targets.length} skill(s) to ${SKILLS_DIR}...\n`);
118
+ const count = installSkills(targets);
119
+ console.log(`\nDone! ${count} skill(s) installed.\n`);
120
+ }
121
+ process.exit(0);
122
+ }
123
+
124
+ if (command === "remove") {
125
+ const targets = args.slice(1);
126
+
127
+ if (targets.length === 0) {
128
+ console.log("Usage: npx openclaudia remove --all | <skill-name> ...");
129
+ process.exit(1);
130
+ }
131
+
132
+ if (targets.includes("--all")) {
133
+ const tmpDir = cloneRepo();
134
+ const all = getAvailableSkills(tmpDir);
135
+ rmSync(tmpDir, { recursive: true, force: true });
136
+ let removed = 0;
137
+ for (const name of all) {
138
+ const dest = join(SKILLS_DIR, name);
139
+ if (existsSync(dest)) {
140
+ rmSync(dest, { recursive: true, force: true });
141
+ console.log(` - ${name}`);
142
+ removed++;
143
+ }
144
+ }
145
+ console.log(`\nRemoved ${removed} skill(s).\n`);
146
+ } else {
147
+ for (const name of targets) {
148
+ const dest = join(SKILLS_DIR, name);
149
+ if (existsSync(dest)) {
150
+ rmSync(dest, { recursive: true, force: true });
151
+ console.log(` - ${name}`);
152
+ } else {
153
+ console.log(` ! ${name} not installed. Skipping.`);
154
+ }
155
+ }
156
+ }
157
+ process.exit(0);
158
+ }
159
+
160
+ console.log(`Unknown command: ${command}`);
161
+ printHelp();
162
+ process.exit(1);
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "openclaudia",
3
+ "version": "0.1.0",
4
+ "description": "Install OpenClaudia marketing skills for Claude Code",
5
+ "bin": {
6
+ "openclaudia": "./index.mjs"
7
+ },
8
+ "keywords": [
9
+ "claude-code",
10
+ "marketing",
11
+ "skills",
12
+ "seo",
13
+ "ai",
14
+ "openclaudia"
15
+ ],
16
+ "homepage": "https://openclaudia.com",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/OpenClaudia/openclaudia-skills"
20
+ },
21
+ "license": "MIT",
22
+ "author": "Quanlai Li <quanlaili@gmail.com> (https://quanl.ai)"
23
+ }