134 lines
4.5 KiB
Bash
134 lines
4.5 KiB
Bash
#!/bin/sh
|
|
set -eu
|
|
|
|
export HWLAB_SERVICE_ID="hwlab-agent-skills"
|
|
export HWLAB_ARTIFACT_KIND="skills-bundle"
|
|
export HWLAB_SERVICE_ENTRYPOINT="skills/hwlab-agent-runtime/SKILL.md"
|
|
export HWLAB_RUNTIME_MODE="${HWLAB_RUNTIME_MODE:-env-reuse-gitea-checkout}"
|
|
export HWLAB_COMMIT_ID="${HWLAB_BOOT_COMMIT:?HWLAB_BOOT_COMMIT is required}"
|
|
export HWLAB_REVISION="${HWLAB_BOOT_COMMIT}"
|
|
export HWLAB_SKILLS_COMMIT_ID="${HWLAB_SKILLS_COMMIT_ID:-${HWLAB_BOOT_COMMIT}}"
|
|
export HWLAB_IMAGE="${HWLAB_ENVIRONMENT_IMAGE:-${HWLAB_IMAGE:-}}"
|
|
export HWLAB_IMAGE_DIGEST="${HWLAB_ENVIRONMENT_DIGEST:-${HWLAB_IMAGE_DIGEST:-unknown}}"
|
|
export PORT="${PORT:-${HWLAB_PORT:-7430}}"
|
|
export HWLAB_PORT="$PORT"
|
|
|
|
bun_bin="${HWLAB_BUN_COMMAND:-}"
|
|
if [ -z "$bun_bin" ]; then
|
|
if command -v bun >/dev/null 2>&1; then
|
|
bun_bin="$(command -v bun)"
|
|
elif [ -x /usr/local/bin/bun ]; then
|
|
bun_bin="/usr/local/bin/bun"
|
|
elif [ -x ./node_modules/.bin/bun ]; then
|
|
bun_bin="./node_modules/.bin/bun"
|
|
else
|
|
echo "hwlab-agent-skills boot failed: bun not found" >&2
|
|
exit 127
|
|
fi
|
|
fi
|
|
|
|
cat > .hwlab-agent-skills-runtime.mjs <<'NODE'
|
|
import { Buffer } from "node:buffer";
|
|
import { createServer } from "node:http";
|
|
import { readdirSync } from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const serviceId = process.env.HWLAB_SERVICE_ID || "hwlab-agent-skills";
|
|
const environment = process.env.HWLAB_ENVIRONMENT || "v02";
|
|
const port = Number.parseInt(process.env.PORT || process.env.HWLAB_PORT || "7430", 10);
|
|
const processStartedAt = new Date();
|
|
|
|
function sendJson(response, statusCode, body) {
|
|
const payload = JSON.stringify(body, null, 2);
|
|
response.writeHead(statusCode, {
|
|
"content-type": "application/json; charset=utf-8",
|
|
"content-length": Buffer.byteLength(payload)
|
|
});
|
|
response.end(payload);
|
|
}
|
|
|
|
function imageTagFromReference(imageReference) {
|
|
const source = String(imageReference || "").trim();
|
|
const slashIndex = source.lastIndexOf("/");
|
|
const colonIndex = source.lastIndexOf(":");
|
|
if (colonIndex <= slashIndex) return null;
|
|
return source.slice(colonIndex + 1) || null;
|
|
}
|
|
|
|
function shortRevision(value) {
|
|
const source = String(value || "").trim();
|
|
return source.length >= 12 ? source.slice(0, 12) : source || "unknown";
|
|
}
|
|
|
|
function skillNames() {
|
|
const root = path.join(process.cwd(), "skills");
|
|
try {
|
|
return readdirSync(root, { withFileTypes: true })
|
|
.filter((item) => item.isDirectory())
|
|
.map((item) => item.name)
|
|
.sort();
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function healthPayload() {
|
|
const commitId = process.env.HWLAB_COMMIT_ID || process.env.HWLAB_BOOT_COMMIT || "unknown";
|
|
const imageReference = process.env.HWLAB_IMAGE || process.env.HWLAB_ENVIRONMENT_IMAGE || "unknown";
|
|
const names = skillNames();
|
|
return {
|
|
serviceId,
|
|
environment,
|
|
status: "ok",
|
|
artifactKind: "skills-bundle",
|
|
runtimeMode: process.env.HWLAB_RUNTIME_MODE || "env-reuse-gitea-checkout",
|
|
revision: process.env.HWLAB_REVISION || commitId,
|
|
commit: {
|
|
id: commitId,
|
|
source: process.env.HWLAB_BUILD_SOURCE || "gitea-runtime-checkout"
|
|
},
|
|
image: {
|
|
reference: imageReference,
|
|
tag: imageTagFromReference(imageReference) || shortRevision(commitId),
|
|
digest: process.env.HWLAB_IMAGE_DIGEST || process.env.HWLAB_ENVIRONMENT_DIGEST || "unknown"
|
|
},
|
|
boot: {
|
|
repo: process.env.HWLAB_BOOT_REPO || null,
|
|
commit: process.env.HWLAB_BOOT_COMMIT || null,
|
|
script: process.env.HWLAB_BOOT_SH || null
|
|
},
|
|
skills: {
|
|
root: `${process.cwd()}/skills`,
|
|
count: names.length,
|
|
names,
|
|
commitId: process.env.HWLAB_SKILLS_COMMIT_ID || commitId,
|
|
entrypoint: process.env.HWLAB_SERVICE_ENTRYPOINT || "skills/hwlab-agent-runtime/SKILL.md"
|
|
},
|
|
process: {
|
|
pid: process.pid,
|
|
startedAt: processStartedAt.toISOString(),
|
|
uptimeSeconds: Math.round((Date.now() - processStartedAt.getTime()) / 1000)
|
|
}
|
|
};
|
|
}
|
|
|
|
const server = createServer((request, response) => {
|
|
const url = new URL(request.url || "/", "http://hwlab-agent-skills.local");
|
|
if (url.pathname === "/health/live" || url.pathname === "/health") {
|
|
sendJson(response, 200, healthPayload());
|
|
return;
|
|
}
|
|
if (url.pathname === "/help") {
|
|
sendJson(response, 200, { serviceId, commands: ["GET /health", "GET /health/live", "GET /help"] });
|
|
return;
|
|
}
|
|
sendJson(response, 404, { error: "not_found", serviceId, path: url.pathname });
|
|
});
|
|
|
|
server.listen(port, "0.0.0.0", () => {
|
|
process.stdout.write(JSON.stringify({ serviceId, environment, status: "listening", port }) + "\n");
|
|
});
|
|
NODE
|
|
|
|
exec "$bun_bin" .hwlab-agent-skills-runtime.mjs
|