opencode-agent-tmux 1.1.3 → 1.1.8

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.
@@ -5,10 +5,34 @@ import { spawn, execSync } from "child_process";
5
5
  import { createServer } from "net";
6
6
  import { env, platform, exit, argv } from "process";
7
7
  import { existsSync } from "fs";
8
- import { join } from "path";
8
+ import { join, dirname } from "path";
9
9
  import { homedir } from "os";
10
+ import { fileURLToPath } from "url";
10
11
  var OPENCODE_PORT_START = parseInt(env.OPENCODE_PORT || "4096", 10);
11
12
  var OPENCODE_PORT_MAX = OPENCODE_PORT_START + 10;
13
+ var __filename = fileURLToPath(import.meta.url);
14
+ var __dirname = dirname(__filename);
15
+ function spawnPluginUpdater() {
16
+ if (env.OPENCODE_TMUX_DISABLE_UPDATES === "1") return;
17
+ const updaterPath = join(__dirname, "../scripts/update-plugins.js");
18
+ if (!existsSync(updaterPath)) return;
19
+ try {
20
+ const child = spawn(
21
+ process.execPath,
22
+ [updaterPath],
23
+ {
24
+ stdio: "ignore",
25
+ detached: true,
26
+ env: {
27
+ ...process.env,
28
+ OPENCODE_TMUX_UPDATE: "1"
29
+ }
30
+ }
31
+ );
32
+ child.unref();
33
+ } catch (error) {
34
+ }
35
+ }
12
36
  function findOpencodeBin() {
13
37
  try {
14
38
  const cmd = platform === "win32" ? "where opencode" : "which -a opencode";
@@ -60,7 +84,20 @@ function hasTmux() {
60
84
  return false;
61
85
  }
62
86
  }
87
+ function extractLogUpdateFlag(args) {
88
+ let logUpdate = false;
89
+ const cleaned = [];
90
+ for (const arg of args) {
91
+ if (arg === "--log-update" || arg.startsWith("--log-update=")) {
92
+ logUpdate = true;
93
+ continue;
94
+ }
95
+ cleaned.push(arg);
96
+ }
97
+ return { args: cleaned, logUpdate };
98
+ }
63
99
  async function main() {
100
+ spawnPluginUpdater();
64
101
  const opencodeBin = findOpencodeBin();
65
102
  if (!opencodeBin) {
66
103
  console.error("\u274C Error: Could not find 'opencode' binary.");
@@ -76,7 +113,13 @@ async function main() {
76
113
  console.warn(`\u26A0\uFE0F Port ${OPENCODE_PORT_START} is in use, using port ${port} instead`);
77
114
  }
78
115
  env.OPENCODE_PORT = port.toString();
79
- const args = argv.slice(2);
116
+ const rawArgs = argv.slice(2);
117
+ const { args, logUpdate } = extractLogUpdateFlag(rawArgs);
118
+ if (logUpdate) {
119
+ env.OPENCODE_AUTO_UPDATE_LOG_UPDATE = "true";
120
+ env.OPENCODE_AUTO_UPDATE_BYPASS_THROTTLE = "true";
121
+ env.OPENCODE_AUTO_UPDATE_DEBUG = "true";
122
+ }
80
123
  const childArgs = ["--port", port.toString(), ...args];
81
124
  const inTmux = !!env.TMUX;
82
125
  const tmuxAvailable = hasTmux();
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/scripts/update-plugins.ts
4
+ import { spawnSync } from "child_process";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import os from "os";
8
+ var HOME = os.homedir();
9
+ var CONFIG_PATH = path.join(HOME, ".config", "opencode", "opencode.json");
10
+ var STATE_DIR = path.join(HOME, ".config", "opencode", "opencode-agent-tmux");
11
+ var STATE_PATH = path.join(STATE_DIR, "update-state.json");
12
+ var UPDATE_INTERVAL_HOURS = 12;
13
+ function ensureStateDir() {
14
+ if (!fs.existsSync(STATE_DIR)) {
15
+ fs.mkdirSync(STATE_DIR, { recursive: true });
16
+ }
17
+ }
18
+ function shouldRunUpdate() {
19
+ try {
20
+ if (!fs.existsSync(STATE_PATH)) return true;
21
+ const raw = fs.readFileSync(STATE_PATH, "utf-8");
22
+ const parsed = JSON.parse(raw);
23
+ if (!parsed.lastRun) return true;
24
+ const lastRun = new Date(parsed.lastRun).getTime();
25
+ if (Number.isNaN(lastRun)) return true;
26
+ const diffHours = (Date.now() - lastRun) / (1e3 * 60 * 60);
27
+ return diffHours >= UPDATE_INTERVAL_HOURS;
28
+ } catch {
29
+ return true;
30
+ }
31
+ }
32
+ function writeLastRun() {
33
+ try {
34
+ ensureStateDir();
35
+ fs.writeFileSync(
36
+ STATE_PATH,
37
+ JSON.stringify({ lastRun: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
38
+ "utf-8"
39
+ );
40
+ } catch {
41
+ }
42
+ }
43
+ function normalizePluginName(name) {
44
+ const trimmed = name.trim();
45
+ if (!trimmed) return null;
46
+ if (trimmed.startsWith("./") || trimmed.startsWith("../")) return null;
47
+ if (trimmed.startsWith("file:") || trimmed.startsWith("git+")) return null;
48
+ if (trimmed.includes(path.sep)) return null;
49
+ const atIndex = trimmed.lastIndexOf("@");
50
+ if (atIndex > 0) {
51
+ return trimmed.slice(0, atIndex);
52
+ }
53
+ return trimmed;
54
+ }
55
+ function loadConfig() {
56
+ try {
57
+ if (!fs.existsSync(CONFIG_PATH)) return null;
58
+ const raw = fs.readFileSync(CONFIG_PATH, "utf-8");
59
+ return JSON.parse(raw);
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+ function saveConfig(config) {
65
+ try {
66
+ const dir = path.dirname(CONFIG_PATH);
67
+ if (!fs.existsSync(dir)) {
68
+ fs.mkdirSync(dir, { recursive: true });
69
+ }
70
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
71
+ } catch {
72
+ }
73
+ }
74
+ function ensurePluginEntry(config) {
75
+ const existing = Array.isArray(config.plugins) ? [...config.plugins] : [];
76
+ const normalized = existing.map(
77
+ (plugin) => plugin === "opencode-subagent-tmux" ? "opencode-agent-tmux" : plugin
78
+ );
79
+ if (!normalized.includes("opencode-agent-tmux")) {
80
+ normalized.push("opencode-agent-tmux");
81
+ }
82
+ if (JSON.stringify(existing) !== JSON.stringify(normalized)) {
83
+ config.plugins = normalized;
84
+ saveConfig(config);
85
+ }
86
+ return normalized;
87
+ }
88
+ function installLatest(plugins) {
89
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
90
+ const unique = Array.from(new Set(plugins));
91
+ for (const plugin of unique) {
92
+ const normalized = normalizePluginName(plugin);
93
+ if (!normalized) continue;
94
+ const target = `${normalized}@latest`;
95
+ spawnSync(npmCmd, ["install", "-g", target], { stdio: "ignore" });
96
+ }
97
+ }
98
+ function main() {
99
+ if (!shouldRunUpdate()) return;
100
+ if (process.env.OPENCODE_TMUX_UPDATE !== "1") return;
101
+ const config = loadConfig() ?? {};
102
+ const plugins = ensurePluginEntry(config);
103
+ const updateList = ["opencode-agent-tmux", ...plugins];
104
+ installLatest(updateList);
105
+ writeLastRun();
106
+ }
107
+ try {
108
+ main();
109
+ } catch {
110
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-agent-tmux",
3
- "version": "1.1.3",
3
+ "version": "1.1.8",
4
4
  "description": "OpenCode plugin that provides tmux integration for viewing agent execution in real-time",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "dev": "tsup --watch",
17
17
  "typecheck": "tsc --noEmit",
18
18
  "prepublishOnly": "bun run build",
19
- "postinstall": "node dist/scripts/install.js || echo 'Skipping postinstall setup (dist not found)'"
19
+ "postinstall": "test -f dist/scripts/install.js && node dist/scripts/install.js || echo 'Skipping postinstall setup (dist not found)'"
20
20
  },
21
21
  "keywords": [
22
22
  "opencode",