@valentia-ai-skills/framework 2.0.2 → 2.0.4

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/README.md CHANGED
@@ -65,16 +65,28 @@ npx ai-skills help # Show help
65
65
  #### Legacy Codebase Intelligence Scanner
66
66
 
67
67
  ```bash
68
- # Upload a legacy codebase intelligence package to your team's Skills Console
69
- npx ai-skills upload-legacy-scan --path ./my-project-intelligence/
68
+ # Add / refresh a project by uploading a scan intelligence package
69
+ npx ai-skills legacy-projects add --path ./my-project-intelligence/
70
70
 
71
- # Validate the package payload without uploading (dry run)
72
- npx ai-skills upload-legacy-scan --path ./my-project-intelligence/ --dry-run
71
+ # Validate the payload without uploading (dry run)
72
+ npx ai-skills legacy-projects add --path ./my-project-intelligence/ --dry-run
73
73
 
74
74
  # Supply an explicit auth token instead of going through OTP
75
- npx ai-skills upload-legacy-scan --path ./my-project-intelligence/ --token <your-token>
75
+ npx ai-skills legacy-projects add --path ./my-project-intelligence/ --token <your-token>
76
+
77
+ # List all legacy projects for your team
78
+ npx ai-skills legacy-projects list
79
+
80
+ # Show detailed status + document counts for a project
81
+ npx ai-skills legacy-projects status "My Project"
82
+
83
+ # Delete a project and all its documents (irreversible — prompts for confirmation)
84
+ npx ai-skills legacy-projects remove "My Project"
76
85
  ```
77
86
 
