@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.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/bin/overwatch +12 -0
- package/dist/bin/overwatch +12 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +6295 -0
- package/dist/daemon.d.ts +10 -0
- package/dist/daemon.js +3578 -0
- package/dist/hooks/claudecode/hooks.json.template +20 -0
- package/dist/hooks/cursor/hooks.json.template +62 -0
- package/dist/hooks/universal-hook.ps1 +118 -0
- package/dist/hooks/universal-hook.sh +60 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +3429 -0
- package/dist/installer.d.ts +30 -0
- package/dist/module.d.ts +55 -0
- package/dist/scanner.d.ts +79 -0
- package/dist/version.d.ts +4 -0
- package/lib/platform-loader.js +234 -0
- package/package.json +75 -0
|
@@ -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 {};
|
package/dist/module.d.ts
ADDED
|
@@ -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,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
|
+
}
|