opencode-zellij 0.0.8 → 0.0.10

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.
@@ -4,6 +4,12 @@ import { appendFileSync, existsSync, readFileSync, rmSync } from "node:fs";
4
4
  //#region src/zellij/pane-watchdog-runner.ts
5
5
  const registryPath = process.argv[2];
6
6
  const pollIntervalMs = 1e3;
7
+ function writeWatchdogDebug(message, error) {
8
+ if (!process.env.ZELLIJ_PTY_DEBUG) return;
9
+ try {
10
+ appendFileSync(`${registryPath}.log`, `${(/* @__PURE__ */ new Date()).toISOString()} ${message}: ${error instanceof Error ? error.message : String(error)}\n`);
11
+ } catch (loggingError) {}
12
+ }
7
13
  if (!registryPath) process.exit(1);
8
14
  function sleep(ms) {
9
15
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -12,7 +18,8 @@ function linuxProcessStartTime(pid) {
12
18
  try {
13
19
  const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
14
20
  return stat.slice(stat.lastIndexOf(")") + 2).trim().split(/\s+/)[19] || null;
15
- } catch {
21
+ } catch (error) {
22
+ writeWatchdogDebug("linuxProcessStartTime failed", error);
16
23
  return null;
17
24
  }
18
25
  }
@@ -20,14 +27,16 @@ function readRegistry() {
20
27
  try {
21
28
  if (!existsSync(registryPath)) return null;
22
29
  return JSON.parse(readFileSync(registryPath, "utf8"));
23
- } catch {
30
+ } catch (error) {
31
+ writeWatchdogDebug("readRegistry failed", error);
24
32
  return null;
25
33
  }
26
34
  }
27
35
  function ownerAlive(registry) {
28
36
  try {
29
37
  process.kill(registry.ownerPid, 0);
30
- } catch {
38
+ } catch (error) {
39
+ writeWatchdogDebug("ownerAlive kill check failed", error);
31
40
  return false;
32
41
  }
33
42
  return !registry.ownerStartTime || linuxProcessStartTime(registry.ownerPid) === registry.ownerStartTime;
@@ -57,7 +66,7 @@ async function main() {
57
66
  function writeFatalError(error) {
58
67
  try {
59
68
  appendFileSync(`${registryPath}.log`, `${(/* @__PURE__ */ new Date()).toISOString()} ${error instanceof Error ? error.stack || error.message : String(error)}\n`);
60
- } catch {}
69
+ } catch (loggingError) {}
61
70
  }
62
71
  main().catch((error) => {
63
72
  writeFatalError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"pane-watchdog-runner.mjs","names":[],"sources":["../src/zellij/pane-watchdog-runner.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process'\nimport { appendFileSync, existsSync, readFileSync, rmSync } from 'node:fs'\nimport process from 'node:process'\n\ninterface WatchdogPane {\n paneId: string\n}\n\ninterface WatchdogRegistry {\n ownerPid: number\n ownerStartTime?: string | null | undefined\n zellijSessionName?: string | null | undefined\n panes?: WatchdogPane[] | undefined\n}\n\nconst registryPath = process.argv[2]\nconst pollIntervalMs = 1_000\n\nif (!registryPath)\n process.exit(1)\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction linuxProcessStartTime(pid: number): string | null {\n try {\n const stat = readFileSync(`/proc/${pid}/stat`, 'utf8')\n const fieldsAfterCommand = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\\s+/)\n return fieldsAfterCommand[19] || null\n }\n catch {\n // Missing /proc data is expected when the owner has exited or on non-Linux systems.\n return null\n }\n}\n\nfunction readRegistry(): WatchdogRegistry | null {\n try {\n if (!existsSync(registryPath!))\n return null\n return JSON.parse(readFileSync(registryPath!, 'utf8')) as WatchdogRegistry\n }\n catch {\n // A missing or corrupt registry cannot be used safely; let the watchdog exit.\n return null\n }\n}\n\nfunction ownerAlive(registry: WatchdogRegistry): boolean {\n try {\n process.kill(registry.ownerPid, 0)\n }\n catch {\n // process.kill(pid, 0) throws when the owner is gone or inaccessible.\n return false\n }\n\n return !registry.ownerStartTime || linuxProcessStartTime(registry.ownerPid) === registry.ownerStartTime\n}\n\nfunction closePane(registry: WatchdogRegistry, paneId: string): void {\n const args: string[] = []\n if (registry.zellijSessionName)\n args.push('--session', registry.zellijSessionName)\n args.push('action', 'close-pane', '--pane-id', paneId)\n spawnSync('zellij', args, { stdio: 'ignore', timeout: 2_000 })\n}\n\nasync function main(): Promise<void> {\n for (;;) {\n const registry = readRegistry()\n if (!registry)\n return\n\n if (!ownerAlive(registry)) {\n const finalRegistry = readRegistry() || registry\n for (const pane of finalRegistry.panes || []) {\n closePane(finalRegistry, pane.paneId)\n }\n rmSync(registryPath!, { force: true })\n return\n }\n\n await sleep(pollIntervalMs)\n }\n}\n\nfunction writeFatalError(error: unknown): void {\n try {\n appendFileSync(`${registryPath}.log`, `${new Date().toISOString()} ${error instanceof Error ? error.stack || error.message : String(error)}\\n`)\n }\n catch {\n // The watchdog has no stderr; if file logging also fails, exiting is the only safe fallback.\n }\n}\n\nmain().catch((error: unknown) => {\n writeFatalError(error)\n process.exit(1)\n})\n"],"mappings":";;;;AAeA,MAAM,eAAe,QAAQ,KAAK;AAClC,MAAM,iBAAiB;AAEvB,IAAI,CAAC,aACH,SAAQ,KAAK,EAAE;AAEjB,SAAS,MAAM,IAA2B;AACxC,QAAO,IAAI,SAAQ,YAAW,WAAW,SAAS,GAAG,CAAC;;AAGxD,SAAS,sBAAsB,KAA4B;AACzD,KAAI;EACF,MAAM,OAAO,aAAa,SAAS,IAAI,QAAQ,OAAO;AAEtD,SAD2B,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,MACrD,CAAC,OAAO;SAE7B;AAEJ,SAAO;;;AAIX,SAAS,eAAwC;AAC/C,KAAI;AACF,MAAI,CAAC,WAAW,aAAc,CAC5B,QAAO;AACT,SAAO,KAAK,MAAM,aAAa,cAAe,OAAO,CAAC;SAElD;AAEJ,SAAO;;;AAIX,SAAS,WAAW,UAAqC;AACvD,KAAI;AACF,UAAQ,KAAK,SAAS,UAAU,EAAE;SAE9B;AAEJ,SAAO;;AAGT,QAAO,CAAC,SAAS,kBAAkB,sBAAsB,SAAS,SAAS,KAAK,SAAS;;AAG3F,SAAS,UAAU,UAA4B,QAAsB;CACnE,MAAM,OAAiB,EAAE;AACzB,KAAI,SAAS,kBACX,MAAK,KAAK,aAAa,SAAS,kBAAkB;AACpD,MAAK,KAAK,UAAU,cAAc,aAAa,OAAO;AACtD,WAAU,UAAU,MAAM;EAAE,OAAO;EAAU,SAAS;EAAO,CAAC;;AAGhE,eAAe,OAAsB;AACnC,UAAS;EACP,MAAM,WAAW,cAAc;AAC/B,MAAI,CAAC,SACH;AAEF,MAAI,CAAC,WAAW,SAAS,EAAE;GACzB,MAAM,gBAAgB,cAAc,IAAI;AACxC,QAAK,MAAM,QAAQ,cAAc,SAAS,EAAE,CAC1C,WAAU,eAAe,KAAK,OAAO;AAEvC,UAAO,cAAe,EAAE,OAAO,MAAM,CAAC;AACtC;;AAGF,QAAM,MAAM,eAAe;;;AAI/B,SAAS,gBAAgB,OAAsB;AAC7C,KAAI;AACF,iBAAe,GAAG,aAAa,OAAO,oBAAG,IAAI,MAAM,EAAC,aAAa,CAAC,GAAG,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM,CAAC,IAAI;SAE3I;;AAKR,MAAM,CAAC,OAAO,UAAmB;AAC/B,iBAAgB,MAAM;AACtB,SAAQ,KAAK,EAAE;EACf"}
1
+ {"version":3,"file":"pane-watchdog-runner.mjs","names":[],"sources":["../src/zellij/pane-watchdog-runner.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process'\nimport { appendFileSync, existsSync, readFileSync, rmSync } from 'node:fs'\nimport process from 'node:process'\n\nconst registryPath = process.argv[2]\nconst pollIntervalMs = 1_000\n\nfunction writeWatchdogDebug(message: string, error: unknown): void {\n if (!process.env.ZELLIJ_PTY_DEBUG)\n return\n\n try {\n appendFileSync(`${registryPath}.log`, `${new Date().toISOString()} ${message}: ${error instanceof Error ? error.message : String(error)}\\n`)\n }\n catch (loggingError) {\n void loggingError\n // The watchdog has no stderr; if file logging fails, there is nowhere else to report diagnostics.\n }\n}\n\ninterface WatchdogPane {\n paneId: string\n}\n\ninterface WatchdogRegistry {\n ownerPid: number\n ownerStartTime?: string | null | undefined\n zellijSessionName?: string | null | undefined\n panes?: WatchdogPane[] | undefined\n}\n\nif (!registryPath)\n process.exit(1)\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction linuxProcessStartTime(pid: number): string | null {\n try {\n const stat = readFileSync(`/proc/${pid}/stat`, 'utf8')\n const fieldsAfterCommand = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\\s+/)\n return fieldsAfterCommand[19] || null\n }\n catch (error) {\n // Missing /proc data is expected when the owner has exited or on non-Linux systems.\n writeWatchdogDebug('linuxProcessStartTime failed', error)\n return null\n }\n}\n\nfunction readRegistry(): WatchdogRegistry | null {\n try {\n if (!existsSync(registryPath!))\n return null\n return JSON.parse(readFileSync(registryPath!, 'utf8')) as WatchdogRegistry\n }\n catch (error) {\n // A missing or corrupt registry cannot be used safely; let the watchdog exit.\n writeWatchdogDebug('readRegistry failed', error)\n return null\n }\n}\n\nfunction ownerAlive(registry: WatchdogRegistry): boolean {\n try {\n process.kill(registry.ownerPid, 0)\n }\n catch (error) {\n // process.kill(pid, 0) throws when the owner is gone or inaccessible.\n writeWatchdogDebug('ownerAlive kill check failed', error)\n return false\n }\n\n return !registry.ownerStartTime || linuxProcessStartTime(registry.ownerPid) === registry.ownerStartTime\n}\n\nfunction closePane(registry: WatchdogRegistry, paneId: string): void {\n const args: string[] = []\n if (registry.zellijSessionName)\n args.push('--session', registry.zellijSessionName)\n args.push('action', 'close-pane', '--pane-id', paneId)\n spawnSync('zellij', args, { stdio: 'ignore', timeout: 2_000 })\n}\n\nasync function main(): Promise<void> {\n for (;;) {\n const registry = readRegistry()\n if (!registry)\n return\n\n if (!ownerAlive(registry)) {\n const finalRegistry = readRegistry() || registry\n for (const pane of finalRegistry.panes || []) {\n closePane(finalRegistry, pane.paneId)\n }\n rmSync(registryPath!, { force: true })\n return\n }\n\n await sleep(pollIntervalMs)\n }\n}\n\nfunction writeFatalError(error: unknown): void {\n try {\n appendFileSync(`${registryPath}.log`, `${new Date().toISOString()} ${error instanceof Error ? error.stack || error.message : String(error)}\\n`)\n }\n catch (loggingError) {\n void loggingError\n // The watchdog has no stderr; if file logging also fails, exiting is the only safe fallback.\n }\n}\n\nmain().catch((error: unknown) => {\n writeFatalError(error)\n process.exit(1)\n})\n"],"mappings":";;;;AAIA,MAAM,eAAe,QAAQ,KAAK;AAClC,MAAM,iBAAiB;AAEvB,SAAS,mBAAmB,SAAiB,OAAsB;AACjE,KAAI,CAAC,QAAQ,IAAI,iBACf;AAEF,KAAI;AACF,iBAAe,GAAG,aAAa,OAAO,oBAAG,IAAI,MAAM,EAAC,aAAa,CAAC,GAAG,QAAQ,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,IAAI;UAEvI,cAAc;;AAiBvB,IAAI,CAAC,aACH,SAAQ,KAAK,EAAE;AAEjB,SAAS,MAAM,IAA2B;AACxC,QAAO,IAAI,SAAQ,YAAW,WAAW,SAAS,GAAG,CAAC;;AAGxD,SAAS,sBAAsB,KAA4B;AACzD,KAAI;EACF,MAAM,OAAO,aAAa,SAAS,IAAI,QAAQ,OAAO;AAEtD,SAD2B,KAAK,MAAM,KAAK,YAAY,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,MACrD,CAAC,OAAO;UAE5B,OAAO;AAEZ,qBAAmB,gCAAgC,MAAM;AACzD,SAAO;;;AAIX,SAAS,eAAwC;AAC/C,KAAI;AACF,MAAI,CAAC,WAAW,aAAc,CAC5B,QAAO;AACT,SAAO,KAAK,MAAM,aAAa,cAAe,OAAO,CAAC;UAEjD,OAAO;AAEZ,qBAAmB,uBAAuB,MAAM;AAChD,SAAO;;;AAIX,SAAS,WAAW,UAAqC;AACvD,KAAI;AACF,UAAQ,KAAK,SAAS,UAAU,EAAE;UAE7B,OAAO;AAEZ,qBAAmB,gCAAgC,MAAM;AACzD,SAAO;;AAGT,QAAO,CAAC,SAAS,kBAAkB,sBAAsB,SAAS,SAAS,KAAK,SAAS;;AAG3F,SAAS,UAAU,UAA4B,QAAsB;CACnE,MAAM,OAAiB,EAAE;AACzB,KAAI,SAAS,kBACX,MAAK,KAAK,aAAa,SAAS,kBAAkB;AACpD,MAAK,KAAK,UAAU,cAAc,aAAa,OAAO;AACtD,WAAU,UAAU,MAAM;EAAE,OAAO;EAAU,SAAS;EAAO,CAAC;;AAGhE,eAAe,OAAsB;AACnC,UAAS;EACP,MAAM,WAAW,cAAc;AAC/B,MAAI,CAAC,SACH;AAEF,MAAI,CAAC,WAAW,SAAS,EAAE;GACzB,MAAM,gBAAgB,cAAc,IAAI;AACxC,QAAK,MAAM,QAAQ,cAAc,SAAS,EAAE,CAC1C,WAAU,eAAe,KAAK,OAAO;AAEvC,UAAO,cAAe,EAAE,OAAO,MAAM,CAAC;AACtC;;AAGF,QAAM,MAAM,eAAe;;;AAI/B,SAAS,gBAAgB,OAAsB;AAC7C,KAAI;AACF,iBAAe,GAAG,aAAa,OAAO,oBAAG,IAAI,MAAM,EAAC,aAAa,CAAC,GAAG,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM,CAAC,IAAI;UAE1I,cAAc;;AAMvB,MAAM,CAAC,OAAO,UAAmB;AAC/B,iBAAgB,MAAM;AACtB,SAAQ,KAAK,EAAE;EACf"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "opencode-zellij",
3
3
  "type": "module",
4
- "version": "0.0.8",
4
+ "version": "0.0.10",
5
5
  "description": "OpenCode plugin for Zellij-backed panes and workflow integrations.",
6
+ "license": "MIT",
6
7
  "repository": {
7
8
  "type": "git",
8
9
  "url": "https://github.com/maou-shonen/opencode-zellij"