@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.
Files changed (156) hide show
  1. package/README.md +337 -0
  2. package/bin/overwatch +12 -0
  3. package/dist/auth/cli-oauth.d.ts +13 -0
  4. package/dist/auth/cli-oauth.d.ts.map +1 -0
  5. package/dist/auth/html-utils.d.ts +20 -0
  6. package/dist/auth/html-utils.d.ts.map +1 -0
  7. package/dist/auth/index.d.ts +10 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/oauth.d.ts +81 -0
  10. package/dist/auth/oauth.d.ts.map +1 -0
  11. package/dist/auth/pkce.d.ts +26 -0
  12. package/dist/auth/pkce.d.ts.map +1 -0
  13. package/dist/auth/token-store.d.ts +44 -0
  14. package/dist/auth/token-store.d.ts.map +1 -0
  15. package/dist/bin/overwatch +12 -0
  16. package/dist/cli.d.ts +6 -0
  17. package/dist/cli.d.ts.map +1 -0
  18. package/dist/cli.js +5449 -0
  19. package/dist/cli.js.map +7 -0
  20. package/dist/config/index.d.ts +5 -0
  21. package/dist/config/index.d.ts.map +1 -0
  22. package/dist/config/manager.d.ts +54 -0
  23. package/dist/config/manager.d.ts.map +1 -0
  24. package/dist/daemon.d.ts +11 -0
  25. package/dist/daemon.d.ts.map +1 -0
  26. package/dist/daemon.js +6004 -0
  27. package/dist/daemon.js.map +7 -0
  28. package/dist/data/ingestor.d.ts +31 -0
  29. package/dist/data/ingestor.d.ts.map +1 -0
  30. package/dist/data/processor.d.ts +96 -0
  31. package/dist/data/processor.d.ts.map +1 -0
  32. package/dist/data/reader.d.ts +24 -0
  33. package/dist/data/reader.d.ts.map +1 -0
  34. package/dist/data/recorder.d.ts +12 -0
  35. package/dist/data/recorder.d.ts.map +1 -0
  36. package/dist/engines/cedar.d.ts +41 -0
  37. package/dist/engines/cedar.d.ts.map +1 -0
  38. package/dist/engines/remote.d.ts +21 -0
  39. package/dist/engines/remote.d.ts.map +1 -0
  40. package/dist/engines/yara.d.ts +12 -0
  41. package/dist/engines/yara.d.ts.map +1 -0
  42. package/dist/handlers/dashboard-handler.d.ts +7 -0
  43. package/dist/handlers/dashboard-handler.d.ts.map +1 -0
  44. package/dist/handlers/hook-handler.d.ts +23 -0
  45. package/dist/handlers/hook-handler.d.ts.map +1 -0
  46. package/dist/handlers/oauth-handler.d.ts +12 -0
  47. package/dist/handlers/oauth-handler.d.ts.map +1 -0
  48. package/dist/handlers/scan-handler.d.ts +13 -0
  49. package/dist/handlers/scan-handler.d.ts.map +1 -0
  50. package/dist/handlers/utils.d.ts +11 -0
  51. package/dist/handlers/utils.d.ts.map +1 -0
  52. package/dist/hooks/claudecode/hooks.json.template +20 -0
  53. package/dist/hooks/cursor/hooks.json.template +74 -0
  54. package/dist/hooks/universal-hook.sh +36 -0
  55. package/dist/http/server.d.ts +38 -0
  56. package/dist/http/server.d.ts.map +1 -0
  57. package/dist/index.d.ts +8 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +5941 -0
  60. package/dist/index.js.map +7 -0
  61. package/dist/installer.d.ts +25 -0
  62. package/dist/installer.d.ts.map +1 -0
  63. package/dist/javelin/admin-client.d.ts +75 -0
  64. package/dist/javelin/admin-client.d.ts.map +1 -0
  65. package/dist/javelin/client.d.ts +30 -0
  66. package/dist/javelin/client.d.ts.map +1 -0
  67. package/dist/javelin/config-reader.d.ts +70 -0
  68. package/dist/javelin/config-reader.d.ts.map +1 -0
  69. package/dist/javelin/index.d.ts +5 -0
  70. package/dist/javelin/index.d.ts.map +1 -0
  71. package/dist/javelin/types.d.ts +81 -0
  72. package/dist/javelin/types.d.ts.map +1 -0
  73. package/dist/lib/policy-engine.d.ts +34 -0
  74. package/dist/lib/policy-engine.d.ts.map +1 -0
  75. package/dist/lib/policy-manager.d.ts +86 -0
  76. package/dist/lib/policy-manager.d.ts.map +1 -0
  77. package/dist/module.d.ts +52 -0
  78. package/dist/module.d.ts.map +1 -0
  79. package/dist/pipeline/context-mapper.d.ts +16 -0
  80. package/dist/pipeline/context-mapper.d.ts.map +1 -0
  81. package/dist/pipeline/extractors/claude-extractor.d.ts +48 -0
  82. package/dist/pipeline/extractors/claude-extractor.d.ts.map +1 -0
  83. package/dist/pipeline/extractors/cursor-extractor.d.ts +44 -0
  84. package/dist/pipeline/extractors/cursor-extractor.d.ts.map +1 -0
  85. package/dist/pipeline/extractors/github-copilot-extractor.d.ts +49 -0
  86. package/dist/pipeline/extractors/github-copilot-extractor.d.ts.map +1 -0
  87. package/dist/pipeline/extractors/index.d.ts +47 -0
  88. package/dist/pipeline/extractors/index.d.ts.map +1 -0
  89. package/dist/pipeline/extractors/registry.d.ts +38 -0
  90. package/dist/pipeline/extractors/registry.d.ts.map +1 -0
  91. package/dist/pipeline/hook-pipeline.d.ts +25 -0
  92. package/dist/pipeline/hook-pipeline.d.ts.map +1 -0
  93. package/dist/policy.cedar +783 -0
  94. package/dist/rules/pre/command_injection.yar +60 -0
  95. package/dist/rules/pre/cross_origin_escalation.yar +106 -0
  96. package/dist/rules/pre/mcp_config_risk.yar +35 -0
  97. package/dist/rules/pre/path_traversal.yar +50 -0
  98. package/dist/rules/pre/prompt_injection.yar +101 -0
  99. package/dist/rules/pre/secrets_leakage.yar +100 -0
  100. package/dist/rules/pre/sql_injection.yar +65 -0
  101. package/dist/scanner.d.ts +80 -0
  102. package/dist/scanner.d.ts.map +1 -0
  103. package/dist/service.d.ts +18 -0
  104. package/dist/service.d.ts.map +1 -0
  105. package/dist/services/interface.d.ts +11 -0
  106. package/dist/services/interface.d.ts.map +1 -0
  107. package/dist/services/launchd.d.ts +12 -0
  108. package/dist/services/launchd.d.ts.map +1 -0
  109. package/dist/services/systemd.d.ts +12 -0
  110. package/dist/services/systemd.d.ts.map +1 -0
  111. package/dist/services/windows.d.ts +7 -0
  112. package/dist/services/windows.d.ts.map +1 -0
  113. package/dist/skills/index.d.ts +7 -0
  114. package/dist/skills/index.d.ts.map +1 -0
  115. package/dist/skills/scanner.d.ts +44 -0
  116. package/dist/skills/scanner.d.ts.map +1 -0
  117. package/dist/skills/types.d.ts +29 -0
  118. package/dist/skills/types.d.ts.map +1 -0
  119. package/dist/types/config.d.ts +165 -0
  120. package/dist/types/config.d.ts.map +1 -0
  121. package/dist/types/events.d.ts +225 -0
  122. package/dist/types/events.d.ts.map +1 -0
  123. package/dist/types/index.d.ts +6 -0
  124. package/dist/types/index.d.ts.map +1 -0
  125. package/dist/types/remote-policy.d.ts +129 -0
  126. package/dist/types/remote-policy.d.ts.map +1 -0
  127. package/dist/types/requests.d.ts +45 -0
  128. package/dist/types/requests.d.ts.map +1 -0
  129. package/dist/types/responses.d.ts +60 -0
  130. package/dist/types/responses.d.ts.map +1 -0
  131. package/dist/ui/images/highflame-mono.png +0 -0
  132. package/dist/ui/views/dashboard.ejs +301 -0
  133. package/dist/ui/views/dashboard.js +785 -0
  134. package/dist/ui/views/partials/commands-table.ejs +54 -0
  135. package/dist/ui/views/partials/events-table.ejs +36 -0
  136. package/dist/ui/views/partials/filter-dropdown.ejs +12 -0
  137. package/dist/ui/views/partials/overview-charts.ejs +149 -0
  138. package/dist/ui/views/partials/scans-table.ejs +136 -0
  139. package/dist/ui/views/partials/sessions-table.ejs +50 -0
  140. package/dist/ui/views/partials/stats-grid.ejs +23 -0
  141. package/dist/ui/views/partials/threats-table.ejs +60 -0
  142. package/dist/utils/index.d.ts +3 -0
  143. package/dist/utils/index.d.ts.map +1 -0
  144. package/dist/utils/logger.d.ts +28 -0
  145. package/dist/utils/logger.d.ts.map +1 -0
  146. package/dist/utils/performance.d.ts +26 -0
  147. package/dist/utils/performance.d.ts.map +1 -0
  148. package/dist/utils/port-manager.d.ts +6 -0
  149. package/dist/utils/port-manager.d.ts.map +1 -0
  150. package/dist/yara/engine.d.ts +58 -0
  151. package/dist/yara/engine.d.ts.map +1 -0
  152. package/dist/yara/index.d.ts +5 -0
  153. package/dist/yara/index.d.ts.map +1 -0
  154. package/lib/platform-loader.js +210 -0
  155. package/package.json +63 -0
  156. package/scripts/postinstall.js +121 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Supported validation engines
