@rotifer/playground 0.7.8 → 0.7.9
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/CHANGELOG.md +11 -0
- package/dist/commands/vg.d.ts +3 -0
- package/dist/commands/vg.d.ts.map +1 -0
- package/dist/commands/vg.js +112 -0
- package/dist/commands/vg.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/scanner/index.d.ts +5 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +10 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/rules.d.ts +3 -0
- package/dist/scanner/rules.d.ts.map +1 -0
- package/dist/scanner/rules.js +94 -0
- package/dist/scanner/rules.js.map +1 -0
- package/dist/scanner/scanner.d.ts +8 -0
- package/dist/scanner/scanner.d.ts.map +1 -0
- package/dist/scanner/scanner.js +100 -0
- package/dist/scanner/scanner.js.map +1 -0
- package/dist/scanner/types.d.ts +27 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +3 -0
- package/dist/scanner/types.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.9] - 2026-03-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **V(g) security scanner** — static analysis engine with 7 rules (S-01 to S-07) detecting dynamic code execution, system commands, obfuscation, external communication, env access, persistent connections, and filesystem operations
|
|
13
|
+
- **CLI: `rotifer vg [path]`** — run V(g) security scan on any Skill or Gene directory with `--json`, `--all`, `--id` options
|
|
14
|
+
- **Security grade mapping** — A/B/C/D/? grades based on finding severity (CRITICAL/HIGH/MEDIUM)
|
|
15
|
+
- Scanner supports `.ts`, `.js`, `.mts`, `.mjs`, `.cjs`, `.tsx`, `.jsx`, `.sh`, `.py` file extensions
|
|
16
|
+
- Comment-line skipping in scan results to reduce false positives
|
|
17
|
+
- Unit tests: scanner rules (S-01 to S-07 pattern matching) and scanner core (grade computation, file collection, edge cases)
|
|
18
|
+
|
|
8
19
|
## [0.7.8] - 2026-02-17
|
|
9
20
|
|
|
10
21
|
### Added
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vg.d.ts","sourceRoot":"","sources":["../../src/commands/vg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,eAAO,MAAM,SAAS,SA4DlB,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.vgCommand = void 0;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const node_path_1 = require("node:path");
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
const index_js_1 = require("../scanner/index.js");
|
|
44
|
+
const display = __importStar(require("../utils/display.js"));
|
|
45
|
+
const GRADE_COLORS = {
|
|
46
|
+
A: chalk_1.default.green,
|
|
47
|
+
B: chalk_1.default.greenBright,
|
|
48
|
+
C: chalk_1.default.yellow,
|
|
49
|
+
D: chalk_1.default.red,
|
|
50
|
+
"?": chalk_1.default.gray,
|
|
51
|
+
};
|
|
52
|
+
const SEVERITY_COLORS = {
|
|
53
|
+
CRITICAL: chalk_1.default.red.bold,
|
|
54
|
+
HIGH: chalk_1.default.yellow,
|
|
55
|
+
MEDIUM: chalk_1.default.dim,
|
|
56
|
+
};
|
|
57
|
+
function printFinding(f) {
|
|
58
|
+
const sev = SEVERITY_COLORS[f.severity]?.(f.severity) ?? f.severity;
|
|
59
|
+
const loc = chalk_1.default.dim(`${f.file}:${f.line}`);
|
|
60
|
+
console.log(` ${sev} [${f.rule}] ${loc}`);
|
|
61
|
+
console.log(` ${chalk_1.default.dim(f.snippet)}`);
|
|
62
|
+
}
|
|
63
|
+
exports.vgCommand = new commander_1.Command("vg")
|
|
64
|
+
.description("V(g) security scan — static analysis for Skill/Gene code safety")
|
|
65
|
+
.argument("[path]", "path to Skill or Gene directory", ".")
|
|
66
|
+
.option("--id <skill_id>", "skill/gene identifier for the report")
|
|
67
|
+
.option("--json", "output raw JSON report")
|
|
68
|
+
.option("--all", "scan all code files, not just src/")
|
|
69
|
+
.action((pathArg, opts) => {
|
|
70
|
+
const dir = (0, node_path_1.resolve)(pathArg);
|
|
71
|
+
const result = (0, index_js_1.scan)(dir, opts.id, { scanAll: opts.all });
|
|
72
|
+
if (opts.json) {
|
|
73
|
+
console.log(JSON.stringify(result, null, 2));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
display.header("V(g) Security Scan");
|
|
77
|
+
if (result.grade === "?") {
|
|
78
|
+
display.info(`No src/ directory found — grade: ${chalk_1.default.gray("?")}`);
|
|
79
|
+
display.info("Pure-prompt Skills without code receive grade \"?\".");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const gradeColor = GRADE_COLORS[result.grade] ?? chalk_1.default.white;
|
|
83
|
+
display.keyValue("Skill", result.skill_id);
|
|
84
|
+
display.keyValue("Files scanned", String(result.stats.files_scanned));
|
|
85
|
+
display.keyValue("Lines of code", String(result.stats.lines_of_code));
|
|
86
|
+
display.keyValue("Grade", gradeColor(result.grade));
|
|
87
|
+
if (result.findings.length === 0) {
|
|
88
|
+
console.log();
|
|
89
|
+
display.success("No security findings — grade A");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
console.log();
|
|
93
|
+
const criticals = result.findings.filter((f) => f.severity === "CRITICAL");
|
|
94
|
+
const highs = result.findings.filter((f) => f.severity === "HIGH");
|
|
95
|
+
const mediums = result.findings.filter((f) => f.severity === "MEDIUM");
|
|
96
|
+
if (criticals.length > 0) {
|
|
97
|
+
console.log(chalk_1.default.red.bold(` CRITICAL (${criticals.length}):`));
|
|
98
|
+
criticals.forEach(printFinding);
|
|
99
|
+
}
|
|
100
|
+
if (highs.length > 0) {
|
|
101
|
+
console.log(chalk_1.default.yellow(` HIGH (${highs.length}):`));
|
|
102
|
+
highs.forEach(printFinding);
|
|
103
|
+
}
|
|
104
|
+
if (mediums.length > 0) {
|
|
105
|
+
console.log(chalk_1.default.dim(` MEDIUM (${mediums.length}):`));
|
|
106
|
+
mediums.forEach(printFinding);
|
|
107
|
+
}
|
|
108
|
+
console.log();
|
|
109
|
+
console.log(chalk_1.default.dim(" Disclaimer: Static analysis only. Not a substitute for"));
|
|
110
|
+
console.log(chalk_1.default.dim(" manual review or runtime sandboxing. See rotifer.dev/badge"));
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=vg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vg.js","sourceRoot":"","sources":["../../src/commands/vg.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ const whoami_js_1 = require("./commands/whoami.js");
|
|
|
29
29
|
const stats_js_1 = require("./commands/stats.js");
|
|
30
30
|
const compare_js_1 = require("./commands/compare.js");
|
|
31
31
|
const network_js_1 = require("./commands/network.js");
|
|
32
|
+
const vg_js_1 = require("./commands/vg.js");
|
|
32
33
|
const pkg = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "..", "package.json"), "utf-8"));
|
|
33
34
|
const program = new commander_1.Command();
|
|
34
35
|
program
|
|
@@ -62,5 +63,6 @@ agent.addCommand(agent_create_js_1.agentCreateCommand);
|
|
|
62
63
|
agent.addCommand(agent_list_js_1.agentListCommand);
|
|
63
64
|
agent.addCommand(agent_run_js_1.agentRunCommand);
|
|
64
65
|
program.addCommand(network_js_1.networkCommand);
|
|
66
|
+
program.addCommand(vg_js_1.vgCommand);
|
|
65
67
|
program.parse();
|
|
66
68
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAuC;AACvC,yCAAiC;AACjC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,sDAAuD;AACvD,gEAAgE;AAChE,4DAA4D;AAC5D,8DAA8D;AAC9D,gEAAgE;AAChE,4DAA4D;AAC5D,0DAA0D;AAC1D,kDAAmD;AACnD,oDAAqD;AACrD,sDAAuD;AACvD,oDAAqD;AACrD,sDAAuD;AACvD,4DAA6D;AAC7D,gDAAiD;AACjD,gDAAiD;AACjD,8CAA+C;AAC/C,wDAAyD;AACzD,oDAAqD;AACrD,kDAAmD;AACnD,sDAAuD;AACvD,sDAAuD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAuC;AACvC,yCAAiC;AACjC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,sDAAuD;AACvD,gEAAgE;AAChE,4DAA4D;AAC5D,8DAA8D;AAC9D,gEAAgE;AAChE,4DAA4D;AAC5D,0DAA0D;AAC1D,kDAAmD;AACnD,oDAAqD;AACrD,sDAAuD;AACvD,oDAAqD;AACrD,sDAAuD;AACvD,4DAA6D;AAC7D,gDAAiD;AACjD,gDAAiD;AACjD,8CAA+C;AAC/C,wDAAyD;AACzD,oDAAqD;AACrD,kDAAmD;AACnD,sDAAuD;AACvD,sDAAuD;AACvD,4CAA6C;AAE7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CACV,uEAAuE,CACxE;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,iCAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,mBAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,6BAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;AACjF,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,kCAAiB,CAAC,CAAC;AAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAC/E,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,8BAAe,CAAC,CAAC;AAElC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,iBAAS,CAAC,CAAC;AAE9B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { scan, scanFile, computeGrade } from "./scanner.js";
|
|
2
|
+
export type { ScanOptions } from "./scanner.js";
|
|
3
|
+
export { SCAN_RULES } from "./rules.js";
|
|
4
|
+
export type { ScanResult, Finding, Grade, Severity, ScanRule } from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCAN_RULES = exports.computeGrade = exports.scanFile = exports.scan = void 0;
|
|
4
|
+
var scanner_js_1 = require("./scanner.js");
|
|
5
|
+
Object.defineProperty(exports, "scan", { enumerable: true, get: function () { return scanner_js_1.scan; } });
|
|
6
|
+
Object.defineProperty(exports, "scanFile", { enumerable: true, get: function () { return scanner_js_1.scanFile; } });
|
|
7
|
+
Object.defineProperty(exports, "computeGrade", { enumerable: true, get: function () { return scanner_js_1.computeGrade; } });
|
|
8
|
+
var rules_js_1 = require("./rules.js");
|
|
9
|
+
Object.defineProperty(exports, "SCAN_RULES", { enumerable: true, get: function () { return rules_js_1.SCAN_RULES; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":";;;AAAA,2CAA4D;AAAnD,kGAAA,IAAI,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,0GAAA,YAAY,OAAA;AAErC,uCAAwC;AAA/B,sGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/scanner/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,UAAU,EAAE,QAAQ,EAyFhC,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCAN_RULES = void 0;
|
|
4
|
+
exports.SCAN_RULES = [
|
|
5
|
+
{
|
|
6
|
+
id: "S-01",
|
|
7
|
+
description: "Dynamic code execution",
|
|
8
|
+
severity: "CRITICAL",
|
|
9
|
+
patterns: [
|
|
10
|
+
/\beval\s*\(/,
|
|
11
|
+
/\bFunction\s*\(/,
|
|
12
|
+
/new\s+Function\s*\(/,
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "S-02",
|
|
17
|
+
description: "System command execution",
|
|
18
|
+
severity: "CRITICAL",
|
|
19
|
+
patterns: [
|
|
20
|
+
/require\s*\(\s*['"]child_process['"]\s*\)/,
|
|
21
|
+
/from\s+['"]child_process['"]/,
|
|
22
|
+
/\bexec\s*\(/,
|
|
23
|
+
/\bexecSync\s*\(/,
|
|
24
|
+
/\bspawn\s*\(/,
|
|
25
|
+
/\bspawnSync\s*\(/,
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "S-03",
|
|
30
|
+
description: "Code obfuscation (base64 decode + execute)",
|
|
31
|
+
severity: "CRITICAL",
|
|
32
|
+
patterns: [
|
|
33
|
+
/\batob\s*\([^)]*\)\s*.*\beval\b/,
|
|
34
|
+
/\beval\s*\(\s*atob\b/,
|
|
35
|
+
/Buffer\.from\s*\([^)]*,\s*['"]base64['"]\s*\).*\beval\b/,
|
|
36
|
+
/\bdecodeURIComponent\s*\(\s*escape\s*\(\s*atob\b/,
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "S-04",
|
|
41
|
+
description: "Suspicious external communication",
|
|
42
|
+
severity: "HIGH",
|
|
43
|
+
patterns: [
|
|
44
|
+
/\bfetch\s*\(/,
|
|
45
|
+
/\bhttp\.request\s*\(/,
|
|
46
|
+
/\bhttps\.request\s*\(/,
|
|
47
|
+
/new\s+XMLHttpRequest\s*\(/,
|
|
48
|
+
/\baxios\s*[.(]/,
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "S-05",
|
|
53
|
+
description: "Environment variable access",
|
|
54
|
+
severity: "HIGH",
|
|
55
|
+
patterns: [
|
|
56
|
+
/\bprocess\.env\b/,
|
|
57
|
+
/\bDeno\.env\b/,
|
|
58
|
+
/\bos\.environ\b/,
|
|
59
|
+
/\bimport\.meta\.env\b/,
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "S-06",
|
|
64
|
+
description: "Persistent outbound connection",
|
|
65
|
+
severity: "HIGH",
|
|
66
|
+
patterns: [
|
|
67
|
+
/new\s+WebSocket\s*\(/,
|
|
68
|
+
/\bnet\.Socket\s*\(/,
|
|
69
|
+
/new\s+net\.Socket\s*\(/,
|
|
70
|
+
/\bnet\.createConnection\s*\(/,
|
|
71
|
+
/\btls\.connect\s*\(/,
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "S-07",
|
|
76
|
+
description: "File system operations",
|
|
77
|
+
severity: "MEDIUM",
|
|
78
|
+
patterns: [
|
|
79
|
+
/\bfs\.readFile\b/,
|
|
80
|
+
/\bfs\.readFileSync\b/,
|
|
81
|
+
/\bfs\.writeFile\b/,
|
|
82
|
+
/\bfs\.writeFileSync\b/,
|
|
83
|
+
/\bfs\.unlink\b/,
|
|
84
|
+
/\bfs\.unlinkSync\b/,
|
|
85
|
+
/\bfs\.rmSync\b/,
|
|
86
|
+
/\bfs\.rm\b/,
|
|
87
|
+
/\bfs\.mkdir\b/,
|
|
88
|
+
/\bfs\.mkdirSync\b/,
|
|
89
|
+
/\breadFileSync\s*\(/,
|
|
90
|
+
/\bwriteFileSync\s*\(/,
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/scanner/rules.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAe;IACpC;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,wBAAwB;QACrC,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,aAAa;YACb,iBAAiB;YACjB,qBAAqB;SACtB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,0BAA0B;QACvC,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,2CAA2C;YAC3C,8BAA8B;YAC9B,aAAa;YACb,iBAAiB;YACjB,cAAc;YACd,kBAAkB;SACnB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,4CAA4C;QACzD,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,iCAAiC;YACjC,sBAAsB;YACtB,yDAAyD;YACzD,kDAAkD;SACnD;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,mCAAmC;QAChD,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,cAAc;YACd,sBAAsB;YACtB,uBAAuB;YACvB,2BAA2B;YAC3B,gBAAgB;SACjB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,6BAA6B;QAC1C,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,kBAAkB;YAClB,eAAe;YACf,iBAAiB;YACjB,uBAAuB;SACxB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,gCAAgC;QAC7C,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,sBAAsB;YACtB,oBAAoB;YACpB,wBAAwB;YACxB,8BAA8B;YAC9B,qBAAqB;SACtB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,wBAAwB;QACrC,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE;YACR,kBAAkB;YAClB,sBAAsB;YACtB,mBAAmB;YACnB,uBAAuB;YACvB,gBAAgB;YAChB,oBAAoB;YACpB,gBAAgB;YAChB,YAAY;YACZ,eAAe;YACf,mBAAmB;YACnB,qBAAqB;YACrB,sBAAsB;SACvB;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Finding, Grade, ScanResult } from "./types.js";
|
|
2
|
+
export declare function scanFile(filePath: string, rootDir: string): Finding[];
|
|
3
|
+
export declare function computeGrade(findings: Finding[]): Grade;
|
|
4
|
+
export interface ScanOptions {
|
|
5
|
+
scanAll?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function scan(dir: string, skillId?: string, options?: ScanOptions): ScanResult;
|
|
8
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA0B7D,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CA2BrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAQvD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,UAAU,CAkCrF"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scanFile = scanFile;
|
|
4
|
+
exports.computeGrade = computeGrade;
|
|
5
|
+
exports.scan = scan;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const rules_js_1 = require("./rules.js");
|
|
9
|
+
const CODE_EXTENSIONS = new Set([".ts", ".js", ".mts", ".mjs", ".cjs", ".tsx", ".jsx", ".sh", ".py"]);
|
|
10
|
+
function collectCodeFiles(dir) {
|
|
11
|
+
const files = [];
|
|
12
|
+
const walk = (d) => {
|
|
13
|
+
for (const entry of (0, node_fs_1.readdirSync)(d)) {
|
|
14
|
+
if (entry === "node_modules" || entry === ".git" || entry === "dist")
|
|
15
|
+
continue;
|
|
16
|
+
const full = (0, node_path_1.join)(d, entry);
|
|
17
|
+
const st = (0, node_fs_1.statSync)(full);
|
|
18
|
+
if (st.isDirectory()) {
|
|
19
|
+
walk(full);
|
|
20
|
+
}
|
|
21
|
+
else if (CODE_EXTENSIONS.has((0, node_path_1.extname)(entry))) {
|
|
22
|
+
files.push(full);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
walk(dir);
|
|
27
|
+
return files;
|
|
28
|
+
}
|
|
29
|
+
function hasSrcDirectory(dir) {
|
|
30
|
+
return (0, node_fs_1.existsSync)((0, node_path_1.join)(dir, "src"));
|
|
31
|
+
}
|
|
32
|
+
function scanFile(filePath, rootDir) {
|
|
33
|
+
const content = (0, node_fs_1.readFileSync)(filePath, "utf-8");
|
|
34
|
+
const lines = content.split("\n");
|
|
35
|
+
const relPath = (0, node_path_1.relative)(rootDir, filePath);
|
|
36
|
+
const findings = [];
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
const line = lines[i];
|
|
39
|
+
if (line.trimStart().startsWith("//") || line.trimStart().startsWith("*"))
|
|
40
|
+
continue;
|
|
41
|
+
for (const rule of rules_js_1.SCAN_RULES) {
|
|
42
|
+
for (const pattern of rule.patterns) {
|
|
43
|
+
if (pattern.test(line)) {
|
|
44
|
+
findings.push({
|
|
45
|
+
rule: rule.id,
|
|
46
|
+
severity: rule.severity,
|
|
47
|
+
file: relPath,
|
|
48
|
+
line: i + 1,
|
|
49
|
+
snippet: line.trim().slice(0, 120),
|
|
50
|
+
});
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return findings;
|
|
57
|
+
}
|
|
58
|
+
function computeGrade(findings) {
|
|
59
|
+
const criticals = findings.filter((f) => f.severity === "CRITICAL").length;
|
|
60
|
+
const highs = findings.filter((f) => f.severity === "HIGH").length;
|
|
61
|
+
if (criticals >= 1)
|
|
62
|
+
return "D";
|
|
63
|
+
if (highs > 2)
|
|
64
|
+
return "C";
|
|
65
|
+
if (highs > 0)
|
|
66
|
+
return "B";
|
|
67
|
+
return "A";
|
|
68
|
+
}
|
|
69
|
+
function scan(dir, skillId, options) {
|
|
70
|
+
const scanAll = options?.scanAll ?? false;
|
|
71
|
+
if (!scanAll && !hasSrcDirectory(dir)) {
|
|
72
|
+
return {
|
|
73
|
+
skill_id: skillId ?? dir,
|
|
74
|
+
scanned_at: new Date().toISOString(),
|
|
75
|
+
grade: "?",
|
|
76
|
+
findings: [],
|
|
77
|
+
stats: { files_scanned: 0, lines_of_code: 0 },
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const scanDir = scanAll ? dir : (0, node_path_1.join)(dir, "src");
|
|
81
|
+
const files = collectCodeFiles(scanDir);
|
|
82
|
+
const allFindings = [];
|
|
83
|
+
let totalLines = 0;
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
const content = (0, node_fs_1.readFileSync)(file, "utf-8");
|
|
86
|
+
totalLines += content.split("\n").length;
|
|
87
|
+
allFindings.push(...scanFile(file, dir));
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
skill_id: skillId ?? dir,
|
|
91
|
+
scanned_at: new Date().toISOString(),
|
|
92
|
+
grade: computeGrade(allFindings),
|
|
93
|
+
findings: allFindings,
|
|
94
|
+
stats: {
|
|
95
|
+
files_scanned: files.length,
|
|
96
|
+
lines_of_code: totalLines,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":";;AA6BA,4BA2BC;AAED,oCAQC;AAMD,oBAkCC;AA1GD,qCAA0E;AAC1E,yCAAoD;AACpD,yCAAwC;AAGxC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEtG,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE;QACzB,KAAK,MAAM,KAAK,IAAI,IAAA,qBAAW,EAAC,CAAC,CAAC,EAAE,CAAC;YACnC,IAAI,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM;gBAAE,SAAS;YAC/E,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC5B,MAAM,EAAE,GAAG,IAAA,kBAAQ,EAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrB,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,CAAC;iBAAM,IAAI,eAAe,CAAC,GAAG,CAAC,IAAA,mBAAO,EAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,IAAA,oBAAU,EAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,SAAgB,QAAQ,CAAC,QAAgB,EAAE,OAAe;IACxD,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAA,oBAAQ,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEpF,KAAK,MAAM,IAAI,IAAI,qBAAU,EAAE,CAAC;YAC9B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACpC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvB,QAAQ,CAAC,IAAI,CAAC;wBACZ,IAAI,EAAE,IAAI,CAAC,EAAE;wBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;qBACnC,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAgB,YAAY,CAAC,QAAmB;IAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;IAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAEnE,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1B,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1B,OAAO,GAAG,CAAC;AACb,CAAC;AAMD,SAAgB,IAAI,CAAC,GAAW,EAAE,OAAgB,EAAE,OAAqB;IACvE,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;IAE1C,IAAI,CAAC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,QAAQ,EAAE,OAAO,IAAI,GAAG;YACxB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,EAAE;YACZ,KAAK,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;SAC9C,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,WAAW,GAAc,EAAE,CAAC;IAClC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5C,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACzC,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,OAAO,IAAI,GAAG;QACxB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC;QAChC,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE;YACL,aAAa,EAAE,KAAK,CAAC,MAAM;YAC3B,aAAa,EAAE,UAAU;SAC1B;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type Severity = "CRITICAL" | "HIGH" | "MEDIUM";
|
|
2
|
+
export type Grade = "A" | "B" | "C" | "D" | "?";
|
|
3
|
+
export interface ScanRule {
|
|
4
|
+
id: string;
|
|
5
|
+
description: string;
|
|
6
|
+
severity: Severity;
|
|
7
|
+
patterns: RegExp[];
|
|
8
|
+
}
|
|
9
|
+
export interface Finding {
|
|
10
|
+
rule: string;
|
|
11
|
+
severity: Severity;
|
|
12
|
+
file: string;
|
|
13
|
+
line: number;
|
|
14
|
+
snippet: string;
|
|
15
|
+
note?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ScanResult {
|
|
18
|
+
skill_id: string;
|
|
19
|
+
scanned_at: string;
|
|
20
|
+
grade: Grade;
|
|
21
|
+
findings: Finding[];
|
|
22
|
+
stats: {
|
|
23
|
+
files_scanned: number;
|
|
24
|
+
lines_of_code: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AACtD,MAAM,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotifer/playground",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.9",
|
|
4
4
|
"description": "Rotifer Protocol Playground — local development environment for gene development, Arena competition, and protocol simulation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Rotifer Protocol Contributors",
|