opena2a-cli 0.5.12 → 0.6.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/README.md +21 -1
- package/dist/commands/detect.d.ts +41 -18
- package/dist/commands/detect.d.ts.map +1 -1
- package/dist/commands/detect.js +729 -120
- package/dist/commands/detect.js.map +1 -1
- package/dist/commands/identity.js +2 -2
- package/dist/commands/identity.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +4 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/review.d.ts +40 -3
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +171 -31
- package/dist/commands/review.js.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/report/detect-html.d.ts +7 -0
- package/dist/report/detect-html.d.ts.map +1 -0
- package/dist/report/detect-html.js +185 -0
- package/dist/report/detect-html.js.map +1 -0
- package/dist/report/review-html.d.ts +1 -1
- package/dist/report/review-html.d.ts.map +1 -1
- package/dist/report/review-html.js +8 -440
- package/dist/report/review-html.js.map +1 -1
- package/dist/util/report-submission.d.ts +1 -0
- package/dist/util/report-submission.d.ts.map +1 -1
- package/dist/util/report-submission.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shadow AI Agent Audit -- HTML Executive Report Generator.
|
|
4
|
+
* Self-contained HTML, dark theme, monospace font, no emojis, no external deps.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.generateDetectHtml = generateDetectHtml;
|
|
41
|
+
const os = __importStar(require("node:os"));
|
|
42
|
+
function esc(s) {
|
|
43
|
+
if (!s)
|
|
44
|
+
return '';
|
|
45
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
46
|
+
.replace(/"/g, '"').replace(/'/g, ''');
|
|
47
|
+
}
|
|
48
|
+
function generateDetectHtml(result) {
|
|
49
|
+
const jsonData = JSON.stringify(result).replace(/<\//g, '<\\/');
|
|
50
|
+
const hostname = esc(os.hostname());
|
|
51
|
+
const username = esc(os.userInfo().username);
|
|
52
|
+
const ts = esc(result.scanTimestamp.replace('T', ' ').replace(/\.\d+Z$/, ' UTC'));
|
|
53
|
+
const dir = esc(result.scanDirectory);
|
|
54
|
+
return `<!DOCTYPE html>
|
|
55
|
+
<html lang="en">
|
|
56
|
+
<head>
|
|
57
|
+
<meta charset="UTF-8">
|
|
58
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
59
|
+
<title>Shadow AI Agent Audit</title>
|
|
60
|
+
<style>
|
|
61
|
+
:root{--bg:#0f172a;--card:#1e293b;--card-border:#334155;--primary:#06b6d4;--text:#e2e8f0;--muted:#94a3b8;--dim:#64748b;--critical:#ef4444;--high:#f97316;--medium:#eab308;--low:#3b82f6;--green:#22c55e;--red:#ef4444;--amber:#f59e0b;--font:'JetBrains Mono','Fira Code','SF Mono',Menlo,Consolas,monospace;}
|
|
62
|
+
*{margin:0;padding:0;box-sizing:border-box;}
|
|
63
|
+
body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:14px;line-height:1.6;}
|
|
64
|
+
.container{max-width:1000px;margin:0 auto;padding:24px 20px;}
|
|
65
|
+
.header{display:flex;align-items:center;justify-content:space-between;padding:12px 0;border-bottom:1px solid var(--card-border);margin-bottom:20px;}
|
|
66
|
+
.header-title{font-size:20px;font-weight:700;color:var(--primary);}
|
|
67
|
+
.header-meta{font-size:12px;color:var(--dim);text-align:right;line-height:1.5;}
|
|
68
|
+
.card{background:var(--card);border:1px solid var(--card-border);border-radius:6px;padding:16px;margin-bottom:12px;}
|
|
69
|
+
.card-title{font-size:14px;font-weight:700;color:var(--text);margin-bottom:10px;}
|
|
70
|
+
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:16px;}
|
|
71
|
+
.stat-card{background:var(--card);border:1px solid var(--card-border);border-radius:6px;padding:12px 14px;text-align:center;}
|
|
72
|
+
.stat-value{font-size:28px;font-weight:700;}
|
|
73
|
+
.stat-label{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:0.5px;margin-top:2px;}
|
|
74
|
+
.score-banner{display:flex;align-items:center;gap:24px;background:var(--card);border:1px solid var(--card-border);border-radius:6px;padding:20px 24px;margin-bottom:16px;}
|
|
75
|
+
.score-banner-num{font-size:48px;font-weight:700;line-height:1;letter-spacing:-1px;}
|
|
76
|
+
.score-banner-bar{flex:1;display:flex;flex-direction:column;gap:6px;}
|
|
77
|
+
.score-banner-track{height:8px;background:rgba(255,255,255,0.06);border-radius:4px;overflow:hidden;}
|
|
78
|
+
.score-banner-fill{height:100%;border-radius:4px;}
|
|
79
|
+
.score-banner-label{font-size:12px;color:var(--dim);display:flex;justify-content:space-between;}
|
|
80
|
+
.score-banner-recovery{font-size:14px;font-weight:600;color:var(--green);white-space:nowrap;}
|
|
81
|
+
.section-title{font-size:16px;font-weight:700;color:var(--text);margin:20px 0 8px;padding-bottom:4px;border-bottom:1px solid var(--card-border);}
|
|
82
|
+
.sev-badge{display:inline-block;font-size:11px;font-weight:600;padding:2px 8px;border-radius:10px;text-transform:uppercase;}
|
|
83
|
+
.sev-critical{background:rgba(239,68,68,0.15);color:var(--critical);}
|
|
84
|
+
.sev-high{background:rgba(249,115,22,0.15);color:var(--high);}
|
|
85
|
+
.sev-medium{background:rgba(234,179,8,0.15);color:var(--medium);}
|
|
86
|
+
.sev-low{background:rgba(59,130,246,0.15);color:var(--low);}
|
|
87
|
+
.status-badge{display:inline-block;font-size:11px;font-weight:700;padding:2px 8px;border-radius:10px;text-transform:uppercase;letter-spacing:0.3px;}
|
|
88
|
+
.status-pass{background:rgba(34,197,94,0.15);color:var(--green);}
|
|
89
|
+
.status-warn{background:rgba(234,179,8,0.15);color:var(--medium);}
|
|
90
|
+
.cmd-block{display:flex;align-items:center;background:rgba(0,0,0,0.3);padding:6px 10px;border-radius:4px;margin:4px 0;font-size:13px;color:var(--primary);}
|
|
91
|
+
.cmd-text{flex:1;}
|
|
92
|
+
.copy-btn{background:none;border:1px solid var(--dim);color:var(--dim);font-family:var(--font);font-size:11px;padding:2px 8px;border-radius:4px;cursor:pointer;margin-left:6px;}
|
|
93
|
+
.copy-btn:hover{border-color:var(--primary);color:var(--primary);}
|
|
94
|
+
.copy-btn.copied{border-color:var(--green);color:var(--green);}
|
|
95
|
+
.finding-card{background:var(--card);border:1px solid var(--card-border);border-radius:6px;padding:16px;margin-bottom:10px;}
|
|
96
|
+
.finding-header{display:flex;align-items:center;gap:10px;margin-bottom:8px;}
|
|
97
|
+
.finding-title{font-size:14px;font-weight:600;}
|
|
98
|
+
.finding-detail{font-size:13px;color:var(--muted);margin-bottom:6px;}
|
|
99
|
+
.finding-why{font-size:13px;color:var(--text);margin-bottom:10px;line-height:1.5;border-left:2px solid var(--card-border);padding-left:10px;}
|
|
100
|
+
.agent-row{display:flex;align-items:center;gap:12px;padding:8px 0;border-bottom:1px solid rgba(51,65,85,0.3);font-size:13px;}
|
|
101
|
+
.agent-row:last-child{border-bottom:none;}
|
|
102
|
+
.agent-name{font-weight:600;min-width:160px;}
|
|
103
|
+
.mcp-group{margin-bottom:12px;}
|
|
104
|
+
.mcp-group-title{font-size:12px;color:var(--dim);text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px;font-weight:600;}
|
|
105
|
+
.mcp-row{padding:6px 0;border-bottom:1px solid rgba(51,65,85,0.2);font-size:13px;}
|
|
106
|
+
.mcp-row:last-child{border-bottom:none;}
|
|
107
|
+
.mcp-name{font-weight:600;color:var(--text);}
|
|
108
|
+
.mcp-caps{font-size:12px;color:var(--muted);margin-top:2px;}
|
|
109
|
+
.means-text{font-size:14px;color:var(--text);line-height:1.6;margin-bottom:8px;}
|
|
110
|
+
.identity-row{display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(51,65,85,0.3);font-size:13px;}
|
|
111
|
+
.identity-row:last-child{border-bottom:none;}
|
|
112
|
+
.identity-label{color:var(--muted);}
|
|
113
|
+
.config-row{padding:8px 0;border-bottom:1px solid rgba(51,65,85,0.3);font-size:13px;}
|
|
114
|
+
.config-row:last-child{border-bottom:none;}
|
|
115
|
+
.config-file{font-weight:600;color:var(--text);}
|
|
116
|
+
.config-detail{font-size:12px;color:var(--muted);margin-top:2px;}
|
|
117
|
+
.footer{text-align:center;padding:20px 0;font-size:11px;color:var(--dim);border-top:1px solid var(--card-border);margin-top:24px;}
|
|
118
|
+
.footer a{color:var(--primary);text-decoration:none;}
|
|
119
|
+
@media(max-width:768px){.stats-grid{grid-template-columns:repeat(2,1fr);}.score-banner{flex-direction:column;align-items:flex-start;}}
|
|
120
|
+
</style>
|
|
121
|
+
</head>
|
|
122
|
+
<body>
|
|
123
|
+
<div class="container">
|
|
124
|
+
<div class="header">
|
|
125
|
+
<div class="header-title">Shadow AI Agent Audit</div>
|
|
126
|
+
<div class="header-meta">${hostname} | ${username}<br>${dir}<br>${ts}</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div id="report"></div>
|
|
129
|
+
<div class="footer">Generated by <a href="https://opena2a.org">opena2a detect</a></div>
|
|
130
|
+
</div>
|
|
131
|
+
<script type="application/json" id="detect-data">${jsonData}</script>
|
|
132
|
+
<script>
|
|
133
|
+
(function(){
|
|
134
|
+
var report=JSON.parse(document.getElementById('detect-data').textContent);
|
|
135
|
+
var s=report.summary;var score=s.governanceScore;
|
|
136
|
+
var projected=Math.min(100,score+s.recoverablePoints);
|
|
137
|
+
var capDescs={'filesystem':'Can read and write files','shell-access':'Can run commands on this computer','database':'Can read and modify databases','network':'Can make requests to external services','browser':'Can control a web browser','source-control':'Can access code repositories','messaging':'Can send messages','payments':'Can access payment systems','cloud-services':'Can access cloud infrastructure'};
|
|
138
|
+
function sc(v){return v>=70?'var(--green)':v>=40?'var(--amber)':'var(--red)';}
|
|
139
|
+
function esc(t){var d=document.createElement('div');d.textContent=t;return d.innerHTML;}
|
|
140
|
+
|
|
141
|
+
var h='<div class="score-banner"><div class="score-banner-num" style="color:'+sc(score)+'">'+score+'</div><div class="score-banner-bar"><div class="score-banner-label"><span>Governance Score</span><span>'+score+'/100</span></div><div class="score-banner-track"><div class="score-banner-fill" style="width:'+score+'%;background:'+sc(score)+'"></div></div>';
|
|
142
|
+
if(s.recoverablePoints>0&&report.findings.length>0){h+='<div class="score-banner-recovery">Path to '+projected+'/100 by addressing '+report.findings.length+' finding'+(report.findings.length!==1?'s':'')+'</div>';}
|
|
143
|
+
h+='</div></div>';
|
|
144
|
+
|
|
145
|
+
var fCount=report.findings.length;
|
|
146
|
+
h+='<div class="stats-grid"><div class="stat-card"><div class="stat-value" style="color:'+(s.ungoverned>0?'var(--amber)':'var(--green)')+'">'+s.totalAgents+'</div><div class="stat-label">AI Agents</div></div><div class="stat-card"><div class="stat-value">'+s.mcpServers+'</div><div class="stat-label">MCP Servers</div></div><div class="stat-card"><div class="stat-value">'+s.aiConfigs+'</div><div class="stat-label">AI Configs</div></div><div class="stat-card"><div class="stat-value" style="color:'+(fCount>0?'var(--amber)':'var(--green)')+'">'+fCount+'</div><div class="stat-label">Findings</div></div></div>';
|
|
147
|
+
|
|
148
|
+
h+='<div class="card"><div class="card-title">What This Means</div>';
|
|
149
|
+
if(s.totalAgents>0){if(s.ungoverned===0){h+='<div class="means-text">Your AI agents have governance in place. Actions are bounded by the rules you defined.</div>';}else{h+='<div class="means-text">'+s.totalAgents+' AI tool'+(s.totalAgents!==1?'s are':' is')+' running. '+s.ungoverned+' '+(s.ungoverned===1?'has':'have')+' no governance rules limiting what '+(s.ungoverned===1?'it':'they')+' can do.</div>';}}
|
|
150
|
+
if(s.mcpServers>0){h+='<div class="means-text">'+s.mcpServers+' MCP server'+(s.mcpServers!==1?'s give':' gives')+' your AI agents additional capabilities (file access, database queries, API calls, etc.).</div>';if(s.unverifiedServers>0){h+='<div class="means-text">'+s.unverifiedServers+' '+(s.unverifiedServers===1?'has':'have')+' no verified identity.</div>';}}
|
|
151
|
+
h+='</div>';
|
|
152
|
+
|
|
153
|
+
if(report.findings.length>0){h+='<h2 class="section-title">Findings ('+report.findings.length+')</h2>';for(var i=0;i<report.findings.length;i++){var f=report.findings[i];h+='<div class="finding-card"><div class="finding-header"><span class="sev-badge sev-'+f.severity+'">'+f.severity+'</span><span class="finding-title">'+esc(f.title)+'</span></div>';if(f.detail){h+='<div class="finding-detail">'+esc(f.detail)+'</div>';}if(f.whyItMatters){h+='<div class="finding-why">'+esc(f.whyItMatters)+'</div>';}h+='<div class="cmd-block"><span class="cmd-text">'+esc(f.remediation)+'</span><button class="copy-btn" data-cmd="'+esc(f.remediation)+'" onclick="copyCmd(this)">Copy</button></div></div>';}}else{h+='<div class="card" style="border-color:var(--green);"><div class="card-title" style="color:var(--green);">All Clear</div><div class="means-text">All detected AI tools have governance in place.</div></div>';}
|
|
154
|
+
|
|
155
|
+
h+='<h2 class="section-title">Running AI Agents</h2><div class="card">';
|
|
156
|
+
if(report.agents.length===0){h+='<div style="color:var(--dim);font-size:13px;">No AI agents detected</div>';}else{for(var j=0;j<report.agents.length;j++){var a=report.agents[j];h+='<div class="agent-row"><span class="agent-name">'+esc(a.name)+'</span><span class="status-badge '+(a.identityStatus==='identified'?'status-pass':'status-warn')+'">'+a.identityStatus+'</span> <span class="status-badge '+(a.governanceStatus==='governed'?'status-pass':'status-warn')+'">'+a.governanceStatus+'</span></div>';}}
|
|
157
|
+
h+='</div>';
|
|
158
|
+
|
|
159
|
+
var pMcp=report.mcpServers.filter(function(x){return x.source.indexOf('(project)')!==-1;});
|
|
160
|
+
var gMcp=report.mcpServers.filter(function(x){return x.source.indexOf('(project)')===-1;});
|
|
161
|
+
h+='<h2 class="section-title">MCP Servers ('+report.mcpServers.length+')</h2>';
|
|
162
|
+
if(report.mcpServers.length>0){h+='<div style="font-size:12px;color:var(--dim);margin-bottom:8px;">Export full asset list for your CMDB: <span style="color:var(--primary);">opena2a detect --export-csv assets.csv</span></div>';}
|
|
163
|
+
h+='<div class="card">';
|
|
164
|
+
if(report.mcpServers.length===0){h+='<div style="color:var(--dim);">No MCP servers found</div>';}
|
|
165
|
+
if(pMcp.length>0){h+='<div class="mcp-group"><div class="mcp-group-title">Project-local ('+pMcp.length+')</div>';for(var k=0;k<pMcp.length;k++){var sv=pMcp[k];var caps=(sv.capabilities||[]).filter(function(c){return c!=='unknown';});h+='<div class="mcp-row"><div class="mcp-name">'+esc(sv.name)+(sv.verified?' <span class="status-badge status-pass">verified</span>':'')+'</div>';if(caps.length>0){h+='<div class="mcp-caps">'+caps.map(function(c){return capDescs[c]||c;}).join(' | ')+'</div>';}h+='</div>';}h+='</div>';}
|
|
166
|
+
if(gMcp.length>0){h+='<div class="mcp-group"><div class="mcp-group-title">Machine-wide ('+gMcp.length+')</div>';var sens=gMcp.filter(function(x){return(x.capabilities||[]).some(function(c){return['shell-access','database','payments','cloud-services'].indexOf(c)!==-1;});});if(sens.length>0){for(var m=0;m<sens.length;m++){var sm=sens[m];var sc2=(sm.capabilities||[]).filter(function(c){return c!=='unknown';});h+='<div class="mcp-row"><div class="mcp-name">'+esc(sm.name)+'</div>';if(sc2.length>0){h+='<div class="mcp-caps">'+sc2.map(function(c){return capDescs[c]||c;}).join(' | ')+'</div>';}h+='</div>';}var ot=gMcp.length-sens.length;if(ot>0){h+='<div style="color:var(--dim);font-size:12px;padding:6px 0;">+ '+ot+' more with standard access</div>';}}else{h+='<div style="color:var(--dim);font-size:12px;">'+gMcp.length+' server'+(gMcp.length!==1?'s':'')+' with standard access</div>';}h+='</div>';}
|
|
167
|
+
h+='</div>';
|
|
168
|
+
|
|
169
|
+
var nw=(report.aiConfigs||[]).filter(function(c){return c.risk!=='low';});
|
|
170
|
+
if(nw.length>0){h+='<h2 class="section-title">AI Config Files</h2><div class="card">';for(var n=0;n<nw.length;n++){var cfg=nw[n];h+='<div class="config-row"><div class="config-file">'+esc(cfg.file)+' <span class="sev-badge sev-'+cfg.risk+'">'+cfg.risk+'</span></div><div class="config-detail">'+esc(cfg.tool)+' -- '+esc(cfg.details)+'</div></div>';}h+='</div>';}
|
|
171
|
+
|
|
172
|
+
// Identity & Governance section omitted from HTML report.
|
|
173
|
+
// The governance score and findings already communicate everything
|
|
174
|
+
// actionable. Showing internal details like ".opena2a/ exists" or
|
|
175
|
+
// "SOUL.md count" adds noise without helping the reader.
|
|
176
|
+
|
|
177
|
+
document.getElementById('report').innerHTML=h;
|
|
178
|
+
|
|
179
|
+
window.copyCmd=function(btn){var cmd=btn.getAttribute('data-cmd');if(navigator.clipboard){navigator.clipboard.writeText(cmd);}else{var ta=document.createElement('textarea');ta.value=cmd;document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);}btn.textContent='OK';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},1500);};
|
|
180
|
+
})();
|
|
181
|
+
</script>
|
|
182
|
+
</body>
|
|
183
|
+
</html>`;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=detect-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-html.js","sourceRoot":"","sources":["../../src/report/detect-html.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWH,gDAyIC;AAjJD,4CAA8B;AAE9B,SAAS,GAAG,CAAC,CAA4B;IACvC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACxE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,kBAAkB,CAAC,MAAoB;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAEtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAwEsB,QAAQ,MAAM,QAAQ,OAAO,GAAG,OAAO,EAAE;;;;;mDAKrB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAoDnD,CAAC;AACT,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates a self-contained HTML file with:
|
|
5
5
|
* - Dark theme (#0f172a bg, #1e293b cards, teal primary)
|
|
6
|
-
* -
|
|
6
|
+
* - 7-tab navigation (Overview, Credentials, Hygiene, Integrity, Shield, HMA, Shadow AI)
|
|
7
7
|
* - Composite score gauge with recovery summary
|
|
8
8
|
* - Phase status cards with timing
|
|
9
9
|
* - Cross-tab navigation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-html.d.ts","sourceRoot":"","sources":["../../src/report/review-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQ1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"review-html.d.ts","sourceRoot":"","sources":["../../src/report/review-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQ1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA2I/D"}
|