3
+ */
4
+ export type ValidationEngine = "yara" | "cedar" | "guardrails";
5
+ /**
6
+ * Base validation request
7
+ */
8
+ export interface ValidationRequest {
9
+ /** Engine to use for validation */
10
+ engine: ValidationEngine;
11
+ /** Payload to validate */
12
+ payload: string;
13
+ /** Optional metadata */
14
+ metadata?: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * YARA-specific validation request
18
+ */
19
+ export interface YaraValidationRequest extends ValidationRequest {
20
+ engine: "yara";
21
+ /** YARA rules to apply (optional, uses default if not provided) */
22
+ rules?: string;
23
+ }
24
+ /**
25
+ * Cedar-specific validation request
26
+ */
27
+ export interface CedarValidationRequest extends ValidationRequest {
28
+ engine: "cedar";
29
+ /** Cedar policy to evaluate (optional, uses default if not provided) */
30
+ policy?: string;
31
+ /** Principal entity for Cedar evaluation */
32
+ principal?: string;
33
+ /** Resource entity for Cedar evaluation */
34
+ resource?: string;
35
+ /** Action to authorize */
36
+ action?: string;
37
+ }
38
+ /**
39
+ * Health check request
40
+ */
41
+ export interface HealthCheckRequest {
42
+ /** Check type */
43
+ type: "ping" | "status";
44
+ }
45
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IAEzB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,MAAM,EAAE,MAAM,CAAC;IAEf,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,MAAM,EAAE,OAAO,CAAC;IAEhB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iBAAiB;IACjB,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Base validation result
3
+ */
4
+ export interface ValidationResult {
5
+ /** Whether validation passed */
6
+ success: boolean;
7
+ /** Validation engine used */
8
+ engine: string;
9
+ /** Validation duration in milliseconds */
10
+ duration: number;
11
+ /** Error message if validation failed */
12
+ error?: string;
13
+ /** Detailed findings */
14
+ findings?: ValidationFinding[];
15
+ /** Additional metadata */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ /**
19
+ * Individual validation finding
20
+ */
21
+ export interface ValidationFinding {
22
+ /** Severity level */
23
+ severity: "low" | "medium" | "high" | "critical";
24
+ /** Finding type/category */
25
+ type: string;
26
+ /** Human-readable message */
27
+ message: string;
28
+ /** Location in payload (if applicable) */
29
+ location?: {
30
+ line?: number;
31
+ column?: number;
32
+ offset?: number;
33
+ };
34
+ /** Additional context */
35
+ context?: Record<string, unknown>;
36
+ }
37
+ /**
38
+ * Health check response
39
+ */
40
+ export interface HealthCheckResponse {
41
+ /** Daemon status */
42
+ status: "healthy" | "degraded" | "unhealthy";
43
+ /** Uptime in milliseconds */
44
+ uptime: number;
45
+ /** System info */
46
+ system?: {
47
+ platform: string;
48
+ nodeVersion: string;
49
+ memory: {
50
+ heapUsed: number;
51
+ heapTotal: number;
52
+ };
53
+ };
54
+ /** Javelin API connectivity status */
55
+ javelin?: {
56
+ connected: boolean;
57
+ error?: string;
58
+ };
59
+ }
60
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/types/responses.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IAEjB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IAEf,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IAEjB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,wBAAwB;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAE/B,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qBAAqB;IACrB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAEjD,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAEhB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAE7C,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IAEf,kBAAkB;IAClB,MAAM,CAAC,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE;YACN,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IAEF,sCAAsC;IACtC,OAAO,CAAC,EAAE;QACR,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH"}
@@ -0,0 +1,301 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Javelin Rampart | Overwatch Dashboard</title>
7
+
8
+ <!-- External Dependencies -->
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
11
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono&display=swap" rel="stylesheet">
12
+
13
+ <!-- Tailwind Config -->
14
+ <script>
15
+ tailwind.config = {
16
+ darkMode: 'class',
17
+ theme: {
18
+ extend: {
19
+ fontFamily: {
20
+ sans: ['Inter', 'sans-serif'],
21
+ mono: ['JetBrains Mono', 'monospace'],
22
+ },
23
+ colors: { zinc: { 850: '#1f1f22', 950: '#09090b' } }
24
+ }
25
+ }
26
+ }
27
+ </script>
28
+
29
+ <style>
30
+ /* Base Styles */
31
+ body {
32
+ background-color: #ffffff;
33
+ color: #09090b;
34
+ transition: background-color 0.2s, color 0.2s;
35
+ }
36
+ .dark body {
37
+ background-color: #09090b;
38
+ color: #fafafa;
39
+ }
40
+
41
+ /* Tab System */
42
+ .tab-content { display: none; }
43
+ .tab-content.active { display: block; }
44
+ .tab-btn.active {
45
+ background-color: #e4e4e7;
46
+ color: #09090b;
47
+ border-bottom: 2px solid #09090b;
48
+ }
49
+ .dark .tab-btn.active {
50
+ background-color: #27272a;
51
+ color: white;
52
+ border-bottom-color: white;
53
+ }
54
+
55
+ /* Scrollbar */
56
+ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
57
+ .custom-scrollbar::-webkit-scrollbar-track {
58
+ background: #f4f4f5;
59
+ transition: background 0.2s;
60
+ }
61
+ .dark .custom-scrollbar::-webkit-scrollbar-track {
62
+ background: #09090b;
63
+ }
64
+ .custom-scrollbar::-webkit-scrollbar-thumb {
65
+ background: #d4d4d8;
66
+ border-radius: 10px;
67
+ transition: background 0.2s;
68
+ }
69
+ .dark .custom-scrollbar::-webkit-scrollbar-thumb {
70
+ background: #27272a;
71
+ }
72
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
73
+ background: #a1a1aa;
74
+ }
75
+ .dark .custom-scrollbar::-webkit-scrollbar-thumb:hover {
76
+ background: #3f3f46;
77
+ }
78
+
79
+ /* Modal */
80
+ .modal-overlay {
81
+ background-color: rgba(0, 0, 0, 0.4);
82
+ backdrop-filter: blur(4px);
83
+ transition: background-color 0.2s;
84
+ }
85
+ .dark .modal-overlay {
86
+ background-color: rgba(0, 0, 0, 0.7);
87
+ }
88
+ .modal-content { box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); }
89
+
90
+ /* Chat Bubbles */
91
+ .chat-bubble { position: relative; max-width: 85%; }
92
+ .chat-bubble::before { content: ""; position: absolute; top: 12px; width: 0; height: 0; border: 6px solid transparent; }
93
+ .chat-bubble.user::before { right: -12px; border-left-color: #d4d4d8; }
94
+ .dark .chat-bubble.user::before { border-left-color: #3f3f46; }
95
+ .chat-bubble.agent::before { left: -12px; border-right-color: #e4e4e7; }
96
+ .dark .chat-bubble.agent::before { border-right-color: #27272a; }
97
+
98
+ /* Theme Toggle Animation */
99
+ .theme-toggle {
100
+ transition: transform 0.3s ease;
101
+ }
102
+ .theme-toggle:hover {
103
+ transform: scale(1.1);
104
+ }
105
+ </style>
106
+ </head>
107
+
108
+ <body class="font-sans antialiased h-screen flex flex-col">
109
+ <!-- Modal Container -->
110
+ <div id="modal-container" class="fixed inset-0 z-50 hidden modal-overlay flex items-center justify-center p-4">
111
+ <div class="bg-white dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-xl w-full max-w-5xl h-[85vh] flex flex-col modal-content relative overflow-hidden transition-colors">
112
+ <button onclick="Dashboard.closeModal()" class="absolute top-4 right-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white p-2 rounded-full hover:bg-zinc-100 dark:hover:bg-zinc-800 z-10 transition-colors">
113
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
114
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
115
+ </svg>
116
+ </button>
117
+ <div id="modal-body" class="flex-1 flex flex-col h-full overflow-hidden"></div>
118
+ </div>
119
+ </div>
120
+
121
+ <!-- Event Detail Modal -->
122
+ <div id="modal-event-detail" class="fixed inset-0 z-50 hidden modal-overlay flex items-center justify-center p-4">
123
+ <div class="bg-white dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-xl w-full max-w-5xl h-[85vh] flex flex-col modal-content relative overflow-hidden transition-colors">
124
+ <button onclick="Dashboard.closeEventDetailModal()" class="absolute top-4 right-4 text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white p-2 rounded-full hover:bg-zinc-100 dark:hover:bg-zinc-800 z-10 transition-colors">
125
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
126
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
127
+ </svg>
128
+ </button>
129
+ <div id="modal-body-event" class="flex-1 flex flex-col h-full overflow-hidden"></div>
130
+ </div>
131
+ </div>
132
+
133
+ <div class="flex h-full overflow-hidden">
134
+ <!-- Sidebar -->
135
+ <aside class="w-64 bg-white dark:bg-zinc-950 border-r border-zinc-200 dark:border-zinc-800 flex flex-col flex-shrink-0 transition-colors">
136
+ <!-- Logo -->
137
+ <div class="p-6 border-b border-zinc-200 dark:border-zinc-800 flex items-center gap-3 transition-colors">
138
+ <div class="w-8 h-8 rounded flex items-center justify-center overflow-hidden">
139
+ <img src="/images/highflame-mono.png" alt="HighFlame" class="w-8 h-8 dark:hidden" />
140
+ <img src="/images/highflame-mono.png" alt="HighFlame" class="w-8 h-8 hidden dark:block" />
141
+ </div>
142
+ <div>
143
+ <h1 class="font-bold text-sm tracking-tight text-zinc-900 dark:text-white">HighFlame</h1>
144
+ <p class="text-[10px] text-zinc-500 dark:text-zinc-400 font-medium uppercase tracking-widest">Overwatch</p>
145
+ </div>
146
+ </div>
147
+
148
+ <!-- Navigation -->
149
+ <nav class="flex-1 p-4 space-y-1">
150
+ <button data-tab="overview" class="tab-btn active w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
151
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v12a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v12a2 2 0 01-2 2h-2a2 2 0 01-2-2V6z"/></svg>
152
+ Overview
153
+ </button>
154
+ <button data-tab="sessions" class="tab-btn w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
155
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
156
+ Sessions
157
+ </button>
158
+ <button data-tab="threats" class="tab-btn w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
159
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
160
+ Threats
161
+ </button>
162
+ <button data-tab="commands" class="tab-btn w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
163
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
164
+ Command Analysis
165
+ </button>
166
+ <button data-tab="events" class="tab-btn w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
167
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
168
+ All Events
169
+ </button>
170
+ <button data-tab="scans" class="tab-btn w-full flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-md transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-900 text-zinc-600 dark:text-zinc-400">
171
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
172
+ MCP Scans
173
+ </button>
174
+ </nav>
175
+
176
+ <!-- Footer Status -->
177
+ <div class="p-4 border-t border-zinc-200 dark:border-zinc-800 transition-colors">
178
+ <div class="bg-zinc-100 dark:bg-zinc-900/50 rounded-lg p-3 space-y-2 transition-colors">
179
+ <p class="text-[10px] font-bold text-zinc-600 dark:text-zinc-500 uppercase">Overwatch Engine</p>
180
+ <div class="flex items-center justify-between">
181
+ <span class="text-xs font-medium text-zinc-700 dark:text-zinc-300">Status</span>
182
+ <span class="flex items-center gap-1.5 text-[10px] font-bold text-green-600 dark:text-green-500 uppercase">
183
+ <span class="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"></span>
184
+ Healthy
185
+ </span>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ </aside>
190
+
191
+ <!-- Main Content -->
192
+ <main class="flex-1 flex flex-col overflow-hidden bg-white dark:bg-black transition-colors">
193
+ <!-- Topbar -->
194
+ <header class="h-14 border-b border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 flex items-center justify-between px-8 flex-shrink-0 transition-colors">
195
+ <div class="flex items-center gap-4">
196
+ <h2 id="view-title" class="text-sm font-semibold text-zinc-900 dark:text-white">Overview</h2>
197
+ <div class="h-4 w-[1px] bg-zinc-300 dark:bg-zinc-800"></div>
198
+ <p class="text-xs text-zinc-600 dark:text-zinc-500" id="current-date"></p>
199
+ </div>
200
+ <div class="flex items-center gap-3">
201
+ <!-- Theme Toggle -->
202
+ <button id="theme-toggle" class="theme-toggle p-2 rounded-lg bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 transition-colors" title="Toggle theme">
203
+ <!-- Sun Icon (Light Mode) -->
204
+ <svg id="theme-icon-light" class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24">
205
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/>
206
+ </svg>
207
+ <!-- Moon Icon (Dark Mode) -->
208
+ <svg id="theme-icon-dark" class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
209
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
210
+ </svg>
211
+ </button>
212
+ <div class="flex -space-x-2">
213
+ <% if (data.installation.cursor.installed) { %>
214
+ <div class="w-6 h-6 rounded-full bg-zinc-200 dark:bg-zinc-800 border-2 border-white dark:border-zinc-950 flex items-center justify-center p-1" title="Cursor: Installed">
215
+ <svg viewBox="0 0 24 24" fill="currentColor" class="text-zinc-700 dark:text-white"><path d="M12 0l-12 12h12v12l12-12h-12v-12z"/></svg>
216
+ </div>
217
+ <% } %>
218
+ <% if (data.installation.claudecode.installed) { %>
219
+ <div class="w-6 h-6 rounded-full bg-zinc-200 dark:bg-zinc-800 border-2 border-white dark:border-zinc-950 flex items-center justify-center p-1" title="Claude Code: Installed">
220
+ <svg viewBox="0 0 24 24" fill="currentColor" class="text-zinc-700 dark:text-white"><path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z"/></svg>
221
+ </div>
222
+ <% } %>
223
+ <% if (data.installation.github_copilot.installed) { %>
224
+ <div class="w-6 h-6 rounded-full bg-zinc-200 dark:bg-zinc-800 border-2 border-white dark:border-zinc-950 flex items-center justify-center p-1" title="GitHub Copilot: Installed">
225
+ <svg viewBox="0 0 24 24" fill="currentColor" class="text-violet-600 dark:text-violet-400"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
226
+ </div>
227
+ <% } %>
228
+ </div>
229
+ </div>
230
+ </header>
231
+
232
+ <!-- Scrollable Content Area -->
233
+ <div class="flex-1 overflow-y-auto custom-scrollbar p-8">
234
+
235
+ <!-- ========== OVERVIEW TAB ========== -->
236
+ <div id="overview" class="tab-content active space-y-8">
237
+ <%- include('partials/stats-grid', { stats: data.stats }) %>
238
+ <%- include('partials/overview-charts', {
239
+ topCursorHooks: data.topCursorHooks,
240
+ topClaudeTools: data.topClaudeTools,
241
+ topGitHubCopilotHooks: data.topGitHubCopilotHooks,
242
+ installation: data.installation
243
+ }) %>
244
+ </div>
245
+
246
+ <!-- ========== SESSIONS TAB ========== -->
247
+ <div id="sessions" class="tab-content">
248
+ <%- include('partials/filter-dropdown', { tableId: 'session-table' }) %>
249
+ <%- include('partials/sessions-table', { sessions: data.sessions }) %>
250
+ </div>
251
+
252
+ <!-- ========== THREATS TAB ========== -->
253
+ <div id="threats" class="tab-content space-y-6">
254
+ <%- include('partials/filter-dropdown', { tableId: 'threat-table' }) %>
255
+ <%- include('partials/threats-table', { threats: data.threats }) %>
256
+ </div>
257
+
258
+ <!-- ========== COMMANDS TAB ========== -->
259
+ <div id="commands" class="tab-content">
260
+ <%- include('partials/filter-dropdown', { tableId: 'command-table' }) %>
261
+ <%- include('partials/commands-table', { commands: data.commands }) %>
262
+ </div>
263
+
264
+ <!-- ========== EVENTS TAB ========== -->
265
+ <div id="events" class="tab-content">
266
+ <%- include('partials/filter-dropdown', { tableId: 'event-table' }) %>
267
+ <%- include('partials/events-table', { events: data.events }) %>
268
+ </div>
269
+
270
+ <!-- ========== MCP SCANS TAB ========== -->
271
+ <div id="scans" class="tab-content">
272
+ <%- include('partials/filter-dropdown', { tableId: 'scan-table' }) %>
273
+ <%- include('partials/scans-table', { scans: data.scans }) %>
274
+ </div>
275
+ </div>
276
+ </main>
277
+ </div>
278
+
279
+ <!-- Dashboard Client Script -->
280
+ <script src="/dashboard.js"></script>
281
+
282
+ <!-- Initialize Dashboard with Server Data -->
283
+ <script>
284
+ Dashboard.init(
285
+ <%- data.sessionsJson %>,
286
+ {
287
+ threats: <%- data.threatsJson %>,
288
+ commands: <%- data.commandsJson %>,
289
+ events: <%- data.eventsJson %>
290
+ },
291
+ {
292
+ labels: <%- data.activityLabelsJson %>,
293
+ cursor: <%- data.cursorDataJson %>,
294
+ claude: <%- data.claudeDataJson %>,
295
+ github_copilot: <%- data.githubCopilotDataJson || '[]' %>
296
+ },
297
+ <%- data.sessionsWithEventsJson %>
298
+ );
299
+ </script>
300
+ </body>
301
+ </html>