timelabs 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.
package/dist/index.js ADDED
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command as Command3 } from "commander";
5
+
6
+ // src/commands/install.ts
7
+ import { Command } from "commander";
8
+ import chalk from "chalk";
9
+
10
+ // src/registry/registry.ts
11
+ import { fileURLToPath } from "url";
12
+ import { dirname, resolve } from "path";
13
+
14
+ // src/registry/skills.json
15
+ var skills_default = [
16
+ {
17
+ name: "test-skill",
18
+ displayName: "Test Skill",
19
+ description: "A sample skill for testing the installer",
20
+ version: "1.0.0",
21
+ targets: ["claude-code", "cursor", "openclaw"]
22
+ }
23
+ ];
24
+
25
+ // src/registry/registry.ts
26
+ var __filename = fileURLToPath(import.meta.url);
27
+ var __dirname = dirname(__filename);
28
+ function loadSkills() {
29
+ return skills_default;
30
+ }
31
+ function filterByTarget(skills, target) {
32
+ if (target === "all") return skills;
33
+ return skills.filter((s) => s.targets.includes(target));
34
+ }
35
+ function getSkillsDir() {
36
+ return resolve(__dirname, "..", "skills");
37
+ }
38
+
39
+ // src/prompts/select-skills.ts
40
+ import { checkbox } from "@inquirer/prompts";
41
+ async function selectSkills(skills) {
42
+ const selected = await checkbox({
43
+ message: "Select skills to install:",
44
+ choices: skills.map((s) => ({
45
+ name: `${s.displayName} - ${s.description}`,
46
+ value: s.name,
47
+ checked: true
48
+ }))
49
+ });
50
+ return skills.filter((s) => selected.includes(s.name));
51
+ }
52
+
53
+ // src/installers/claude-code.ts
54
+ import { existsSync, mkdirSync, cpSync } from "fs";
55
+ import { resolve as resolve2, join } from "path";
56
+ import { homedir } from "os";
57
+ var ClaudeCodeInstaller = class {
58
+ name = "Claude Code";
59
+ targetKey = "claude-code";
60
+ isAvailable() {
61
+ return existsSync(resolve2(homedir(), ".claude"));
62
+ }
63
+ getTargetDir(skillName) {
64
+ return resolve2(homedir(), ".claude", "skills", skillName);
65
+ }
66
+ async install(skillName, skillsDir) {
67
+ const src = join(skillsDir, skillName, "claude-code");
68
+ const dest = this.getTargetDir(skillName);
69
+ if (!existsSync(src)) {
70
+ throw new Error(`No Claude Code files found for skill "${skillName}"`);
71
+ }
72
+ mkdirSync(dest, { recursive: true });
73
+ cpSync(src, dest, { recursive: true });
74
+ }
75
+ };
76
+
77
+ // src/installers/cursor.ts
78
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, cpSync as cpSync2 } from "fs";
79
+ import { resolve as resolve3, join as join2 } from "path";
80
+ import { homedir as homedir2 } from "os";
81
+ var CursorInstaller = class {
82
+ name = "Cursor";
83
+ targetKey = "cursor";
84
+ isAvailable() {
85
+ return existsSync2(resolve3(homedir2(), ".cursor"));
86
+ }
87
+ getTargetDir(_skillName) {
88
+ return resolve3(homedir2(), ".cursor", "rules");
89
+ }
90
+ async install(skillName, skillsDir) {
91
+ const src = join2(skillsDir, skillName, "cursor");
92
+ const dest = this.getTargetDir(skillName);
93
+ if (!existsSync2(src)) {
94
+ throw new Error(`No Cursor files found for skill "${skillName}"`);
95
+ }
96
+ mkdirSync2(dest, { recursive: true });
97
+ cpSync2(src, dest, { recursive: true });
98
+ }
99
+ };
100
+
101
+ // src/installers/openclaw.ts
102
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, cpSync as cpSync3 } from "fs";
103
+ import { resolve as resolve4, join as join3 } from "path";
104
+ import { homedir as homedir3 } from "os";
105
+ var OpenClawInstaller = class {
106
+ name = "OpenClaw";
107
+ targetKey = "openclaw";
108
+ isAvailable() {
109
+ return existsSync3(resolve4(homedir3(), ".openclaw"));
110
+ }
111
+ getTargetDir(skillName) {
112
+ return resolve4(homedir3(), ".openclaw", "workspace", "skills", skillName);
113
+ }
114
+ async install(skillName, skillsDir) {
115
+ const src = join3(skillsDir, skillName, "openclaw");
116
+ const dest = this.getTargetDir(skillName);
117
+ if (!existsSync3(src)) {
118
+ throw new Error(`No OpenClaw files found for skill "${skillName}"`);
119
+ }
120
+ mkdirSync3(dest, { recursive: true });
121
+ cpSync3(src, dest, { recursive: true });
122
+ }
123
+ };
124
+
125
+ // src/commands/install.ts
126
+ var allInstallers = [
127
+ new ClaudeCodeInstaller(),
128
+ new CursorInstaller(),
129
+ new OpenClawInstaller()
130
+ ];
131
+ var installCommand = new Command("install").description("Interactively select and install skills").option(
132
+ "-t, --target <target>",
133
+ "Target AI tool (claude-code, cursor, openclaw, all)",
134
+ "all"
135
+ ).action(async (opts) => {
136
+ const { target } = opts;
137
+ const skills = filterByTarget(loadSkills(), target);
138
+ if (skills.length === 0) {
139
+ console.log(chalk.yellow("No skills found for the specified target."));
140
+ return;
141
+ }
142
+ const selected = await selectSkills(skills);
143
+ if (selected.length === 0) {
144
+ console.log(chalk.yellow("No skills selected."));
145
+ return;
146
+ }
147
+ const skillsDir = getSkillsDir();
148
+ const installers = target === "all" ? allInstallers : allInstallers.filter((i) => i.targetKey === target);
149
+ let installed = 0;
150
+ let skipped = 0;
151
+ for (const skill of selected) {
152
+ for (const installer of installers) {
153
+ if (!skill.targets.includes(installer.targetKey)) continue;
154
+ if (!installer.isAvailable()) {
155
+ console.log(
156
+ chalk.dim(
157
+ ` \u23ED ${installer.name} not detected, skipping "${skill.displayName}"`
158
+ )
159
+ );
160
+ skipped++;
161
+ continue;
162
+ }
163
+ try {
164
+ await installer.install(skill.name, skillsDir);
165
+ console.log(
166
+ chalk.green(
167
+ ` \u2713 Installed "${skill.displayName}" for ${installer.name}`
168
+ )
169
+ );
170
+ installed++;
171
+ } catch (err) {
172
+ const msg = err instanceof Error ? err.message : String(err);
173
+ console.log(
174
+ chalk.red(` \u2717 Failed to install "${skill.displayName}" for ${installer.name}: ${msg}`)
175
+ );
176
+ }
177
+ }
178
+ }
179
+ console.log();
180
+ console.log(
181
+ chalk.bold(`Done! ${installed} installed, ${skipped} skipped.`)
182
+ );
183
+ });
184
+
185
+ // src/commands/list.ts
186
+ import { Command as Command2 } from "commander";
187
+ import chalk2 from "chalk";
188
+ var listCommand = new Command2("list").description("List available skills").option(
189
+ "-t, --target <target>",
190
+ "Filter by AI tool (claude-code, cursor, openclaw, all)",
191
+ "all"
192
+ ).action((opts) => {
193
+ const skills = filterByTarget(loadSkills(), opts.target);
194
+ if (skills.length === 0) {
195
+ console.log(chalk2.yellow("No skills found."));
196
+ return;
197
+ }
198
+ console.log(chalk2.bold("\nAvailable Skills:\n"));
199
+ for (const skill of skills) {
200
+ console.log(` ${chalk2.cyan(skill.displayName)} (${skill.version})`);
201
+ console.log(` ${skill.description}`);
202
+ console.log(` Targets: ${skill.targets.join(", ")}`);
203
+ console.log();
204
+ }
205
+ });
206
+
207
+ // src/index.ts
208
+ var program = new Command3();
209
+ program.name("timelabs").description("Install AI skill packages for Claude Code, Cursor, and OpenClaw").version("0.1.0");
210
+ program.addCommand(installCommand);
211
+ program.addCommand(listCommand);
212
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "timelabs",
3
+ "version": "0.1.0",
4
+ "description": "Install AI skill packages for Claude Code, Cursor, and OpenClaw",
5
+ "type": "module",
6
+ "bin": {
7
+ "timelabs": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "skills"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsup --watch"
16
+ },
17
+ "keywords": [
18
+ "cli",
19
+ "ai",
20
+ "skills",
21
+ "claude",
22
+ "cursor",
23
+ "openclaw"
24
+ ],
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@inquirer/prompts": "^7.0.0",
28
+ "chalk": "^5.3.0",
29
+ "commander": "^12.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "tsup": "^8.0.0",
34
+ "typescript": "^5.5.0"
35
+ }
36
+ }
@@ -0,0 +1,7 @@
1
+ # Test Skill
2
+
3
+ This is a test skill for Claude Code.
4
+
5
+ ## Instructions
6
+
7
+ When the user asks you to run the test skill, respond with "Test skill is active!"
@@ -0,0 +1,7 @@
1
+ # Test Skill
2
+
3
+ This is a test skill for Cursor.
4
+
5
+ ## Instructions
6
+
7
+ When the user asks you to run the test skill, respond with "Test skill is active!"
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: test-skill
3
+ version: 1.0.0
4
+ description: A sample skill for testing the installer
5
+ ---
6
+
7
+ # Test Skill
8
+
9
+ This is a test skill for OpenClaw.
10
+
11
+ ## Instructions
12
+
13
+ When the user asks you to run the test skill, respond with "Test skill is active!"
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "test-skill",
3
+ "displayName": "Test Skill",
4
+ "description": "A sample skill for testing the installer",
5
+ "version": "1.0.0"
6
+ }