@oculum/cli 1.0.13 → 1.0.15
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/dist/index.js +127 -106
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -12404,6 +12404,29 @@ var require_entropy = __commonJS({
|
|
|
12404
12404
|
];
|
|
12405
12405
|
return debugPatterns.some((pattern) => pattern.test(lineContent));
|
|
12406
12406
|
}
|
|
12407
|
+
function isCommandLineSnippet(value, lineContent) {
|
|
12408
|
+
const commandContextPatterns = [
|
|
12409
|
+
/\b(quickFix|command|example|usage|cli|help|hint)\b/i,
|
|
12410
|
+
/\b(run|exec|execute|install)\b\s*:/i
|
|
12411
|
+
];
|
|
12412
|
+
const envAssignmentPatterns = [
|
|
12413
|
+
/^\s*(export\s+)?[A-Z_][A-Z0-9_]*=/,
|
|
12414
|
+
// export VAR=... or VAR=...
|
|
12415
|
+
/\bNODE_OPTIONS=/i
|
|
12416
|
+
];
|
|
12417
|
+
const commandPatterns = [
|
|
12418
|
+
/^\s*\$\s+/,
|
|
12419
|
+
// shell prompt
|
|
12420
|
+
/\s--[a-z0-9][a-z0-9-]*/i,
|
|
12421
|
+
// CLI flags
|
|
12422
|
+
/\b(npm|pnpm|yarn|npx|node|bun|deno|git|curl|wget|oculum|python|pip|brew)\b/i
|
|
12423
|
+
];
|
|
12424
|
+
const hasCommandContext = commandContextPatterns.some((p2) => p2.test(lineContent));
|
|
12425
|
+
const looksLikeEnvAssignment = envAssignmentPatterns.some((p2) => p2.test(value));
|
|
12426
|
+
const looksLikeCommand = commandPatterns.some((p2) => p2.test(value));
|
|
12427
|
+
const hasMultipleTokens = value.trim().split(/\s+/).length >= 2;
|
|
12428
|
+
return (hasCommandContext || looksLikeEnvAssignment || looksLikeCommand) && hasMultipleTokens;
|
|
12429
|
+
}
|
|
12407
12430
|
function isInlineStyle(lineContent) {
|
|
12408
12431
|
const jsxStylePatterns = [
|
|
12409
12432
|
/style\s*=\s*\{\{/,
|
|
@@ -12556,6 +12579,8 @@ var require_entropy = __commonJS({
|
|
|
12556
12579
|
continue;
|
|
12557
12580
|
if (isDebugLogContent(lineContent))
|
|
12558
12581
|
continue;
|
|
12582
|
+
if (isCommandLineSnippet(value, lineContent))
|
|
12583
|
+
continue;
|
|
12559
12584
|
if (isRegexPattern(value))
|
|
12560
12585
|
continue;
|
|
12561
12586
|
if (isTemplateWithCode(value, lineContent))
|
|
@@ -14317,7 +14342,11 @@ var require_path_exclusions = __commonJS({
|
|
|
14317
14342
|
"**/demo/**",
|
|
14318
14343
|
"**/sample/**",
|
|
14319
14344
|
"**/samples/**",
|
|
14320
|
-
"**/playground/**"
|
|
14345
|
+
"**/playground/**",
|
|
14346
|
+
"**/oculum.json",
|
|
14347
|
+
// Scanner output files
|
|
14348
|
+
"**/*.scan.json"
|
|
14349
|
+
// Any scan result files
|
|
14321
14350
|
],
|
|
14322
14351
|
fixturePatterns: [
|
|
14323
14352
|
"**/fixtures/**",
|
|
@@ -15892,8 +15921,7 @@ var require_dangerous_functions = __commonJS({
|
|
|
15892
15921
|
const contextEnd = Math.min(lines.length, lineNumber + 5);
|
|
15893
15922
|
const context = lines.slice(contextStart, contextEnd).join("\n");
|
|
15894
15923
|
const cosmeticContextPatterns = [
|
|
15895
|
-
// UI component files
|
|
15896
|
-
/\/(components?|ui|widgets?|animations?|contexts?)\//i,
|
|
15924
|
+
// UI component files - REMOVED, let severity classification handle these
|
|
15897
15925
|
// Style-related variables/functions
|
|
15898
15926
|
/\b(style|styles|css|className|animation|transition)/i,
|
|
15899
15927
|
/\b(width|height|opacity|color|transform|rotate|scale|translate)/i,
|
|
@@ -15906,13 +15934,9 @@ var require_dangerous_functions = __commonJS({
|
|
|
15906
15934
|
/delay.*Math\.random/i,
|
|
15907
15935
|
/duration.*Math\.random/i,
|
|
15908
15936
|
// UI state variations
|
|
15909
|
-
/\b(variant|theme|layout|position).*Math\.random/i
|
|
15910
|
-
// UI identifier
|
|
15911
|
-
|
|
15912
|
-
/\bid\s*=.*Math\.random/i,
|
|
15913
|
-
/\bkey\s*=.*Math\.random/i,
|
|
15914
|
-
// React keys
|
|
15915
|
-
/\btempId|temporaryId|uniqueId\b/i
|
|
15937
|
+
/\b(variant|theme|layout|position).*Math\.random/i
|
|
15938
|
+
// NOTE: Removed UI identifier patterns (key, id, tempId, etc.) - these should be
|
|
15939
|
+
// classified with info/low severity by the severity classification logic, not skipped entirely
|
|
15916
15940
|
];
|
|
15917
15941
|
if (cosmeticContextPatterns.some((p2) => p2.test(context))) {
|
|
15918
15942
|
return true;
|
|
@@ -15936,10 +15960,14 @@ var require_dangerous_functions = __commonJS({
|
|
|
15936
15960
|
}
|
|
15937
15961
|
function extractFunctionContext(content, lineNumber) {
|
|
15938
15962
|
const lines = content.split("\n");
|
|
15939
|
-
const start = Math.max(0, lineNumber -
|
|
15963
|
+
const start = Math.max(0, lineNumber - 20);
|
|
15940
15964
|
for (let i = lineNumber; i >= start; i--) {
|
|
15941
15965
|
const line = lines[i];
|
|
15942
|
-
const
|
|
15966
|
+
const hasMethodCallWithArrowCallback = /\.\w+\(.*\([^)]*\)\s*=>/.test(line);
|
|
15967
|
+
if (hasMethodCallWithArrowCallback) {
|
|
15968
|
+
continue;
|
|
15969
|
+
}
|
|
15970
|
+
const funcDeclMatch = line.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)/i);
|
|
15943
15971
|
if (funcDeclMatch) {
|
|
15944
15972
|
return funcDeclMatch[1].toLowerCase();
|
|
15945
15973
|
}
|
|
@@ -16077,7 +16105,24 @@ var require_dangerous_functions = __commonJS({
|
|
|
16077
16105
|
"dialog",
|
|
16078
16106
|
"popup",
|
|
16079
16107
|
"unique",
|
|
16080
|
-
"react"
|
|
16108
|
+
"react",
|
|
16109
|
+
// Non-security randomness usage (backoff/sampling/experiments)
|
|
16110
|
+
"jitter",
|
|
16111
|
+
"retry",
|
|
16112
|
+
"backoff",
|
|
16113
|
+
"delay",
|
|
16114
|
+
"timeout",
|
|
16115
|
+
"latency",
|
|
16116
|
+
"sample",
|
|
16117
|
+
"sampling",
|
|
16118
|
+
"probability",
|
|
16119
|
+
"chance",
|
|
16120
|
+
"rollout",
|
|
16121
|
+
"experiment",
|
|
16122
|
+
"abtest",
|
|
16123
|
+
"cohort",
|
|
16124
|
+
"bucket",
|
|
16125
|
+
"variant"
|
|
16081
16126
|
];
|
|
16082
16127
|
if (lowRiskPatterns.some((p2) => lower.includes(p2))) {
|
|
16083
16128
|
return "low";
|
|
@@ -16109,7 +16154,9 @@ var require_dangerous_functions = __commonJS({
|
|
|
16109
16154
|
const inUIContext = isCosmeticMathRandom(lineContent, content, lineNumber);
|
|
16110
16155
|
const businessLogicPatterns = [
|
|
16111
16156
|
/\b(business|order|invoice|customer|product|transaction)Id\b/i,
|
|
16112
|
-
/\b(reference|tracking|confirmation)Number\b/i
|
|
16157
|
+
/\b(reference|tracking|confirmation)Number\b/i,
|
|
16158
|
+
/\b(backoff|retry|jitter|delay|timeout|latency)\b/i,
|
|
16159
|
+
/\b(sample|sampling|probability|chance|rollout|experiment|abtest|cohort|bucket|variant)\b/i
|
|
16113
16160
|
];
|
|
16114
16161
|
const inBusinessLogicContext = businessLogicPatterns.some((p2) => p2.test(context)) && !inSecurityContext;
|
|
16115
16162
|
let contextDescription = "unknown context";
|
|
@@ -16120,7 +16167,7 @@ var require_dangerous_functions = __commonJS({
|
|
|
16120
16167
|
} else if (inUIContext) {
|
|
16121
16168
|
contextDescription = "UI/cosmetic usage";
|
|
16122
16169
|
} else if (inBusinessLogicContext) {
|
|
16123
|
-
contextDescription = "
|
|
16170
|
+
contextDescription = "non-security usage";
|
|
16124
16171
|
}
|
|
16125
16172
|
return {
|
|
16126
16173
|
inSecurityContext,
|
|
@@ -16388,24 +16435,24 @@ var require_dangerous_functions = __commonJS({
|
|
|
16388
16435
|
explanation = " (seed/demo data generation)";
|
|
16389
16436
|
description = "Math.random() used for generating fixture/seed data. Not security-critical in development contexts.";
|
|
16390
16437
|
suggestedFix = "Acceptable for seed data. Use crypto.randomUUID() if uniqueness guarantees needed.";
|
|
16391
|
-
} else if (nameRisk === "high" || context.inSecurityContext || functionIntent === "security") {
|
|
16392
|
-
severity2 = "high";
|
|
16393
|
-
confidence2 = "high";
|
|
16394
|
-
explanation = " (security-sensitive context)";
|
|
16395
|
-
description = "Math.random() is NOT cryptographically secure and MUST NOT be used for tokens, keys, passwords, or session IDs. This can lead to predictable values that attackers can exploit.";
|
|
16396
|
-
suggestedFix = "Replace with crypto.randomBytes() or crypto.randomUUID() for security-sensitive operations";
|
|
16397
16438
|
} else if (toStringPattern.intent === "short-ui-id") {
|
|
16398
16439
|
severity2 = "info";
|
|
16399
16440
|
confidence2 = "low";
|
|
16400
16441
|
explanation = " (UI correlation ID)";
|
|
16401
16442
|
description = "Math.random() used for short UI correlation IDs. Not security-critical, but collisions possible in high-volume scenarios.";
|
|
16402
16443
|
suggestedFix = "For UI correlation, crypto.randomUUID() provides better uniqueness guarantees";
|
|
16444
|
+
} else if (nameRisk === "high" || context.inSecurityContext || functionIntent === "security") {
|
|
16445
|
+
severity2 = "high";
|
|
16446
|
+
confidence2 = "high";
|
|
16447
|
+
explanation = " (security-sensitive context)";
|
|
16448
|
+
description = "Math.random() is NOT cryptographically secure and MUST NOT be used for tokens, keys, passwords, or session IDs. This can lead to predictable values that attackers can exploit.";
|
|
16449
|
+
suggestedFix = "Replace with crypto.randomBytes() or crypto.randomUUID() for security-sensitive operations";
|
|
16403
16450
|
} else if (nameRisk === "low" || context.inBusinessLogicContext || toStringPattern.intent === "business-id") {
|
|
16404
16451
|
severity2 = "low";
|
|
16405
16452
|
confidence2 = "low";
|
|
16406
|
-
explanation = " (
|
|
16407
|
-
description = "Math.random() is being used for non-security purposes (business IDs,
|
|
16408
|
-
suggestedFix = "
|
|
16453
|
+
explanation = " (non-security usage)";
|
|
16454
|
+
description = "Math.random() is being used for non-security purposes (business IDs, sampling, jitter/backoff, experiments). While not critical, Math.random() can produce collisions or bias in high-volume scenarios.";
|
|
16455
|
+
suggestedFix = "Use crypto.randomUUID() for uniqueness-sensitive IDs. For sampling/backoff, consider a seeded PRNG if determinism is needed.";
|
|
16409
16456
|
} else {
|
|
16410
16457
|
severity2 = "medium";
|
|
16411
16458
|
confidence2 = "medium";
|
|
@@ -37475,7 +37522,7 @@ Example response format (OPTIMIZED):
|
|
|
37475
37522
|
keep: { type: "boolean" }
|
|
37476
37523
|
},
|
|
37477
37524
|
required: ["index", "keep"],
|
|
37478
|
-
additionalProperties:
|
|
37525
|
+
additionalProperties: false
|
|
37479
37526
|
}
|
|
37480
37527
|
}
|
|
37481
37528
|
},
|
|
@@ -44649,18 +44696,19 @@ async function status() {
|
|
|
44649
44696
|
spinner.succeed(" Authenticated");
|
|
44650
44697
|
console.log("");
|
|
44651
44698
|
const email = result.email || config.email || "unknown";
|
|
44652
|
-
const
|
|
44653
|
-
|
|
44654
|
-
|
|
44699
|
+
const rawTier = String(result.tier || "free");
|
|
44700
|
+
const normalizedTier = rawTier === "enterprise" ? "max" : rawTier;
|
|
44701
|
+
if (normalizedTier !== config.tier || email !== config.email) {
|
|
44702
|
+
setAuthCredentials(config.apiKey, email, normalizedTier);
|
|
44655
44703
|
}
|
|
44656
|
-
const tierBadge =
|
|
44704
|
+
const tierBadge = normalizedTier === "pro" ? source_default.bgBlue.white(" PRO ") : normalizedTier === "max" ? source_default.bgMagenta.white(" MAX ") : normalizedTier === "starter" ? source_default.bgCyan.white(" STARTER ") : source_default.bgGray.white(" FREE ");
|
|
44657
44705
|
console.log(source_default.dim(" Email: ") + source_default.white(email));
|
|
44658
44706
|
console.log(source_default.dim(" Plan: ") + tierBadge);
|
|
44659
44707
|
console.log("");
|
|
44660
44708
|
console.log(source_default.bold(" Available Scan Depths:"));
|
|
44661
44709
|
console.log("");
|
|
44662
44710
|
console.log(source_default.green(" \u2713 ") + source_default.white("cheap") + source_default.dim(" Fast pattern matching (always free)"));
|
|
44663
|
-
if (
|
|
44711
|
+
if (normalizedTier === "pro" || normalizedTier === "max") {
|
|
44664
44712
|
console.log(source_default.green(" \u2713 ") + source_default.white("validated") + source_default.dim(" AI validation (~70% fewer false positives)"));
|
|
44665
44713
|
console.log(source_default.dim(" \u{1F512} ") + source_default.white("deep") + source_default.dim(" Multi-agent analysis (coming soon)"));
|
|
44666
44714
|
} else {
|
|
@@ -46394,6 +46442,48 @@ var esm_default = { watch, FSWatcher };
|
|
|
46394
46442
|
// src/commands/watch.ts
|
|
46395
46443
|
var import_scanner2 = __toESM(require_dist());
|
|
46396
46444
|
var import_formatters2 = __toESM(require_formatters());
|
|
46445
|
+
var WATCH_IGNORE_PATTERNS = [
|
|
46446
|
+
"**/node_modules/**",
|
|
46447
|
+
"**/dist/**",
|
|
46448
|
+
"**/build/**",
|
|
46449
|
+
"**/.git/**",
|
|
46450
|
+
"**/vendor/**",
|
|
46451
|
+
"**/__pycache__/**",
|
|
46452
|
+
"**/venv/**",
|
|
46453
|
+
"**/.venv/**",
|
|
46454
|
+
"**/coverage/**",
|
|
46455
|
+
"**/.next/**",
|
|
46456
|
+
"**/.nuxt/**",
|
|
46457
|
+
"**/.turbo/**",
|
|
46458
|
+
"**/out/**",
|
|
46459
|
+
"**/.cache/**",
|
|
46460
|
+
"**/.vercel/**",
|
|
46461
|
+
"**/.netlify/**",
|
|
46462
|
+
"**/target/**",
|
|
46463
|
+
"**/bin/**",
|
|
46464
|
+
"**/obj/**",
|
|
46465
|
+
"**/.gradle/**",
|
|
46466
|
+
"**/.mvn/**",
|
|
46467
|
+
"**/bower_components/**",
|
|
46468
|
+
"**/jspm_packages/**",
|
|
46469
|
+
"**/.yarn/**",
|
|
46470
|
+
"**/.pnp.*",
|
|
46471
|
+
"**/package-lock.json",
|
|
46472
|
+
"**/yarn.lock",
|
|
46473
|
+
"**/pnpm-lock.yaml",
|
|
46474
|
+
"**/*.min.js",
|
|
46475
|
+
"**/*.min.css",
|
|
46476
|
+
"**/*.bundle.js",
|
|
46477
|
+
"**/validation-test/**",
|
|
46478
|
+
"**/validation-repos/**",
|
|
46479
|
+
"**/validation-results/**",
|
|
46480
|
+
"**/test-files/**",
|
|
46481
|
+
"**/.env",
|
|
46482
|
+
"**/.env.*",
|
|
46483
|
+
"**/.env.local",
|
|
46484
|
+
"**/.env.*.local",
|
|
46485
|
+
"**/**.env"
|
|
46486
|
+
];
|
|
46397
46487
|
function isScannableFile2(filePath) {
|
|
46398
46488
|
const ext2 = (0, import_path5.extname)(filePath).toLowerCase();
|
|
46399
46489
|
const fileName = (0, import_path5.basename)(filePath);
|
|
@@ -46563,17 +46653,9 @@ async function watch2(targetPath, options) {
|
|
|
46563
46653
|
"**/*.cs",
|
|
46564
46654
|
"**/package.json"
|
|
46565
46655
|
];
|
|
46566
|
-
const ignorePatterns2 = [
|
|
46567
|
-
"**/node_modules/**",
|
|
46568
|
-
"**/dist/**",
|
|
46569
|
-
"**/build/**",
|
|
46570
|
-
"**/.git/**",
|
|
46571
|
-
"**/vendor/**",
|
|
46572
|
-
"**/__pycache__/**"
|
|
46573
|
-
];
|
|
46574
46656
|
const allFiles2 = await glob3(patterns2, {
|
|
46575
46657
|
cwd: absolutePath,
|
|
46576
|
-
ignore:
|
|
46658
|
+
ignore: WATCH_IGNORE_PATTERNS,
|
|
46577
46659
|
nodir: true,
|
|
46578
46660
|
absolute: true
|
|
46579
46661
|
});
|
|
@@ -46584,35 +46666,7 @@ async function watch2(targetPath, options) {
|
|
|
46584
46666
|
isScanning = false;
|
|
46585
46667
|
runScanOnChanges();
|
|
46586
46668
|
};
|
|
46587
|
-
const watcherIgnore =
|
|
46588
|
-
"**/node_modules/**",
|
|
46589
|
-
"**/dist/**",
|
|
46590
|
-
"**/build/**",
|
|
46591
|
-
"**/.git/**",
|
|
46592
|
-
"**/vendor/**",
|
|
46593
|
-
"**/__pycache__/**",
|
|
46594
|
-
"**/venv/**",
|
|
46595
|
-
"**/.venv/**",
|
|
46596
|
-
"**/coverage/**",
|
|
46597
|
-
"**/.next/**",
|
|
46598
|
-
"**/.nuxt/**",
|
|
46599
|
-
"**/.turbo/**",
|
|
46600
|
-
"**/out/**",
|
|
46601
|
-
"**/.cache/**",
|
|
46602
|
-
"**/.vercel/**",
|
|
46603
|
-
"**/.netlify/**",
|
|
46604
|
-
"**/target/**",
|
|
46605
|
-
"**/.gradle/**",
|
|
46606
|
-
"**/.mvn/**",
|
|
46607
|
-
"**/bower_components/**",
|
|
46608
|
-
"**/.yarn/**",
|
|
46609
|
-
"**/package-lock.json",
|
|
46610
|
-
"**/yarn.lock",
|
|
46611
|
-
"**/pnpm-lock.yaml",
|
|
46612
|
-
"**/*.min.js",
|
|
46613
|
-
"**/*.min.css",
|
|
46614
|
-
"**/*.bundle.js"
|
|
46615
|
-
];
|
|
46669
|
+
const watcherIgnore = WATCH_IGNORE_PATTERNS;
|
|
46616
46670
|
const watcher = esm_default.watch(absolutePath, {
|
|
46617
46671
|
ignored: watcherIgnore,
|
|
46618
46672
|
persistent: true,
|
|
@@ -46696,42 +46750,9 @@ async function watch2(targetPath, options) {
|
|
|
46696
46750
|
"**/*.cs",
|
|
46697
46751
|
"**/package.json"
|
|
46698
46752
|
];
|
|
46699
|
-
const ignorePatterns = [
|
|
46700
|
-
"**/node_modules/**",
|
|
46701
|
-
"**/dist/**",
|
|
46702
|
-
"**/build/**",
|
|
46703
|
-
"**/.git/**",
|
|
46704
|
-
"**/vendor/**",
|
|
46705
|
-
"**/__pycache__/**",
|
|
46706
|
-
"**/venv/**",
|
|
46707
|
-
"**/.venv/**",
|
|
46708
|
-
"**/coverage/**",
|
|
46709
|
-
"**/.next/**",
|
|
46710
|
-
"**/.nuxt/**",
|
|
46711
|
-
"**/.turbo/**",
|
|
46712
|
-
"**/out/**",
|
|
46713
|
-
"**/.cache/**",
|
|
46714
|
-
"**/.vercel/**",
|
|
46715
|
-
"**/.netlify/**",
|
|
46716
|
-
"**/target/**",
|
|
46717
|
-
"**/bin/**",
|
|
46718
|
-
"**/obj/**",
|
|
46719
|
-
"**/.gradle/**",
|
|
46720
|
-
"**/.mvn/**",
|
|
46721
|
-
"**/bower_components/**",
|
|
46722
|
-
"**/jspm_packages/**",
|
|
46723
|
-
"**/.yarn/**",
|
|
46724
|
-
"**/.pnp.*",
|
|
46725
|
-
"**/package-lock.json",
|
|
46726
|
-
"**/yarn.lock",
|
|
46727
|
-
"**/pnpm-lock.yaml",
|
|
46728
|
-
"**/*.min.js",
|
|
46729
|
-
"**/*.min.css",
|
|
46730
|
-
"**/*.bundle.js"
|
|
46731
|
-
];
|
|
46732
46753
|
const allFiles = await glob2(patterns, {
|
|
46733
46754
|
cwd: absolutePath,
|
|
46734
|
-
ignore:
|
|
46755
|
+
ignore: WATCH_IGNORE_PATTERNS,
|
|
46735
46756
|
nodir: true,
|
|
46736
46757
|
absolute: true
|
|
46737
46758
|
});
|
|
@@ -47453,7 +47474,7 @@ function showLogo() {
|
|
|
47453
47474
|
async function showWelcomeScreen() {
|
|
47454
47475
|
console.clear();
|
|
47455
47476
|
showLogo();
|
|
47456
|
-
console.log(source_default.bold.white(" AI-Native
|
|
47477
|
+
console.log(source_default.bold.white(" AI-Native Security Scanner for Modern Codebases\n"));
|
|
47457
47478
|
console.log(source_default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
47458
47479
|
console.log(source_default.white(" Oculum detects security vulnerabilities in AI-generated"));
|
|
47459
47480
|
console.log(source_default.white(" code and LLM-powered applications, including:\n"));
|
|
@@ -48586,7 +48607,7 @@ async function runUsageFlow() {
|
|
|
48586
48607
|
console.log(source_default.bold(" \u{1F4CA} Oculum Usage"));
|
|
48587
48608
|
console.log(source_default.dim(" " + "\u2500".repeat(38)));
|
|
48588
48609
|
console.log("");
|
|
48589
|
-
const planBadge = plan.name === "pro" ? source_default.bgBlue.white(" PRO ") : plan.name === "
|
|
48610
|
+
const planBadge = plan.name === "pro" ? source_default.bgBlue.white(" PRO ") : plan.name === "max" ? source_default.bgMagenta.white(" MAX ") : plan.name === "starter" ? source_default.bgCyan.white(" STARTER ") : source_default.bgGray.white(" FREE ");
|
|
48590
48611
|
console.log(source_default.dim(" Plan: ") + planBadge + source_default.white(` ${plan.displayName}`));
|
|
48591
48612
|
console.log(source_default.dim(" Month: ") + source_default.white(usageData.month));
|
|
48592
48613
|
console.log("");
|
|
@@ -48878,7 +48899,7 @@ async function usage(options) {
|
|
|
48878
48899
|
console.log(source_default.bold(" \u{1F4CA} Oculum Usage"));
|
|
48879
48900
|
console.log(source_default.dim(" " + "\u2500".repeat(38)));
|
|
48880
48901
|
console.log("");
|
|
48881
|
-
const planBadge = plan.name === "pro" ? source_default.bgBlue.white(" PRO ") : plan.name === "
|
|
48902
|
+
const planBadge = plan.name === "pro" ? source_default.bgBlue.white(" PRO ") : plan.name === "max" ? source_default.bgMagenta.white(" MAX ") : plan.name === "starter" ? source_default.bgCyan.white(" STARTER ") : source_default.bgGray.white(" FREE ");
|
|
48882
48903
|
console.log(source_default.dim(" Plan: ") + planBadge + source_default.white(` ${plan.displayName}`));
|
|
48883
48904
|
console.log(source_default.dim(" Month: ") + source_default.white(usageData.month));
|
|
48884
48905
|
console.log("");
|
|
@@ -49377,7 +49398,7 @@ function shouldRunUI() {
|
|
|
49377
49398
|
return isOcAlias || isUICommand;
|
|
49378
49399
|
}
|
|
49379
49400
|
var program2 = new Command();
|
|
49380
|
-
program2.name("oculum").description("AI-native security scanner for detecting vulnerabilities in LLM-generated code").version("1.0.
|
|
49401
|
+
program2.name("oculum").description("AI-native security scanner for detecting vulnerabilities in LLM-generated code").version("1.0.15").addHelpText("after", `
|
|
49381
49402
|
Quick Start:
|
|
49382
49403
|
$ oculum scan . Scan current directory (free)
|
|
49383
49404
|
$ oculum ui Interactive mode with guided setup
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oculum/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "AI-native security scanner CLI for detecting vulnerabilities in AI-generated code, BYOK patterns, and modern web applications",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"url": "https://github.com/flexipie/oculum/issues"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --banner:js=\"#!/usr/bin/env node\" --define:process.env.OCULUM_API_URL='undefined' --define:VERSION='\"
|
|
22
|
+
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --banner:js=\"#!/usr/bin/env node\" --define:process.env.OCULUM_API_URL='undefined' --define:VERSION='\"'$npm_package_version'\"'",
|
|
23
23
|
"dev": "npm run build -- --watch",
|
|
24
24
|
"test": "echo \"No tests configured yet\"",
|
|
25
25
|
"lint": "eslint src/"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@oculum/scanner": "^1.0.
|
|
29
|
-
"@oculum/shared": "^1.0.
|
|
28
|
+
"@oculum/scanner": "^1.0.5",
|
|
29
|
+
"@oculum/shared": "^1.0.5",
|
|
30
30
|
"commander": "^12.1.0",
|
|
31
31
|
"chalk": "^5.3.0",
|
|
32
32
|
"ora": "^8.1.1",
|