agent-discover 1.0.5 → 1.0.7
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/CHANGELOG.md +2 -2
- package/README.md +58 -39
- package/dist/domain/marketplace.d.ts.map +1 -1
- package/dist/domain/marketplace.js +1 -0
- package/dist/domain/marketplace.js.map +1 -1
- package/dist/domain/proxy.d.ts +5 -1
- package/dist/domain/proxy.d.ts.map +1 -1
- package/dist/domain/proxy.js +50 -14
- package/dist/domain/proxy.js.map +1 -1
- package/dist/domain/registry.d.ts +2 -2
- package/dist/domain/registry.d.ts.map +1 -1
- package/dist/domain/registry.js +4 -23
- package/dist/domain/registry.js.map +1 -1
- package/dist/lib.d.ts +1 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/storage/database.js +7 -1
- package/dist/storage/database.js.map +1 -1
- package/dist/transport/mcp-handlers.d.ts.map +1 -1
- package/dist/transport/mcp-handlers.js +9 -11
- package/dist/transport/mcp-handlers.js.map +1 -1
- package/dist/transport/mcp.d.ts.map +1 -1
- package/dist/transport/mcp.js +0 -5
- package/dist/transport/mcp.js.map +1 -1
- package/dist/transport/rest.d.ts.map +1 -1
- package/dist/transport/rest.js +86 -10
- package/dist/transport/rest.js.map +1 -1
- package/dist/types.d.ts +2 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/app.js +156 -79
- package/dist/ui/styles.css +0 -59
- package/package.json +1 -1
package/dist/ui/app.js
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
let currentTab = 'installed';
|
|
13
13
|
let searchTimeout = null;
|
|
14
14
|
let openSections = {}; // track open sections per server: { "serverId-sectionName": true }
|
|
15
|
-
let openApprovalDropdown = null; // server id with open dropdown
|
|
16
15
|
|
|
17
16
|
// -------------------------------------------------------------------------
|
|
18
17
|
// WebSocket
|
|
@@ -185,9 +184,6 @@
|
|
|
185
184
|
: 'Active'
|
|
186
185
|
: 'Inactive';
|
|
187
186
|
|
|
188
|
-
// Approval badge removed — not useful without automatic classification
|
|
189
|
-
|
|
190
|
-
// Combined status: active+healthy=green, active+unhealthy=red, inactive=gray
|
|
191
187
|
var healthStatus = s.health_status || 'unknown';
|
|
192
188
|
|
|
193
189
|
// Error count
|
|
@@ -279,8 +275,16 @@
|
|
|
279
275
|
esc(s.source || 'local') +
|
|
280
276
|
'</span>' +
|
|
281
277
|
'<span>' +
|
|
282
|
-
|
|
278
|
+
(function () {
|
|
279
|
+
var t = s.transport || 'stdio';
|
|
280
|
+
if (t === 'sse') return 'remote sse';
|
|
281
|
+
if (t === 'streamable-http') return 'remote http';
|
|
282
|
+
return 'local stdio';
|
|
283
|
+
})() +
|
|
283
284
|
'</span>' +
|
|
285
|
+
(s.transport && s.transport !== 'stdio' && s.homepage
|
|
286
|
+
? '<span style="font-size:11px;color:var(--text-muted)">' + esc(s.homepage) + '</span>'
|
|
287
|
+
: '') +
|
|
284
288
|
'</div>' +
|
|
285
289
|
toolSection +
|
|
286
290
|
actionsSection +
|
|
@@ -487,20 +491,49 @@
|
|
|
487
491
|
.map(function (s, idx) {
|
|
488
492
|
var pkgs = (s.packages || [])
|
|
489
493
|
.map(function (p) {
|
|
490
|
-
|
|
494
|
+
var rt = p.runtime || 'stdio';
|
|
495
|
+
var color =
|
|
496
|
+
rt === 'streamable-http'
|
|
497
|
+
? 'var(--accent, #5d8da8)'
|
|
498
|
+
: rt === 'sse'
|
|
499
|
+
? 'var(--orange, #e67e22)'
|
|
500
|
+
: 'var(--green, #27ae60)';
|
|
501
|
+
return (
|
|
502
|
+
'<span class="tag" style="border-color:' +
|
|
503
|
+
color +
|
|
504
|
+
';color:' +
|
|
505
|
+
color +
|
|
506
|
+
'">' +
|
|
507
|
+
esc(rt) +
|
|
508
|
+
': ' +
|
|
509
|
+
esc(p.name) +
|
|
510
|
+
'</span>'
|
|
511
|
+
);
|
|
491
512
|
})
|
|
492
513
|
.join('');
|
|
493
514
|
|
|
494
515
|
var safeName = (s.name || '').replace(/\//g, '-');
|
|
495
516
|
var isInstalled =
|
|
496
517
|
installedNames.indexOf(safeName) !== -1 || installedNames.indexOf(s.name) !== -1;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
518
|
+
|
|
519
|
+
// All transport types are supported (stdio, sse, streamable-http)
|
|
520
|
+
var isRemoteOnly = false;
|
|
521
|
+
|
|
522
|
+
var installBtn;
|
|
523
|
+
if (isInstalled) {
|
|
524
|
+
installBtn =
|
|
525
|
+
'<button class="btn-install btn-installed" disabled><span class="material-symbols-outlined" style="font-size:14px">check_circle</span>Installed</button>';
|
|
526
|
+
} else if (isRemoteOnly) {
|
|
527
|
+
installBtn =
|
|
528
|
+
'<button class="btn-install" disabled title="Remote server — not supported for local activation"><span class="material-symbols-outlined" style="font-size:14px">cloud_off</span>Remote only</button>';
|
|
529
|
+
} else {
|
|
530
|
+
installBtn =
|
|
531
|
+
'<button class="btn-install" data-browse-idx="' +
|
|
500
532
|
idx +
|
|
501
533
|
'" onclick="window.__installFromBrowse(' +
|
|
502
534
|
idx +
|
|
503
535
|
', this)"><span class="material-symbols-outlined" style="font-size:14px">download</span>Install</button>';
|
|
536
|
+
}
|
|
504
537
|
|
|
505
538
|
return (
|
|
506
539
|
'<div class="server-card">' +
|
|
@@ -545,13 +578,16 @@
|
|
|
545
578
|
window.__activateServer = function (id) {
|
|
546
579
|
fetch('/api/servers/' + id + '/activate', { method: 'POST' })
|
|
547
580
|
.then(function (r) {
|
|
548
|
-
return r.json()
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
581
|
+
return r.json().then(function (data) {
|
|
582
|
+
if (data.error) {
|
|
583
|
+
showToast('Activation failed: ' + data.error, 'error');
|
|
584
|
+
} else if (data.status === 'activated') {
|
|
585
|
+
showToast('Activated with ' + (data.tool_count || 0) + ' tools', 'success');
|
|
586
|
+
}
|
|
587
|
+
});
|
|
552
588
|
})
|
|
553
589
|
.catch(function (err) {
|
|
554
|
-
|
|
590
|
+
showToast('Activation failed: ' + err.message, 'error');
|
|
555
591
|
});
|
|
556
592
|
};
|
|
557
593
|
|
|
@@ -591,29 +627,54 @@
|
|
|
591
627
|
'<span class="material-symbols-outlined" style="font-size:14px">hourglass_top</span>Installing...';
|
|
592
628
|
|
|
593
629
|
var safeName = (server.name || '').replace(/\//g, '-');
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
var
|
|
597
|
-
|
|
598
|
-
|
|
630
|
+
// Detect transport and build config
|
|
631
|
+
var pkg = (server.packages || [])[0];
|
|
632
|
+
var transport = (pkg && (pkg.transport || pkg.runtime)) || 'stdio';
|
|
633
|
+
var remoteUrl = pkg && pkg.url ? pkg.url : null;
|
|
634
|
+
|
|
635
|
+
var serverData = {
|
|
636
|
+
name: safeName,
|
|
637
|
+
description: server.description || '',
|
|
638
|
+
source: 'registry',
|
|
639
|
+
transport: transport,
|
|
640
|
+
tags: ['marketplace'],
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
if (transport === 'streamable-http' || transport === 'sse') {
|
|
644
|
+
serverData.homepage = remoteUrl || server.repository || '';
|
|
645
|
+
} else {
|
|
646
|
+
// stdio / node / python — default to npx
|
|
647
|
+
serverData.transport = 'stdio';
|
|
648
|
+
serverData.command = 'npx';
|
|
649
|
+
serverData.args = ['-y', pkg ? pkg.name || server.name : server.name || safeName];
|
|
599
650
|
}
|
|
651
|
+
|
|
600
652
|
fetch('/api/servers', {
|
|
601
653
|
method: 'POST',
|
|
602
654
|
headers: { 'Content-Type': 'application/json' },
|
|
603
|
-
body: JSON.stringify(
|
|
604
|
-
name: safeName,
|
|
605
|
-
description: server.description || '',
|
|
606
|
-
command: 'npx',
|
|
607
|
-
args: ['-y', server.name || npmPkg],
|
|
608
|
-
source: 'registry',
|
|
609
|
-
tags: ['marketplace'],
|
|
610
|
-
}),
|
|
655
|
+
body: JSON.stringify(serverData),
|
|
611
656
|
})
|
|
612
657
|
.then(function (r) {
|
|
613
658
|
if (!r.ok) throw new Error('Install failed');
|
|
614
659
|
return r.json();
|
|
615
660
|
})
|
|
616
|
-
.then(function () {
|
|
661
|
+
.then(function (data) {
|
|
662
|
+
if (serverData.command === 'npx' && data && data.id) {
|
|
663
|
+
btn.innerHTML =
|
|
664
|
+
'<span class="material-symbols-outlined" style="font-size:14px">downloading</span>Downloading...';
|
|
665
|
+
return fetch('/api/servers/' + data.id + '/preinstall', { method: 'POST' })
|
|
666
|
+
.then(function () {
|
|
667
|
+
btn.innerHTML =
|
|
668
|
+
'<span class="material-symbols-outlined" style="font-size:14px">check_circle</span>Ready';
|
|
669
|
+
btn.classList.add('btn-installed');
|
|
670
|
+
})
|
|
671
|
+
.catch(function () {
|
|
672
|
+
// Download failed but install succeeded
|
|
673
|
+
btn.innerHTML =
|
|
674
|
+
'<span class="material-symbols-outlined" style="font-size:14px">check_circle</span>Installed';
|
|
675
|
+
btn.classList.add('btn-installed');
|
|
676
|
+
});
|
|
677
|
+
}
|
|
617
678
|
btn.innerHTML =
|
|
618
679
|
'<span class="material-symbols-outlined" style="font-size:14px">check_circle</span>Installed';
|
|
619
680
|
btn.classList.add('btn-installed');
|
|
@@ -635,30 +696,80 @@
|
|
|
635
696
|
var pkg = (input ? input.value : '').trim();
|
|
636
697
|
if (!pkg) return;
|
|
637
698
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
tags: ['npm'],
|
|
649
|
-
}),
|
|
650
|
-
})
|
|
699
|
+
// Find the install button and show spinner
|
|
700
|
+
var btn = input ? input.parentElement.querySelector('.btn-install') : null;
|
|
701
|
+
var origHtml = btn ? btn.innerHTML : '';
|
|
702
|
+
if (btn) {
|
|
703
|
+
btn.disabled = true;
|
|
704
|
+
btn.innerHTML =
|
|
705
|
+
'<span class="material-symbols-outlined" style="font-size:14px">hourglass_top</span> Checking...';
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
fetch('/api/npm-check?package=' + encodeURIComponent(pkg))
|
|
651
709
|
.then(function (r) {
|
|
652
|
-
if (!r.ok) throw new Error('Install failed');
|
|
653
710
|
return r.json();
|
|
654
711
|
})
|
|
655
|
-
.then(function () {
|
|
656
|
-
|
|
657
|
-
|
|
712
|
+
.then(function (data) {
|
|
713
|
+
if (!data.exists) {
|
|
714
|
+
showToast('Package not found on npm', 'error');
|
|
715
|
+
if (btn) {
|
|
716
|
+
btn.disabled = false;
|
|
717
|
+
btn.innerHTML = origHtml;
|
|
718
|
+
}
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
var safeName = pkg.replace(/@/g, '').replace(/\//g, '-');
|
|
723
|
+
return fetch('/api/servers', {
|
|
724
|
+
method: 'POST',
|
|
725
|
+
headers: { 'Content-Type': 'application/json' },
|
|
726
|
+
body: JSON.stringify({
|
|
727
|
+
name: safeName,
|
|
728
|
+
command: 'npx',
|
|
729
|
+
args: ['-y', pkg],
|
|
730
|
+
description: 'Installed from npm: ' + pkg,
|
|
731
|
+
source: 'registry',
|
|
732
|
+
tags: ['npm'],
|
|
733
|
+
}),
|
|
734
|
+
})
|
|
735
|
+
.then(function (r) {
|
|
736
|
+
if (!r.ok) throw new Error('Install failed');
|
|
737
|
+
return r.json();
|
|
738
|
+
})
|
|
739
|
+
.then(function (data) {
|
|
740
|
+
if (data && data.id) {
|
|
741
|
+
if (btn) {
|
|
742
|
+
btn.innerHTML =
|
|
743
|
+
'<span class="material-symbols-outlined" style="font-size:14px">downloading</span> Downloading...';
|
|
744
|
+
}
|
|
745
|
+
return fetch('/api/servers/' + data.id + '/preinstall', { method: 'POST' })
|
|
746
|
+
.then(function () {
|
|
747
|
+
showToast('Installed and downloaded ' + pkg, 'success');
|
|
748
|
+
})
|
|
749
|
+
.catch(function () {
|
|
750
|
+
showToast(
|
|
751
|
+
'Installed ' + pkg + ' (download will happen on first activate)',
|
|
752
|
+
'success',
|
|
753
|
+
);
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
showToast('Installed ' + pkg, 'success');
|
|
757
|
+
})
|
|
758
|
+
.then(function () {
|
|
759
|
+
if (input) input.value = '';
|
|
760
|
+
if (btn) {
|
|
761
|
+
btn.disabled = false;
|
|
762
|
+
btn.innerHTML = origHtml;
|
|
763
|
+
}
|
|
764
|
+
});
|
|
658
765
|
})
|
|
659
766
|
.catch(function (err) {
|
|
660
767
|
console.error('npm install failed:', err);
|
|
661
768
|
showToast('Install failed: ' + err.message, 'error');
|
|
769
|
+
if (btn) {
|
|
770
|
+
btn.disabled = false;
|
|
771
|
+
btn.innerHTML = origHtml;
|
|
772
|
+
}
|
|
662
773
|
});
|
|
663
774
|
};
|
|
664
775
|
|
|
@@ -702,29 +813,6 @@
|
|
|
702
813
|
render();
|
|
703
814
|
};
|
|
704
815
|
|
|
705
|
-
window.__toggleApprovalDropdown = function (serverId) {
|
|
706
|
-
openApprovalDropdown = openApprovalDropdown === serverId ? null : serverId;
|
|
707
|
-
render();
|
|
708
|
-
};
|
|
709
|
-
|
|
710
|
-
window.__setApproval = function (serverId, status) {
|
|
711
|
-
openApprovalDropdown = null;
|
|
712
|
-
fetch('/api/servers/' + serverId, {
|
|
713
|
-
method: 'PUT',
|
|
714
|
-
headers: { 'Content-Type': 'application/json' },
|
|
715
|
-
body: JSON.stringify({ approval_status: status }),
|
|
716
|
-
})
|
|
717
|
-
.then(function (r) {
|
|
718
|
-
return r.json();
|
|
719
|
-
})
|
|
720
|
-
.then(function () {
|
|
721
|
-
showToast('Approval status set to ' + status, 'success');
|
|
722
|
-
})
|
|
723
|
-
.catch(function () {
|
|
724
|
-
showToast('Failed to update approval status', 'error');
|
|
725
|
-
});
|
|
726
|
-
};
|
|
727
|
-
|
|
728
816
|
window.__checkHealth = function (serverId) {
|
|
729
817
|
fetch('/api/servers/' + serverId + '/health', { method: 'POST' })
|
|
730
818
|
.then(function (r) {
|
|
@@ -855,17 +943,6 @@
|
|
|
855
943
|
}, 3000);
|
|
856
944
|
}
|
|
857
945
|
|
|
858
|
-
// -------------------------------------------------------------------------
|
|
859
|
-
// Close approval dropdown on outside click
|
|
860
|
-
// -------------------------------------------------------------------------
|
|
861
|
-
|
|
862
|
-
document.addEventListener('click', function (e) {
|
|
863
|
-
if (openApprovalDropdown !== null && !e.target.closest('.approval-badge')) {
|
|
864
|
-
openApprovalDropdown = null;
|
|
865
|
-
render();
|
|
866
|
-
}
|
|
867
|
-
});
|
|
868
|
-
|
|
869
946
|
// -------------------------------------------------------------------------
|
|
870
947
|
// Init
|
|
871
948
|
// -------------------------------------------------------------------------
|
package/dist/ui/styles.css
CHANGED
|
@@ -697,65 +697,6 @@ body {
|
|
|
697
697
|
color: #e57373;
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
-
/* ---------------------------------------------------------------------------
|
|
701
|
-
Approval badges
|
|
702
|
-
--------------------------------------------------------------------------- */
|
|
703
|
-
|
|
704
|
-
.approval-badge {
|
|
705
|
-
font-size: 11px;
|
|
706
|
-
padding: 2px 8px;
|
|
707
|
-
border-radius: 4px;
|
|
708
|
-
font-weight: 500;
|
|
709
|
-
cursor: pointer;
|
|
710
|
-
position: relative;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
.approval-experimental {
|
|
714
|
-
color: #e89b3e;
|
|
715
|
-
border: 1px solid rgba(232, 155, 62, 0.3);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
.approval-approved {
|
|
719
|
-
color: #4caf50;
|
|
720
|
-
border: 1px solid rgba(76, 175, 80, 0.3);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
.approval-production {
|
|
724
|
-
color: var(--accent);
|
|
725
|
-
border: 1px solid rgba(93, 141, 168, 0.3);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
.approval-dropdown {
|
|
729
|
-
position: absolute;
|
|
730
|
-
top: 100%;
|
|
731
|
-
left: 0;
|
|
732
|
-
margin-top: 4px;
|
|
733
|
-
background: var(--bg-elevated);
|
|
734
|
-
border: 1px solid var(--border);
|
|
735
|
-
border-radius: 6px;
|
|
736
|
-
box-shadow: var(--shadow-md);
|
|
737
|
-
z-index: 10;
|
|
738
|
-
min-width: 120px;
|
|
739
|
-
overflow: hidden;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
.approval-dropdown-item {
|
|
743
|
-
display: block;
|
|
744
|
-
width: 100%;
|
|
745
|
-
padding: 6px 12px;
|
|
746
|
-
border: none;
|
|
747
|
-
background: transparent;
|
|
748
|
-
color: var(--text);
|
|
749
|
-
font-family: var(--font-ui);
|
|
750
|
-
font-size: 12px;
|
|
751
|
-
text-align: left;
|
|
752
|
-
cursor: pointer;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
.approval-dropdown-item:hover {
|
|
756
|
-
background: var(--bg-hover);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
700
|
/* ---------------------------------------------------------------------------
|
|
760
701
|
Health dot
|
|
761
702
|
--------------------------------------------------------------------------- */
|
package/package.json
CHANGED