@towles/tool 0.0.107 → 0.0.108

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.
Files changed (76) hide show
  1. package/README.md +7 -1
  2. package/package.json +2 -1
  3. package/plugins/tt-agentboard/README.md +160 -0
  4. package/plugins/tt-agentboard/apps/server/package.json +20 -0
  5. package/plugins/tt-agentboard/apps/server/src/main.ts +60 -0
  6. package/plugins/tt-agentboard/apps/tui/build.ts +11 -0
  7. package/plugins/tt-agentboard/apps/tui/bunfig.toml +1 -0
  8. package/plugins/tt-agentboard/apps/tui/package.json +23 -0
  9. package/plugins/tt-agentboard/apps/tui/scripts/sessionizer.sh +36 -0
  10. package/plugins/tt-agentboard/apps/tui/src/components/DetailPanel.tsx +350 -0
  11. package/plugins/tt-agentboard/apps/tui/src/components/DiffStats.tsx +33 -0
  12. package/plugins/tt-agentboard/apps/tui/src/components/SessionCard.tsx +177 -0
  13. package/plugins/tt-agentboard/apps/tui/src/components/StatusBar.tsx +49 -0
  14. package/plugins/tt-agentboard/apps/tui/src/constants.ts +46 -0
  15. package/plugins/tt-agentboard/apps/tui/src/detail-panel-height.ts +21 -0
  16. package/plugins/tt-agentboard/apps/tui/src/index.tsx +880 -0
  17. package/plugins/tt-agentboard/apps/tui/src/mux-context.ts +61 -0
  18. package/plugins/tt-agentboard/apps/tui/tsconfig.json +15 -0
  19. package/plugins/tt-agentboard/bun.lock +444 -0
  20. package/plugins/tt-agentboard/package.json +26 -0
  21. package/plugins/tt-agentboard/packages/mux-tmux/package.json +14 -0
  22. package/plugins/tt-agentboard/packages/mux-tmux/src/client.ts +550 -0
  23. package/plugins/tt-agentboard/packages/mux-tmux/src/index.ts +18 -0
  24. package/plugins/tt-agentboard/packages/mux-tmux/src/provider.ts +259 -0
  25. package/plugins/tt-agentboard/packages/mux-tmux/tsconfig.json +13 -0
  26. package/plugins/tt-agentboard/packages/runtime/package.json +14 -0
  27. package/plugins/tt-agentboard/packages/runtime/src/agents/tracker.ts +233 -0
  28. package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/amp.ts +316 -0
  29. package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/claude-code.ts +374 -0
  30. package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/codex.ts +364 -0
  31. package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/opencode.ts +249 -0
  32. package/plugins/tt-agentboard/packages/runtime/src/config.ts +70 -0
  33. package/plugins/tt-agentboard/packages/runtime/src/contracts/agent-watcher.ts +38 -0
  34. package/plugins/tt-agentboard/packages/runtime/src/contracts/agent.ts +16 -0
  35. package/plugins/tt-agentboard/packages/runtime/src/contracts/index.ts +3 -0
  36. package/plugins/tt-agentboard/packages/runtime/src/contracts/mux.ts +148 -0
  37. package/plugins/tt-agentboard/packages/runtime/src/debug.ts +19 -0
  38. package/plugins/tt-agentboard/packages/runtime/src/index.ts +69 -0
  39. package/plugins/tt-agentboard/packages/runtime/src/mux/detect.ts +20 -0
  40. package/plugins/tt-agentboard/packages/runtime/src/mux/registry.ts +45 -0
  41. package/plugins/tt-agentboard/packages/runtime/src/plugins/loader.ts +152 -0
  42. package/plugins/tt-agentboard/packages/runtime/src/server/context.ts +112 -0
  43. package/plugins/tt-agentboard/packages/runtime/src/server/git-info.ts +164 -0
  44. package/plugins/tt-agentboard/packages/runtime/src/server/index.ts +1753 -0
  45. package/plugins/tt-agentboard/packages/runtime/src/server/launcher.ts +71 -0
  46. package/plugins/tt-agentboard/packages/runtime/src/server/metadata-store.ts +86 -0
  47. package/plugins/tt-agentboard/packages/runtime/src/server/pane-scanner.ts +327 -0
  48. package/plugins/tt-agentboard/packages/runtime/src/server/port-scanner.ts +155 -0
  49. package/plugins/tt-agentboard/packages/runtime/src/server/session-order.ts +127 -0
  50. package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-manager.ts +232 -0
  51. package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-width-sync.ts +66 -0
  52. package/plugins/tt-agentboard/packages/runtime/src/shared.ts +179 -0
  53. package/plugins/tt-agentboard/packages/runtime/src/themes.ts +750 -0
  54. package/plugins/tt-agentboard/packages/runtime/test/config.test.ts +83 -0
  55. package/plugins/tt-agentboard/packages/runtime/test/tracker.test.ts +172 -0
  56. package/plugins/tt-agentboard/packages/runtime/tsconfig.json +13 -0
  57. package/plugins/tt-agentboard/tsconfig.json +19 -0
  58. package/plugins/tt-auto-claude/.claude-plugin/plugin.json +8 -0
  59. package/plugins/tt-auto-claude/commands/create-issue.md +20 -0
  60. package/plugins/tt-auto-claude/commands/list.md +21 -0
  61. package/plugins/tt-auto-claude/skills/auto-claude/SKILL.md +71 -0
  62. package/plugins/tt-core/.claude-plugin/plugin.json +8 -0
  63. package/plugins/tt-core/README.md +18 -0
  64. package/plugins/tt-core/commands/improve-architecture.md +66 -0
  65. package/plugins/tt-core/commands/interview-me.md +38 -0
  66. package/plugins/tt-core/commands/prd-to-issues.md +49 -0
  67. package/plugins/tt-core/commands/refine-text.md +30 -0
  68. package/plugins/tt-core/commands/task.md +37 -0
  69. package/plugins/tt-core/commands/tdd.md +69 -0
  70. package/plugins/tt-core/commands/write-prd.md +69 -0
  71. package/plugins/tt-core/promptfooconfig.interview-me.yaml +155 -0
  72. package/plugins/tt-core/promptfooconfig.refine-text.yaml +242 -0
  73. package/plugins/tt-core/promptfooconfig.tdd.yaml +144 -0
  74. package/plugins/tt-core/promptfooconfig.write-prd.yaml +145 -0
  75. package/plugins/tt-core/skills/towles-tool/SKILL.md +35 -0
  76. 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 start
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.107",
3
+ "version": "0.0.108",
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,11 @@
1
+ import solidPlugin from "@opentui/solid/bun-plugin";
2
+
3
+ await Bun.build({
4
+ entrypoints: ["./src/index.tsx"],
5
+ outdir: "./dist",
6
+ target: "bun",
7
+ minify: true,
8
+ plugins: [solidPlugin],
9
+ });
10
+
11
+ console.log("Build complete!");
@@ -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"