create-loopengine 0.1.21 → 0.1.22
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/package.json +1 -1
- package/template/adapters/http.ts +63 -0
- package/template/package.json +1 -1
package/package.json
CHANGED
|
@@ -85,6 +85,9 @@ import {
|
|
|
85
85
|
deleteSkill,
|
|
86
86
|
SkillInvalidIdError,
|
|
87
87
|
SkillNotFoundError,
|
|
88
|
+
listDeclaredEnvVars,
|
|
89
|
+
setEnvVar,
|
|
90
|
+
EnvVarNameError,
|
|
88
91
|
listSkillgardenCatalog,
|
|
89
92
|
readSkillgardenCatalogEntry,
|
|
90
93
|
addSkillgardenSkillToAgent,
|
|
@@ -921,6 +924,53 @@ function handleSkillDelete(res: ServerResponse, agentName: string, skillId: stri
|
|
|
921
924
|
res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ ok: true }))
|
|
922
925
|
}
|
|
923
926
|
|
|
927
|
+
// Backs the Admin UI's "Environment" section — every env var a package
|
|
928
|
+
// (see loopengine's own PACKAGES.md, bin/package-manager.ts) declared it
|
|
929
|
+
// needs for this agent, with set/not-set status only. Read-only, so no
|
|
930
|
+
// extra auth gate beyond the normal Basic Auth middleware every admin
|
|
931
|
+
// route already has.
|
|
932
|
+
function handleEnvGet(res: ServerResponse, agentName: string): void {
|
|
933
|
+
if (!getEntry(agentName)) {
|
|
934
|
+
res.writeHead(404, { 'content-type': 'application/json' }).end(JSON.stringify({ error: `unknown agent '${agentName}'` }))
|
|
935
|
+
return
|
|
936
|
+
}
|
|
937
|
+
res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(listDeclaredEnvVars(agentName)))
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// Writes a raw secret value into .env — meaningfully more sensitive than
|
|
941
|
+
// the rest of the admin surface (config/business data vs. an actual
|
|
942
|
+
// credential), so unlike every other route here, this one refuses
|
|
943
|
+
// outright when LOOPENGINE_ADMIN_AUTH isn't set at all, rather than just
|
|
944
|
+
// warning at startup and proceeding open like the rest of this file does
|
|
945
|
+
// (see loopengine's own PACKAGES.md, "Managing package secrets in the
|
|
946
|
+
// Admin UI" — LOOPENGINE_ADMIN_AUTH being optional today is an
|
|
947
|
+
// acceptable gap for config, not for secrets).
|
|
948
|
+
async function handleEnvPut(req: IncomingMessage, res: ServerResponse, agentName: string, varName: string): Promise<void> {
|
|
949
|
+
if (!adminAuth) {
|
|
950
|
+
res.writeHead(403, { 'content-type': 'application/json' }).end(
|
|
951
|
+
JSON.stringify({ error: 'Refusing to set an env var without LOOPENGINE_ADMIN_AUTH configured — set it before managing secrets through this route.' }),
|
|
952
|
+
)
|
|
953
|
+
return
|
|
954
|
+
}
|
|
955
|
+
if (!getEntry(agentName)) {
|
|
956
|
+
res.writeHead(404, { 'content-type': 'application/json' }).end(JSON.stringify({ error: `unknown agent '${agentName}'` }))
|
|
957
|
+
return
|
|
958
|
+
}
|
|
959
|
+
const body = await readJsonBody(req)
|
|
960
|
+
if (typeof body.value !== 'string') {
|
|
961
|
+
res.writeHead(400, { 'content-type': 'application/json' }).end(JSON.stringify({ error: 'value is required' }))
|
|
962
|
+
return
|
|
963
|
+
}
|
|
964
|
+
try {
|
|
965
|
+
setEnvVar(varName, body.value)
|
|
966
|
+
} catch (err) {
|
|
967
|
+
const status = err instanceof EnvVarNameError ? 400 : 500
|
|
968
|
+
res.writeHead(status, { 'content-type': 'application/json' }).end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
|
|
969
|
+
return
|
|
970
|
+
}
|
|
971
|
+
res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ ok: true }))
|
|
972
|
+
}
|
|
973
|
+
|
|
924
974
|
// Backs the Skills tab's "Browse skillgarden catalog" section — a
|
|
925
975
|
// read-only, agent-independent list of everything skillgarden ships in
|
|
926
976
|
// its own bundled registry (see loopengine's own web/skillgarden-admin.ts).
|
|
@@ -2120,6 +2170,19 @@ const server = createServer(async (req, res) => {
|
|
|
2120
2170
|
return
|
|
2121
2171
|
}
|
|
2122
2172
|
|
|
2173
|
+
// Backs the Admin UI's "Environment" section — see
|
|
2174
|
+
// handleEnvGet/handleEnvPut's own doc comments above.
|
|
2175
|
+
const envListMatch = pathname.match(/^\/agents\/([^/]+)\/env$/)
|
|
2176
|
+
if (envListMatch && req.method === 'GET') {
|
|
2177
|
+
handleEnvGet(res, decodeURIComponent(envListMatch[1]))
|
|
2178
|
+
return
|
|
2179
|
+
}
|
|
2180
|
+
const envVarMatch = pathname.match(/^\/agents\/([^/]+)\/env\/([^/]+)$/)
|
|
2181
|
+
if (envVarMatch && req.method === 'PUT') {
|
|
2182
|
+
await handleEnvPut(req, res, decodeURIComponent(envVarMatch[1]), decodeURIComponent(envVarMatch[2]))
|
|
2183
|
+
return
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2123
2186
|
// Backs the Skills tab's "Browse skillgarden catalog" section — see
|
|
2124
2187
|
// the three handlers above it.
|
|
2125
2188
|
if (req.method === 'GET' && pathname === '/skillgarden-catalog') {
|