@aspect-guard/core 0.4.0 → 0.5.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/index.d.ts CHANGED
@@ -166,9 +166,46 @@ declare class ExtensionGuardScanner {
166
166
  private calculateSummary;
167
167
  }
168
168
 
169
+ /**
170
+ * IDE extension paths organized by IDE name.
171
+ * Each IDE has multiple possible paths to support:
172
+ * - Different OS (Windows, macOS, Linux)
173
+ * - Different installation methods (user, system, portable)
174
+ * - Remote development scenarios (SSH, WSL, containers)
175
+ *
176
+ * Paths use these placeholders:
177
+ * - ~ : User home directory
178
+ * - %USERPROFILE% : Windows user profile
179
+ * - %APPDATA% : Windows AppData/Roaming
180
+ * - %LOCALAPPDATA% : Windows AppData/Local
181
+ *
182
+ * References:
183
+ * - https://code.visualstudio.com/docs/editor/extension-marketplace
184
+ * - https://code.visualstudio.com/docs/remote/troubleshooting
185
+ * - https://vscodium.com/
186
+ * - https://zed.dev/docs/extensions/installing-extensions
187
+ */
169
188
  declare const IDE_PATHS: Record<string, string[]>;
189
+ /**
190
+ * Expand path placeholders to actual paths
191
+ */
170
192
  declare function expandPath(inputPath: string): string;
193
+ /**
194
+ * Detect all installed IDE extension paths
195
+ */
171
196
  declare function detectIDEPaths(): DetectedIDE[];
197
+ /**
198
+ * Get list of all supported IDE names
199
+ */
200
+ declare function getSupportedIDEs(): string[];
201
+ /**
202
+ * Check if a specific IDE is installed
203
+ */
204
+ declare function isIDEInstalled(ideName: string): boolean;
205
+ /**
206
+ * Get the extension path for a specific IDE
207
+ */
208
+ declare function getIDEExtensionPath(ideName: string): string | null;
172
209
 
173
210
  declare function readExtension(extensionPath: string): Promise<ExtensionInfo | null>;
174
211
  declare function readExtensionsFromDirectory(directoryPath: string): Promise<ExtensionInfo[]>;
@@ -710,6 +747,6 @@ declare function generateBaseline(_extensionPaths: string[], _outputPath?: strin
710
747
  errors: string[];
711
748
  }>;
712
749
 
713
- declare const VERSION = "0.4.0";
750
+ declare const VERSION = "0.5.0";
714
751
 
715
- export { ALL_POPULAR_EXTENSIONS, type AdjustFindingsOptions, type AuditReport, type BundleDetectionResult, DETECTION_RULES, type DetectedIDE, type DetectionRule, type Evidence, type ExtensionCategory, ExtensionGuardScanner, type ExtensionHash, type ExtensionInfo, type ExtensionManifest, type Finding, type FindingCategory, type FullScanReport, type HashDatabase, IDE_PATHS, type InspectOptions, type IntegrityInfo, type IntegrityResult, type IntegrityStatus, JsonReporter, MEGA_POPULAR_EXTENSIONS, MarkdownReporter, POPULAR_EXTENSIONS, type PolicyAction, type PolicyConfig, PolicyEngine, type PolicyRules, type PolicyViolation, type PopularExtension, type Reporter, type ReporterOptions, type RiskLevel, RuleEngine, type RuleEngineOptions, SEVERITY_ORDER, SarifReporter, type ScanOptions, type ScanResult, type ScanSummary, type Severity, TRUSTED_EXTENSION_IDS, TRUSTED_PUBLISHERS, VERIFIED_PUBLISHERS, VERSION, addHash, adjustFindings, categorizeExtension, clearHashCache, collectFiles, compareSeverity, computeExtensionHashes, createHashRecord, detectBundle, detectIDEPaths, expandPath, generateBaseline, getDefaultDatabasePath, getHash, getPopularityTier, isAtLeastSeverity, isBundleOutputPath, isMegaPopular, isPopular, isTrustedExtension, isTrustedPublisher, isVerifiedPublisher, loadHashDatabase, loadPolicyConfig, readExtension, readExtensionsFromDirectory, registerBuiltInRules, ruleRegistry, saveHashDatabase, sha256, shouldCollectFile, shouldReduceSeverityForBundle, verifyIntegrity };
752
+ export { ALL_POPULAR_EXTENSIONS, type AdjustFindingsOptions, type AuditReport, type BundleDetectionResult, DETECTION_RULES, type DetectedIDE, type DetectionRule, type Evidence, type ExtensionCategory, ExtensionGuardScanner, type ExtensionHash, type ExtensionInfo, type ExtensionManifest, type Finding, type FindingCategory, type FullScanReport, type HashDatabase, IDE_PATHS, type InspectOptions, type IntegrityInfo, type IntegrityResult, type IntegrityStatus, JsonReporter, MEGA_POPULAR_EXTENSIONS, MarkdownReporter, POPULAR_EXTENSIONS, type PolicyAction, type PolicyConfig, PolicyEngine, type PolicyRules, type PolicyViolation, type PopularExtension, type Reporter, type ReporterOptions, type RiskLevel, RuleEngine, type RuleEngineOptions, SEVERITY_ORDER, SarifReporter, type ScanOptions, type ScanResult, type ScanSummary, type Severity, TRUSTED_EXTENSION_IDS, TRUSTED_PUBLISHERS, VERIFIED_PUBLISHERS, VERSION, addHash, adjustFindings, categorizeExtension, clearHashCache, collectFiles, compareSeverity, computeExtensionHashes, createHashRecord, detectBundle, detectIDEPaths, expandPath, generateBaseline, getDefaultDatabasePath, getHash, getIDEExtensionPath, getPopularityTier, getSupportedIDEs, isAtLeastSeverity, isBundleOutputPath, isIDEInstalled, isMegaPopular, isPopular, isTrustedExtension, isTrustedPublisher, isVerifiedPublisher, loadHashDatabase, loadPolicyConfig, readExtension, readExtensionsFromDirectory, registerBuiltInRules, ruleRegistry, saveHashDatabase, sha256, shouldCollectFile, shouldReduceSeverityForBundle, verifyIntegrity };
package/dist/index.js CHANGED
@@ -22,27 +22,151 @@ import * as fs from "fs";
22
22
  import * as os from "os";
