@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,5 @@
1
+ export * from './npm-registry-client.js';
2
+ export * from './github-repo-client.js';
3
+ export * from './node-process-runner.js';
4
+ export * from './cli-approval-prompt.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './npm-registry-client.js';
2
+ export * from './github-repo-client.js';
3
+ export * from './node-process-runner.js';
4
+ export * from './cli-approval-prompt.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ProcessResult, ProcessRunner } from '../ports/process-runner.js';
2
+ export declare class NodeProcessRunner implements ProcessRunner {
3
+ run(command: string, args: string[], options?: {
4
+ cwd?: string;
5
+ env?: Record<string, string>;
6
+ }): Promise<ProcessResult>;
7
+ }
8
+ //# sourceMappingURL=node-process-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-process-runner.d.ts","sourceRoot":"","sources":["../../src/adapters/node-process-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE/E,qBAAa,iBAAkB,YAAW,aAAa;IAC/C,GAAG,CACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GACvD,OAAO,CAAC,aAAa,CAAC;CAoB1B"}
@@ -0,0 +1,21 @@
1
+ import { spawn } from 'node:child_process';
2
+ export class NodeProcessRunner {
3
+ async run(command, args, options) {
4
+ return new Promise((resolve, reject) => {
5
+ const child = spawn(command, args, {
6
+ cwd: options?.cwd,
7
+ env: { ...process.env, ...options?.env },
8
+ shell: false,
9
+ });
10
+ let stdout = '';
11
+ let stderr = '';
12
+ child.stdout?.on('data', (data) => { stdout += data.toString(); });
13
+ child.stderr?.on('data', (data) => { stderr += data.toString(); });
14
+ child.on('error', reject);
15
+ child.on('close', (code) => {
16
+ resolve({ exitCode: code ?? 1, stdout, stderr });
17
+ });
18
+ });
19
+ }
20
+ }
21
+ //# sourceMappingURL=node-process-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-process-runner.js","sourceRoot":"","sources":["../../src/adapters/node-process-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,GAAG,CACP,OAAe,EACf,IAAc,EACd,OAAwD;QAExD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;gBACjC,GAAG,EAAE,OAAO,EAAE,GAAG;gBACjB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE;gBACxC,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3E,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAE3E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { NpmPackageInfo, OsvVulnerability, RegistryClient } from '../ports/registry-client.js';
2
+ export declare class NpmRegistryClient implements RegistryClient {
3
+ private readonly registryUrl;
4
+ constructor(registryUrl?: string);
5
+ getNpmPackage(name: string, version?: string): Promise<NpmPackageInfo>;
6
+ checkOsv(packageName: string, version: string, ecosystem: string): Promise<OsvVulnerability[]>;
7
+ }
8
+ //# sourceMappingURL=npm-registry-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-registry-client.d.ts","sourceRoot":"","sources":["../../src/adapters/npm-registry-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AA2BpG,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,WAAW,SAA+B;IAIhD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA8CtE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAmBrG"}
@@ -0,0 +1,66 @@
1
+ export class NpmRegistryClient {
2
+ registryUrl;
3
+ constructor(registryUrl = 'https://registry.npmjs.org') {
4
+ this.registryUrl = registryUrl;
5
+ }
6
+ async getNpmPackage(name, version) {
7
+ const encoded = encodeURIComponent(name).replace('%40', '@');
8
+ const url = `${this.registryUrl}/${encoded}`;
9
+ const response = await fetch(url);
10
+ if (!response.ok) {
11
+ throw new Error(`npm package not found: ${name} (${response.status})`);
12
+ }
13
+ const data = (await response.json());
14
+ const resolvedVersion = version ?? data['dist-tags'].latest;
15
+ const versionInfo = data.versions[resolvedVersion];
16
+ if (!versionInfo) {
17
+ throw new Error(`Version ${resolvedVersion} not found for ${name}`);
18
+ }
19
+ const author = typeof versionInfo.author === 'string'
20
+ ? versionInfo.author
21
+ : versionInfo.author?.name;
22
+ const repository = typeof versionInfo.repository === 'string'
23
+ ? versionInfo.repository
24
+ : versionInfo.repository?.url?.replace(/^git\+/, '').replace(/\.git$/, '');
25
+ return {
26
+ name: versionInfo.name,
27
+ version: versionInfo.version,
28
+ author,
29
+ maintainers: versionInfo.maintainers?.map((m) => m.name),
30
+ repository,
31
+ homepage: versionInfo.homepage,
32
+ license: versionInfo.license,
33
+ publishDate: data.time?.[resolvedVersion],
34
+ firstPublishDate: data.time?.created,
35
+ keywords: versionInfo.keywords,
36
+ verifiedPublisher: false,
37
+ scripts: versionInfo.scripts,
38
+ dependencies: versionInfo.dependencies,
39
+ devDependencies: versionInfo.devDependencies,
40
+ optionalDependencies: versionInfo.optionalDependencies,
41
+ description: versionInfo.description,
42
+ sourceUrl: repository,
43
+ tarballUrl: versionInfo.dist.tarball,
44
+ signedRelease: !!versionInfo.dist.integrity,
45
+ };
46
+ }
47
+ async checkOsv(packageName, version, ecosystem) {
48
+ const response = await fetch('https://api.osv.dev/v1/query', {
49
+ method: 'POST',
50
+ headers: { 'Content-Type': 'application/json' },
51
+ body: JSON.stringify({
52
+ package: { name: packageName, ecosystem },
53
+ version,
54
+ }),
55
+ });
56
+ if (!response.ok)
57
+ return [];
58
+ const data = (await response.json());
59
+ return (data.vulns ?? []).map((v) => ({
60
+ id: v.id,
61
+ summary: v.summary,
62
+ severity: v.database_specific?.severity,
63
+ }));
64
+ }
65
+ }
66
+ //# sourceMappingURL=npm-registry-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-registry-client.js","sourceRoot":"","sources":["../../src/adapters/npm-registry-client.ts"],"names":[],"mappings":"AA2BA,MAAM,OAAO,iBAAiB;IACX,WAAW,CAAS;IAErC,YAAY,WAAW,GAAG,4BAA4B;QACpD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,OAAgB;QAChD,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;QAC5D,MAAM,eAAe,GAAG,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACnD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,WAAW,eAAe,kBAAkB,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,WAAW,CAAC,MAAM,KAAK,QAAQ;YACnD,CAAC,CAAC,WAAW,CAAC,MAAM;YACpB,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC;QAE7B,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,UAAU,KAAK,QAAQ;YAC3D,CAAC,CAAC,WAAW,CAAC,UAAU;YACxB,CAAC,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE7E,OAAO;YACL,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,MAAM;YACN,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACxD,UAAU;YACV,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC;YACzC,gBAAgB,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO;YACpC,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,iBAAiB,EAAE,KAAK;YACxB,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY,EAAE,WAAW,CAAC,YAAY;YACtC,eAAe,EAAE,WAAW,CAAC,eAAe;YAC5C,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;YACtD,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,SAAS,EAAE,UAAU;YACrB,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO;YACpC,aAAa,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS;SAC5C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,WAAmB,EAAE,OAAe,EAAE,SAAiB;QACpE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,8BAA8B,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE;gBACzC,OAAO;aACR,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAE5B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkG,CAAC;QACtI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,CAAC,iBAAiB,EAAE,QAAQ;SACxC,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { AnalysisContext, Analyzer } from './analyzer.js';
2
+ export declare class AiPromptAnalyzer implements Analyzer {
3
+ readonly id = "ai-prompt";
4
+ supports(ctx: AnalysisContext): boolean;
5
+ analyze(ctx: AnalysisContext): Promise<import("../domain/finding.js").Finding[]>;
6
+ }
7
+ //# sourceMappingURL=ai-prompt-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-prompt-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/ai-prompt-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA8B/D,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,QAAQ,CAAC,EAAE,eAAe;IAE1B,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAIjC,OAAO,CAAC,GAAG,EAAE,eAAe;CAgEnC"}
@@ -0,0 +1,88 @@
1
+ import { createFinding } from '../domain/finding.js';
2
+ import { findMatchingLine } from './match-evidence.js';
3
+ import { AI_INJECTION_RULES, INVISIBLE_UNICODE, ZERO_WIDTH_CHARS } from './rules/index.js';
4
+ const PROMPT_EXTENSIONS = ['.md', '.txt', '.yaml', '.yml', '.json'];
5
+ const SKILL_FILE_PATTERN = /(?:^|\/)SKILL\.md$/i;
6
+ const GENERIC_PACKAGE_DOC_PATTERN = /(?:^|\/)(?:README|CHANGELOG|HISTORY|CONTRIBUTING|LICENSE)(?:\.\w+)?$/i;
7
+ const EXPLICIT_PROMPT_FILE_PATTERN = /(?:^|\/)(?:prompt|system-prompt|instructions)(?:\.\w+)?$|\.(?:prompt|skill)\.(?:md|txt|yaml|yml)$/i;
8
+ function isSkillTarget(ecosystem) {
9
+ return ecosystem === 'skill' || ecosystem === 'local';
10
+ }
11
+ function isPromptFile(path, ecosystem) {
12
+ if (SKILL_FILE_PATTERN.test(path) || path.toUpperCase().includes('SKILL')) {
13
+ return true;
14
+ }
15
+ if (isSkillTarget(ecosystem)) {
16
+ return PROMPT_EXTENSIONS.some((ext) => path.endsWith(ext));
17
+ }
18
+ if (GENERIC_PACKAGE_DOC_PATTERN.test(path)) {
19
+ return false;
20
+ }
21
+ return EXPLICIT_PROMPT_FILE_PATTERN.test(path);
22
+ }
23
+ export class AiPromptAnalyzer {
24
+ id = 'ai-prompt';
25
+ supports(ctx) {
26
+ return ctx.artifact.files.some((f) => isPromptFile(f.path, ctx.target.ecosystem));
27
+ }
28
+ async analyze(ctx) {
29
+ const findings = [];
30
+ const promptFiles = ctx.artifact.files.filter((f) => isPromptFile(f.path, ctx.target.ecosystem));
31
+ for (const file of promptFiles) {
32
+ for (const rule of AI_INJECTION_RULES) {
33
+ rule.pattern.lastIndex = 0;
34
+ if (rule.pattern.test(file.content)) {
35
+ const match = findMatchingLine(file.content, rule.pattern);
36
+ findings.push(createFinding({
37
+ category: 'ai-prompt',
38
+ severity: rule.severity,
39
+ title: rule.title,
40
+ description: rule.description,
41
+ ruleId: rule.id,
42
+ file: file.path,
43
+ line: match?.line,
44
+ evidence: match?.evidence,
45
+ }));
46
+ }
47
+ }
48
+ if (ZERO_WIDTH_CHARS.test(file.content)) {
49
+ findings.push(createFinding({
50
+ category: 'ai-prompt',
51
+ severity: 'CRITICAL',
52
+ title: 'Zero-width characters',
53
+ description: 'Hidden zero-width Unicode characters detected in prompt content',
54
+ ruleId: 'zero-width',
55
+ file: file.path,
56
+ }));
57
+ }
58
+ if (INVISIBLE_UNICODE.test(file.content)) {
59
+ findings.push(createFinding({
60
+ category: 'ai-prompt',
61
+ severity: 'HIGH',
62
+ title: 'Invisible Unicode characters',
63
+ description: 'Invisible Unicode characters detected in prompt content',
64
+ ruleId: 'invisible-unicode',
65
+ file: file.path,
66
+ }));
67
+ }
68
+ const htmlComments = file.content.match(/<!--[\s\S]*?-->/g);
69
+ if (htmlComments && htmlComments.length > 0) {
70
+ for (const comment of htmlComments) {
71
+ if (comment.length > 50) {
72
+ findings.push(createFinding({
73
+ category: 'ai-prompt',
74
+ severity: 'MEDIUM',
75
+ title: 'Hidden HTML comment',
76
+ description: 'Large HTML comment that may contain hidden instructions',
77
+ ruleId: 'html-comment',
78
+ file: file.path,
79
+ evidence: comment.slice(0, 100),
80
+ }));
81
+ }
82
+ }
83
+ }
84
+ }
85
+ return findings;
86
+ }
87
+ }
88
+ //# sourceMappingURL=ai-prompt-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-prompt-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/ai-prompt-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Artifact } from '../domain/artifact.js';
2
+ import type { Finding } from '../domain/finding.js';
3
+ import type { Target } from '../domain/target.js';
4
+ export interface AnalysisContext {
5
+ readonly artifact: Artifact;
6
+ readonly target: Target;
7
+ }
8
+ export interface Analyzer {
9
+ readonly id: string;
10
+ supports(ctx: AnalysisContext): boolean;
11
+ analyze(ctx: AnalysisContext): Promise<Finding[]>;
12
+ }
13
+ export declare function runAnalyzers(analyzers: Analyzer[], ctx: AnalysisContext): Promise<Finding[]>;
14
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC;IACxC,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACnD;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,QAAQ,EAAE,EACrB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,OAAO,EAAE,CAAC,CASpB"}
@@ -0,0 +1,11 @@
1
+ export async function runAnalyzers(analyzers, ctx) {
2
+ const findings = [];
3
+ for (const analyzer of analyzers) {
4
+ if (analyzer.supports(ctx)) {
5
+ const result = await analyzer.analyze(ctx);
6
+ findings.push(...result);
7
+ }
8
+ }
9
+ return findings;
10
+ }
11
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/analyzers/analyzer.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAqB,EACrB,GAAoB;IAEpB,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { AnalysisContext, Analyzer } from './analyzer.js';
2
+ import type { RegistryClient } from '../ports/registry-client.js';
3
+ export declare class DependencyAnalyzer implements Analyzer {
4
+ private readonly registry?;
5
+ readonly id = "dependency";
6
+ constructor(registry?: RegistryClient | undefined);
7
+ supports(ctx: AnalysisContext): boolean;
8
+ analyze(ctx: AnalysisContext): Promise<import("../domain/finding.js").Finding[]>;
9
+ }
10
+ //# sourceMappingURL=dependency-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/dependency-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAKlE,qBAAa,kBAAmB,YAAW,QAAQ;IAGrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAFtC,QAAQ,CAAC,EAAE,gBAAgB;gBAEE,QAAQ,CAAC,EAAE,cAAc,YAAA;IAEtD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAIjC,OAAO,CAAC,GAAG,EAAE,eAAe;CAyEnC"}
@@ -0,0 +1,79 @@
1
+ import { createFinding } from '../domain/finding.js';
2
+ const DEPENDENCY_WARNING_THRESHOLD = 50;
3
+ const DEPENDENCY_CRITICAL_THRESHOLD = 200;
4
+ export class DependencyAnalyzer {
5
+ registry;
6
+ id = 'dependency';
7
+ constructor(registry) {
8
+ this.registry = registry;
9
+ }
10
+ supports(ctx) {
11
+ return !!(ctx.artifact.metadata.dependencies || ctx.artifact.manifest);
12
+ }
13
+ async analyze(ctx) {
14
+ const findings = [];
15
+ const manifestDeps = ctx.artifact.manifest?.dependencies;
16
+ const deps = {
17
+ ...(ctx.artifact.metadata.dependencies ?? {}),
18
+ ...(manifestDeps ?? {}),
19
+ };
20
+ const depCount = Object.keys(deps).length;
21
+ if (depCount > DEPENDENCY_CRITICAL_THRESHOLD) {
22
+ findings.push(createFinding({
23
+ category: 'dependency',
24
+ severity: 'HIGH',
25
+ title: 'Excessive dependencies',
26
+ description: `Package has ${depCount} dependencies`,
27
+ ruleId: 'excessive-deps',
28
+ }));
29
+ }
30
+ else if (depCount > DEPENDENCY_WARNING_THRESHOLD) {
31
+ findings.push(createFinding({
32
+ category: 'dependency',
33
+ severity: 'MEDIUM',
34
+ title: 'Many dependencies',
35
+ description: `Package has ${depCount} dependencies`,
36
+ ruleId: 'many-deps',
37
+ }));
38
+ }
39
+ for (const [name, version] of Object.entries(deps)) {
40
+ if (version.includes('http://') || version.includes('git+http')) {
41
+ findings.push(createFinding({
42
+ category: 'dependency',
43
+ severity: 'HIGH',
44
+ title: 'Non-HTTPS dependency source',
45
+ description: `Dependency ${name} uses non-HTTPS source: ${version}`,
46
+ ruleId: 'insecure-dep-source',
47
+ }));
48
+ }
49
+ if (version.startsWith('file:') || version.startsWith('../')) {
50
+ findings.push(createFinding({
51
+ category: 'dependency',
52
+ severity: 'MEDIUM',
53
+ title: 'Local file dependency',
54
+ description: `Dependency ${name} references local file: ${version}`,
55
+ ruleId: 'local-dep',
56
+ }));
57
+ }
58
+ }
59
+ if (this.registry && ctx.artifact.metadata.name && ctx.artifact.metadata.version) {
60
+ try {
61
+ const vulns = await this.registry.checkOsv(ctx.artifact.metadata.name, ctx.artifact.metadata.version, 'npm');
62
+ for (const vuln of vulns) {
63
+ findings.push(createFinding({
64
+ category: 'dependency',
65
+ severity: vuln.severity === 'CRITICAL' ? 'CRITICAL' : 'HIGH',
66
+ title: `Known vulnerability: ${vuln.id}`,
67
+ description: vuln.summary,
68
+ ruleId: 'cve',
69
+ }));
70
+ }
71
+ }
72
+ catch {
73
+ // OSV lookup is best-effort
74
+ }
75
+ }
76
+ return findings;
77
+ }
78
+ }
79
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/dependency-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Analyzer } from './analyzer.js';
2
+ import type { RegistryClient } from '../ports/registry-client.js';
3
+ export declare function createDefaultAnalyzers(registry?: RegistryClient): Analyzer[];
4
+ export * from './analyzer.js';
5
+ export * from './metadata-analyzer.js';
6
+ export * from './source-analyzer.js';
7
+ export * from './static-code-analyzer.js';
8
+ export * from './install-script-analyzer.js';
9
+ export * from './ai-prompt-analyzer.js';
10
+ export * from './secret-analyzer.js';
11
+ export * from './dependency-analyzer.js';
12
+ export * from './network-analyzer.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAS9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,QAAQ,EAAE,CAW5E;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { AiPromptAnalyzer } from './ai-prompt-analyzer.js';
2
+ import { DependencyAnalyzer } from './dependency-analyzer.js';
3
+ import { InstallScriptAnalyzer } from './install-script-analyzer.js';
4
+ import { MetadataAnalyzer } from './metadata-analyzer.js';
5
+ import { NetworkAnalyzer } from './network-analyzer.js';
6
+ import { SecretAnalyzer } from './secret-analyzer.js';
7
+ import { SourceAnalyzer } from './source-analyzer.js';
8
+ import { StaticCodeAnalyzer } from './static-code-analyzer.js';
9
+ export function createDefaultAnalyzers(registry) {
10
+ return [
11
+ new MetadataAnalyzer(),
12
+ new SourceAnalyzer(),
13
+ new StaticCodeAnalyzer(),
14
+ new InstallScriptAnalyzer(),
15
+ new AiPromptAnalyzer(),
16
+ new SecretAnalyzer(),
17
+ new DependencyAnalyzer(registry),
18
+ new NetworkAnalyzer(),
19
+ ];
20
+ }
21
+ export * from './analyzer.js';
22
+ export * from './metadata-analyzer.js';
23
+ export * from './source-analyzer.js';
24
+ export * from './static-code-analyzer.js';
25
+ export * from './install-script-analyzer.js';
26
+ export * from './ai-prompt-analyzer.js';
27
+ export * from './secret-analyzer.js';
28
+ export * from './dependency-analyzer.js';
29
+ export * from './network-analyzer.js';
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,MAAM,UAAU,sBAAsB,CAAC,QAAyB;IAC9D,OAAO;QACL,IAAI,gBAAgB,EAAE;QACtB,IAAI,cAAc,EAAE;QACpB,IAAI,kBAAkB,EAAE;QACxB,IAAI,qBAAqB,EAAE;QAC3B,IAAI,gBAAgB,EAAE;QACtB,IAAI,cAAc,EAAE;QACpB,IAAI,kBAAkB,CAAC,QAAQ,CAAC;QAChC,IAAI,eAAe,EAAE;KACtB,CAAC;AACJ,CAAC;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AnalysisContext, Analyzer } from './analyzer.js';
2
+ export declare class InstallScriptAnalyzer implements Analyzer {
3
+ readonly id = "install-script";
4
+ supports(ctx: AnalysisContext): boolean;
5
+ analyze(ctx: AnalysisContext): Promise<import("../domain/finding.js").Finding[]>;
6
+ }
7
+ //# sourceMappingURL=install-script-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-script-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/install-script-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgB/D,qBAAa,qBAAsB,YAAW,QAAQ;IACpD,QAAQ,CAAC,EAAE,oBAAoB;IAE/B,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAIjC,OAAO,CAAC,GAAG,EAAE,eAAe;CA+CnC"}
@@ -0,0 +1,64 @@
1
+ import { createFinding } from '../domain/finding.js';
2
+ const INSTALL_SCRIPT_KEYS = ['postinstall', 'preinstall', 'prepare', 'install', 'prepublish'];
3
+ const DANGEROUS_INSTALL_PATTERNS = [
4
+ { pattern: /curl\s+[^|]+\|\s*(?:bash|sh)/gi, severity: 'CRITICAL', title: 'curl pipe to shell in install script' },
5
+ { pattern: /wget\s+[^|]+\|\s*(?:bash|sh)/gi, severity: 'CRITICAL', title: 'wget pipe to shell in install script' },
6
+ { pattern: /Invoke-WebRequest|Invoke-RestMethod/gi, severity: 'HIGH', title: 'PowerShell web request in install script' },
7
+ { pattern: /\bsudo\s+/g, severity: 'HIGH', title: 'sudo in install script' },
8
+ { pattern: /chmod\s+\+x/g, severity: 'MEDIUM', title: 'chmod +x in install script' },
9
+ { pattern: /rm\s+-rf/g, severity: 'HIGH', title: 'rm -rf in install script' },
10
+ { pattern: /npx\s+/g, severity: 'MEDIUM', title: 'npx in install script' },
11
+ { pattern: /npm\s+exec/g, severity: 'MEDIUM', title: 'npm exec in install script' },
12
+ { pattern: /docker\s+pull/g, severity: 'MEDIUM', title: 'docker pull in install script' },
13
+ { pattern: /pip\s+install/g, severity: 'MEDIUM', title: 'pip install in install script' },
14
+ ];
15
+ export class InstallScriptAnalyzer {
16
+ id = 'install-script';
17
+ supports(ctx) {
18
+ return !!ctx.artifact.metadata.scripts;
19
+ }
20
+ async analyze(ctx) {
21
+ const findings = [];
22
+ const scripts = ctx.artifact.metadata.scripts ?? {};
23
+ for (const key of INSTALL_SCRIPT_KEYS) {
24
+ const script = scripts[key];
25
+ if (!script)
26
+ continue;
27
+ findings.push(createFinding({
28
+ category: 'install-script',
29
+ severity: 'MEDIUM',
30
+ title: `Install script: ${key}`,
31
+ description: `Package defines a ${key} script`,
32
+ ruleId: `script-${key}`,
33
+ evidence: script,
34
+ }));
35
+ for (const check of DANGEROUS_INSTALL_PATTERNS) {
36
+ check.pattern.lastIndex = 0;
37
+ if (check.pattern.test(script)) {
38
+ findings.push(createFinding({
39
+ category: 'install-script',
40
+ severity: check.severity,
41
+ title: check.title,
42
+ description: `Dangerous pattern in ${key} script: ${check.title}`,
43
+ ruleId: `dangerous-${key}`,
44
+ evidence: script,
45
+ }));
46
+ }
47
+ }
48
+ }
49
+ for (const file of ctx.artifact.files) {
50
+ if (file.path.match(/postinstall\.(sh|ps1|js)$/i)) {
51
+ findings.push(createFinding({
52
+ category: 'install-script',
53
+ severity: 'HIGH',
54
+ title: 'Standalone install script file',
55
+ description: `Found install script file: ${file.path}`,
56
+ ruleId: 'standalone-script',
57
+ file: file.path,
58
+ }));
59
+ }
60
+ }
61
+ return findings;
62
+ }
63
+ }
64
+ //# sourceMappingURL=install-script-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-script-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/install-script-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const MAX_EVIDENCE_LENGTH = 120;
2
+ export declare function findMatchingLine(content: string, pattern: RegExp): {
3
+ line: number;
4
+ evidence: string;
5
+ } | undefined;
6
+ //# sourceMappingURL=match-evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match-evidence.d.ts","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAYhD"}
@@ -0,0 +1,15 @@
1
+ export const MAX_EVIDENCE_LENGTH = 120;
2
+ export function findMatchingLine(content, pattern) {
3
+ const lines = content.split('\n');
4
+ for (let i = 0; i < lines.length; i++) {
5
+ pattern.lastIndex = 0;
6
+ if (pattern.test(lines[i])) {
7
+ return {
8
+ line: i + 1,
9
+ evidence: lines[i].trim().slice(0, MAX_EVIDENCE_LENGTH),
10
+ };
11
+ }
12
+ }
13
+ return undefined;
14
+ }
15
+ //# sourceMappingURL=match-evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match-evidence.js","sourceRoot":"","sources":["../../src/analyzers/match-evidence.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,OAAe;IAEf,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YAC5B,OAAO;gBACL,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;aACzD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AnalysisContext, Analyzer } from './analyzer.js';
2
+ export declare class MetadataAnalyzer implements Analyzer {
3
+ readonly id = "metadata";
4
+ supports(): boolean;
5
+ analyze(ctx: AnalysisContext): Promise<import("../domain/finding.js").Finding[]>;
6
+ }
7
+ //# sourceMappingURL=metadata-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/metadata-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAS/D,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,QAAQ,CAAC,EAAE,cAAc;IAEzB,QAAQ,IAAI,OAAO;IAIb,OAAO,CAAC,GAAG,EAAE,eAAe;CAmGnC"}