understanding-prime-env 0.1.4 → 0.1.5
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/bin/install.js +76 -38
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const os = require('os');
|
|
8
|
-
const readline = require('readline');
|
|
9
8
|
|
|
10
9
|
const SKILL_NAME = 'understand-prime-env';
|
|
11
10
|
const PACKAGE_ROOT = path.join(__dirname, '..');
|
|
12
11
|
const SKILL_MD_PATH = path.join(PACKAGE_ROOT, 'skills', SKILL_NAME, 'SKILL.md');
|
|
13
12
|
|
|
14
|
-
// ── helpers
|
|
13
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
15
14
|
|
|
16
15
|
function readSkillRaw() {
|
|
17
16
|
return fs.readFileSync(SKILL_MD_PATH, 'utf8');
|
|
@@ -37,9 +36,64 @@ function appendOrCreate(filePath, section) {
|
|
|
37
36
|
|
|
38
37
|
function ok(msg) { console.log('\x1b[32m✓\x1b[0m ' + msg); }
|
|
39
38
|
function info(msg) { console.log('\x1b[36mℹ\x1b[0m ' + msg); }
|
|
40
|
-
function warn(msg) { console.log('\x1b[33m⚠\x1b[0m ' + msg); }
|
|
41
39
|
function fail(msg) { console.error('\x1b[31m✗\x1b[0m ' + msg); process.exit(1); }
|
|
42
40
|
|
|
41
|
+
// ── arrow-key selector ────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
function select(question, choices) {
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
let cursor = 0;
|
|
46
|
+
|
|
47
|
+
const RESET = '\x1b[0m';
|
|
48
|
+
const BOLD = '\x1b[1m';
|
|
49
|
+
const ACCENT = '\x1b[35m'; // purple
|
|
50
|
+
const DIM = '\x1b[2m';
|
|
51
|
+
const UP = '\x1b[1A';
|
|
52
|
+
const CLEAR = '\x1b[2K\r';
|
|
53
|
+
|
|
54
|
+
function render(first) {
|
|
55
|
+
if (!first) {
|
|
56
|
+
// move up past all choices + question line
|
|
57
|
+
process.stdout.write(UP.repeat(choices.length + 1));
|
|
58
|
+
}
|
|
59
|
+
process.stdout.write(`${CLEAR}${BOLD}${question}${RESET}\n`);
|
|
60
|
+
choices.forEach((c, i) => {
|
|
61
|
+
const active = i === cursor;
|
|
62
|
+
const pointer = active ? `${ACCENT}❯${RESET}` : ' ';
|
|
63
|
+
const label = active ? `${BOLD}${c}${RESET}` : `${DIM}${c}${RESET}`;
|
|
64
|
+
process.stdout.write(`${CLEAR} ${pointer} ${label}\n`);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
render(true);
|
|
69
|
+
|
|
70
|
+
process.stdin.setRawMode(true);
|
|
71
|
+
process.stdin.resume();
|
|
72
|
+
process.stdin.setEncoding('utf8');
|
|
73
|
+
|
|
74
|
+
function cleanup() {
|
|
75
|
+
process.stdin.setRawMode(false);
|
|
76
|
+
process.stdin.pause();
|
|
77
|
+
process.stdin.removeListener('data', onKey);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function onKey(key) {
|
|
81
|
+
if (key === '') { cleanup(); process.exit(0); } // Ctrl+C
|
|
82
|
+
if (key === '[A' || key === 'k') cursor = (cursor - 1 + choices.length) % choices.length; // up
|
|
83
|
+
if (key === '[B' || key === 'j') cursor = (cursor + 1) % choices.length; // down
|
|
84
|
+
if (key === '\r' || key === '\n') {
|
|
85
|
+
cleanup();
|
|
86
|
+
process.stdout.write('\n');
|
|
87
|
+
resolve(cursor);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
render(false);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
process.stdin.on('data', onKey);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
43
97
|
// ── installers ────────────────────────────────────────────────────────────────
|
|
44
98
|
|
|
45
99
|
function installClaude(isGlobal) {
|
|
@@ -62,10 +116,9 @@ function installCursor() {
|
|
|
62
116
|
const dest = path.join(process.cwd(), '.cursor', 'rules');
|
|
63
117
|
ensureDir(dest);
|
|
64
118
|
const outPath = path.join(dest, `${SKILL_NAME}.mdc`);
|
|
65
|
-
// Cursor MDC format: YAML front-matter + markdown body
|
|
66
119
|
const mdc = [
|
|
67
120
|
'---',
|
|
68
|
-
|
|
121
|
+
'description: understand-prime-env — generate HTML overview for a Prime Intellect verifiers environment',
|
|
69
122
|
'globs:',
|
|
70
123
|
' - "**/*.py"',
|
|
71
124
|
'alwaysApply: false',
|
|
@@ -81,7 +134,7 @@ function installCursor() {
|
|
|
81
134
|
function installWindsurf() {
|
|
82
135
|
const body = readSkillBody();
|
|
83
136
|
const outPath = path.join(process.cwd(), '.windsurfrules');
|
|
84
|
-
const section = `# understand-
|
|
137
|
+
const section = `# understand-prime-env\n\n${body}`;
|
|
85
138
|
appendOrCreate(outPath, section);
|
|
86
139
|
ok(`Windsurf → ${outPath}`);
|
|
87
140
|
}
|
|
@@ -91,7 +144,7 @@ function installCopilot() {
|
|
|
91
144
|
const dir = path.join(process.cwd(), '.github');
|
|
92
145
|
ensureDir(dir);
|
|
93
146
|
const outPath = path.join(dir, 'copilot-instructions.md');
|
|
94
|
-
const section = `# understand-
|
|
147
|
+
const section = `# understand-prime-env\n\n${body}`;
|
|
95
148
|
appendOrCreate(outPath, section);
|
|
96
149
|
ok(`GitHub Copilot → ${outPath}`);
|
|
97
150
|
}
|
|
@@ -111,7 +164,7 @@ function installZed() {
|
|
|
111
164
|
const separator = existing ? '\n\n---\n\n' : '';
|
|
112
165
|
settings.assistant = settings.assistant ?? {};
|
|
113
166
|
settings.assistant.default_context = settings.assistant.default_context ?? {};
|
|
114
|
-
settings.assistant.default_context.custom_instructions = existing + separator + `# understand-
|
|
167
|
+
settings.assistant.default_context.custom_instructions = existing + separator + `# understand-prime-env\n\n${body}`;
|
|
115
168
|
|
|
116
169
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
117
170
|
ok(`Zed → ${settingsPath}`);
|
|
@@ -128,16 +181,16 @@ function installAll(isGlobal) {
|
|
|
128
181
|
// ── CLI ───────────────────────────────────────────────────────────────────────
|
|
129
182
|
|
|
130
183
|
const TOOLS = {
|
|
131
|
-
claude: { label: 'Claude Code',
|
|
132
|
-
cursor: { label: 'Cursor',
|
|
133
|
-
windsurf: { label: 'Windsurf',
|
|
134
|
-
copilot: { label: 'GitHub Copilot',
|
|
135
|
-
zed: { label: 'Zed',
|
|
136
|
-
all: { label: 'All of the above',fn: (g) => installAll(g) },
|
|
184
|
+
claude: { label: 'Claude Code', fn: (g) => installClaude(g) },
|
|
185
|
+
cursor: { label: 'Cursor', fn: () => installCursor() },
|
|
186
|
+
windsurf: { label: 'Windsurf', fn: () => installWindsurf() },
|
|
187
|
+
copilot: { label: 'GitHub Copilot', fn: () => installCopilot() },
|
|
188
|
+
zed: { label: 'Zed', fn: () => installZed() },
|
|
189
|
+
all: { label: 'All of the above', fn: (g) => installAll(g) },
|
|
137
190
|
};
|
|
138
191
|
|
|
139
192
|
const HELP = `
|
|
140
|
-
understand-
|
|
193
|
+
understand-prime-env installer
|
|
141
194
|
Usage: npx understanding-prime-env [tool] [options]
|
|
142
195
|
|
|
143
196
|
Tools (optional — omit for interactive prompt):
|
|
@@ -167,21 +220,8 @@ function parseArgs() {
|
|
|
167
220
|
return { tool, isGlobal };
|
|
168
221
|
}
|
|
169
222
|
|
|
170
|
-
async function prompt(question, choices) {
|
|
171
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
172
|
-
console.log('\n' + question);
|
|
173
|
-
choices.forEach((c, i) => console.log(` ${i + 1}) ${c}`));
|
|
174
|
-
return new Promise((resolve) => {
|
|
175
|
-
rl.question('\nEnter number: ', (answer) => {
|
|
176
|
-
rl.close();
|
|
177
|
-
const idx = parseInt(answer, 10) - 1;
|
|
178
|
-
resolve(idx >= 0 && idx < choices.length ? idx : -1);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
223
|
async function main() {
|
|
184
|
-
console.log('\n\x1b[1munderstand-
|
|
224
|
+
console.log('\n\x1b[1munderstand-prime-env\x1b[0m · Prime Intellect verifiers skill\n');
|
|
185
225
|
|
|
186
226
|
const { tool, isGlobal } = parseArgs();
|
|
187
227
|
|
|
@@ -190,20 +230,18 @@ async function main() {
|
|
|
190
230
|
return;
|
|
191
231
|
}
|
|
192
232
|
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
const labels = keys.map(k => TOOLS[k].label);
|
|
196
|
-
const idx = await prompt('Which editor / CLI tool do you want to install for?', labels);
|
|
197
|
-
if (idx === -1) { fail('Invalid selection.'); }
|
|
233
|
+
const keys = Object.keys(TOOLS);
|
|
234
|
+
const labels = keys.map(k => TOOLS[k].label);
|
|
198
235
|
|
|
236
|
+
const idx = await select('Which editor / CLI tool do you want to install for?', labels);
|
|
199
237
|
const chosen = keys[idx];
|
|
200
238
|
let global = isGlobal;
|
|
201
239
|
|
|
202
240
|
if (chosen === 'claude' || chosen === 'all') {
|
|
203
|
-
const scopeIdx = await
|
|
204
|
-
'
|
|
205
|
-
|
|
206
|
-
);
|
|
241
|
+
const scopeIdx = await select('Install scope for Claude Code:', [
|
|
242
|
+
'Global (~/.claude/skills/ — available everywhere)',
|
|
243
|
+
'Local (.claude/skills/ — this project only)',
|
|
244
|
+
]);
|
|
207
245
|
global = scopeIdx === 0;
|
|
208
246
|
}
|
|
209
247
|
|