ttyd-mux 0.3.0 → 0.4.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 +105 -1
- package/dist/caddy/client.d.ts +3 -55
- package/dist/caddy/client.d.ts.map +1 -1
- package/dist/caddy/client.js +0 -73
- package/dist/caddy/client.js.map +1 -1
- package/dist/caddy/route-builder.d.ts +49 -0
- package/dist/caddy/route-builder.d.ts.map +1 -0
- package/dist/caddy/route-builder.js +175 -0
- package/dist/caddy/route-builder.js.map +1 -0
- package/dist/caddy/types.d.ts +27 -0
- package/dist/caddy/types.d.ts.map +1 -0
- package/dist/caddy/types.js +3 -0
- package/dist/caddy/types.js.map +1 -0
- package/dist/client/api-client.d.ts +26 -0
- package/dist/client/api-client.d.ts.map +1 -0
- package/dist/client/api-client.js +62 -0
- package/dist/client/api-client.js.map +1 -0
- package/dist/client/daemon-client.d.ts +48 -0
- package/dist/client/daemon-client.d.ts.map +1 -0
- package/dist/client/daemon-client.js +205 -0
- package/dist/client/daemon-client.js.map +1 -0
- package/dist/client/index.d.ts +2 -10
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -136
- package/dist/client/index.js.map +1 -1
- package/dist/commands/attach.js +3 -4
- package/dist/commands/attach.js.map +1 -1
- package/dist/commands/caddy.d.ts +2 -1
- package/dist/commands/caddy.d.ts.map +1 -1
- package/dist/commands/caddy.js +227 -75
- package/dist/commands/caddy.js.map +1 -1
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +100 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +180 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +11 -0
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/reload.d.ts +14 -0
- package/dist/commands/reload.d.ts.map +1 -0
- package/dist/commands/reload.js +50 -0
- package/dist/commands/reload.js.map +1 -0
- package/dist/commands/shutdown.d.ts +2 -1
- package/dist/commands/shutdown.d.ts.map +1 -1
- package/dist/commands/shutdown.js +8 -2
- package/dist/commands/shutdown.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +16 -3
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/stop.js.map +1 -1
- package/dist/commands/up.js.map +1 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +9 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/state-store.d.ts +27 -0
- package/dist/config/state-store.d.ts.map +1 -0
- package/dist/config/state-store.js +55 -0
- package/dist/config/state-store.js.map +1 -0
- package/dist/config/state.d.ts +6 -0
- package/dist/config/state.d.ts.map +1 -1
- package/dist/config/state.js +49 -14
- package/dist/config/state.js.map +1 -1
- package/dist/config/types.d.ts +35 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +23 -1
- package/dist/config/types.js.map +1 -1
- package/dist/daemon/api-handler.d.ts +5 -0
- package/dist/daemon/api-handler.d.ts.map +1 -0
- package/dist/daemon/api-handler.js +97 -0
- package/dist/daemon/api-handler.js.map +1 -0
- package/dist/daemon/config-manager.d.ts +43 -0
- package/dist/daemon/config-manager.d.ts.map +1 -0
- package/dist/daemon/config-manager.js +154 -0
- package/dist/daemon/config-manager.js.map +1 -0
- package/dist/daemon/http-proxy.d.ts +27 -0
- package/dist/daemon/http-proxy.d.ts.map +1 -0
- package/dist/daemon/http-proxy.js +110 -0
- package/dist/daemon/http-proxy.js.map +1 -0
- package/dist/daemon/ime-helper.d.ts +1 -1
- package/dist/daemon/ime-helper.d.ts.map +1 -1
- package/dist/daemon/ime-helper.js +284 -10
- package/dist/daemon/ime-helper.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +134 -29
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/portal-utils.d.ts +20 -0
- package/dist/daemon/portal-utils.d.ts.map +1 -0
- package/dist/daemon/portal-utils.js +109 -0
- package/dist/daemon/portal-utils.js.map +1 -0
- package/dist/daemon/portal.d.ts.map +1 -1
- package/dist/daemon/portal.js +20 -77
- package/dist/daemon/portal.js.map +1 -1
- package/dist/daemon/pwa.d.ts +52 -0
- package/dist/daemon/pwa.d.ts.map +1 -0
- package/dist/daemon/pwa.js +229 -0
- package/dist/daemon/pwa.js.map +1 -0
- package/dist/daemon/router.d.ts +15 -0
- package/dist/daemon/router.d.ts.map +1 -0
- package/dist/daemon/router.js +164 -0
- package/dist/daemon/router.js.map +1 -0
- package/dist/daemon/server.d.ts +15 -3
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +23 -271
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/session-manager.d.ts +44 -10
- package/dist/daemon/session-manager.d.ts.map +1 -1
- package/dist/daemon/session-manager.js +125 -49
- package/dist/daemon/session-manager.js.map +1 -1
- package/dist/daemon/session-resolver.d.ts +1 -1
- package/dist/daemon/session-resolver.d.ts.map +1 -1
- package/dist/daemon/session-resolver.js.map +1 -1
- package/dist/daemon/toolbar/config.d.ts +13 -0
- package/dist/daemon/toolbar/config.d.ts.map +1 -0
- package/dist/daemon/toolbar/config.js +13 -0
- package/dist/daemon/toolbar/config.js.map +1 -0
- package/dist/daemon/toolbar/index.d.ts +43 -0
- package/dist/daemon/toolbar/index.d.ts.map +1 -0
- package/dist/daemon/toolbar/index.js +835 -0
- package/dist/daemon/toolbar/index.js.map +1 -0
- package/dist/daemon/toolbar/styles.d.ts +5 -0
- package/dist/daemon/toolbar/styles.d.ts.map +1 -0
- package/dist/daemon/toolbar/styles.js +278 -0
- package/dist/daemon/toolbar/styles.js.map +1 -0
- package/dist/daemon/toolbar/template.d.ts +6 -0
- package/dist/daemon/toolbar/template.d.ts.map +1 -0
- package/dist/daemon/toolbar/template.js +45 -0
- package/dist/daemon/toolbar/template.js.map +1 -0
- package/dist/daemon/ws-proxy.d.ts +17 -0
- package/dist/daemon/ws-proxy.d.ts.map +1 -0
- package/dist/daemon/ws-proxy.js +95 -0
- package/dist/daemon/ws-proxy.js.map +1 -0
- package/dist/deploy/caddyfile.d.ts +8 -0
- package/dist/deploy/caddyfile.d.ts.map +1 -0
- package/dist/deploy/caddyfile.js +62 -0
- package/dist/deploy/caddyfile.js.map +1 -0
- package/dist/deploy/deploy-script.d.ts +8 -0
- package/dist/deploy/deploy-script.d.ts.map +1 -0
- package/dist/deploy/deploy-script.js +72 -0
- package/dist/deploy/deploy-script.js.map +1 -0
- package/dist/deploy/static-portal.d.ts +3 -0
- package/dist/deploy/static-portal.d.ts.map +1 -0
- package/dist/deploy/static-portal.js +59 -0
- package/dist/deploy/static-portal.js.map +1 -0
- package/dist/index.js +38 -9
- package/dist/index.js.map +1 -1
- package/dist/test-setup.d.ts +19 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +33 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/tmux.d.ts +28 -1
- package/dist/tmux.d.ts.map +1 -1
- package/dist/tmux.js +37 -32
- package/dist/tmux.js.map +1 -1
- package/dist/ui.d.ts +2 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +16 -9
- package/dist/ui.js.map +1 -1
- package/dist/utils/errors.d.ts +4 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +9 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +53 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/process-runner.d.ts +50 -0
- package/dist/utils/process-runner.d.ts.map +1 -0
- package/dist/utils/process-runner.js +73 -0
- package/dist/utils/process-runner.js.map +1 -0
- package/dist/utils/socket-client.d.ts +24 -0
- package/dist/utils/socket-client.d.ts.map +1 -0
- package/dist/utils/socket-client.js +30 -0
- package/dist/utils/socket-client.js.map +1 -0
- package/dist/utils/tmux-client.d.ts +57 -0
- package/dist/utils/tmux-client.d.ts.map +1 -0
- package/dist/utils/tmux-client.js +117 -0
- package/dist/utils/tmux-client.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -2
- package/dist/daemon/proxy.d.ts +0 -7
- package/dist/daemon/proxy.d.ts.map +0 -1
- package/dist/daemon/proxy.js +0 -17
- package/dist/daemon/proxy.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,sBAAsB,EAAsB,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5D,sDAAsD;AACtD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC;AAE3D,8BAA8B;AAC9B,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAEtD,oCAAoC;AACpC,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAGlC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAwB,sBAAsB;IAC7E,MAAM,EACJ,aAAa,EACb,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EACjB,GAAG,MAAM,CAAC;IAEX,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAmCiB,aAAa;0BACb,aAAa;yCACE,wBAAwB,MAAM,oBAAoB;mCACxD,WAAW;4BAClB,oBAAoB;kCACd,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAknBjB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+GvC,CAAC;AACP,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,SAAwB,sBAAsB;IACzE,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAAgB;IAC1D,MAAM,SAAS,GAAG;SACX,aAAa;EACpB,WAAW;EACX,cAAc,CAAC,OAAO,CAAC,8BAA8B,EAAE,mDAAmD,CAAC;eAC9F,QAAQ;CACtB,CAAC;IACA,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,SAAS,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Toolbar CSS Styles
|
|
3
|
+
*/
|
|
4
|
+
export declare const toolbarStyles = "\n#ttyd-toolbar {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-top: 2px solid #007acc;\n padding: 8px;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n box-shadow: 0 -2px 10px rgba(0,0,0,0.3);\n}\n\n#ttyd-toolbar.hidden {\n display: none;\n}\n\n#ttyd-toolbar-buttons {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n flex-wrap: wrap;\n}\n\n#ttyd-toolbar-buttons button {\n background: #3a3a3a;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n cursor: pointer;\n font-size: 13px;\n padding: 8px 12px;\n min-height: 40px;\n min-width: 44px;\n touch-action: manipulation;\n flex-shrink: 0;\n}\n\n#ttyd-toolbar-buttons button:hover, #ttyd-toolbar-buttons button:active {\n background: #4a4a4a;\n}\n\n#ttyd-toolbar-buttons button.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-toolbar-buttons button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-toolbar-buttons button.modifier.active {\n background: #d9534f;\n border-color: #c9302c;\n}\n\n#ttyd-toolbar-send {\n background: #007acc !important;\n border-color: #005a9e !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-send:hover, #ttyd-toolbar-send:active {\n background: #005a9e !important;\n}\n\n#ttyd-toolbar-run {\n background: #28a745 !important;\n border-color: #1e7e34 !important;\n font-weight: bold;\n}\n\n#ttyd-toolbar-run:hover, #ttyd-toolbar-run:active {\n background: #1e7e34 !important;\n}\n\n#ttyd-toolbar-auto.active {\n background: #f0ad4e !important;\n border-color: #eea236 !important;\n color: #000;\n}\n\n#ttyd-toolbar-scroll.active {\n background: #17a2b8 !important;\n border-color: #138496 !important;\n}\n\n#ttyd-toolbar-input-row {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n}\n\n#ttyd-toolbar-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 8px;\n color: #fff;\n font-family: monospace;\n font-size: 16px;\n padding: 12px;\n outline: none;\n resize: none;\n min-height: 44px;\n max-height: 120px;\n line-height: 1.4;\n}\n\n#ttyd-toolbar-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-toolbar-input::placeholder {\n color: #888;\n}\n\n#ttyd-toolbar-toggle {\n position: fixed;\n bottom: 16px;\n right: 16px;\n background: #007acc;\n border: 2px solid #005a9e;\n border-radius: 50%;\n color: #fff;\n cursor: pointer;\n font-size: 20px;\n width: 56px;\n height: 56px;\n z-index: 10001;\n touch-action: manipulation;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n#ttyd-toolbar-toggle:hover, #ttyd-toolbar-toggle:active {\n background: #005a9e;\n transform: scale(1.05);\n}\n\n#ttyd-toolbar.hidden ~ #ttyd-toolbar-toggle {\n bottom: 16px;\n}\n\n/* Adjust terminal height when toolbar is visible */\nbody:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 140px) !important;\n}\n\n/* Minimized mode - compact toolbar with input only */\n#ttyd-toolbar.minimized #ttyd-toolbar-buttons {\n display: none;\n}\n\n#ttyd-toolbar.minimized {\n padding: 4px 8px;\n}\n\n#ttyd-toolbar-minimize {\n background: #555 !important;\n border-color: #666 !important;\n font-size: 10px;\n padding: 4px 8px;\n min-width: 32px;\n min-height: 32px;\n}\n\n/* Onboarding tooltip */\n#ttyd-toolbar-onboarding {\n position: fixed;\n bottom: 90px;\n right: 16px;\n background: #333;\n border: 1px solid #007acc;\n border-radius: 8px;\n padding: 12px 16px;\n color: #fff;\n font-size: 13px;\n max-width: 280px;\n z-index: 10002;\n box-shadow: 0 4px 12px rgba(0,0,0,0.4);\n line-height: 1.5;\n}\n\n#ttyd-toolbar-onboarding::after {\n content: '';\n position: absolute;\n bottom: -8px;\n right: 24px;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-top: 8px solid #333;\n}\n\n#ttyd-toolbar-onboarding-close {\n position: absolute;\n top: 4px;\n right: 8px;\n background: none;\n border: none;\n color: #888;\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n#ttyd-toolbar-onboarding-close:hover {\n color: #fff;\n}\n\n#ttyd-toolbar-onboarding ul {\n margin: 8px 0 0 0;\n padding-left: 20px;\n}\n\n#ttyd-toolbar-onboarding li {\n margin: 4px 0;\n}\n\n#ttyd-toolbar-onboarding code {\n background: #444;\n padding: 2px 6px;\n border-radius: 4px;\n font-family: monospace;\n}\n\n/* Mobile optimizations */\n@media (max-width: 768px) {\n #ttyd-toolbar {\n padding: 6px;\n }\n\n #ttyd-toolbar-buttons {\n gap: 4px;\n margin-bottom: 6px;\n }\n\n #ttyd-toolbar-buttons button {\n font-size: 12px;\n padding: 6px 10px;\n min-height: 36px;\n min-width: 40px;\n }\n\n #ttyd-toolbar-input {\n font-size: 16px;\n padding: 10px;\n }\n\n #ttyd-toolbar-toggle {\n width: 64px;\n height: 64px;\n font-size: 24px;\n }\n\n body:has(#ttyd-toolbar:not(.hidden)) .xterm {\n height: calc(100vh - 130px) !important;\n }\n\n body:has(#ttyd-toolbar.minimized:not(.hidden)) .xterm {\n height: calc(100vh - 60px) !important;\n }\n\n #ttyd-toolbar-onboarding {\n left: 16px;\n right: 16px;\n max-width: none;\n }\n}\n";
|
|
5
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa,2pKAiRzB,CAAC"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Toolbar CSS Styles
|
|
3
|
+
*/
|
|
4
|
+
export const toolbarStyles = `
|
|
5
|
+
#ttyd-toolbar {
|
|
6
|
+
position: fixed;
|
|
7
|
+
bottom: 0;
|
|
8
|
+
left: 0;
|
|
9
|
+
right: 0;
|
|
10
|
+
background: #1e1e1e;
|
|
11
|
+
border-top: 2px solid #007acc;
|
|
12
|
+
padding: 8px;
|
|
13
|
+
z-index: 10000;
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
15
|
+
box-shadow: 0 -2px 10px rgba(0,0,0,0.3);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#ttyd-toolbar.hidden {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#ttyd-toolbar-buttons {
|
|
23
|
+
display: flex;
|
|
24
|
+
gap: 6px;
|
|
25
|
+
margin-bottom: 8px;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#ttyd-toolbar-buttons button {
|
|
30
|
+
background: #3a3a3a;
|
|
31
|
+
border: 1px solid #555;
|
|
32
|
+
border-radius: 6px;
|
|
33
|
+
color: #fff;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
font-size: 13px;
|
|
36
|
+
padding: 8px 12px;
|
|
37
|
+
min-height: 40px;
|
|
38
|
+
min-width: 44px;
|
|
39
|
+
touch-action: manipulation;
|
|
40
|
+
flex-shrink: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#ttyd-toolbar-buttons button:hover, #ttyd-toolbar-buttons button:active {
|
|
44
|
+
background: #4a4a4a;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#ttyd-toolbar-buttons button.active {
|
|
48
|
+
background: #007acc;
|
|
49
|
+
border-color: #005a9e;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#ttyd-toolbar-buttons button.modifier {
|
|
53
|
+
background: #2d2d2d;
|
|
54
|
+
font-weight: bold;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#ttyd-toolbar-buttons button.modifier.active {
|
|
58
|
+
background: #d9534f;
|
|
59
|
+
border-color: #c9302c;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#ttyd-toolbar-send {
|
|
63
|
+
background: #007acc !important;
|
|
64
|
+
border-color: #005a9e !important;
|
|
65
|
+
font-weight: bold;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#ttyd-toolbar-send:hover, #ttyd-toolbar-send:active {
|
|
69
|
+
background: #005a9e !important;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#ttyd-toolbar-run {
|
|
73
|
+
background: #28a745 !important;
|
|
74
|
+
border-color: #1e7e34 !important;
|
|
75
|
+
font-weight: bold;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#ttyd-toolbar-run:hover, #ttyd-toolbar-run:active {
|
|
79
|
+
background: #1e7e34 !important;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#ttyd-toolbar-auto.active {
|
|
83
|
+
background: #f0ad4e !important;
|
|
84
|
+
border-color: #eea236 !important;
|
|
85
|
+
color: #000;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#ttyd-toolbar-scroll.active {
|
|
89
|
+
background: #17a2b8 !important;
|
|
90
|
+
border-color: #138496 !important;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#ttyd-toolbar-input-row {
|
|
94
|
+
display: flex;
|
|
95
|
+
gap: 8px;
|
|
96
|
+
align-items: flex-end;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#ttyd-toolbar-input {
|
|
100
|
+
flex: 1;
|
|
101
|
+
background: #2d2d2d;
|
|
102
|
+
border: 1px solid #555;
|
|
103
|
+
border-radius: 8px;
|
|
104
|
+
color: #fff;
|
|
105
|
+
font-family: monospace;
|
|
106
|
+
font-size: 16px;
|
|
107
|
+
padding: 12px;
|
|
108
|
+
outline: none;
|
|
109
|
+
resize: none;
|
|
110
|
+
min-height: 44px;
|
|
111
|
+
max-height: 120px;
|
|
112
|
+
line-height: 1.4;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#ttyd-toolbar-input:focus {
|
|
116
|
+
border-color: #007acc;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#ttyd-toolbar-input::placeholder {
|
|
120
|
+
color: #888;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#ttyd-toolbar-toggle {
|
|
124
|
+
position: fixed;
|
|
125
|
+
bottom: 16px;
|
|
126
|
+
right: 16px;
|
|
127
|
+
background: #007acc;
|
|
128
|
+
border: 2px solid #005a9e;
|
|
129
|
+
border-radius: 50%;
|
|
130
|
+
color: #fff;
|
|
131
|
+
cursor: pointer;
|
|
132
|
+
font-size: 20px;
|
|
133
|
+
width: 56px;
|
|
134
|
+
height: 56px;
|
|
135
|
+
z-index: 10001;
|
|
136
|
+
touch-action: manipulation;
|
|
137
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#ttyd-toolbar-toggle:hover, #ttyd-toolbar-toggle:active {
|
|
144
|
+
background: #005a9e;
|
|
145
|
+
transform: scale(1.05);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#ttyd-toolbar.hidden ~ #ttyd-toolbar-toggle {
|
|
149
|
+
bottom: 16px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Adjust terminal height when toolbar is visible */
|
|
153
|
+
body:has(#ttyd-toolbar:not(.hidden)) .xterm {
|
|
154
|
+
height: calc(100vh - 140px) !important;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Minimized mode - compact toolbar with input only */
|
|
158
|
+
#ttyd-toolbar.minimized #ttyd-toolbar-buttons {
|
|
159
|
+
display: none;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#ttyd-toolbar.minimized {
|
|
163
|
+
padding: 4px 8px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#ttyd-toolbar-minimize {
|
|
167
|
+
background: #555 !important;
|
|
168
|
+
border-color: #666 !important;
|
|
169
|
+
font-size: 10px;
|
|
170
|
+
padding: 4px 8px;
|
|
171
|
+
min-width: 32px;
|
|
172
|
+
min-height: 32px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Onboarding tooltip */
|
|
176
|
+
#ttyd-toolbar-onboarding {
|
|
177
|
+
position: fixed;
|
|
178
|
+
bottom: 90px;
|
|
179
|
+
right: 16px;
|
|
180
|
+
background: #333;
|
|
181
|
+
border: 1px solid #007acc;
|
|
182
|
+
border-radius: 8px;
|
|
183
|
+
padding: 12px 16px;
|
|
184
|
+
color: #fff;
|
|
185
|
+
font-size: 13px;
|
|
186
|
+
max-width: 280px;
|
|
187
|
+
z-index: 10002;
|
|
188
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.4);
|
|
189
|
+
line-height: 1.5;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
#ttyd-toolbar-onboarding::after {
|
|
193
|
+
content: '';
|
|
194
|
+
position: absolute;
|
|
195
|
+
bottom: -8px;
|
|
196
|
+
right: 24px;
|
|
197
|
+
border-left: 8px solid transparent;
|
|
198
|
+
border-right: 8px solid transparent;
|
|
199
|
+
border-top: 8px solid #333;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#ttyd-toolbar-onboarding-close {
|
|
203
|
+
position: absolute;
|
|
204
|
+
top: 4px;
|
|
205
|
+
right: 8px;
|
|
206
|
+
background: none;
|
|
207
|
+
border: none;
|
|
208
|
+
color: #888;
|
|
209
|
+
font-size: 16px;
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
padding: 4px;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
#ttyd-toolbar-onboarding-close:hover {
|
|
215
|
+
color: #fff;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
#ttyd-toolbar-onboarding ul {
|
|
219
|
+
margin: 8px 0 0 0;
|
|
220
|
+
padding-left: 20px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
#ttyd-toolbar-onboarding li {
|
|
224
|
+
margin: 4px 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#ttyd-toolbar-onboarding code {
|
|
228
|
+
background: #444;
|
|
229
|
+
padding: 2px 6px;
|
|
230
|
+
border-radius: 4px;
|
|
231
|
+
font-family: monospace;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Mobile optimizations */
|
|
235
|
+
@media (max-width: 768px) {
|
|
236
|
+
#ttyd-toolbar {
|
|
237
|
+
padding: 6px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
#ttyd-toolbar-buttons {
|
|
241
|
+
gap: 4px;
|
|
242
|
+
margin-bottom: 6px;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#ttyd-toolbar-buttons button {
|
|
246
|
+
font-size: 12px;
|
|
247
|
+
padding: 6px 10px;
|
|
248
|
+
min-height: 36px;
|
|
249
|
+
min-width: 40px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#ttyd-toolbar-input {
|
|
253
|
+
font-size: 16px;
|
|
254
|
+
padding: 10px;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
#ttyd-toolbar-toggle {
|
|
258
|
+
width: 64px;
|
|
259
|
+
height: 64px;
|
|
260
|
+
font-size: 24px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
body:has(#ttyd-toolbar:not(.hidden)) .xterm {
|
|
264
|
+
height: calc(100vh - 130px) !important;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
body:has(#ttyd-toolbar.minimized:not(.hidden)) .xterm {
|
|
268
|
+
height: calc(100vh - 60px) !important;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
#ttyd-toolbar-onboarding {
|
|
272
|
+
left: 16px;
|
|
273
|
+
right: 16px;
|
|
274
|
+
max-width: none;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
`;
|
|
278
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiR5B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Toolbar HTML Template
|
|
3
|
+
*/
|
|
4
|
+
export declare const toolbarHtml = "\n<div id=\"ttyd-toolbar\" class=\"hidden\">\n <div id=\"ttyd-toolbar-buttons\">\n <button id=\"ttyd-toolbar-ctrl\" class=\"modifier\">Ctrl</button>\n <button id=\"ttyd-toolbar-alt\" class=\"modifier\">Alt</button>\n <button id=\"ttyd-toolbar-shift\" class=\"modifier\">Shift</button>\n <button id=\"ttyd-toolbar-scroll\" class=\"modifier\">Scroll</button>\n <button id=\"ttyd-toolbar-esc\">Esc</button>\n <button id=\"ttyd-toolbar-tab\">Tab</button>\n <button id=\"ttyd-toolbar-up\">\u2191</button>\n <button id=\"ttyd-toolbar-down\">\u2193</button>\n <button id=\"ttyd-toolbar-pageup\">PgUp</button>\n <button id=\"ttyd-toolbar-pagedown\">PgDn</button>\n <button id=\"ttyd-toolbar-enter\">Enter</button>\n <button id=\"ttyd-toolbar-zoomout\">A-</button>\n <button id=\"ttyd-toolbar-zoomin\">A+</button>\n <button id=\"ttyd-toolbar-copy\">Copy</button>\n <button id=\"ttyd-toolbar-copyall\">All</button>\n <button id=\"ttyd-toolbar-send\">Send</button>\n <button id=\"ttyd-toolbar-run\">Run</button>\n <button id=\"ttyd-toolbar-auto\" class=\"modifier\">Auto</button>\n <button id=\"ttyd-toolbar-minimize\">\u25BC</button>\n </div>\n <div id=\"ttyd-toolbar-input-row\">\n <textarea id=\"ttyd-toolbar-input\" rows=\"1\" placeholder=\"\u65E5\u672C\u8A9E\u5165\u529B (Enter: \u9001\u4FE1)\"></textarea>\n </div>\n</div>\n<button id=\"ttyd-toolbar-toggle\">\u2328</button>\n";
|
|
5
|
+
export declare const onboardingHtml = "\n<div id=\"ttyd-toolbar-onboarding\">\n <button id=\"ttyd-toolbar-onboarding-close\">\u00D7</button>\n <strong>Toolbar Tips</strong>\n <ul>\n <li><code>Ctrl+J</code> \u3067\u30C4\u30FC\u30EB\u30D0\u30FC\u8868\u793A/\u975E\u8868\u793A</li>\n <li>\u30D4\u30F3\u30C1\u64CD\u4F5C\u3067\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA\u5909\u66F4</li>\n <li>\u30C0\u30D6\u30EB\u30BF\u30C3\u30D7\u3067 Enter \u9001\u4FE1</li>\n <li><code>\u25BC</code> \u3067\u30B3\u30F3\u30D1\u30AF\u30C8\u8868\u793A</li>\n </ul>\n</div>\n";
|
|
6
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,g6CA4BvB,CAAC;AAEF,eAAO,MAAM,cAAc,qhBAW1B,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Toolbar HTML Template
|
|
3
|
+
*/
|
|
4
|
+
export const toolbarHtml = `
|
|
5
|
+
<div id="ttyd-toolbar" class="hidden">
|
|
6
|
+
<div id="ttyd-toolbar-buttons">
|
|
7
|
+
<button id="ttyd-toolbar-ctrl" class="modifier">Ctrl</button>
|
|
8
|
+
<button id="ttyd-toolbar-alt" class="modifier">Alt</button>
|
|
9
|
+
<button id="ttyd-toolbar-shift" class="modifier">Shift</button>
|
|
10
|
+
<button id="ttyd-toolbar-scroll" class="modifier">Scroll</button>
|
|
11
|
+
<button id="ttyd-toolbar-esc">Esc</button>
|
|
12
|
+
<button id="ttyd-toolbar-tab">Tab</button>
|
|
13
|
+
<button id="ttyd-toolbar-up">↑</button>
|
|
14
|
+
<button id="ttyd-toolbar-down">↓</button>
|
|
15
|
+
<button id="ttyd-toolbar-pageup">PgUp</button>
|
|
16
|
+
<button id="ttyd-toolbar-pagedown">PgDn</button>
|
|
17
|
+
<button id="ttyd-toolbar-enter">Enter</button>
|
|
18
|
+
<button id="ttyd-toolbar-zoomout">A-</button>
|
|
19
|
+
<button id="ttyd-toolbar-zoomin">A+</button>
|
|
20
|
+
<button id="ttyd-toolbar-copy">Copy</button>
|
|
21
|
+
<button id="ttyd-toolbar-copyall">All</button>
|
|
22
|
+
<button id="ttyd-toolbar-send">Send</button>
|
|
23
|
+
<button id="ttyd-toolbar-run">Run</button>
|
|
24
|
+
<button id="ttyd-toolbar-auto" class="modifier">Auto</button>
|
|
25
|
+
<button id="ttyd-toolbar-minimize">▼</button>
|
|
26
|
+
</div>
|
|
27
|
+
<div id="ttyd-toolbar-input-row">
|
|
28
|
+
<textarea id="ttyd-toolbar-input" rows="1" placeholder="日本語入力 (Enter: 送信)"></textarea>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<button id="ttyd-toolbar-toggle">⌨</button>
|
|
32
|
+
`;
|
|
33
|
+
export const onboardingHtml = `
|
|
34
|
+
<div id="ttyd-toolbar-onboarding">
|
|
35
|
+
<button id="ttyd-toolbar-onboarding-close">×</button>
|
|
36
|
+
<strong>Toolbar Tips</strong>
|
|
37
|
+
<ul>
|
|
38
|
+
<li><code>Ctrl+J</code> でツールバー表示/非表示</li>
|
|
39
|
+
<li>ピンチ操作でフォントサイズ変更</li>
|
|
40
|
+
<li>ダブルタップで Enter 送信</li>
|
|
41
|
+
<li><code>▼</code> でコンパクト表示</li>
|
|
42
|
+
</ul>
|
|
43
|
+
</div>
|
|
44
|
+
`;
|
|
45
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4B1B,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;CAW7B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { Socket } from 'node:net';
|
|
3
|
+
import type { Config } from '../config/types.js';
|
|
4
|
+
import WebSocket from 'ws';
|
|
5
|
+
/**
|
|
6
|
+
* Gracefully close a WebSocket connection
|
|
7
|
+
*/
|
|
8
|
+
export declare function closeWebSocket(ws: WebSocket, code: number, reason: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Setup bidirectional WebSocket forwarding
|
|
11
|
+
*/
|
|
12
|
+
export declare function setupWebSocketForwarding(clientWs: WebSocket, backendWs: WebSocket): void;
|
|
13
|
+
/**
|
|
14
|
+
* Handle WebSocket upgrade request
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleUpgrade(config: Config, req: IncomingMessage, socket: Socket, head: Buffer): void;
|
|
17
|
+
//# sourceMappingURL=ws-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-proxy.d.ts","sourceRoot":"","sources":["../../src/daemon/ws-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,mBAAmB,CAAC;AAE9D,OAAO,SAA8B,MAAM,IAAI,CAAC;AAQhD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMhF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CA4CxF;AAoCD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,IAAI,CAaN"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createLogger } from '../utils/logger.js';
|
|
2
|
+
import WebSocket, { WebSocketServer } from 'ws';
|
|
3
|
+
import { findSessionForPath } from './router.js';
|
|
4
|
+
const log = createLogger('websocket');
|
|
5
|
+
// Create WebSocket server (noServer mode for manual upgrade handling)
|
|
6
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
7
|
+
/**
|
|
8
|
+
* Gracefully close a WebSocket connection
|
|
9
|
+
*/
|
|
10
|
+
export function closeWebSocket(ws, code, reason) {
|
|
11
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
12
|
+
ws.close(code, reason);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
ws.terminate();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Setup bidirectional WebSocket forwarding
|
|
20
|
+
*/
|
|
21
|
+
export function setupWebSocketForwarding(clientWs, backendWs) {
|
|
22
|
+
let closed = false;
|
|
23
|
+
const cleanup = (initiator, code, reason) => {
|
|
24
|
+
if (closed) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
closed = true;
|
|
28
|
+
log.debug(`WebSocket cleanup initiated by ${initiator}, code=${code}`);
|
|
29
|
+
const closeCode = code ?? 1000;
|
|
30
|
+
const closeReason = reason?.toString() ?? '';
|
|
31
|
+
const wsToClose = initiator === 'client' ? backendWs : clientWs;
|
|
32
|
+
closeWebSocket(wsToClose, closeCode, closeReason);
|
|
33
|
+
};
|
|
34
|
+
// Forward messages bidirectionally
|
|
35
|
+
clientWs.on('message', (data, isBinary) => {
|
|
36
|
+
if (backendWs.readyState === WebSocket.OPEN) {
|
|
37
|
+
backendWs.send(data, { binary: isBinary });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
backendWs.on('message', (data, isBinary) => {
|
|
41
|
+
if (clientWs.readyState === WebSocket.OPEN) {
|
|
42
|
+
clientWs.send(data, { binary: isBinary });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Handle close events
|
|
46
|
+
clientWs.on('close', (code, reason) => cleanup('client', code, reason));
|
|
47
|
+
backendWs.on('close', (code, reason) => cleanup('backend', code, reason));
|
|
48
|
+
// Handle errors - terminate to ensure cleanup
|
|
49
|
+
clientWs.on('error', (err) => {
|
|
50
|
+
log.error(`Client WebSocket error: ${err.message}`);
|
|
51
|
+
clientWs.terminate();
|
|
52
|
+
cleanup('client', 1006);
|
|
53
|
+
});
|
|
54
|
+
backendWs.on('error', (err) => {
|
|
55
|
+
log.error(`Backend WebSocket error: ${err.message}`);
|
|
56
|
+
backendWs.terminate();
|
|
57
|
+
cleanup('backend', 1006);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Connect to backend WebSocket and setup forwarding
|
|
62
|
+
*/
|
|
63
|
+
function connectToBackend(session, url, protocol, req, socket, head) {
|
|
64
|
+
const backendUrl = `ws://127.0.0.1:${session.port}${url}`;
|
|
65
|
+
log.debug(`Connecting to backend WebSocket: ${backendUrl}`);
|
|
66
|
+
const backendWs = new WebSocket(backendUrl, protocol ? protocol.split(',').map((p) => p.trim()) : []);
|
|
67
|
+
backendWs.on('open', () => {
|
|
68
|
+
log.debug(`Backend WebSocket connected: ${backendUrl}`);
|
|
69
|
+
// Upgrade client connection once backend is ready
|
|
70
|
+
wss.handleUpgrade(req, socket, head, (clientWs) => {
|
|
71
|
+
setupWebSocketForwarding(clientWs, backendWs);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
backendWs.on('error', (err) => {
|
|
75
|
+
log.error(`Backend WebSocket connection failed: ${backendUrl} - ${err.message}`);
|
|
76
|
+
backendWs.terminate();
|
|
77
|
+
socket.destroy();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Handle WebSocket upgrade request
|
|
82
|
+
*/
|
|
83
|
+
export function handleUpgrade(config, req, socket, head) {
|
|
84
|
+
const url = req.url ?? '/';
|
|
85
|
+
log.debug(`WebSocket upgrade request: ${url}`);
|
|
86
|
+
const session = findSessionForPath(config, url);
|
|
87
|
+
if (!session) {
|
|
88
|
+
log.warn(`WebSocket upgrade rejected - no session for: ${url}`);
|
|
89
|
+
socket.destroy();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const protocol = req.headers['sec-websocket-protocol'];
|
|
93
|
+
connectToBackend(session, url, protocol, req, socket, head);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=ws-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-proxy.js","sourceRoot":"","sources":["../../src/daemon/ws-proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config, SessionState } from '../config/types.js';
|
|
2
|
+
export interface CaddyfileOptions {
|
|
3
|
+
hostname: string;
|
|
4
|
+
portalDir: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateCaddyfileSnippet(config: Config, sessions: SessionState[], options: CaddyfileOptions): string;
|
|
7
|
+
export declare function generateCaddyJson(config: Config, sessions: SessionState[], options: CaddyfileOptions): object;
|
|
8
|
+
//# sourceMappingURL=caddyfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caddyfile.d.ts","sourceRoot":"","sources":["../../src/deploy/caddyfile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAoCR;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,gBAAgB,GACxB,MAAM,CA8BR"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getFullPath } from '../config/config.js';
|
|
2
|
+
export function generateCaddyfileSnippet(config, sessions, options) {
|
|
3
|
+
const { hostname, portalDir } = options;
|
|
4
|
+
const basePath = config.base_path;
|
|
5
|
+
const lines = [
|
|
6
|
+
`# ttyd-mux static mode configuration for ${hostname}`,
|
|
7
|
+
`# Generated at ${new Date().toISOString()}`,
|
|
8
|
+
'# Add this inside your site block in Caddyfile',
|
|
9
|
+
'',
|
|
10
|
+
'# Portal page (static HTML)',
|
|
11
|
+
`handle ${basePath} {`,
|
|
12
|
+
' rewrite * /index.html',
|
|
13
|
+
` root * ${portalDir}`,
|
|
14
|
+
' file_server',
|
|
15
|
+
'}',
|
|
16
|
+
'',
|
|
17
|
+
`handle ${basePath}/ {`,
|
|
18
|
+
' rewrite * /index.html',
|
|
19
|
+
` root * ${portalDir}`,
|
|
20
|
+
' file_server',
|
|
21
|
+
'}'
|
|
22
|
+
];
|
|
23
|
+
if (sessions.length > 0) {
|
|
24
|
+
lines.push('', '# Session routes (direct to ttyd)');
|
|
25
|
+
for (const session of sessions) {
|
|
26
|
+
const fullPath = getFullPath(config, session.path);
|
|
27
|
+
lines.push('', `# Session: ${session.name}`);
|
|
28
|
+
lines.push(`handle ${fullPath}/* {`);
|
|
29
|
+
lines.push(` reverse_proxy localhost:${session.port}`);
|
|
30
|
+
lines.push('}');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return lines.join('\n');
|
|
34
|
+
}
|
|
35
|
+
export function generateCaddyJson(config, sessions, options) {
|
|
36
|
+
const { hostname, portalDir } = options;
|
|
37
|
+
const basePath = config.base_path;
|
|
38
|
+
const routes = [];
|
|
39
|
+
// Portal routes
|
|
40
|
+
routes.push({
|
|
41
|
+
match: [{ host: [hostname], path: [basePath, `${basePath}/`] }],
|
|
42
|
+
handle: [
|
|
43
|
+
{ handler: 'rewrite', uri: '/index.html' },
|
|
44
|
+
{ handler: 'file_server', root: portalDir }
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
// Session routes
|
|
48
|
+
for (const session of sessions) {
|
|
49
|
+
const fullPath = getFullPath(config, session.path);
|
|
50
|
+
routes.push({
|
|
51
|
+
match: [{ host: [hostname], path: [`${fullPath}/*`] }],
|
|
52
|
+
handle: [
|
|
53
|
+
{
|
|
54
|
+
handler: 'reverse_proxy',
|
|
55
|
+
upstreams: [{ dial: `localhost:${session.port}` }]
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return { routes };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=caddyfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caddyfile.js","sourceRoot":"","sources":["../../src/deploy/caddyfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQjD,MAAM,UAAU,wBAAwB,CACtC,MAAc,EACd,QAAwB,EACxB,OAAyB;IAEzB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;IAElC,MAAM,KAAK,GAAa;QACtB,4CAA4C,QAAQ,EAAE;QACtD,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;QAC5C,gDAAgD;QAChD,EAAE;QACF,6BAA6B;QAC7B,UAAU,QAAQ,IAAI;QACtB,2BAA2B;QAC3B,cAAc,SAAS,EAAE;QACzB,iBAAiB;QACjB,GAAG;QACH,EAAE;QACF,UAAU,QAAQ,KAAK;QACvB,2BAA2B;QAC3B,cAAc,SAAS,EAAE;QACzB,iBAAiB;QACjB,GAAG;KACJ,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,CAAC,CAAC;QAEpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,MAAM,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,+BAA+B,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,QAAwB,EACxB,OAAyB;IAEzB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;IAElC,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,gBAAgB;IAChB,MAAM,CAAC,IAAI,CAAC;QACV,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC/D,MAAM,EAAE;YACN,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE;YAC1C,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5C;KACF,CAAC,CAAC;IAEH,iBAAiB;IACjB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,EAAE;gBACN;oBACE,OAAO,EAAE,eAAe;oBACxB,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;iBACnD;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from '../config/types.js';
|
|
2
|
+
export interface DeployScriptOptions {
|
|
3
|
+
hostname: string;
|
|
4
|
+
deployDir: string;
|
|
5
|
+
caddyAdminApi: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function generateDeployScript(config: Config, options: DeployScriptOptions): string;
|
|
8
|
+
//# sourceMappingURL=deploy-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-script.d.ts","sourceRoot":"","sources":["../../src/deploy/deploy-script.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAuEzF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function generateDeployScript(config, options) {
|
|
2
|
+
const { hostname, deployDir, caddyAdminApi } = options;
|
|
3
|
+
const basePath = config.base_path;
|
|
4
|
+
return `#!/bin/bash
|
|
5
|
+
# ttyd-mux deploy script for static mode
|
|
6
|
+
# Generated at ${new Date().toISOString()}
|
|
7
|
+
#
|
|
8
|
+
# This script sets up Caddy routes for ttyd-mux static mode.
|
|
9
|
+
# Run this after starting sessions with 'ttyd-mux up'.
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
DEPLOY_DIR="${deployDir}"
|
|
14
|
+
HOSTNAME="${hostname}"
|
|
15
|
+
BASE_PATH="${basePath}"
|
|
16
|
+
CADDY_ADMIN_API="${caddyAdminApi}"
|
|
17
|
+
|
|
18
|
+
echo "ttyd-mux deploy script"
|
|
19
|
+
echo "======================"
|
|
20
|
+
echo ""
|
|
21
|
+
|
|
22
|
+
# Check if portal directory exists
|
|
23
|
+
if [ ! -d "\$DEPLOY_DIR/portal" ]; then
|
|
24
|
+
echo "Error: Portal directory not found at \$DEPLOY_DIR/portal"
|
|
25
|
+
echo "Run 'ttyd-mux deploy' first to generate deployment files."
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Check if Caddy Admin API is available
|
|
30
|
+
if ! curl -s "\$CADDY_ADMIN_API/config/" > /dev/null 2>&1; then
|
|
31
|
+
echo "Error: Cannot connect to Caddy Admin API at \$CADDY_ADMIN_API"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Option 1: Make sure Caddy is running with admin API enabled"
|
|
34
|
+
echo "Option 2: Manually add the Caddyfile snippet from:"
|
|
35
|
+
echo " \$DEPLOY_DIR/Caddyfile.snippet"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
echo "Setting up Caddy routes..."
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
# Read and apply routes from caddy-routes.json
|
|
43
|
+
if [ -f "\$DEPLOY_DIR/caddy-routes.json" ]; then
|
|
44
|
+
ROUTES=\$(cat "\$DEPLOY_DIR/caddy-routes.json")
|
|
45
|
+
|
|
46
|
+
# Get current config to find the server
|
|
47
|
+
CONFIG=\$(curl -s "\$CADDY_ADMIN_API/config/")
|
|
48
|
+
|
|
49
|
+
# Try to find existing server for the hostname
|
|
50
|
+
# This is a simplified approach - you may need to adjust for your setup
|
|
51
|
+
echo "Applying routes for \$HOSTNAME..."
|
|
52
|
+
|
|
53
|
+
# Note: This is a basic implementation. For production use,
|
|
54
|
+
# you may want to use 'ttyd-mux caddy setup' or manually configure.
|
|
55
|
+
echo ""
|
|
56
|
+
echo "Routes configuration saved to: \$DEPLOY_DIR/caddy-routes.json"
|
|
57
|
+
echo ""
|
|
58
|
+
echo "To apply manually, either:"
|
|
59
|
+
echo "1. Run: ttyd-mux caddy setup --hostname \$HOSTNAME"
|
|
60
|
+
echo "2. Add the snippet from \$DEPLOY_DIR/Caddyfile.snippet to your Caddyfile"
|
|
61
|
+
else
|
|
62
|
+
echo "Warning: caddy-routes.json not found"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Portal files are in: \$DEPLOY_DIR/portal/"
|
|
67
|
+
echo "Caddyfile snippet: \$DEPLOY_DIR/Caddyfile.snippet"
|
|
68
|
+
echo ""
|
|
69
|
+
echo "Done!"
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=deploy-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-script.js","sourceRoot":"","sources":["../../src/deploy/deploy-script.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,OAA4B;IAC/E,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;IAElC,OAAO;;iBAEQ,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;;;;;;;cAO3B,SAAS;YACX,QAAQ;aACP,QAAQ;mBACF,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsD/B,CAAC;AACF,CAAC"}
|