loopengine 0.1.39 → 0.1.41
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/index.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export { readActauthConfig, addActauthRule, updateActauthRule, removeActauthRule
|
|
|
59
59
|
export type { ActauthRuleInput, ActauthConfigView } from './web/actauth-admin.js';
|
|
60
60
|
export { installAbility, upgradeAbility, listInstalledAbilities, AbilityManifestError, AbilityVersionError, AbilityCollisionError, AbilityAlreadyInstalledError, AbilityNotInstalledError, } from './bin/ability-manager.js';
|
|
61
61
|
export type { InstalledAbilityRecord, AbilityEnvDecl, UpgradeFileResult } from './bin/ability-manager.js';
|
|
62
|
-
export { searchPublicAbilities } from './web/abilities-admin.js';
|
|
62
|
+
export { searchPublicAbilities, fetchLatestAbilityVersion } from './web/abilities-admin.js';
|
|
63
63
|
export type { PublicAbilitySearchResult } from './web/abilities-admin.js';
|
|
64
64
|
export { describeModelProviders, describeGateways } from './web/global-config.js';
|
|
65
65
|
export type { ModelProviderInfo, AgentModelUsage, ModelsView, GatewayProviderInfo, GatewaysView } from './web/global-config.js';
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ export { readSkill, writeSkill, deleteSkill, SkillInvalidIdError, SkillNotFoundE
|
|
|
52
52
|
export { listDeclaredEnvVars, setEnvVar, EnvVarNameError } from './web/env-admin.js';
|
|
53
53
|
export { readActauthConfig, addActauthRule, updateActauthRule, removeActauthRule, setDefaultDecision, ActauthRuleExistsError, ActauthRuleNotFoundError, } from './web/actauth-admin.js';
|
|
54
54
|
export { installAbility, upgradeAbility, listInstalledAbilities, AbilityManifestError, AbilityVersionError, AbilityCollisionError, AbilityAlreadyInstalledError, AbilityNotInstalledError, } from './bin/ability-manager.js';
|
|
55
|
-
export { searchPublicAbilities } from './web/abilities-admin.js';
|
|
55
|
+
export { searchPublicAbilities, fetchLatestAbilityVersion } from './web/abilities-admin.js';
|
|
56
56
|
export { describeModelProviders, describeGateways } from './web/global-config.js';
|
|
57
57
|
export { createTrackedApprover, listApprovals, decideApproval, findApproval } from './web/web-approver.js';
|
|
58
58
|
export { scaffoldAgent, scaffoldSubagent, AgentNameError, AgentExistsError, AgentNotFoundError, AgentModelError } from './bin/cli.js';
|
|
@@ -4,3 +4,12 @@ export interface PublicAbilitySearchResult {
|
|
|
4
4
|
version: string;
|
|
5
5
|
}
|
|
6
6
|
export declare function searchPublicAbilities(query?: string): Promise<PublicAbilitySearchResult[]>;
|
|
7
|
+
/** The latest version currently published on the public npm registry for
|
|
8
|
+
* `packageName`, or null if it can't be determined — not published
|
|
9
|
+
* there at all (a private/file:/git-installed ability, the common case
|
|
10
|
+
* during local development), a network hiccup, or a timeout. Best-effort
|
|
11
|
+
* only: the Abilities tab uses this to decide whether an installed
|
|
12
|
+
* ability's own "Upgrade" button is worth showing, not to block
|
|
13
|
+
* anything, so a failure here surfaces as "can't tell, show the button
|
|
14
|
+
* anyway" rather than an error the operator has to deal with. */
|
|
15
|
+
export declare function fetchLatestAbilityVersion(packageName: string): Promise<string | null>;
|
|
@@ -38,3 +38,29 @@ export async function searchPublicAbilities(query) {
|
|
|
38
38
|
const needle = query.toLowerCase();
|
|
39
39
|
return results.filter((r) => r.name.toLowerCase().includes(needle) || r.description.toLowerCase().includes(needle));
|
|
40
40
|
}
|
|
41
|
+
const NPM_LATEST_VERSION_TIMEOUT_MS = 5000;
|
|
42
|
+
/** The latest version currently published on the public npm registry for
|
|
43
|
+
* `packageName`, or null if it can't be determined — not published
|
|
44
|
+
* there at all (a private/file:/git-installed ability, the common case
|
|
45
|
+
* during local development), a network hiccup, or a timeout. Best-effort
|
|
46
|
+
* only: the Abilities tab uses this to decide whether an installed
|
|
47
|
+
* ability's own "Upgrade" button is worth showing, not to block
|
|
48
|
+
* anything, so a failure here surfaces as "can't tell, show the button
|
|
49
|
+
* anyway" rather than an error the operator has to deal with. */
|
|
50
|
+
export async function fetchLatestAbilityVersion(packageName) {
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeout = setTimeout(() => controller.abort(), NPM_LATEST_VERSION_TIMEOUT_MS);
|
|
53
|
+
try {
|
|
54
|
+
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, { signal: controller.signal });
|
|
55
|
+
if (!res.ok)
|
|
56
|
+
return null;
|
|
57
|
+
const data = (await res.json());
|
|
58
|
+
return typeof data.version === 'string' ? data.version : null;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1288,19 +1288,31 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1288
1288
|
}
|
|
1289
1289
|
|
|
1290
1290
|
function renderInstalledAbilityRow(a) {
|
|
1291
|
+
// a.upToDate only ever comes back true when the npm registry lookup
|
|
1292
|
+
// (handleAbilitiesGet's own fetchLatestAbilityVersion) actually
|
|
1293
|
+
// succeeded and matched — a private/file:/git-installed ability, or
|
|
1294
|
+
// any registry hiccup, leaves it false, so the button still shows
|
|
1295
|
+
// rather than silently hiding on an unknown instead of a genuine
|
|
1296
|
+
// "nothing to upgrade".
|
|
1297
|
+
var actionHtml = a.upToDate
|
|
1298
|
+
? '<span class="hint">up to date</span>'
|
|
1299
|
+
: '<button type="button" class="ability-upgrade-btn" data-name="' + escapeHtml(a.name) + '">Upgrade</button>';
|
|
1291
1300
|
return '<tr>' +
|
|
1292
1301
|
'<td><code>' + escapeHtml(a.name) + '</code></td>' +
|
|
1293
1302
|
'<td>' + escapeHtml(a.version) + '</td>' +
|
|
1294
1303
|
'<td class="hint">' + escapeHtml((a.tools || []).join(', ')) + '</td>' +
|
|
1295
|
-
'<td
|
|
1304
|
+
'<td>' + actionHtml + '</td>' +
|
|
1296
1305
|
'</tr>';
|
|
1297
1306
|
}
|
|
1298
1307
|
|
|
1299
|
-
function renderAbilitySearchResultRow(pkg) {
|
|
1308
|
+
function renderAbilitySearchResultRow(pkg, installedNames) {
|
|
1309
|
+
var actionHtml = installedNames.indexOf(pkg.name) !== -1
|
|
1310
|
+
? '<span class="hint">Installed</span>'
|
|
1311
|
+
: '<button type="button" class="ability-install-btn" data-spec="' + escapeHtml(pkg.name) + '">Install</button>';
|
|
1300
1312
|
return '<tr>' +
|
|
1301
1313
|
'<td><code>' + escapeHtml(pkg.name) + '</code> <span class="hint">' + escapeHtml(pkg.version) + '</span></td>' +
|
|
1302
1314
|
'<td>' + escapeHtml(pkg.description || '') + '</td>' +
|
|
1303
|
-
'<td
|
|
1315
|
+
'<td>' + actionHtml + '</td>' +
|
|
1304
1316
|
'</tr>';
|
|
1305
1317
|
}
|
|
1306
1318
|
|
|
@@ -1420,7 +1432,7 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1420
1432
|
// "list every published ability" (the keyword filter alone, no extra
|
|
1421
1433
|
// search text), so an operator sees what's out there immediately
|
|
1422
1434
|
// instead of having to search for something before anything shows up.
|
|
1423
|
-
function runAbilitySearch(name, q, content, resultsEl) {
|
|
1435
|
+
function runAbilitySearch(name, q, content, resultsEl, installedNames) {
|
|
1424
1436
|
resultsEl.innerHTML = '<p class="hint">Loading…</p>';
|
|
1425
1437
|
fetch('/agents/' + encodeURIComponent(name) + '/abilities/search' + (q ? '?q=' + encodeURIComponent(q) : ''))
|
|
1426
1438
|
.then(function (r) { return r.json().then(function (j) { return { ok: r.ok, body: j }; }); })
|
|
@@ -1428,7 +1440,7 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1428
1440
|
if (!result.ok) throw new Error(result.body.error || 'search failed');
|
|
1429
1441
|
var results = result.body.results || [];
|
|
1430
1442
|
resultsEl.innerHTML = results.length
|
|
1431
|
-
? '<table><thead><tr><th>Package</th><th>Description</th><th></th></tr></thead><tbody>' + results.map(renderAbilitySearchResultRow).join('') + '</tbody></table>'
|
|
1443
|
+
? '<table><thead><tr><th>Package</th><th>Description</th><th></th></tr></thead><tbody>' + results.map(function (pkg) { return renderAbilitySearchResultRow(pkg, installedNames); }).join('') + '</tbody></table>'
|
|
1432
1444
|
: '<p class="hint">No public abilities found.</p>';
|
|
1433
1445
|
var installBtns = resultsEl.querySelectorAll('.ability-install-btn');
|
|
1434
1446
|
for (var i = 0; i < installBtns.length; i++) {
|
|
@@ -1443,7 +1455,7 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1443
1455
|
});
|
|
1444
1456
|
}
|
|
1445
1457
|
|
|
1446
|
-
function wireAbilitiesHandlers(name) {
|
|
1458
|
+
function wireAbilitiesHandlers(name, installedNames) {
|
|
1447
1459
|
var content = abilitiesContentEl();
|
|
1448
1460
|
if (!content) return;
|
|
1449
1461
|
|
|
@@ -1462,11 +1474,11 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1462
1474
|
searchForm.addEventListener('submit', function (ev) {
|
|
1463
1475
|
ev.preventDefault();
|
|
1464
1476
|
var q = new FormData(searchForm).get('q');
|
|
1465
|
-
runAbilitySearch(name, q, content, resultsEl);
|
|
1477
|
+
runAbilitySearch(name, q, content, resultsEl, installedNames);
|
|
1466
1478
|
});
|
|
1467
1479
|
// List every published ability immediately, not just after the
|
|
1468
1480
|
// operator explicitly searches for something.
|
|
1469
|
-
runAbilitySearch(name, '', content, resultsEl);
|
|
1481
|
+
runAbilitySearch(name, '', content, resultsEl, installedNames);
|
|
1470
1482
|
}
|
|
1471
1483
|
|
|
1472
1484
|
var installForm = content.querySelector('#abilityInstallForm');
|
|
@@ -1485,7 +1497,8 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1485
1497
|
var content = abilitiesContentEl();
|
|
1486
1498
|
if (!content) return;
|
|
1487
1499
|
content.innerHTML = renderAbilitiesConfigHtml(data);
|
|
1488
|
-
|
|
1500
|
+
var installedNames = (data.abilities || []).map(function (a) { return a.name; });
|
|
1501
|
+
wireAbilitiesHandlers(name, installedNames);
|
|
1489
1502
|
abilitiesLoadedFor = name;
|
|
1490
1503
|
}
|
|
1491
1504
|
|