23
23
  import * as path from "path";
24
24
  var IDE_PATHS = {
25
- "VS Code": ["~/.vscode/extensions"],
26
- "VS Code Insiders": ["~/.vscode-insiders/extensions"],
25
+ // VS Code - Standard installation
26
+ "VS Code": [
27
+ // Linux & macOS
28
+ "~/.vscode/extensions",
29
+ // Windows
30
+ "%USERPROFILE%/.vscode/extensions",
31
+ "%USERPROFILE%\\.vscode\\extensions"
32
+ ],
33
+ // VS Code Insiders - Preview builds
34
+ "VS Code Insiders": [
35
+ // Linux & macOS
36
+ "~/.vscode-insiders/extensions",
37
+ // Windows
38
+ "%USERPROFILE%/.vscode-insiders/extensions",
39
+ "%USERPROFILE%\\.vscode-insiders\\extensions"
40
+ ],
41
+ // VS Code Server - Remote SSH connections
27
42
  "VS Code Server": ["~/.vscode-server/extensions"],
28
- Cursor: ["~/.cursor/extensions"],
29
- Windsurf: ["~/.windsurf/extensions"],
30
- Trae: ["~/.trae/extensions"],
31
- VSCodium: ["~/.vscode-oss/extensions"]
43
+ // VS Code Server Insiders - Remote SSH for Insiders
44
+ "VS Code Server Insiders": ["~/.vscode-server-insiders/extensions"],
45
+ // Cursor - AI-powered code editor (VS Code fork)
46
+ // https://cursor.com
47
+ Cursor: [
48
+ // Linux & macOS
49
+ "~/.cursor/extensions",
50
+ // Windows
51
+ "%USERPROFILE%/.cursor/extensions",
52
+ "%USERPROFILE%\\.cursor\\extensions",
53
+ // macOS alternate location
54
+ "~/Library/Application Support/Cursor/User/extensions"
55
+ ],
56
+ // Cursor Server - Remote Cursor connections
57
+ "Cursor Server": ["~/.cursor-server/extensions"],
58
+ // Windsurf - Codeium AI IDE (VS Code fork)
59
+ // https://codeium.com/windsurf
60
+ Windsurf: [
61
+ // Linux & macOS
62
+ "~/.windsurf/extensions",
63
+ // Windows
64
+ "%USERPROFILE%/.windsurf/extensions",
65
+ "%USERPROFILE%\\.windsurf\\extensions",
66
+ // macOS alternate location
67
+ "~/Library/Application Support/Windsurf/extensions"
68
+ ],
69
+ // Windsurf Server - Remote Windsurf connections
70
+ "Windsurf Server": ["~/.windsurf-server/extensions"],
71
+ // Trae - ByteDance AI IDE (VS Code fork)
72
+ // https://www.trae.ai / https://www.marscode.com
73
+ Trae: [
74
+ // Linux & macOS
75
+ "~/.trae/extensions",
76
+ // Windows
77
+ "%USERPROFILE%/.trae/extensions",
78
+ "%USERPROFILE%\\.trae\\extensions"
79
+ ],
80
+ // VSCodium - Open source VS Code without telemetry
81
+ // https://vscodium.com
82
+ VSCodium: [
83
+ // Linux & macOS
84
+ "~/.vscode-oss/extensions",
85
+ // Windows
86
+ "%USERPROFILE%/.vscode-oss/extensions",
87
+ "%USERPROFILE%\\.vscode-oss\\extensions",
88
+ // Flatpak installation (Linux)
89
+ "~/.var/app/com.vscodium.codium/data/codium/extensions"
90
+ ],
91
+ // VSCodium Insiders
92
+ "VSCodium Insiders": [
93
+ "~/.vscode-oss-insiders/extensions",
94
+ "%USERPROFILE%/.vscode-oss-insiders/extensions"
95
+ ],
96
+ // Code - OSS (open source build from Microsoft repo)
97
+ "Code - OSS": ["~/.config/Code - OSS/extensions", "~/.vscode-oss/extensions"],
98
+ // Positron - Posit's data science IDE (VS Code fork)
99
+ // https://github.com/posit-dev/positron
100
+ Positron: [
101
+ "~/.positron/extensions",
102
+ "%USERPROFILE%/.positron/extensions",
103
+ "~/Library/Application Support/Positron/extensions"
104
+ ],
105
+ // Theia - Eclipse Theia IDE (VS Code compatible)
106
+ // https://theia-ide.org
107
+ Theia: ["~/.theia/extensions", "%USERPROFILE%/.theia/extensions"],
108
+ // OpenVSCode Server - Web-based VS Code
109
+ // https://github.com/gitpod-io/openvscode-server
110
+ "OpenVSCode Server": ["~/.openvscode-server/extensions"],
111
+ // code-server - VS Code in the browser
112
+ // https://github.com/coder/code-server
113
+ "code-server": ["~/.local/share/code-server/extensions", "~/.config/code-server/extensions"],
114
+ // GitHub Codespaces (when accessed locally)
115
+ "GitHub Codespaces": ["~/.codespaces/.vscode-remote/extensions"],
116
+ // Gitpod
117
+ Gitpod: ["/workspace/.gitpod/extensions", "~/.gitpod/extensions"],
118
+ // DevPod
119
+ DevPod: ["~/.devpod/extensions"]
120
+ // Lapce - Lightning-fast native code editor (has its own extension format but partially compatible)
121
+ // https://lapce.dev
122
+ // Note: Lapce uses a different extension format, included for future compatibility
123
+ // Lapce: [
124
+ // '~/.lapce/plugins',
125
+ // '~/Library/Application Support/Lapce/plugins',
126
+ // ],
127
+ // Zed - High-performance editor (different extension format, not VS Code compatible)
128
+ // https://zed.dev
129
+ // Note: Zed uses its own extension format, not VS Code compatible
130
+ // Included as reference for potential future support
131
+ // Zed: [
132
+ // '~/Library/Application Support/Zed/extensions',
133
+ // '~/.local/share/zed/extensions',
134
+ // ],
32
135
  };
