diff --git a/modules/agent/views/scripts/skills/index.phtml b/modules/agent/views/scripts/skills/index.phtml
index 60ce311..887fe95 100644
--- a/modules/agent/views/scripts/skills/index.phtml
+++ b/modules/agent/views/scripts/skills/index.phtml
@@ -79,6 +79,26 @@ document.addEventListener('DOMContentLoaded', function () {
}
function toast(res) { ((res && res.messages) || []).forEach(function (m) { TigerDOM.toast(m.message, { type: m.class }); }); }
+ // A skill entry rides on the button as individual data-* attrs (NOT a JSON blob: esc() doesn't
+ // quote-escape, so JSON in a double-quoted attribute breaks). attr() adds the missing "-escape.
+ function attr(s) { return esc(s).replace(/"/g, '"'); }
+ function entryAttrs(row) {
+ return ' data-source="' + attr(row.source) + '" data-sourcelabel="' + attr(row.sourceLabel) + '"'
+ + ' data-name="' + attr(row.name) + '" data-repo="' + attr(row.repo) + '"'
+ + ' data-ref="' + attr(row.ref) + '" data-path="' + attr(row.path) + '" data-url="' + attr(row.url) + '"';
+ }
+ function readEntry(el) {
+ return {
+ source: el.getAttribute('data-source') || '',
+ sourceLabel: el.getAttribute('data-sourcelabel') || '',
+ name: el.getAttribute('data-name') || '',
+ repo: el.getAttribute('data-repo') || '',
+ ref: el.getAttribute('data-ref') || '',
+ path: el.getAttribute('data-path') || '',
+ url: el.getAttribute('data-url') || ''
+ };
+ }
+
var table = tigerDataTable('#sk-table', {
service: { module: 'agent', service: 'skills', action: 'datatable' },
ordering: false, // installed-first pinning is authoritative (server-side)
@@ -109,13 +129,10 @@ document.addEventListener('DOMContentLoaded', function () {
var h = '';
// View source (always) — key if installed, else the repo/ref/path for a live fetch.
h += ' ';
if (!row.installed) {
- h += '