@highflame/overwatch-v2 2.0.0-internal.1

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.
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Hook Installer
3
+ * Installs IDE-specific hooks that integrate with Guardian daemon
4
+ */
5
+ export type SupportedIDE = "cursor" | "claudecode" | "github_copilot" | "gemini_cli" | "codex";
6
+ interface InstallResult {
7
+ ide: string;
8
+ hooksLocation: string;
9
+ hooksInstalled: boolean;
10
+ }
11
+ /**
12
+ * Install hooks for an IDE
13
+ * @param ide IDE identifier
14
+ * @param options Optional configuration (e.g., repoPath for GitHub Copilot)
15
+ */
16
+ export declare function installHooks(ide: string, options?: {
17
+ repoPath?: string;
18
+ }): Promise<void>;
19
+ /**
20
+ * Uninstall hooks for an IDE
21
+ * @param ide IDE name
22
+ * @param silent If true, don't print messages (used by clear command)
23
+ */
24
+ export declare function uninstallHooks(ide: string, silent?: boolean): Promise<void>;
25
+ /**
26
+ * List installed hooks
27
+ * Checks IDE-native hook locations to determine if hooks are installed
28
+ */
29
+ export declare function listInstalledHooks(): Promise<InstallResult[]>;
30
+ export {};
@@ -0,0 +1,55 @@
1
+ export declare class GuardianModule {
2
+ private readonly configReader;
3
+ private httpServer;
4
+ private scanner;
5
+ private cerberusClient;
6
+ private hookPipeline;
7
+ private hookHandler;
8
+ private scanHandler;
9
+ private oauthHandler;
10
+ private skillsScanner;
11
+ private projectSkillsCache;
12
+ private static readonly PROJECT_SKILLS_CACHE_TTL;
13
+ private agentDetector;
14
+ private machineId;
15
+ private coverageInterval;
16
+ private static readonly COVERAGE_INTERVAL_MS;
17
+ private scanIngestor;
18
+ private skillsIngestor;
19
+ private adminClient;
20
+ private installationRecorder;
21
+ private pendingOAuthStates;
22
+ private readonly oauthStateTimeout;
23
+ private initialized;
24
+ private debug;
25
+ constructor(config?: {
26
+ httpPort?: number;
27
+ debug?: boolean;
28
+ });
29
+ init(): Promise<void>;
30
+ /**
31
+ * Start coverage reporting - runs on startup and every 10 minutes
32
+ */
33
+ private startCoverageReporting;
34
+ /**
35
+ * Report coverage metrics to admin API
36
+ */
37
+ private reportCoverage;
38
+ /**
39
+ * Initialize admin client for installation tracking and coverage reporting.
40
+ * Extracted from the removed initPolicyManager().
41
+ */
42
+ private initAdminClient;
43
+ private checkInstallation;
44
+ private recordInstallation;
45
+ startServer(): Promise<void>;
46
+ private runStartupSkillsScan;
47
+ private handleShutdown;
48
+ stopServer(): Promise<void>;
49
+ getPort(): number;
50
+ /**
51
+ * Scan project-level skills if not recently cached
52
+ * Called from hook handler when workspace is present in event
53
+ */
54
+ scanProjectSkillsIfNeeded(workspace: string): Promise<void>;
55
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * MCP Scanner - Runs bundled ramparts binary for MCP config scanning
3
+ *
4
+ * Supports running ramparts as a child process for local YARA scanning
5
+ * of MCP server configurations.
6
+ *
7
+ * Uses platform-loader for cross-platform binary discovery.
8
+ */
9
+ /**
10
+ * Scan result from ramparts CLI
11
+ */
12
+ export interface ScanResult {
13
+ scan_type: string;
14
+ total_servers: number;
15
+ results: ScanServerResult[];
16
+ }
17
+ export interface ScanServerResult {
18
+ server_name: string;
19
+ url?: string;
20
+ server_info?: {
21
+ name?: string;
22
+ metadata?: {
23
+ transport?: string;
24
+ };
25
+ };
26
+ tools?: unknown[];
27
+ prompts?: unknown[];
28
+ resources?: unknown[];
29
+ security_issues?: {
30
+ tool_issues?: unknown[];
31
+ };
32
+ yara_results?: YaraResult[];
33
+ }
34
+ export interface YaraResult {
35
+ status: "ok" | "warning" | "error";
36
+ target_type?: string;
37
+ rule_name?: string;
38
+ rule_metadata?: {
39
+ severity?: string;
40
+ description?: string;
41
+ };
42
+ }
43
+ /**
44
+ * MCP Scanner that uses bundled ramparts binary
45
+ */
46
+ export declare class MCPScanner {
47
+ private rampartsPath;
48
+ constructor();
49
+ /**
50
+ * Find the ramparts binary based on platform
51
+ * Uses platform-loader for cross-platform discovery.
52
+ *
53
+ * Search order:
54
+ * 1. Platform package (npm optionalDependency)
55
+ * 2. Local bin/ directory (dev mode)
56
+ * 3. ~/.overwatch/bin/
57
+ * 4. System PATH
58
+ */
59
+ private findRampartsBinary;
60
+ /**
61
+ * Check if scanner is available
62
+ */
63
+ isAvailable(): boolean;
64
+ /**
65
+ * Get the path to ramparts binary
66
+ */
67
+ getBinaryPath(): string | null;
68
+ /**
69
+ * Run MCP config scan
70
+ * @param rulesDir Optional custom YARA rules directory
71
+ */
72
+ runScan(rulesDir?: string): Promise<ScanResult>;
73
+ /**
74
+ * Parse ramparts CLI output
75
+ * Handles cases where CLI prints banner/logs before JSON
76
+ */
77
+ private parseOutput;
78
+ private getEmptyResult;
79
+ }
@@ -0,0 +1,4 @@
1
+ export declare const VERSION: string;
2
+ export declare const HIGHFLAME_API_URL = "https://api.highflame.ai";
3
+ export declare const HIGHFLAME_OAUTH_URL = "https://studio.highflame.ai";
4
+ export declare const HIGHFLAME_CERBERUS_URL = "https://cerberus.highflame.ai";
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Platform Loader
3
+ *
4
+ * Runtime platform detection and binary/module loading for @highflame/overwatch-v2.
5
+ * Follows the esbuild distribution pattern with platform-specific optionalDependencies.
6
+ *
7
+ * Loading order:
8
+ * 1. Try loading from @highflame/overwatch-{platform} package (npm install)
9
+ * 2. Fall back to local bin/
10
+ * 3. Fall back to ~/.overwatch/bin/ and system PATH
11
+ */
12
+
13
+ const path = require("path");
14
+ const fs = require("fs");
15
+ const os = require("os");
16
+
17
+ // Platform mapping: Node.js platform/arch -> package suffix and Rust target
18
+ const PLATFORM_MAP = {
19
+ 'darwin-arm64': {
20
+ package: '@highflame/overwatch-v2-darwin-arm64',
21
+ rustTarget: 'aarch64-apple-darwin',
22
+ binaryName: 'ramparts-aarch64-apple-darwin',
23
+ },
24
+ 'darwin-x64': {
25
+ package: '@highflame/overwatch-v2-darwin-x64',
26
+ rustTarget: 'x86_64-apple-darwin',
27
+ binaryName: 'ramparts-x86_64-apple-darwin',
28
+ },
29
+ 'linux-x64': {
30
+ package: '@highflame/overwatch-v2-linux-x64',
31
+ rustTarget: 'x86_64-unknown-linux-gnu',
32
+ binaryName: 'ramparts-x86_64-unknown-linux-gnu',
33
+ },
34
+ 'linux-arm64': {
35
+ package: '@highflame/overwatch-v2-linux-arm64',
36
+ rustTarget: 'aarch64-unknown-linux-gnu',
37
+ binaryName: 'ramparts-aarch64-unknown-linux-gnu',
38
+ },
39
+ "win32-x64": {
40
+ package: "@highflame/overwatch-v2-win32-x64",
41
+ rustTarget: "x86_64-pc-windows-msvc",
42
+ binaryName: "ramparts-x86_64-pc-windows-msvc.exe",
43
+ },
44
+ "win32-arm64": {
45
+ package: "@highflame/overwatch-v2-win32-arm64",
46
+ rustTarget: "aarch64-pc-windows-msvc",
47
+ binaryName: "ramparts-aarch64-pc-windows-msvc.exe",
48
+ },
49
+ };
50
+
51
+ /**
52
+ * Get current platform key (e.g., "darwin-arm64")
53
+ * @returns {string}
54
+ */
55
+ function getPlatformKey() {
56
+ return `${process.platform}-${process.arch}`;
57
+ }
58
+
59
+ /**
60
+ * Get platform configuration for current platform
61
+ * @returns {object|null}
62
+ */
63
+ function getPlatformConfig() {
64
+ const key = getPlatformKey();
65
+ return PLATFORM_MAP[key] || null;
66
+ }
67
+
68
+ /**
69
+ * Try to load the platform-specific package
70
+ * Uses indirect require to prevent bundler analysis (esbuild, webpack)
71
+ * @returns {object|null} The loaded platform package or null
72
+ */
73
+ function loadPlatformPackage() {
74
+ const config = getPlatformConfig();
75
+ if (!config) {
76
+ return null;
77
+ }
78
+
79
+ try {
80
+ // Use indirect require to prevent bundler from analyzing this
81
+ // This allows the optionalDependencies to work correctly
82
+ const dynamicRequire =
83
+ typeof __non_webpack_require__ !== "undefined"
84
+ ? __non_webpack_require__
85
+ : require;
86
+ return dynamicRequire(config.package);
87
+ } catch (error) {
88
+ // Package not installed - this is expected when using local dev setup
89
+ return null;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get the guardian package root directory
95
+ * Works from both dist/ and lib/ locations
96
+ * @returns {string}
97
+ */
98
+ function getPackageRoot() {
99
+ // This file is in lib/, so go up one level
100
+ // When bundled, __dirname will be dist/, so this still works
101
+ let currentDir = __dirname;
102
+
103
+ // Handle various directory structures
104
+ const baseName = path.basename(currentDir);
105
+ if (baseName === "lib" || baseName === "dist") {
106
+ return path.resolve(currentDir, "..");
107
+ }
108
+
109
+ // If we're deeply nested (e.g., dist/lib), go up appropriately
110
+ return path.resolve(currentDir, "..");
111
+ }
112
+
113
+ /**
114
+ * Get the path to the ramparts binary
115
+ *
116
+ * Search order:
117
+ * 1. Platform package (npm optionalDependency)
118
+ * 2. Local bin/ directory (dev mode)
119
+ * 3. ~/.overwatch/bin/
120
+ * 4. System PATH
121
+ *
122
+ * @returns {string|null} Path to binary or null if not found
123
+ */
124
+ function getRampartsBinaryPath() {
125
+ const config = getPlatformConfig();
126
+
127
+ // 1. Try platform package first
128
+ const platformPkg = loadPlatformPackage();
129
+ if (platformPkg && typeof platformPkg.getRampartsBinaryPath === "function") {
130
+ const binaryPath = platformPkg.getRampartsBinaryPath();
131
+ if (binaryPath && fs.existsSync(binaryPath)) {
132
+ return binaryPath;
133
+ }
134
+ }
135
+
136
+ // 2. Try local bin/ directory (dev mode)
137
+ const packageRoot = getPackageRoot();
138
+ const localPaths = [];
139
+ const isWindows = process.platform === "win32";
140
+ const genericBinaryName = isWindows ? "ramparts.exe" : "ramparts";
141
+
142
+ if (config) {
143
+ // Platform-specific binary name
144
+ localPaths.push(path.join(packageRoot, "bin", config.binaryName));
145
+ }
146
+
147
+ // Generic paths
148
+ localPaths.push(
149
+ path.join(packageRoot, "bin", genericBinaryName),
150
+ path.join(packageRoot, "dist", "bin", genericBinaryName),
151
+ );
152
+
153
+ for (const p of localPaths) {
154
+ if (fs.existsSync(p)) {
155
+ return p;
156
+ }
157
+ }
158
+
159
+ // 3. Try ~/.overwatch/bin/
160
+ const overwatchPaths = [];
161
+ if (config) {
162
+ overwatchPaths.push(
163
+ path.join(os.homedir(), ".overwatch", "bin", config.binaryName),
164
+ );
165
+ }
166
+ overwatchPaths.push(
167
+ path.join(os.homedir(), ".overwatch", "bin", genericBinaryName),
168
+ );
169
+
170
+ for (const p of overwatchPaths) {
171
+ if (fs.existsSync(p)) {
172
+ return p;
173
+ }
174
+ }
175
+
176
+ // 4. Try PATH as last resort
177
+ try {
178
+ const { execSync } = require("child_process");
179
+ const findCmd = isWindows
180
+ ? `where ${genericBinaryName}`
181
+ : `which ${genericBinaryName}`;
182
+
183
+ const result = execSync(findCmd, { encoding: "utf-8" }).trim();
184
+ // 'where' on Windows can return multiple lines; take the first one
185
+ const foundPath = result.split(/\r?\n/)[0];
186
+ if (foundPath && fs.existsSync(foundPath)) {
187
+ return foundPath;
188
+ }
189
+ } catch {
190
+ // Not in PATH
191
+ }
192
+
193
+ return null;
194
+ }
195
+
196
+ /**
197
+ * Check if the current platform is supported
198
+ * @returns {boolean}
199
+ */
200
+ function isPlatformSupported() {
201
+ return getPlatformConfig() !== null;
202
+ }
203
+
204
+ /**
205
+ * Get a helpful error message when platform binaries are not found
206
+ * @returns {string}
207
+ */
208
+ function getPlatformNotFoundMessage() {
209
+ const key = getPlatformKey();
210
+ const config = getPlatformConfig();
211
+
212
+ if (!config) {
213
+ return `Unsupported platform: ${key}. Supported platforms: ${Object.keys(PLATFORM_MAP).join(", ")}`;
214
+ }
215
+
216
+ return (
217
+ `Platform binaries not found for ${key}.\n` +
218
+ `\n` +
219
+ `To fix this, either:\n` +
220
+ ` 1. Install the platform package: npm install ${config.package}\n` +
221
+ ` 2. Run the native deps build: ./scripts/build-native-deps.sh\n` +
222
+ ` 3. Place binaries in ~/.overwatch/bin/\n`
223
+ );
224
+ }
225
+
226
+ module.exports = {
227
+ getPlatformKey,
228
+ getPlatformConfig,
229
+ loadPlatformPackage,
230
+ getRampartsBinaryPath,
231
+ isPlatformSupported,
232
+ getPlatformNotFoundMessage,
233
+ PLATFORM_MAP,
234
+ };
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@highflame/overwatch-v2",
3
+ "version": "2.0.0-internal.1",
4
+ "description": "Standalone security daemon for IDE-agnostic AI agent security",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "overwatch": "./bin/overwatch",
9
+ "overwatch-daemon": "./dist/daemon.js"
10
+ },
11
+ "scripts": {
12
+ "build": "node esbuild.config.mjs && tsc --emitDeclarationOnly",
13
+ "build:watch": "node esbuild.config.mjs --watch",
14
+ "typecheck": "tsc --noEmit",
15
+ "clean": "rm -rf dist",
16
+ "prebuild": "npm run clean",
17
+ "prepublishOnly": "npm run build",
18
+ "test": "jest",
19
+ "test:unit": "jest --selectProjects unit",
20
+ "test:integration": "jest --selectProjects integration"
21
+ },
22
+ "keywords": [
23
+ "security",
24
+ "validation",
25
+ "javelin",
26
+ "guardrails",
27
+ "daemon",
28
+ "ipc",
29
+ "ai-security",
30
+ "mcp",
31
+ "ide-security",
32
+ "cursor",
33
+ "claude-code"
34
+ ],
35
+ "author": "Highflame AI",
36
+ "license": "MIT",
37
+ "homepage": "https://docs.highflame.ai/",
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "tag": "internal"
41
+ },
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "dependencies": {
46
+ "commander": "^11.1.0",
47
+ "open": "^11.0.0"
48
+ },
49
+ "optionalDependencies": {
50
+ "@highflame/overwatch-v2-darwin-arm64": "2.0.0-internal.1",
51
+ "@highflame/overwatch-v2-darwin-x64": "2.0.0-internal.1",
52
+ "@highflame/overwatch-v2-linux-arm64": "2.0.0-internal.1",
53
+ "@highflame/overwatch-v2-linux-x64": "2.0.0-internal.1",
54
+ "@highflame/overwatch-v2-win32-arm64": "2.0.0-internal.1",
55
+ "@highflame/overwatch-v2-win32-x64": "2.0.0-internal.1"
56
+ },
57
+ "devDependencies": {
58
+ "@types/jest": "^30.0.0",
59
+ "@types/node": "^18.19.130",
60
+ "esbuild": "^0.20.2",
61
+ "jest": "^30.2.0",
62
+ "ts-jest": "^29.4.6",
63
+ "typescript": "^5.9.3"
64
+ },
65
+ "files": [
66
+ "dist/*.js",
67
+ "dist/*.d.ts",
68
+ "dist/bin",
69
+ "dist/hooks",
70
+ "lib",
71
+ "bin/overwatch",
72
+ "README.md",
73
+ "LICENSE"
74
+ ]
75
+ }