korext 0.9.4 → 0.9.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/README.md +11 -1
- package/bin/korext.js +36 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,16 @@ OWASP Top 10 | PCI-DSS | HIPAA | GDPR | SOC 2 | NIST SP 800-53 | NIST SP 800-171
|
|
|
99
99
|
| `KOREXT_API_TOKEN` | API authentication token (recommended) |
|
|
100
100
|
| `KOREXT_TOKEN` | Deprecated alias (shows warning) |
|
|
101
101
|
|
|
102
|
+
## Changelog
|
|
103
|
+
|
|
104
|
+
### v0.9.5
|
|
105
|
+
|
|
106
|
+
Fixed
|
|
107
|
+
- Watch mode now detects file changes correctly and scans on startup
|
|
108
|
+
- Enforcing a nonexistent directory now prints an error and exits with code 2 instead of silently passing
|
|
109
|
+
- Offline enforcement prints how many rules are available versus how many require server analysis
|
|
110
|
+
- Policy commands now default to the production API instead of localhost
|
|
111
|
+
|
|
102
112
|
## Links
|
|
103
113
|
|
|
104
114
|
- Website: [korext.com](https://www.korext.com)
|
|
@@ -112,4 +122,4 @@ OWASP Top 10 | PCI-DSS | HIPAA | GDPR | SOC 2 | NIST SP 800-53 | NIST SP 800-171
|
|
|
112
122
|
|
|
113
123
|
**Publisher**: Korext
|
|
114
124
|
**License**: Proprietary
|
|
115
|
-
**Version**: 0.
|
|
125
|
+
**Version**: 0.9.5
|
package/bin/korext.js
CHANGED
|
@@ -267,6 +267,14 @@ program
|
|
|
267
267
|
let forceOffline = options.offline;
|
|
268
268
|
let localDefinitions = null;
|
|
269
269
|
|
|
270
|
+
// Pre-flight: verify directory exists
|
|
271
|
+
const resolvedInputDir = path.resolve(dir);
|
|
272
|
+
if (!fs.existsSync(resolvedInputDir)) {
|
|
273
|
+
if (isText) console.error(chalk.red(`\n✖ Directory does not exist: ${resolvedInputDir}`));
|
|
274
|
+
else console.error(JSON.stringify({ error: `Directory does not exist: ${resolvedInputDir}` }));
|
|
275
|
+
process.exit(2);
|
|
276
|
+
}
|
|
277
|
+
|
|
270
278
|
if (isText) {
|
|
271
279
|
console.log(`\n${chalk.bold.hex('#F27D26')('▲ KOREXT CLI ENFORCEMENT ENGINE')} v${version}`);
|
|
272
280
|
console.log(chalk.dim('======================================='));
|
|
@@ -295,6 +303,11 @@ program
|
|
|
295
303
|
if (isText) {
|
|
296
304
|
console.log(chalk.yellow('\n⚡ Offline mode: using local rule engine (regex-based analysis)'));
|
|
297
305
|
console.log(chalk.dim(` Cached rules: v${localDefinitions.version} · ${localDefinitions.ruleCount} rules · ${localDefinitions.packCount} packs`));
|
|
306
|
+
// Show rule coverage breakdown
|
|
307
|
+
const packRules = localDefinitions.packs?.[pack]?.rules || [];
|
|
308
|
+
const availableCount = packRules.filter(r => localDefinitions.rules?.[r]).length;
|
|
309
|
+
const serverOnlyCount = packRules.length - availableCount;
|
|
310
|
+
console.log(chalk.dim(` Offline mode: ${availableCount} of ${packRules.length} rules available. ${serverOnlyCount} rules require server analysis.`));
|
|
298
311
|
console.log(chalk.dim(' Note: AI-powered deep analysis is unavailable in offline mode.\n'));
|
|
299
312
|
}
|
|
300
313
|
}
|
|
@@ -1309,6 +1322,29 @@ program
|
|
|
1309
1322
|
if (fs.existsSync(fullPath)) analyzeWatchedFile(fullPath);
|
|
1310
1323
|
}, DEBOUNCE_MS));
|
|
1311
1324
|
});
|
|
1325
|
+
|
|
1326
|
+
// Also do an initial scan of all existing files on startup
|
|
1327
|
+
const initialFiles = [];
|
|
1328
|
+
function walkDir(d) {
|
|
1329
|
+
let entries;
|
|
1330
|
+
try { entries = fs.readdirSync(d, { withFileTypes: true }); } catch { return; }
|
|
1331
|
+
for (const entry of entries) {
|
|
1332
|
+
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
1333
|
+
const fullPath = path.join(d, entry.name);
|
|
1334
|
+
if (entry.isDirectory()) {
|
|
1335
|
+
walkDir(fullPath);
|
|
1336
|
+
} else if (SUPPORTED_EXTS.has(path.extname(entry.name))) {
|
|
1337
|
+
initialFiles.push(fullPath);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
walkDir(dir);
|
|
1342
|
+
if (initialFiles.length > 0) {
|
|
1343
|
+
console.log(chalk.dim(` Initial scan: ${initialFiles.length} file(s)...\n`));
|
|
1344
|
+
for (const f of initialFiles) {
|
|
1345
|
+
await analyzeWatchedFile(f);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1312
1348
|
} catch (e) {
|
|
1313
1349
|
console.error(chalk.red(`Failed to watch ${dir}: ${e.message}`));
|
|
1314
1350
|
process.exit(1);
|