ttyd-mux 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -0
- package/dist/caddy/client.d.ts +84 -0
- package/dist/caddy/client.d.ts.map +1 -0
- package/dist/caddy/client.js +144 -0
- package/dist/caddy/client.js.map +1 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +124 -0
- package/dist/client/index.js.map +1 -0
- package/dist/commands/attach.d.ts +5 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +100 -0
- package/dist/commands/attach.js.map +1 -0
- package/dist/commands/caddy.d.ts +10 -0
- package/dist/commands/caddy.d.ts.map +1 -0
- package/dist/commands/caddy.js +151 -0
- package/dist/commands/caddy.js.map +1 -0
- package/dist/commands/daemon.d.ts +6 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +24 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/down.d.ts +5 -0
- package/dist/commands/down.d.ts.map +1 -0
- package/dist/commands/down.js +25 -0
- package/dist/commands/down.js.map +1 -0
- package/dist/commands/shutdown.d.ts +5 -0
- package/dist/commands/shutdown.d.ts.map +1 -0
- package/dist/commands/shutdown.js +10 -0
- package/dist/commands/shutdown.js.map +1 -0
- package/dist/commands/start.d.ts +6 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +59 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +38 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +6 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +39 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/up.d.ts +8 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +48 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/config/config.d.ts +13 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +53 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/state.d.ts +20 -0
- package/dist/config/state.d.ts.map +1 -0
- package/dist/config/state.js +119 -0
- package/dist/config/state.js.map +1 -0
- package/dist/config/types.d.ts +70 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +17 -0
- package/dist/config/types.js.map +1 -0
- package/dist/daemon/index.d.ts +6 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +103 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/portal.d.ts +4 -0
- package/dist/daemon/portal.d.ts.map +1 -0
- package/dist/daemon/portal.js +127 -0
- package/dist/daemon/portal.js.map +1 -0
- package/dist/daemon/proxy.d.ts +7 -0
- package/dist/daemon/proxy.d.ts.map +1 -0
- package/dist/daemon/proxy.js +17 -0
- package/dist/daemon/proxy.js.map +1 -0
- package/dist/daemon/server.d.ts +5 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +172 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/session-manager.d.ts +37 -0
- package/dist/daemon/session-manager.d.ts.map +1 -0
- package/dist/daemon/session-manager.js +131 -0
- package/dist/daemon/session-manager.js.map +1 -0
- package/dist/daemon/session-resolver.d.ts +41 -0
- package/dist/daemon/session-resolver.d.ts.map +1 -0
- package/dist/daemon/session-resolver.js +68 -0
- package/dist/daemon/session-resolver.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/tmux.d.ts +8 -0
- package/dist/tmux.d.ts.map +1 -0
- package/dist/tmux.js +65 -0
- package/dist/tmux.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +25 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +118 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils/errors.d.ts +25 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +52 -0
- package/dist/utils/errors.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# ttyd-mux
|
|
2
|
+
|
|
3
|
+
ttyd session multiplexer - 複数の ttyd+tmux セッションを管理するCLIツール
|
|
4
|
+
|
|
5
|
+
## 概要
|
|
6
|
+
|
|
7
|
+
ttyd-mux は、複数の Web ターミナル(ttyd)セッションを簡単に管理するためのツールです。
|
|
8
|
+
|
|
9
|
+
- カレントディレクトリで `ttyd-mux up` するだけでブラウザアクセス可能なターミナルを起動
|
|
10
|
+
- 複数セッションを一元管理するポータルページを提供
|
|
11
|
+
- Caddy などのリバースプロキシと連携して外部公開
|
|
12
|
+
|
|
13
|
+
## インストール
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# npm でグローバルインストール
|
|
17
|
+
npm install -g ttyd-mux
|
|
18
|
+
|
|
19
|
+
# または npx で直接実行
|
|
20
|
+
npx ttyd-mux up
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 必要な依存関係
|
|
24
|
+
|
|
25
|
+
- **Node.js** 18 以上(または Bun)
|
|
26
|
+
- **ttyd**: https://github.com/tsl0922/ttyd
|
|
27
|
+
- **tmux**: ターミナルマルチプレクサ
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Ubuntu/Debian
|
|
31
|
+
sudo apt install ttyd tmux
|
|
32
|
+
|
|
33
|
+
# macOS (Homebrew)
|
|
34
|
+
brew install ttyd tmux
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## クイックスタート
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# プロジェクトディレクトリで起動
|
|
41
|
+
cd ~/my-project
|
|
42
|
+
ttyd-mux up
|
|
43
|
+
|
|
44
|
+
# ブラウザでアクセス
|
|
45
|
+
# http://localhost:7680/ttyd-mux/my-project/
|
|
46
|
+
|
|
47
|
+
# 状態確認
|
|
48
|
+
ttyd-mux status
|
|
49
|
+
|
|
50
|
+
# 停止
|
|
51
|
+
ttyd-mux down
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## コマンド
|
|
55
|
+
|
|
56
|
+
### メインコマンド
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
ttyd-mux up [--name <name>] # セッション起動 → 自動アタッチ
|
|
60
|
+
ttyd-mux up --detach # セッション起動のみ(アタッチしない)
|
|
61
|
+
ttyd-mux down # カレントディレクトリのセッション停止
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### セッション管理
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
ttyd-mux start <name> # 事前定義セッションを起動
|
|
68
|
+
ttyd-mux start --all # 全ての事前定義セッションを起動
|
|
69
|
+
ttyd-mux stop <name> # セッション停止
|
|
70
|
+
ttyd-mux stop --all # 全セッション停止
|
|
71
|
+
ttyd-mux status # 状態表示
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 直接アクセス
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ttyd-mux attach [name] # tmuxセッションに直接アタッチ
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### デーモン制御
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ttyd-mux daemon # デーモン起動
|
|
84
|
+
ttyd-mux daemon -f # フォアグラウンドで起動(デバッグ用)
|
|
85
|
+
ttyd-mux shutdown # デーモン終了
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 設定生成
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ttyd-mux generate caddy # Caddyfile生成
|
|
92
|
+
ttyd-mux generate caddy -o Caddyfile --hostname example.com
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 設定
|
|
96
|
+
|
|
97
|
+
設定ファイルは以下の順序で検索されます:
|
|
98
|
+
|
|
99
|
+
1. `./ttyd-mux.yaml`
|
|
100
|
+
2. `./.ttyd-mux.yaml`
|
|
101
|
+
3. `~/.config/ttyd-mux/config.yaml`
|
|
102
|
+
|
|
103
|
+
### 設定例
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
# ~/.config/ttyd-mux/config.yaml
|
|
107
|
+
|
|
108
|
+
# URLパスのプレフィックス
|
|
109
|
+
base_path: /ttyd-mux
|
|
110
|
+
|
|
111
|
+
# ttydセッションのベースポート
|
|
112
|
+
base_port: 7600
|
|
113
|
+
|
|
114
|
+
# デーモンのHTTPポート
|
|
115
|
+
daemon_port: 7680
|
|
116
|
+
|
|
117
|
+
# リッスンアドレス(デフォルト: IPv4 + IPv6 localhost)
|
|
118
|
+
listen_addresses:
|
|
119
|
+
- "127.0.0.1"
|
|
120
|
+
- "::1"
|
|
121
|
+
# - "0.0.0.0" # 外部からのアクセスを許可する場合
|
|
122
|
+
|
|
123
|
+
# セッション起動時に自動でtmuxにアタッチ(デフォルト: true)
|
|
124
|
+
auto_attach: true
|
|
125
|
+
|
|
126
|
+
# 事前定義セッション(オプション)
|
|
127
|
+
sessions:
|
|
128
|
+
- name: project-a
|
|
129
|
+
dir: /home/user/project-a
|
|
130
|
+
path: /project-a
|
|
131
|
+
port_offset: 1
|
|
132
|
+
|
|
133
|
+
- name: project-b
|
|
134
|
+
dir: /home/user/project-b
|
|
135
|
+
path: /project-b
|
|
136
|
+
port_offset: 2
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## アーキテクチャ
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
┌─────────────────┐
|
|
143
|
+
│ ttyd :7601 │
|
|
144
|
+
│ (-b /ttyd-mux/ │
|
|
145
|
+
┌─────────┐ ┌──────────────┐ │ project-a) │
|
|
146
|
+
│ Caddy │──────│ ttyd-mux │───┼─────────────────┤
|
|
147
|
+
│ │ │ daemon │ │ ttyd :7602 │
|
|
148
|
+
│ :443 │ │ :7680 │ │ (-b /ttyd-mux/ │
|
|
149
|
+
└─────────┘ │ │ │ project-b) │
|
|
150
|
+
│ - Portal │ └─────────────────┘
|
|
151
|
+
│ - Proxy │
|
|
152
|
+
│ - API │
|
|
153
|
+
└──────────────┘
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- **Caddy**: 外部からのリクエストを ttyd-mux に転送
|
|
157
|
+
- **ttyd-mux daemon**: ポータル表示 + ttyd へのリバースプロキシ
|
|
158
|
+
- **ttyd**: 各セッションの Web ターミナル(tmux を起動)
|
|
159
|
+
|
|
160
|
+
## Caddy との連携
|
|
161
|
+
|
|
162
|
+
### Admin API で設定(推奨)
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# ルートを追加
|
|
166
|
+
ttyd-mux caddy setup --hostname example.com
|
|
167
|
+
|
|
168
|
+
# 設定を確認
|
|
169
|
+
ttyd-mux caddy status
|
|
170
|
+
|
|
171
|
+
# ルートを削除
|
|
172
|
+
ttyd-mux caddy remove --hostname example.com
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Caddyfile 手動編集
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# コピペ用スニペットを表示
|
|
179
|
+
ttyd-mux caddy snippet
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```caddyfile
|
|
183
|
+
handle /ttyd-mux/* {
|
|
184
|
+
reverse_proxy 127.0.0.1:7680
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
詳細は [docs/caddy-setup.md](docs/caddy-setup.md) を参照。
|
|
189
|
+
|
|
190
|
+
## ファイル構成
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
~/.config/ttyd-mux/
|
|
194
|
+
config.yaml # 設定ファイル
|
|
195
|
+
|
|
196
|
+
~/.local/state/ttyd-mux/
|
|
197
|
+
state.json # 実行中セッションの状態
|
|
198
|
+
ttyd-mux.sock # デーモン通信用ソケット
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 開発
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# 開発実行
|
|
205
|
+
bun run src/index.ts <command>
|
|
206
|
+
|
|
207
|
+
# テスト
|
|
208
|
+
bun test
|
|
209
|
+
|
|
210
|
+
# 型チェック
|
|
211
|
+
bun run typecheck
|
|
212
|
+
|
|
213
|
+
# リント
|
|
214
|
+
bun run check
|
|
215
|
+
|
|
216
|
+
# ビルド(単一実行ファイル)
|
|
217
|
+
bun build src/index.ts --compile --outfile ttyd-mux
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## ライセンス
|
|
221
|
+
|
|
222
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface CaddyConfig {
|
|
2
|
+
apps?: {
|
|
3
|
+
http?: {
|
|
4
|
+
servers?: Record<string, CaddyServer>;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export interface CaddyServer {
|
|
9
|
+
listen?: string[];
|
|
10
|
+
routes?: CaddyRoute[];
|
|
11
|
+
}
|
|
12
|
+
export interface CaddyRoute {
|
|
13
|
+
match?: CaddyMatch[];
|
|
14
|
+
handle?: CaddyHandler[];
|
|
15
|
+
}
|
|
16
|
+
export interface CaddyMatch {
|
|
17
|
+
host?: string[];
|
|
18
|
+
path?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface CaddyHandler {
|
|
21
|
+
handler: string;
|
|
22
|
+
upstreams?: Array<{
|
|
23
|
+
dial: string;
|
|
24
|
+
}>;
|
|
25
|
+
body?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_ADMIN_API = "http://localhost:2019";
|
|
28
|
+
/**
|
|
29
|
+
* Client for Caddy Admin API
|
|
30
|
+
*/
|
|
31
|
+
export declare class CaddyClient {
|
|
32
|
+
private adminApi;
|
|
33
|
+
constructor(adminApi?: string);
|
|
34
|
+
/**
|
|
35
|
+
* Get current Caddy configuration
|
|
36
|
+
*/
|
|
37
|
+
getConfig(): Promise<CaddyConfig>;
|
|
38
|
+
/**
|
|
39
|
+
* Get all HTTP servers
|
|
40
|
+
*/
|
|
41
|
+
getServers(): Promise<Record<string, CaddyServer>>;
|
|
42
|
+
/**
|
|
43
|
+
* Update routes for a server
|
|
44
|
+
*/
|
|
45
|
+
updateServerRoutes(serverName: string, routes: CaddyRoute[]): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Create a new server
|
|
48
|
+
*/
|
|
49
|
+
createServer(serverName: string, server: CaddyServer): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Find server that handles a specific hostname
|
|
52
|
+
*/
|
|
53
|
+
findServerForHost(servers: Record<string, CaddyServer>, hostname: string): {
|
|
54
|
+
name: string;
|
|
55
|
+
server: CaddyServer;
|
|
56
|
+
} | null;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a route exists for hostname and path
|
|
59
|
+
*/
|
|
60
|
+
routeExists(server: CaddyServer, hostname: string, basePath: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Create a reverse proxy route
|
|
63
|
+
*/
|
|
64
|
+
createProxyRoute(hostname: string, basePath: string, upstream: string): CaddyRoute;
|
|
65
|
+
/**
|
|
66
|
+
* Extract upstream from route handlers
|
|
67
|
+
*/
|
|
68
|
+
private extractUpstream;
|
|
69
|
+
/**
|
|
70
|
+
* Find ttyd-mux routes in all servers
|
|
71
|
+
*/
|
|
72
|
+
findTtydMuxRoutes(servers: Record<string, CaddyServer>, basePath: string): Array<{
|
|
73
|
+
serverName: string;
|
|
74
|
+
hosts: string[];
|
|
75
|
+
paths: string[];
|
|
76
|
+
upstream: string;
|
|
77
|
+
}>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Connect to Caddy Admin API and return client
|
|
81
|
+
* Throws error if connection fails
|
|
82
|
+
*/
|
|
83
|
+
export declare function connectToCaddy(adminApi?: string): Promise<CaddyClient>;
|
|
84
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/caddy/client.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE;YACL,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SACvC,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ;gBAAR,QAAQ,GAAE,MAA0B;IAExD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IAQvC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAKxD;;OAEG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAajF;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1E;;OAEG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,QAAQ,EAAE,MAAM,GACf;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI;IAe/C;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAU7E;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAiBlF;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,QAAQ,EAAE,MAAM,GACf,KAAK,CAAC;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CAuBH;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,GAAE,MAA0B,GAAG,OAAO,CAAC,WAAW,CAAC,CAS/F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export const DEFAULT_ADMIN_API = 'http://localhost:2019';
|
|
2
|
+
/**
|
|
3
|
+
* Client for Caddy Admin API
|
|
4
|
+
*/
|
|
5
|
+
export class CaddyClient {
|
|
6
|
+
adminApi;
|
|
7
|
+
constructor(adminApi = DEFAULT_ADMIN_API) {
|
|
8
|
+
this.adminApi = adminApi;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get current Caddy configuration
|
|
12
|
+
*/
|
|
13
|
+
async getConfig() {
|
|
14
|
+
const response = await fetch(`${this.adminApi}/config/`);
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
throw new Error(`Failed to get config: ${response.status}`);
|
|
17
|
+
}
|
|
18
|
+
return (await response.json());
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get all HTTP servers
|
|
22
|
+
*/
|
|
23
|
+
async getServers() {
|
|
24
|
+
const config = await this.getConfig();
|
|
25
|
+
return config.apps?.http?.servers ?? {};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update routes for a server
|
|
29
|
+
*/
|
|
30
|
+
async updateServerRoutes(serverName, routes) {
|
|
31
|
+
const response = await fetch(`${this.adminApi}/config/apps/http/servers/${serverName}/routes`, {
|
|
32
|
+
method: 'PUT',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: JSON.stringify(routes)
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
const text = await response.text();
|
|
38
|
+
throw new Error(`Failed to update routes: ${response.status} ${text}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a new server
|
|
43
|
+
*/
|
|
44
|
+
async createServer(serverName, server) {
|
|
45
|
+
const response = await fetch(`${this.adminApi}/config/apps/http/servers/${serverName}`, {
|
|
46
|
+
method: 'PUT',
|
|
47
|
+
headers: { 'Content-Type': 'application/json' },
|
|
48
|
+
body: JSON.stringify(server)
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
const text = await response.text();
|
|
52
|
+
throw new Error(`Failed to create server: ${response.status} ${text}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Find server that handles a specific hostname
|
|
57
|
+
*/
|
|
58
|
+
findServerForHost(servers, hostname) {
|
|
59
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
60
|
+
const routes = server.routes ?? [];
|
|
61
|
+
for (const route of routes) {
|
|
62
|
+
const matches = route.match ?? [];
|
|
63
|
+
for (const match of matches) {
|
|
64
|
+
if (match.host?.includes(hostname)) {
|
|
65
|
+
return { name, server };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if a route exists for hostname and path
|
|
74
|
+
*/
|
|
75
|
+
routeExists(server, hostname, basePath) {
|
|
76
|
+
const routes = server.routes ?? [];
|
|
77
|
+
return routes.some((route) => {
|
|
78
|
+
const matches = route.match ?? [];
|
|
79
|
+
return matches.some((m) => m.host?.includes(hostname) && m.path?.some((p) => p.startsWith(basePath)));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a reverse proxy route
|
|
84
|
+
*/
|
|
85
|
+
createProxyRoute(hostname, basePath, upstream) {
|
|
86
|
+
return {
|
|
87
|
+
match: [
|
|
88
|
+
{
|
|
89
|
+
host: [hostname],
|
|
90
|
+
path: [`${basePath}/*`]
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
handle: [
|
|
94
|
+
{
|
|
95
|
+
handler: 'reverse_proxy',
|
|
96
|
+
upstreams: [{ dial: upstream }]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Extract upstream from route handlers
|
|
103
|
+
*/
|
|
104
|
+
extractUpstream(route) {
|
|
105
|
+
const handlers = route.handle ?? [];
|
|
106
|
+
const proxyHandler = handlers.find((h) => h.handler === 'reverse_proxy');
|
|
107
|
+
return proxyHandler?.upstreams?.[0]?.dial ?? 'unknown';
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Find ttyd-mux routes in all servers
|
|
111
|
+
*/
|
|
112
|
+
findTtydMuxRoutes(servers, basePath) {
|
|
113
|
+
const results = [];
|
|
114
|
+
for (const [serverName, server] of Object.entries(servers)) {
|
|
115
|
+
for (const route of server.routes ?? []) {
|
|
116
|
+
for (const match of route.match ?? []) {
|
|
117
|
+
const paths = match.path ?? [];
|
|
118
|
+
if (paths.some((p) => p.startsWith(basePath))) {
|
|
119
|
+
const hosts = match.host ?? ['*'];
|
|
120
|
+
const upstream = this.extractUpstream(route);
|
|
121
|
+
results.push({ serverName, hosts, paths, upstream });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return results;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Connect to Caddy Admin API and return client
|
|
131
|
+
* Throws error if connection fails
|
|
132
|
+
*/
|
|
133
|
+
export async function connectToCaddy(adminApi = DEFAULT_ADMIN_API) {
|
|
134
|
+
const client = new CaddyClient(adminApi);
|
|
135
|
+
// Test connection by getting config
|
|
136
|
+
try {
|
|
137
|
+
await client.getConfig();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
throw new Error(`Cannot connect to Caddy Admin API at ${adminApi}`);
|
|
141
|
+
}
|
|
142
|
+
return client;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/caddy/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Config, SessionResponse, StartSessionRequest, StatusResponse } from '../config/types.js';
|
|
2
|
+
export declare function isDaemonRunning(): Promise<boolean>;
|
|
3
|
+
export declare function ensureDaemon(configPath?: string): Promise<void>;
|
|
4
|
+
export declare function shutdownDaemon(): Promise<void>;
|
|
5
|
+
export declare function apiRequest<T>(config: Config, method: string, path: string, body?: unknown): Promise<T>;
|
|
6
|
+
export declare function getStatus(config: Config): Promise<StatusResponse>;
|
|
7
|
+
export declare function getSessions(config: Config): Promise<SessionResponse[]>;
|
|
8
|
+
export declare function startSession(config: Config, request: StartSessionRequest): Promise<SessionResponse>;
|
|
9
|
+
export declare function stopSession(config: Config, name: string): Promise<void>;
|
|
10
|
+
export declare function requestShutdown(config: Config): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,mBAAmB,EACnB,cAAc,EACf,MAAM,oBAAoB,CAAC;AAK5B,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CA6BxD;AAED,wBAAsB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BrE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BpD;AAUD,wBAAsB,UAAU,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,GACb,OAAO,CAAC,CAAC,CAAC,CAgBZ;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEvE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAE5E;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { connect } from 'node:net';
|
|
4
|
+
import { getDaemonState, getSocketPath } from '../config/state.js';
|
|
5
|
+
const DAEMON_START_TIMEOUT = 5000;
|
|
6
|
+
const DAEMON_CHECK_INTERVAL = 100;
|
|
7
|
+
export async function isDaemonRunning() {
|
|
8
|
+
const socketPath = getSocketPath();
|
|
9
|
+
if (!existsSync(socketPath)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const socket = connect(socketPath);
|
|
14
|
+
socket.on('connect', () => {
|
|
15
|
+
socket.write('ping');
|
|
16
|
+
});
|
|
17
|
+
socket.on('data', (data) => {
|
|
18
|
+
const response = data.toString().trim();
|
|
19
|
+
socket.end();
|
|
20
|
+
resolve(response === 'pong');
|
|
21
|
+
});
|
|
22
|
+
socket.on('error', () => {
|
|
23
|
+
resolve(false);
|
|
24
|
+
});
|
|
25
|
+
socket.setTimeout(1000, () => {
|
|
26
|
+
socket.destroy();
|
|
27
|
+
resolve(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export async function ensureDaemon(configPath) {
|
|
32
|
+
if (await isDaemonRunning()) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Find the path to the daemon script
|
|
36
|
+
const daemonScript = new URL('../daemon/index.js', import.meta.url).pathname;
|
|
37
|
+
// Spawn daemon in background (use same runtime as current process)
|
|
38
|
+
const child = spawn(process.execPath, [daemonScript], {
|
|
39
|
+
detached: true,
|
|
40
|
+
stdio: 'ignore',
|
|
41
|
+
env: {
|
|
42
|
+
...process.env,
|
|
43
|
+
TTYD_MUX_CONFIG: configPath ?? ''
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
child.unref();
|
|
47
|
+
// Wait for daemon to be ready
|
|
48
|
+
const startTime = Date.now();
|
|
49
|
+
while (Date.now() - startTime < DAEMON_START_TIMEOUT) {
|
|
50
|
+
if (await isDaemonRunning()) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await sleep(DAEMON_CHECK_INTERVAL);
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Failed to start daemon: timeout');
|
|
56
|
+
}
|
|
57
|
+
export async function shutdownDaemon() {
|
|
58
|
+
const socketPath = getSocketPath();
|
|
59
|
+
if (!existsSync(socketPath)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const socket = connect(socketPath);
|
|
64
|
+
socket.on('connect', () => {
|
|
65
|
+
socket.write('shutdown');
|
|
66
|
+
});
|
|
67
|
+
socket.on('data', (data) => {
|
|
68
|
+
const response = data.toString().trim();
|
|
69
|
+
socket.end();
|
|
70
|
+
if (response === 'ok') {
|
|
71
|
+
resolve();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
reject(new Error('Unexpected response'));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
socket.on('error', (err) => {
|
|
78
|
+
reject(err);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// === HTTP API Client ===
|
|
83
|
+
function getDaemonUrl(config) {
|
|
84
|
+
const daemon = getDaemonState();
|
|
85
|
+
const port = daemon?.port ?? config.daemon_port;
|
|
86
|
+
return `http://localhost:${port}`;
|
|
87
|
+
}
|
|
88
|
+
export async function apiRequest(config, method, path, body) {
|
|
89
|
+
const url = `${getDaemonUrl(config)}${config.base_path}${path}`;
|
|
90
|
+
const response = await fetch(url, {
|
|
91
|
+
method,
|
|
92
|
+
headers: body ? { 'Content-Type': 'application/json' } : undefined,
|
|
93
|
+
body: body ? JSON.stringify(body) : undefined
|
|
94
|
+
});
|
|
95
|
+
const data = await response.json();
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new Error(data.error ?? 'Request failed');
|
|
98
|
+
}
|
|
99
|
+
return data;
|
|
100
|
+
}
|
|
101
|
+
export async function getStatus(config) {
|
|
102
|
+
return apiRequest(config, 'GET', '/api/status');
|
|
103
|
+
}
|
|
104
|
+
export async function getSessions(config) {
|
|
105
|
+
return apiRequest(config, 'GET', '/api/sessions');
|
|
106
|
+
}
|
|
107
|
+
export async function startSession(config, request) {
|
|
108
|
+
return apiRequest(config, 'POST', '/api/sessions', request);
|
|
109
|
+
}
|
|
110
|
+
export async function stopSession(config, name) {
|
|
111
|
+
await apiRequest(config, 'DELETE', `/api/sessions/${encodeURIComponent(name)}`);
|
|
112
|
+
}
|
|
113
|
+
export async function requestShutdown(config) {
|
|
114
|
+
try {
|
|
115
|
+
await apiRequest(config, 'POST', '/api/shutdown');
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Server will shut down, so connection may be lost
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function sleep(ms) {
|
|
122
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CASf"}
|