opencode-agent-tmux 1.0.5 → 1.0.6
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/bin/opencode-tmux.js +107 -0
- package/dist/index.js +2 -2
- package/dist/scripts/install.js +125 -0
- package/package.json +7 -8
- package/bin/opencode-tmux.js +0 -127
- package/scripts/install.js +0 -146
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/bin/opencode-tmux.ts
|
|
4
|
+
import { spawn, execSync } from "child_process";
|
|
5
|
+
import { createServer } from "net";
|
|
6
|
+
import { env, platform, exit, argv } from "process";
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
var OPENCODE_PORT_START = parseInt(env.OPENCODE_PORT || "4096", 10);
|
|
11
|
+
var OPENCODE_PORT_MAX = OPENCODE_PORT_START + 10;
|
|
12
|
+
function findOpencodeBin() {
|
|
13
|
+
try {
|
|
14
|
+
const cmd = platform === "win32" ? "where opencode" : "which -a opencode";
|
|
15
|
+
const output = execSync(cmd, { encoding: "utf-8" }).trim().split("\n");
|
|
16
|
+
const currentScript = argv[1];
|
|
17
|
+
for (const bin of output) {
|
|
18
|
+
const normalizedBin = bin.trim();
|
|
19
|
+
if (normalizedBin.includes("opencode-tmux") || normalizedBin === currentScript) continue;
|
|
20
|
+
if (normalizedBin) return normalizedBin;
|
|
21
|
+
}
|
|
22
|
+
} catch (e) {
|
|
23
|
+
}
|
|
24
|
+
const commonPaths = [
|
|
25
|
+
join(homedir(), ".opencode", "bin", platform === "win32" ? "opencode.exe" : "opencode"),
|
|
26
|
+
join(homedir(), "AppData", "Local", "opencode", "bin", "opencode.exe"),
|
|
27
|
+
// Common Windows location
|
|
28
|
+
"/usr/local/bin/opencode",
|
|
29
|
+
"/usr/bin/opencode"
|
|
30
|
+
];
|
|
31
|
+
for (const p of commonPaths) {
|
|
32
|
+
if (existsSync(p)) return p;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function checkPort(port) {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
const server = createServer();
|
|
39
|
+
server.listen(port, "127.0.0.1");
|
|
40
|
+
server.on("listening", () => {
|
|
41
|
+
server.close();
|
|
42
|
+
resolve(true);
|
|
43
|
+
});
|
|
44
|
+
server.on("error", () => {
|
|
45
|
+
resolve(false);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async function findAvailablePort() {
|
|
50
|
+
for (let port = OPENCODE_PORT_START; port <= OPENCODE_PORT_MAX; port++) {
|
|
51
|
+
if (await checkPort(port)) return port;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function hasTmux() {
|
|
56
|
+
try {
|
|
57
|
+
execSync("tmux -V", { stdio: "ignore" });
|
|
58
|
+
return true;
|
|
59
|
+
} catch (e) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function main() {
|
|
64
|
+
const opencodeBin = findOpencodeBin();
|
|
65
|
+
if (!opencodeBin) {
|
|
66
|
+
console.error("\u274C Error: Could not find 'opencode' binary.");
|
|
67
|
+
console.error(" Please ensure OpenCode is installed and in your PATH.");
|
|
68
|
+
exit(1);
|
|
69
|
+
}
|
|
70
|
+
const port = await findAvailablePort();
|
|
71
|
+
if (!port) {
|
|
72
|
+
console.error("\u274C No ports available in range " + OPENCODE_PORT_START + "-" + OPENCODE_PORT_MAX);
|
|
73
|
+
exit(1);
|
|
74
|
+
}
|
|
75
|
+
if (port !== OPENCODE_PORT_START) {
|
|
76
|
+
console.warn(`\u26A0\uFE0F Port ${OPENCODE_PORT_START} is in use, using port ${port} instead`);
|
|
77
|
+
}
|
|
78
|
+
env.OPENCODE_PORT = port.toString();
|
|
79
|
+
const args = argv.slice(2);
|
|
80
|
+
const childArgs = ["--port", port.toString(), ...args];
|
|
81
|
+
const inTmux = !!env.TMUX;
|
|
82
|
+
const tmuxAvailable = hasTmux();
|
|
83
|
+
if (inTmux || !tmuxAvailable) {
|
|
84
|
+
const child = spawn(opencodeBin, childArgs, { stdio: "inherit" });
|
|
85
|
+
child.on("close", (code) => exit(code ?? 0));
|
|
86
|
+
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
87
|
+
process.on("SIGTERM", () => child.kill("SIGTERM"));
|
|
88
|
+
} else {
|
|
89
|
+
console.log("\u{1F680} Launching tmux session...");
|
|
90
|
+
const safeCommand = [
|
|
91
|
+
`"${opencodeBin}"`,
|
|
92
|
+
`--port ${port}`,
|
|
93
|
+
...args.map((a) => `"${a}"`)
|
|
94
|
+
].join(" ");
|
|
95
|
+
const shellCommand = `${safeCommand} || { echo "Exit code: $?"; echo "Press Enter to close..."; read; }`;
|
|
96
|
+
const tmuxArgs = [
|
|
97
|
+
"new-session",
|
|
98
|
+
shellCommand
|
|
99
|
+
];
|
|
100
|
+
const child = spawn("tmux", tmuxArgs, { stdio: "inherit" });
|
|
101
|
+
child.on("close", (code) => exit(code ?? 0));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
main().catch((err) => {
|
|
105
|
+
console.error(err);
|
|
106
|
+
exit(1);
|
|
107
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/scripts/install.ts
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import os from "os";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
var __dirname = path.dirname(__filename);
|
|
10
|
+
var HOME = os.homedir();
|
|
11
|
+
function detectShell() {
|
|
12
|
+
const shell = process.env.SHELL || "";
|
|
13
|
+
const platform = process.platform;
|
|
14
|
+
if (platform === "win32") {
|
|
15
|
+
const documents = path.join(HOME, "Documents");
|
|
16
|
+
const psDir = path.join(documents, "PowerShell");
|
|
17
|
+
const psProfile = path.join(psDir, "Microsoft.PowerShell_profile.ps1");
|
|
18
|
+
return {
|
|
19
|
+
name: "powershell",
|
|
20
|
+
rcFile: psProfile,
|
|
21
|
+
dir: psDir
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (shell.includes("zsh")) {
|
|
25
|
+
return { name: "zsh", rcFile: path.join(HOME, ".zshrc") };
|
|
26
|
+
} else if (shell.includes("bash")) {
|
|
27
|
+
const bashProfile = path.join(HOME, ".bash_profile");
|
|
28
|
+
const bashrc = path.join(HOME, ".bashrc");
|
|
29
|
+
return {
|
|
30
|
+
name: "bash",
|
|
31
|
+
rcFile: fs.existsSync(bashProfile) ? bashProfile : bashrc
|
|
32
|
+
};
|
|
33
|
+
} else if (shell.includes("fish")) {
|
|
34
|
+
return {
|
|
35
|
+
name: "fish",
|
|
36
|
+
rcFile: path.join(HOME, ".config", "fish", "config.fish")
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return { name: "unknown", rcFile: path.join(HOME, ".profile") };
|
|
40
|
+
}
|
|
41
|
+
function getAliasContent(shellName) {
|
|
42
|
+
if (shellName === "powershell") {
|
|
43
|
+
return `
|
|
44
|
+
function opencode {
|
|
45
|
+
opencode-tmux $args
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
return `alias opencode='opencode-tmux'`;
|
|
50
|
+
}
|
|
51
|
+
function getExportLine() {
|
|
52
|
+
return `export OPENCODE_PORT=4096`;
|
|
53
|
+
}
|
|
54
|
+
function setupAlias() {
|
|
55
|
+
const shell = detectShell();
|
|
56
|
+
console.log("");
|
|
57
|
+
console.log("\u{1F527} Setting up opencode-agent-tmux auto-launcher...");
|
|
58
|
+
console.log(` Detected shell: ${shell.name}`);
|
|
59
|
+
console.log(` Config file: ${shell.rcFile}`);
|
|
60
|
+
if (shell.name === "powershell") {
|
|
61
|
+
if (shell.dir && !fs.existsSync(shell.dir)) {
|
|
62
|
+
fs.mkdirSync(shell.dir, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!fs.existsSync(shell.rcFile)) {
|
|
66
|
+
console.log(` Creating ${shell.rcFile}...`);
|
|
67
|
+
fs.writeFileSync(shell.rcFile, "", "utf-8");
|
|
68
|
+
}
|
|
69
|
+
let rcContent = fs.readFileSync(shell.rcFile, "utf-8");
|
|
70
|
+
const aliasContent = getAliasContent(shell.name);
|
|
71
|
+
const MARKER_START = "# >>> opencode-agent-tmux >>>";
|
|
72
|
+
const MARKER_END = "# <<< opencode-agent-tmux <<<";
|
|
73
|
+
const OLD_MARKER_START = "# >>> opencode-subagent-tmux >>>";
|
|
74
|
+
const OLD_MARKER_END = "# <<< opencode-subagent-tmux <<<";
|
|
75
|
+
if (rcContent.includes(OLD_MARKER_START)) {
|
|
76
|
+
console.log(" Removing old opencode-subagent-tmux alias...");
|
|
77
|
+
const regex = new RegExp(`${OLD_MARKER_START}[\\s\\S]*?${OLD_MARKER_END}\\n?`, "g");
|
|
78
|
+
rcContent = rcContent.replace(regex, "");
|
|
79
|
+
fs.writeFileSync(shell.rcFile, rcContent, "utf-8");
|
|
80
|
+
console.log(" \u2713 Removed old alias");
|
|
81
|
+
rcContent = fs.readFileSync(shell.rcFile, "utf-8");
|
|
82
|
+
}
|
|
83
|
+
if (rcContent.includes(MARKER_START)) {
|
|
84
|
+
console.log(" \u2713 Auto-launcher already configured");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
let configBlock = "";
|
|
88
|
+
if (shell.name === "powershell") {
|
|
89
|
+
configBlock = `
|
|
90
|
+
${MARKER_START}
|
|
91
|
+
$env:OPENCODE_PORT="4096"
|
|
92
|
+
${aliasContent}
|
|
93
|
+
${MARKER_END}
|
|
94
|
+
`;
|
|
95
|
+
} else {
|
|
96
|
+
configBlock = `
|
|
97
|
+
${MARKER_START}
|
|
98
|
+
${getExportLine()}
|
|
99
|
+
${aliasContent}
|
|
100
|
+
${MARKER_END}
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
fs.appendFileSync(shell.rcFile, configBlock);
|
|
104
|
+
console.log(" \u2713 Auto-launcher configured successfully!");
|
|
105
|
+
console.log("");
|
|
106
|
+
console.log(" To activate now:");
|
|
107
|
+
if (shell.name === "powershell") {
|
|
108
|
+
console.log(` . ${shell.rcFile}`);
|
|
109
|
+
} else {
|
|
110
|
+
console.log(` source ${shell.rcFile}`);
|
|
111
|
+
}
|
|
112
|
+
console.log("");
|
|
113
|
+
console.log(" Or restart your terminal.");
|
|
114
|
+
console.log("");
|
|
115
|
+
console.log(' Usage: Just type "opencode" and tmux + port 4096 will be auto-configured!');
|
|
116
|
+
console.log("");
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
setupAlias();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error("");
|
|
122
|
+
console.error("\u26A0\uFE0F Failed to auto-configure shell alias:", error.message);
|
|
123
|
+
console.error("");
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-agent-tmux",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
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",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"opencode-tmux": "./bin/opencode-tmux.js"
|
|
9
|
+
"opencode-tmux": "./dist/bin/opencode-tmux.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
|
-
"dist"
|
|
13
|
-
"bin",
|
|
14
|
-
"scripts"
|
|
12
|
+
"dist"
|
|
15
13
|
],
|
|
16
14
|
"scripts": {
|
|
17
|
-
"build": "tsup
|
|
18
|
-
"dev": "tsup
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"dev": "tsup --watch",
|
|
19
17
|
"typecheck": "tsc --noEmit",
|
|
20
18
|
"prepublishOnly": "bun run build",
|
|
21
|
-
"postinstall": "node scripts/install.js"
|
|
19
|
+
"postinstall": "node dist/scripts/install.js"
|
|
22
20
|
},
|
|
23
21
|
"keywords": [
|
|
24
22
|
"opencode",
|
|
@@ -33,6 +31,7 @@
|
|
|
33
31
|
},
|
|
34
32
|
"devDependencies": {
|
|
35
33
|
"@types/bun": "^1.2.4",
|
|
34
|
+
"@types/node": "^25.0.10",
|
|
36
35
|
"tsup": "^8.3.6",
|
|
37
36
|
"typescript": "^5.7.3"
|
|
38
37
|
}
|
package/bin/opencode-tmux.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { spawn, execSync } from 'child_process';
|
|
4
|
-
import { createServer } from 'net';
|
|
5
|
-
import { env, platform, exit, argv } from 'process';
|
|
6
|
-
import { existsSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
8
|
-
import { homedir } from 'os';
|
|
9
|
-
|
|
10
|
-
const OPENCODE_PORT_START = parseInt(env.OPENCODE_PORT || '4096', 10);
|
|
11
|
-
const OPENCODE_PORT_MAX = OPENCODE_PORT_START + 10;
|
|
12
|
-
|
|
13
|
-
function findOpencodeBin() {
|
|
14
|
-
try {
|
|
15
|
-
const cmd = platform === 'win32' ? 'where opencode' : 'which -a opencode';
|
|
16
|
-
const output = execSync(cmd, { encoding: 'utf-8' }).trim().split('\n');
|
|
17
|
-
const currentScript = process.argv[1];
|
|
18
|
-
|
|
19
|
-
for (const bin of output) {
|
|
20
|
-
const normalizedBin = bin.trim();
|
|
21
|
-
if (normalizedBin.includes('opencode-tmux') || normalizedBin === currentScript) continue;
|
|
22
|
-
if (normalizedBin) return normalizedBin;
|
|
23
|
-
}
|
|
24
|
-
} catch (e) {
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const commonPaths = [
|
|
28
|
-
join(homedir(), '.opencode', 'bin', platform === 'win32' ? 'opencode.exe' : 'opencode'),
|
|
29
|
-
join(homedir(), 'AppData', 'Local', 'opencode', 'bin', 'opencode.exe'),
|
|
30
|
-
'/usr/local/bin/opencode',
|
|
31
|
-
'/usr/bin/opencode'
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
for (const p of commonPaths) {
|
|
35
|
-
if (existsSync(p)) return p;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function checkPort(port) {
|
|
42
|
-
return new Promise((resolve) => {
|
|
43
|
-
const server = createServer();
|
|
44
|
-
server.listen(port, '127.0.0.1');
|
|
45
|
-
server.on('listening', () => {
|
|
46
|
-
server.close();
|
|
47
|
-
resolve(true);
|
|
48
|
-
});
|
|
49
|
-
server.on('error', () => {
|
|
50
|
-
resolve(false);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function findAvailablePort() {
|
|
56
|
-
for (let port = OPENCODE_PORT_START; port <= OPENCODE_PORT_MAX; port++) {
|
|
57
|
-
if (await checkPort(port)) return port;
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function hasTmux() {
|
|
63
|
-
try {
|
|
64
|
-
execSync('tmux -V', { stdio: 'ignore' });
|
|
65
|
-
return true;
|
|
66
|
-
} catch (e) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function main() {
|
|
72
|
-
const opencodeBin = findOpencodeBin();
|
|
73
|
-
if (!opencodeBin) {
|
|
74
|
-
console.error("❌ Error: Could not find 'opencode' binary.");
|
|
75
|
-
console.error(" Please ensure OpenCode is installed and in your PATH.");
|
|
76
|
-
exit(1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const port = await findAvailablePort();
|
|
80
|
-
if (!port) {
|
|
81
|
-
console.error("❌ No ports available in range " + OPENCODE_PORT_START + "-" + OPENCODE_PORT_MAX);
|
|
82
|
-
exit(1);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (port !== OPENCODE_PORT_START) {
|
|
86
|
-
console.warn(`⚠️ Port ${OPENCODE_PORT_START} is in use, using port ${port} instead`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
env.OPENCODE_PORT = port.toString();
|
|
90
|
-
const args = argv.slice(2);
|
|
91
|
-
const childArgs = ['--port', port.toString(), ...args];
|
|
92
|
-
|
|
93
|
-
const inTmux = !!env.TMUX;
|
|
94
|
-
const tmuxAvailable = hasTmux();
|
|
95
|
-
|
|
96
|
-
if (inTmux || !tmuxAvailable) {
|
|
97
|
-
const child = spawn(opencodeBin, childArgs, { stdio: 'inherit' });
|
|
98
|
-
child.on('close', (code) => exit(code));
|
|
99
|
-
|
|
100
|
-
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
101
|
-
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
102
|
-
|
|
103
|
-
} else {
|
|
104
|
-
console.log("🚀 Launching tmux session...");
|
|
105
|
-
|
|
106
|
-
const safeCommand = [
|
|
107
|
-
`"${opencodeBin}"`,
|
|
108
|
-
`--port ${port}`,
|
|
109
|
-
...args.map(a => `"${a}"`)
|
|
110
|
-
].join(' ');
|
|
111
|
-
|
|
112
|
-
const shellCommand = `${safeCommand} || { echo "Exit code: $?"; echo "Press Enter to close..."; read; }`;
|
|
113
|
-
|
|
114
|
-
const tmuxArgs = [
|
|
115
|
-
'new-session',
|
|
116
|
-
shellCommand
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
const child = spawn('tmux', tmuxArgs, { stdio: 'inherit' });
|
|
120
|
-
child.on('close', (code) => exit(code));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
main().catch(err => {
|
|
125
|
-
console.error(err);
|
|
126
|
-
exit(1);
|
|
127
|
-
});
|
package/scripts/install.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import os from 'os';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
|
|
11
|
-
const HOME = os.homedir();
|
|
12
|
-
|
|
13
|
-
function detectShell() {
|
|
14
|
-
const shell = process.env.SHELL || '';
|
|
15
|
-
const platform = process.platform;
|
|
16
|
-
|
|
17
|
-
if (platform === 'win32') {
|
|
18
|
-
const documents = path.join(HOME, 'Documents');
|
|
19
|
-
const psDir = path.join(documents, 'PowerShell');
|
|
20
|
-
const psProfile = path.join(psDir, 'Microsoft.PowerShell_profile.ps1');
|
|
21
|
-
return {
|
|
22
|
-
name: 'powershell',
|
|
23
|
-
rcFile: psProfile,
|
|
24
|
-
dir: psDir
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (shell.includes('zsh')) {
|
|
29
|
-
return { name: 'zsh', rcFile: path.join(HOME, '.zshrc') };
|
|
30
|
-
} else if (shell.includes('bash')) {
|
|
31
|
-
const bashProfile = path.join(HOME, '.bash_profile');
|
|
32
|
-
const bashrc = path.join(HOME, '.bashrc');
|
|
33
|
-
return {
|
|
34
|
-
name: 'bash',
|
|
35
|
-
rcFile: fs.existsSync(bashProfile) ? bashProfile : bashrc
|
|
36
|
-
};
|
|
37
|
-
} else if (shell.includes('fish')) {
|
|
38
|
-
return {
|
|
39
|
-
name: 'fish',
|
|
40
|
-
rcFile: path.join(HOME, '.config', 'fish', 'config.fish')
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return { name: 'unknown', rcFile: path.join(HOME, '.profile') };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function getAliasContent(shellName) {
|
|
48
|
-
if (shellName === 'powershell') {
|
|
49
|
-
return `
|
|
50
|
-
function opencode {
|
|
51
|
-
opencode-tmux $args
|
|
52
|
-
}
|
|
53
|
-
`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return `alias opencode='opencode-tmux'`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function getExportLine() {
|
|
60
|
-
return `export OPENCODE_PORT=4096`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function setupAlias() {
|
|
64
|
-
const shell = detectShell();
|
|
65
|
-
|
|
66
|
-
console.log('');
|
|
67
|
-
console.log('🔧 Setting up opencode-agent-tmux auto-launcher...');
|
|
68
|
-
console.log(` Detected shell: ${shell.name}`);
|
|
69
|
-
console.log(` Config file: ${shell.rcFile}`);
|
|
70
|
-
|
|
71
|
-
if (shell.name === 'powershell') {
|
|
72
|
-
if (!fs.existsSync(shell.dir)) {
|
|
73
|
-
fs.mkdirSync(shell.dir, { recursive: true });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!fs.existsSync(shell.rcFile)) {
|
|
78
|
-
console.log(` Creating ${shell.rcFile}...`);
|
|
79
|
-
fs.writeFileSync(shell.rcFile, '', 'utf-8');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let rcContent = fs.readFileSync(shell.rcFile, 'utf-8');
|
|
83
|
-
const aliasContent = getAliasContent(shell.name);
|
|
84
|
-
|
|
85
|
-
const MARKER_START = '# >>> opencode-agent-tmux >>>';
|
|
86
|
-
const MARKER_END = '# <<< opencode-agent-tmux <<<';
|
|
87
|
-
|
|
88
|
-
const OLD_MARKER_START = '# >>> opencode-subagent-tmux >>>';
|
|
89
|
-
const OLD_MARKER_END = '# <<< opencode-subagent-tmux <<<';
|
|
90
|
-
|
|
91
|
-
if (rcContent.includes(OLD_MARKER_START)) {
|
|
92
|
-
console.log(' Removing old opencode-subagent-tmux alias...');
|
|
93
|
-
const regex = new RegExp(`${OLD_MARKER_START}[\\s\\S]*?${OLD_MARKER_END}\\n?`, 'g');
|
|
94
|
-
rcContent = rcContent.replace(regex, '');
|
|
95
|
-
fs.writeFileSync(shell.rcFile, rcContent, 'utf-8');
|
|
96
|
-
console.log(' ✓ Removed old alias');
|
|
97
|
-
rcContent = fs.readFileSync(shell.rcFile, 'utf-8');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (rcContent.includes(MARKER_START)) {
|
|
101
|
-
console.log(' ✓ Auto-launcher already configured');
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let configBlock = '';
|
|
106
|
-
if (shell.name === 'powershell') {
|
|
107
|
-
configBlock = `
|
|
108
|
-
${MARKER_START}
|
|
109
|
-
$env:OPENCODE_PORT="4096"
|
|
110
|
-
${aliasContent}
|
|
111
|
-
${MARKER_END}
|
|
112
|
-
`;
|
|
113
|
-
} else {
|
|
114
|
-
configBlock = `
|
|
115
|
-
${MARKER_START}
|
|
116
|
-
${getExportLine()}
|
|
117
|
-
${aliasContent}
|
|
118
|
-
${MARKER_END}
|
|
119
|
-
`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
fs.appendFileSync(shell.rcFile, configBlock);
|
|
123
|
-
|
|
124
|
-
console.log(' ✓ Auto-launcher configured successfully!');
|
|
125
|
-
console.log('');
|
|
126
|
-
console.log(' To activate now:');
|
|
127
|
-
if (shell.name === 'powershell') {
|
|
128
|
-
console.log(` . ${shell.rcFile}`);
|
|
129
|
-
} else {
|
|
130
|
-
console.log(` source ${shell.rcFile}`);
|
|
131
|
-
}
|
|
132
|
-
console.log('');
|
|
133
|
-
console.log(' Or restart your terminal.');
|
|
134
|
-
console.log('');
|
|
135
|
-
console.log(' Usage: Just type "opencode" and tmux + port 4096 will be auto-configured!');
|
|
136
|
-
console.log('');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
setupAlias();
|
|
141
|
-
} catch (error) {
|
|
142
|
-
console.error('');
|
|
143
|
-
console.error('⚠️ Failed to auto-configure shell alias:', error.message);
|
|
144
|
-
console.error('');
|
|
145
|
-
process.exit(0);
|
|
146
|
-
}
|