@rankcli/cli 0.0.27 → 0.0.28

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.
@@ -10,6 +10,7 @@ import * as vm from "vm";
10
10
  import * as path from "path";
11
11
  import * as fs from "fs";
12
12
  import * as os from "os";
13
+ var SEA_MODULE_SPECIFIER = "node:sea";
13
14
  var PREMIUM_CHECK_NAMES = [
14
15
  "analyzeFeaturedSnippet",
15
16
  "analyzeInternalLinkGraph",
@@ -37,7 +38,7 @@ var wasmModule = null;
37
38
  var auditContext = null;
38
39
  async function loadWasm() {
39
40
  if (wasmModule) return wasmModule;
40
- const sea = __require("sea");
41
+ const sea = __require(SEA_MODULE_SPECIFIER);
41
42
  if (sea.isSea()) {
42
43
  const gluePath = extractSeaWasmAssets();
43
44
  const dynamicRequire = __require("module").createRequire(gluePath);
@@ -61,7 +62,7 @@ Searched: ${possiblePaths.join(", ")}`
61
62
  );
62
63
  }
63
64
  function extractSeaWasmAssets() {
64
- const sea = __require("sea");
65
+ const sea = __require(SEA_MODULE_SPECIFIER);
65
66
  const dir = path.join(os.tmpdir(), "rankcli-wasm-sea");
66
67
  fs.mkdirSync(dir, { recursive: true });
67
68
  const glueAsset = sea.getRawAsset("rankcli_audit_engine.js");
package/dist/index.js CHANGED
@@ -1221,6 +1221,7 @@ var vm = __toESM(require("vm"));
1221
1221
  var path2 = __toESM(require("path"));
1222
1222
  var fs2 = __toESM(require("fs"));
1223
1223
  var os = __toESM(require("os"));
1224
+ var SEA_MODULE_SPECIFIER = "node:sea";
1224
1225
  var PREMIUM_CHECK_NAMES = [
1225
1226
  "analyzeFeaturedSnippet",
1226
1227
  "analyzeInternalLinkGraph",
@@ -1248,7 +1249,7 @@ var wasmModule = null;
1248
1249
  var auditContext = null;
1249
1250
  async function loadWasm() {
1250
1251
  if (wasmModule) return wasmModule;
1251
- const sea = require("sea");
1252
+ const sea = require(SEA_MODULE_SPECIFIER);
1252
1253
  if (sea.isSea()) {
1253
1254
  const gluePath = extractSeaWasmAssets();
1254
1255
  const dynamicRequire = require("module").createRequire(gluePath);
@@ -1272,7 +1273,7 @@ Searched: ${possiblePaths.join(", ")}`
1272
1273
  );
1273
1274
  }
1274
1275
  function extractSeaWasmAssets() {
1275
- const sea = require("sea");
1276
+ const sea = require(SEA_MODULE_SPECIFIER);
1276
1277
  const dir = path2.join(os.tmpdir(), "rankcli-wasm-sea");
1277
1278
  fs2.mkdirSync(dir, { recursive: true });
1278
1279
  const glueAsset = sea.getRawAsset("rankcli_audit_engine.js");
@@ -1437,7 +1438,7 @@ Return JSON with:
1437
1438
  headers["x-api-key"] = apiKey;
1438
1439
  headers["anthropic-version"] = "2023-06-01";
1439
1440
  body = JSON.stringify({
1440
- model: "claude-3-haiku-20240307",
1441
+ model: "claude-haiku-4-5",
1441
1442
  max_tokens: 1500,
1442
1443
  messages: [{ role: "user", content: prompt }]
1443
1444
  });
@@ -1492,101 +1493,56 @@ function mergeIssues(issueArrays) {
1492
1493
  return Array.from(issueMap.values());
1493
1494
  }
1494
1495
  async function syncToCloud(url, report, mergedIssues, pagesAudited, aiAnalysis, durationMs, checksRun) {
1495
- const supabase = await getAuthenticatedClient();
1496
- if (!supabase) return null;
1497
- const { userId, sitesLimit } = getUserInfo();
1498
- if (!userId) return null;
1496
+ let authHeader = null;
1497
+ if (isApiKeyAuth()) {
1498
+ const apiKey = getApiKey();
1499
+ if (apiKey) authHeader = { "X-API-Key": apiKey };
1500
+ } else {
1501
+ const session = await getSession();
1502
+ if (session) authHeader = { Authorization: `Bearer ${session.access_token}` };
1503
+ }
1504
+ if (!authHeader) return null;
1505
+ const score = report.healthScore?.overall || 0;
1506
+ const healthScores = {
1507
+ overall: score,
1508
+ crawlability: report.healthScore?.crawlability || 0,
1509
+ onPage: report.healthScore?.onPage || 0,
1510
+ content: report.healthScore?.content || 0,
1511
+ performance: report.healthScore?.performance || 0,
1512
+ security: report.healthScore?.security || 0,
1513
+ localSeo: report.healthScore?.localSeo || 0,
1514
+ aiReadiness: report.healthScore?.aiReadiness || 0
1515
+ };
1499
1516
  try {
1500
- const parsedUrl = new URL(url);
1501
- const domain = parsedUrl.port ? `${parsedUrl.hostname}:${parsedUrl.port}` : parsedUrl.hostname;
1502
- const { data: existingProject } = await supabase.from("projects").select("id").eq("user_id", userId).eq("domain", domain).eq("is_active", true).single();
1503
- let projectId;
1504
- if (existingProject) {
1505
- projectId = existingProject.id;
1506
- } else {
1507
- const { count } = await supabase.from("projects").select("id", { count: "exact", head: true }).eq("user_id", userId).eq("is_active", true);
1508
- const limit = sitesLimit ?? 1;
1509
- if (count !== null && count >= limit) {
1510
- console.log(import_chalk4.default.yellow(`
1511
- \u26A0\uFE0F Project limit reached (${count}/${limit})`));
1512
- console.log(import_chalk4.default.dim(` Upgrade at: ${WEB_APP_URL}/account`));
1513
- return null;
1514
- }
1515
- const { data: newProject, error: projectError } = await supabase.from("projects").insert({
1516
- user_id: userId,
1517
- name: domain,
1517
+ const res = await fetch(`${getApiUrl()}/functions/v1/sync-audit`, {
1518
+ method: "POST",
1519
+ headers: { "Content-Type": "application/json", ...authHeader },
1520
+ body: JSON.stringify({
1518
1521
  url,
1519
- domain
1520
- }).select("id").single();
1521
- if (projectError || !newProject) {
1522
- console.error(import_chalk4.default.dim("Failed to create project"));
1523
- return null;
1524
- }
1525
- projectId = newProject.id;
1526
- }
1527
- const score = report.healthScore?.overall || 0;
1528
- const healthScores = {
1529
- overall: score,
1530
- crawlability: report.healthScore?.crawlability || 0,
1531
- onPage: report.healthScore?.onPage || 0,
1532
- content: report.healthScore?.content || 0,
1533
- performance: report.healthScore?.performance || 0,
1534
- security: report.healthScore?.security || 0,
1535
- localSeo: report.healthScore?.localSeo || 0,
1536
- aiReadiness: report.healthScore?.aiReadiness || 0
1537
- };
1538
- const now = (/* @__PURE__ */ new Date()).toISOString();
1539
- const { data: audit2, error: auditError } = await supabase.from("audits").insert({
1540
- project_id: projectId,
1541
- triggered_by: "cli",
1542
- triggered_by_user: userId,
1543
- status: "completed",
1544
- score,
1545
- pages_crawled: pagesAudited,
1546
- issues_found: mergedIssues.length,
1547
- checks_run: checksRun,
1548
- health_scores: healthScores,
1549
- started_at: new Date(Date.now() - durationMs).toISOString(),
1550
- completed_at: now,
1551
- duration_ms: durationMs,
1552
- summary: {
1553
- errors: mergedIssues.filter((i) => i.severity === "error").length,
1554
- warnings: mergedIssues.filter((i) => i.severity === "warning").length,
1555
- notices: mergedIssues.filter((i) => i.severity === "notice").length,
1522
+ issues: mergedIssues,
1556
1523
  pagesAudited,
1557
1524
  checksRun,
1558
- source: "cli"
1559
- },
1560
- ai_analysis: aiAnalysis
1561
- }).select("id").single();
1562
- if (auditError || !audit2) {
1563
- console.error(import_chalk4.default.dim("Failed to save audit"));
1525
+ durationMs,
1526
+ healthScores,
1527
+ aiAnalysis
1528
+ })
1529
+ });
1530
+ const data = await res.json();
1531
+ if (!res.ok) {
1532
+ if (data.error === "project_limit_reached") {
1533
+ console.log(import_chalk4.default.yellow(`
1534
+ \u26A0\uFE0F Project limit reached (${data.count}/${data.limit})`));
1535
+ console.log(import_chalk4.default.dim(` Upgrade at: ${WEB_APP_URL}/account`));
1536
+ } else {
1537
+ console.error(import_chalk4.default.dim(data.error || "Cloud sync failed"));
1538
+ }
1564
1539
  return null;
1565
1540
  }
1566
- if (mergedIssues.length > 0) {
1567
- const issueRecords = mergedIssues.map((issue) => ({
1568
- audit_id: audit2.id,
1569
- project_id: projectId,
1570
- code: issue.code,
1571
- severity: issue.severity,
1572
- category: issue.category,
1573
- title: issue.title,
1574
- description: issue.description || "",
1575
- impact: issue.impact || "",
1576
- how_to_fix: issue.howToFix || "",
1577
- affected_urls: issue.affectedUrls || [],
1578
- details: issue.details || {},
1579
- status: "open"
1580
- }));
1581
- await supabase.from("audit_issues").insert(issueRecords);
1582
- }
1583
- await supabase.from("projects").update({
1584
- last_audit_at: now,
1585
- last_audit_score: score,
1586
- last_scheduled_audit_at: now,
1587
- scheduled_audit_source: "cli"
1588
- }).eq("id", projectId);
1589
- return { projectId, auditId: audit2.id };
1541
+ if (!data.projectId || !data.auditId) {
1542
+ console.error(import_chalk4.default.dim("Cloud sync returned an unexpected response"));
1543
+ return null;
1544
+ }
1545
+ return { projectId: data.projectId, auditId: data.auditId };
1590
1546
  } catch (error) {
1591
1547
  console.error(import_chalk4.default.dim("Cloud sync failed"));
1592
1548
  return null;
@@ -3602,7 +3558,7 @@ async function testWebhook(channel, webhookUrl) {
3602
3558
  }
3603
3559
 
3604
3560
  // src/version.ts
3605
- var VERSION = "0.0.26";
3561
+ var VERSION = "0.0.28";
3606
3562
 
3607
3563
  // src/index.ts
3608
3564
  var program = new import_commander.Command();
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getPremiumChecks,
4
4
  initEngine
5
- } from "./chunk-NF755NKY.mjs";
5
+ } from "./chunk-N4BQT53D.mjs";
6
6
 
7
7
  // src/index.ts
8
8
  import { Command } from "commander";
@@ -1259,7 +1259,7 @@ Return JSON with:
1259
1259
  headers["x-api-key"] = apiKey;
1260
1260
  headers["anthropic-version"] = "2023-06-01";
1261
1261
  body = JSON.stringify({
1262
- model: "claude-3-haiku-20240307",
1262
+ model: "claude-haiku-4-5",
1263
1263
  max_tokens: 1500,
1264
1264
  messages: [{ role: "user", content: prompt }]
1265
1265
  });
@@ -1314,101 +1314,56 @@ function mergeIssues(issueArrays) {
1314
1314
  return Array.from(issueMap.values());
1315
1315
  }
1316
1316
  async function syncToCloud(url, report, mergedIssues, pagesAudited, aiAnalysis, durationMs, checksRun) {
1317
- const supabase = await getAuthenticatedClient();
1318
- if (!supabase) return null;
1319
- const { userId, sitesLimit } = getUserInfo();
1320
- if (!userId) return null;
1317
+ let authHeader = null;
1318
+ if (isApiKeyAuth()) {
1319
+ const apiKey = getApiKey();
1320
+ if (apiKey) authHeader = { "X-API-Key": apiKey };
1321
+ } else {
1322
+ const session = await getSession();
1323
+ if (session) authHeader = { Authorization: `Bearer ${session.access_token}` };
1324
+ }
1325
+ if (!authHeader) return null;
1326
+ const score = report.healthScore?.overall || 0;
1327
+ const healthScores = {
1328
+ overall: score,
1329
+ crawlability: report.healthScore?.crawlability || 0,
1330
+ onPage: report.healthScore?.onPage || 0,
1331
+ content: report.healthScore?.content || 0,
1332
+ performance: report.healthScore?.performance || 0,
1333
+ security: report.healthScore?.security || 0,
1334
+ localSeo: report.healthScore?.localSeo || 0,
1335
+ aiReadiness: report.healthScore?.aiReadiness || 0
1336
+ };
1321
1337
  try {
1322
- const parsedUrl = new URL(url);
1323
- const domain = parsedUrl.port ? `${parsedUrl.hostname}:${parsedUrl.port}` : parsedUrl.hostname;
1324
- const { data: existingProject } = await supabase.from("projects").select("id").eq("user_id", userId).eq("domain", domain).eq("is_active", true).single();
1325
- let projectId;
1326
- if (existingProject) {
1327
- projectId = existingProject.id;
1328
- } else {
1329
- const { count } = await supabase.from("projects").select("id", { count: "exact", head: true }).eq("user_id", userId).eq("is_active", true);
1330
- const limit = sitesLimit ?? 1;
1331
- if (count !== null && count >= limit) {
1332
- console.log(chalk4.yellow(`
1333
- \u26A0\uFE0F Project limit reached (${count}/${limit})`));
1334
- console.log(chalk4.dim(` Upgrade at: ${WEB_APP_URL}/account`));
1335
- return null;
1336
- }
1337
- const { data: newProject, error: projectError } = await supabase.from("projects").insert({
1338
- user_id: userId,
1339
- name: domain,
1338
+ const res = await fetch(`${getApiUrl()}/functions/v1/sync-audit`, {
1339
+ method: "POST",
1340
+ headers: { "Content-Type": "application/json", ...authHeader },
1341
+ body: JSON.stringify({
1340
1342
  url,
1341
- domain
1342
- }).select("id").single();
1343
- if (projectError || !newProject) {
1344
- console.error(chalk4.dim("Failed to create project"));
1345
- return null;
1346
- }
1347
- projectId = newProject.id;
1348
- }
1349
- const score = report.healthScore?.overall || 0;
1350
- const healthScores = {
1351
- overall: score,
1352
- crawlability: report.healthScore?.crawlability || 0,
1353
- onPage: report.healthScore?.onPage || 0,
1354
- content: report.healthScore?.content || 0,
1355
- performance: report.healthScore?.performance || 0,
1356
- security: report.healthScore?.security || 0,
1357
- localSeo: report.healthScore?.localSeo || 0,
1358
- aiReadiness: report.healthScore?.aiReadiness || 0
1359
- };
1360
- const now = (/* @__PURE__ */ new Date()).toISOString();
1361
- const { data: audit2, error: auditError } = await supabase.from("audits").insert({
1362
- project_id: projectId,
1363
- triggered_by: "cli",
1364
- triggered_by_user: userId,
1365
- status: "completed",
1366
- score,
1367
- pages_crawled: pagesAudited,
1368
- issues_found: mergedIssues.length,
1369
- checks_run: checksRun,
1370
- health_scores: healthScores,
1371
- started_at: new Date(Date.now() - durationMs).toISOString(),
1372
- completed_at: now,
1373
- duration_ms: durationMs,
1374
- summary: {
1375
- errors: mergedIssues.filter((i) => i.severity === "error").length,
1376
- warnings: mergedIssues.filter((i) => i.severity === "warning").length,
1377
- notices: mergedIssues.filter((i) => i.severity === "notice").length,
1343
+ issues: mergedIssues,
1378
1344
  pagesAudited,
1379
1345
  checksRun,
1380
- source: "cli"
1381
- },
1382
- ai_analysis: aiAnalysis
1383
- }).select("id").single();
1384
- if (auditError || !audit2) {
1385
- console.error(chalk4.dim("Failed to save audit"));
1346
+ durationMs,
1347
+ healthScores,
1348
+ aiAnalysis
1349
+ })
1350
+ });
1351
+ const data = await res.json();
1352
+ if (!res.ok) {
1353
+ if (data.error === "project_limit_reached") {
1354
+ console.log(chalk4.yellow(`
1355
+ \u26A0\uFE0F Project limit reached (${data.count}/${data.limit})`));
1356
+ console.log(chalk4.dim(` Upgrade at: ${WEB_APP_URL}/account`));
1357
+ } else {
1358
+ console.error(chalk4.dim(data.error || "Cloud sync failed"));
1359
+ }
1386
1360
  return null;
1387
1361
  }
1388
- if (mergedIssues.length > 0) {
1389
- const issueRecords = mergedIssues.map((issue) => ({
1390
- audit_id: audit2.id,
1391
- project_id: projectId,
1392
- code: issue.code,
1393
- severity: issue.severity,
1394
- category: issue.category,
1395
- title: issue.title,
1396
- description: issue.description || "",
1397
- impact: issue.impact || "",
1398
- how_to_fix: issue.howToFix || "",
1399
- affected_urls: issue.affectedUrls || [],
1400
- details: issue.details || {},
1401
- status: "open"
1402
- }));
1403
- await supabase.from("audit_issues").insert(issueRecords);
1404
- }
1405
- await supabase.from("projects").update({
1406
- last_audit_at: now,
1407
- last_audit_score: score,
1408
- last_scheduled_audit_at: now,
1409
- scheduled_audit_source: "cli"
1410
- }).eq("id", projectId);
1411
- return { projectId, auditId: audit2.id };
1362
+ if (!data.projectId || !data.auditId) {
1363
+ console.error(chalk4.dim("Cloud sync returned an unexpected response"));
1364
+ return null;
1365
+ }
1366
+ return { projectId: data.projectId, auditId: data.auditId };
1412
1367
  } catch (error) {
1413
1368
  console.error(chalk4.dim("Cloud sync failed"));
1414
1369
  return null;
@@ -3459,7 +3414,7 @@ async function testWebhook(channel, webhookUrl) {
3459
3414
  }
3460
3415
 
3461
3416
  // src/version.ts
3462
- var VERSION = "0.0.26";
3417
+ var VERSION = "0.0.28";
3463
3418
 
3464
3419
  // src/index.ts
3465
3420
  var program = new Command();
@@ -40,6 +40,7 @@ var vm = __toESM(require("vm"));
40
40
  var path = __toESM(require("path"));
41
41
  var fs = __toESM(require("fs"));
42
42
  var os = __toESM(require("os"));
43
+ var SEA_MODULE_SPECIFIER = "node:sea";
43
44
  var PREMIUM_CHECK_NAMES = [
44
45
  "analyzeFeaturedSnippet",
45
46
  "analyzeInternalLinkGraph",
@@ -67,7 +68,7 @@ var wasmModule = null;
67
68
  var auditContext = null;
68
69
  async function loadWasm() {
69
70
  if (wasmModule) return wasmModule;
70
- const sea = require("sea");
71
+ const sea = require(SEA_MODULE_SPECIFIER);
71
72
  if (sea.isSea()) {
72
73
  const gluePath = extractSeaWasmAssets();
73
74
  const dynamicRequire = require("module").createRequire(gluePath);
@@ -91,7 +92,7 @@ Searched: ${possiblePaths.join(", ")}`
91
92
  );
92
93
  }
93
94
  function extractSeaWasmAssets() {
94
- const sea = require("sea");
95
+ const sea = require(SEA_MODULE_SPECIFIER);
95
96
  const dir = path.join(os.tmpdir(), "rankcli-wasm-sea");
96
97
  fs.mkdirSync(dir, { recursive: true });
97
98
  const glueAsset = sea.getRawAsset("rankcli_audit_engine.js");
@@ -3,7 +3,7 @@ import {
3
3
  getVersion,
4
4
  initEngine,
5
5
  isReady
6
- } from "./chunk-NF755NKY.mjs";
6
+ } from "./chunk-N4BQT53D.mjs";
7
7
  export {
8
8
  getPremiumChecks,
9
9
  getVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rankcli/cli",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "description": "RankCLI - Ship code, get ranked. SEO meets CI/CD.",
5
5
  "homepage": "https://rankcli.dev",
6
6
  "main": "dist/index.js",