87
+ > `upload-legacy-scan` is also available as a direct alias:
88
+ > `npx ai-skills upload-legacy-scan --path ./my-project-intelligence/`
89
+
78
90
  The `--path` directory must contain a `manifest.json` file. See the [Legacy Scanner](#legacy-codebase-intelligence-scanner) section below for the required format.
79
91
 
80
92
  ### Environment Variables
@@ -85,6 +97,7 @@ The `--path` directory must contain a `manifest.json` file. See the [Legacy Scan
85
97
  | `AI_SKILLS_ANALYZE_URL` | Override the analyze commit function URL |
86
98
  | `AI_SKILLS_SCAN_URL` | Override the scan results function URL |
87
99
  | `AI_SKILLS_UPLOAD_LEGACY_URL` | Override the upload-legacy-scan Edge Function URL |
100
+ | `AI_SKILLS_MANAGE_LEGACY_URL` | Override the manage-legacy-projects Edge Function URL |
88
101
 
89
102
  ---
90
103
 
@@ -276,9 +289,10 @@ The framework supports ingesting intelligence packages generated by legacy codeb
276
289
  ### How It Works
277
290
 
278
291
  1. **Scan** — A compatible scanner tool analyses an existing codebase and produces an intelligence folder
279
- 2. **Upload** — `npx ai-skills upload-legacy-scan --path <folder>` packages and ships the output to your team's console
280
- 3. **Review** — Tech leads review auto-generated skills, approve or request revisions per skill, and publish approved skills into the active toolkit
281
- 4. **Rescan** — Re-running the upload on the same project name appends a new version, preserving history
292
+ 2. **Add** — `npx ai-skills legacy-projects add --path <folder>` uploads the package, creating the project if it doesn't exist or replacing its documents if it does
293
+ 3. **Review** — Tech leads review auto-generated skills, reports, and diagrams in the Skills Console, approving or flagging each document
294
+ 4. **Promote** — Approved skills are promoted into the team's active toolkit and distributed on the next `npx ai-skills update`
295
+ 5. **Rescan** — Re-running `add` on the same project name replaces all documents with the latest scan output
282
296
 
283
297
  ### Intelligence Package Format
284
298
 
@@ -318,18 +332,34 @@ my-project-intelligence/
318
332
 
319
333
  ### Skills Console — Legacy Scanners View
320
334
 
321
- After upload, each project appears in the **Legacy Scanners** section of the Skills Console with:
335
+ After upload, each project appears in the **Legacy Scanners** section of the Skills Console with five tabs:
322
336
 
323
- - **Overview** project stats, completeness score, tech stack
324
- - **Modules** — per-skill approval workflow (approve / needs revision)
325
- - **API Registry** searchable endpoint documentation
326
- - **Business Rules** — searchable rule catalogue
327
- - **Architecture** interactive Mermaid diagrams
328
- - **Risk Report** severity-categorised risk sections
329
- - **Reproduction Guide** interactive onboarding checklist
337
+ | Tab | Contents |
338
+ |-----|----------|
339
+ | **Overview** | Project stats, completeness score, tech stack, interactive reproduction guide |
340
+ | **Skills** | Per-skill approval workflow approve or flag each extracted skill |
341
+ | **Reports** | Searchable reports: API registry, business rules, data models, risk report, etc. |
342
+ | **Architecture** | Interactive Mermaid architecture and ER diagrams |
343
+ | **All Files** | Full document list with category filter + content copy |
330
344
 
331
345
  Approved skills are promoted into the team's standard toolkit and distributed on the next `npx ai-skills update`.
332
346
 
347
+ ### Managing Projects from the CLI
348
+
349
+ ```bash
350
+ # Add a new project (or refresh an existing one)
351
+ npx ai-skills legacy-projects add --path ./my-project-intelligence/
352
+
353
+ # List all projects with status, module count, and completeness score
354
+ npx ai-skills legacy-projects list
355
+
356
+ # Inspect a specific project — shows document counts per category
357
+ npx ai-skills legacy-projects status "My Project"
358
+
359
+ # Permanently delete a project and all its documents
360
+ npx ai-skills legacy-projects remove "My Project"
361
+ ```
362
+
333
363
  ---
334
364
 
335
365
  ## Architecture
package/bin/cli.js CHANGED
@@ -1369,6 +1369,39 @@ async function cmdUploadLegacyScan() {
1369
1369
  process.exit(1);
1370
1370
  }
1371
1371
 
1372
+ // ── Normalize manifest fields (handles alternate scanner output formats) ──
1373
+ if (!manifest.statistics) manifest.statistics = {};
1374
+ const mstats = manifest.statistics;
1375
+ // Some scanners output completionPercentage instead of completeness_score
1376
+ if (mstats.completeness_score === undefined) {
1377
+ mstats.completeness_score = mstats.completionPercentage ?? 0;
1378
+ }
1379
+ // Some scanners put module count in source.modules
1380
+ if (mstats.total_modules === undefined) {
1381
+ mstats.total_modules =
1382
+ manifest.source?.modules ??
1383
+ manifest.source?.fileCount ??
1384
+ (manifest.skills?.length ?? 0);
1385
+ }
1386
+ // Build tech_stack from source fields or scalar values in technologies if missing
1387
+ if (!manifest.tech_stack) {
1388
+ if (manifest.source) {
1389
+ const ts = {};
1390
+ if (manifest.source.language) ts.language = manifest.source.language;
1391
+ if (manifest.source.framework) ts.framework = manifest.source.framework;
1392
+ manifest.tech_stack = ts;
1393
+ } else if (manifest.technologies && typeof manifest.technologies === "object" && !Array.isArray(manifest.technologies)) {
1394
+ // Only use scalar leaf values to avoid [object Object] in display
1395
+ const ts = {};
1396
+ for (const [k, v] of Object.entries(manifest.technologies)) {
1397
+ if (typeof v === "string" || typeof v === "number") ts[k] = v;
1398
+ }
1399
+ manifest.tech_stack = ts;
1400
+ } else {
1401
+ manifest.tech_stack = {};
1402
+ }
1403
+ }
1404
+
1372
1405
  const projectName = manifest.project;
1373
1406
  console.log(`Project: ${c("bold", projectName)}`);
1374
1407
  console.log(`Scanned: ${c("dim", manifest.scanned_at)}`);
@@ -1382,17 +1415,23 @@ async function cmdUploadLegacyScan() {
1382
1415
 
1383
1416
  // ── Read skill files ──
1384
1417
  const skillPayload = [];
1418
+ let modulePriority = 1;
1385
1419
  for (const skillEntry of (manifest.skills || [])) {
1386
- if (!skillEntry.name || !skillEntry.file) continue;
1387
- const skillFilePath = path.join(resolvedPath, skillEntry.file);
1420
+ const skillFile = skillEntry.file || skillEntry.path;
1421
+ if (!skillEntry.name || !skillFile) continue;
1422
+ const skillFilePath = path.join(resolvedPath, skillFile);
1388
1423
  if (!fs.existsSync(skillFilePath)) {
1389
- console.log(c("yellow", ` ⚠ Skill file not found: ${skillEntry.file} — skipping`));
1424
+ console.log(c("yellow", ` ⚠ Skill file not found: ${skillFile} — skipping`));
1390
1425
  continue;
1391
1426
  }
1427
+ const isMaster = (skillEntry.type || "module") === "master";
1392
1428
  skillPayload.push({
1429
+ category: "skill",
1430
+ document_type: isMaster ? "master" : "module",
1393
1431
  name: skillEntry.name,
1394
- type: skillEntry.type || "module",
1395
1432
  content: fs.readFileSync(skillFilePath, "utf-8"),
1433
+ priority: isMaster ? 0 : modulePriority++,
1434
+ metadata: {},
1396
1435
  });
1397
1436
  }
1398
1437
  console.log(`Skills: ${c("green", skillPayload.length.toString())} module(s)`);
@@ -1400,31 +1439,58 @@ async function cmdUploadLegacyScan() {
1400
1439
  // ── Read diagram files ──
1401
1440
  const diagramPayload = [];
1402
1441
  for (const diagramEntry of (manifest.diagrams || [])) {
1403
- if (!diagramEntry.name || !diagramEntry.file) continue;
1404
- const diagramFilePath = path.join(resolvedPath, diagramEntry.file);
1442
+ const diagramFile = diagramEntry.file || diagramEntry.path;
1443
+ if (!diagramEntry.name || !diagramFile) continue;
1444
+ const diagramFilePath = path.join(resolvedPath, diagramFile);
1405
1445
  if (!fs.existsSync(diagramFilePath)) {
1406
- console.log(c("yellow", ` ⚠ Diagram file not found: ${diagramEntry.file} — skipping`));
1446
+ console.log(c("yellow", ` ⚠ Diagram file not found: ${diagramFile} — skipping`));
1407
1447
  continue;
1408
1448
  }
1409
1449
  diagramPayload.push({
1450
+ category: "diagram",
1451
+ document_type: diagramEntry.type || "architecture",
1410
1452
  name: diagramEntry.name,
1411
- type: diagramEntry.type || "architecture",
1412
1453
  content: fs.readFileSync(diagramFilePath, "utf-8"),
1454
+ priority: 0,
1455
+ metadata: {},
1413
1456
  });
1414
1457
  }
1458
+ // Auto-discover .mmd/.mermaid files from diagrams/ subdirectory if manifest listed none
1459
+ if (diagramPayload.length === 0) {
1460
+ const diagramsDir = path.join(resolvedPath, "diagrams");
1461
+ if (fs.existsSync(diagramsDir)) {
1462
+ for (const file of fs.readdirSync(diagramsDir).sort()) {
1463
+ if (/\.(mmd|mermaid)$/i.test(file)) {
1464
+ const name = file.replace(/\.(mmd|mermaid)$/i, "");
1465
+ diagramPayload.push({
1466
+ category: "diagram",
1467
+ document_type: "architecture",
1468
+ name,
1469
+ content: fs.readFileSync(path.join(diagramsDir, file), "utf-8"),
1470
+ priority: 0,
1471
+ metadata: {},
1472
+ });
1473
+ }
1474
+ }
1475
+ if (diagramPayload.length > 0) {
1476
+ console.log(c("dim", ` (auto-discovered ${diagramPayload.length} diagram(s) from diagrams/)`))
1477
+ }
1478
+ }
1479
+ }
1415
1480
  console.log(`Diagrams: ${c("green", diagramPayload.length.toString())} file(s)`);
1416
1481
 
1417
- // ── Read report files ──
1418
- const reportsPayload = {};
1482
+ // ── Read report/guide files ──
1483
+ const GUIDE_TYPES = new Set(["overview", "reproduction_guide"]);
1484
+ const reportPayload = [];
1419
1485
  const reportFileMap = {
1420
- overview: ["OVERVIEW.md", "overview.md"],
1421
- api_registry: ["API_REGISTRY.md", "api_registry.md"],
1422
- business_rules: ["BUSINESS_RULES.md", "business_rules.md"],
1423
- data_models: ["DATA_MODELS.md", "data_models.md"],
1424
- dependencies: ["DEPENDENCIES.md", "dependencies.md"],
1425
- env_config: ["ENV_CONFIG.md", "env_config.md"],
1426
- risk_report: ["RISK_REPORT.md", "risk_report.md"],
1427
- glossary: ["GLOSSARY.md", "glossary.md"],
1486
+ overview: ["OVERVIEW.md", "overview.md"],
1487
+ api_registry: ["API_REGISTRY.md", "api_registry.md"],
1488
+ business_rules: ["BUSINESS_RULES.md", "business_rules.md"],
1489
+ data_models: ["DATA_MODELS.md", "data_models.md"],
1490
+ dependencies: ["DEPENDENCIES.md", "dependencies.md"],
1491
+ env_config: ["ENV_CONFIG.md", "env_config.md"],
1492
+ risk_report: ["RISK_REPORT.md", "risk_report.md"],
1493
+ glossary: ["GLOSSARY.md", "glossary.md"],
1428
1494
  reproduction_guide: ["REPRODUCTION_GUIDE.md", "reproduction_guide.md"],
1429
1495
  };
1430
1496
 
@@ -1436,23 +1502,36 @@ async function cmdUploadLegacyScan() {
1436
1502
  ];
1437
1503
  const found = reportPaths.find((p) => fs.existsSync(p));
1438
1504
  if (found) {
1439
- reportsPayload[key] = fs.readFileSync(found, "utf-8");
1505
+ const isGuide = GUIDE_TYPES.has(key);
1506
+ const displayName = key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
1507
+ reportPayload.push({
1508
+ category: isGuide ? "guide" : "report",
1509
+ document_type: key,
1510
+ name: displayName,
1511
+ content: fs.readFileSync(found, "utf-8"),
1512
+ priority: 0,
1513
+ metadata: {},
1514
+ });
1440
1515
  break;
1441
1516
  }
1442
1517
  }
1443
1518
  }
1444
1519
 
1445
- const reportCount = Object.keys(reportsPayload).length;
1520
+ const reportCount = reportPayload.length;
1446
1521
  console.log(`Reports: ${c("green", reportCount.toString())} file(s)\n`);
1447
1522
 
1523
+ // ── Build unified documents array ──
1524
+ const documentsPayload = [...skillPayload, ...diagramPayload, ...reportPayload];
1525
+
1448
1526
  // ── Dry run: print summary and exit ──
1449
1527
  if (dryRun) {
1450
1528
  console.log(c("yellow", "Dry run — payload summary:"));
1451
1529
  const stats = manifest.statistics || {};
1452
1530
  console.log(` Project name: ${projectName}`);
1453
- console.log(` Modules: ${skillPayload.length}`);
1454
- console.log(` Diagrams: ${diagramPayload.length}`);
1455
- console.log(` Reports: ${reportCount}`);
1531
+ console.log(` Documents total: ${documentsPayload.length}`);
1532
+ console.log(` — Skills: ${skillPayload.length}`);
1533
+ console.log(` — Diagrams: ${diagramPayload.length}`);
1534
+ console.log(` — Reports/Guides: ${reportCount}`);
1456
1535
  if (stats.completeness_score !== undefined) {
1457
1536
  console.log(` Completeness: ${stats.completeness_score}%`);
1458
1537
  }
@@ -1472,13 +1551,13 @@ async function cmdUploadLegacyScan() {
1472
1551
  email = await ask(`${c("bold", "Work email:")} `);
1473
1552
  const otpResult = await requestOtpForEmail(email);
1474
1553
  email = otpResult.email;
1475
- await verifyOtp(email); // we only need the OTP verification, not the toolkit
1554
+ await verifyOtp(email);
1476
1555
  }
1477
1556
  }
1478
1557
 
1479
1558
  // ── Upload ──
1480
1559
  console.log(c("dim", `Uploading to Valentia (${projectName})...\n`));
1481
- process.stdout.write(` ${c("dim", "→")} Sending ${skillPayload.length} skills, ${diagramPayload.length} diagrams, ${reportCount} reports...`);
1560
+ process.stdout.write(` ${c("dim", "→")} Sending ${documentsPayload.length} documents (${skillPayload.length} skills, ${diagramPayload.length} diagrams, ${reportCount} reports)...`);
1482
1561
 
1483
1562
  let result;
1484
1563
  try {
@@ -1487,9 +1566,7 @@ async function cmdUploadLegacyScan() {
1487
1566
  {
1488
1567
  project_name: projectName,
1489
1568
  manifest,
1490
- skills: skillPayload,
1491
- diagrams: diagramPayload,
1492
- reports: reportsPayload,
1569
+ documents: documentsPayload,
1493
1570
  email,
1494
1571
  },
1495
1572
  authToken
@@ -1504,12 +1581,9 @@ async function cmdUploadLegacyScan() {
1504
1581
 
1505
1582
  console.log(c("green", "✓ Upload complete!\n"));
1506
1583
  console.log(` Project ID: ${c("bold", result.project_id)}`);
1507
- console.log(` Skills created: ${c("bold", (result.skills_created || []).length.toString())}`);
1508
- if (result.storage_urls?.diagrams?.length) {
1509
- console.log(` Diagrams stored: ${c("dim", result.storage_urls.diagrams.length.toString())}`);
1510
- }
1511
- if (result.storage_urls?.reports?.length) {
1512
- console.log(` Reports stored: ${c("dim", result.storage_urls.reports.length.toString())}`);
1584
+ console.log(` Documents created: ${c("bold", (result.documents_created || 0).toString())}`);
1585
+ if (result.skills_count > 0) {
1586
+ console.log(` Skills: ${c("dim", result.skills_count.toString())}`);
1513
1587
  }
1514
1588
  if (result.console_url) {
1515
1589
  console.log(`\n View in console: ${c("bold", result.console_url)}`);
@@ -1517,6 +1591,115 @@ async function cmdUploadLegacyScan() {
1517
1591
  console.log("");
1518
1592
  }
1519
1593
 
1594
+ // ── Legacy Projects Command ──
1595
+
1596
+ const MANAGE_LEGACY_PROJECTS_URL =
1597
+ process.env.AI_SKILLS_MANAGE_LEGACY_URL ||
1598
+ "https://znshdhjquohrzvbnloki.supabase.co/functions/v1/manage-legacy-projects";
1599
+
1600
+ async function cmdLegacyProjects() {
1601
+ const subcommand = process.argv[3] || "list";
1602
+ const args = process.argv.slice(4);
1603
+
1604
+ // Resolve email
1605
+ const config = loadConfig();
1606
+ let email = config?.email;
1607
+ if (!email) {
1608
+ console.log(c("yellow", "No saved config. Run 'npx ai-skills setup' first."));
1609
+ process.exit(1);
1610
+ }
1611
+
1612
+ if (subcommand === "list") {
1613
+ console.log(c("blue", "\n━━━ Legacy Projects ━━━\n"));
1614
+ let result;
1615
+ try {
1616
+ result = await fetchJSONWithAuth(MANAGE_LEGACY_PROJECTS_URL, { action: "list", email }, null);
1617
+ } catch (err) {
1618
+ console.log(c("red", `✗ ${err.message}`));
1619
+ process.exit(1);
1620
+ }
1621
+ const projects = result.projects || [];
1622
+ if (projects.length === 0) {
1623
+ console.log(c("dim", "No legacy projects found.\n"));
1624
+ return;
1625
+ }
1626
+ for (const p of projects) {
1627
+ const statusColor = p.status === "fully_approved" ? "green" : p.status === "partially_approved" ? "yellow" : "dim";
1628
+ const scanDate = p.last_scanned_at ? new Date(p.last_scanned_at).toLocaleDateString() : "?";
1629
+ console.log(` ${c("bold", p.name)}`);
1630
+ console.log(` Status: ${c(statusColor, p.status)} | ${p.module_count} modules | ${p.completeness_score}% | Scanned: ${scanDate}`);
1631
+ console.log(` ${c("dim", p.console_url)}`);
1632
+ console.log("");
1633
+ }
1634
+ console.log(c("dim", ` ${projects.length} project(s)\n`));
1635
+
1636
+ } else if (subcommand === "status") {
1637
+ const projectName = args[0];
1638
+ if (!projectName) {
1639
+ console.log(c("red", "Usage: npx ai-skills legacy-projects status <project-name>"));
1640
+ process.exit(1);
1641
+ }
1642
+ console.log(c("blue", `\n━━━ Legacy Project: ${projectName} ━━━\n`));
1643
+ let result;
1644
+ try {
1645
+ result = await fetchJSONWithAuth(MANAGE_LEGACY_PROJECTS_URL, { action: "status", email, project_name: projectName }, null);
1646
+ } catch (err) {
1647
+ console.log(c("red", `✗ ${err.message}`));
1648
+ process.exit(1);
1649
+ }
1650
+ const p = result.project;
1651
+ const docs = result.documents || {};
1652
+ const statusColor = p.status === "fully_approved" ? "green" : p.status === "partially_approved" ? "yellow" : "dim";
1653
+ console.log(` Project: ${c("bold", p.name)}`);
1654
+ console.log(` Status: ${c(statusColor, p.status)}`);
1655
+ console.log(` Completeness: ${p.completeness_score}%`);
1656
+ console.log(` Modules: ${p.module_count} | Endpoints: ${p.total_endpoints} | Rules: ${p.total_business_rules}`);
1657
+ console.log(` Scanned: ${p.last_scanned_at ? new Date(p.last_scanned_at).toLocaleDateString() : "?"}`);
1658
+ console.log("");
1659
+ if (Object.keys(docs).length > 0) {
1660
+ console.log(c("bold", " Documents:"));
1661
+ for (const [cat, counts] of Object.entries(docs)) {
1662
+ console.log(` ${cat.padEnd(10)} ${counts.total} total, ${counts.approved} approved, ${counts.pending} pending`);
1663
+ }
1664
+ }
1665
+ console.log(`\n Console: ${c("dim", p.console_url)}\n`);
1666
+
1667
+ } else if (subcommand === "add") {
1668
+ // Delegate to upload-legacy-scan — argv flags (--path, --dry-run, --token) are preserved
1669
+ await cmdUploadLegacyScan();
1670
+ return;
1671
+
1672
+ } else if (subcommand === "remove") {
1673
+ const projectName = args[0];
1674
+ if (!projectName) {
1675
+ console.log(c("red", "Usage: npx ai-skills legacy-projects remove <project-name>"));
1676
+ process.exit(1);
1677
+ }
1678
+ const confirm = await ask(`${c("red", `Delete "${projectName}" and all its documents? This cannot be undone. Type the project name to confirm: `)} `);
1679
+ if (confirm.trim() !== projectName) {
1680
+ console.log(c("yellow", "Cancelled.\n"));
1681
+ return;
1682
+ }
1683
+ let result;
1684
+ try {
1685
+ result = await fetchJSONWithAuth(MANAGE_LEGACY_PROJECTS_URL, { action: "remove", email, project_name: projectName }, null);
1686
+ } catch (err) {
1687
+ console.log(c("red", `✗ ${err.message}`));
1688
+ process.exit(1);
1689
+ }
1690
+ if (result.removed) {
1691
+ console.log(c("green", `✓ "${result.name}" deleted.\n`));
1692
+ } else {
1693
+ console.log(c("red", "Failed to delete project."));
1694
+ }
1695
+
1696
+ } else {
1697
+ console.log(c("red", `Unknown subcommand: ${subcommand}`));
1698
+ console.log(c("dim", "Usage: npx ai-skills legacy-projects add --path <dir> | list | status <name> | remove <name>\n"));
1699
+ process.exit(1);
1700
+ }
1701
+ }
1702
+
1520
1703
  // ── Main ──
1521
1704
 
1522
1705
  const command = process.argv[2] || "setup";
@@ -1529,6 +1712,7 @@ switch (command) {
1529
1712
  case "doctor": cmdDoctor(); break;
1530
1713
  case "analyze": cmdAnalyze(); break;
1531
1714
  case "upload-legacy-scan": cmdUploadLegacyScan(); break;
1715
+ case "legacy-projects": cmdLegacyProjects(); break;
1532
1716
  case "help": case "--help": case "-h":
1533
1717
  console.log(`
1534
1718
  ${c("blue", "AI Skills Framework")} — @valentia-ai-skills/framework
@@ -1540,6 +1724,10 @@ Usage:
1540
1724
  npx ai-skills list List locally bundled skills
1541
1725
  npx ai-skills analyze Analyze last commit against active skills
1542
1726
  npx ai-skills upload-legacy-scan Upload a legacy codebase intelligence package
1727
+ npx ai-skills legacy-projects add --path <dir> Upload a scan package and add / refresh the project
1728
+ npx ai-skills legacy-projects list List all legacy projects
1729
+ npx ai-skills legacy-projects status <name> Show project status and document counts
1730
+ npx ai-skills legacy-projects remove <name> Delete a project and all its documents
1543
1731
  npx ai-skills doctor Health check (config + API + tools)
1544
1732
 
1545
1733
  Flags:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valentia-ai-skills/framework",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
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",
@@ -3,7 +3,7 @@ name: aisupportapp/project-architecture
3
3
  description: Auto-generated project-architecture for aisupportapp. Created by project-scanner.
4
4
  version: 1.0.0
5
5
  scope: project
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: aisupportapp/project-conventions
3
3
  description: Auto-generated project-conventions for aisupportapp. Created by project-scanner.
4
4
  version: 1.0.0
5
5
  scope: project
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: aisupportapp/project-workflows
3
3
  description: Auto-generated project-workflows for aisupportapp. Created by project-scanner.
4
4
  version: 1.0.0
5
5
  scope: project
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: aisupportapp/test-installation
3
3
  description: No description
4
4
  version: 1.0.0
5
5
  scope: project
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  # Skill Name
@@ -3,7 +3,7 @@ name: api-design
3
3
  description: No description
4
4
  version: 1.0.0
5
5
  scope: global
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: appointment-oas-app
3
3
  description: No description
4
4
  version: 1.0.1
5
5
  scope: global
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: code-standards
3
3
  description: No description
4
4
  version: 1.0.0
5
5
  scope: global
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -3,7 +3,7 @@ name: codebase-legacy-intelligence
3
3
  description: A complete project Ecosystem Builder
4
4
  version: 1.0.0
5
5
  scope: global
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  ---
@@ -11,7 +11,7 @@ description: Reverse-engineer any codebase into AI-ready skill files. Use this s
11
11
  auto-trigger.
12
12
  version: 1.0.0
13
13
  scope: global
14
- last_reviewed: 2026-03-28
14
+ last_reviewed: 2026-03-29
15
15
  ---
16
16
 
17
17
  # Project Scanner
@@ -3,7 +3,7 @@ name: viteapp/core-workflows
3
3
  description: No description
4
4
  version: 1.0.0
5
5
  scope: project
6
- last_reviewed: 2026-03-28
6
+ last_reviewed: 2026-03-29
7
7
  ---
8
8
 
9
9
  # Skill Name