33
136
  function expandPath(inputPath) {
34
- if (inputPath.startsWith("~")) {
35
- return path.join(os.homedir(), inputPath.slice(1));
36
- }
37
- if (inputPath.includes("%USERPROFILE%")) {
38
- return inputPath.replace("%USERPROFILE%", os.homedir());
137
+ let result = inputPath;
138
+ const home = os.homedir();
139
+ if (result.startsWith("~/")) {
140
+ result = path.join(home, result.slice(2));
141
+ } else if (result.startsWith("~\\")) {
142
+ result = path.join(home, result.slice(2));
143
+ } else if (result === "~") {
144
+ result = home;
145
+ }
146
+ if (process.platform === "win32") {
147
+ result = result.replace(/%USERPROFILE%/gi, home);
148
+ result = result.replace(
149
+ /%APPDATA%/gi,
150
+ process.env.APPDATA || path.join(home, "AppData", "Roaming")
151
+ );
152
+ result = result.replace(
153
+ /%LOCALAPPDATA%/gi,
154
+ process.env.LOCALAPPDATA || path.join(home, "AppData", "Local")
155
+ );
156
+ } else {
157
+ result = result.replace(/%USERPROFILE%/gi, home);
39
158
  }
40
- return inputPath;
159
+ return path.normalize(result);
41
160
  }
42
161
  function countExtensions(dirPath) {
43
162
  try {
44
163
  const entries = fs.readdirSync(dirPath, { withFileTypes: true });
45
- return entries.filter((entry) => entry.isDirectory()).length;
164
+ return entries.filter((entry) => {
165
+ if (!entry.isDirectory()) return false;
166
+ if (entry.name.startsWith(".")) return false;
167
+ if (entry.name === "node_modules") return false;
168
+ return true;
169
+ }).length;
46
170
  } catch {
47
171
  return 0;
48
172
  }
@@ -53,17 +177,42 @@ function detectIDEPaths() {
53
177
  for (const idePath of paths) {
54
178
  const expandedPath = expandPath(idePath);
55
179
  if (fs.existsSync(expandedPath)) {
56
- detected.push({
57
- name: ideName,
58
- path: expandedPath,
59
- extensionCount: countExtensions(expandedPath)
60
- });
61
- break;
180
+ const extensionCount = countExtensions(expandedPath);
181
+ if (extensionCount > 0) {
182
+ detected.push({
183
+ name: ideName,
184
+ path: expandedPath,
185
+ extensionCount
186
+ });
187
+ break;
188
+ }
62
189
  }
63
190
  }
64
191
  }
65
192
  return detected;
66
193
  }
194
+ function getSupportedIDEs() {
195
+ return Object.keys(IDE_PATHS);
196
+ }
197
+ function isIDEInstalled(ideName) {
198
+ const paths = IDE_PATHS[ideName];
199
+ if (!paths) return false;
200
+ return paths.some((p) => {
201
+ const expanded = expandPath(p);
202
+ return fs.existsSync(expanded) && countExtensions(expanded) > 0;
203
+ });
204
+ }
205
+ function getIDEExtensionPath(ideName) {
206
+ const paths = IDE_PATHS[ideName];
207
+ if (!paths) return null;
208
+ for (const p of paths) {
209
+ const expanded = expandPath(p);
210
+ if (fs.existsSync(expanded)) {
211
+ return expanded;
212
+ }
213
+ }
214
+ return null;
215
+ }
67
216
 
68
217
  // src/scanner/extension-reader.ts
69
218
  import * as fs2 from "fs/promises";
@@ -641,7 +790,11 @@ var EXPECTED_BEHAVIORS = {
641
790
  {
642
791
  // SCM extensions may spawn git processes
643
792
  ruleIds: ["EG-CRIT-002"],
644
- matchedPatterns: ["child_process-exec", "child_process-execSync", "child_process-spawn-shell"]
793
+ matchedPatterns: [
794
+ "child_process-exec",
795
+ "child_process-execSync",
796
+ "child_process-spawn-shell"
797
+ ]
645
798
  }
646
799
  ],
647
800
  debugger: [
@@ -1996,9 +2149,7 @@ var ExtensionGuardScanner = class {
1996
2149
  minSeverity: this.options.severity
1997
2150
  });
1998
2151
  if (this.options.verifyIntegrity) {
1999
- this.hashDatabase = loadHashDatabase(
2000
- this.options.hashDatabasePath || void 0
2001
- );
2152
+ this.hashDatabase = loadHashDatabase(this.options.hashDatabasePath || void 0);
2002
2153
  }
2003
2154
  }
