77 Commits
Author SHA1 Message Date
Pierre MartinandClaude Sonnet 4.6 e95992572f fix: corriger les références incorrectes dans la doc et go.mod
- go.mod : module path github.com/pieMusic → git.sans.pub/pierre/vmux
- README : URL clone et version Go (1.22 → 1.25)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:09:46 +02:00
Pierre Martin a151f64ffa merge: intégrer l'initial commit Gitea 2026-05-21 18:00:47 +02:00
Pierre MartinandClaude Sonnet 4.6 f6881c1619 docs: add README, licence WTFPL et documentation
- README.md : vision, installation, commandes, aperçu fonctionnement
- LICENSE : WTFPL v2
- docs/architecture.md : composants, flux de données, index des fichiers
- docs/i3-integration.md : config i3bar, switch, focus, dépannage
- .gitignore : exclure .direnv/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 17:57:51 +02:00
Pierre MartinandClaude Opus 4.6 001c453462 fix: improve state detection accuracy and notification UX
- Hook reads JSON from stdin (not env vars) matching Claude Code protocol
- end_turn = Idle (not NeedsInput); real questions come from hooks
- Permission prompt (stale tool_use) never becomes Idle
- Notifications auto-expire after 10s (--expire-time)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:29:26 +01:00
Pierre Martin 0e4ced5b1f feat: add vmux setup and vmux hook for Claude Code integration
- vmux setup: idempotently adds hooks to ~/.claude/settings.json
- vmux hook: receives Claude Code hook events via env vars and forwards to daemon
- Daemon handles "hook" action on Unix socket (no HTTP server needed)
- Hooks provide instant state detection (permission/question/idle)
2026-03-23 23:11:47 +01:00
Pierre Martin 994b78aee5 docs(phase-04): complete phase execution 2026-03-23 23:05:14 +01:00
Pierre Martin 64e4509241 docs(phase-04): add verification and summary for plan 04-02 2026-03-23 23:04:49 +01:00
Pierre Martin fd246f046b feat(04-02): i3bar widget with per-session colors, workspace prefix, wait type and duration
- One i3bar block per session (individual colors: red/green/gray)
- Workspace prefix: 10-vmux[W], 3-auth[? 3m]
- Wait type markers: ⚡ permission, ? question, ! generic
- Wait duration: [⚡ 30s], [? 3m], [? 1h15m]
- Standalone mode only (separate bar, no i3status wrapping)
- Removed isTerminal and i3status wrapping code
2026-03-23 23:04:37 +01:00
Pierre MartinandClaude Opus 4.6 221a4447e2 feat(04-02): add vmux i3bar subcommand with i3status wrapping
- runI3Bar: standalone mode (polling 2s) and i3status wrapping mode
- i3bar protocol v1: header + infinite JSON array on stdout
- queryVmuxBlock: daemon offline fallback in gray
- CLI: vmux i3bar auto-detects i3status in PATH
- Stdout sync after each write to avoid buffering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:30:30 +01:00
Pierre MartinandClaude Opus 4.6 a28e8d6f1e test(04-02): add i3bar formatting with TDD
- I3BarBlock struct for i3bar protocol JSON
- formatI3BarBlocks: compact format D-06/D-07/D-08
- 10 tests covering mixed states, colors, labels, markers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:29:09 +01:00
Pierre Martin 399e3e8f02 docs(04-01): complete notifications et mode focus plan
- SUMMARY.md with execution results
- STATE.md updated (position, decisions, metrics)
- ROADMAP.md progress updated
- Requirements NOTIF-01, NOTIF-02 marked complete
2026-03-23 21:27:10 +01:00
Pierre Martin efbe31928e feat(04-01): integrate notifications and focus mode into daemon
- Notifier + FocusTimer fields in Daemon, initialized in NewDaemon
- processHookEvent notifies on Working -> Needs Input only (D-01)
- Focus mode suppresses notifications when active (D-05)
- FocusArgs in protocol, "focus" handler in daemon
- CLI "vmux focus <minutes>" command
- Tests for all notification transitions and focus handler
2026-03-23 21:26:02 +01:00
Pierre Martin b96c6d05be feat(04-01): add Notifier interface and FocusTimer
- Notifier interface with ExecNotifier (notify-send) and NullNotifier
- FocusTimer thread-safe with Set/IsActive/Remaining
- shortName helper for session display names
- Full test coverage for all components
2026-03-23 21:23:57 +01:00
Pierre MartinandClaude Opus 4.6 421bff8f73 fix: read 200 tail lines to find preview through progress noise
Claude Code emits many progress lines during work, burying the last
assistant text. 5 lines was not enough to reach it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:21:31 +01:00
Pierre Martin dc1ec72056 docs(04): phase 4 plans, research, validation 2026-03-23 21:10:27 +01:00
Pierre Martin cf252fc634 docs(04): create phase plan for notifications et i3bar 2026-03-23 21:07:35 +01:00
Pierre MartinandClaude Opus 4.6 bab681ca30 feat: stabilize list output with fixed-height preview (5 lines, 300 chars)
Each session always occupies the same number of lines, preventing
visual jitter between watch refreshes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:50:28 +01:00
Pierre Martin bdac6d07a9 docs(04): research phase domain 2026-03-23 20:48:03 +01:00
Pierre MartinandClaude Opus 4.6 c921124bcc feat: sort sessions by workspace number in list output
Also restart daemon on make watch so new binary is used.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:42:10 +01:00
Pierre Martin afa238e29a docs(state): record phase 4 context session 2026-03-23 20:31:54 +01:00
Pierre Martin 719d389d01 docs(04): capture phase context 2026-03-23 20:31:54 +01:00
Pierre Martin 5b7c9c5157 feat: add make watch for live dashboard with colors 2026-03-23 19:54:44 +01:00
Pierre Martin 9d43cb204a docs(phase-03): complete phase execution 2026-03-23 19:51:09 +01:00
Pierre MartinandClaude Opus 4.6 bed07b1552 docs(03-02): complete hook server integration plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:48:15 +01:00
Pierre MartinandClaude Opus 4.6 9cf0480510 feat(03-02): display WaitType in vmux list for sessions awaiting input
- Show "Needs Input: permission" or "Needs Input: question" when WaitType set
- No WaitType shown for Working state or when WaitType empty
- No regression on existing display tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:46:52 +01:00
Pierre MartinandClaude Opus 4.6 e60524961a test(03-02): add failing tests for WaitType display in vmux list
- TestDisplayWaitTypePermission, TestDisplayWaitTypeQuestion
- TestDisplayWaitTypeEmpty, TestDisplayWorkingNoWaitType

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:46:18 +01:00
Pierre MartinandClaude Opus 4.6 79ad8fb16a feat(03-02): integrate hook server into daemon with graceful degradation and dynamic poll
- Add hookPort, httpServer, lastHookTime, mu to Daemon struct
- startHookServer binds HTTP on hookPort, degrades if port busy
- Stop() closes httpServer before unix listener
- pollLoop uses time.After(currentPollInterval()) instead of fixed ticker
- currentPollInterval returns 20s when hooks active (<60s), 5s otherwise
- processHookEvent records lastHookTime on each hook event

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:45:48 +01:00
Pierre MartinandClaude Opus 4.6 5f13eb174b test(03-02): add failing tests for hook server integration and poll slowdown
- TestHookServerStartsWithDaemon, TestHookServerStopsWithDaemon
- TestHookServerPortBusy (graceful degradation)
- TestPollSlowdown (20s when hooks active, 5s otherwise)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:44:30 +01:00
Pierre MartinandClaude Opus 4.6 a59fc01933 docs(03-01): complete hook event processing plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:42:43 +01:00
Pierre MartinandClaude Opus 4.6 5bec9430b7 feat(03-01): HTTP handler POST /hook with validation and body size limit
- handleHook validates POST method (405 on others)
- MaxBytesReader limits body to 64KB (400 on overflow)
- JSON decode errors return 400
- Valid payloads update registry via processHookEvent
- 4 tests cover OK, method not allowed, bad JSON, body too large

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:41:11 +01:00
Pierre MartinandClaude Opus 4.6 e1b176cf55 feat(03-01): HookEvent struct, processHookEvent mapping, UpdateFromHook, WaitType
- HookEvent struct parses Claude Code hook JSON payload
- processHookEvent maps Notification/Stop/PostToolUse/PreToolUse to State+WaitType
- UpdateFromHook creates new entries and manages WaitingSince transitions
- SessionInfo.WaitType serialized in JSON with omitempty
- 12 tests cover all event mappings, edge cases, and JSON serialization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:40:02 +01:00
Pierre Martin 10a9d95116 docs(03): phase 3 plans, validation, and research 2026-03-23 19:36:15 +01:00
Pierre Martin 005c6c1214 docs(03): create phase plan for hook server 2026-03-23 19:33:24 +01:00
Pierre Martin f7228922cc docs(phase-3): research hook server domain 2026-03-23 19:29:45 +01:00
Pierre Martin e0e6486c19 docs(state): record phase 3 context session 2026-03-23 19:24:41 +01:00
Pierre Martin a990c1a1b4 docs(03): capture phase context 2026-03-23 19:24:41 +01:00
Pierre Martin 2375374f2f docs(phase-02): complete phase execution 2026-03-23 19:20:03 +01:00
Pierre Martin 4cb12b2e2a docs(02-03): complete CLI + wiring plan 2026-03-23 18:43:15 +01:00
Pierre Martin 8594c48f84 fix: detect permission prompts as NeedsInput when tool_use is stale (>10s)
When Claude requests a tool permission approval, the last JSONL entry is
type=assistant with stop_reason=tool_use. Previously this was always
classified as Working. Now, if the tool_use entry is older than 10s with
no new activity, it's classified as NeedsInput.

