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
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|