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.
Files changed (106) hide show
  1. package/README.md +222 -0
  2. package/dist/caddy/client.d.ts +84 -0
  3. package/dist/caddy/client.d.ts.map +1 -0
  4. package/dist/caddy/client.js +144 -0
  5. package/dist/caddy/client.js.map +1 -0
  6. package/dist/client/index.d.ts +11 -0
  7. package/dist/client/index.d.ts.map +1 -0
  8. package/dist/client/index.js +124 -0
  9. package/dist/client/index.js.map +1 -0
  10. package/dist/commands/attach.d.ts +5 -0
  11. package/dist/commands/attach.d.ts.map +1 -0
  12. package/dist/commands/attach.js +100 -0
  13. package/dist/commands/attach.js.map +1 -0
  14. package/dist/commands/caddy.d.ts +10 -0
  15. package/dist/commands/caddy.d.ts.map +1 -0
  16. package/dist/commands/caddy.js +151 -0
  17. package/dist/commands/caddy.js.map +1 -0
  18. package/dist/commands/daemon.d.ts +6 -0
  19. package/dist/commands/daemon.d.ts.map +1 -0
  20. package/dist/commands/daemon.js +24 -0
  21. package/dist/commands/daemon.js.map +1 -0
  22. package/dist/commands/down.d.ts +5 -0
  23. package/dist/commands/down.d.ts.map +1 -0
  24. package/dist/commands/down.js +25 -0
  25. package/dist/commands/down.js.map +1 -0
  26. package/dist/commands/shutdown.d.ts +5 -0
  27. package/dist/commands/shutdown.d.ts.map +1 -0
  28. package/dist/commands/shutdown.js +10 -0
  29. package/dist/commands/shutdown.js.map +1 -0
  30. package/dist/commands/start.d.ts +6 -0
  31. package/dist/commands/start.d.ts.map +1 -0
  32. package/dist/commands/start.js +59 -0
  33. package/dist/commands/start.js.map +1 -0
  34. package/dist/commands/status.d.ts +5 -0
  35. package/dist/commands/status.d.ts.map +1 -0
  36. package/dist/commands/status.js +38 -0
  37. package/dist/commands/status.js.map +1 -0
  38. package/dist/commands/stop.d.ts +6 -0
  39. package/dist/commands/stop.d.ts.map +1 -0
  40. package/dist/commands/stop.js +39 -0
  41. package/dist/commands/stop.js.map +1 -0
  42. package/dist/commands/up.d.ts +8 -0
  43. package/dist/commands/up.d.ts.map +1 -0
  44. package/dist/commands/up.js +48 -0
  45. package/dist/commands/up.js.map +1 -0
  46. package/dist/config/config.d.ts +13 -0
  47. package/dist/config/config.d.ts.map +1 -0
  48. package/dist/config/config.js +53 -0
  49. package/dist/config/config.js.map +1 -0
  50. package/dist/config/index.d.ts +4 -0
  51. package/dist/config/index.d.ts.map +1 -0
  52. package/dist/config/index.js +4 -0
  53. package/dist/config/index.js.map +1 -0
  54. package/dist/config/state.d.ts +20 -0
  55. package/dist/config/state.d.ts.map +1 -0
  56. package/dist/config/state.js +119 -0
  57. package/dist/config/state.js.map +1 -0
  58. package/dist/config/types.d.ts +70 -0
  59. package/dist/config/types.d.ts.map +1 -0
  60. package/dist/config/types.js +17 -0
  61. package/dist/config/types.js.map +1 -0
  62. package/dist/daemon/index.d.ts +6 -0
  63. package/dist/daemon/index.d.ts.map +1 -0
  64. package/dist/daemon/index.js +103 -0
  65. package/dist/daemon/index.js.map +1 -0
  66. package/dist/daemon/portal.d.ts +4 -0
  67. package/dist/daemon/portal.d.ts.map +1 -0
  68. package/dist/daemon/portal.js +127 -0
  69. package/dist/daemon/portal.js.map +1 -0
  70. package/dist/daemon/proxy.d.ts +7 -0
  71. package/dist/daemon/proxy.d.ts.map +1 -0
  72. package/dist/daemon/proxy.js +17 -0
  73. package/dist/daemon/proxy.js.map +1 -0
  74. package/dist/daemon/server.d.ts +5 -0
  75. package/dist/daemon/server.d.ts.map +1 -0
  76. package/dist/daemon/server.js +172 -0
  77. package/dist/daemon/server.js.map +1 -0
  78. package/dist/daemon/session-manager.d.ts +37 -0
  79. package/dist/daemon/session-manager.d.ts.map +1 -0
  80. package/dist/daemon/session-manager.js +131 -0
  81. package/dist/daemon/session-manager.js.map +1 -0
  82. package/dist/daemon/session-resolver.d.ts +41 -0
  83. package/dist/daemon/session-resolver.d.ts.map +1 -0
  84. package/dist/daemon/session-resolver.js +68 -0
  85. package/dist/daemon/session-resolver.js.map +1 -0
  86. package/dist/index.d.ts +3 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +95 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/tmux.d.ts +8 -0
  91. package/dist/tmux.d.ts.map +1 -0
  92. package/dist/tmux.js +65 -0
  93. package/dist/tmux.js.map +1 -0
  94. package/dist/types.d.ts +7 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/dist/ui.d.ts +25 -0
  99. package/dist/ui.d.ts.map +1 -0
  100. package/dist/ui.js +118 -0
  101. package/dist/ui.js.map +1 -0
  102. package/dist/utils/errors.d.ts +25 -0
  103. package/dist/utils/errors.d.ts.map +1 -0
  104. package/dist/utils/errors.js +52 -0
  105. package/dist/utils/errors.js.map +1 -0
  106. package/package.json +69 -0
@@ -0,0 +1,100 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { getSessions, isDaemonRunning } from '../client/index.js';
3
+ import { loadConfig } from '../config/config.js';
4
+ export async function attachCommand(name, options) {
5
+ // If no name provided, show selection UI
6
+ if (!name) {
7
+ await interactiveAttach(options);
8
+ return;
9
+ }
10
+ // Attach to named session
11
+ await attachToSession(name);
12
+ }
13
+ async function interactiveAttach(_options) {
14
+ // Check if daemon is running to get session list
15
+ const running = await isDaemonRunning();
16
+ let sessions = [];
17
+ if (running) {
18
+ try {
19
+ sessions = await getSessions(loadConfig(_options.config));
20
+ }
21
+ catch {
22
+ // Ignore errors
23
+ }
24
+ }
25
+ // Also get tmux sessions directly
26
+ const tmuxSessions = await getTmuxSessions();
27
+ // Merge session lists (prefer daemon info)
28
+ const allSessions = new Map();
29
+ for (const session of sessions) {
30
+ allSessions.set(session.name, session.dir);
31
+ }
32
+ for (const name of tmuxSessions) {
33
+ if (!allSessions.has(name)) {
34
+ allSessions.set(name, '');
35
+ }
36
+ }
37
+ if (allSessions.size === 0) {
38
+ console.log('No tmux sessions available.');
39
+ console.log('Start one with: ttyd-mux up');
40
+ return;
41
+ }
42
+ // Simple selection UI
43
+ const sessionList = Array.from(allSessions.entries());
44
+ console.log('Available sessions:');
45
+ sessionList.forEach(([name, dir], index) => {
46
+ const dirInfo = dir ? ` (${dir})` : '';
47
+ console.log(` ${index + 1}. ${name}${dirInfo}`);
48
+ });
49
+ // Read user input
50
+ const readline = await import('node:readline');
51
+ const rl = readline.createInterface({
52
+ input: process.stdin,
53
+ output: process.stdout
54
+ });
55
+ rl.question('\nSelect session (number or name): ', async (answer) => {
56
+ rl.close();
57
+ const num = Number.parseInt(answer, 10);
58
+ let sessionName;
59
+ if (!Number.isNaN(num) && num >= 1 && num <= sessionList.length) {
60
+ const entry = sessionList[num - 1];
61
+ sessionName = entry ? entry[0] : answer.trim();
62
+ }
63
+ else {
64
+ sessionName = answer.trim();
65
+ }
66
+ if (!sessionName) {
67
+ console.log('Cancelled.');
68
+ return;
69
+ }
70
+ await attachToSession(sessionName);
71
+ });
72
+ }
73
+ async function attachToSession(name) {
74
+ // Check if inside tmux
75
+ const insideTmux = !!process.env['TMUX'];
76
+ const args = insideTmux ? ['switch-client', '-t', name] : ['attach-session', '-t', name];
77
+ const tmux = spawn('tmux', args, {
78
+ stdio: 'inherit'
79
+ });
80
+ tmux.on('exit', (code) => {
81
+ process.exit(code ?? 0);
82
+ });
83
+ }
84
+ async function getTmuxSessions() {
85
+ const { execSync } = await import('node:child_process');
86
+ try {
87
+ const output = execSync('tmux list-sessions -F "#{session_name}"', {
88
+ encoding: 'utf-8',
89
+ stdio: ['pipe', 'pipe', 'pipe']
90
+ });
91
+ return output
92
+ .trim()
93
+ .split('\n')
94
+ .filter((s) => s.length > 0);
95
+ }
96
+ catch {
97
+ return [];
98
+ }
99
+ }
100
+ //# sourceMappingURL=attach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface CaddyOptions {
2
+ hostname?: string;
3
+ adminApi?: string;
4
+ config?: string;
5
+ }
6
+ export declare function caddySnippetCommand(options: CaddyOptions): void;
7
+ export declare function caddySetupCommand(options: CaddyOptions): Promise<void>;
8
+ export declare function caddyRemoveCommand(options: CaddyOptions): Promise<void>;
9
+ export declare function caddyStatusCommand(options: CaddyOptions): Promise<void>;
10
+ //# sourceMappingURL=caddy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caddy.d.ts","sourceRoot":"","sources":["../../src/commands/caddy.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAU/D;AAGD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmE5E;AAGD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C7E;AAGD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC7E"}
@@ -0,0 +1,151 @@
1
+ import { DEFAULT_ADMIN_API, connectToCaddy } from '../caddy/client.js';
2
+ import { loadConfig } from '../config/config.js';
3
+ import { handleCliError } from '../utils/errors.js';
4
+ // Generate snippet for Caddyfile users
5
+ export function caddySnippetCommand(options) {
6
+ const config = loadConfig(options.config);
7
+ const basePath = config.base_path;
8
+ const daemonPort = config.daemon_port;
9
+ console.log('# Add this to your Caddyfile inside your site block:');
10
+ console.log('');
11
+ console.log(`handle ${basePath}/* {`);
12
+ console.log(` reverse_proxy localhost:${daemonPort}`);
13
+ console.log('}');
14
+ }
15
+ // Setup route via Admin API
16
+ export async function caddySetupCommand(options) {
17
+ const config = loadConfig(options.config);
18
+ const adminApi = options.adminApi ?? DEFAULT_ADMIN_API;
19
+ const hostname = options.hostname;
20
+ if (!hostname) {
21
+ console.error('Error: --hostname is required');
22
+ process.exit(1);
23
+ }
24
+ const basePath = config.base_path;
25
+ const daemonPort = config.daemon_port;
26
+ let client;
27
+ try {
28
+ client = await connectToCaddy(adminApi);
29
+ }
30
+ catch {
31
+ console.error(`Error: Cannot connect to Caddy Admin API at ${adminApi}`);
32
+ console.error('Make sure Caddy is running and admin API is enabled.');
33
+ process.exit(1);
34
+ }
35
+ try {
36
+ const servers = await client.getServers();
37
+ const ttydMuxRoute = client.createProxyRoute(hostname, basePath, `localhost:${daemonPort}`);
38
+ const serverInfo = client.findServerForHost(servers, hostname);
39
+ if (serverInfo) {
40
+ // Add route to existing server
41
+ if (client.routeExists(serverInfo.server, hostname, basePath)) {
42
+ console.log(`Route for ${hostname}${basePath}/* already exists.`);
43
+ return;
44
+ }
45
+ // Prepend route (higher priority)
46
+ const existingRoutes = serverInfo.server.routes ?? [];
47
+ await client.updateServerRoutes(serverInfo.name, [ttydMuxRoute, ...existingRoutes]);
48
+ console.log(`Added route: ${hostname}${basePath}/* -> localhost:${daemonPort}`);
49
+ }
50
+ else {
51
+ // Create new server with this route
52
+ const newServer = {
53
+ listen: [':443'],
54
+ routes: [
55
+ ttydMuxRoute,
56
+ {
57
+ // Fallback route
58
+ handle: [
59
+ {
60
+ handler: 'static_response',
61
+ body: 'OK'
62
+ }
63
+ ]
64
+ }
65
+ ]
66
+ };
67
+ const serverName = `srv_${hostname.replace(/\./g, '_')}`;
68
+ await client.createServer(serverName, newServer);
69
+ console.log(`Created server for ${hostname} with route: ${basePath}/* -> localhost:${daemonPort}`);
70
+ }
71
+ }
72
+ catch (error) {
73
+ handleCliError('Error', error);
74
+ process.exit(1);
75
+ }
76
+ }
77
+ // Remove route via Admin API
78
+ export async function caddyRemoveCommand(options) {
79
+ const config = loadConfig(options.config);
80
+ const adminApi = options.adminApi ?? DEFAULT_ADMIN_API;
81
+ const hostname = options.hostname;
82
+ if (!hostname) {
83
+ console.error('Error: --hostname is required');
84
+ process.exit(1);
85
+ }
86
+ const basePath = config.base_path;
87
+ let client;
88
+ try {
89
+ client = await connectToCaddy(adminApi);
90
+ }
91
+ catch {
92
+ console.error(`Error: Cannot connect to Caddy Admin API at ${adminApi}`);
93
+ process.exit(1);
94
+ }
95
+ try {
96
+ const servers = await client.getServers();
97
+ // Find and remove the route
98
+ for (const [serverName, server] of Object.entries(servers)) {
99
+ const routes = server.routes ?? [];
100
+ const filteredRoutes = routes.filter((route) => {
101
+ const matches = route.match ?? [];
102
+ return !matches.some((m) => m.host?.includes(hostname) && m.path?.some((p) => p.startsWith(basePath)));
103
+ });
104
+ if (filteredRoutes.length < routes.length) {
105
+ await client.updateServerRoutes(serverName, filteredRoutes);
106
+ console.log(`Removed route: ${hostname}${basePath}/*`);
107
+ return;
108
+ }
109
+ }
110
+ console.log(`Route for ${hostname}${basePath}/* not found.`);
111
+ }
112
+ catch (error) {
113
+ handleCliError('Error', error);
114
+ process.exit(1);
115
+ }
116
+ }
117
+ // Show current Caddy status
118
+ export async function caddyStatusCommand(options) {
119
+ const config = loadConfig(options.config);
120
+ const adminApi = options.adminApi ?? DEFAULT_ADMIN_API;
121
+ const basePath = config.base_path;
122
+ let client;
123
+ try {
124
+ client = await connectToCaddy(adminApi);
125
+ }
126
+ catch {
127
+ console.error(`Error: Cannot connect to Caddy Admin API at ${adminApi}`);
128
+ console.error('Make sure Caddy is running and admin API is enabled.');
129
+ process.exit(1);
130
+ }
131
+ console.log(`Caddy Admin API: ${adminApi}`);
132
+ console.log('');
133
+ const servers = await client.getServers();
134
+ if (Object.keys(servers).length === 0) {
135
+ console.log('No HTTP servers configured.');
136
+ return;
137
+ }
138
+ const routes = client.findTtydMuxRoutes(servers, basePath);
139
+ if (routes.length === 0) {
140
+ console.log(`No ttyd-mux routes found (looking for ${basePath}/*)`);
141
+ return;
142
+ }
143
+ for (const route of routes) {
144
+ console.log(`ttyd-mux route found in server "${route.serverName}":`);
145
+ console.log(` Hosts: ${route.hosts.join(', ')}`);
146
+ console.log(` Path: ${route.paths.join(', ')}`);
147
+ console.log(` Upstream: ${route.upstream}`);
148
+ console.log('');
149
+ }
150
+ }
151
+ //# sourceMappingURL=caddy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caddy.js","sourceRoot":"","sources":["../../src/commands/caddy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface DaemonOptions {
2
+ foreground?: boolean;
3
+ config?: string;
4
+ }
5
+ export declare function daemonCommand(options: DaemonOptions): Promise<void>;
6
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBzE"}
@@ -0,0 +1,24 @@
1
+ import { isDaemonRunning } from '../client/index.js';
2
+ import { startDaemon } from '../daemon/index.js';
3
+ export async function daemonCommand(options) {
4
+ // Check if already running
5
+ if (await isDaemonRunning()) {
6
+ console.log('Daemon is already running.');
7
+ console.log('Use "ttyd-mux shutdown" to stop it first.');
8
+ process.exit(1);
9
+ }
10
+ if (options.foreground) {
11
+ // Run in foreground
12
+ await startDaemon({
13
+ configPath: options.config,
14
+ foreground: true
15
+ });
16
+ }
17
+ else {
18
+ // Import and use ensureDaemon to start in background
19
+ const { ensureDaemon } = await import('../client/index.js');
20
+ await ensureDaemon(options.config);
21
+ console.log('Daemon started in background.');
22
+ }
23
+ }
24
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,2BAA2B;IAC3B,IAAI,MAAM,eAAe,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,oBAAoB;QACpB,MAAM,WAAW,CAAC;YAChB,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,qDAAqD;QACrD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC5D,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface DownOptions {
2
+ config?: string;
3
+ }
4
+ export declare function downCommand(options: DownOptions): Promise<void>;
5
+ //# sourceMappingURL=down.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBrE"}
@@ -0,0 +1,25 @@
1
+ import { ensureDaemon, getSessions, stopSession } from '../client/index.js';
2
+ import { loadConfig } from '../config/config.js';
3
+ import { handleCliError } from '../utils/errors.js';
4
+ export async function downCommand(options) {
5
+ const config = loadConfig(options.config);
6
+ const dir = process.cwd();
7
+ // Ensure daemon is running
8
+ await ensureDaemon(options.config);
9
+ // Find session for current directory
10
+ const sessions = await getSessions(config);
11
+ const session = sessions.find((s) => s.dir === dir);
12
+ if (!session) {
13
+ console.error(`No session found for directory: ${dir}`);
14
+ process.exit(1);
15
+ }
16
+ try {
17
+ await stopSession(config, session.name);
18
+ console.log(`Session "${session.name}" stopped`);
19
+ }
20
+ catch (error) {
21
+ handleCliError('Failed to stop session', error);
22
+ process.exit(1);
23
+ }
24
+ }
25
+ //# sourceMappingURL=down.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,2BAA2B;IAC3B,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC,qCAAqC;IACrC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAEpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,WAAW,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface ShutdownOptions {
2
+ config?: string;
3
+ }
4
+ export declare function shutdownCommand(_options: ShutdownOptions): Promise<void>;
5
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9E"}
@@ -0,0 +1,10 @@
1
+ import { isDaemonRunning, shutdownDaemon } from '../client/index.js';
2
+ export async function shutdownCommand(_options) {
3
+ const running = await isDaemonRunning();
4
+ if (!running) {
5
+ console.log('Daemon is not running.');
6
+ return;
7
+ }
8
+ await shutdownDaemon();
9
+ }
10
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMrE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAyB;IAC7D,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;IAExC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,cAAc,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface StartOptions {
2
+ all?: boolean;
3
+ config?: string;
4
+ }
5
+ export declare function startCommand(name: string | undefined, options: StartOptions): Promise<void>;
6
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DjG"}
@@ -0,0 +1,59 @@
1
+ import { startSession as apiStartSession, ensureDaemon } from '../client/index.js';
2
+ import { findSessionDefinition, getFullPath, loadConfig } from '../config/config.js';
3
+ import { handleCliError } from '../utils/errors.js';
4
+ export async function startCommand(name, options) {
5
+ const config = loadConfig(options.config);
6
+ // Ensure daemon is running
7
+ await ensureDaemon(options.config);
8
+ if (options.all) {
9
+ // Start all predefined sessions
10
+ const sessions = config.sessions ?? [];
11
+ if (sessions.length === 0) {
12
+ console.log('No sessions defined in config.');
13
+ return;
14
+ }
15
+ for (const sessionDef of sessions) {
16
+ try {
17
+ const session = await apiStartSession(config, {
18
+ name: sessionDef.name,
19
+ dir: sessionDef.dir,
20
+ path: sessionDef.path
21
+ });
22
+ const fullPath = getFullPath(config, session.path);
23
+ console.log(`Started "${session.name}" on :${session.port} (${fullPath})`);
24
+ }
25
+ catch (error) {
26
+ handleCliError(`Failed to start "${sessionDef.name}"`, error);
27
+ }
28
+ }
29
+ return;
30
+ }
31
+ if (!name) {
32
+ console.error('Session name required. Use --all to start all sessions.');
33
+ process.exit(1);
34
+ }
35
+ // Find session definition
36
+ const sessionDef = findSessionDefinition(config, name);
37
+ if (!sessionDef) {
38
+ console.error(`Session "${name}" not found in config.`);
39
+ process.exit(1);
40
+ }
41
+ try {
42
+ const session = await apiStartSession(config, {
43
+ name: sessionDef.name,
44
+ dir: sessionDef.dir,
45
+ path: sessionDef.path
46
+ });
47
+ const fullPath = getFullPath(config, session.path);
48
+ const url = `http://localhost:${config.daemon_port}${fullPath}/`;
49
+ console.log(`Session "${session.name}" started`);
50
+ console.log(` Port: ${session.port}`);
51
+ console.log(` Path: ${fullPath}`);
52
+ console.log(` URL: ${url}`);
53
+ }
54
+ catch (error) {
55
+ handleCliError('Failed to start session', error);
56
+ process.exit(1);
57
+ }
58
+ }
59
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface StatusOptions {
2
+ config?: string;
3
+ }
4
+ export declare function statusCommand(options: StatusOptions): Promise<void>;
5
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCzE"}
@@ -0,0 +1,38 @@
1
+ import { getStatus, isDaemonRunning } from '../client/index.js';
2
+ import { getFullPath, loadConfig } from '../config/config.js';
3
+ import { handleCliError } from '../utils/errors.js';
4
+ export async function statusCommand(options) {
5
+ const config = loadConfig(options.config);
6
+ const running = await isDaemonRunning();
7
+ if (!running) {
8
+ console.log('Daemon: not running');
9
+ console.log('\nStart daemon with: ttyd-mux daemon');
10
+ return;
11
+ }
12
+ try {
13
+ const status = await getStatus(config);
14
+ console.log('Daemon: running');
15
+ if (status.daemon) {
16
+ console.log(` PID: ${status.daemon.pid}`);
17
+ console.log(` Port: ${status.daemon.port}`);
18
+ }
19
+ console.log('\nSessions:');
20
+ if (status.sessions.length === 0) {
21
+ console.log(' (no active sessions)');
22
+ }
23
+ else {
24
+ for (const session of status.sessions) {
25
+ const fullPath = getFullPath(config, session.path);
26
+ console.log(` ${session.name}`);
27
+ console.log(` Port: ${session.port}`);
28
+ console.log(` Path: ${fullPath}`);
29
+ console.log(` Dir: ${session.dir}`);
30
+ }
31
+ }
32
+ }
33
+ catch (error) {
34
+ handleCliError('Failed to get status', error);
35
+ process.exit(1);
36
+ }
37
+ }
38
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMpD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QAEvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnD,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzC,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface StopOptions {
2
+ all?: boolean;
3
+ config?: string;
4
+ }
5
+ export declare function stopCommand(name: string | undefined, options: StopOptions): Promise<void>;
6
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC/F"}
@@ -0,0 +1,39 @@
1
+ import { ensureDaemon, getSessions, stopSession } from '../client/index.js';
2
+ import { loadConfig } from '../config/config.js';
3
+ import { handleCliError } from '../utils/errors.js';
4
+ export async function stopCommand(name, options) {
5
+ const config = loadConfig(options.config);
6
+ // Ensure daemon is running
7
+ await ensureDaemon(options.config);
8
+ if (options.all) {
9
+ // Stop all sessions
10
+ const sessions = await getSessions(config);
11
+ if (sessions.length === 0) {
12
+ console.log('No active sessions.');
13
+ return;
14
+ }
15
+ for (const session of sessions) {
16
+ try {
17
+ await stopSession(config, session.name);
18
+ console.log(`Stopped "${session.name}"`);
19
+ }
20
+ catch (error) {
21
+ handleCliError(`Failed to stop "${session.name}"`, error);
22
+ }
23
+ }
24
+ return;
25
+ }
26
+ if (!name) {
27
+ console.error('Session name required. Use --all to stop all sessions.');
28
+ process.exit(1);
29
+ }
30
+ try {
31
+ await stopSession(config, name);
32
+ console.log(`Session "${name}" stopped`);
33
+ }
34
+ catch (error) {
35
+ handleCliError('Failed to stop session', error);
36
+ process.exit(1);
37
+ }
38
+ }
39
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAOpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAwB,EAAE,OAAoB;IAC9E,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C,2BAA2B;IAC3B,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,oBAAoB;QACpB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,cAAc,CAAC,mBAAmB,OAAO,CAAC,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,WAAW,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface UpOptions {
2
+ name?: string;
3
+ config?: string;
4
+ attach?: boolean;
5
+ detach?: boolean;
6
+ }
7
+ export declare function upCommand(options: UpOptions): Promise<void>;
8
+ //# sourceMappingURL=up.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CjE"}