opencode-zellij 0.0.16 → 0.0.18
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/README.md +13 -2
- package/README.zh.md +13 -2
- package/dist/index.d.mts +9 -107
- package/dist/index.mjs +220 -709
- package/dist/index.mjs.map +1 -1
- package/dist/pane-watchdog-runner.mjs +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -76,7 +76,6 @@ Optional sidecar config files are loaded from `~/.config/opencode/opencode-zelli
|
|
|
76
76
|
```jsonc
|
|
77
77
|
{
|
|
78
78
|
"$schema": "https://raw.githubusercontent.com/maou-shonen/opencode-zellij/main/opencode-zellij.schema.json",
|
|
79
|
-
"autoUpdate": true,
|
|
80
79
|
"pty": {
|
|
81
80
|
"enabled": true,
|
|
82
81
|
"sudoPane": "allow" // allow, deny, or hide
|
|
@@ -85,7 +84,7 @@ Optional sidecar config files are loaded from `~/.config/opencode/opencode-zelli
|
|
|
85
84
|
}
|
|
86
85
|
```
|
|
87
86
|
|
|
88
|
-
Set `
|
|
87
|
+
Set `pty.enabled` or `tabTitle.enabled` to `false` to turn those features off.
|
|
89
88
|
|
|
90
89
|
## Dynamic tab title
|
|
91
90
|
|
|
@@ -99,6 +98,18 @@ When OpenCode runs inside Zellij, the plugin updates the current tab title to sh
|
|
|
99
98
|
|
|
100
99
|
The title is updated best-effort from OpenCode session, question, permission, and branch events.
|
|
101
100
|
|
|
101
|
+
## Pane completion event
|
|
102
|
+
|
|
103
|
+
When a plugin-created pane exits, the plugin immediately calls `client.session.promptAsync()` (falling back to `client.session.prompt()`) on the OpenCode session that owns the pane, so the agent wakes up and sees something like:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
[zellij_pty] pane terminal_742 exit=0 — call zellij_pty_read to read, then zellij_pty_kill to close.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The prompt is fired exactly once per pane terminal event (de-duplicated by `paneId` + `event.id`), even if multiple terminal signals arrive (e.g. process exit followed by pane close). The plugin only targets the session that owns the pane — a different session's prompt is never touched.
|
|
110
|
+
|
|
111
|
+
If `client.session.prompt` rejects (e.g. the session is busy with a `MessageAbortedError`), the plugin logs at debug level and continues without retrying. The OpenCode server handles prompt scheduling.
|
|
112
|
+
|
|
102
113
|
## Pane cleanup watchdog
|
|
103
114
|
|
|
104
115
|
When the plugin creates a pane, it also starts a small detached Node.js watchdog process for that OpenCode plugin instance. The watchdog keeps a per-instance registry under `$XDG_RUNTIME_DIR/opencode-zellij-*` (or the system temp directory), watches the owning OpenCode process, and closes plugin-created panes if OpenCode exits before normal plugin cleanup can run, such as when leaving with Ctrl-D.
|
package/README.zh.md
CHANGED
|
@@ -76,7 +76,6 @@ OpenCode 會在啟動時自動安裝 npm plugins。Zellij 也必須已安裝,
|
|
|
76
76
|
```jsonc
|
|
77
77
|
{
|
|
78
78
|
"$schema": "https://raw.githubusercontent.com/maou-shonen/opencode-zellij/main/opencode-zellij.schema.json",
|
|
79
|
-
"autoUpdate": true,
|
|
80
79
|
"pty": {
|
|
81
80
|
"enabled": true,
|
|
82
81
|
"sudoPane": "allow" // allow, deny, or hide
|
|
@@ -85,7 +84,7 @@ OpenCode 會在啟動時自動安裝 npm plugins。Zellij 也必須已安裝,
|
|
|
85
84
|
}
|
|
86
85
|
```
|
|
87
86
|
|
|
88
|
-
將 `
|
|
87
|
+
將 `pty.enabled` 或 `tabTitle.enabled` 設為 `false` 可關閉對應功能。
|
|
89
88
|
|
|
90
89
|
## 動態 tab title
|
|
91
90
|
|
|
@@ -99,6 +98,18 @@ OpenCode 會在啟動時自動安裝 npm plugins。Zellij 也必須已安裝,
|
|
|
99
98
|
|
|
100
99
|
Title 會 best-effort 根據 OpenCode session、question、permission 與 branch events 更新。
|
|
101
100
|
|
|
101
|
+
## Pane 完成事件
|
|
102
|
+
|
|
103
|
+
當 plugin 建立的 pane 結束時,plugin 會立刻呼叫 `client.session.promptAsync()`(找不到時 fallback 到 `client.session.prompt()`)對擁有該 pane 的 OpenCode session 主動推一則通知,讓 agent 馬上醒過來並看到類似:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
[zellij_pty] pane terminal_742 exit=0 — call zellij_pty_read to read, then zellij_pty_kill to close.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
每一個 pane 的 terminal event 只會觸發一次 prompt(用 `paneId` + `event.id` 去重),即使 process exit 之後又收到 pane close 也只會送一次。Plugin 只會對擁有該 pane 的 session 發送 prompt——其他 session 完全不會被影響。
|
|
110
|
+
|
|
111
|
+
如果 `client.session.prompt` 拒絕(例如 session 正在忙、收到 `MessageAbortedError`),plugin 會用 debug 層級 log 然後繼續,不重試。Prompt 的排程交給 OpenCode server 處理。
|
|
112
|
+
|
|
102
113
|
## Pane cleanup watchdog
|
|
103
114
|
|
|
104
115
|
當 plugin 建立 pane 時,也會為該 OpenCode plugin instance 啟動一個小型 detached Node.js watchdog process。watchdog 會把 per-instance registry 放在 `$XDG_RUNTIME_DIR/opencode-zellij-*`(或系統 temp directory),監控擁有該 registry 的 OpenCode process,並在 OpenCode 還沒來得及執行正常 plugin cleanup 就退出時關閉 plugin 建立的 panes,例如使用 Ctrl-D 離開。
|
package/dist/index.d.mts
CHANGED
|
@@ -1,56 +1,5 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
import { Plugin } from "@opencode-ai/plugin";
|
|
3
2
|
|
|
4
|
-
//#region src/auto-update.d.ts
|
|
5
|
-
type ExecFileLike = (file: string, args: string[], options: {
|
|
6
|
-
cwd: string;
|
|
7
|
-
timeout?: number;
|
|
8
|
-
}) => Promise<{
|
|
9
|
-
stdout: string;
|
|
10
|
-
stderr: string;
|
|
11
|
-
}>;
|
|
12
|
-
interface CheckOptions {
|
|
13
|
-
importMetaUrl: string;
|
|
14
|
-
fetchImpl?: typeof fetch;
|
|
15
|
-
execImpl?: ExecFileLike;
|
|
16
|
-
}
|
|
17
|
-
type UpdateResult = {
|
|
18
|
-
type: 'skipped';
|
|
19
|
-
reason: string;
|
|
20
|
-
} | {
|
|
21
|
-
type: 'up-to-date';
|
|
22
|
-
currentVersion: string;
|
|
23
|
-
} | {
|
|
24
|
-
type: 'updated';
|
|
25
|
-
fromVersion: string;
|
|
26
|
-
toVersion: string;
|
|
27
|
-
} | {
|
|
28
|
-
type: 'failed';
|
|
29
|
-
currentVersion: string;
|
|
30
|
-
latestVersion: string;
|
|
31
|
-
reason: string;
|
|
32
|
-
};
|
|
33
|
-
declare function checkAndUpdate(options: CheckOptions): Promise<UpdateResult>;
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/config.d.ts
|
|
36
|
-
declare const completionNotificationModeSchema: z.ZodEnum<{
|
|
37
|
-
off: "off";
|
|
38
|
-
queue: "queue";
|
|
39
|
-
toast: "toast";
|
|
40
|
-
"queue+toast": "queue+toast";
|
|
41
|
-
prompt: "prompt";
|
|
42
|
-
}>;
|
|
43
|
-
interface CompletionNotificationPromptConfig {
|
|
44
|
-
requireIdle: boolean;
|
|
45
|
-
cooldownMs: number;
|
|
46
|
-
maxAttempts: number;
|
|
47
|
-
}
|
|
48
|
-
interface CompletionNotificationConfig {
|
|
49
|
-
mode: CompletionNotificationMode;
|
|
50
|
-
prompt: CompletionNotificationPromptConfig;
|
|
51
|
-
}
|
|
52
|
-
type CompletionNotificationMode = z.infer<typeof completionNotificationModeSchema>;
|
|
53
|
-
//#endregion
|
|
54
3
|
//#region src/pty/session.d.ts
|
|
55
4
|
type SessionStatus = 'running' | 'exited' | 'killed' | 'unknown' | 'terminal';
|
|
56
5
|
type SessionTerminalReason = 'pane_closed' | 'exit_marker' | 'read_cleanup' | 'subscriber_exit' | 'subscriber_error' | 'session_deleted';
|
|
@@ -59,7 +8,6 @@ interface SessionTombstone {
|
|
|
59
8
|
terminalAt: string;
|
|
60
9
|
tail: string[];
|
|
61
10
|
paneClosedAt: string | null;
|
|
62
|
-
notificationSentAt: string | null;
|
|
63
11
|
}
|
|
64
12
|
interface PtySession {
|
|
65
13
|
id: string;
|
|
@@ -82,41 +30,18 @@ interface PtySession {
|
|
|
82
30
|
}
|
|
83
31
|
//#endregion
|
|
84
32
|
//#region src/zellij/completion-notifications.d.ts
|
|
85
|
-
interface
|
|
86
|
-
tui?: {
|
|
87
|
-
showToast?: (options: {
|
|
88
|
-
body: {
|
|
89
|
-
title: string;
|
|
90
|
-
message: string;
|
|
91
|
-
variant: 'success' | 'error';
|
|
92
|
-
duration: number;
|
|
93
|
-
};
|
|
94
|
-
}) => Promise<unknown>;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
interface CompletionNotificationPromptClient {
|
|
33
|
+
interface CompletionNotificationClient {
|
|
98
34
|
session?: {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
directory: string;
|
|
102
|
-
};
|
|
103
|
-
}) => Promise<unknown>;
|
|
104
|
-
prompt?: (request: CompletionPromptRequest) => Promise<unknown>;
|
|
105
|
-
promptAsync?: (request: CompletionPromptRequest) => Promise<unknown>;
|
|
35
|
+
prompt?: ((request: any) => Promise<unknown>) | undefined;
|
|
36
|
+
promptAsync?: ((request: any) => Promise<unknown>) | undefined;
|
|
106
37
|
};
|
|
107
38
|
}
|
|
108
|
-
interface CompletionNotificationClient extends CompletionNotificationToastClient, CompletionNotificationPromptClient {}
|
|
109
39
|
interface CompletionNotificationContext {
|
|
110
40
|
client: CompletionNotificationClient;
|
|
111
|
-
|
|
112
|
-
config: CompletionNotificationConfig;
|
|
113
|
-
markSent: (sessionId: string) => void;
|
|
41
|
+
serverUrl?: URL | undefined;
|
|
114
42
|
}
|
|
115
43
|
interface CompletionNotificationManager {
|
|
116
44
|
handleSessionTerminal: (event: SubscriberTerminalEvent) => Promise<void>;
|
|
117
|
-
injectQueuedChatMessage: (input: unknown) => unknown;
|
|
118
|
-
clearSession: (sessionId: string) => void;
|
|
119
|
-
clearAll: () => void;
|
|
120
45
|
dispose: () => void;
|
|
121
46
|
}
|
|
122
47
|
interface SubscriberTerminalEvent {
|
|
@@ -124,40 +49,17 @@ interface SubscriberTerminalEvent {
|
|
|
124
49
|
reason: SessionTerminalReason;
|
|
125
50
|
session: PtySession;
|
|
126
51
|
}
|
|
127
|
-
interface CompletionPromptRequest {
|
|
128
|
-
path: {
|
|
129
|
-
id: string;
|
|
130
|
-
};
|
|
131
|
-
body: {
|
|
132
|
-
parts: Array<{
|
|
133
|
-
type: 'text';
|
|
134
|
-
text: string;
|
|
135
|
-
}>;
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
52
|
//#endregion
|
|
139
53
|
//#region src/plugin.d.ts
|
|
140
|
-
interface ToastClient {
|
|
141
|
-
tui: {
|
|
142
|
-
showToast: (options: {
|
|
143
|
-
body: {
|
|
144
|
-
title: string;
|
|
145
|
-
message: string;
|
|
146
|
-
variant: 'success' | 'error';
|
|
147
|
-
duration: number;
|
|
148
|
-
};
|
|
149
|
-
}) => Promise<unknown>;
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
declare function showUpdateToast(client: ToastClient, result: UpdateResult): void;
|
|
153
|
-
declare function startAutoUpdateCheck(client: ToastClient, importMetaUrl: string, check?: typeof checkAndUpdate): void;
|
|
154
54
|
interface ZellijPtyPluginDependencies {
|
|
155
|
-
importMetaUrl?: string | undefined;
|
|
156
|
-
startAutoUpdateCheck?: typeof startAutoUpdateCheck | undefined;
|
|
157
55
|
createCompletionNotifications?: (context: CompletionNotificationContext) => CompletionNotificationManager | undefined;
|
|
158
56
|
}
|
|
159
57
|
declare function createZellijPtyPlugin(dependencies?: ZellijPtyPluginDependencies): Plugin;
|
|
160
58
|
declare const ZellijPtyPlugin: Plugin;
|
|
59
|
+
declare const _default: {
|
|
60
|
+
id: string;
|
|
61
|
+
server: Plugin;
|
|
62
|
+
};
|
|
161
63
|
//#endregion
|
|
162
|
-
export {
|
|
64
|
+
export { ZellijPtyPlugin, ZellijPtyPluginDependencies, createZellijPtyPlugin, _default as default };
|
|
163
65
|
//# sourceMappingURL=index.d.mts.map
|