@rexymayderio/sentinel 0.1.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.
Files changed (191) hide show
  1. package/README.md +295 -0
  2. package/dist/acquire/acquirer.d.ts +38 -0
  3. package/dist/acquire/acquirer.d.ts.map +1 -0
  4. package/dist/acquire/acquirer.js +178 -0
  5. package/dist/acquire/acquirer.js.map +1 -0
  6. package/dist/adapters/cli-approval-prompt.d.ts +13 -0
  7. package/dist/adapters/cli-approval-prompt.d.ts.map +1 -0
  8. package/dist/adapters/cli-approval-prompt.js +44 -0
  9. package/dist/adapters/cli-approval-prompt.js.map +1 -0
  10. package/dist/adapters/github-repo-client.d.ts +9 -0
  11. package/dist/adapters/github-repo-client.d.ts.map +1 -0
  12. package/dist/adapters/github-repo-client.js +48 -0
  13. package/dist/adapters/github-repo-client.js.map +1 -0
  14. package/dist/adapters/index.d.ts +5 -0
  15. package/dist/adapters/index.d.ts.map +1 -0
  16. package/dist/adapters/index.js +5 -0
  17. package/dist/adapters/index.js.map +1 -0
  18. package/dist/adapters/node-process-runner.d.ts +8 -0
  19. package/dist/adapters/node-process-runner.d.ts.map +1 -0
  20. package/dist/adapters/node-process-runner.js +21 -0
  21. package/dist/adapters/node-process-runner.js.map +1 -0
  22. package/dist/adapters/npm-registry-client.d.ts +8 -0
  23. package/dist/adapters/npm-registry-client.d.ts.map +1 -0
  24. package/dist/adapters/npm-registry-client.js +66 -0
  25. package/dist/adapters/npm-registry-client.js.map +1 -0
  26. package/dist/analyzers/ai-prompt-analyzer.d.ts +7 -0
  27. package/dist/analyzers/ai-prompt-analyzer.d.ts.map +1 -0
  28. package/dist/analyzers/ai-prompt-analyzer.js +88 -0
  29. package/dist/analyzers/ai-prompt-analyzer.js.map +1 -0
  30. package/dist/analyzers/analyzer.d.ts +14 -0
  31. package/dist/analyzers/analyzer.d.ts.map +1 -0
  32. package/dist/analyzers/analyzer.js +11 -0
  33. package/dist/analyzers/analyzer.js.map +1 -0
  34. package/dist/analyzers/dependency-analyzer.d.ts +10 -0
  35. package/dist/analyzers/dependency-analyzer.d.ts.map +1 -0
  36. package/dist/analyzers/dependency-analyzer.js +79 -0
  37. package/dist/analyzers/dependency-analyzer.js.map +1 -0
  38. package/dist/analyzers/index.d.ts +13 -0
  39. package/dist/analyzers/index.d.ts.map +1 -0
  40. package/dist/analyzers/index.js +30 -0
  41. package/dist/analyzers/index.js.map +1 -0
  42. package/dist/analyzers/install-script-analyzer.d.ts +7 -0
  43. package/dist/analyzers/install-script-analyzer.d.ts.map +1 -0
  44. package/dist/analyzers/install-script-analyzer.js +64 -0
  45. package/dist/analyzers/install-script-analyzer.js.map +1 -0
  46. package/dist/analyzers/match-evidence.d.ts +6 -0
  47. package/dist/analyzers/match-evidence.d.ts.map +1 -0
  48. package/dist/analyzers/match-evidence.js +15 -0
  49. package/dist/analyzers/match-evidence.js.map +1 -0
  50. package/dist/analyzers/metadata-analyzer.d.ts +7 -0
  51. package/dist/analyzers/metadata-analyzer.d.ts.map +1 -0
  52. package/dist/analyzers/metadata-analyzer.js +105 -0
  53. package/dist/analyzers/metadata-analyzer.js.map +1 -0
  54. package/dist/analyzers/network-analyzer.d.ts +7 -0
  55. package/dist/analyzers/network-analyzer.d.ts.map +1 -0
  56. package/dist/analyzers/network-analyzer.js +47 -0
  57. package/dist/analyzers/network-analyzer.js.map +1 -0
  58. package/dist/analyzers/rules/index.d.ts +19 -0
  59. package/dist/analyzers/rules/index.d.ts.map +1 -0
  60. package/dist/analyzers/rules/index.js +70 -0
  61. package/dist/analyzers/rules/index.js.map +1 -0
  62. package/dist/analyzers/secret-analyzer.d.ts +7 -0
  63. package/dist/analyzers/secret-analyzer.d.ts.map +1 -0
  64. package/dist/analyzers/secret-analyzer.js +33 -0
  65. package/dist/analyzers/secret-analyzer.js.map +1 -0
  66. package/dist/analyzers/source-analyzer.d.ts +7 -0
  67. package/dist/analyzers/source-analyzer.d.ts.map +1 -0
  68. package/dist/analyzers/source-analyzer.js +73 -0
  69. package/dist/analyzers/source-analyzer.js.map +1 -0
  70. package/dist/analyzers/static-code-analyzer.d.ts +7 -0
  71. package/dist/analyzers/static-code-analyzer.d.ts.map +1 -0
  72. package/dist/analyzers/static-code-analyzer.js +67 -0
  73. package/dist/analyzers/static-code-analyzer.js.map +1 -0
  74. package/dist/analyzers/test-path.d.ts +2 -0
  75. package/dist/analyzers/test-path.d.ts.map +1 -0
  76. package/dist/analyzers/test-path.js +32 -0
  77. package/dist/analyzers/test-path.js.map +1 -0
  78. package/dist/cli/index.d.ts +3 -0
  79. package/dist/cli/index.d.ts.map +1 -0
  80. package/dist/cli/index.js +176 -0
  81. package/dist/cli/index.js.map +1 -0
  82. package/dist/cli/spinner.d.ts +5 -0
  83. package/dist/cli/spinner.d.ts.map +1 -0
  84. package/dist/cli/spinner.js +39 -0
  85. package/dist/cli/spinner.js.map +1 -0
  86. package/dist/core/index.d.ts +3 -0
  87. package/dist/core/index.d.ts.map +1 -0
  88. package/dist/core/index.js +3 -0
  89. package/dist/core/index.js.map +1 -0
  90. package/dist/core/permissions.d.ts +4 -0
  91. package/dist/core/permissions.d.ts.map +1 -0
  92. package/dist/core/permissions.js +28 -0
  93. package/dist/core/permissions.js.map +1 -0
  94. package/dist/core/sentinel.d.ts +32 -0
  95. package/dist/core/sentinel.d.ts.map +1 -0
  96. package/dist/core/sentinel.js +164 -0
  97. package/dist/core/sentinel.js.map +1 -0
  98. package/dist/domain/artifact.d.ts +34 -0
  99. package/dist/domain/artifact.d.ts.map +1 -0
  100. package/dist/domain/artifact.js +2 -0
  101. package/dist/domain/artifact.js.map +1 -0
  102. package/dist/domain/finding.d.ts +22 -0
  103. package/dist/domain/finding.d.ts.map +1 -0
  104. package/dist/domain/finding.js +30 -0
  105. package/dist/domain/finding.js.map +1 -0
  106. package/dist/domain/index.d.ts +7 -0
  107. package/dist/domain/index.d.ts.map +1 -0
  108. package/dist/domain/index.js +7 -0
  109. package/dist/domain/index.js.map +1 -0
  110. package/dist/domain/permission.d.ts +8 -0
  111. package/dist/domain/permission.d.ts.map +1 -0
  112. package/dist/domain/permission.js +21 -0
  113. package/dist/domain/permission.js.map +1 -0
  114. package/dist/domain/report.d.ts +35 -0
  115. package/dist/domain/report.d.ts.map +1 -0
  116. package/dist/domain/report.js +2 -0
  117. package/dist/domain/report.js.map +1 -0
  118. package/dist/domain/risk.d.ts +14 -0
  119. package/dist/domain/risk.d.ts.map +1 -0
  120. package/dist/domain/risk.js +15 -0
  121. package/dist/domain/risk.js.map +1 -0
  122. package/dist/domain/target.d.ts +12 -0
  123. package/dist/domain/target.d.ts.map +1 -0
  124. package/dist/domain/target.js +43 -0
  125. package/dist/domain/target.js.map +1 -0
  126. package/dist/engine/data-assessment.d.ts +10 -0
  127. package/dist/engine/data-assessment.d.ts.map +1 -0
  128. package/dist/engine/data-assessment.js +39 -0
  129. package/dist/engine/data-assessment.js.map +1 -0
  130. package/dist/engine/default-policy.d.ts +16 -0
  131. package/dist/engine/default-policy.d.ts.map +1 -0
  132. package/dist/engine/default-policy.js +15 -0
  133. package/dist/engine/default-policy.js.map +1 -0
  134. package/dist/engine/index.d.ts +4 -0
  135. package/dist/engine/index.d.ts.map +1 -0
  136. package/dist/engine/index.js +4 -0
  137. package/dist/engine/index.js.map +1 -0
  138. package/dist/engine/policy-engine.d.ts +13 -0
  139. package/dist/engine/policy-engine.d.ts.map +1 -0
  140. package/dist/engine/policy-engine.js +78 -0
  141. package/dist/engine/policy-engine.js.map +1 -0
  142. package/dist/engine/risk-calculator.d.ts +15 -0
  143. package/dist/engine/risk-calculator.d.ts.map +1 -0
  144. package/dist/engine/risk-calculator.js +57 -0
  145. package/dist/engine/risk-calculator.js.map +1 -0
  146. package/dist/factory.d.ts +14 -0
  147. package/dist/factory.d.ts.map +1 -0
  148. package/dist/factory.js +25 -0
  149. package/dist/factory.js.map +1 -0
  150. package/dist/index.d.ts +4 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +4 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/mcp/server.d.ts +3 -0
  155. package/dist/mcp/server.d.ts.map +1 -0
  156. package/dist/mcp/server.js +151 -0
  157. package/dist/mcp/server.js.map +1 -0
  158. package/dist/ports/approval-prompt.d.ts +5 -0
  159. package/dist/ports/approval-prompt.d.ts.map +1 -0
  160. package/dist/ports/approval-prompt.js +2 -0
  161. package/dist/ports/approval-prompt.js.map +1 -0
  162. package/dist/ports/clock.d.ts +5 -0
  163. package/dist/ports/clock.d.ts.map +1 -0
  164. package/dist/ports/clock.js +4 -0
  165. package/dist/ports/clock.js.map +1 -0
  166. package/dist/ports/index.d.ts +6 -0
  167. package/dist/ports/index.d.ts.map +1 -0
  168. package/dist/ports/index.js +6 -0
  169. package/dist/ports/index.js.map +1 -0
  170. package/dist/ports/process-runner.d.ts +12 -0
  171. package/dist/ports/process-runner.d.ts.map +1 -0
  172. package/dist/ports/process-runner.js +2 -0
  173. package/dist/ports/process-runner.js.map +1 -0
  174. package/dist/ports/registry-client.d.ts +14 -0
  175. package/dist/ports/registry-client.d.ts.map +1 -0
  176. package/dist/ports/registry-client.js +2 -0
  177. package/dist/ports/registry-client.js.map +1 -0
  178. package/dist/ports/repo-client.d.ts +18 -0
  179. package/dist/ports/repo-client.d.ts.map +1 -0
  180. package/dist/ports/repo-client.js +2 -0
  181. package/dist/ports/repo-client.js.map +1 -0
  182. package/dist/report/index.d.ts +2 -0
  183. package/dist/report/index.d.ts.map +1 -0
  184. package/dist/report/index.js +2 -0
  185. package/dist/report/index.js.map +1 -0
  186. package/dist/report/report-generator.d.ts +29 -0
  187. package/dist/report/report-generator.d.ts.map +1 -0
  188. package/dist/report/report-generator.js +167 -0
  189. package/dist/report/report-generator.js.map +1 -0
  190. package/package.json +50 -0
  191. package/skills/sentinel/SKILL.md +525 -0
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { readFile } from 'node:fs/promises';
4
+ import kleur from 'kleur';
5
+ import { createDefaultSentinel } from '../factory.js';
6
+ import { startSpinner } from './spinner.js';
7
+ const program = new Command();
8
+ const TARGET_TYPES_HELP = `
9
+ Target types:
10
+ npm npm package (e.g. express, lodash@4.17.21)
11
+ github GitHub repository (e.g. owner/repo)
12
+ skill Local AI skill directory or SKILL.md path
13
+ local Any local directory to scan
14
+
15
+ Exit codes:
16
+ 0 Verification passed (decision is not BLOCK)
17
+ 1 Runtime error or install denied/failed
18
+ 2 Policy BLOCK — do not install
19
+ `;
20
+ const VERIFY_EXAMPLES = `
21
+ Examples:
22
+ sentinel verify npm express
23
+ sentinel verify npm lodash@4.17.21
24
+ sentinel verify github expressjs/express
25
+ sentinel verify skill ./my-skill
26
+ sentinel verify local ./my-project
27
+ sentinel verify npm express --json
28
+ sentinel verify npm express --markdown
29
+ sentinel verify npm express --policy ./policy.json
30
+ `;
31
+ const INSTALL_EXAMPLES = `
32
+ Examples:
33
+ sentinel install npm express
34
+ sentinel install github owner/repo
35
+ sentinel install skill ./my-skill
36
+ sentinel install npm express --yes
37
+ sentinel install npm express --json
38
+ sentinel install npm express --policy ./policy.json
39
+
40
+ Approval:
41
+ Runs verification first, then prompts [y/N] unless auto-approved.
42
+ --yes skips the prompt for non-BLOCK decisions (WARN, REQUIRE_APPROVAL, APPROVE).
43
+ BLOCK decisions cannot be overridden.
44
+ `;
45
+ program
46
+ .name('sentinel')
47
+ .description('Universal Security Verification Framework for AI Agent Installations')
48
+ .version('0.1.0')
49
+ .addHelpText('after', `
50
+ Commands:
51
+ verify Analyze a target without installing (read-only)
52
+ install Verify, prompt for approval, then install
53
+
54
+ Quick start:
55
+ sentinel verify npm express
56
+ sentinel verify github owner/repo
57
+ sentinel install skill ./my-skill --yes
58
+
59
+ Run "sentinel <command> --help" for command-specific options and examples.
60
+ ${TARGET_TYPES_HELP}`);
61
+ program
62
+ .command('verify')
63
+ .description('Verify a package, repository, skill, or other target without installing')
64
+ .argument('<type>', 'Target ecosystem: npm, github, skill, or local')
65
+ .argument('<target>', 'Package name, owner/repo, or filesystem path')
66
+ .option('--json', 'Output the full verification report as JSON (machine-readable)')
67
+ .option('--markdown', 'Output the report as Markdown')
68
+ .option('--policy <file>', 'Path to a JSON policy file (overrides default thresholds and lists)')
69
+ .option('--score-tests', 'Score findings in test/fixture files at full severity (default: down-weighted)')
70
+ .addHelpText('after', `${VERIFY_EXAMPLES}
71
+ Options (default output is a colored terminal report):
72
+ --json Structured JSON with findings, risk, policy, permissions, evidence
73
+ --markdown Markdown table suitable for docs or PR comments
74
+ --policy Custom policy: blockThreshold, warnThreshold, minConfidence,
75
+ trustedPublishers, corporateWhitelist, corporateBlacklist, etc.
76
+ --score-tests Treat dangerous code in test/fixture files at full weight
77
+ (by default such findings are shown but down-weighted)
78
+
79
+ ${TARGET_TYPES_HELP}`)
80
+ .action(async (type, target, opts) => {
81
+ try {
82
+ const format = opts.json ? 'json' : opts.markdown ? 'markdown' : 'terminal';
83
+ const policyConfig = await resolvePolicyConfig(opts.policy, opts.scoreTests);
84
+ const sentinel = createDefaultSentinel({ policyConfig, reportFormat: format });
85
+ const spinner = startSpinner(`Verifying ${type}:${target}...`);
86
+ let report;
87
+ try {
88
+ report = await sentinel.verify(type, target);
89
+ }
90
+ finally {
91
+ spinner.stop();
92
+ }
93
+ const output = sentinel.generateReport(report, format);
94
+ console.log(output);
95
+ if (report.policy.decision === 'BLOCK') {
96
+ process.exit(2);
97
+ }
98
+ }
99
+ catch (error) {
100
+ console.error(kleur.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
101
+ process.exit(1);
102
+ }
103
+ });
104
+ program
105
+ .command('install')
106
+ .description('Verify and install a target (requires approval unless auto-approved)')
107
+ .argument('<type>', 'Target ecosystem: npm, github, skill, or local')
108
+ .argument('<target>', 'Package name, owner/repo, or filesystem path')
109
+ .option('--json', 'Output the verification report as JSON instead of terminal format')
110
+ .option('--yes', 'Auto-approve installation after verification (cannot override BLOCK)')
111
+ .option('--policy <file>', 'Path to a JSON policy file (overrides default thresholds and lists)')
112
+ .option('--score-tests', 'Score findings in test/fixture files at full severity (default: down-weighted)')
113
+ .addHelpText('after', `${INSTALL_EXAMPLES}
114
+ Options:
115
+ --json Output report as JSON (terminal format is default)
116
+ --yes Skip the interactive [y/N] approval prompt when policy allows it
117
+ --policy Custom policy file (same fields as verify --policy)
118
+ --score-tests Treat dangerous code in test/fixture files at full weight
119
+
120
+ Install behavior by ecosystem:
121
+ npm npm install <name> --ignore-scripts
122
+ github git clone https://github.com/<owner>/<repo>.git
123
+ skill Verified locally — no file copy (MVP)
124
+ local Verified locally — no installation step (MVP)
125
+
126
+ ${TARGET_TYPES_HELP}`)
127
+ .action(async (type, target, opts) => {
128
+ try {
129
+ const format = opts.json ? 'json' : 'terminal';
130
+ const policyConfig = await resolvePolicyConfig(opts.policy, opts.scoreTests);
131
+ const sentinel = createDefaultSentinel({
132
+ policyConfig,
133
+ reportFormat: format,
134
+ autoApprove: opts.yes,
135
+ });
136
+ const spinner = startSpinner(`Verifying ${type}:${target}...`);
137
+ let spinnerStopped = false;
138
+ const stopSpinner = () => {
139
+ if (!spinnerStopped) {
140
+ spinner.stop();
141
+ spinnerStopped = true;
142
+ }
143
+ };
144
+ let result;
145
+ try {
146
+ result = await sentinel.install(type, target, { onVerified: stopSpinner });
147
+ }
148
+ finally {
149
+ stopSpinner();
150
+ }
151
+ const output = sentinel.generateReport(result.report, format);
152
+ console.log(output);
153
+ if (!result.success) {
154
+ console.error(kleur.red(`\n${result.message}`));
155
+ process.exit(result.report.policy.decision === 'BLOCK' ? 2 : 1);
156
+ }
157
+ console.log(kleur.green(`\n${result.message}`));
158
+ }
159
+ catch (error) {
160
+ console.error(kleur.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
161
+ process.exit(1);
162
+ }
163
+ });
164
+ async function loadPolicyFile(path) {
165
+ const content = await readFile(path, 'utf-8');
166
+ return JSON.parse(content);
167
+ }
168
+ async function resolvePolicyConfig(policyPath, scoreTests) {
169
+ const fromFile = policyPath ? await loadPolicyFile(policyPath) : undefined;
170
+ if (!scoreTests) {
171
+ return fromFile;
172
+ }
173
+ return { ...fromFile, scoreTestCodeFully: true };
174
+ }
175
+ program.parse();
176
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface Spinner {
2
+ stop(finalMessage?: string): void;
3
+ }
4
+ export declare function startSpinner(message: string): Spinner;
5
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAkCD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAKrD"}
@@ -0,0 +1,39 @@
1
+ import kleur from 'kleur';
2
+ const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
3
+ const FRAME_INTERVAL_MS = 80;
4
+ class TtySpinner {
5
+ message;
6
+ frameIndex = 0;
7
+ timer;
8
+ startedAt = Date.now();
9
+ constructor(message) {
10
+ this.message = message;
11
+ process.stderr.write('\x1B[?25l');
12
+ this.render();
13
+ this.timer = setInterval(() => this.render(), FRAME_INTERVAL_MS);
14
+ if (typeof this.timer.unref === 'function') {
15
+ this.timer.unref();
16
+ }
17
+ }
18
+ render() {
19
+ const frame = FRAMES[this.frameIndex] ?? FRAMES[0];
20
+ this.frameIndex = (this.frameIndex + 1) % FRAMES.length;
21
+ const elapsed = ((Date.now() - this.startedAt) / 1000).toFixed(1);
22
+ process.stderr.write(`\r${kleur.cyan(frame)} ${this.message} ${kleur.dim(`(${elapsed}s)`)}`);
23
+ }
24
+ stop() {
25
+ clearInterval(this.timer);
26
+ process.stderr.write('\r\x1B[K');
27
+ process.stderr.write('\x1B[?25h');
28
+ }
29
+ }
30
+ class NoopSpinner {
31
+ stop() { }
32
+ }
33
+ export function startSpinner(message) {
34
+ if (!process.stderr.isTTY) {
35
+ return new NoopSpinner();
36
+ }
37
+ return new TtySpinner(message);
38
+ }
39
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAClE,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAM7B,MAAM,UAAU;IAKe;IAJrB,UAAU,GAAG,CAAC,CAAC;IACN,KAAK,CAAiB;IACtB,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAExC,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACjE,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,MAAM;QACZ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC,CAAE,CAAC;QACpD,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACxD,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI;QACF,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;CACF;AAED,MAAM,WAAW;IACf,IAAI,KAAU,CAAC;CAChB;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,OAAO,IAAI,WAAW,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './sentinel.js';
2
+ export * from './permissions.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './sentinel.js';
2
+ export * from './permissions.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Finding } from '../domain/finding.js';
2
+ import type { Permission } from '../domain/permission.js';
3
+ export declare function buildPermissionGraph(findings: Finding[]): Permission[];
4
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/core/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,yBAAyB,CAAC;AAW1E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,CAoBtE"}
@@ -0,0 +1,28 @@
1
+ const PERMISSION_RULE_MAP = [
2
+ { ruleIds: ['spawn', 'exec', 'child-process', 'os-system', 'subprocess', 'powershell'], type: 'shell', description: 'Shell command execution' },
3
+ { ruleIds: ['hardcoded-ip', 'discord-webhook', 'telegram-bot', 'ngrok', 'cloudflare-tunnel'], type: 'network-internet', description: 'Internet network access' },
4
+ { ruleIds: ['private-ip'], type: 'network-localhost', description: 'Localhost/private network access' },
5
+ { ruleIds: ['aws-key', 'openai-key', 'anthropic-key', 'private-key', 'github-token'], type: 'secrets', description: 'Secret/credential access' },
6
+ { ruleIds: ['rm-rf'], type: 'filesystem-delete', description: 'Filesystem deletion' },
7
+ { ruleIds: ['chmod-x', 'registry-edit', 'cron', 'startup-folder'], type: 'filesystem-write', description: 'Filesystem modification' },
8
+ ];
9
+ export function buildPermissionGraph(findings) {
10
+ const permissions = [];
11
+ const seen = new Set();
12
+ for (const finding of findings) {
13
+ if (finding.positive || !finding.ruleId)
14
+ continue;
15
+ for (const mapping of PERMISSION_RULE_MAP) {
16
+ if (mapping.ruleIds.includes(finding.ruleId) && !seen.has(mapping.type)) {
17
+ seen.add(mapping.type);
18
+ permissions.push({
19
+ type: mapping.type,
20
+ description: mapping.description,
21
+ source: finding.file ?? finding.ruleId,
22
+ });
23
+ }
24
+ }
25
+ }
26
+ return permissions;
27
+ }
28
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/core/permissions.ts"],"names":[],"mappings":"AAGA,MAAM,mBAAmB,GAA4E;IACnG,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAC/I,EAAE,OAAO,EAAE,CAAC,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAChK,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,kCAAkC,EAAE;IACvG,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,0BAA0B,EAAE;IAChJ,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACrF,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,yBAAyB,EAAE;CACtI,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,QAAmB;IACtD,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,SAAS;QAElD,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACvB,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { AcquirerRegistry } from '../acquire/acquirer.js';
2
+ import type { Analyzer } from '../analyzers/analyzer.js';
3
+ import type { ReportFormat, InstallResult, VerificationReport } from '../domain/report.js';
4
+ import type { PolicyConfig } from '../engine/default-policy.js';
5
+ import type { ApprovalPrompt } from '../ports/approval-prompt.js';
6
+ import type { ProcessRunner } from '../ports/process-runner.js';
7
+ export interface SentinelOptions {
8
+ readonly acquirerRegistry: AcquirerRegistry;
9
+ readonly analyzers: Analyzer[];
10
+ readonly policyConfig?: Partial<PolicyConfig>;
11
+ readonly approvalPrompt: ApprovalPrompt;
12
+ readonly processRunner: ProcessRunner;
13
+ readonly reportFormat?: ReportFormat;
14
+ }
15
+ export declare class Sentinel {
16
+ private readonly options;
17
+ private readonly riskCalculator;
18
+ private readonly policyEngine;
19
+ private readonly reportGenerator;
20
+ private readonly policyConfig;
21
+ constructor(options: SentinelOptions);
22
+ verify(ecosystem: string, raw: string): Promise<VerificationReport>;
23
+ private buildUnverifiableReport;
24
+ install(ecosystem: string, raw: string, options?: {
25
+ forceApprove?: boolean;
26
+ onVerified?: () => void;
27
+ }): Promise<InstallResult>;
28
+ generateReport(report: VerificationReport, format?: ReportFormat): string;
29
+ private runInstaller;
30
+ }
31
+ export declare function createSentinel(options: SentinelOptions): Sentinel;
32
+ //# sourceMappingURL=sentinel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/core/sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIzD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAgB,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAIzG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9C,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAED,qBAAa,QAAQ;IAMP,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAEf,OAAO,EAAE,eAAe;IAO/C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8CzE,OAAO,CAAC,uBAAuB;IA6BzB,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,GAC5D,OAAO,CAAC,aAAa,CAAC;IAoCzB,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;YAI3D,YAAY;CAmB3B;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAEjE"}
@@ -0,0 +1,164 @@
1
+ import { cleanupArtifact } from '../acquire/acquirer.js';
2
+ import { runAnalyzers } from '../analyzers/analyzer.js';
3
+ import { isTestPath } from '../analyzers/test-path.js';
4
+ import { buildPermissionGraph } from './permissions.js';
5
+ import { parseTarget } from '../domain/target.js';
6
+ import { DEFAULT_POLICY } from '../engine/default-policy.js';
7
+ import { assessData, hasMeaningfulMetadata, unverifiableAssessment } from '../engine/data-assessment.js';
8
+ import { PolicyEngine } from '../engine/policy-engine.js';
9
+ import { RiskCalculator, TEST_FINDING_WEIGHT } from '../engine/risk-calculator.js';
10
+ import { ReportGenerator } from '../report/report-generator.js';
11
+ export class Sentinel {
12
+ options;
13
+ riskCalculator = new RiskCalculator();
14
+ policyEngine;
15
+ reportGenerator = new ReportGenerator();
16
+ policyConfig;
17
+ constructor(options) {
18
+ this.options = options;
19
+ this.policyConfig = options.policyConfig
20
+ ? { ...DEFAULT_POLICY, ...options.policyConfig }
21
+ : DEFAULT_POLICY;
22
+ this.policyEngine = new PolicyEngine(this.policyConfig);
23
+ }
24
+ async verify(ecosystem, raw) {
25
+ const start = Date.now();
26
+ const target = parseTarget(ecosystem, raw);
27
+ const acquirer = this.options.acquirerRegistry.get(target.ecosystem);
28
+ let artifact;
29
+ try {
30
+ artifact = await acquirer.acquire(target);
31
+ }
32
+ catch (error) {
33
+ const reason = error instanceof Error ? error.message : String(error);
34
+ return this.buildUnverifiableReport(target, reason, start);
35
+ }
36
+ try {
37
+ const rawFindings = await runAnalyzers(this.options.analyzers, { artifact, target });
38
+ const findings = tagTestFindings(rawFindings);
39
+ const permissions = buildPermissionGraph(findings.filter((f) => !f.isTest));
40
+ const evidence = {
41
+ hasMetadata: hasMeaningfulMetadata(artifact.metadata),
42
+ fileCount: artifact.files.length,
43
+ };
44
+ const testFindingWeight = this.policyConfig.scoreTestCodeFully ? 1 : TEST_FINDING_WEIGHT;
45
+ const risk = this.riskCalculator.calculate(findings, evidence, { testFindingWeight });
46
+ const dataAssessment = assessData(target, artifact, findings, risk, this.policyConfig);
47
+ const policy = this.policyEngine.evaluate(target, risk, findings, permissions, dataAssessment);
48
+ const criticalCount = findings.filter((f) => f.severity === 'CRITICAL' && !f.positive).length;
49
+ const summary = `${risk.level} risk (${risk.score}/100) - ${criticalCount} critical findings`;
50
+ return {
51
+ target,
52
+ findings,
53
+ risk,
54
+ policy,
55
+ permissions,
56
+ dataAssessment,
57
+ summary,
58
+ recommendedAction: recommendedActionFor(policy.decision),
59
+ scannedAt: new Date().toISOString(),
60
+ durationMs: Date.now() - start,
61
+ };
62
+ }
63
+ finally {
64
+ await cleanupArtifact(artifact);
65
+ }
66
+ }
67
+ buildUnverifiableReport(target, reason, start) {
68
+ const dataAssessment = unverifiableAssessment(`Could not acquire target: ${reason}`);
69
+ const risk = {
70
+ score: 0,
71
+ level: 'LOW',
72
+ confidence: 0,
73
+ positiveSignals: 0,
74
+ negativeSignals: 0,
75
+ };
76
+ const policy = {
77
+ decision: 'REQUIRE_APPROVAL',
78
+ reasons: ['Not enough data was gathered to verify this target automatically', ...dataAssessment.reasons],
79
+ overrides: [],
80
+ };
81
+ return {
82
+ target,
83
+ findings: [],
84
+ risk,
85
+ policy,
86
+ permissions: [],
87
+ dataAssessment,
88
+ summary: 'Could not gather data - manual review required',
89
+ recommendedAction: recommendedActionFor(policy.decision),
90
+ scannedAt: new Date().toISOString(),
91
+ durationMs: Date.now() - start,
92
+ };
93
+ }
94
+ async install(ecosystem, raw, options) {
95
+ const report = await this.verify(ecosystem, raw);
96
+ options?.onVerified?.();
97
+ if (report.policy.decision === 'BLOCK') {
98
+ return {
99
+ success: false,
100
+ message: 'Installation blocked by policy',
101
+ report,
102
+ };
103
+ }
104
+ const approved = options?.forceApprove
105
+ ? true
106
+ : await this.options.approvalPrompt.requestApproval(report);
107
+ if (!approved) {
108
+ return {
109
+ success: false,
110
+ message: 'Installation denied by user',
111
+ report,
112
+ };
113
+ }
114
+ const target = report.target;
115
+ const installResult = await this.runInstaller(target);
116
+ return {
117
+ success: installResult.exitCode === 0,
118
+ message: installResult.exitCode === 0
119
+ ? `Successfully installed ${target.ecosystem}:${target.name}`
120
+ : `Installation failed: ${installResult.stderr || installResult.stdout}`,
121
+ report,
122
+ };
123
+ }
124
+ generateReport(report, format) {
125
+ return this.reportGenerator.generate(report, format ?? this.options.reportFormat ?? 'terminal');
126
+ }
127
+ async runInstaller(target) {
128
+ const { processRunner } = this.options;
129
+ switch (target.ecosystem) {
130
+ case 'npm':
131
+ return processRunner.run('npm', ['install', target.name, '--ignore-scripts'], {
132
+ env: { npm_config_ignore_scripts: 'true' },
133
+ });
134
+ case 'github': {
135
+ const [owner, repo] = target.name.split('/');
136
+ return processRunner.run('git', ['clone', `https://github.com/${owner}/${repo}.git`]);
137
+ }
138
+ case 'skill':
139
+ case 'local':
140
+ return { exitCode: 0, stdout: 'Local skill/directory verified - no installation needed', stderr: '' };
141
+ default:
142
+ return { exitCode: 1, stdout: '', stderr: `No installer for ecosystem: ${target.ecosystem}` };
143
+ }
144
+ }
145
+ }
146
+ export function createSentinel(options) {
147
+ return new Sentinel(options);
148
+ }
149
+ function tagTestFindings(findings) {
150
+ return findings.map((finding) => finding.file && isTestPath(finding.file) ? { ...finding, isTest: true } : finding);
151
+ }
152
+ function recommendedActionFor(decision) {
153
+ switch (decision) {
154
+ case 'BLOCK':
155
+ return 'DO NOT INSTALL';
156
+ case 'REQUIRE_APPROVAL':
157
+ return 'REVIEW AND APPROVE BEFORE INSTALLING';
158
+ case 'WARN':
159
+ return 'PROCEED WITH CAUTION';
160
+ default:
161
+ return 'SAFE TO INSTALL';
162
+ }
163
+ }
164
+ //# sourceMappingURL=sentinel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentinel.js","sourceRoot":"","sources":["../../src/core/sentinel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export interface FileEntry {
2
+ readonly path: string;
3
+ readonly content: string;
4
+ readonly size: number;
5
+ }
6
+ export interface PackageMetadata {
7
+ readonly name?: string;
8
+ readonly version?: string;
9
+ readonly author?: string;
10
+ readonly maintainers?: string[];
11
+ readonly repository?: string;
12
+ readonly homepage?: string;
13
+ readonly license?: string;
14
+ readonly publishDate?: string;
15
+ readonly firstPublishDate?: string;
16
+ readonly downloadCount?: number;
17
+ readonly keywords?: string[];
18
+ readonly verifiedPublisher?: boolean;
19
+ readonly signedRelease?: boolean;
20
+ readonly scripts?: Record<string, string>;
21
+ readonly dependencies?: Record<string, string>;
22
+ readonly devDependencies?: Record<string, string>;
23
+ readonly optionalDependencies?: Record<string, string>;
24
+ readonly sourceUrl?: string;
25
+ readonly description?: string;
26
+ }
27
+ export interface Artifact {
28
+ readonly target: import('./target.js').Target;
29
+ readonly rootPath: string;
30
+ readonly files: FileEntry[];
31
+ readonly metadata: PackageMetadata;
32
+ readonly manifest?: Record<string, unknown>;
33
+ }
34
+ //# sourceMappingURL=artifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact.d.ts","sourceRoot":"","sources":["../../src/domain/artifact.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,MAAM,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../src/domain/artifact.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ export declare const SEVERITIES: readonly ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"];
2
+ export type Severity = (typeof SEVERITIES)[number];
3
+ export declare const CATEGORIES: readonly ["metadata", "source", "repository", "static-code", "dependency", "install-script", "ai-prompt", "permission", "network", "secret", "binary", "reputation", "behavioral"];
4
+ export type Category = (typeof CATEGORIES)[number];
5
+ export declare const SEVERITY_WEIGHTS: Record<Severity, number>;
6
+ export interface Finding {
7
+ readonly id: string;
8
+ readonly category: Category;
9
+ readonly severity: Severity;
10
+ readonly title: string;
11
+ readonly description: string;
12
+ readonly evidence?: string;
13
+ readonly file?: string;
14
+ readonly line?: number;
15
+ readonly ruleId?: string;
16
+ readonly positive?: boolean;
17
+ readonly isTest?: boolean;
18
+ }
19
+ export declare function createFinding(partial: Omit<Finding, 'id'> & {
20
+ id?: string;
21
+ }): Finding;
22
+ //# sourceMappingURL=finding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding.d.ts","sourceRoot":"","sources":["../../src/domain/finding.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,wDAAyD,CAAC;AACjF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,UAAU,oLAcb,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMrD,CAAC;AAEF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAKT"}
@@ -0,0 +1,30 @@
1
+ export const SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO'];
2
+ export const CATEGORIES = [
3
+ 'metadata',
4
+ 'source',
5
+ 'repository',
6
+ 'static-code',
7
+ 'dependency',
8
+ 'install-script',
9
+ 'ai-prompt',
10
+ 'permission',
11
+ 'network',
12
+ 'secret',
13
+ 'binary',
14
+ 'reputation',
15
+ 'behavioral',
16
+ ];
17
+ export const SEVERITY_WEIGHTS = {
18
+ CRITICAL: 50,
19
+ HIGH: 20,
20
+ MEDIUM: 10,
21
+ LOW: 2,
22
+ INFO: 0,
23
+ };
24
+ export function createFinding(partial) {
25
+ return {
26
+ id: partial.id ?? `${partial.category}-${partial.ruleId ?? partial.title}`.replace(/\s+/g, '-').toLowerCase(),
27
+ ...partial,
28
+ };
29
+ }
30
+ //# sourceMappingURL=finding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding.js","sourceRoot":"","sources":["../../src/domain/finding.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAGjF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,WAAW;IACX,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,YAAY;CACJ,CAAC;AAGX,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;CACR,CAAC;AAgBF,MAAM,UAAU,aAAa,CAC3B,OAA8C;IAE9C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;QAC7G,GAAG,OAAO;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './target.js';
2
+ export * from './finding.js';
3
+ export * from './risk.js';
4
+ export * from './artifact.js';
5
+ export * from './permission.js';
6
+ export * from './report.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}