loopengine 0.1.35 → 0.1.37
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.
|
@@ -1128,17 +1128,31 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1128
1128
|
// More than one ability declaring the same name doesn't get resolved
|
|
1129
1129
|
// here — there's one .env per project, so both read whatever single
|
|
1130
1130
|
// value ends up set, whether that's actually correct or a coincidence
|
|
1131
|
-
// (see env-admin.ts's own doc comment).
|
|
1132
|
-
// of just the first one seen
|
|
1133
|
-
// looking, instead of silently hiding all but one
|
|
1131
|
+
// (see env-admin.ts's own doc comment). Naming every declaring
|
|
1132
|
+
// ability instead of just the first one seen makes that visible to
|
|
1133
|
+
// whoever's looking, instead of silently hiding all but one — shown
|
|
1134
|
+
// here (not a separate "Required by" column, now that rows are
|
|
1135
|
+
// already grouped under one ability's own card) only when there
|
|
1136
|
+
// actually is more than one, since inside its own card which ability
|
|
1137
|
+
// this is is already obvious from context.
|
|
1134
1138
|
var sharedNote = v.abilityNames.length > 1
|
|
1135
|
-
? ' <span class="hint" title="
|
|
1139
|
+
? ' <span class="hint" title="Also declared by: ' + escapeHtml(v.abilityNames.join(', ')) + '. There is only one value for it project-wide, so check whether they actually need the same one.">(shared)</span>'
|
|
1136
1140
|
: '';
|
|
1141
|
+
// A secret's value is never sent to the browser at all (see
|
|
1142
|
+
// env-admin.ts) — "set" is the most this tab can ever say about one.
|
|
1143
|
+
// A non-secret var's actual value comes through, so show it instead
|
|
1144
|
+
// of a bare "set", since the whole point of looking here is usually
|
|
1145
|
+
// to check *what* something is currently configured to, not just
|
|
1146
|
+
// whether it has a value.
|
|
1147
|
+
var statusHtml = !v.set
|
|
1148
|
+
? '<span class="error">not set</span>'
|
|
1149
|
+
: v.secret
|
|
1150
|
+
? '<span class="hint">set</span>'
|
|
1151
|
+
: '<code>' + escapeHtml(v.value || '') + '</code>';
|
|
1137
1152
|
return '<tr>' +
|
|
1138
|
-
'<td><code>' + escapeHtml(v.name) + '</code
|
|
1153
|
+
'<td><code>' + escapeHtml(v.name) + '</code>' + sharedNote + '</td>' +
|
|
1139
1154
|
'<td style="max-width:320px">' + escapeHtml(v.description || '') + '</td>' +
|
|
1140
|
-
'<td
|
|
1141
|
-
'<td>' + (v.set ? '<span class="hint">set</span>' : '<span class="error">not set</span>') + '</td>' +
|
|
1155
|
+
'<td>' + statusHtml + '</td>' +
|
|
1142
1156
|
'<td><form class="add-source env-var-form" data-name="' + escapeHtml(v.name) + '">' +
|
|
1143
1157
|
'<input type="' + (v.secret ? 'password' : 'text') + '" name="value" placeholder="' + (v.set ? 'unchanged unless you type a new value' : 'value') + '" required>' +
|
|
1144
1158
|
'<button type="submit">Save</button>' +
|
|
@@ -1146,10 +1160,52 @@ export const agentsConfigPageHtml = `<!doctype html>
|
|
|
1146
1160
|
'</tr>';
|
|
1147
1161
|
}
|
|
1148
1162
|
|
|
1163
|
+
// One card per ability, matching the same .source/.source-head/
|
|
1164
|
+
// status-ok/status-error look Gateway Tools sources already use — so
|
|
1165
|
+
// an operator scanning the tab sees, per ability, whether it's fully
|
|
1166
|
+
// configured or not, instead of hunting through one long flat table
|
|
1167
|
+
// for rows that belong to whichever ability they're actually trying to
|
|
1168
|
+
// set up right now.
|
|
1169
|
+
function renderEnvAbilityCard(abilityName, vars) {
|
|
1170
|
+
var missing = vars.filter(function (v) { return !v.set; }).length;
|
|
1171
|
+
var statusHtml = missing === 0
|
|
1172
|
+
? '<span class="status-ok">all set</span>'
|
|
1173
|
+
: '<span class="status-error">' + missing + ' of ' + vars.length + ' not set</span>';
|
|
1174
|
+
var rows = vars.map(renderEnvRow).join('');
|
|
1175
|
+
return '<div class="source">' +
|
|
1176
|
+
'<div class="source-head"><h4>' + escapeHtml(abilityName) + '</h4>' + statusHtml + '</div>' +
|
|
1177
|
+
'<table><thead><tr><th>Name</th><th style="max-width:320px">Description</th><th>Current value</th><th>Set value</th></tr></thead><tbody>' + rows + '</tbody></table>' +
|
|
1178
|
+
'</div>';
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1149
1181
|
function renderEnvConfigHtml(vars) {
|
|
1150
1182
|
if (!vars.length) return '<p class="hint">No installed ability has declared any environment variables for this agent yet.</p>';
|
|
1151
|
-
|
|
1152
|
-
|
|
1183
|
+
|
|
1184
|
+
var missingCount = vars.filter(function (v) { return !v.set; }).length;
|
|
1185
|
+
var summaryHtml = '<p class="hint">' + vars.length + ' environment variable' + (vars.length === 1 ? '' : 's') + ' across every installed ability' +
|
|
1186
|
+
(missingCount ? ' — <span class="error">' + missingCount + ' still not set</span>.' : ' — all set.') + '</p>';
|
|
1187
|
+
|
|
1188
|
+
// Grouped by declaring ability, not a single flat list — a var
|
|
1189
|
+
// declared by more than one ability (rare, but see renderEnvRow's
|
|
1190
|
+
// own comment) appears once under each, since either ability's own
|
|
1191
|
+
// card is a place an operator setting that ability up would
|
|
1192
|
+
// reasonably look for it.
|
|
1193
|
+
var byAbility = {};
|
|
1194
|
+
var abilityNames = [];
|
|
1195
|
+
vars.forEach(function (v) {
|
|
1196
|
+
v.abilityNames.forEach(function (abilityName) {
|
|
1197
|
+
if (!byAbility[abilityName]) {
|
|
1198
|
+
byAbility[abilityName] = [];
|
|
1199
|
+
abilityNames.push(abilityName);
|
|
1200
|
+
}
|
|
1201
|
+
byAbility[abilityName].push(v);
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
abilityNames.sort();
|
|
1205
|
+
|
|
1206
|
+
return summaryHtml + abilityNames.map(function (abilityName) {
|
|
1207
|
+
return renderEnvAbilityCard(abilityName, byAbility[abilityName]);
|
|
1208
|
+
}).join('');
|
|
1153
1209
|
}
|
|
1154
1210
|
|
|
1155
1211
|
function envContentEl() {
|
package/dist/web/env-admin.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export interface DeclaredEnvVar {
|
|
|
9
9
|
* an array, not a single name. */
|
|
10
10
|
abilityNames: string[];
|
|
11
11
|
set: boolean;
|
|
12
|
+
/** The live value, but only when `secret` is false — a secret is never
|
|
13
|
+
* echoed back once set, same rule this file's own top comment and
|
|
14
|
+
* web/http-tool-admin.ts's `{{ENV_VAR}}` header handling already
|
|
15
|
+
* follow. Undefined whenever `secret` is true or `set` is false. */
|
|
16
|
+
value?: string;
|
|
12
17
|
}
|
|
13
18
|
/** Every env var any ability installed for `agentName` declared it
|
|
14
19
|
* needs, merged by name. There's one .env per *project*, not per agent
|
package/dist/web/env-admin.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Backs the Admin UI's "Environment" section — every env var an ability
|
|
2
2
|
// (see ABILITIES.md, bin/ability-manager.ts) declared as required,
|
|
3
3
|
// across every ability installed for an agent, with set/not-set status
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// and, for a non-secret var, its live value (so an operator can actually
|
|
5
|
+
// tell what's configured, not just that something is). A value marked
|
|
6
|
+
// `secret` is never echoed back once set — same never-echo-a-secret rule
|
|
7
|
+
// web/http-tool-admin.ts's own `{{ENV_VAR}}` header handling already
|
|
8
|
+
// establishes for a tool's own secrets.
|
|
7
9
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
10
|
import { join } from 'node:path';
|
|
9
11
|
import { agentDir } from '../core/gateway-tools.js';
|
|
@@ -51,14 +53,18 @@ export function listDeclaredEnvVars(agentName) {
|
|
|
51
53
|
if (existing) {
|
|
52
54
|
existing.abilityNames.push(abilityName);
|
|
53
55
|
existing.secret = existing.secret || decl.secret === true;
|
|
56
|
+
if (existing.secret)
|
|
57
|
+
existing.value = undefined;
|
|
54
58
|
continue;
|
|
55
59
|
}
|
|
60
|
+
const rawValue = process.env[decl.name];
|
|
56
61
|
byName.set(decl.name, {
|
|
57
62
|
name: decl.name,
|
|
58
63
|
description: decl.description,
|
|
59
64
|
secret: decl.secret === true,
|
|
60
65
|
abilityNames: [abilityName],
|
|
61
|
-
set:
|
|
66
|
+
set: rawValue !== undefined,
|
|
67
|
+
value: decl.secret === true ? undefined : rawValue,
|
|
62
68
|
});
|
|
63
69
|
}
|
|
64
70
|
}
|