aboutsummaryrefslogtreecommitdiff
path: root/src/integration/assets/kilo
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-09 15:59:34 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-09 15:59:34 +0300
commitdf7880c54b8b5d337421cb4b1dd8daea27008801 (patch)
tree4d0cc6290ad71c413bac71cfaab4ef41ea017ecb /src/integration/assets/kilo
parenteeacb45b4b6ab4446c5bea1331f743fee5e5b9f8 (diff)
feat: update agent lifecycle integrations
Diffstat (limited to 'src/integration/assets/kilo')
-rw-r--r--src/integration/assets/kilo/herdr-agent-state.js159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/integration/assets/kilo/herdr-agent-state.js b/src/integration/assets/kilo/herdr-agent-state.js
new file mode 100644
index 00000000..aa1a0c1b
--- /dev/null
+++ b/src/integration/assets/kilo/herdr-agent-state.js
@@ -0,0 +1,159 @@
+// installed by herdr
+// managed by herdr; reinstalling or updating the integration overwrites this file.
+// add custom hooks/plugins beside this file instead of editing it.
+// HERDR_INTEGRATION_ID=kilo
+// HERDR_INTEGRATION_VERSION=1
+
+import net from "node:net";
+
+const SOURCE = "herdr:kilo";
+const AGENT = "kilo";
+let reportSeq = Date.now() * 1000;
+
+function nextReportSeq() {
+ reportSeq += 1;
+ return reportSeq;
+}
+
+function sessionIDFromProperties(properties) {
+ return typeof properties?.sessionID === "string" && properties.sessionID
+ ? properties.sessionID
+ : undefined;
+}
+
+function stateFromSessionStatus(status) {
+ if (typeof status !== "string") {
+ return undefined;
+ }
+ switch (status.toLowerCase()) {
+ case "idle":
+ return "idle";
+ case "active":
+ case "busy":
+ case "pending":
+ case "running":
+ case "streaming":
+ case "working":
+ return "working";
+ default:
+ return undefined;
+ }
+}
+
+function request(method, params) {
+ const paneId = process.env.HERDR_PANE_ID;
+ const socketPath = process.env.HERDR_SOCKET_PATH;
+
+ if (!paneId || !socketPath) {
+ return Promise.resolve();
+ }
+
+ const requestId = `${SOURCE}:${Date.now()}:${Math.floor(Math.random() * 1_000_000)
+ .toString()
+ .padStart(6, "0")}`;
+ const request = {
+ id: requestId,
+ method,
+ params: {
+ pane_id: paneId,
+ source: SOURCE,
+ agent: AGENT,
+ seq: nextReportSeq(),
+ ...params,
+ },
+ };
+
+ return new Promise((resolve) => {
+ const client = net.createConnection(socketPath, () => {
+ client.write(`${JSON.stringify(request)}\n`);
+ });
+
+ const finish = () => {
+ client.destroy();
+ resolve();
+ };
+
+ client.setTimeout(500, finish);
+ client.on("data", finish);
+ client.on("error", finish);
+ client.on("end", finish);
+ client.on("close", resolve);
+ });
+}
+
+function reportSession(sessionID) {
+ if (!sessionID) {
+ return Promise.resolve();
+ }
+ return request("pane.report_agent_session", { agent_session_id: sessionID });
+}
+
+function reportState(state, sessionID) {
+ const params = { state };
+ if (sessionID) {
+ params.agent_session_id = sessionID;
+ }
+ return request("pane.report_agent", params);
+}
+
+function releaseAgent() {
+ return request("pane.release_agent", {});
+}
+
+export const HerdrAgentStatePlugin = async () => {
+ if (
+ process.env.HERDR_ENV !== "1" ||
+ !process.env.HERDR_SOCKET_PATH ||
+ !process.env.HERDR_PANE_ID
+ ) {
+ return {};
+ }
+
+ return {
+ "chat.message": async ({ sessionID }) => {
+ await reportState("working", sessionID);
+ },
+ event: async ({ event }) => {
+ const type = event?.type;
+ const properties = event?.properties ?? {};
+ const sessionID = sessionIDFromProperties(properties);
+
+ switch (type) {
+ case "session.created":
+ case "session.updated":
+ await reportSession(sessionID);
+ break;
+ case "session.status": {
+ const state = stateFromSessionStatus(properties.status);
+ if (state) {
+ await reportState(state, sessionID);
+ } else {
+ await reportSession(sessionID);
+ }
+ break;
+ }
+ case "tool.execute.before":
+ case "tool.execute.after":
+ case "permission.replied":
+ case "question.replied":
+ case "question.rejected":
+ case "session.compacted":
+ await reportState("working", sessionID);
+ break;
+ case "permission.asked":
+ case "question.asked":
+ case "session.error":
+ await reportState("blocked", sessionID);
+ break;
+ case "session.idle":
+ await reportState("idle", sessionID);
+ break;
+ case "session.deleted":
+ await releaseAgent();
+ break;
+ default:
+ break;
+ }
+ },
+ };
+};