feat: auto-reload tibi-server on api/ changes + skill docs for project registration

This commit is contained in:
2026-07-02 20:39:38 +00:00
parent 2d52272b2e
commit 3e8f6ec312
5 changed files with 150 additions and 50 deletions
+75 -7
View File
@@ -1,5 +1,6 @@
const esbuild = require("esbuild")
const fs = require("fs")
const http = require("http")
const path = require("path")
const config = require(process.cwd() + (process.argv?.length > 3 ? "/" + process.argv[3] : "/esbuild.config.js"))
@@ -71,15 +72,82 @@ switch (process.argv?.length > 2 ? process.argv[2] : "build") {
bs.reload()
}
})
const watcher = watch(config.watch.path)
log("watching files...")
watcher.on("change", function (path) {
log(`${path} changed`, true)
build(true).then(() => {
if (bs) {
bs.reload()
// Trigger tibi-server project reload for api/ changes
const apiDir = path.resolve("api") + "/"
let reloadInFlight = false
let reloadQueued = false
function reloadTibi() {
if (!config.tibiReloadUrl || !config.adminToken) {
log("tibi-server reload: missing URL or token (running in mock mode?)")
return
}
if (reloadInFlight) {
reloadQueued = true
log("tibi-server reload: already in flight, queuing another...")
return
}
reloadInFlight = true
const parts = new URL(config.tibiReloadUrl)
const opts = {
hostname: parts.hostname,
port: parts.port,
path: parts.pathname,
method: "POST",
headers: { Authorization: "Bearer " + config.adminToken },
timeout: 5000,
}
let body = ""
const finishReload = () => {
reloadInFlight = false
if (reloadQueued) {
reloadQueued = false
log("tibi-server reload: executing queued reload...")
reloadTibi()
}
}
const req = http.request(opts, (res) => {
res.on("data", (chunk) => (body += chunk))
res.on("end", () => {
if (res.statusCode === 200) {
log("tibi-server reloaded ✓")
} else {
console.error(
"\x1b[33mtibi-server reload: HTTP " + res.statusCode + " — " + body.trim() + "\x1b[0m"
)
}
finishReload()
})
})
req.on("error", (e) => {
console.error("\x1b[33mtibi-server reload failed: " + e.message + "\x1b[0m")
finishReload()
})
req.end()
}
const { path: watchPaths, ignored: watchIgnored, ...watchRest } = config.watch
const watcher = watch(watchPaths, { ignored: watchIgnored, ...watchRest })
log("watching files...")
const DEBOUNCE_MS = 200
let frontendTimer, apiTimer
watcher.on("change", function (changedPath) {
log(`${changedPath} changed`, true)
if (changedPath.startsWith(apiDir)) {
clearTimeout(apiTimer)
apiTimer = setTimeout(() => {
log("api/ change detected → reloading tibi-server...")
reloadTibi()
}, DEBOUNCE_MS)
} else {
clearTimeout(frontendTimer)
frontendTimer = setTimeout(() => {
build(true).then(() => {
if (bs) {
bs.reload()
}
})
}, DEBOUNCE_MS)
}
})
break
default: