@towles/tool 0.0.107 → 0.0.109
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/README.md +7 -1
- package/package.json +2 -1
- package/plugins/tt-agentboard/README.md +160 -0
- package/plugins/tt-agentboard/apps/server/package.json +20 -0
- package/plugins/tt-agentboard/apps/server/src/main.ts +60 -0
- package/plugins/tt-agentboard/apps/tui/build.ts +11 -0
- package/plugins/tt-agentboard/apps/tui/bunfig.toml +1 -0
- package/plugins/tt-agentboard/apps/tui/package.json +23 -0
- package/plugins/tt-agentboard/apps/tui/scripts/sessionizer.sh +36 -0
- package/plugins/tt-agentboard/apps/tui/src/components/DetailPanel.tsx +350 -0
- package/plugins/tt-agentboard/apps/tui/src/components/DiffStats.tsx +33 -0
- package/plugins/tt-agentboard/apps/tui/src/components/SessionCard.tsx +177 -0
- package/plugins/tt-agentboard/apps/tui/src/components/StatusBar.tsx +49 -0
- package/plugins/tt-agentboard/apps/tui/src/constants.ts +46 -0
- package/plugins/tt-agentboard/apps/tui/src/detail-panel-height.ts +21 -0
- package/plugins/tt-agentboard/apps/tui/src/index.tsx +880 -0
- package/plugins/tt-agentboard/apps/tui/src/mux-context.ts +61 -0
- package/plugins/tt-agentboard/apps/tui/tsconfig.json +15 -0
- package/plugins/tt-agentboard/bun.lock +444 -0
- package/plugins/tt-agentboard/package.json +26 -0
- package/plugins/tt-agentboard/packages/mux-tmux/package.json +14 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/client.ts +550 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/index.ts +18 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/provider.ts +259 -0
- package/plugins/tt-agentboard/packages/mux-tmux/tsconfig.json +13 -0
- package/plugins/tt-agentboard/packages/runtime/package.json +14 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/tracker.ts +233 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/amp.ts +316 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/claude-code.ts +374 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/codex.ts +364 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/opencode.ts +249 -0
- package/plugins/tt-agentboard/packages/runtime/src/config.ts +70 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/agent-watcher.ts +38 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/agent.ts +16 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/index.ts +3 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/mux.ts +148 -0
- package/plugins/tt-agentboard/packages/runtime/src/debug.ts +19 -0
- package/plugins/tt-agentboard/packages/runtime/src/index.ts +69 -0
- package/plugins/tt-agentboard/packages/runtime/src/mux/detect.ts +20 -0
- package/plugins/tt-agentboard/packages/runtime/src/mux/registry.ts +45 -0
- package/plugins/tt-agentboard/packages/runtime/src/plugins/loader.ts +152 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/context.ts +112 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/git-info.ts +164 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/index.ts +1753 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/launcher.ts +71 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/metadata-store.ts +86 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/pane-scanner.ts +327 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/port-scanner.ts +155 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/session-order.ts +127 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-manager.ts +232 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-width-sync.ts +66 -0
- package/plugins/tt-agentboard/packages/runtime/src/shared.ts +179 -0
- package/plugins/tt-agentboard/packages/runtime/src/themes.ts +750 -0
- package/plugins/tt-agentboard/packages/runtime/test/config.test.ts +83 -0
- package/plugins/tt-agentboard/packages/runtime/test/tracker.test.ts +172 -0
- package/plugins/tt-agentboard/packages/runtime/tsconfig.json +13 -0
- package/plugins/tt-agentboard/tsconfig.json +19 -0
- package/plugins/tt-auto-claude/.claude-plugin/plugin.json +8 -0
- package/plugins/tt-auto-claude/commands/create-issue.md +20 -0
- package/plugins/tt-auto-claude/commands/list.md +21 -0
- package/plugins/tt-auto-claude/skills/auto-claude/SKILL.md +71 -0
- package/plugins/tt-core/.claude-plugin/plugin.json +8 -0
- package/plugins/tt-core/README.md +18 -0
- package/plugins/tt-core/commands/improve-architecture.md +66 -0
- package/plugins/tt-core/commands/interview-me.md +38 -0
- package/plugins/tt-core/commands/prd-to-issues.md +49 -0
- package/plugins/tt-core/commands/refine-text.md +30 -0
- package/plugins/tt-core/commands/task.md +37 -0
- package/plugins/tt-core/commands/tdd.md +69 -0
- package/plugins/tt-core/commands/write-prd.md +69 -0
- package/plugins/tt-core/promptfooconfig.interview-me.yaml +155 -0
- package/plugins/tt-core/promptfooconfig.refine-text.yaml +242 -0
- package/plugins/tt-core/promptfooconfig.tdd.yaml +144 -0
- package/plugins/tt-core/promptfooconfig.write-prd.yaml +145 -0
- package/plugins/tt-core/skills/towles-tool/SKILL.md +35 -0
- package/src/cli.ts +2 -1
- package/src/commands/agentboard.ts +19 -2
package/README.md
CHANGED
|
@@ -12,13 +12,19 @@ claude plugin install tt@towles-tool
|
|
|
12
12
|
claude plugin update tt@towles-tool
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
### Global Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun install -g towles-tool
|
|
19
|
+
```
|
|
20
|
+
|
|
15
21
|
### From Source
|
|
16
22
|
|
|
17
23
|
```bash
|
|
18
24
|
git clone https://github.com/ChrisTowles/towles-tool.git
|
|
19
25
|
cd towles-tool
|
|
20
26
|
bun install
|
|
21
|
-
bun
|
|
27
|
+
bun link
|
|
22
28
|
```
|
|
23
29
|
|
|
24
30
|
## CLI Commands
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@towles/tool",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.109",
|
|
4
4
|
"description": "One off quality of life scripts that I use on a daily basis.",
|
|
5
5
|
"homepage": "https://github.com/ChrisTowles/towles-tool#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"bin",
|
|
24
24
|
"patches",
|
|
25
|
+
"plugins",
|
|
25
26
|
"src"
|
|
26
27
|
],
|
|
27
28
|
"type": "module",
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# AgentBoard
|
|
2
|
+
|
|
3
|
+
Tmux sidebar TUI for monitoring sessions and AI agents. Based on [opensessions](https://github.com/nicholasgasior/opensessions).
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
AgentBoard v1 was a Nuxt web UI with embedded terminal rendering in the browser, built around a Kanban board workflow — create tickets, watch them move across columns as agents work. In practice, most tasks only need one or two touches before they're done, so constantly tracking which state a card is in added friction instead of removing it. The real unit of work is just a tmux session — when it's ready, merge it.
|
|
8
|
+
|
|
9
|
+
On top of that, fighting the gap between a web page and the real terminal meant losing Claude Code's native TUI goodness — keybindings, scrollback, copy/paste, all the little things that just work in a real terminal. Less is more. A tmux sidebar that lives right next to your sessions keeps everything terminal-native, no translation layer needed.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Install into tmux (one-time)
|
|
15
|
+
tt agentboard setup
|
|
16
|
+
|
|
17
|
+
# Reload tmux, then toggle the sidebar:
|
|
18
|
+
# prefix a t
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Keybindings
|
|
22
|
+
|
|
23
|
+
### Tmux (prefix defaults to `C-a`)
|
|
24
|
+
|
|
25
|
+
| Key | Action |
|
|
26
|
+
| -------------- | ------------------------ |
|
|
27
|
+
| `prefix a t` | Toggle sidebar |
|
|
28
|
+
| `prefix a s` | Focus sidebar |
|
|
29
|
+
| `prefix a 1-9` | Jump to session by index |
|
|
30
|
+
|
|
31
|
+
### In Sidebar
|
|
32
|
+
|
|
33
|
+
| Key | Action |
|
|
34
|
+
| ------------------------- | --------------------------- |
|
|
35
|
+
| `Tab` / `Shift+Tab` | Cycle sessions |
|
|
36
|
+
| `j` / `k` / `Up` / `Down` | Move focus |
|
|
37
|
+
| `Enter` | Switch to session |
|
|
38
|
+
| `1-9` | Jump to session |
|
|
39
|
+
| `d` | Hide session |
|
|
40
|
+
| `x` | Kill session (with confirm) |
|
|
41
|
+
| `r` | Refresh |
|
|
42
|
+
| `u` | Show all sessions |
|
|
43
|
+
| `n` / `c` | New session (fzf picker) |
|
|
44
|
+
| `?` | Help overlay |
|
|
45
|
+
| `q` | Quit |
|
|
46
|
+
|
|
47
|
+
### Agent Detail Panel
|
|
48
|
+
|
|
49
|
+
| Key | Action |
|
|
50
|
+
| ----------------------- | ---------------------- |
|
|
51
|
+
| `Right` / `l` | Switch to agents panel |
|
|
52
|
+
| `Left` / `h` / `Escape` | Back to sessions |
|
|
53
|
+
| `Enter` | Focus agent pane |
|
|
54
|
+
| `d` | Dismiss agent |
|
|
55
|
+
| `x` | Kill agent pane |
|
|
56
|
+
| `Alt+Up/Down` | Reorder sessions |
|
|
57
|
+
|
|
58
|
+
## Architecture
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
plugins/tt-agentboard/
|
|
62
|
+
apps/
|
|
63
|
+
server/ WebSocket server (port 4201)
|
|
64
|
+
tui/ OpenTUI + Solid.js terminal UI
|
|
65
|
+
packages/
|
|
66
|
+
runtime/ Shared types, themes, agent watchers
|
|
67
|
+
mux-tmux/ Tmux provider (session/pane management)
|
|
68
|
+
scripts/ Tmux keybinding scripts
|
|
69
|
+
(tmux init via `tt agentboard init`)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Server
|
|
73
|
+
|
|
74
|
+
WebSocket server on `127.0.0.1:4201`. Auto-started by the TUI or tmux scripts.
|
|
75
|
+
|
|
76
|
+
- Scans tmux sessions, git info, listening ports
|
|
77
|
+
- Tracks agent status (Claude Code, Amp, Codex, OpenCode)
|
|
78
|
+
- Broadcasts state to connected TUI clients
|
|
79
|
+
- HTTP endpoints for tmux hooks (`/focus`, `/toggle`, `/ensure-sidebar`, etc.)
|
|
80
|
+
|
|
81
|
+
### TUI
|
|
82
|
+
|
|
83
|
+
Solid.js app rendered via OpenTUI. Connects to server over WebSocket.
|
|
84
|
+
|
|
85
|
+
- Session cards with accent bars, status icons, branch info
|
|
86
|
+
- Resizable detail panel with agent list + metadata
|
|
87
|
+
- Mouse support (click, drag to resize)
|
|
88
|
+
- Help overlay (`?`)
|
|
89
|
+
|
|
90
|
+
#### TUI Components
|
|
91
|
+
|
|
92
|
+
**`SessionCard`** (`components/SessionCard.tsx`) — session list item
|
|
93
|
+
|
|
94
|
+
- Row 1: session name (truncated to 18 chars) + status icon (braille spinner when running, `●` for unseen terminal states)
|
|
95
|
+
- Row 2: git branch + listening port hint (`⌁4201`, or `⌁4201+2` for multiple)
|
|
96
|
+
- Row 3: metadata summary (status text + progress like `3/5` or `42%`)
|
|
97
|
+
- Left accent bar colored by state: green (current), yellow (running), red (error), peach (interrupted), lavender (focused), teal (unseen done)
|
|
98
|
+
|
|
99
|
+
**`DetailPanel`** (`components/DetailPanel.tsx`) — expanded view for focused session
|
|
100
|
+
|
|
101
|
+
- Drag-resizable separator (height persisted per session in config)
|
|
102
|
+
- Truncated working directory
|
|
103
|
+
- Agent list via `AgentListItem` sub-component (see below)
|
|
104
|
+
- Metadata section: status line with tone icon + progress, last 8 log entries
|
|
105
|
+
|
|
106
|
+
**`AgentListItem`** (inside `DetailPanel.tsx`) — single agent instance row
|
|
107
|
+
|
|
108
|
+
- Status icon: braille spinner (running), `◉` (waiting), `✓` (done), `✗` (error), `⚠` (interrupted)
|
|
109
|
+
- Agent name, thread name, status text
|
|
110
|
+
- Dismiss `✕` button (hover turns red), click row to focus the agent's tmux pane
|
|
111
|
+
- Flash animation on click
|
|
112
|
+
|
|
113
|
+
**`HelpOverlay`** (inline in `index.tsx`) — modal overlay
|
|
114
|
+
|
|
115
|
+
- Shows all keybindings in a bordered dialog
|
|
116
|
+
- Dismissed by pressing any key
|
|
117
|
+
|
|
118
|
+
#### TUI Utilities
|
|
119
|
+
|
|
120
|
+
- `constants.ts` — shared icons (`SPINNERS`, `UNSEEN_ICON`, `TONE_ICONS`), spark blocks for sparkline charts, theme list, tone-to-color mapping
|
|
121
|
+
- `mux-context.ts` — tmux detection, pane refocus after startup, client TTY and session name resolution
|
|
122
|
+
- `detail-panel-height.ts` — per-session detail panel height persistence (min 4 rows, default 10)
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
Config file: `~/.config/towles-tool/agentboard/config.json`
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"theme": "catppuccin-mocha",
|
|
131
|
+
"sidebarWidth": 26,
|
|
132
|
+
"sidebarPosition": "left"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## CLI Commands
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
tt agentboard setup # Install tmux plugin
|
|
140
|
+
tt agentboard uninstall # Remove from tmux
|
|
141
|
+
tt agentboard server # Start server manually
|
|
142
|
+
tt agentboard tui # Start TUI manually
|
|
143
|
+
tt agentboard keys # Show keybindings
|
|
144
|
+
tt agentboard restart # Kill stash sessions, ensure server, toggle sidebar on
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Agent Watchers
|
|
148
|
+
|
|
149
|
+
Detects and tracks AI coding agents running in tmux sessions:
|
|
150
|
+
|
|
151
|
+
- **Claude Code** - reads `~/.claude/projects/` JSONL journals
|
|
152
|
+
- **Amp** - detects from pane titles
|
|
153
|
+
- **Codex** - reads `~/.codex/logs_1.sqlite`
|
|
154
|
+
- **OpenCode** - reads log files via `lsof`
|
|
155
|
+
|
|
156
|
+
## Themes
|
|
157
|
+
|
|
158
|
+
Theme is set via config file. Available themes:
|
|
159
|
+
|
|
160
|
+
catppuccin-mocha, catppuccin-latte, catppuccin-frappe, catppuccin-macchiato, tokyo-night, gruvbox-dark, nord, dracula, github-dark, one-dark, kanagawa, everforest, material, cobalt2, flexoki, ayu, aura, matrix, transparent
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tt-agentboard/server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/main.ts",
|
|
7
|
+
"types": "src/main.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"start": "bun run src/main.ts",
|
|
10
|
+
"dev": "bun --watch run src/main.ts"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@tt-agentboard/mux-tmux": "workspace:*",
|
|
14
|
+
"@tt-agentboard/runtime": "workspace:*"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/bun": "latest",
|
|
18
|
+
"typescript": "^5"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AmpAgentWatcher,
|
|
3
|
+
ClaudeCodeAgentWatcher,
|
|
4
|
+
CodexAgentWatcher,
|
|
5
|
+
OpenCodeAgentWatcher,
|
|
6
|
+
PluginLoader,
|
|
7
|
+
loadConfig,
|
|
8
|
+
startServer,
|
|
9
|
+
} from "@tt-agentboard/runtime";
|
|
10
|
+
import { TmuxProvider } from "@tt-agentboard/mux-tmux";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const loader = new PluginLoader();
|
|
15
|
+
|
|
16
|
+
// Register tmux provider (tmux only)
|
|
17
|
+
try {
|
|
18
|
+
const provider = new TmuxProvider();
|
|
19
|
+
loader.registerMux(provider);
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error("Failed to initialize tmux provider:", err);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
25
|
+
const pluginDir = join(home, ".config", "towles-tool", "agentboard", "plugins");
|
|
26
|
+
const localPlugins = loader.loadDir(pluginDir);
|
|
27
|
+
if (localPlugins.length > 0) {
|
|
28
|
+
console.log(`Loaded local plugins: ${localPlugins.join(", ")}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (config.plugins.length > 0) {
|
|
32
|
+
const npmPlugins = loader.loadPackages(config.plugins);
|
|
33
|
+
if (npmPlugins.length > 0) {
|
|
34
|
+
console.log(`Loaded npm plugins: ${npmPlugins.join(", ")}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mux = loader.resolve(config.mux);
|
|
39
|
+
if (!mux) {
|
|
40
|
+
console.error(
|
|
41
|
+
"No terminal multiplexer detected.\n" +
|
|
42
|
+
`Registered providers: ${loader.registry.list().join(", ") || "(none)"}\n` +
|
|
43
|
+
"$TMUX environment variable is not set — are you running inside a tmux session?\n" +
|
|
44
|
+
"Set 'mux' in ~/.config/towles-tool/agentboard/config.json to override.",
|
|
45
|
+
);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
loader.registerWatcher(new AmpAgentWatcher());
|
|
50
|
+
loader.registerWatcher(new ClaudeCodeAgentWatcher());
|
|
51
|
+
loader.registerWatcher(new CodexAgentWatcher());
|
|
52
|
+
loader.registerWatcher(new OpenCodeAgentWatcher());
|
|
53
|
+
|
|
54
|
+
const watchers = loader.getWatchers();
|
|
55
|
+
if (watchers.length > 0) {
|
|
56
|
+
console.log(`Agent watchers: ${watchers.map((watcher) => watcher.name).join(", ")}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(`Primary mux provider: ${mux.name}`);
|
|
60
|
+
startServer(mux, [], watchers);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
preload = ["@opentui/solid/preload"]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tt-agentboard/tui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.tsx",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "bun run src/index.tsx",
|
|
9
|
+
"dev": "bun --watch run src/index.tsx",
|
|
10
|
+
"build": "bun run build.ts"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@opentui/core": "^0.1.88",
|
|
14
|
+
"@opentui/solid": "^0.1.88",
|
|
15
|
+
"@tt-agentboard/mux-tmux": "workspace:*",
|
|
16
|
+
"@tt-agentboard/runtime": "workspace:*",
|
|
17
|
+
"solid-js": "^1.9.11"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/bun": "latest",
|
|
21
|
+
"typescript": "^5"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# agentboard sessionizer — fuzzy directory picker for new tmux sessions
|
|
3
|
+
# Requires: fzf, find
|
|
4
|
+
|
|
5
|
+
SEARCH_DIR="${SESSIONIZER_DIR:-$HOME/code}"
|
|
6
|
+
|
|
7
|
+
if ! command -v fzf &>/dev/null; then
|
|
8
|
+
echo "fzf is required for the sessionizer. Install it: https://github.com/junegunn/fzf"
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
if [ ! -d "$SEARCH_DIR" ]; then
|
|
13
|
+
echo "Directory not found: $SEARCH_DIR"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
selected=$(find "$SEARCH_DIR" -mindepth 1 -maxdepth 3 -type d 2>/dev/null | fzf \
|
|
18
|
+
--reverse \
|
|
19
|
+
--header="Pick a directory for new session" \
|
|
20
|
+
--preview=':' \
|
|
21
|
+
--preview-window=hidden \
|
|
22
|
+
--bind='ctrl-c:abort')
|
|
23
|
+
|
|
24
|
+
[ -z "$selected" ] && exit 0
|
|
25
|
+
|
|
26
|
+
# Derive session name from directory basename, replacing dots with underscores
|
|
27
|
+
session_name=$(basename "$selected" | tr '.' '_')
|
|
28
|
+
|
|
29
|
+
# If session already exists, just switch to it
|
|
30
|
+
if tmux has-session -t "=$session_name" 2>/dev/null; then
|
|
31
|
+
tmux switch-client -t "$session_name"
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
tmux new-session -d -s "$session_name" -c "$selected"
|
|
36
|
+
tmux switch-client -t "$session_name"
|