maqcli 0.4.0 → 0.6.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/dist/core/capabilities.d.ts +2 -0
- package/dist/core/cli-probe.d.ts +44 -0
- package/dist/core/cli-probe.js +85 -0
- package/dist/core/command-catalog.js +1 -0
- package/dist/core/config-store.d.ts +8 -0
- package/dist/core/config-store.js +28 -1
- package/dist/core/exec.d.ts +9 -0
- package/dist/core/exec.js +7 -2
- package/dist/core/launcher.d.ts +6 -0
- package/dist/core/launcher.js +61 -20
- package/dist/core/orchestrator.d.ts +5 -0
- package/dist/core/orchestrator.js +8 -0
- package/dist/core/permissions.d.ts +80 -0
- package/dist/core/permissions.js +147 -0
- package/dist/core/providers-catalog.d.ts +1 -0
- package/dist/core/providers-catalog.js +18 -0
- package/dist/core/sandbox.d.ts +14 -1
- package/dist/core/sandbox.js +49 -1
- package/dist/core/security.d.ts +113 -0
- package/dist/core/security.js +303 -0
- package/dist/core/session.d.ts +2 -0
- package/dist/core/session.js +1 -0
- package/dist/core/skills.d.ts +9 -0
- package/dist/core/skills.js +10 -2
- package/dist/core/tools.d.ts +2 -0
- package/dist/core/tools.js +7 -1
- package/dist/index.js +110 -2
- package/dist/phases/scout.js +16 -0
- package/dist/server/daemon.js +42 -1
- package/dist/server/webui.js +144 -1
- package/package.json +1 -1
package/dist/server/webui.js
CHANGED
|
@@ -90,6 +90,28 @@ export function webuiHtml(version) {
|
|
|
90
90
|
pre{white-space:pre-wrap;word-break:break-word;font-size:12px;color:var(--ink)}
|
|
91
91
|
.rhead{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--edge)}
|
|
92
92
|
a{color:var(--blue2)}
|
|
93
|
+
.overlay{position:fixed;inset:0;background:var(--bg);z-index:60;display:none;flex-direction:column}
|
|
94
|
+
.overlay.show{display:flex}
|
|
95
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px;padding:16px;overflow:auto;align-content:start}
|
|
96
|
+
.fcard{background:var(--panel);border:1px solid var(--edge);border-radius:12px;padding:14px;cursor:pointer}
|
|
97
|
+
.fcard:hover{border-color:var(--blue);box-shadow:0 0 0 1px var(--blue) inset}
|
|
98
|
+
.fcard h4{margin:0 0 4px;color:var(--ink);font-size:14px}
|
|
99
|
+
.fcard .cat{font-size:10px;color:var(--blue2);text-transform:uppercase;letter-spacing:1px}
|
|
100
|
+
.fcard p{margin:6px 0 0;font-size:12px;color:var(--mut)}
|
|
101
|
+
.req{padding:9px 12px;border-bottom:1px solid #0f1626}
|
|
102
|
+
.req .a{font-size:12.5px;color:var(--ink)} .req .r{font-size:11px;color:var(--mut);margin:2px 0 6px}
|
|
103
|
+
.req.destructive{box-shadow:inset 3px 0 0 var(--red)} .req.major{box-shadow:inset 3px 0 0 var(--warn)}
|
|
104
|
+
.req .btns{display:flex;gap:6px}
|
|
105
|
+
.req button{border:none;border-radius:6px;padding:4px 10px;cursor:pointer;font-size:11px}
|
|
106
|
+
.ok-btn{background:var(--ok);color:#00231a} .no-btn{background:var(--red);color:#2a0007}
|
|
107
|
+
.sechead{display:flex;align-items:center;gap:8px;margin:18px 0 8px}
|
|
108
|
+
.sechead:first-child{margin-top:0}
|
|
109
|
+
.sechead .n{background:var(--panel2);border:1px solid var(--edge);border-radius:999px;padding:2px 9px;font-size:11px;color:var(--mut)}
|
|
110
|
+
.seclist{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:6px}
|
|
111
|
+
.secitem{background:var(--panel);border:1px solid var(--edge);border-radius:8px;padding:8px 10px;font-family:ui-monospace,monospace;font-size:12px;color:var(--ink);word-break:break-all}
|
|
112
|
+
.secnote{color:var(--mut);font-size:12px;margin:4px 0 14px}
|
|
113
|
+
.pill2{display:inline-flex;align-items:center;gap:6px;background:var(--panel2);border:1px solid var(--edge);border-radius:999px;padding:5px 12px;font-size:12px;color:var(--ink);margin-right:8px}
|
|
114
|
+
.pill2.on{color:var(--ok);border-color:var(--ok)}
|
|
93
115
|
</style></head>
|
|
94
116
|
<body>
|
|
95
117
|
<header>
|
|
@@ -98,15 +120,19 @@ export function webuiHtml(version) {
|
|
|
98
120
|
<span class="e-mut" style="font-size:12px">megalodon · v${version}</span>
|
|
99
121
|
<span class="grow"></span>
|
|
100
122
|
<div class="switch">
|
|
123
|
+
<button onclick="openFeatures()">☰ Features</button>
|
|
101
124
|
<button onclick="feat('agents')">Agents</button>
|
|
102
125
|
<button onclick="feat('connectivity')">Connectivity</button>
|
|
103
126
|
<button onclick="feat('doctor')">Doctor</button>
|
|
104
127
|
<button onclick="feat('models')">Models</button>
|
|
128
|
+
<button onclick="openSecurity()">🔒 Security</button>
|
|
105
129
|
<button class="ghost" onclick="togglePreview()">Preview</button>
|
|
106
130
|
</div>
|
|
107
131
|
</header>
|
|
108
132
|
<main id="main">
|
|
109
133
|
<div class="col left">
|
|
134
|
+
<div class="sec">Request box <span id="reqCount" class="badge"></span></div>
|
|
135
|
+
<div id="requests"><div class="empty">No pending requests.</div></div>
|
|
110
136
|
<div class="sec">Sessions & history</div>
|
|
111
137
|
<div id="sessions"><div class="empty">No sessions yet.</div></div>
|
|
112
138
|
<div class="sec">Agents</div>
|
|
@@ -139,6 +165,24 @@ export function webuiHtml(version) {
|
|
|
139
165
|
<div id="preview" style="padding:12px"><div class="empty">Select a session to inspect its result.</div></div>
|
|
140
166
|
</div>
|
|
141
167
|
</main>
|
|
168
|
+
<div class="overlay" id="features">
|
|
169
|
+
<div class="rhead" style="padding:14px 16px">
|
|
170
|
+
<button class="ghost" onclick="closeFeatures()">← Back to home</button>
|
|
171
|
+
<b style="margin-left:12px">All features</b>
|
|
172
|
+
<span class="grow"></span>
|
|
173
|
+
<span class="e-mut" style="font-size:12px">everything MAQ can do — click to run</span>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="grid" id="featureGrid"><div class="empty">loading…</div></div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="overlay" id="security">
|
|
178
|
+
<div class="rhead" style="padding:14px 16px">
|
|
179
|
+
<button class="ghost" onclick="closeSecurity()">← Back to home</button>
|
|
180
|
+
<b style="margin-left:12px">Security rules</b>
|
|
181
|
+
<span class="grow"></span>
|
|
182
|
+
<span class="e-mut" style="font-size:12px">enforced at the code level — same rules the terminal ('maq security') shows and enforces</span>
|
|
183
|
+
</div>
|
|
184
|
+
<div id="securityBody" style="overflow:auto;padding:16px"><div class="empty">loading…</div></div>
|
|
185
|
+
</div>
|
|
142
186
|
<script>
|
|
143
187
|
"use strict";
|
|
144
188
|
var base = location.origin;
|
|
@@ -312,7 +356,106 @@ function renderAgents(agents){
|
|
|
312
356
|
});
|
|
313
357
|
}
|
|
314
358
|
|
|
315
|
-
|
|
359
|
+
async function openFeatures(){
|
|
360
|
+
document.getElementById('features').classList.add('show');
|
|
361
|
+
var grid=document.getElementById('featureGrid'); grid.innerHTML='loading…';
|
|
362
|
+
try{
|
|
363
|
+
var cat=await (await api('/v1/commands')).json();
|
|
364
|
+
var cmds=(cat.maq||[]); grid.innerHTML='';
|
|
365
|
+
cmds.forEach(function(c){
|
|
366
|
+
var card=h('div','fcard');
|
|
367
|
+
card.innerHTML='<div class="cat">'+c.category+'</div><h4>'+c.name+'</h4><p>'+c.summary+'</p>';
|
|
368
|
+
card.onclick=function(){ runFeature(c); };
|
|
369
|
+
grid.appendChild(card);
|
|
370
|
+
});
|
|
371
|
+
}catch(e){ grid.innerHTML='<div class="empty">'+e+'</div>'; }
|
|
372
|
+
}
|
|
373
|
+
function closeFeatures(){ document.getElementById('features').classList.remove('show'); }
|
|
374
|
+
|
|
375
|
+
async function openSecurity(){
|
|
376
|
+
document.getElementById('security').classList.add('show');
|
|
377
|
+
var box=document.getElementById('securityBody'); box.innerHTML='loading…';
|
|
378
|
+
try{
|
|
379
|
+
var d=await (await api('/v1/security')).json();
|
|
380
|
+
var r=d.rules, evs=(d.events||[]);
|
|
381
|
+
var html='';
|
|
382
|
+
html+='<div style="margin-bottom:14px">';
|
|
383
|
+
html+='<span class="pill2 on">permission posture: '+r.permissionMode+'</span>';
|
|
384
|
+
html+='<span class="pill2 on">secret env scrubbing: on</span>';
|
|
385
|
+
html+='<span class="pill2 on">prompt-injection scanning: on</span>';
|
|
386
|
+
html+='</div>';
|
|
387
|
+
|
|
388
|
+
html+=sec('Protected paths (never writable — cannot be overridden by config)', r.protectedPaths.length);
|
|
389
|
+
html+='<div class="seclist">'+r.protectedPaths.map(function(p){return '<div class="secitem">'+esc(p)+'</div>';}).join('')+'</div>';
|
|
390
|
+
html+='<div class="secnote">Enforced in sandbox.ts checkWrite(), unconditionally, before any tier logic — a compromised agent cannot argue past this with a clever prompt.</div>';
|
|
391
|
+
|
|
392
|
+
html+=sec('Protected file patterns (matched by name, anywhere in the project)', r.protectedNamePatterns.length);
|
|
393
|
+
html+='<div class="seclist">'+r.protectedNamePatterns.map(function(p){return '<div class="secitem">'+esc(p)+'</div>';}).join('')+'</div>';
|
|
394
|
+
|
|
395
|
+
if(r.extraProtectedPaths && r.extraProtectedPaths.length){
|
|
396
|
+
html+=sec('Project-added protected paths', r.extraProtectedPaths.length);
|
|
397
|
+
html+='<div class="seclist">'+r.extraProtectedPaths.map(function(p){return '<div class="secitem">'+esc(p)+'</div>';}).join('')+'</div>';
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
html+=sec('Network egress allowlist (default-deny everything else)', r.netAllowlist.length);
|
|
401
|
+
html+='<div class="seclist">'+r.netAllowlist.map(function(p){return '<div class="secitem">'+esc(p)+'</div>';}).join('')+'</div>';
|
|
402
|
+
html+='<div class="secnote">Enforced in tools.ts http_get and available to any outbound call site via security.ts checkEgress(). Not just a suggestion in a prompt.</div>';
|
|
403
|
+
|
|
404
|
+
html+=sec('Prompt-injection scanning', r.promptInjectionScanning.length);
|
|
405
|
+
html+='<div class="seclist">'+r.promptInjectionScanning.map(function(p){return '<div class="secitem">'+esc(p)+'</div>';}).join('')+'</div>';
|
|
406
|
+
html+='<div class="secnote">README, manifest, git commits, AGENTS.md and skill files are scanned for override/exfiltration/jailbreak patterns before they reach a model. Findings are surfaced loudly, never silently dropped.</div>';
|
|
407
|
+
|
|
408
|
+
html+=sec('Recent findings (this session)', evs.length);
|
|
409
|
+
if(!evs.length){ html+='<div class="secnote">None recorded yet — findings appear here as tasks run.</div>'; }
|
|
410
|
+
else {
|
|
411
|
+
html+='<div>'+evs.slice().reverse().map(function(e){
|
|
412
|
+
var cls=e.severity==='high'?'e-red':'e-warn';
|
|
413
|
+
return '<div class="ev"><span class="ic '+cls+'">⚠</span><span class="tx '+cls+'">'+esc(e.kind)+': '+esc(e.detail)+'</span></div>';
|
|
414
|
+
}).join('')+'</div>';
|
|
415
|
+
}
|
|
416
|
+
}catch(e){ box.innerHTML='<div class="empty">'+e+'</div>'; return; }
|
|
417
|
+
box.innerHTML = html;
|
|
418
|
+
}
|
|
419
|
+
function sec(title,count){ return '<div class="sechead"><b>'+title+'</b><span class="n">'+count+'</span></div>'; }
|
|
420
|
+
function esc(s){ var d=document.createElement('div'); d.textContent=String(s); return d.innerHTML; }
|
|
421
|
+
function closeSecurity(){ document.getElementById('security').classList.remove('show'); }
|
|
422
|
+
|
|
423
|
+
function runFeature(c){
|
|
424
|
+
closeFeatures();
|
|
425
|
+
if(c.needsInput==='task'||c.needsInput==='query'){
|
|
426
|
+
var g=document.getElementById('goal'); g.focus();
|
|
427
|
+
if(c.name==='orchestrate'){ mode='parallel'; renderModes(); }
|
|
428
|
+
g.placeholder='['+c.name+'] '+c.summary;
|
|
429
|
+
} else {
|
|
430
|
+
feat(c.name);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
async function loadRequests(){
|
|
435
|
+
try{
|
|
436
|
+
var d=await (await api('/v1/requests')).json();
|
|
437
|
+
var box=document.getElementById('requests'); var pend=(d.pending||[]);
|
|
438
|
+
document.getElementById('reqCount').textContent=pend.length?String(pend.length):'';
|
|
439
|
+
if(!pend.length){ box.innerHTML='<div class="empty">No pending requests.</div>'; return; }
|
|
440
|
+
box.innerHTML='';
|
|
441
|
+
pend.forEach(function(r){
|
|
442
|
+
var it=h('div','req '+r.risk);
|
|
443
|
+
var a=h('div','a'); a.textContent=r.action+' — '+(r.detail||'');
|
|
444
|
+
var reason=h('div','r'); reason.textContent=r.risk+' · '+(r.reason||'');
|
|
445
|
+
var btns=h('div','btns');
|
|
446
|
+
var ok=h('button','ok-btn','Approve'); ok.onclick=function(){ decideReq(r.id,'approve'); };
|
|
447
|
+
var no=h('button','no-btn','Deny'); no.onclick=function(){ decideReq(r.id,'deny'); };
|
|
448
|
+
btns.appendChild(ok); btns.appendChild(no);
|
|
449
|
+
it.appendChild(a); it.appendChild(reason); it.appendChild(btns); box.appendChild(it);
|
|
450
|
+
});
|
|
451
|
+
}catch(e){}
|
|
452
|
+
}
|
|
453
|
+
async function decideReq(id,action){
|
|
454
|
+
try{ await api('/v1/requests/'+id,{method:'POST',body:JSON.stringify({action:action})}); loadRequests(); }catch(e){}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
renderModes(); refreshSessions(); feat('agents'); loadRequests();
|
|
458
|
+
setInterval(refreshSessions, 5000); setInterval(loadRequests, 3000);
|
|
316
459
|
document.getElementById('goal').addEventListener('keydown', function(e){ if((e.metaKey||e.ctrlKey)&&e.key==='Enter')startTask(); });
|
|
317
460
|
</script>
|
|
318
461
|
</body></html>`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maqcli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "MAQ master orchestrator — a token-efficient, agent-agnostic supervisor CLI that sits on top of any worker CLI (AI or not) via a Scout -> Plan -> Execute -> Verify pipeline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|