@highflame/overwatch 1.0.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/README.md +337 -0
- package/bin/overwatch +12 -0
- package/dist/auth/cli-oauth.d.ts +13 -0
- package/dist/auth/cli-oauth.d.ts.map +1 -0
- package/dist/auth/html-utils.d.ts +20 -0
- package/dist/auth/html-utils.d.ts.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/oauth.d.ts +81 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/pkce.d.ts +26 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/token-store.d.ts +44 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/bin/overwatch +12 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5449 -0
- package/dist/cli.js.map +7 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/manager.d.ts +54 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/daemon.d.ts +11 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +6004 -0
- package/dist/daemon.js.map +7 -0
- package/dist/data/ingestor.d.ts +31 -0
- package/dist/data/ingestor.d.ts.map +1 -0
- package/dist/data/processor.d.ts +96 -0
- package/dist/data/processor.d.ts.map +1 -0
- package/dist/data/reader.d.ts +24 -0
- package/dist/data/reader.d.ts.map +1 -0
- package/dist/data/recorder.d.ts +12 -0
- package/dist/data/recorder.d.ts.map +1 -0
- package/dist/engines/cedar.d.ts +41 -0
- package/dist/engines/cedar.d.ts.map +1 -0
- package/dist/engines/remote.d.ts +21 -0
- package/dist/engines/remote.d.ts.map +1 -0
- package/dist/engines/yara.d.ts +12 -0
- package/dist/engines/yara.d.ts.map +1 -0
- package/dist/handlers/dashboard-handler.d.ts +7 -0
- package/dist/handlers/dashboard-handler.d.ts.map +1 -0
- package/dist/handlers/hook-handler.d.ts +23 -0
- package/dist/handlers/hook-handler.d.ts.map +1 -0
- package/dist/handlers/oauth-handler.d.ts +12 -0
- package/dist/handlers/oauth-handler.d.ts.map +1 -0
- package/dist/handlers/scan-handler.d.ts +13 -0
- package/dist/handlers/scan-handler.d.ts.map +1 -0
- package/dist/handlers/utils.d.ts +11 -0
- package/dist/handlers/utils.d.ts.map +1 -0
- package/dist/hooks/claudecode/hooks.json.template +20 -0
- package/dist/hooks/cursor/hooks.json.template +74 -0
- package/dist/hooks/universal-hook.sh +36 -0
- package/dist/http/server.d.ts +38 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5941 -0
- package/dist/index.js.map +7 -0
- package/dist/installer.d.ts +25 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/javelin/admin-client.d.ts +75 -0
- package/dist/javelin/admin-client.d.ts.map +1 -0
- package/dist/javelin/client.d.ts +30 -0
- package/dist/javelin/client.d.ts.map +1 -0
- package/dist/javelin/config-reader.d.ts +70 -0
- package/dist/javelin/config-reader.d.ts.map +1 -0
- package/dist/javelin/index.d.ts +5 -0
- package/dist/javelin/index.d.ts.map +1 -0
- package/dist/javelin/types.d.ts +81 -0
- package/dist/javelin/types.d.ts.map +1 -0
- package/dist/lib/policy-engine.d.ts +34 -0
- package/dist/lib/policy-engine.d.ts.map +1 -0
- package/dist/lib/policy-manager.d.ts +86 -0
- package/dist/lib/policy-manager.d.ts.map +1 -0
- package/dist/module.d.ts +52 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/pipeline/context-mapper.d.ts +16 -0
- package/dist/pipeline/context-mapper.d.ts.map +1 -0
- package/dist/pipeline/extractors/claude-extractor.d.ts +48 -0
- package/dist/pipeline/extractors/claude-extractor.d.ts.map +1 -0
- package/dist/pipeline/extractors/cursor-extractor.d.ts +44 -0
- package/dist/pipeline/extractors/cursor-extractor.d.ts.map +1 -0
- package/dist/pipeline/extractors/github-copilot-extractor.d.ts +49 -0
- package/dist/pipeline/extractors/github-copilot-extractor.d.ts.map +1 -0
- package/dist/pipeline/extractors/index.d.ts +47 -0
- package/dist/pipeline/extractors/index.d.ts.map +1 -0
- package/dist/pipeline/extractors/registry.d.ts +38 -0
- package/dist/pipeline/extractors/registry.d.ts.map +1 -0
- package/dist/pipeline/hook-pipeline.d.ts +25 -0
- package/dist/pipeline/hook-pipeline.d.ts.map +1 -0
- package/dist/policy.cedar +783 -0
- package/dist/rules/pre/command_injection.yar +60 -0
- package/dist/rules/pre/cross_origin_escalation.yar +106 -0
- package/dist/rules/pre/mcp_config_risk.yar +35 -0
- package/dist/rules/pre/path_traversal.yar +50 -0
- package/dist/rules/pre/prompt_injection.yar +101 -0
- package/dist/rules/pre/secrets_leakage.yar +100 -0
- package/dist/rules/pre/sql_injection.yar +65 -0
- package/dist/scanner.d.ts +80 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/service.d.ts +18 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/services/interface.d.ts +11 -0
- package/dist/services/interface.d.ts.map +1 -0
- package/dist/services/launchd.d.ts +12 -0
- package/dist/services/launchd.d.ts.map +1 -0
- package/dist/services/systemd.d.ts +12 -0
- package/dist/services/systemd.d.ts.map +1 -0
- package/dist/services/windows.d.ts +7 -0
- package/dist/services/windows.d.ts.map +1 -0
- package/dist/skills/index.d.ts +7 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/scanner.d.ts +44 -0
- package/dist/skills/scanner.d.ts.map +1 -0
- package/dist/skills/types.d.ts +29 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/types/config.d.ts +165 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/events.d.ts +225 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/remote-policy.d.ts +129 -0
- package/dist/types/remote-policy.d.ts.map +1 -0
- package/dist/types/requests.d.ts +45 -0
- package/dist/types/requests.d.ts.map +1 -0
- package/dist/types/responses.d.ts +60 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/ui/images/highflame-mono.png +0 -0
- package/dist/ui/views/dashboard.ejs +301 -0
- package/dist/ui/views/dashboard.js +785 -0
- package/dist/ui/views/partials/commands-table.ejs +54 -0
- package/dist/ui/views/partials/events-table.ejs +36 -0
- package/dist/ui/views/partials/filter-dropdown.ejs +12 -0
- package/dist/ui/views/partials/overview-charts.ejs +149 -0
- package/dist/ui/views/partials/scans-table.ejs +136 -0
- package/dist/ui/views/partials/sessions-table.ejs +50 -0
- package/dist/ui/views/partials/stats-grid.ejs +23 -0
- package/dist/ui/views/partials/threats-table.ejs +60 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +28 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/performance.d.ts +26 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/dist/utils/port-manager.d.ts +6 -0
- package/dist/utils/port-manager.d.ts.map +1 -0
- package/dist/yara/engine.d.ts +58 -0
- package/dist/yara/engine.d.ts.map +1 -0
- package/dist/yara/index.d.ts +5 -0
- package/dist/yara/index.d.ts.map +1 -0
- package/lib/platform-loader.js +210 -0
- package/package.json +63 -0
- package/scripts/postinstall.js +121 -0
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# Overwatch
|
|
2
|
+
|
|
3
|
+
**Overwatch** is a standalone security daemon that provides real-time threat detection and policy enforcement for AI coding assistants like Cursor, Claude Code, VS Code, Windsurf, Cline, and Aider.
|
|
4
|
+
|
|
5
|
+
## What is Overwatch?
|
|
6
|
+
|
|
7
|
+
Overwatch acts as a security layer between your IDE and AI assistants, intercepting and validating all actions (prompts, shell commands, file operations, MCP tool calls) through a multi-engine guardrail system:
|
|
8
|
+
|
|
9
|
+
- **YARA Engine**: Fast local pattern matching for secrets, injection attacks, and malicious patterns
|
|
10
|
+
- **Cedar Engine**: Policy-based authorization decisions using declarative rules
|
|
11
|
+
- **Javelin API**: Remote LLM-powered guardrails for advanced threat detection
|
|
12
|
+
|
|
13
|
+
### Key Features
|
|
14
|
+
|
|
15
|
+
- **IDE-Agnostic**: Works with any IDE via universal bash hooks
|
|
16
|
+
- **Zero Extensions Required**: Runs as a standalone system service
|
|
17
|
+
- **Real-Time Protection**: Sub-second threat detection on every action
|
|
18
|
+
- **Multi-IDE Support**: One daemon serves all IDEs simultaneously
|
|
19
|
+
- **Policy Engine**: Declarative Cedar policies for fine-grained control
|
|
20
|
+
- **Event Logging**: Complete audit trail in `~/.overwatch/events.jsonl`
|
|
21
|
+
- **Web Dashboard**: Real-time monitoring at `http://localhost:17580/dashboard`
|
|
22
|
+
- **Auto-Start**: System service (launchd/systemd) for automatic daemon startup
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Prerequisites
|
|
29
|
+
|
|
30
|
+
- **Node.js**: 18+
|
|
31
|
+
- **IDEs**: Cursor, Claude Code, VS Code (GitHub Copilot), or any IDE with hook support
|
|
32
|
+
|
|
33
|
+
### Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Install globally via npm
|
|
37
|
+
npm install -g @highflame/overwatch
|
|
38
|
+
|
|
39
|
+
# Start Overwatch daemon
|
|
40
|
+
overwatch start
|
|
41
|
+
|
|
42
|
+
# Verify daemon is running
|
|
43
|
+
overwatch status
|
|
44
|
+
# Output: ✅ Overwatch is running on port 17580
|
|
45
|
+
|
|
46
|
+
# Install hooks for your IDE
|
|
47
|
+
overwatch install cursor
|
|
48
|
+
|
|
49
|
+
# (Optional) Install as system service for auto-start
|
|
50
|
+
overwatch install-service
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**That's it!** Overwatch is now protecting your IDE.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Setup for Cursor IDE
|
|
58
|
+
|
|
59
|
+
### Step 1: Install Hooks
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
overwatch install cursor
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**What this does:**
|
|
66
|
+
|
|
67
|
+
- Starts Overwatch daemon (if not running)
|
|
68
|
+
- Copies hook scripts to `~/.overwatch/cursor/hooks/`
|
|
69
|
+
- Updates `~/.cursor/hooks.json` with Overwatch hooks
|
|
70
|
+
- Copies YARA rules and Cedar policy
|
|
71
|
+
- Creates Overwatch config at `~/.overwatch/config.json`
|
|
72
|
+
|
|
73
|
+
### Step 2: Restart Cursor
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pkill -9 Cursor
|
|
77
|
+
open -a Cursor
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Step 3: Verify Installation
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Check hooks are installed
|
|
84
|
+
cat ~/.cursor/hooks.json | jq 'keys'
|
|
85
|
+
|
|
86
|
+
# Check Overwatch is running
|
|
87
|
+
overwatch status
|
|
88
|
+
|
|
89
|
+
# Test in Cursor
|
|
90
|
+
# Open Cursor, chat with AI, watch events:
|
|
91
|
+
tail -f ~/.overwatch/events.jsonl | jq
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Cursor Hooks Installed
|
|
95
|
+
|
|
96
|
+
Overwatch installs 12 hooks for Cursor:
|
|
97
|
+
|
|
98
|
+
**Pre-execution (blocking)** - These validate actions and can block them:
|
|
99
|
+
|
|
100
|
+
- `beforeSubmitPrompt` - Validates user prompts for injection attacks
|
|
101
|
+
- `beforeShellExecution` - Validates shell commands before execution
|
|
102
|
+
- `beforeMCPExecution` - Validates MCP tool/resource access
|
|
103
|
+
- `beforeTabFileRead` - Validates file reads in tab context
|
|
104
|
+
- `beforeReadFile` - Validates file reads by AI
|
|
105
|
+
|
|
106
|
+
**Post-execution (observational)** - These record events for audit/analytics:
|
|
107
|
+
|
|
108
|
+
- `afterShellExecution` - Records shell command results
|
|
109
|
+
- `afterMCPExecution` - Records MCP tool execution results
|
|
110
|
+
- `afterFileEdit` - Records file edit operations
|
|
111
|
+
- `afterTabFileEdit` - Records tab file edit operations
|
|
112
|
+
- `afterAgentResponse` - Records agent responses
|
|
113
|
+
- `afterAgentThought` - Records agent reasoning steps
|
|
114
|
+
|
|
115
|
+
**Session:**
|
|
116
|
+
|
|
117
|
+
- `stop` - Records session stop events
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Setup for Claude Code
|
|
122
|
+
|
|
123
|
+
Claude Code supports two integration approaches:
|
|
124
|
+
|
|
125
|
+
### Option A: Plugin Installation (Recommended)
|
|
126
|
+
|
|
127
|
+
Overwatch is available as a Claude Code plugin:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Install from marketplace
|
|
131
|
+
/plugin marketplace add overwatch
|
|
132
|
+
|
|
133
|
+
# Enable the plugin
|
|
134
|
+
/overwatch:enable
|
|
135
|
+
|
|
136
|
+
# Restart the session
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This approach provides:
|
|
140
|
+
|
|
141
|
+
- Automatic updates via plugin marketplace
|
|
142
|
+
- Enterprise deployment via `managed-settings.json`
|
|
143
|
+
- Better integration with Claude Code's plugin ecosystem
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
### Claude Code Hooks Installed
|
|
147
|
+
|
|
148
|
+
Overwatch installs 3 hooks for Claude Code:
|
|
149
|
+
|
|
150
|
+
1. **UserPromptSubmit** - Validates all user prompts for injection attacks
|
|
151
|
+
2. **PreToolUse** - Validates tool use (Bash, Read, Write, etc.) before execution
|
|
152
|
+
3. **PostToolUse** - Records tool execution results (observational, non-blocking)
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Setup for GitHub Copilot CLI
|
|
157
|
+
|
|
158
|
+
GitHub Copilot CLI uses a hooks system via `.github/hooks/hooks.json`.
|
|
159
|
+
|
|
160
|
+
### Prerequisites
|
|
161
|
+
|
|
162
|
+
- **GitHub Copilot CLI** installed (`gh copilot`)
|
|
163
|
+
- **Overwatch daemon** running (see Quick Start above)
|
|
164
|
+
|
|
165
|
+
### Step 1: Install Hooks
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
overwatch install github_copilot
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**What this does:**
|
|
172
|
+
|
|
173
|
+
- Starts Overwatch daemon (if not running)
|
|
174
|
+
- Creates `hooks.json` at `~/.overwatch/github_copilot/hooks/hooks.json`
|
|
175
|
+
- Copies YARA rules and Cedar policy
|
|
176
|
+
|
|
177
|
+
### Step 2: Copy Hooks to Your Repository
|
|
178
|
+
|
|
179
|
+
Copy the generated hooks to each repository where you want Overwatch protection:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Copy hooks.json to your repository
|
|
183
|
+
mkdir -p /path/to/your/repo/.github/hooks
|
|
184
|
+
cp ~/.overwatch/github_copilot/hooks/hooks.json /path/to/your/repo/.github/hooks/
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Step 3: Verify Installation
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Check Overwatch is running
|
|
191
|
+
overwatch status
|
|
192
|
+
|
|
193
|
+
# Verify hooks file in your repo
|
|
194
|
+
cat /path/to/your/repo/.github/hooks/hooks.json | jq
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### GitHub Copilot CLI Hooks Installed
|
|
198
|
+
|
|
199
|
+
Overwatch installs 6 hooks for GitHub Copilot CLI:
|
|
200
|
+
|
|
201
|
+
**Pre-execution (blocking)**:
|
|
202
|
+
|
|
203
|
+
- `userPromptSubmitted` - Validates user prompts for injection attacks
|
|
204
|
+
- `preToolUse` - Validates tool use before execution
|
|
205
|
+
|
|
206
|
+
**Post-execution (observational)**:
|
|
207
|
+
|
|
208
|
+
- `postToolUse` - Records tool execution results
|
|
209
|
+
|
|
210
|
+
**Session management:**
|
|
211
|
+
|
|
212
|
+
- `sessionStart` - Records when CLI session starts
|
|
213
|
+
- `sessionEnd` - Records when CLI session ends
|
|
214
|
+
|
|
215
|
+
**Error handling:**
|
|
216
|
+
|
|
217
|
+
- `errorOccurred` - Records errors during execution
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## CLI Commands
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Daemon Management
|
|
225
|
+
overwatch start [--debug] # Start daemon
|
|
226
|
+
overwatch stop # Stop daemon
|
|
227
|
+
overwatch restart [--debug] # Restart daemon
|
|
228
|
+
overwatch status # Show status
|
|
229
|
+
|
|
230
|
+
# Hook Installation
|
|
231
|
+
overwatch install <ide> # Install hooks
|
|
232
|
+
overwatch uninstall <ide> # Uninstall hooks
|
|
233
|
+
overwatch hooks # List installed hooks
|
|
234
|
+
|
|
235
|
+
# System Service (Auto-start on boot)
|
|
236
|
+
overwatch install-service # Install launchd/systemd service
|
|
237
|
+
overwatch uninstall-service # Uninstall service
|
|
238
|
+
|
|
239
|
+
# Scanning
|
|
240
|
+
overwatch scan # Scan MCP servers
|
|
241
|
+
|
|
242
|
+
# Supported IDEs: cursor, claudecode, github_copilot
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Configuration
|
|
248
|
+
|
|
249
|
+
### Global Configuration
|
|
250
|
+
|
|
251
|
+
Located at `~/.overwatch/config.json`:
|
|
252
|
+
|
|
253
|
+
```json
|
|
254
|
+
{
|
|
255
|
+
"version": "2.0",
|
|
256
|
+
"createdAt": "<timestamp>",
|
|
257
|
+
"engines": {
|
|
258
|
+
"yara": {
|
|
259
|
+
"enabled": true
|
|
260
|
+
},
|
|
261
|
+
"cedar": {
|
|
262
|
+
"enabled": true
|
|
263
|
+
},
|
|
264
|
+
"javelin": {
|
|
265
|
+
"enabled": true
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
"daemon": {
|
|
269
|
+
"autoStart": true,
|
|
270
|
+
"logLevel": "info"
|
|
271
|
+
},
|
|
272
|
+
"enabled": true,
|
|
273
|
+
"ides": {
|
|
274
|
+
"cursor": {
|
|
275
|
+
"enabled": true,
|
|
276
|
+
"mode": "enforce",
|
|
277
|
+
"hooksInstalled": true,
|
|
278
|
+
"hooksPath": "~/.overwatch/cursor/hooks"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## File Locations
|
|
287
|
+
|
|
288
|
+
| Component | Path |
|
|
289
|
+
| --------------------------- | ------------------------------------------------ |
|
|
290
|
+
| **Overwatch Daemon** | |
|
|
291
|
+
| Overwatch port file | `~/.overwatch/guardian_port` |
|
|
292
|
+
| Daemon log | `~/.overwatch/guardian.log` |
|
|
293
|
+
| **Events & Data** | |
|
|
294
|
+
| Events log | `~/.overwatch/events.jsonl` |
|
|
295
|
+
| Scans log | `~/.overwatch/scans.jsonl` |
|
|
296
|
+
| **Configuration** | |
|
|
297
|
+
| Global config | `~/.overwatch/config.json` |
|
|
298
|
+
| Global YARA rules | `~/.overwatch/rules/pre/*.yar` |
|
|
299
|
+
| Global Cedar policy | `~/.overwatch/policy.cedar` |
|
|
300
|
+
| **Universal Hook** | |
|
|
301
|
+
| Universal adapter | `~/.overwatch/hooks/universal-hook.sh` |
|
|
302
|
+
| **Cursor Integration** | |
|
|
303
|
+
| Hooks config | `~/.cursor/hooks.json` |
|
|
304
|
+
| **Claude Code Integration** | |
|
|
305
|
+
| Hooks config | `~/.claude/hooks.json` |
|
|
306
|
+
| **System Service** | |
|
|
307
|
+
| launchd plist (macOS) | `~/Library/LaunchAgents/com.overwatch.plist` |
|
|
308
|
+
| systemd unit (Linux) | `~/.config/systemd/user/overwatch.service` |
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Troubleshooting
|
|
313
|
+
|
|
314
|
+
### Hooks not executing
|
|
315
|
+
|
|
316
|
+
- Verify Overwatch daemon is running: `overwatch status`
|
|
317
|
+
- Check hook installation: `overwatch hooks`
|
|
318
|
+
- Verify hooks.json syntax: `jq . ~/.cursor/hooks.json`
|
|
319
|
+
|
|
320
|
+
### Events not appearing
|
|
321
|
+
|
|
322
|
+
- Check Overwatch is running: `overwatch status`
|
|
323
|
+
- Verify port file exists: `cat ~/.overwatch/guardian_port`
|
|
324
|
+
- Check events log: `tail -f ~/.overwatch/events.jsonl | jq`
|
|
325
|
+
|
|
326
|
+
### Hooks timing out
|
|
327
|
+
|
|
328
|
+
- Default timeout is 10 seconds (configurable in hooks.json)
|
|
329
|
+
- Check Overwatch daemon is responsive: `curl http://localhost:$(cat ~/.overwatch/guardian_port)/health`
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
MIT
|
package/bin/overwatch
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Overwatch CLI Entry Point
|
|
4
|
+
* This script is the main entry point for the overwatch command
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Resolve the CLI module path relative to this script
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const cliPath = path.join(__dirname, '..', 'dist', 'cli.js');
|
|
10
|
+
|
|
11
|
+
// Load and run the CLI
|
|
12
|
+
require(cliPath);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI OAuth 2.0 PKCE flow
|
|
3
|
+
* Handles OAuth authentication flow for CLI commands
|
|
4
|
+
* Starts temporary callback server on ephemeral port
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Perform OAuth PKCE flow for CLI
|
|
8
|
+
* @param openBrowser Whether to open browser automatically (default: true)
|
|
9
|
+
* @returns User email on success
|
|
10
|
+
* @throws Error on failure
|
|
11
|
+
*/
|
|
12
|
+
export declare function performCLIOAuthFlow(openBrowser?: boolean): Promise<string>;
|
|
13
|
+
//# sourceMappingURL=cli-oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-oauth.d.ts","sourceRoot":"","sources":["../../src/auth/cli-oauth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4BH;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,GAAE,OAAc,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiDjB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML utilities for OAuth responses
|
|
3
|
+
* Provides secure HTML generation with proper escaping
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Escape HTML entities to prevent XSS attacks
|
|
7
|
+
*/
|
|
8
|
+
export declare function escapeHtml(unsafe: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate success HTML response for OAuth callback
|
|
11
|
+
* @param message Success message to display
|
|
12
|
+
* @param email Optional user email (will be escaped)
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateSuccessHtml(message: string, email?: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generate error HTML response for OAuth callback
|
|
17
|
+
* @param error Error message to display (will be escaped)
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateErrorHtml(error: string): string;
|
|
20
|
+
//# sourceMappingURL=html-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../../src/auth/html-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOjD;AA0CD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBvD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth authentication module
|
|
3
|
+
* Provides PKCE-based OAuth 2.0 authentication for Highflame
|
|
4
|
+
*/
|
|
5
|
+
export { generateCodeVerifier, generateCodeChallenge, generateState, } from "./pkce";
|
|
6
|
+
export { OAUTH_CONFIG, TOKEN_EXPIRY_SECONDS, OAuthState, TokenResponse, UserInfo, buildAuthorizationUrl, exchangeCodeForTokens, refreshAccessToken, isTokenExpired, createOAuthState, } from "./oauth";
|
|
7
|
+
export { performCLIOAuthFlow } from "./cli-oauth";
|
|
8
|
+
export { AuthStatus, saveTokens, loadTokens, clearTokens, getValidAccessToken, needsReauth, getAuthStatus, } from "./token-store";
|
|
9
|
+
export { escapeHtml, generateSuccessHtml, generateErrorHtml, } from "./html-utils";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACd,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EACL,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 flow manager for Highflame authentication
|
|
3
|
+
* Uses PKCE for secure public client authentication
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* OAuth configuration for Highflame Studio
|
|
7
|
+
*/
|
|
8
|
+
export declare const OAUTH_CONFIG: {
|
|
9
|
+
authUrl: string;
|
|
10
|
+
tokenUrl: string;
|
|
11
|
+
clientId: string;
|
|
12
|
+
scopes: string[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Token expiry: 90 days in seconds
|
|
16
|
+
*/
|
|
17
|
+
export declare const TOKEN_EXPIRY_SECONDS: number;
|
|
18
|
+
/**
|
|
19
|
+
* Pending OAuth flow state
|
|
20
|
+
*/
|
|
21
|
+
export interface OAuthState {
|
|
22
|
+
state: string;
|
|
23
|
+
codeVerifier: string;
|
|
24
|
+
redirectUri: string;
|
|
25
|
+
createdAt: number;
|
|
26
|
+
status: "pending" | "completed" | "failed" | "expired";
|
|
27
|
+
tokens?: TokenResponse;
|
|
28
|
+
error?: string;
|
|
29
|
+
userInfo?: UserInfo;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Token response from Highflame Studio API
|
|
33
|
+
*/
|
|
34
|
+
export interface TokenResponse {
|
|
35
|
+
access_token: string;
|
|
36
|
+
refresh_token?: string;
|
|
37
|
+
expires_in: number;
|
|
38
|
+
token_type: "Bearer";
|
|
39
|
+
expires_at?: number;
|
|
40
|
+
scope?: string;
|
|
41
|
+
user?: {
|
|
42
|
+
id: string;
|
|
43
|
+
email: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* User information from Highflame Studio API
|
|
48
|
+
*/
|
|
49
|
+
export interface UserInfo {
|
|
50
|
+
id: string;
|
|
51
|
+
email: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build the OAuth authorization URL with PKCE parameters
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildAuthorizationUrl(state: string, codeChallenge: string, redirectUri: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Exchange authorization code for tokens
|
|
59
|
+
* Public client flow - no client_secret required, PKCE verifier proves identity
|
|
60
|
+
*/
|
|
61
|
+
export declare function exchangeCodeForTokens(code: string, codeVerifier: string, redirectUri: string): Promise<{
|
|
62
|
+
tokens: TokenResponse;
|
|
63
|
+
userInfo: UserInfo;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Refresh access token using refresh token
|
|
67
|
+
* Placeholder for future refresh endpoint implementation
|
|
68
|
+
*/
|
|
69
|
+
export declare function refreshAccessToken(_refreshToken: string): Promise<TokenResponse | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Check if tokens are expired or about to expire
|
|
72
|
+
* @param expiresAt Unix timestamp in milliseconds
|
|
73
|
+
* @param bufferSeconds Buffer time before actual expiry (default: 1 day)
|
|
74
|
+
*/
|
|
75
|
+
export declare function isTokenExpired(expiresAt: number, bufferSeconds?: number): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Create a new OAuth flow state
|
|
78
|
+
* @param guardianPort The port Guardian daemon is running on
|
|
79
|
+
*/
|
|
80
|
+
export declare function createOAuthState(guardianPort: number): OAuthState;
|
|
81
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;CAKxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,QAAQ,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CAYR;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAyCxD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAI/B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAc,GAC5B,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAYjE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PKCE (Proof Key for Code Exchange) utilities
|
|
3
|
+
* Used for secure OAuth 2.0 flow without client_secret (public client)
|
|
4
|
+
* RFC 7636: https://tools.ietf.org/html/rfc7636
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate a cryptographically random code verifier
|
|
8
|
+
* Per RFC 7636: 43-128 characters, using unreserved characters
|
|
9
|
+
* [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
|
|
10
|
+
*
|
|
11
|
+
* We use 32 random bytes → 43 base64url characters
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateCodeVerifier(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate code challenge from verifier using S256 method
|
|
16
|
+
* challenge = BASE64URL(SHA256(verifier))
|
|
17
|
+
*
|
|
18
|
+
* S256 is more secure than plain method and required by most OAuth providers
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateCodeChallenge(verifier: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate random state parameter for CSRF protection
|
|
23
|
+
* Returns 32-character hex string (16 random bytes)
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateState(): string;
|
|
26
|
+
//# sourceMappingURL=pkce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token storage for OAuth authentication
|
|
3
|
+
* Stores tokens in ~/.overwatch/session.json (separate from config for security)
|
|
4
|
+
*/
|
|
5
|
+
import { TokenResponse, UserInfo } from "./oauth";
|
|
6
|
+
import { AuthConfig } from "../types";
|
|
7
|
+
/**
|
|
8
|
+
* Auth status response
|
|
9
|
+
*/
|
|
10
|
+
export interface AuthStatus {
|
|
11
|
+
authenticated: boolean;
|
|
12
|
+
email?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
orgName?: string;
|
|
15
|
+
expiresAt?: number;
|
|
16
|
+
expired?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Save tokens to session.json file
|
|
20
|
+
*/
|
|
21
|
+
export declare function saveTokens(tokens: TokenResponse, userInfo?: UserInfo): void;
|
|
22
|
+
/**
|
|
23
|
+
* Load tokens from session.json file
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadTokens(): AuthConfig | null;
|
|
26
|
+
/**
|
|
27
|
+
* Clear tokens by deleting session.json file
|
|
28
|
+
*/
|
|
29
|
+
export declare function clearTokens(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Get access token if valid, null if expired or missing
|
|
32
|
+
* Attempts to refresh token if expired and refresh token is available
|
|
33
|
+
*/
|
|
34
|
+
export declare function getValidAccessToken(): Promise<string | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if re-authentication is needed
|
|
37
|
+
* Returns true if tokens are expired or missing
|
|
38
|
+
*/
|
|
39
|
+
export declare function needsReauth(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Get auth status for display
|
|
42
|
+
*/
|
|
43
|
+
export declare function getAuthStatus(): AuthStatus;
|
|
44
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EACL,aAAa,EACb,QAAQ,EAGT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAStC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA0CD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAmB3E;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAWlC;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBlE;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAIrC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAc1C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Overwatch CLI Entry Point
|
|
4
|
+
* This script is the main entry point for the overwatch command
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Resolve the CLI module path relative to this script
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const cliPath = path.join(__dirname, '..', 'dist', 'cli.js');
|
|
10
|
+
|
|
11
|
+
// Load and run the CLI
|
|
12
|
+
require(cliPath);
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|