@grympler/opencode-tmux-handover 1.0.1 → 1.0.2
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/package.json +1 -1
- package/src/index.ts +85 -12
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,28 +1,101 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin"
|
|
2
2
|
import { fileURLToPath } from "url"
|
|
3
3
|
import { dirname, join } from "path"
|
|
4
|
-
import { existsSync } from "fs"
|
|
4
|
+
import { existsSync, unlinkSync, symlinkSync, mkdirSync, lstatSync, readlinkSync } from "fs"
|
|
5
5
|
import { homedir } from "os"
|
|
6
|
-
import { loadConfig } from "./config.js"
|
|
6
|
+
import { loadConfig, type PluginConfig } from "./config.js"
|
|
7
7
|
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url)
|
|
9
9
|
const __dirname = dirname(__filename)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const ALL_COMMANDS = ["tmux", "tmux-oc", "tmux-claude", "tmux-copilot"]
|
|
12
|
+
|
|
13
|
+
function isSymlink(path: string): boolean {
|
|
14
|
+
try {
|
|
15
|
+
return lstatSync(path).isSymbolicLink()
|
|
16
|
+
} catch {
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ensureSymlink(src: string, dest: string) {
|
|
22
|
+
if (!existsSync(src)) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (isSymlink(dest)) {
|
|
27
|
+
try {
|
|
28
|
+
const target = readlinkSync(dest)
|
|
29
|
+
if (target === src) {
|
|
30
|
+
return // Already correct
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// proceed to replace
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (existsSync(dest) || isSymlink(dest)) {
|
|
38
|
+
try {
|
|
39
|
+
unlinkSync(dest)
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(`tt-plugin: Failed to remove old link ${dest}:`, err)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
}
|
|
13
45
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
46
|
+
try {
|
|
47
|
+
symlinkSync(src, dest)
|
|
48
|
+
console.log(`tt-plugin: Linked command ${dest}`)
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error(`tt-plugin: Failed to link ${dest}:`, err)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function removeLink(path: string) {
|
|
55
|
+
if (existsSync(path) || isSymlink(path)) {
|
|
17
56
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
await $`bash ${installScript}`.quiet()
|
|
21
|
-
console.log("tt-plugin: Auto-installation completed")
|
|
57
|
+
unlinkSync(path)
|
|
58
|
+
console.log(`tt-plugin: Removed disabled command ${path}`)
|
|
22
59
|
} catch (err) {
|
|
23
|
-
console.error(
|
|
60
|
+
console.error(`tt-plugin: Failed to remove ${path}:`, err)
|
|
24
61
|
}
|
|
25
62
|
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function syncCommands(config: PluginConfig) {
|
|
66
|
+
const commandsDir = join(homedir(), ".config", "opencode", "commands")
|
|
67
|
+
|
|
68
|
+
if (!existsSync(commandsDir)) {
|
|
69
|
+
mkdirSync(commandsDir, { recursive: true })
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 1. Always ensure tt-configure is installed
|
|
73
|
+
const configureLink = join(commandsDir, "tt-configure.md")
|
|
74
|
+
const configureSrc = join(__dirname, "commands", "tt-configure.md")
|
|
75
|
+
ensureSymlink(configureSrc, configureLink)
|
|
76
|
+
|
|
77
|
+
// 2. Sync enabled/disabled commands
|
|
78
|
+
for (const cmd of ALL_COMMANDS) {
|
|
79
|
+
const linkPath = join(commandsDir, `${cmd}.md`)
|
|
80
|
+
const srcPath = join(__dirname, "commands", `${cmd}.md`)
|
|
81
|
+
|
|
82
|
+
if (config.enabledCommands.includes(cmd)) {
|
|
83
|
+
ensureSymlink(srcPath, linkPath)
|
|
84
|
+
} else {
|
|
85
|
+
removeLink(linkPath)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const TmuxLauncher: Plugin = async ({ $, directory }) => {
|
|
91
|
+
const config = loadConfig()
|
|
92
|
+
|
|
93
|
+
// Sync commands based on configuration on startup
|
|
94
|
+
try {
|
|
95
|
+
syncCommands(config)
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.error("tt-plugin: Command sync failed:", err)
|
|
98
|
+
}
|
|
26
99
|
|
|
27
100
|
return {
|
|
28
101
|
"command.execute.before": async (input, output) => {
|