@valentia-ai-skills/framework 1.0.4 → 1.0.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/cli.js +90 -18
- package/package.json +2 -2
package/bin/cli.js
CHANGED
|
@@ -214,6 +214,71 @@ function getLocalSkills() {
|
|
|
214
214
|
return skills;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
// ── Email + OTP Verification ──
|
|
218
|
+
|
|
219
|
+
async function requestOtpForEmail(emailInput) {
|
|
220
|
+
let email = emailInput;
|
|
221
|
+
let attempts = 0;
|
|
222
|
+
|
|
223
|
+
while (attempts < 2) {
|
|
224
|
+
if (!email || !email.includes("@")) {
|
|
225
|
+
console.log(c("red", "Invalid email."));
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
console.log(c("dim", "\nVerifying your email..."));
|
|
230
|
+
|
|
231
|
+
const response = await fetchJSON(SUPABASE_FUNCTION_URL, { email, action: "request_otp" });
|
|
232
|
+
|
|
233
|
+
if (response.error === "not_found") {
|
|
234
|
+
attempts++;
|
|
235
|
+
if (attempts >= 2) {
|
|
236
|
+
console.log(c("red", "\n✗ Email not recognized. Access denied."));
|
|
237
|
+
console.log(c("dim", " Contact your Framework Admin to be added to the system.\n"));
|
|
238
|
+
process.exit(1);
|
|
239
|
+
}
|
|
240
|
+
console.log(c("yellow", "\n⚠ Email not found. Please check and try again.\n"));
|
|
241
|
+
email = await ask(`${c("bold", "Enter your work email:")} `);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (response.error) {
|
|
246
|
+
throw new Error(response.error);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// OTP sent successfully
|
|
250
|
+
console.log(c("green", `\n✓ Found: ${response.user_name}`));
|
|
251
|
+
console.log(c("dim", ` A verification code has been sent to ${email}\n`));
|
|
252
|
+
|
|
253
|
+
return email;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function verifyOtp(email) {
|
|
258
|
+
const otp = await ask(`${c("bold", "Enter the 6-digit code:")} `);
|
|
259
|
+
|
|
260
|
+
if (!otp || otp.length < 4) {
|
|
261
|
+
console.log(c("red", "Invalid code."));
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(c("dim", "\nVerifying code..."));
|
|
266
|
+
|
|
267
|
+
const response = await fetchJSON(SUPABASE_FUNCTION_URL, { email, otp, action: "verify_otp" });
|
|
268
|
+
|
|
269
|
+
if (response.error === "invalid_otp") {
|
|
270
|
+
console.log(c("red", "\n✗ Invalid verification code. Please run setup again."));
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (response.error) {
|
|
275
|
+
throw new Error(response.error);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
console.log(c("green", "✓ Verified!\n"));
|
|
279
|
+
return response;
|
|
280
|
+
}
|
|
281
|
+
|
|
217
282
|
// ── Commands ──
|
|
218
283
|
|
|
219
284
|
async function cmdSetup() {
|
|
@@ -229,37 +294,39 @@ async function cmdSetup() {
|
|
|
229
294
|
}
|
|
230
295
|
|
|
231
296
|
// 2. Ask for email
|
|
232
|
-
|
|
233
|
-
if (!email || !email.includes("@")) {
|
|
234
|
-
console.log(c("red", "Invalid email. Please try again."));
|
|
235
|
-
process.exit(1);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// 3. Lookup team from Supabase
|
|
239
|
-
console.log(c("dim", "\nLooking up your team..."));
|
|
297
|
+
let email = await ask(`${c("bold", "Enter your work email:")} `);
|
|
240
298
|
|
|
241
|
-
let response;
|
|
242
299
|
let skills;
|
|
243
300
|
let teamName = null;
|
|
244
301
|
let useRemote = true;
|
|
245
302
|
|
|
246
303
|
try {
|
|
247
|
-
|
|
304
|
+
// 3. Request OTP (with 1 retry for wrong email)
|
|
305
|
+
email = await requestOtpForEmail(email);
|
|
306
|
+
|
|
307
|
+
// 4. Verify OTP and get skills
|
|
308
|
+
const response = await verifyOtp(email);
|
|
248
309
|
|
|
249
310
|
if (response.team) {
|
|
250
311
|
teamName = response.team.name;
|
|
251
|
-
console.log(c("green",
|
|
312
|
+
console.log(c("green", `✓ Team: ${teamName}`));
|
|
252
313
|
if (response.user) {
|
|
253
314
|
console.log(c("dim", ` Welcome, ${response.user.name} (${response.user.role})`));
|
|
254
315
|
}
|
|
255
316
|
if (response.team.stack_tags?.length) {
|
|
256
317
|
console.log(c("dim", ` Stack: ${response.team.stack_tags.join(", ")}`));
|
|
257
318
|
}
|
|
258
|
-
} else {
|
|
259
|
-
console.log(c("yellow",
|
|
319
|
+
} else if (response.message) {
|
|
320
|
+
console.log(c("yellow", `⚠ ${response.message}`));
|
|
260
321
|
}
|
|
261
322
|
|
|
262
323
|
skills = response.skills || [];
|
|
324
|
+
|
|
325
|
+
if (skills.length === 0) {
|
|
326
|
+
console.log(c("yellow", "\n⚠ No skills are enabled for your team. Contact your Team Lead."));
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
|
|
263
330
|
console.log(` ${c("bold", skills.length)} skill(s) to install\n`);
|
|
264
331
|
|
|
265
332
|
} catch (err) {
|
|
@@ -275,7 +342,7 @@ async function cmdSetup() {
|
|
|
275
342
|
process.exit(1);
|
|
276
343
|
}
|
|
277
344
|
|
|
278
|
-
//
|
|
345
|
+
// 5. Install for each tool
|
|
279
346
|
for (const toolKey of tools) {
|
|
280
347
|
const tool = TOOL_CONFIGS[toolKey];
|
|
281
348
|
if (!tool) continue;
|
|
@@ -290,7 +357,7 @@ async function cmdSetup() {
|
|
|
290
357
|
console.log("");
|
|
291
358
|
}
|
|
292
359
|
|
|
293
|
-
//
|
|
360
|
+
// 6. Save config
|
|
294
361
|
const config = {
|
|
295
362
|
version: require(path.join(__dirname, "..", "package.json")).version,
|
|
296
363
|
email,
|
|
@@ -302,7 +369,7 @@ async function cmdSetup() {
|
|
|
302
369
|
};
|
|
303
370
|
saveConfig(config);
|
|
304
371
|
|
|
305
|
-
//
|
|
372
|
+
// 7. Summary
|
|
306
373
|
console.log(c("blue", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
|
307
374
|
console.log(c("green", "✅ Setup complete!"));
|
|
308
375
|
console.log(` ${skills.length} skills installed for ${tools.length} tool(s)`);
|
|
@@ -320,13 +387,18 @@ async function cmdUpdate() {
|
|
|
320
387
|
process.exit(1);
|
|
321
388
|
}
|
|
322
389
|
|
|
323
|
-
|
|
390
|
+
const email = config.email;
|
|
391
|
+
console.log(c("dim", `Updating for ${email}...`));
|
|
324
392
|
|
|
325
393
|
let skills;
|
|
326
394
|
let teamName = config.team;
|
|
327
395
|
|
|
328
396
|
try {
|
|
329
|
-
|
|
397
|
+
// Request OTP for the saved email
|
|
398
|
+
await requestOtpForEmail(email);
|
|
399
|
+
|
|
400
|
+
// Verify OTP
|
|
401
|
+
const response = await verifyOtp(email);
|
|
330
402
|
skills = response.skills || [];
|
|
331
403
|
teamName = response.team?.name || config.team;
|
|
332
404
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valentia-ai-skills/framework",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "AI development skills framework
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "AI development skills framework ÃÂÃÂÃÂâÃÂÃÂÃÂÃÂÃÂÃÂÃÂàcentralized coding standards, security patterns, and SOPs for AI-assisted development. Works with Claude Code, Cursor, Copilot, Windsurf, and any AI coding tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-skills",
|
|
7
7
|
"claude-code",
|