projmux 0.0.0-reserved → 0.4.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/LICENSE +21 -0
- package/README-ko.md +316 -0
- package/README.md +327 -0
- package/npm/projmux.js +73 -0
- package/package.json +30 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Crevisse Partners
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README-ko.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# projmux
|
|
2
|
+
|
|
3
|
+
터미널에서 프로젝트별 tmux 작업 공간을 만들고 유지하는 도구입니다.
|
|
4
|
+
|
|
5
|
+
`projmux`는 프로젝트 디렉터리를 오래 유지되는 tmux workspace로 매핑하고,
|
|
6
|
+
preview, sidebar navigation, 생성된 keybinding, status metadata, AI pane
|
|
7
|
+
attention signal을 함께 제공합니다. 자체 tmux 앱(`projmux shell`)으로 실행할
|
|
8
|
+
수도 있고, 기존 tmux 서버에 같은 기능을 설치할 수도 있습니다.
|
|
9
|
+
|
|
10
|
+
[English README](README.md)
|
|
11
|
+
|
|
12
|
+
## 왜 projmux인가
|
|
13
|
+
|
|
14
|
+
많은 tmux project switcher는 "디렉터리를 고르고 세션에 붙는다"에서 멈춥니다.
|
|
15
|
+
`projmux`는 그 흐름을 기본값으로 삼고, 매일 쓰는 터미널 workspace에 필요한
|
|
16
|
+
앱 수준의 요소를 더합니다.
|
|
17
|
+
|
|
18
|
+
- **프로젝트 정체성이 안정적으로 유지됩니다.** directory, pin, live session,
|
|
19
|
+
preview selection, lifecycle command가 같은 session model을 공유합니다.
|
|
20
|
+
- **전환하기 전에 맥락을 볼 수 있습니다.** popup과 sidebar에서 session,
|
|
21
|
+
window, pane, git branch, Kubernetes context, pane metadata를 미리 봅니다.
|
|
22
|
+
- **tmux layer를 손으로 이어 붙이지 않습니다.** popup launcher, window/pane
|
|
23
|
+
rename, status segment, pane border, attention badge, app mode에 필요한 tmux
|
|
24
|
+
설정을 `projmux`가 생성합니다.
|
|
25
|
+
- **AI pane을 일급 workspace 요소로 다룹니다.** Codex/Claude pane을 실행하고,
|
|
26
|
+
agent 이름, topic, thinking/waiting 상태, pane/window/session badge, desktop
|
|
27
|
+
notification까지 tmux 안에서 추적합니다.
|
|
28
|
+
- **격리 실행과 기존 tmux 통합 중 선택할 수 있습니다.** `projmux shell`로 자체
|
|
29
|
+
tmux 앱을 쓰거나, 생성된 snippet을 기존 tmux 서버에 설치할 수 있습니다.
|
|
30
|
+
|
|
31
|
+
## 0.4 주요 변경
|
|
32
|
+
|
|
33
|
+
- **`projmux setup` / `projmux init`** — 터미널이 어떤 키 시퀀스를
|
|
34
|
+
swallow 하는지 진단한 뒤, Ghostty 또는 Windows Terminal 설정에 맞는
|
|
35
|
+
CSI-u 바인딩을 자동 머지한다.
|
|
36
|
+
- **`projmux doctor`** — 런타임 의존성 점검 + 최소 버전 강제 (tmux 3.4,
|
|
37
|
+
fzf 0.55).
|
|
38
|
+
- **`projmux focus`** — AI reply-ready 와 status-bar notify 클릭이 공유하는
|
|
39
|
+
통합 switch-client 디스패처.
|
|
40
|
+
- **영속 notify queue** — `projmux notify push|list|ack|reconcile` 가 TTL,
|
|
41
|
+
severity, source, target 메타데이터를 가진 큐를 디스크에 보존한다.
|
|
42
|
+
자세한 내용은 [notify-queue.md](docs/notify-queue.md).
|
|
43
|
+
- **Authoritative 사용량 추적** — `projmux usage` 가 Claude OAuth usage
|
|
44
|
+
endpoint 와 Codex 로컬 rollout 의 `rate_limits` 를 직접 읽는다.
|
|
45
|
+
자세한 내용은 [usage-tracking.md](docs/usage-tracking.md).
|
|
46
|
+
- **Two-line clickable status bar** — row 0 는 native window list 를 그대로
|
|
47
|
+
살려 탭 클릭으로 전환할 수 있고, row 1 은 좌측 notify HUD 와 우측 usage
|
|
48
|
+
HUD 로 분할된다. 폭이 좁아지면 두 세그먼트 모두 단계적으로 축소된다.
|
|
49
|
+
자세한 내용은 [statusbar.md](docs/statusbar.md).
|
|
50
|
+
|
|
51
|
+
## 무엇을 하나
|
|
52
|
+
|
|
53
|
+
- 프로젝트 디렉터리에서 tmux session을 만들거나 기존 session으로 전환.
|
|
54
|
+
- 기존 session을 window/pane preview와 함께 탐색.
|
|
55
|
+
- `fzf` 기반 popup/sidebar navigation 제공.
|
|
56
|
+
- 자주 쓰는 프로젝트 pin 관리와 일반적인 source root 자동 탐색.
|
|
57
|
+
- window/pane preview 선택 상태 저장 및 빠른 순환.
|
|
58
|
+
- launcher, rename prompt, pane border, status segment, attention hook을 위한
|
|
59
|
+
tmux binding 생성.
|
|
60
|
+
- git branch와 Kubernetes context/namespace를 status area에 표시.
|
|
61
|
+
- Two-line clickable status bar — row 0 의 native 윈도우 목록은 탭 클릭으로
|
|
62
|
+
바로 전환되고, row 1 은 notify(좌)와 AI usage(우) HUD 세그먼트로 분할된다.
|
|
63
|
+
- Codex/Claude/plain shell split을 만들고 agent/topic/status/notification 상태를
|
|
64
|
+
tmux UI에 표시.
|
|
65
|
+
|
|
66
|
+
## 일반적인 사용 흐름
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
projmux shell
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
앱을 한 번 실행한 뒤, 생성된 tmux binding으로 다음 일을 합니다:
|
|
73
|
+
|
|
74
|
+
- sidebar 또는 popup에서 프로젝트 이동,
|
|
75
|
+
- attach 전에 session 내용을 미리 확인,
|
|
76
|
+
- 현재 workspace에 Codex, Claude, plain shell split 추가,
|
|
77
|
+
- window와 AI pane topic rename,
|
|
78
|
+
- 확인이 필요한 pane을 badge와 desktop notification으로 파악.
|
|
79
|
+
|
|
80
|
+
## 요구 사항
|
|
81
|
+
|
|
82
|
+
- [Go 1.24+](https://go.dev/dl/) — binary 설치/빌드에 필요.
|
|
83
|
+
- [tmux](https://github.com/tmux/tmux/wiki/Installing) **≥ 3.4** — workspace 런타임. 이전 버전은 `display-popup -T` 등 projmux 가 사용하는 기능이 없습니다.
|
|
84
|
+
- [fzf](https://github.com/junegunn/fzf#installation) **≥ 0.55** — popup/sidebar picker. 멀티라인 피커가 `--marker-multi-line`, `--gap-line`, `--highlight-line` 을 사용하며 모두 0.55 까지 도입됐습니다.
|
|
85
|
+
- [zsh](https://zsh.sourceforge.io/) — `projmux shell` 이 만드는 앱 tmux 설정의 기본 shell.
|
|
86
|
+
- [git](https://git-scm.com/downloads) — branch/status segment.
|
|
87
|
+
- `stty` — POSIX 터미널 제어, `projmux setup` 에서 사용. macOS/Linux 기본 시스템에 이미 포함, Windows 호스트에선 해당 없음.
|
|
88
|
+
- [kubectl](https://kubernetes.io/docs/tasks/tools/) — 선택, Kubernetes status segment 사용 시에만.
|
|
89
|
+
|
|
90
|
+
데스크톱 알림: Linux 는 `notify-send`, WSL 은 `powershell.exe` 토스트를 사용합니다.
|
|
91
|
+
다른 실행 파일로 보내려면 `PROJMUX_NOTIFY_HOOK` 을 설정하세요.
|
|
92
|
+
|
|
93
|
+
`projmux doctor` 를 실행하면 위 의존성이 모두 PATH 에 있는지, tmux/fzf 가
|
|
94
|
+
최소 지원 버전을 만족하는지 한 번에 확인할 수 있습니다.
|
|
95
|
+
|
|
96
|
+
## 설치
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
go install github.com/crevissepartners/projmux/cmd/projmux@latest
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
binary 는 `$(go env GOBIN)` (설정된 경우) 또는 `$(go env GOPATH)/bin`
|
|
103
|
+
(기본값 `~/go/bin`) 에 떨어집니다. 해당 디렉터리가 `PATH` 에 있어야 합니다:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
export PATH="$(go env GOPATH)/bin:$PATH"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
확인:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
projmux version
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 선택: `PROJMUX_PROJDIR`
|
|
116
|
+
|
|
117
|
+
`PROJMUX_PROJDIR` 은 projmux 가 picker/탐색에서 기본으로 사용할 프로젝트
|
|
118
|
+
루트입니다. 설정하지 않으면 projmux 가 내장된 source-root 탐색(`~/source`,
|
|
119
|
+
`~/work`, `~/projects`, `~/src`, `~/code`, `~/source/repos`) 으로 자동
|
|
120
|
+
fallback 합니다.
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
export PROJMUX_PROJDIR="$HOME/source/repos"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`~/.zshrc` (또는 사용 중인 shell rc 파일) 에 한 줄 추가하면 됩니다. 첫 실행
|
|
127
|
+
이후에는 `~/.config/projmux/projdir` 에 memoize 되므로, 이후 env 가 없어도 같은
|
|
128
|
+
루트가 유지됩니다.
|
|
129
|
+
|
|
130
|
+
`PROJMUX_PROJDIR` 은 OS-native PATH 형식의 multi-path 도 받습니다 (Linux/macOS
|
|
131
|
+
는 `:`, Windows 는 `;`). 첫 번째 비어있지 않은 항목이 primary 프로젝트 루트가
|
|
132
|
+
되고, 이후 항목은 `PROJMUX_MANAGED_ROOTS` 처럼 managed roots 검색 목록 앞에
|
|
133
|
+
prepend 됩니다. saved 파일에는 primary 만 memoize 됩니다.
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
# Linux/macOS — primary repo + 보조 검색 root
|
|
137
|
+
export PROJMUX_PROJDIR="$HOME/source/repos:/srv/work/repos"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### 최초 설치 시 projdir 지정
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
PROJMUX_PROJDIR=/your/path go install github.com/crevissepartners/projmux/cmd/projmux@latest
|
|
144
|
+
PROJMUX_PROJDIR=/your/path projmux tmux apply
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
env 가 살아있는 첫 실행이 `~/.config/projmux/projdir` 에 값을 기록하므로,
|
|
148
|
+
이후 새 shell 에서 env 없이도 같은 루트가 유지됩니다.
|
|
149
|
+
|
|
150
|
+
### 소스에서 빌드
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
git clone https://github.com/crevissepartners/projmux.git
|
|
154
|
+
cd projmux
|
|
155
|
+
make install
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`make install` 은 빌드 후 `$(go env GOPATH)/bin/projmux` 를 atomically 교체하고
|
|
159
|
+
`projmux tmux apply` 를 실행해 동작 중인 `-L projmux` 서버가 즉시 새 binding 을
|
|
160
|
+
반영하도록 합니다. 설치 위치는 `INSTALL_DIR=/usr/local/bin` 으로 override.
|
|
161
|
+
|
|
162
|
+
## 빠른 시작
|
|
163
|
+
|
|
164
|
+
격리된 projmux tmux 앱을 실행합니다:
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
projmux shell
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
projmux가 이 tmux 서버, 생성된 설정, status bar, popup binding을 직접 소유합니다.
|
|
171
|
+
하단 좌측 뱃지에는 현재 프로젝트 이름이, 우측에는 경로/kube/git/시간이 표시됩니다.
|
|
172
|
+
|
|
173
|
+
키가 동작하지 않으면 `projmux setup` 으로 터미널이 어떤 시퀀스를 swallow 하는지
|
|
174
|
+
진단한 뒤, `projmux init [terminal] --apply` (terminal 생략 시 자동 감지) 로
|
|
175
|
+
필요한 CSI-u 바인딩을 터미널 설정에 머지하세요. 여러 머신을 dotfiles 로
|
|
176
|
+
관리하는 경우에는 `--allow-symlink` 또는 `--config <path>` 로 의도를 명시합니다.
|
|
177
|
+
전체 흐름과 수동 CSI-u fallback 은 [터미널 키 설정](docs/keybindings.md) 참고.
|
|
178
|
+
|
|
179
|
+
뭔가 동작이 이상하면 `projmux doctor` 가 어떤 의존성이 누락/구버전인지와
|
|
180
|
+
설치 방법을 알려줍니다. 지원 버전은 [요구 사항](#요구-사항) 참고.
|
|
181
|
+
|
|
182
|
+
## 업그레이드
|
|
183
|
+
|
|
184
|
+
`projmux upgrade` 는 `go install` 로 binary 를 다시 받아 atomically 교체하고,
|
|
185
|
+
동작 중인 `-L projmux` 서버에 라이브 tmux 설정까지 다시 적용합니다.
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
projmux upgrade # @latest 로 교체 + apply
|
|
189
|
+
projmux upgrade --ref @v0.2.0 # 특정 tag 고정
|
|
190
|
+
projmux upgrade --ref @main # branch tracking
|
|
191
|
+
projmux upgrade --target /usr/local/bin/projmux # 다른 경로 교체
|
|
192
|
+
projmux upgrade --no-apply # 'projmux tmux apply' 생략
|
|
193
|
+
projmux upgrade --dry-run # 실행 없이 단계만 출력
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
upgrade 는 호출 shell 의 `PROJMUX_PROJDIR` 을 읽어 primary (첫 번째) 경로를
|
|
197
|
+
`~/.config/projmux/projdir` 에 memoize 하므로, 새 binary 도 같은 프로젝트 루트
|
|
198
|
+
컨텍스트를 유지합니다.
|
|
199
|
+
|
|
200
|
+
업그레이드와 동시에 새 프로젝트 루트로 전환하고 싶다면 env 와 함께 호출하세요:
|
|
201
|
+
|
|
202
|
+
```sh
|
|
203
|
+
PROJMUX_PROJDIR=/new/path projmux upgrade
|
|
204
|
+
|
|
205
|
+
# multi-path 도 동일하게 동작합니다. saved 파일에는 primary 만 기록됩니다.
|
|
206
|
+
PROJMUX_PROJDIR="/main/repos:/secondary/repos" projmux upgrade # Linux/macOS
|
|
207
|
+
# Windows: PROJMUX_PROJDIR="C:\main\repos;C:\secondary\repos"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 사용법
|
|
211
|
+
|
|
212
|
+
일상 작업은 `projmux shell` 안의 tmux 키바인딩으로 진행합니다 —
|
|
213
|
+
[터미널 키 설정](docs/keybindings.md) 참고. pin / preview / status helper /
|
|
214
|
+
`upgrade` 같은 CLI 전체 표면은 `projmux help` 또는 `<command> --help` 로 확인할
|
|
215
|
+
수 있습니다.
|
|
216
|
+
|
|
217
|
+
## 프로젝트 탐색 방식
|
|
218
|
+
|
|
219
|
+
`projmux switch`는 pinned directory, 현재 살아 있는 tmux session, 발견된
|
|
220
|
+
project root를 합쳐 후보를 만듭니다. 기본 탐색은 존재하는 경우 `~/source`,
|
|
221
|
+
`~/work`, `~/projects`, `~/src`, `~/code`, `~/source/repos` 같은 일반적인
|
|
222
|
+
소스 디렉터리를 우선합니다. `projmux settings`의 `Project Picker > Add
|
|
223
|
+
Project...`는 이 filesystem root를 depth 3까지 스캔하므로 `~`나 `~rp` 밖의
|
|
224
|
+
프로젝트도 picker 후보로 추가할 수 있습니다. 세션 이름은 정규화된 디렉터리
|
|
225
|
+
경로에서 만들어지므로 같은 프로젝트는 다시 실행해도 같은 tmux 세션으로 연결됩니다.
|
|
226
|
+
|
|
227
|
+
탐색 root를 영구적으로 커스터마이즈하려면 Project Picker 섹션의 다음 항목을
|
|
228
|
+
사용하세요:
|
|
229
|
+
|
|
230
|
+
- `+ Add Workdir...` - 디렉터리 하나를 saved workdirs 목록에 누적 추가.
|
|
231
|
+
- `Workdirs` - 저장된 workdir 검토/삭제. 환경변수 `PROJMUX_MANAGED_ROOTS` /
|
|
232
|
+
`TMUX_SESSIONIZER_ROOTS`가 설정되어 있으면 read-only 행으로 함께 표시되어
|
|
233
|
+
saved 목록 대신 env list가 우선되는 이유를 한눈에 볼 수 있습니다.
|
|
234
|
+
|
|
235
|
+
`Add Workdir > Type path manually...`를 고르면 파일시스템 스캔을 건너뛰고
|
|
236
|
+
경로를 직접 입력할 수 있습니다. 스캔에 부담이 큰 WSL 마운트
|
|
237
|
+
(`/mnt/c/Users/...`), 대용량 NFS, 프로젝트별 임시 루트 등에 활용하세요.
|
|
238
|
+
|
|
239
|
+
저장 파일은 `~/.config/projmux/workdirs`이며, 절대경로 한 줄당 한 항목이고
|
|
240
|
+
`#`로 시작하는 줄은 주석으로 무시됩니다. env가 설정되어 있을 때는 무시되며
|
|
241
|
+
env가 비었을 때만 사용됩니다.
|
|
242
|
+
|
|
243
|
+
## Hooks
|
|
244
|
+
|
|
245
|
+
projmux는 새 tmux 세션을 만들 때마다 선택적 사용자 스크립트
|
|
246
|
+
`~/.config/projmux/hooks/post-create`를 실행합니다. `tmux set-environment`로
|
|
247
|
+
세션별 환경 변수를 주입하거나(예: 프로젝트 경로별 `GH_TOKEN` 선택) 다른
|
|
248
|
+
부수 효과를 걸 때 활용하세요. 파일이 없거나 실행 비트가 빠져 있으면 조용히
|
|
249
|
+
건너뛰며, hook 실패는 세션 생성을 막지 않습니다. 환경 변수 계약, 예시,
|
|
250
|
+
문제 해결은 [Hooks](docs/hooks.md)를 참고하세요.
|
|
251
|
+
|
|
252
|
+
## 환경 변수
|
|
253
|
+
|
|
254
|
+
| 변수 | 용도 |
|
|
255
|
+
| --- | --- |
|
|
256
|
+
| `PROJMUX_PROJDIR` | 현재 shell 의 기본 프로젝트 루트. OS-native PATH 형식 multi-value 지원: 첫 항목이 primary repo root (saved 파일에 memoize), 이후 항목은 managed-roots 검색 목록 앞에 prepend. |
|
|
257
|
+
| `PROJMUX_MANAGED_ROOTS` | 콜론 구분 검색 root 목록. saved/default 보다 우선. |
|
|
258
|
+
| `PROJMUX_NOTIFY_HOOK` | AI desktop notification 을 내장 sender 대신 받는 외부 실행 파일. |
|
|
259
|
+
| `PROJMUX_USAGE_STATE_DIR` | AI 사용량 snapshot 캐시 디렉터리. 기본값은 `<state>/projmux/usage`. Dropbox/iCloud 같은 동기화 위치를 가리키게 하면 여러 머신 사이에서 authoritative 사용량을 공유할 수 있다. |
|
|
260
|
+
| `PROJMUX_USAGE_DEBUG` | 비어 있지 않으면 `projmux status usage` 의 adapter 오류를 swallow 하지 않고 stderr 로 surface 한다. |
|
|
261
|
+
| `PROJMUX_USAGE_LIMITS_PATH` | 사용 중단 (deprecated). limit 값은 upstream API (Anthropic OAuth usage endpoint, Codex `rate_limits`) 에서 직접 가져오므로 이 변수는 읽되 무시된다. |
|
|
262
|
+
|
|
263
|
+
## AI 사용량 추적
|
|
264
|
+
|
|
265
|
+
`projmux usage` 는 Claude Code 와 Codex CLI 양쪽의 authoritative 5시간 / 주간
|
|
266
|
+
사용률을 보고한다. 두 어댑터 모두 upstream 의 계정 뷰를 직접 읽으므로 `claude
|
|
267
|
+
/usage` 와 `codex` 가 native 로 보여주는 숫자와 일치한다:
|
|
268
|
+
|
|
269
|
+
- **Claude** — `~/.claude/.credentials.json` 의 bearer 토큰으로
|
|
270
|
+
`GET https://api.anthropic.com/api/oauth/usage` 호출. 401 응답 시 한 번의
|
|
271
|
+
refresh round-trip 을 수행해 credentials 파일을 회전된 토큰으로 다시 쓴다.
|
|
272
|
+
토큰은 로그에 기록되지 않는다.
|
|
273
|
+
- **Codex** — 가장 최근의 `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl` 에서
|
|
274
|
+
마지막 `rate_limits` 페이로드를 읽는다. `primary` 는 5시간 창,
|
|
275
|
+
`secondary` 는 주간 창에 매핑된다.
|
|
276
|
+
|
|
277
|
+
Snapshot 은 `<state>/projmux/usage/snapshots.json` (또는
|
|
278
|
+
`PROJMUX_USAGE_STATE_DIR`) 에 저장되며, tmux 상태바에서 `projmux status
|
|
279
|
+
usage` 가 실행될 때 최대 30초 주기로만 refresh 된다.
|
|
280
|
+
|
|
281
|
+
## 범위
|
|
282
|
+
|
|
283
|
+
`projmux`는 portable한 세션 관리 핵심을 담당합니다. 예를 들어 session naming,
|
|
284
|
+
project discovery, pin, preview state, tmux orchestration, status segment,
|
|
285
|
+
생성 가능한 tmux binding이 여기에 속합니다.
|
|
286
|
+
|
|
287
|
+
## 개발
|
|
288
|
+
|
|
289
|
+
자주 쓰는 명령:
|
|
290
|
+
|
|
291
|
+
```sh
|
|
292
|
+
make build
|
|
293
|
+
make fmt
|
|
294
|
+
make fix
|
|
295
|
+
make test
|
|
296
|
+
make test-integration
|
|
297
|
+
make test-e2e
|
|
298
|
+
make verify
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
추가 문서:
|
|
302
|
+
|
|
303
|
+
- [Architecture](docs/architecture.md)
|
|
304
|
+
- [CLI Reference](docs/cli.md)
|
|
305
|
+
- [Statusbar](docs/statusbar.md)
|
|
306
|
+
- [Notify queue](docs/notify-queue.md)
|
|
307
|
+
- [Usage tracking](docs/usage-tracking.md)
|
|
308
|
+
- [Hooks](docs/hooks.md)
|
|
309
|
+
- [Migration Plan](docs/migration-plan.md)
|
|
310
|
+
- [Repo Layout](docs/repo-layout.md)
|
|
311
|
+
- [터미널 키 설정](docs/keybindings.md)
|
|
312
|
+
- [Agent Workflow](docs/agent-workflow.md)
|
|
313
|
+
|
|
314
|
+
## 라이선스
|
|
315
|
+
|
|
316
|
+
MIT. [LICENSE](LICENSE)를 참고하세요.
|
package/README.md
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# projmux
|
|
2
|
+
|
|
3
|
+
Project-aware tmux workspace management for people who live in terminals.
|
|
4
|
+
|
|
5
|
+
`projmux` turns project directories into durable tmux workspaces with previews,
|
|
6
|
+
sidebar navigation, generated keybindings, status metadata, and AI-pane
|
|
7
|
+
attention signals. It can run as its own tmux app (`projmux shell`) or install
|
|
8
|
+
the same behavior into your existing tmux server.
|
|
9
|
+
|
|
10
|
+
[한국어 README](README-ko.md)
|
|
11
|
+
|
|
12
|
+
## Why projmux
|
|
13
|
+
|
|
14
|
+
Most tmux project switchers stop at "pick a directory and attach a session".
|
|
15
|
+
`projmux` treats that as the foundation, then adds the app-level pieces needed
|
|
16
|
+
for a daily terminal workspace:
|
|
17
|
+
|
|
18
|
+
- **Project identity stays stable.** Directories, pins, live sessions, preview
|
|
19
|
+
selection, and lifecycle commands all use the same normalized session model.
|
|
20
|
+
- **The UI shows context before you switch.** Popup and sidebar pickers preview
|
|
21
|
+
sessions, windows, panes, git branch, Kubernetes context, and pane metadata.
|
|
22
|
+
- **The tmux layer is generated, not hand-spliced.** `projmux` writes the tmux
|
|
23
|
+
config it needs for popup launchers, window/pane rename flows, status
|
|
24
|
+
segments, pane borders, attention badges, and app mode.
|
|
25
|
+
- **AI panes are first-class.** Codex and Claude panes can be launched,
|
|
26
|
+
labeled, tracked as thinking or waiting, surfaced in pane/window/session
|
|
27
|
+
badges, and announced through desktop notifications.
|
|
28
|
+
- **You can choose isolation or integration.** Use `projmux shell` as a
|
|
29
|
+
self-contained tmux app, or install the generated snippet into your normal
|
|
30
|
+
tmux server.
|
|
31
|
+
|
|
32
|
+
## What's new in 0.4
|
|
33
|
+
|
|
34
|
+
- **`projmux setup` / `projmux init`** — diagnose terminal key delivery,
|
|
35
|
+
then auto-merge the right CSI-u bindings into Ghostty or Windows
|
|
36
|
+
Terminal configs.
|
|
37
|
+
- **`projmux doctor`** — runtime dependency report with minimum-version
|
|
38
|
+
enforcement (tmux 3.4, fzf 0.55).
|
|
39
|
+
- **`projmux focus`** — unified switch-client dispatch shared by the
|
|
40
|
+
AI reply-ready flow and the status-bar notify click.
|
|
41
|
+
- **Persistent notify queue** — `projmux notify push|list|ack|reconcile`
|
|
42
|
+
with TTL, severity, source, and target metadata. See
|
|
43
|
+
[notify-queue.md](docs/notify-queue.md).
|
|
44
|
+
- **Authoritative usage tracking** — `projmux usage` reads Claude's
|
|
45
|
+
OAuth usage endpoint and Codex's local rollout `rate_limits`. See
|
|
46
|
+
[usage-tracking.md](docs/usage-tracking.md).
|
|
47
|
+
- **Two-line clickable status bar** — row 0 keeps the native window
|
|
48
|
+
list (click a tab to switch), row 1 splits a notify HUD pill (left)
|
|
49
|
+
and a usage HUD bar (right). Both segments degrade gracefully on
|
|
50
|
+
narrow status budgets. See [statusbar.md](docs/statusbar.md).
|
|
51
|
+
|
|
52
|
+
## What It Does
|
|
53
|
+
|
|
54
|
+
- Creates or switches to tmux sessions from project directories.
|
|
55
|
+
- Shows existing sessions with window and pane previews.
|
|
56
|
+
- Provides popup and sidebar navigation surfaces backed by `fzf`.
|
|
57
|
+
- Pins important projects and scans common source roots for new ones.
|
|
58
|
+
- Persists preview selection for fast window and pane cycling.
|
|
59
|
+
- Generates tmux bindings for launchers, rename prompts, pane borders, status
|
|
60
|
+
segments, and attention hooks.
|
|
61
|
+
- Displays git branch and Kubernetes context/namespace in the status area.
|
|
62
|
+
- Renders a two-line clickable status bar with click-to-switch tabs on
|
|
63
|
+
row 0 and HUD-style notify (left) and AI usage (right) segments on
|
|
64
|
+
row 1.
|
|
65
|
+
- Launches AI splits and keeps their agent name, topic, status, and
|
|
66
|
+
notification state visible in tmux.
|
|
67
|
+
|
|
68
|
+
## Typical Workflow
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
projmux shell
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Open the app once, then use its generated tmux bindings to:
|
|
75
|
+
|
|
76
|
+
- jump between projects from a sidebar or popup,
|
|
77
|
+
- inspect sessions before attaching,
|
|
78
|
+
- split Codex, Claude, or a plain shell into the current workspace,
|
|
79
|
+
- rename windows and AI pane topics without losing metadata,
|
|
80
|
+
- see which panes need review from badges and desktop notifications.
|
|
81
|
+
|
|
82
|
+
## Requirements
|
|
83
|
+
|
|
84
|
+
- [Go 1.24+](https://go.dev/dl/) — required to install or build the binary.
|
|
85
|
+
- [tmux](https://github.com/tmux/tmux/wiki/Installing) **≥ 3.4** — the workspace runtime. Earlier versions miss `display-popup -T` and other features projmux depends on.
|
|
86
|
+
- [fzf](https://github.com/junegunn/fzf#installation) **≥ 0.55** — interactive popup/sidebar pickers. The multiline picker uses `--marker-multi-line`, `--gap-line`, and `--highlight-line`, which landed by 0.55.
|
|
87
|
+
- [zsh](https://zsh.sourceforge.io/) — default shell of the generated app config (`projmux shell`).
|
|
88
|
+
- [git](https://git-scm.com/downloads) — branch/status metadata.
|
|
89
|
+
- `stty` — POSIX terminal control, used by `projmux setup`. Already shipped by every macOS / Linux base system; not applicable on Windows hosts.
|
|
90
|
+
- [kubectl](https://kubernetes.io/docs/tasks/tools/) — optional, only for the Kubernetes status segment.
|
|
91
|
+
|
|
92
|
+
Desktop notifications: Linux uses `notify-send`; WSL routes Windows toasts via
|
|
93
|
+
`powershell.exe`. Override either with `PROJMUX_NOTIFY_HOOK`.
|
|
94
|
+
|
|
95
|
+
Run `projmux doctor` any time to verify everything is on `PATH` and that
|
|
96
|
+
tmux/fzf meet the minimum supported versions.
|
|
97
|
+
|
|
98
|
+
## Install
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
go install github.com/crevissepartners/projmux/cmd/projmux@latest
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
This drops the binary in `$(go env GOBIN)` (when set) or `$(go env GOPATH)/bin`
|
|
105
|
+
(default `~/go/bin`). Make sure that directory is on your `PATH`:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
export PATH="$(go env GOPATH)/bin:$PATH"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Verify:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
projmux version
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Optional: `PROJMUX_PROJDIR`
|
|
118
|
+
|
|
119
|
+
`PROJMUX_PROJDIR` is the default project root projmux uses for picker and
|
|
120
|
+
discovery. It is optional — when unset, projmux falls back to its built-in
|
|
121
|
+
source-root discovery (`~/source`, `~/work`, `~/projects`, `~/src`, `~/code`,
|
|
122
|
+
`~/source/repos`).
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
export PROJMUX_PROJDIR="$HOME/source/repos"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Add the line to `~/.zshrc` (or your shell's rc file). The resolved value is
|
|
129
|
+
memoized to `~/.config/projmux/projdir` after first use, so later shells keep
|
|
130
|
+
the same root even without the env var.
|
|
131
|
+
|
|
132
|
+
`PROJMUX_PROJDIR` accepts an OS-native PATH-style multi-value (`:` on
|
|
133
|
+
Linux/macOS, `;` on Windows). The first non-empty entry is the primary
|
|
134
|
+
project root; any additional entries are prepended to the managed-roots
|
|
135
|
+
search list, so they participate in discovery just like
|
|
136
|
+
`PROJMUX_MANAGED_ROOTS`. Only the primary path is memoized to
|
|
137
|
+
`~/.config/projmux/projdir`.
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
# Linux/macOS — primary repo + secondary search root
|
|
141
|
+
export PROJMUX_PROJDIR="$HOME/source/repos:/srv/work/repos"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Set the project root at install time
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
PROJMUX_PROJDIR=/your/path go install github.com/crevissepartners/projmux/cmd/projmux@latest
|
|
148
|
+
PROJMUX_PROJDIR=/your/path projmux tmux apply
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The first invocation that sees the env var writes
|
|
152
|
+
`~/.config/projmux/projdir`, so later shells without the env var still
|
|
153
|
+
resolve the same root.
|
|
154
|
+
|
|
155
|
+
### From source
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
git clone https://github.com/crevissepartners/projmux.git
|
|
159
|
+
cd projmux
|
|
160
|
+
make install
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`make install` builds, atomically replaces `$(go env GOPATH)/bin/projmux`, and
|
|
164
|
+
runs `projmux tmux apply` so the live `-L projmux` server picks up new bindings
|
|
165
|
+
without a restart. Override the destination with `INSTALL_DIR=/usr/local/bin`.
|
|
166
|
+
|
|
167
|
+
## Quick Start
|
|
168
|
+
|
|
169
|
+
Launch the isolated projmux tmux app:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
projmux shell
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
projmux owns this tmux server, its generated config, status bar, and popup
|
|
176
|
+
bindings. The left status badge shows the current project name; the right side
|
|
177
|
+
shows path, kube segment, git segment, and clock.
|
|
178
|
+
|
|
179
|
+
If a key does not fire, run `projmux setup` to see which sequences your
|
|
180
|
+
terminal swallows, then `projmux init [terminal] --apply` (auto-detects when
|
|
181
|
+
no terminal is given) to merge the right CSI-u bindings into your terminal
|
|
182
|
+
config. Dotfiles users on multi-machine setups should pass
|
|
183
|
+
`--allow-symlink` or `--config <path>` to make their intent explicit. Full
|
|
184
|
+
flow and the manual CSI-u fallback are in
|
|
185
|
+
[Terminal Keybindings](docs/keybindings.md).
|
|
186
|
+
|
|
187
|
+
If anything looks off, `projmux doctor` reports which dependency is
|
|
188
|
+
missing or stale and how to install it. See [Requirements](#requirements)
|
|
189
|
+
for the supported versions.
|
|
190
|
+
|
|
191
|
+
## Upgrading
|
|
192
|
+
|
|
193
|
+
`projmux upgrade` reinstalls the binary via `go install`, atomically replaces
|
|
194
|
+
the active file, and reapplies the live tmux config so a running `-L projmux`
|
|
195
|
+
server picks up new bindings without a restart.
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
projmux upgrade # @latest, replace + apply
|
|
199
|
+
projmux upgrade --ref @v0.2.0 # pin a specific tag
|
|
200
|
+
projmux upgrade --ref @main # track a branch
|
|
201
|
+
projmux upgrade --target /usr/local/bin/projmux # replace another path
|
|
202
|
+
projmux upgrade --no-apply # skip 'projmux tmux apply'
|
|
203
|
+
projmux upgrade --dry-run # print the steps only
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The upgrade reads `PROJMUX_PROJDIR` from the calling shell and memoizes the
|
|
207
|
+
primary (first) path to `~/.config/projmux/projdir`, so the new binary keeps
|
|
208
|
+
the same project root context as the one it replaces.
|
|
209
|
+
|
|
210
|
+
Pass a new project root inline to atomically switch the binary and the saved
|
|
211
|
+
projdir in one step:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
PROJMUX_PROJDIR=/new/path projmux upgrade
|
|
215
|
+
|
|
216
|
+
# Multi-path also works; only the primary entry is persisted to the saved file.
|
|
217
|
+
PROJMUX_PROJDIR="/main/repos:/secondary/repos" projmux upgrade # Linux/macOS
|
|
218
|
+
# Windows: PROJMUX_PROJDIR="C:\main\repos;C:\secondary\repos"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Usage
|
|
222
|
+
|
|
223
|
+
Day-to-day, projmux is driven by tmux keybindings inside `projmux shell` — see
|
|
224
|
+
[Terminal Keybindings](docs/keybindings.md). For the full CLI surface (pins,
|
|
225
|
+
preview state, status helpers, `upgrade`, etc.), run `projmux help` or
|
|
226
|
+
`<command> --help`.
|
|
227
|
+
|
|
228
|
+
## How It Finds Projects
|
|
229
|
+
|
|
230
|
+
`projmux switch` combines pinned directories, live tmux sessions, and discovered
|
|
231
|
+
project roots. The default discovery logic favors common source locations such
|
|
232
|
+
as `~/source`, `~/work`, `~/projects`, `~/src`, `~/code`, and `~/source/repos`
|
|
233
|
+
when they exist. `projmux settings` also has `Project Picker > Add Project...`,
|
|
234
|
+
which scans those filesystem roots up to depth 3 so projects outside `~` and
|
|
235
|
+
`~rp` can be added to the picker. Session names are derived from normalized
|
|
236
|
+
directory paths, so a project keeps the same tmux session name across launches.
|
|
237
|
+
|
|
238
|
+
For permanent search-root customization, the Project Picker section also
|
|
239
|
+
includes:
|
|
240
|
+
|
|
241
|
+
- `+ Add Workdir...` - append a single directory to the saved workdirs list.
|
|
242
|
+
- `Workdirs` - review and remove saved workdirs. The same picker also surfaces
|
|
243
|
+
any active `PROJMUX_MANAGED_ROOTS` / `TMUX_SESSIONIZER_ROOTS` env values as
|
|
244
|
+
read-only rows so you can see why an env list might be overriding the saved
|
|
245
|
+
file.
|
|
246
|
+
|
|
247
|
+
`Add Workdir > Type path manually...` gives you a typed entry that skips the
|
|
248
|
+
filesystem scan. Use it for paths you do not want crawled, e.g. WSL mounts
|
|
249
|
+
(`/mnt/c/Users/...`), large NFS mounts, or per-project temp roots.
|
|
250
|
+
|
|
251
|
+
The saved file lives at `~/.config/projmux/workdirs` (one absolute path per
|
|
252
|
+
line, `#` comments allowed). It is consulted only when the env vars are unset.
|
|
253
|
+
|
|
254
|
+
## Hooks
|
|
255
|
+
|
|
256
|
+
projmux runs an optional user script at `~/.config/projmux/hooks/post-create`
|
|
257
|
+
whenever it creates a new tmux session. Use it to inject per-session env via
|
|
258
|
+
`tmux set-environment` (e.g. picking a `GH_TOKEN` based on the project path).
|
|
259
|
+
Missing or non-executable hooks are skipped silently; failures never block
|
|
260
|
+
session creation. See [Hooks](docs/hooks.md) for the env contract, examples,
|
|
261
|
+
and troubleshooting.
|
|
262
|
+
|
|
263
|
+
## Environment Variables
|
|
264
|
+
|
|
265
|
+
| Variable | Purpose |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| `PROJMUX_PROJDIR` | Default project root for the current shell. Accepts an OS-native PATH-style multi-value: the first entry is the primary repo root (memoized to `~/.config/projmux/projdir`), and any additional entries are prepended to the managed-roots search list. |
|
|
268
|
+
| `PROJMUX_MANAGED_ROOTS` | Colon-separated list of search roots. Overrides the saved/default list. |
|
|
269
|
+
| `PROJMUX_NOTIFY_HOOK` | External executable that receives AI desktop notifications instead of the built-in sender. |
|
|
270
|
+
| `PROJMUX_USAGE_STATE_DIR` | Override directory for the AI-usage snapshot cache. Defaults to `<state>/projmux/usage`. Point this at a synced location (Dropbox, iCloud Drive, etc) to share authoritative usage between machines. |
|
|
271
|
+
| `PROJMUX_USAGE_DEBUG` | When non-empty, surfaces adapter errors from `projmux status usage` to stderr instead of swallowing them. |
|
|
272
|
+
| `PROJMUX_USAGE_LIMITS_PATH` | Deprecated. Limits now come from the upstream APIs (Anthropic OAuth usage endpoint, Codex `rate_limits`); this variable is read but ignored. |
|
|
273
|
+
|
|
274
|
+
## AI usage tracking
|
|
275
|
+
|
|
276
|
+
`projmux usage` reports authoritative 5-hour and weekly utilisation for both
|
|
277
|
+
Claude Code and the Codex CLI. Both adapters read from the upstream's own
|
|
278
|
+
view of your account so the percentages match what `claude /usage` and
|
|
279
|
+
`codex` show natively:
|
|
280
|
+
|
|
281
|
+
- **Claude** — calls `GET https://api.anthropic.com/api/oauth/usage` with the
|
|
282
|
+
bearer token in `~/.claude/.credentials.json`. The adapter performs a
|
|
283
|
+
single refresh round-trip on 401 and rewrites the credentials file with
|
|
284
|
+
the rotated tokens. Tokens are never logged.
|
|
285
|
+
- **Codex** — reads the most recent `rate_limits` payload from the newest
|
|
286
|
+
`~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`. `primary` maps to the 5h
|
|
287
|
+
window, `secondary` to the weekly window.
|
|
288
|
+
|
|
289
|
+
Snapshots are persisted under `<state>/projmux/usage/snapshots.json` (or
|
|
290
|
+
`PROJMUX_USAGE_STATE_DIR`) and refreshed at most every 30 seconds when
|
|
291
|
+
`projmux status usage` runs in the tmux status bar.
|
|
292
|
+
|
|
293
|
+
## Scope
|
|
294
|
+
|
|
295
|
+
`projmux` owns the portable session-management core: naming, discovery, pins,
|
|
296
|
+
preview state, tmux orchestration, status segments, and generated tmux bindings.
|
|
297
|
+
|
|
298
|
+
## Development
|
|
299
|
+
|
|
300
|
+
Useful commands:
|
|
301
|
+
|
|
302
|
+
```sh
|
|
303
|
+
make build
|
|
304
|
+
make fmt
|
|
305
|
+
make fix
|
|
306
|
+
make test
|
|
307
|
+
make test-integration
|
|
308
|
+
make test-e2e
|
|
309
|
+
make verify
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
More documentation:
|
|
313
|
+
|
|
314
|
+
- [Architecture](docs/architecture.md)
|
|
315
|
+
- [CLI Reference](docs/cli.md)
|
|
316
|
+
- [Statusbar](docs/statusbar.md)
|
|
317
|
+
- [Notify queue](docs/notify-queue.md)
|
|
318
|
+
- [Usage tracking](docs/usage-tracking.md)
|
|
319
|
+
- [Hooks](docs/hooks.md)
|
|
320
|
+
- [Migration Plan](docs/migration-plan.md)
|
|
321
|
+
- [Repo Layout](docs/repo-layout.md)
|
|
322
|
+
- [Terminal Keybindings](docs/keybindings.md)
|
|
323
|
+
- [Agent Workflow](docs/agent-workflow.md)
|
|
324
|
+
|
|
325
|
+
## License
|
|
326
|
+
|
|
327
|
+
MIT. See [LICENSE](LICENSE).
|
package/npm/projmux.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { spawnSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
const platformPackages = {
|
|
9
|
+
"darwin arm64": "@projmux/darwin-arm64",
|
|
10
|
+
"darwin x64": "@projmux/darwin-x64",
|
|
11
|
+
"linux arm64": "@projmux/linux-arm64",
|
|
12
|
+
"linux x64": "@projmux/linux-x64"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function packageName() {
|
|
16
|
+
return platformPackages[`${process.platform} ${process.arch}`];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function executableCandidates() {
|
|
20
|
+
const candidates = [];
|
|
21
|
+
if (process.env.PROJMUX_BINARY) {
|
|
22
|
+
candidates.push(process.env.PROJMUX_BINARY);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const pkg = packageName();
|
|
26
|
+
if (pkg) {
|
|
27
|
+
try {
|
|
28
|
+
candidates.push(require.resolve(`${pkg}/bin/projmux`));
|
|
29
|
+
} catch (_) {
|
|
30
|
+
// Optional dependency may be omitted by unsupported platforms or install
|
|
31
|
+
// flags. Fall through to the local development binary candidate.
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
candidates.push(path.resolve(__dirname, "..", ".bin", "projmux"));
|
|
36
|
+
return candidates;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveExecutable() {
|
|
40
|
+
for (const candidate of executableCandidates()) {
|
|
41
|
+
if (candidate && fs.existsSync(candidate)) {
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const exe = resolveExecutable();
|
|
49
|
+
if (!exe) {
|
|
50
|
+
const pkg = packageName();
|
|
51
|
+
const target = `${process.platform}/${process.arch}`;
|
|
52
|
+
const detail = pkg
|
|
53
|
+
? `Expected optional dependency ${pkg} to provide bin/projmux.`
|
|
54
|
+
: "No npm platform package is defined for this target.";
|
|
55
|
+
console.error(`projmux: unsupported or incomplete npm install for ${target}.`);
|
|
56
|
+
console.error(detail);
|
|
57
|
+
console.error("Install from GitHub Releases or build from source for this platform.");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const result = spawnSync(exe, process.argv.slice(2), {
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
env: {
|
|
64
|
+
...process.env,
|
|
65
|
+
PROJMUX_INSTALLER: process.env.PROJMUX_INSTALLER || "npm"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (result.error) {
|
|
70
|
+
console.error(`projmux: failed to execute ${exe}: ${result.error.message}`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
CHANGED
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projmux",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "tmux project session manager
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "tmux project session manager",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"
|
|
6
|
+
"homepage": "https://github.com/crevissepartners/projmux#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/crevissepartners/projmux.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/crevissepartners/projmux/issues"
|
|
13
|
+
},
|
|
14
|
+
"type": "commonjs",
|
|
15
|
+
"bin": {
|
|
16
|
+
"projmux": "npm/projmux.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"npm/projmux.js",
|
|
20
|
+
"README.md",
|
|
21
|
+
"README-ko.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"optionalDependencies": {
|
|
25
|
+
"@projmux/darwin-arm64": "0.4.2",
|
|
26
|
+
"@projmux/darwin-x64": "0.4.2",
|
|
27
|
+
"@projmux/linux-arm64": "0.4.2",
|
|
28
|
+
"@projmux/linux-x64": "0.4.2"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"package:npm": "scripts/package-npm.sh",
|
|
32
|
+
"package:npm:pack": "scripts/package-npm.sh --pack"
|
|
33
|
+
}
|
|
7
34
|
}
|