2004
2155
  async scan(options) {
@@ -2124,9 +2275,7 @@ var ExtensionGuardScanner = class {
2124
2275
  return Math.max(0, Math.min(100, score));
2125
2276
  }
2126
2277
  calculateRiskLevel(trustScore, findings) {
2127
- const realFindings = findings.filter(
2128
- (f) => !f.description?.includes("[Downgraded:")
2129
- );
2278
+ const realFindings = findings.filter((f) => !f.description?.includes("[Downgraded:"));
2130
2279
  if (realFindings.some((f) => f.severity === "critical")) {
2131
2280
  return "critical";
2132
2281
  }
@@ -2847,7 +2996,7 @@ var PolicyEngine = class {
2847
2996
  };
2848
2997
 
2849
2998
  // src/index.ts
2850
- var VERSION = "0.4.0";
2999
+ var VERSION = "0.5.0";
2851
3000
  export {
2852
3001
  ALL_POPULAR_EXTENSIONS,
2853
3002
  DETECTION_RULES,
@@ -2879,9 +3028,12 @@ export {
2879
3028
  generateBaseline,
2880
3029
  getDefaultDatabasePath,
2881
3030
  getHash,
3031
+ getIDEExtensionPath,
2882
3032
  getPopularityTier,
3033
+ getSupportedIDEs,
2883
3034
  isAtLeastSeverity,
2884
3035
  isBundleOutputPath,
3036
+ isIDEInstalled,
2885
3037
  isMegaPopular,
2886
3038
  isPopular,
2887
3039
  isTrustedExtension,