sentinelflow 0.2.0
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/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +130 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scan.d.ts +24 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +232 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sentinelflow init [path]
|
|
3
|
+
*
|
|
4
|
+
* Initializes SentinelFlow governance in a project by creating
|
|
5
|
+
* the .sentinelflow/ directory and a default manifest.
|
|
6
|
+
*/
|
|
7
|
+
export declare function initCommand(targetPath: string): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkDH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDnE"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* sentinelflow init [path]
|
|
4
|
+
*
|
|
5
|
+
* Initializes SentinelFlow governance in a project by creating
|
|
6
|
+
* the .sentinelflow/ directory and a default manifest.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.initCommand = initCommand;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const DEFAULT_MANIFEST = `# SentinelFlow Configuration
|
|
46
|
+
# https://github.com/omswaroop/sentinelflow
|
|
47
|
+
|
|
48
|
+
# Governance settings for this project
|
|
49
|
+
governance:
|
|
50
|
+
# Who is responsible for AI agents in this project?
|
|
51
|
+
default_owner: ""
|
|
52
|
+
default_team: ""
|
|
53
|
+
|
|
54
|
+
# Minimum scan requirements
|
|
55
|
+
require_scan_before_commit: false
|
|
56
|
+
min_severity_to_block: "critical"
|
|
57
|
+
|
|
58
|
+
# Compliance standards to enforce
|
|
59
|
+
compliance:
|
|
60
|
+
# - eu-ai-act
|
|
61
|
+
# - soc2
|
|
62
|
+
# - hipaa
|
|
63
|
+
# - iso-42001
|
|
64
|
+
|
|
65
|
+
# Scanner settings
|
|
66
|
+
scanner:
|
|
67
|
+
# Rules to skip (by ID)
|
|
68
|
+
skip_rules: []
|
|
69
|
+
|
|
70
|
+
# Additional paths to scan for agent configs
|
|
71
|
+
include_paths: []
|
|
72
|
+
|
|
73
|
+
# Paths to exclude from scanning
|
|
74
|
+
exclude_paths:
|
|
75
|
+
- node_modules
|
|
76
|
+
- .git
|
|
77
|
+
- dist
|
|
78
|
+
- build
|
|
79
|
+
|
|
80
|
+
# Registry settings
|
|
81
|
+
registry:
|
|
82
|
+
# Where to store the registry (local = SQLite file)
|
|
83
|
+
backend: local
|
|
84
|
+
|
|
85
|
+
# SentinelFlow Cloud URL (for team sync, Phase 2+)
|
|
86
|
+
# cloud_url: https://api.sentinelflow.ai
|
|
87
|
+
# cloud_token: $SENTINELFLOW_TOKEN
|
|
88
|
+
`;
|
|
89
|
+
async function initCommand(targetPath) {
|
|
90
|
+
const rootDir = path.resolve(targetPath);
|
|
91
|
+
const sfDir = path.join(rootDir, ".sentinelflow");
|
|
92
|
+
if (fs.existsSync(sfDir)) {
|
|
93
|
+
console.log("\n SentinelFlow already initialized in this project.");
|
|
94
|
+
console.log(` Config: ${sfDir}/config.yaml`);
|
|
95
|
+
console.log(" Run 'sentinelflow scan' to scan for agents.\n");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Create .sentinelflow/ directory
|
|
99
|
+
fs.mkdirSync(sfDir, { recursive: true });
|
|
100
|
+
fs.mkdirSync(path.join(sfDir, "reports"), { recursive: true });
|
|
101
|
+
// Write default config
|
|
102
|
+
fs.writeFileSync(path.join(sfDir, "config.yaml"), DEFAULT_MANIFEST, "utf-8");
|
|
103
|
+
// Add to .gitignore if it exists
|
|
104
|
+
const gitignorePath = path.join(rootDir, ".gitignore");
|
|
105
|
+
if (fs.existsSync(gitignorePath)) {
|
|
106
|
+
const gitignore = fs.readFileSync(gitignorePath, "utf-8");
|
|
107
|
+
if (!gitignore.includes(".sentinelflow/registry")) {
|
|
108
|
+
fs.appendFileSync(gitignorePath, "\n# SentinelFlow local registry (config is committed, data is not)\n" +
|
|
109
|
+
".sentinelflow/agents.json\n" +
|
|
110
|
+
".sentinelflow/reports.json\n" +
|
|
111
|
+
".sentinelflow/events.json\n" +
|
|
112
|
+
".sentinelflow/registry.db\n");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log(`
|
|
116
|
+
\x1b[32m✓\x1b[0m SentinelFlow initialized!
|
|
117
|
+
|
|
118
|
+
Created:
|
|
119
|
+
${sfDir}/config.yaml — Governance configuration
|
|
120
|
+
${sfDir}/reports/ — Scan report storage
|
|
121
|
+
|
|
122
|
+
Next steps:
|
|
123
|
+
1. Edit .sentinelflow/config.yaml to set your team info
|
|
124
|
+
2. Run \x1b[1msentinelflow scan\x1b[0m to discover agents
|
|
125
|
+
3. Review findings and register agents
|
|
126
|
+
|
|
127
|
+
Learn more: https://github.com/omswaroop/sentinelflow
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDH,kCAoDC;AApGD,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CxB,CAAC;AAEK,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAElD,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,cAAc,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,kCAAkC;IAClC,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,uBAAuB;IACvB,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,EAC/B,gBAAgB,EAChB,OAAO,CACR,CAAC;IAEF,iCAAiC;IACjC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAClD,EAAE,CAAC,cAAc,CACf,aAAa,EACb,sEAAsE;gBACpE,6BAA6B;gBAC7B,8BAA8B;gBAC9B,6BAA6B;gBAC7B,6BAA6B,CAChC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC;;;;MAIR,KAAK;MACL,KAAK;;;;;;;;CAQV,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sentinelflow scan [path]
|
|
3
|
+
*
|
|
4
|
+
* The main scanning command. Detects frameworks, parses agents,
|
|
5
|
+
* runs governance rules, applies suppressions, and reports findings.
|
|
6
|
+
*
|
|
7
|
+
* Phase 1.5 additions:
|
|
8
|
+
* - --preset flag (strict/standard/monitor) for progressive adoption
|
|
9
|
+
* - --show-suppressed flag for audit review of hidden findings
|
|
10
|
+
* - .sentinelflow-policy.yaml loading for project-level suppressions
|
|
11
|
+
* - Coverage footer showing what static analysis can and cannot see
|
|
12
|
+
* - Preset-aware exit codes (monitor never fails CI)
|
|
13
|
+
*/
|
|
14
|
+
interface ScanCommandOptions {
|
|
15
|
+
format: string;
|
|
16
|
+
minSeverity?: string;
|
|
17
|
+
rules?: string;
|
|
18
|
+
registry?: boolean;
|
|
19
|
+
preset?: string;
|
|
20
|
+
showSuppressed?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function scanCommand(targetPath: string, options: ScanCommandOptions): Promise<void>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwBH,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA0Mf"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* sentinelflow scan [path]
|
|
4
|
+
*
|
|
5
|
+
* The main scanning command. Detects frameworks, parses agents,
|
|
6
|
+
* runs governance rules, applies suppressions, and reports findings.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1.5 additions:
|
|
9
|
+
* - --preset flag (strict/standard/monitor) for progressive adoption
|
|
10
|
+
* - --show-suppressed flag for audit review of hidden findings
|
|
11
|
+
* - .sentinelflow-policy.yaml loading for project-level suppressions
|
|
12
|
+
* - Coverage footer showing what static analysis can and cannot see
|
|
13
|
+
* - Preset-aware exit codes (monitor never fails CI)
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.scanCommand = scanCommand;
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const scanner_1 = require("@sentinelflow/scanner");
|
|
53
|
+
const VALID_FORMATS = ["terminal", "json", "md", "sarif"];
|
|
54
|
+
const VALID_SEVERITIES = ["critical", "high", "medium", "low", "info"];
|
|
55
|
+
const VALID_PRESETS = ["strict", "standard", "monitor"];
|
|
56
|
+
async function scanCommand(targetPath, options) {
|
|
57
|
+
const rootDir = path.resolve(targetPath);
|
|
58
|
+
// ── Input Validation ──────────────────────────────────────
|
|
59
|
+
if (!fs.existsSync(rootDir)) {
|
|
60
|
+
console.error(`\n \x1b[31mError:\x1b[0m Directory not found: ${rootDir}\n`);
|
|
61
|
+
process.exit(2);
|
|
62
|
+
}
|
|
63
|
+
if (!fs.statSync(rootDir).isDirectory()) {
|
|
64
|
+
console.error(`\n \x1b[31mError:\x1b[0m Not a directory: ${rootDir}\n`);
|
|
65
|
+
process.exit(2);
|
|
66
|
+
}
|
|
67
|
+
const format = options.format;
|
|
68
|
+
if (!VALID_FORMATS.includes(format)) {
|
|
69
|
+
console.error(`\n \x1b[31mError:\x1b[0m Invalid format "${options.format}". ` +
|
|
70
|
+
`Valid formats: ${VALID_FORMATS.join(", ")}\n`);
|
|
71
|
+
process.exit(2);
|
|
72
|
+
}
|
|
73
|
+
if (options.minSeverity && !VALID_SEVERITIES.includes(options.minSeverity)) {
|
|
74
|
+
console.error(`\n \x1b[31mError:\x1b[0m Invalid severity "${options.minSeverity}". ` +
|
|
75
|
+
`Valid values: ${VALID_SEVERITIES.join(", ")}\n`);
|
|
76
|
+
process.exit(2);
|
|
77
|
+
}
|
|
78
|
+
const preset = (options.preset ?? "standard");
|
|
79
|
+
if (!VALID_PRESETS.includes(preset)) {
|
|
80
|
+
console.error(`\n \x1b[31mError:\x1b[0m Invalid preset "${options.preset}". ` +
|
|
81
|
+
`Valid presets: ${VALID_PRESETS.join(", ")}\n`);
|
|
82
|
+
process.exit(2);
|
|
83
|
+
}
|
|
84
|
+
// ── Run Scan ──────────────────────────────────────────────
|
|
85
|
+
try {
|
|
86
|
+
const result = await (0, scanner_1.scan)({
|
|
87
|
+
rootDir,
|
|
88
|
+
minSeverity: options.minSeverity,
|
|
89
|
+
rules: options.rules?.split(",").map((r) => r.trim()),
|
|
90
|
+
updateRegistry: options.registry,
|
|
91
|
+
});
|
|
92
|
+
// ── Handle Empty Scans ────────────────────────────────
|
|
93
|
+
if (result.frameworks.length === 0 && format === "terminal") {
|
|
94
|
+
console.log(`
|
|
95
|
+
\x1b[36m\x1b[1mSentinelFlow v0.2.0\x1b[0m — Agent Governance Scanner
|
|
96
|
+
|
|
97
|
+
Scanning ${rootDir}...
|
|
98
|
+
|
|
99
|
+
\x1b[33mNo agent frameworks detected.\x1b[0m
|
|
100
|
+
|
|
101
|
+
SentinelFlow scans for agents in:
|
|
102
|
+
• Claude Code (.claude/ directory, CLAUDE.md, AGENTS.md)
|
|
103
|
+
• Cursor (.cursor/ directory, .cursorrules)
|
|
104
|
+
• Codex (.codex/ directory, .agents/)
|
|
105
|
+
• LangChain (pyproject.toml with langchain dependency)
|
|
106
|
+
• CrewAI (crew.yaml, agents.yaml)
|
|
107
|
+
• Kiro (.kiro/ directory)
|
|
108
|
+
|
|
109
|
+
Run \x1b[1msentinelflow init\x1b[0m to set up governance for this project.
|
|
110
|
+
`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// ── Apply Suppressions ────────────────────────────────
|
|
114
|
+
// Load policy file if it exists
|
|
115
|
+
const { policy, warnings: policyWarnings } = (0, scanner_1.loadPolicyFile)(rootDir);
|
|
116
|
+
// Determine effective preset (CLI flag overrides policy file)
|
|
117
|
+
const effectivePreset = options.preset
|
|
118
|
+
? preset
|
|
119
|
+
: policy?.preset ?? "standard";
|
|
120
|
+
// Apply suppressions from inline comments + policy file
|
|
121
|
+
// Pass empty config files array — inline suppression parsing happens
|
|
122
|
+
// inside applySuppressions via the policy file loader. Config file content
|
|
123
|
+
// isn't available from ScanResult, but policy-file and preset suppressions
|
|
124
|
+
// still work fully.
|
|
125
|
+
const suppressionResult = (0, scanner_1.applySuppressions)(result.report.findings, [], rootDir);
|
|
126
|
+
// Replace findings with active-only (unless --show-suppressed)
|
|
127
|
+
if (!options.showSuppressed) {
|
|
128
|
+
result.report.findings = suppressionResult.active;
|
|
129
|
+
// Recalculate summary
|
|
130
|
+
result.report.summary = {
|
|
131
|
+
critical: result.report.findings.filter((f) => f.severity === "critical").length,
|
|
132
|
+
high: result.report.findings.filter((f) => f.severity === "high").length,
|
|
133
|
+
medium: result.report.findings.filter((f) => f.severity === "medium").length,
|
|
134
|
+
low: result.report.findings.filter((f) => f.severity === "low").length,
|
|
135
|
+
info: result.report.findings.filter((f) => f.severity === "info").length,
|
|
136
|
+
total: result.report.findings.length,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// ── Output in Requested Format ────────────────────────
|
|
140
|
+
switch (format) {
|
|
141
|
+
case "json":
|
|
142
|
+
console.log((0, scanner_1.formatJSON)(result));
|
|
143
|
+
break;
|
|
144
|
+
case "md":
|
|
145
|
+
console.log((0, scanner_1.formatMarkdown)(result));
|
|
146
|
+
break;
|
|
147
|
+
case "sarif":
|
|
148
|
+
console.log((0, scanner_1.formatSARIF)(result));
|
|
149
|
+
break;
|
|
150
|
+
case "terminal":
|
|
151
|
+
default:
|
|
152
|
+
console.log((0, scanner_1.formatTerminal)(result));
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
// ── Suppression Summary (terminal only) ───────────────
|
|
156
|
+
if (format === "terminal" && suppressionResult.suppressed.length > 0) {
|
|
157
|
+
if (options.showSuppressed) {
|
|
158
|
+
console.log(` \x1b[33mSuppressed findings (${suppressionResult.suppressed.length}):\x1b[0m`);
|
|
159
|
+
for (const { finding, suppression } of suppressionResult.suppressed) {
|
|
160
|
+
console.log(` \x1b[2m${finding.rule_id}\x1b[0m ${finding.title}`);
|
|
161
|
+
console.log(` Reason: ${suppression.reason}`);
|
|
162
|
+
if (suppression.expires)
|
|
163
|
+
console.log(` Expires: ${suppression.expires}`);
|
|
164
|
+
if (suppression.ticket)
|
|
165
|
+
console.log(` Ticket: ${suppression.ticket}`);
|
|
166
|
+
}
|
|
167
|
+
console.log("");
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(` \x1b[2m${suppressionResult.suppressed.length} finding(s) suppressed. ` +
|
|
171
|
+
`Use --show-suppressed to review.\x1b[0m`);
|
|
172
|
+
console.log("");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ── Expired Suppressions Warning ──────────────────────
|
|
176
|
+
if (format === "terminal" && suppressionResult.expired_suppressions.length > 0) {
|
|
177
|
+
console.log(` \x1b[33m⚠ ${suppressionResult.expired_suppressions.length} expired suppression(s):\x1b[0m`);
|
|
178
|
+
for (const exp of suppressionResult.expired_suppressions) {
|
|
179
|
+
console.log(` ${exp.rule_id} — expired ${exp.expires} — ${exp.reason}`);
|
|
180
|
+
}
|
|
181
|
+
console.log(" \x1b[2mRemove expired entries from .sentinelflow-policy.yaml\x1b[0m");
|
|
182
|
+
console.log("");
|
|
183
|
+
}
|
|
184
|
+
// ── Coverage Footer ───────────────────────────────────
|
|
185
|
+
if (format === "terminal") {
|
|
186
|
+
const agentCount = result.agents.length;
|
|
187
|
+
const configCount = result.report.findings.length;
|
|
188
|
+
console.log(` \x1b[2m┌─ Coverage ──────────────────────────────────────────┐\x1b[0m`);
|
|
189
|
+
console.log(` \x1b[2m│ Static analysis of ${agentCount} agent definition(s). │\x1b[0m`);
|
|
190
|
+
console.log(` \x1b[2m│ │\x1b[0m`);
|
|
191
|
+
console.log(` \x1b[2m│ Not analyzed (requires runtime context): │\x1b[0m`);
|
|
192
|
+
console.log(` \x1b[2m│ · IAM roles and cloud permissions │\x1b[0m`);
|
|
193
|
+
console.log(` \x1b[2m│ · Secrets injected via Vault / env variables │\x1b[0m`);
|
|
194
|
+
console.log(` \x1b[2m│ · Network policies and service mesh config │\x1b[0m`);
|
|
195
|
+
console.log(` \x1b[2m│ · Feature flags gating agent capabilities │\x1b[0m`);
|
|
196
|
+
console.log(` \x1b[2m│ │\x1b[0m`);
|
|
197
|
+
console.log(` \x1b[2m│ Preset: ${effectivePreset.padEnd(10)} Docs: sentinelflow.dev │\x1b[0m`);
|
|
198
|
+
console.log(` \x1b[2m└────────────────────────────────────────────────────┘\x1b[0m`);
|
|
199
|
+
console.log("");
|
|
200
|
+
}
|
|
201
|
+
// Print warnings
|
|
202
|
+
const allWarnings = [...result.warnings, ...policyWarnings];
|
|
203
|
+
if (allWarnings.length > 0 && format === "terminal") {
|
|
204
|
+
console.log(" \x1b[33mWarnings:\x1b[0m");
|
|
205
|
+
for (const warning of allWarnings) {
|
|
206
|
+
console.log(` \x1b[33m⚠\x1b[0m ${warning}`);
|
|
207
|
+
}
|
|
208
|
+
console.log("");
|
|
209
|
+
}
|
|
210
|
+
// ── Exit Code (preset-aware) ──────────────────────────
|
|
211
|
+
const presetConfig = scanner_1.PRESETS[effectivePreset];
|
|
212
|
+
const { summary } = result.report;
|
|
213
|
+
const shouldFail = presetConfig.exitOnSeverities.some((sev) => {
|
|
214
|
+
switch (sev) {
|
|
215
|
+
case "critical": return summary.critical > 0;
|
|
216
|
+
case "high": return summary.high > 0;
|
|
217
|
+
case "medium": return summary.medium > 0;
|
|
218
|
+
case "low": return summary.low > 0;
|
|
219
|
+
default: return false;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (shouldFail) {
|
|
223
|
+
process.exit(1);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
228
|
+
console.error(`\n \x1b[31mError:\x1b[0m ${message}\n`);
|
|
229
|
+
process.exit(2);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SentinelFlow CLI
|
|
4
|
+
*
|
|
5
|
+
* The vendor-neutral governance layer for enterprise AI agents.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* sentinelflow scan [path] Scan for agents and governance issues
|
|
9
|
+
* sentinelflow init Initialize SentinelFlow in a project
|
|
10
|
+
* sentinelflow registry list List registered agents
|
|
11
|
+
*
|
|
12
|
+
* Future (Phase 2):
|
|
13
|
+
* sentinelflow monitor Live-tail agent events
|
|
14
|
+
* sentinelflow dashboard Launch the governance dashboard
|
|
15
|
+
*
|
|
16
|
+
* Future (Phase 3):
|
|
17
|
+
* sentinelflow comply <standard> Run compliance checks
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* SentinelFlow CLI
|
|
5
|
+
*
|
|
6
|
+
* The vendor-neutral governance layer for enterprise AI agents.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* sentinelflow scan [path] Scan for agents and governance issues
|
|
10
|
+
* sentinelflow init Initialize SentinelFlow in a project
|
|
11
|
+
* sentinelflow registry list List registered agents
|
|
12
|
+
*
|
|
13
|
+
* Future (Phase 2):
|
|
14
|
+
* sentinelflow monitor Live-tail agent events
|
|
15
|
+
* sentinelflow dashboard Launch the governance dashboard
|
|
16
|
+
*
|
|
17
|
+
* Future (Phase 3):
|
|
18
|
+
* sentinelflow comply <standard> Run compliance checks
|
|
19
|
+
*/
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
const commander_1 = require("commander");
|
|
55
|
+
const scan_1 = require("./commands/scan");
|
|
56
|
+
const init_1 = require("./commands/init");
|
|
57
|
+
const program = new commander_1.Command();
|
|
58
|
+
program
|
|
59
|
+
.name("sentinelflow")
|
|
60
|
+
.description("The vendor-neutral governance layer for enterprise AI agents")
|
|
61
|
+
.version("0.1.0");
|
|
62
|
+
// ── sentinelflow scan ───────────────────────────────────────
|
|
63
|
+
program
|
|
64
|
+
.command("scan")
|
|
65
|
+
.description("Scan for AI agents and governance issues")
|
|
66
|
+
.argument("[path]", "Project directory to scan", ".")
|
|
67
|
+
.option("-f, --format <format>", "Output format: terminal, json, md, sarif", "terminal")
|
|
68
|
+
.option("--min-severity <severity>", "Minimum severity: critical, high, medium, low, info")
|
|
69
|
+
.option("--rules <rules>", "Comma-separated rule IDs to run")
|
|
70
|
+
.option("--preset <preset>", "Scan preset: strict, standard, monitor", "standard")
|
|
71
|
+
.option("--show-suppressed", "Show suppressed findings for audit review")
|
|
72
|
+
.option("--no-registry", "Skip updating the local registry")
|
|
73
|
+
.action(scan_1.scanCommand);
|
|
74
|
+
// ── sentinelflow init ───────────────────────────────────────
|
|
75
|
+
program
|
|
76
|
+
.command("init")
|
|
77
|
+
.description("Initialize SentinelFlow in the current project")
|
|
78
|
+
.argument("[path]", "Project directory", ".")
|
|
79
|
+
.action(init_1.initCommand);
|
|
80
|
+
// ── sentinelflow registry ───────────────────────────────────
|
|
81
|
+
const registry = program
|
|
82
|
+
.command("registry")
|
|
83
|
+
.description("Manage the agent registry");
|
|
84
|
+
registry
|
|
85
|
+
.command("list")
|
|
86
|
+
.description("List all registered agents")
|
|
87
|
+
.option("--framework <framework>", "Filter by framework")
|
|
88
|
+
.option("--status <status>", "Filter by governance status")
|
|
89
|
+
.option("--json", "Output as JSON")
|
|
90
|
+
.action(async (options) => {
|
|
91
|
+
const path = await Promise.resolve().then(() => __importStar(require("path")));
|
|
92
|
+
const { LocalRegistry } = await Promise.resolve().then(() => __importStar(require("@sentinelflow/core")));
|
|
93
|
+
const reg = new LocalRegistry(process.cwd());
|
|
94
|
+
await reg.initialize();
|
|
95
|
+
const agents = await reg.listAgents({
|
|
96
|
+
framework: options.framework,
|
|
97
|
+
status: options.status,
|
|
98
|
+
});
|
|
99
|
+
if (options.json) {
|
|
100
|
+
console.log(JSON.stringify(agents, null, 2));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
if (agents.length === 0) {
|
|
104
|
+
console.log("\n No agents registered. Run 'sentinelflow scan' first.\n");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
console.log(`\n ${agents.length} agents registered:\n`);
|
|
108
|
+
for (const agent of agents) {
|
|
109
|
+
const risk = agent.governance.risk_level ?? "unassessed";
|
|
110
|
+
const status = agent.governance.status;
|
|
111
|
+
console.log(` ${agent.name} (${agent.framework}) — ${status} — risk: ${risk}`);
|
|
112
|
+
}
|
|
113
|
+
console.log("");
|
|
114
|
+
}
|
|
115
|
+
await reg.close();
|
|
116
|
+
});
|
|
117
|
+
program.parse();
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sentinelflow",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "The vendor-neutral governance scanner for AI agents. Scans Claude Code, Cursor, Codex, LangChain, CrewAI, and Kiro configs for security and compliance issues.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"sentinelflow": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "Om Satya Swaroop",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/Omsatyaswaroop29/sentinelflow.git"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/Omsatyaswaroop29/sentinelflow#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/Omsatyaswaroop29/sentinelflow/issues"
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist"],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ai",
|
|
23
|
+
"ai-agents",
|
|
24
|
+
"governance",
|
|
25
|
+
"security",
|
|
26
|
+
"scanner",
|
|
27
|
+
"claude-code",
|
|
28
|
+
"cursor",
|
|
29
|
+
"codex",
|
|
30
|
+
"langchain",
|
|
31
|
+
"crewai",
|
|
32
|
+
"llm",
|
|
33
|
+
"compliance",
|
|
34
|
+
"eu-ai-act",
|
|
35
|
+
"owasp",
|
|
36
|
+
"sarif",
|
|
37
|
+
"sast",
|
|
38
|
+
"devsecops"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc",
|
|
42
|
+
"dev": "tsc --watch",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"lint": "tsc --noEmit",
|
|
45
|
+
"clean": "rm -rf dist"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@sentinelflow/core": "workspace:*",
|
|
49
|
+
"@sentinelflow/parsers": "workspace:*",
|
|
50
|
+
"@sentinelflow/scanner": "workspace:*",
|
|
51
|
+
"commander": "^13.0.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"vitest": "^2.1.0",
|
|
55
|
+
"typescript": "^5.7.0"
|
|
56
|
+
}
|
|
57
|
+
}
|