@grympler/opencode-tmux-handover 1.0.0

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.
@@ -0,0 +1,514 @@
1
+ # From Local Plugin to Web-Available: Distribution & Configuration Guide
2
+
3
+ This guide explains how to evolve the `tt-plugin` from a local development plugin to a web-available npm package, and how to add customizable settings for command availability.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Current Architecture](#current-architecture)
10
+ 2. [Distribution Methods](#distribution-methods)
11
+ 3. [Publishing to npm](#publishing-to-npm)
12
+ 4. [Adding Plugin Configuration](#adding-plugin-configuration)
13
+ 5. [Plugin Settings Management](#plugin-settings-management)
14
+ 6. [Examples](#examples)
15
+
16
+ ---
17
+
18
+ ## Current Architecture
19
+
20
+ The `tt-plugin` currently uses a **local installation model**:
21
+
22
+ ```
23
+ tt-plugin (local directory)
24
+ ├── src/
25
+ │ ├── index.ts # Plugin entry point
26
+ │ ├── commands/ # Command definitions (.md files)
27
+ │ └── scripts/ # Bash implementations
28
+ ├── scripts/ # Registration utilities
29
+ ├── install.sh # Local installation script
30
+ └── package.json # Plugin manifest
31
+ ```
32
+
33
+ **Current Flow:**
34
+ 1. User clones repository locally
35
+ 2. Runs `npm run install`
36
+ 3. Plugin path is added to `~/.config/opencode/opencode.json`
37
+ 4. Commands are symlinked to `~/.config/opencode/commands/`
38
+
39
+ **Limitations:**
40
+ - Requires manual git cloning
41
+ - Must be maintained locally
42
+ - No version management
43
+ - Updates require manual pulling
44
+ - No built-in configuration UI
45
+
46
+ ---
47
+
48
+ ## Distribution Methods
49
+
50
+ ### Option 1: Local Files (Current)
51
+ **Best for:** Personal use, development, testing
52
+
53
+ ```bash
54
+ # Users manually clone and install
55
+ git clone https://github.com/yourname/tt-plugin.git
56
+ cd tt-plugin
57
+ npm run install
58
+ ```
59
+
60
+ **Pros:**
61
+ - Full control over code
62
+ - Easy to debug
63
+ - No build process needed
64
+
65
+ **Cons:**
66
+ - Manual updates
67
+ - Version conflicts
68
+ - Not discoverable
69
+
70
+ ---
71
+
72
+ ### Option 2: npm Registry (Recommended)
73
+ **Best for:** Wide distribution, discoverability, version management
74
+
75
+ ```bash
76
+ # Users simply add to config
77
+ ```
78
+
79
+ ```json
80
+ {
81
+ "plugin": ["tt-plugin"]
82
+ }
83
+ ```
84
+
85
+ **Pros:**
86
+ - Automatic installation via Bun
87
+ - Version management (semantic versioning)
88
+ - Discoverable in OpenCode ecosystem
89
+ - Easy updates
90
+ - No symlink management
91
+
92
+ **Cons:**
93
+ - Requires build step
94
+ - Must publish to npm
95
+ - Less flexible for local development
96
+
97
+ ---
98
+
99
+ ### Option 3: GitHub Package Registry
100
+ **Best for:** Organizations, private packages
101
+
102
+ ```json
103
+ {
104
+ "plugin": ["@yourorg/tt-plugin"]
105
+ }
106
+ ```
107
+
108
+ Similar to npm but hosted on GitHub.
109
+
110
+ ---
111
+
112
+ ## Publishing to npm
113
+
114
+ ### Step 1: Prepare Package
115
+
116
+ Update your `package.json`:
117
+
118
+ ```json
119
+ {
120
+ "name": "tt-plugin",
121
+ "version": "1.0.0",
122
+ "description": "OpenCode plugin for launching tmux with AI assistants",
123
+ "main": "src/index.ts",
124
+ "type": "module",
125
+ "repository": {
126
+ "type": "git",
127
+ "url": "https://github.com/yourusername/tt-plugin"
128
+ },
129
+ "keywords": ["opencode", "plugin", "tmux", "terminal"],
130
+ "author": "Your Name",
131
+ "license": "MIT",
132
+ "engines": {
133
+ "opencode": ">=dev",
134
+ "tmux": ">=3.0",
135
+ "bash": ">=4.0"
136
+ }
137
+ }
138
+ ```
139
+
140
+ **Important fields:**
141
+ - `name`: Must be lowercase, can include scopes (`@org/name`)
142
+ - `version`: Follows semantic versioning (1.0.0)
143
+ - `main`: Entry point (TypeScript supported by Bun)
144
+ - `type`: "module" for ES modules
145
+ - `files`: Include only necessary files
146
+
147
+ ### Step 2: Build (Optional)
148
+
149
+ If you need to transpile TypeScript:
150
+
151
+ ```bash
152
+ # In your build process
153
+ npx tsc src/index.ts --outDir dist/
154
+ ```
155
+
156
+ Update `package.json` main field:
157
+ ```json
158
+ "main": "dist/index.js"
159
+ ```
160
+
161
+ **For this plugin:** No build needed! Bun natively supports TypeScript.
162
+
163
+ ### Step 3: Create npm Account
164
+
165
+ ```bash
166
+ npm login
167
+ # Enter credentials
168
+ ```
169
+
170
+ Or sign up at https://www.npmjs.com/signup
171
+
172
+ ### Step 4: Publish
173
+
174
+ ```bash
175
+ # First time publish
176
+ npm publish
177
+
178
+ # Subsequent updates (bump version first)
179
+ npm version minor # or major, patch
180
+ npm publish
181
+ ```
182
+
183
+ ### Step 5: Verify Installation
184
+
185
+ Users can then use it:
186
+
187
+ ```json
188
+ {
189
+ "plugin": ["tt-plugin"]
190
+ }
191
+ ```
192
+
193
+ OpenCode will automatically install it to `~/.cache/opencode/node_modules/tt-plugin`. This includes all bundled files (specifically `src/scripts/*.sh`), ensuring the bash scripts are available locally for the plugin to execute.
194
+
195
+ ---
196
+
197
+ ## Adding Plugin Configuration
198
+
199
+ OpenCode plugins can accept configuration through two mechanisms:
200
+
201
+ ### Method 1: Config File Settings
202
+
203
+ Store configuration in `opencode.json`:
204
+
205
+ ```json
206
+ {
207
+ "plugin": [
208
+ {
209
+ "path": "tt-plugin",
210
+ "config": {
211
+ "enabledCommands": ["tmux", "tmux-oc"],
212
+ "defaultTerminal": "alacritty",
213
+ "sessionPrefix": "oc"
214
+ }
215
+ }
216
+ ]
217
+ }
218
+ ```
219
+
220
+ **Note:** Current OpenCode plugin system doesn't natively support this structure. This would require either:
221
+ 1. Custom environment variables
222
+ 2. Reading a separate config file
223
+ 3. Extending the plugin API (future feature)
224
+
225
+ ### Method 2: Environment Variables
226
+
227
+ Users can set environment variables to control behavior:
228
+
229
+ ```bash
230
+ export TT_PLUGIN_COMMANDS="tmux,tmux-oc,tmux-claude"
231
+ export TT_PLUGIN_DEFAULT_TERMINAL="alacritty"
232
+ ```
233
+
234
+ Modify your plugin to read these:
235
+
236
+ ```typescript
237
+ // src/index.ts
238
+ const enabledCommands = (process.env.TT_PLUGIN_COMMANDS || "tmux,tmux-oc,tmux-claude,tmux-copilot").split(",")
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Plugin Settings Management
244
+
245
+ ### Approach: JSON Configuration File
246
+
247
+ Create a configuration system that reads from `~/.config/opencode/tt-plugin-config.json`:
248
+
249
+ #### 1. Update Plugin to Read Config
250
+
251
+ ```typescript
252
+ // src/index.ts
253
+ import type { Plugin } from "@opencode-ai/plugin"
254
+ import { readFileSync } from "fs"
255
+ import { homedir } from "os"
256
+ import { join } from "path"
257
+
258
+ interface PluginConfig {
259
+ enabledCommands: string[]
260
+ defaultTerminal?: string
261
+ sessionPrefix?: string
262
+ }
263
+
264
+ function loadConfig(): PluginConfig {
265
+ const configPath = join(homedir(), ".config", "opencode", "tt-plugin-config.json")
266
+
267
+ try {
268
+ const config = JSON.parse(readFileSync(configPath, "utf-8"))
269
+ return {
270
+ enabledCommands: ["tmux", "tmux-oc", "tmux-claude", "tmux-copilot"],
271
+ ...config
272
+ }
273
+ } catch {
274
+ // Return defaults if no config file
275
+ return {
276
+ enabledCommands: ["tmux", "tmux-oc", "tmux-claude", "tmux-copilot"]
277
+ }
278
+ }
279
+ }
280
+
281
+ export const TmuxLauncher: Plugin = async ({ $, directory }) => {
282
+ const config = loadConfig()
283
+
284
+ return {
285
+ "command.execute.before": async (input, output) => {
286
+ const commandName = input.command || ""
287
+
288
+ // Check if command is enabled
289
+ if (!config.enabledCommands.includes(commandName)) {
290
+ return
291
+ }
292
+
293
+ if (!commandName.startsWith("tmux")) return
294
+
295
+ const scriptMap: Record<string, string> = {
296
+ tmux: "opencode-tmux.sh",
297
+ "tmux-oc": "opencode-tmux-oc.sh",
298
+ "tmux-claude": "opencode-tmux-claude.sh",
299
+ "tmux-copilot": "opencode-tmux-copilot.sh"
300
+ }
301
+
302
+ const scriptName = scriptMap[commandName]
303
+ if (!scriptName) return
304
+
305
+ const scriptPath = join(import.meta.dirname, "..", "scripts", scriptName)
306
+
307
+ try {
308
+ await $`bash ${scriptPath}`.cwd(directory)
309
+ output.parts = []
310
+ } catch (err) {
311
+ console.error("tt-plugin:", err)
312
+ }
313
+ }
314
+ }
315
+ }
316
+ ```
317
+
318
+ #### 2. Create Setup/Configuration Command
319
+
320
+ Add a command to help users configure the plugin:
321
+
322
+ ```bash
323
+ #!/usr/bin/env bash
324
+ # scripts/opencode-tt-configure.sh
325
+
326
+ set -euo pipefail
327
+
328
+ CONFIG_DIR="$HOME/.config/opencode"
329
+ CONFIG_FILE="$CONFIG_DIR/tt-plugin-config.json"
330
+
331
+ mkdir -p "$CONFIG_DIR"
332
+
333
+ # Show current configuration
334
+ if [ -f "$CONFIG_FILE" ]; then
335
+ echo "Current configuration:"
336
+ cat "$CONFIG_FILE"
337
+ echo ""
338
+ fi
339
+
340
+ # Create default config if it doesn't exist
341
+ if [ ! -f "$CONFIG_FILE" ]; then
342
+ cat > "$CONFIG_FILE" << 'EOF'
343
+ {
344
+ "enabledCommands": ["tmux", "tmux-oc", "tmux-claude", "tmux-copilot"],
345
+ "defaultTerminal": "auto",
346
+ "sessionPrefix": "oc"
347
+ }
348
+ EOF
349
+ echo "Created default configuration at: $CONFIG_FILE"
350
+ fi
351
+
352
+ echo ""
353
+ echo "Edit the configuration file to customize:"
354
+ echo " - enabledCommands: Which tmux commands to enable"
355
+ echo " - defaultTerminal: Preferred terminal emulator (auto, gnome-terminal, alacritty, kitty, etc.)"
356
+ echo " - sessionPrefix: Prefix for tmux session names"
357
+ echo ""
358
+ echo "To edit: $EDITOR $CONFIG_FILE"
359
+ ```
360
+
361
+ #### 3. Add Configuration Command to Plugin
362
+
363
+ Add to `src/commands/tt-configure.md`:
364
+
365
+ ```markdown
366
+ ---
367
+ description: Configure tt-plugin settings
368
+ ---
369
+
370
+ Open the tt-plugin configuration file to customize enabled commands, terminal preference, and session naming.
371
+ ```
372
+
373
+ #### 4. Example Configuration File
374
+
375
+ `~/.config/opencode/tt-plugin-config.json`:
376
+
377
+ ```json
378
+ {
379
+ "enabledCommands": [
380
+ "tmux",
381
+ "tmux-oc"
382
+ ],
383
+ "defaultTerminal": "alacritty",
384
+ "sessionPrefix": "dev"
385
+ }
386
+ ```
387
+
388
+ ---
389
+
390
+ ## Examples
391
+
392
+ ### Example 1: User Only Wants Two Commands
393
+
394
+ **Scenario:** User only uses `/tmux` and `/tmux-oc`, doesn't want `/tmux-claude` or `/tmux-copilot`
395
+
396
+ **Configuration:**
397
+
398
+ ```json
399
+ {
400
+ "enabledCommands": ["tmux", "tmux-oc"],
401
+ "defaultTerminal": "auto",
402
+ "sessionPrefix": "oc"
403
+ }
404
+ ```
405
+
406
+ **Result:** Running `/tmux-claude` would be ignored (no error, just silently skipped)
407
+
408
+ ---
409
+
410
+ ### Example 2: NPM Package Installation
411
+
412
+ **Step 1:** Publish package
413
+
414
+ ```bash
415
+ npm login
416
+ npm version minor
417
+ npm publish
418
+ ```
419
+
420
+ **Step 2:** User adds to config
421
+
422
+ ```bash
423
+ # User updates ~/.config/opencode/opencode.json
424
+ ```
425
+
426
+ ```json
427
+ {
428
+ "plugin": ["tt-plugin"],
429
+ "command": {
430
+ "tt-configure": {
431
+ "template": "Help me configure the tt-plugin settings"
432
+ }
433
+ }
434
+ }
435
+ ```
436
+
437
+ **Step 3:** OpenCode installs automatically
438
+
439
+ ```
440
+ At startup, OpenCode runs:
441
+ bun install --cwd ~/.cache/opencode
442
+
443
+ Plugin loads from:
444
+ ~/.cache/opencode/node_modules/tt-plugin/src/index.ts
445
+ ```
446
+
447
+ ---
448
+
449
+ ### Example 3: Scoped Organization Package
450
+
451
+ If publishing as organization package:
452
+
453
+ **Update package.json:**
454
+
455
+ ```json
456
+ {
457
+ "name": "@myorg/tt-plugin",
458
+ "version": "1.0.0"
459
+ }
460
+ ```
461
+
462
+ **Publish:**
463
+
464
+ ```bash
465
+ npm publish --access public # Scoped packages require explicit public access
466
+ ```
467
+
468
+ **User config:**
469
+
470
+ ```json
471
+ {
472
+ "plugin": ["@myorg/tt-plugin"]
473
+ }
474
+ ```
475
+
476
+ ---
477
+
478
+ ## Summary: Local → Web Distribution Path
479
+
480
+ | Phase | Method | Installation | Version Mgmt | Discoverability |
481
+ |-------|--------|--------------|--------------|-----------------|
482
+ | **Development** | Local directory | `git clone` + `npm run install` | Manual | Private |
483
+ | **Testing** | npm (pre-release) | `npm install --save-dev` | Semantic | npm only |
484
+ | **Production** | npm Registry | Config file entry | Automatic | npm registry + ecosystem |
485
+ | **Enterprise** | GitHub Packages | Config file entry | Automatic | Private registry |
486
+
487
+ ---
488
+
489
+ ## Configuration Best Practices
490
+
491
+ ### For Plugin Developers
492
+
493
+ 1. **Provide sensible defaults** - Don't break if config file is missing
494
+ 2. **Document configuration** - Include examples in README
495
+ 3. **Version config schema** - If changing config format, handle migrations
496
+ 4. **Validate configuration** - Check for invalid values at startup
497
+ 5. **Log configuration** - Help users debug with clear logs
498
+
499
+ ### For Users
500
+
501
+ 1. **Keep it simple** - Only configure what's necessary
502
+ 2. **Follow JSON syntax** - Use JSON validators
503
+ 3. **Backup config** - Version control your config file
504
+ 4. **Update regularly** - Check for new configuration options
505
+
506
+ ---
507
+
508
+ ## Related Resources
509
+
510
+ - [OpenCode Plugins Documentation](https://opencode.ai/docs/plugins)
511
+ - [OpenCode Commands Documentation](https://opencode.ai/docs/commands)
512
+ - [npm Publishing Guide](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry)
513
+ - [OpenCode Ecosystem](https://opencode.ai/docs/ecosystem)
514
+ - [semantic-release](https://github.com/semantic-release/semantic-release) - Automated versioning