zjbar-opencode 1.1.5 → 1.1.7
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/dist/index.js +58 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -61,7 +61,7 @@ function shouldNotify(hookEvent, paneId, termProgram) {
|
|
|
61
61
|
}
|
|
62
62
|
return true;
|
|
63
63
|
}
|
|
64
|
-
function sendNotification(hookEvent, paneId, zellijSession, termProgram) {
|
|
64
|
+
function sendNotification(hookEvent, paneId, zellijSession, termProgram, summary) {
|
|
65
65
|
const appName = "OpenCode";
|
|
66
66
|
const iconFile = "opencode-logo.png";
|
|
67
67
|
const pluginDir = join(homedir(), ".config", "zellij", "plugins");
|
|
@@ -71,15 +71,15 @@ function sendNotification(hookEvent, paneId, zellijSession, termProgram) {
|
|
|
71
71
|
switch (hookEvent) {
|
|
72
72
|
case "PermissionRequest":
|
|
73
73
|
title = `⚠ ${appName}`;
|
|
74
|
-
message = "Permission requested";
|
|
74
|
+
message = summary || "Permission requested";
|
|
75
75
|
break;
|
|
76
76
|
case "Stop":
|
|
77
77
|
title = `✅ ${appName}`;
|
|
78
|
-
message = "Task completed";
|
|
78
|
+
message = summary || "Task completed";
|
|
79
79
|
break;
|
|
80
80
|
case "Notification":
|
|
81
81
|
title = appName;
|
|
82
|
-
message = "Notification received";
|
|
82
|
+
message = summary || "Notification received";
|
|
83
83
|
break;
|
|
84
84
|
default:
|
|
85
85
|
title = appName;
|
|
@@ -107,13 +107,47 @@ function sendNotification(hookEvent, paneId, zellijSession, termProgram) {
|
|
|
107
107
|
execFileCb("notify-send", [title, message]);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
|
|
110
|
+
function cleanAndTruncate(text, maxLen = 120) {
|
|
111
|
+
let cleaned = text.replace(/\*\*/g, "").replace(/\*/g, "").replace(/`/g, "").replace(/^#+ /gm, "").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\n/g, " ").replace(/ {2,}/g, " ").trim();
|
|
112
|
+
if (cleaned.length > maxLen) {
|
|
113
|
+
cleaned = cleaned.slice(0, maxLen - 3);
|
|
114
|
+
const lastSpace = cleaned.lastIndexOf(" ");
|
|
115
|
+
if (lastSpace > 0)
|
|
116
|
+
cleaned = cleaned.slice(0, lastSpace);
|
|
117
|
+
cleaned += "...";
|
|
118
|
+
}
|
|
119
|
+
return cleaned;
|
|
120
|
+
}
|
|
121
|
+
async function getSessionSummary(client, sessionId) {
|
|
122
|
+
const res = await client.session.messages({
|
|
123
|
+
path: { id: sessionId }
|
|
124
|
+
});
|
|
125
|
+
if (!res.data)
|
|
126
|
+
return null;
|
|
127
|
+
const messages = Array.isArray(res.data) ? res.data : [];
|
|
128
|
+
for (let i = messages.length - 1;i >= 0; i--) {
|
|
129
|
+
const msg = messages[i];
|
|
130
|
+
if (msg.info?.role !== "assistant")
|
|
131
|
+
continue;
|
|
132
|
+
if (!msg.parts)
|
|
133
|
+
continue;
|
|
134
|
+
for (let j = msg.parts.length - 1;j >= 0; j--) {
|
|
135
|
+
const part = msg.parts[j];
|
|
136
|
+
if (part.type === "text" && part.text) {
|
|
137
|
+
return cleanAndTruncate(part.text);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
var ZjbarPlugin = async ({ directory, client }) => {
|
|
111
144
|
const zellijSession = process.env.ZELLIJ_SESSION_NAME;
|
|
112
145
|
const paneId = process.env.ZELLIJ_PANE_ID;
|
|
113
146
|
if (!zellijSession || !paneId)
|
|
114
147
|
return {};
|
|
115
148
|
const sessionId = crypto.randomUUID();
|
|
116
149
|
const termProgram = process.env.TERM_PROGRAM || null;
|
|
150
|
+
let activeSessionId = null;
|
|
117
151
|
let zellijBin = "zellij";
|
|
118
152
|
try {
|
|
119
153
|
const { execFileSync } = __require("node:child_process");
|
|
@@ -126,7 +160,7 @@ var ZjbarPlugin = async ({ directory }) => {
|
|
|
126
160
|
}
|
|
127
161
|
}
|
|
128
162
|
}
|
|
129
|
-
function sendToZjbar(hookEvent, toolName) {
|
|
163
|
+
function sendToZjbar(hookEvent, toolName, summary) {
|
|
130
164
|
const payload = JSON.stringify({
|
|
131
165
|
source: "opencode",
|
|
132
166
|
pane_id: parseInt(paneId, 10),
|
|
@@ -148,7 +182,7 @@ var ZjbarPlugin = async ({ directory }) => {
|
|
|
148
182
|
], { detached: true, stdio: "ignore" });
|
|
149
183
|
child.unref();
|
|
150
184
|
if (shouldNotify(hookEvent, paneId, termProgram)) {
|
|
151
|
-
sendNotification(hookEvent, paneId, zellijSession, termProgram);
|
|
185
|
+
sendNotification(hookEvent, paneId, zellijSession, termProgram, summary);
|
|
152
186
|
}
|
|
153
187
|
}
|
|
154
188
|
sendToZjbar("SessionStart");
|
|
@@ -157,18 +191,31 @@ var ZjbarPlugin = async ({ directory }) => {
|
|
|
157
191
|
const ev = event;
|
|
158
192
|
switch (ev.type) {
|
|
159
193
|
case "session.created":
|
|
194
|
+
activeSessionId = ev.properties?.sessionID || null;
|
|
160
195
|
sendToZjbar("SessionStart");
|
|
161
196
|
break;
|
|
162
|
-
case "session.idle":
|
|
163
|
-
|
|
197
|
+
case "session.idle": {
|
|
198
|
+
const sid = ev.properties?.sessionID || activeSessionId;
|
|
199
|
+
let summary = null;
|
|
200
|
+
if (sid && client) {
|
|
201
|
+
try {
|
|
202
|
+
summary = await getSessionSummary(client, sid);
|
|
203
|
+
} catch {}
|
|
204
|
+
}
|
|
205
|
+
sendToZjbar("Stop", null, summary);
|
|
164
206
|
break;
|
|
207
|
+
}
|
|
165
208
|
case "session.deleted":
|
|
166
209
|
sendToZjbar("SessionEnd");
|
|
167
210
|
break;
|
|
168
|
-
case "permission.asked":
|
|
169
|
-
|
|
211
|
+
case "permission.asked": {
|
|
212
|
+
const perm = ev.properties;
|
|
213
|
+
const permTitle = perm?.title || null;
|
|
214
|
+
sendToZjbar("PermissionRequest", null, permTitle);
|
|
170
215
|
break;
|
|
216
|
+
}
|
|
171
217
|
case "message.created":
|
|
218
|
+
activeSessionId = ev.properties?.info?.sessionID || activeSessionId;
|
|
172
219
|
sendToZjbar("UserPromptSubmit");
|
|
173
220
|
break;
|
|
174
221
|
}
|