codelibrium-cli 1.0.0 → 1.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.js +169 -0
  2. package/package.json +10 -6
package/index.js ADDED
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+
3
+ const https = require('https');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const SUPABASE_HOST = 'dlrwytcguskuolvvwhbn.supabase.co';
8
+ const SUPABASE_ANON_KEY =
9
+ process.env.VITE_SUPABASE_ANON_KEY ||
10
+ process.env.SUPABASE_ANON_KEY ||
11
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImRscnd5dGNndXNrdW9sdnZ3aGJuIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQxMDgzOTksImV4cCI6MjA4OTY4NDM5OX0.v7y5qqQQ-CcXRIVZdjypFUT-32Z2eElFAMy3uMFY-xQ';
12
+
13
+ const TOOL_TO_FILENAME = {
14
+ cursor: '.cursorrules',
15
+ claude: 'CLAUDE.md',
16
+ windsurf: '.windsurfrules',
17
+ cline: '.clinerules',
18
+ copilot: '.github/copilot-instructions.md',
19
+ };
20
+
21
+ const VALID_TOOLS = Object.keys(TOOL_TO_FILENAME);
22
+
23
+ function printHelp() {
24
+ console.log(`Codelibrium CLI — install published rulesets into your project.
25
+
26
+ Usage:
27
+ npx codelibrium-cli install <slug> [tool]
28
+
29
+ Commands:
30
+ install <slug> [tool] Fetch a published ruleset and write it to the right file.
31
+ [tool] defaults to "cursor" if omitted.
32
+
33
+ Valid tools:
34
+ ${VALID_TOOLS.join(', ')}
35
+
36
+ Tool → file:
37
+ cursor → .cursorrules
38
+ claude → CLAUDE.md
39
+ windsurf → .windsurfrules
40
+ cline → .clinerules
41
+ copilot → .github/copilot-instructions.md
42
+
43
+ Examples:
44
+ npx codelibrium-cli install my-ruleset
45
+ npx codelibrium-cli install my-ruleset claude
46
+
47
+ Options:
48
+ -h, --help Show this message
49
+ `);
50
+ }
51
+
52
+ function fail(message) {
53
+ console.error(message);
54
+ process.exit(1);
55
+ }
56
+
57
+ function httpsGetJson(urlPath) {
58
+ return new Promise((resolve, reject) => {
59
+ const opts = {
60
+ hostname: SUPABASE_HOST,
61
+ path: urlPath,
62
+ method: 'GET',
63
+ headers: {
64
+ apikey: SUPABASE_ANON_KEY,
65
+ Authorization: `Bearer ${SUPABASE_ANON_KEY}`,
66
+ Accept: 'application/json',
67
+ },
68
+ };
69
+
70
+ const req = https.request(opts, (res) => {
71
+ let body = '';
72
+ res.setEncoding('utf8');
73
+ res.on('data', (chunk) => {
74
+ body += chunk;
75
+ });
76
+ res.on('end', () => {
77
+ if (res.statusCode < 200 || res.statusCode >= 300) {
78
+ reject(
79
+ new Error(
80
+ `Request failed (${res.statusCode}): ${body.slice(0, 300)}${body.length > 300 ? '…' : ''}`,
81
+ ),
82
+ );
83
+ return;
84
+ }
85
+ try {
86
+ resolve(JSON.parse(body));
87
+ } catch (e) {
88
+ reject(new Error(`Invalid JSON from server: ${e.message}`));
89
+ }
90
+ });
91
+ });
92
+
93
+ req.on('error', (err) => {
94
+ reject(new Error(`Network error: ${err.message}`));
95
+ });
96
+ req.end();
97
+ });
98
+ }
99
+
100
+ async function cmdInstall(slug, tool) {
101
+ if (!slug || slug.startsWith('-')) {
102
+ fail('Missing <slug>.\n\nUsage: npx codelibrium-cli install <slug> [tool]\nRun with --help for more.');
103
+ }
104
+
105
+ const t = (tool || 'cursor').toLowerCase();
106
+ if (!TOOL_TO_FILENAME[t]) {
107
+ fail(
108
+ `Unknown tool "${tool || ''}". Valid tools: ${VALID_TOOLS.join(', ')}\nRun with --help for more.`,
109
+ );
110
+ }
111
+
112
+ const filename = TOOL_TO_FILENAME[t];
113
+ const cwd = process.cwd();
114
+ const outPath = path.join(cwd, filename);
115
+
116
+ console.log(`Fetching "${slug}" from Codelibrium...`);
117
+
118
+ const query =
119
+ '/rest/v1/rulesets?slug=eq.' +
120
+ encodeURIComponent(slug) +
121
+ '&select=content,tool,name&is_published=eq.true';
122
+
123
+ let rows;
124
+ try {
125
+ rows = await httpsGetJson(query);
126
+ } catch (e) {
127
+ fail(e.message || String(e));
128
+ }
129
+
130
+ if (!Array.isArray(rows) || rows.length === 0) {
131
+ fail(`No ruleset found with slug "${slug}"`);
132
+ }
133
+
134
+ const row = rows[0];
135
+ const content = row.content;
136
+ const name = row.name != null ? String(row.name) : slug;
137
+
138
+ if (content == null || typeof content !== 'string') {
139
+ fail('Ruleset has no usable content field.');
140
+ }
141
+
142
+ const dir = path.dirname(outPath);
143
+ fs.mkdirSync(dir, { recursive: true });
144
+ fs.writeFileSync(outPath, content, 'utf8');
145
+
146
+ console.log(`✓ Installed "${name}" → ${filename}`);
147
+ console.log('Run your AI tool and the ruleset will be active.');
148
+ }
149
+
150
+ async function main() {
151
+ const argv = process.argv.slice(2);
152
+
153
+ if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
154
+ printHelp();
155
+ return;
156
+ }
157
+
158
+ const cmd = argv[0];
159
+ if (cmd === 'install') {
160
+ await cmdInstall(argv[1], argv[2]);
161
+ return;
162
+ }
163
+
164
+ fail(`Unknown command "${cmd}".\nRun with --help for usage.`);
165
+ }
166
+
167
+ main().catch((e) => {
168
+ fail(e.message || String(e));
169
+ });
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "codelibrium-cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
+ "description": "Install AI rulesets, skills and prompts from Codelibrium",
4
5
  "main": "index.js",
6
+ "bin": {
7
+ "codelibrium": "./index.js",
8
+ "codelibrium-cli": "./index.js"
9
+ },
10
+ "keywords": ["ai", "cursor", "rules", "codelibrium"],
11
+ "author": "Codelibrium",
12
+ "license": "MIT",
5
13
  "scripts": {
6
14
  "test": "echo \"Error: no test specified\" && exit 1"
7
- },
8
- "keywords": [],
9
- "author": "",
10
- "license": "ISC",
11
- "description": ""
15
+ }
12
16
  }