Also fix vmux label to accept fuzzy match queries (not just session UUIDs).
2026-03-23 18:29:32 +01:00
Pierre Martin 170790fcda feat(02-03): main.go subcommands + display enrichi avec workspace, label, duree
- main.go dispatch list/switch/label/stop/daemon via client socket
- DisplaySessionInfos affiche [ws:N], label entre guillemets, "depuis X min"
- formatDuration pour duree relative humaine (< 1 min, 3 min, 1 h 5 min)
- Daemon mode integre i3 + X11 avec degradation gracieuse
- Tests complets pour tous les champs optionnels du display
2026-03-23 17:54:18 +01:00
Pierre Martin a79a0e154c feat(02-03): client socket, autostart daemon, switch handler, workspace wiring
- Client struct sends JSON requests to daemon over Unix socket
- EnsureDaemon auto-starts the daemon if not running (retry 50ms x 20)
- Switch handler uses FuzzyMatch + SwitchToWorkspace via i3 IPC
- InitWorkspaceResolver wires BuildTerminalWorkspaceMap + ResolveWorkspace
- sysattr_linux.go for Setsid detach on daemon spawn
2026-03-23 17:51:31 +01:00
Pierre Martin a388c9477d docs(02-02): complete i3 bridge plan
- SUMMARY.md with 2 tasks, 15 tests, 4 TDD commits
- STATE.md updated: plan 2/3, decisions recorded
- ROADMAP.md: phase 02 progress 2/3
- REQUIREMENTS.md: I3-01, I3-02 marked complete
2026-03-23 17:47:27 +01:00
Pierre Martin 185119e580 docs(02-01): complete daemon vmuxd plan
- SUMMARY.md with protocol types, registry, labels, socket server
- STATE.md updated: plan 3/3, decisions, metrics
- ROADMAP.md updated: phase 02 progress
- REQUIREMENTS.md: DISC-04, STATE-04 complete
2026-03-23 17:47:14 +01:00
Pierre Martin 4b142a79b5 feat(02-01): add Unix socket server, poll loop, and stop handler
- Daemon struct with Start/Stop/Wait lifecycle
- Unix socket server handling list/label/stop actions
- Poll loop scanning /proc every 5s
- Stale socket cleanup before listen
- Connection dispatch with JSON encoding
- Tests with -race: StartStop, ListOverSocket, LabelOverSocket, UnknownAction
2026-03-23 17:45:57 +01:00
Pierre Martin 9427dd3eda feat(02-02): implement fuzzy match + switch workspace + i3 commander
- FuzzyMatch searches label > branch > cwd (case-insensitive)
- SwitchToWorkspace sends 'workspace number N' via I3Commander interface
- RealI3Commander wraps go.i3wm.org/i3/v4 RunCommand
- 9 tests covering priority, no-match, case-insensitive, errors
2026-03-23 17:45:32 +01:00
Pierre Martin 4a298d5ad0 test(02-02): add failing tests for fuzzy match + switch workspace
- TestFuzzyMatchByLabel, TestFuzzyMatchByBranch, TestFuzzyMatchByCwd
- TestFuzzyMatchPriority (label wins over branch)
- TestFuzzyMatchNoResult, TestFuzzyMatchCaseInsensitive
- TestSwitchToWorkspace, TestSwitchToWorkspaceError, TestSwitchToWorkspaceI3Error
2026-03-23 17:44:56 +01:00
Pierre Martin a2fb37e2b5 feat(02-02): implement PPID chain walk + workspace resolution
- ReadPPID parses PPid from /proc/PID/status
- ResolveWorkspace walks PPID chain (max 20 levels) to find terminal workspace
- BuildTerminalWorkspaceMap traverses i3 tree + X11 _NET_WM_PID
- RealX11Resolver wraps xgbutil/ewmh for production use
- Interfaces I3TreeProvider and X11PIDResolver for testability
- Fix unused imports in daemon.go (Rule 3: blocking build)
2026-03-23 17:43:58 +01:00
Pierre Martin 5315e88494 feat(02-01): implement protocol types, SessionRegistry, and LabelStore
- Enrich Session with Workspace, Label, WaitingSince fields
- Protocol types: Request, Response, SessionInfo, SwitchArgs, LabelArgs
- SessionRegistry with WaitingSince transition tracking
- LabelStore with JSON file persistence
2026-03-23 17:43:12 +01:00
Pierre Martin c9a28df3dc test(02-02): add failing tests for PPID chain walk + workspace resolution
- TestReadPPID, TestReadPPIDMissing
- TestResolveWorkspace, TestResolveWorkspaceNotFound, TestResolveWorkspaceMaxDepth
- TestBuildTerminalWorkspaceMapUnit
- Add go.i3wm.org/i3/v4 dependency
2026-03-23 17:42:44 +01:00
Pierre Martin a49f7d1c57 test(02-01): add failing tests for protocol types, registry, and label store
- TestRequestMarshal, TestResponseWithSessions
- TestRegistryUpdate, TestRegistryWaitingSince, TestRegistryRemoveStale
- TestLabelStoreSetGet, TestLabelStorePersistence, TestLabelStoreLoadMissing
2026-03-23 17:41:58 +01:00
Pierre Martin 51544cab0b docs(02): phase 2 plans 2026-03-23 17:37:09 +01:00
Pierre Martin 1d78b7dc3a docs(phase-2): add research and validation strategy 2026-03-23 15:33:41 +01:00
Pierre Martin be223468bc docs(02): research daemon et i3 bridge phase domain 2026-03-23 15:32:48 +01:00
Pierre Martin e1c42e2029 docs(state): record phase 2 context session 2026-03-23 15:22:11 +01:00
Pierre Martin e84fb71812 docs(02): capture phase context 2026-03-23 15:22:05 +01:00
Pierre Martin a6eb9f1406 chore: add Makefile and .envrc for dev environment 2026-03-23 14:44:36 +01:00
Pierre Martin 205499c00d docs(phase-01): evolve PROJECT.md after phase completion 2026-03-23 14:44:30 +01:00
Pierre Martin f9a53632a3 docs(phase-01): complete phase execution 2026-03-23 14:44:06 +01:00
Pierre MartinandClaude Opus 4.6 766ce541a1 chore(01-02): add .gitignore for vmux binary
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:31:25 +01:00
Pierre MartinandClaude Opus 4.6 f1dcee0ae2 feat(01-02): add CLI display and main.go for vmux list
- DisplaySessions: colored output with state, cwd, branch, preview
- display_test.go: 5 tests covering color, noColor, empty, worktree, noBranch
- main.go: full pipeline FindClaudeProcesses -> FindSession -> DetectState -> Display
- Supports --no-color flag and NO_COLOR env var
- resolveWorktree via git rev-parse --show-toplevel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:30:55 +01:00
Pierre MartinandClaude Opus 4.6 e7ced9c3a3 test(01-02): add failing tests then implement session + state
- TailReadJSONL: reverse-read JSONL without loading entire file
- FindSessionForProcess: match PID to most recent JSONL via EncodePath
- DetectState: heuristic based on last message stop_reason + tool name
- ExtractPreview: extract first 3 lines of last assistant text
- All 17 tests pass (session_test.go + state_test.go)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:29:19 +01:00
Pierre MartinandClaude Opus 4.6 d1c1239e1e docs(01-01): complete scaffolding + process detection plan
- SUMMARY.md with execution results
- STATE.md advanced to plan 2/2
- ROADMAP.md and REQUIREMENTS.md updated (DISC-01, DISC-02 complete)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:26:38 +01:00
Pierre MartinandClaude Opus 4.6 166e44161d feat(01-01): implement FindClaudeProcesses and EncodePath
- Scan /proc for PIDs with "claude" in cmdline
- Read cwd via os.Readlink, skip errors silently
- EncodePath replaces / and . with - for ~/.claude/projects/ folder names

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:25:27 +01:00
Pierre MartinandClaude Opus 4.6 81ee7dc49d test(01-01): add failing tests for proc scanning and path encoding
- TestFindClaudeProcesses with fake /proc (2 claude + 1 bash)
- TestFindClaudeProcesses_PermissionDenied (silent skip)
- TestFindClaudeProcesses_EmptyProc (empty slice)
- TestEncodePath and TestEncodePath_DotDir

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:24:59 +01:00
Pierre MartinandClaude Opus 4.6 12e1ba79ba feat(01-01): scaffold Go project with types
- shell.nix with go and gopls for NixOS dev environment
- go.mod for github.com/pieMusic/vmux module
- types.go with Process, Session, SessionState (Working/NeedsInput/Idle/Unknown)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:24:24 +01:00
Pierre Martin 929ee4ce7d docs(01): phase 1 plans and research 2026-03-23 13:16:15 +01:00
Pierre Martin 1b81b56ae7 fix(01): revise plan 01-01 based on checker feedback 2026-03-23 13:14:33 +01:00
Pierre Martin 4916a75011 docs(01-session-discovery): create phase plan 2026-03-23 13:09:19 +01:00
Pierre Martin 3faba89614 docs(phase-1): add validation strategy 2026-03-23 13:05:17 +01:00
Pierre Martin e5ee3635bb docs(01): research phase session discovery 2026-03-23 13:04:40 +01:00
Pierre Martin 16b42777e3 docs(state): record phase 1 context session 2026-03-23 12:53:36 +01:00
Pierre Martin 33e35e71db docs(01): capture phase context 2026-03-23 12:52:57 +01:00
Pierre Martin 699007b3f7 docs: create roadmap (4 phases) 2026-03-23 12:20:49 +01:00
Pierre Martin 2d21a199a4 docs: define v1 requirements 2026-03-23 11:33:50 +01:00
Pierre Martin 3030b88057 docs: complete project research 2026-03-23 11:25:05 +01:00
Pierre Martin ec1e6134eb chore: add project config 2026-03-23 11:02:50 +01:00
Pierre Martin 7bedb08301 docs: initialize project 2026-03-23 10:57:35 +01:00