ttyd-mux 0.4.2 → 0.4.3

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 (84) hide show
  1. package/dist/commands/share.d.ts +25 -0
  2. package/dist/commands/share.d.ts.map +1 -0
  3. package/dist/commands/share.js +108 -0
  4. package/dist/commands/share.js.map +1 -0
  5. package/dist/config/state-store.d.ts +9 -1
  6. package/dist/config/state-store.d.ts.map +1 -1
  7. package/dist/config/state-store.js +30 -2
  8. package/dist/config/state-store.js.map +1 -1
  9. package/dist/config/state.d.ts +9 -1
  10. package/dist/config/state.d.ts.map +1 -1
  11. package/dist/config/state.js +67 -1
  12. package/dist/config/state.js.map +1 -1
  13. package/dist/config/types.d.ts +52 -0
  14. package/dist/config/types.d.ts.map +1 -1
  15. package/dist/config/types.js +23 -1
  16. package/dist/config/types.js.map +1 -1
  17. package/dist/daemon/api-handler.d.ts.map +1 -1
  18. package/dist/daemon/api-handler.js +180 -2
  19. package/dist/daemon/api-handler.js.map +1 -1
  20. package/dist/daemon/http-proxy.d.ts +3 -2
  21. package/dist/daemon/http-proxy.d.ts.map +1 -1
  22. package/dist/daemon/http-proxy.js +7 -4
  23. package/dist/daemon/http-proxy.js.map +1 -1
  24. package/dist/daemon/index.d.ts.map +1 -1
  25. package/dist/daemon/index.js +22 -2
  26. package/dist/daemon/index.js.map +1 -1
  27. package/dist/daemon/notification/index.d.ts +42 -0
  28. package/dist/daemon/notification/index.d.ts.map +1 -0
  29. package/dist/daemon/notification/index.js +83 -0
  30. package/dist/daemon/notification/index.js.map +1 -0
  31. package/dist/daemon/notification/matcher.d.ts +30 -0
  32. package/dist/daemon/notification/matcher.d.ts.map +1 -0
  33. package/dist/daemon/notification/matcher.js +72 -0
  34. package/dist/daemon/notification/matcher.js.map +1 -0
  35. package/dist/daemon/notification/sender.d.ts +38 -0
  36. package/dist/daemon/notification/sender.d.ts.map +1 -0
  37. package/dist/daemon/notification/sender.js +74 -0
  38. package/dist/daemon/notification/sender.js.map +1 -0
  39. package/dist/daemon/notification/subscription.d.ts +35 -0
  40. package/dist/daemon/notification/subscription.d.ts.map +1 -0
  41. package/dist/daemon/notification/subscription.js +52 -0
  42. package/dist/daemon/notification/subscription.js.map +1 -0
  43. package/dist/daemon/notification/types.d.ts +70 -0
  44. package/dist/daemon/notification/types.d.ts.map +1 -0
  45. package/dist/daemon/notification/types.js +5 -0
  46. package/dist/daemon/notification/types.js.map +1 -0
  47. package/dist/daemon/notification/vapid.d.ts +25 -0
  48. package/dist/daemon/notification/vapid.d.ts.map +1 -0
  49. package/dist/daemon/notification/vapid.js +56 -0
  50. package/dist/daemon/notification/vapid.js.map +1 -0
  51. package/dist/daemon/pwa.d.ts +2 -1
  52. package/dist/daemon/pwa.d.ts.map +1 -1
  53. package/dist/daemon/pwa.js +51 -0
  54. package/dist/daemon/pwa.js.map +1 -1
  55. package/dist/daemon/router.d.ts +10 -0
  56. package/dist/daemon/router.d.ts.map +1 -1
  57. package/dist/daemon/router.js +122 -10
  58. package/dist/daemon/router.js.map +1 -1
  59. package/dist/daemon/share-manager.d.ts +55 -0
  60. package/dist/daemon/share-manager.d.ts.map +1 -0
  61. package/dist/daemon/share-manager.js +115 -0
  62. package/dist/daemon/share-manager.js.map +1 -0
  63. package/dist/daemon/toolbar/index.d.ts +4 -12
  64. package/dist/daemon/toolbar/index.d.ts.map +1 -1
  65. package/dist/daemon/toolbar/index.js +6 -794
  66. package/dist/daemon/toolbar/index.js.map +1 -1
  67. package/dist/daemon/toolbar/styles.d.ts +1 -1
  68. package/dist/daemon/toolbar/styles.d.ts.map +1 -1
  69. package/dist/daemon/toolbar/styles.js +106 -0
  70. package/dist/daemon/toolbar/styles.js.map +1 -1
  71. package/dist/daemon/toolbar/template.d.ts +1 -1
  72. package/dist/daemon/toolbar/template.d.ts.map +1 -1
  73. package/dist/daemon/toolbar/template.js +11 -0
  74. package/dist/daemon/toolbar/template.js.map +1 -1
  75. package/dist/daemon/ws-proxy.d.ts +21 -1
  76. package/dist/daemon/ws-proxy.d.ts.map +1 -1
  77. package/dist/daemon/ws-proxy.js +107 -5
  78. package/dist/daemon/ws-proxy.js.map +1 -1
  79. package/dist/index.js +18 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/toolbar.js +2 -0
  82. package/dist/version.d.ts +1 -1
  83. package/dist/version.js +1 -1
  84. package/package.json +6 -2
@@ -1 +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"}
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;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,QAAgB,EAChB,SAAwB,sBAAsB;IAE9C,MAAM,YAAY,GAAG,uCAAuC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;IAC/F,MAAM,SAAS,GAAG;SACX,aAAa;EACpB,WAAW;EACX,cAAc,CAAC,OAAO,CAAC,8BAA8B,EAAE,mDAAmD,CAAC;EAC3G,YAAY;eACC,QAAQ;CACtB,CAAC;IACA,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,SAAS,CAAC,CAAC;AACxD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Terminal Toolbar CSS Styles
3
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";
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 #ttyd-search-bar {\n padding: 6px;\n }\n\n #ttyd-search-input {\n font-size: 14px;\n padding: 8px 10px;\n }\n}\n\n/* Search bar styles */\n#ttyd-search-bar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n background: #1e1e1e;\n border-bottom: 2px solid #007acc;\n padding: 8px 12px;\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 display: flex;\n gap: 8px;\n align-items: center;\n}\n\n#ttyd-search-bar.hidden {\n display: none;\n}\n\n#ttyd-search-input {\n flex: 1;\n background: #2d2d2d;\n border: 1px solid #555;\n border-radius: 6px;\n color: #fff;\n font-family: monospace;\n font-size: 14px;\n padding: 8px 12px;\n outline: none;\n min-width: 100px;\n}\n\n#ttyd-search-input:focus {\n border-color: #007acc;\n}\n\n#ttyd-search-input::placeholder {\n color: #888;\n}\n\n#ttyd-search-count {\n color: #888;\n font-size: 12px;\n white-space: nowrap;\n min-width: 50px;\n text-align: center;\n}\n\n#ttyd-search-bar 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: 6px 10px;\n min-height: 32px;\n min-width: 32px;\n touch-action: manipulation;\n}\n\n#ttyd-search-bar button:hover,\n#ttyd-search-bar button:active {\n background: #4a4a4a;\n}\n\n#ttyd-search-bar button.modifier {\n background: #2d2d2d;\n font-weight: bold;\n}\n\n#ttyd-search-bar button.modifier.active {\n background: #007acc;\n border-color: #005a9e;\n}\n\n#ttyd-search-close {\n color: #888;\n}\n\n#ttyd-search-close:hover {\n color: #fff;\n}\n\n/* Visual bell effect */\n.xterm.bell-flash {\n animation: bell-flash 100ms ease-out;\n}\n\n@keyframes bell-flash {\n 0% { filter: brightness(1); }\n 50% { filter: brightness(1.5); }\n 100% { filter: brightness(1); }\n}\n";
5
5
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa,0gOA2XzB,CAAC"}
@@ -273,6 +273,112 @@ body:has(#ttyd-toolbar:not(.hidden)) .xterm {
273
273
  right: 16px;
274
274
  max-width: none;
275
275
  }
276
+
277
+ #ttyd-search-bar {
278
+ padding: 6px;
279
+ }
280
+
281
+ #ttyd-search-input {
282
+ font-size: 14px;
283
+ padding: 8px 10px;
284
+ }
285
+ }
286
+
287
+ /* Search bar styles */
288
+ #ttyd-search-bar {
289
+ position: fixed;
290
+ top: 0;
291
+ left: 0;
292
+ right: 0;
293
+ background: #1e1e1e;
294
+ border-bottom: 2px solid #007acc;
295
+ padding: 8px 12px;
296
+ z-index: 10000;
297
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
298
+ box-shadow: 0 2px 10px rgba(0,0,0,0.3);
299
+ display: flex;
300
+ gap: 8px;
301
+ align-items: center;
302
+ }
303
+
304
+ #ttyd-search-bar.hidden {
305
+ display: none;
306
+ }
307
+
308
+ #ttyd-search-input {
309
+ flex: 1;
310
+ background: #2d2d2d;
311
+ border: 1px solid #555;
312
+ border-radius: 6px;
313
+ color: #fff;
314
+ font-family: monospace;
315
+ font-size: 14px;
316
+ padding: 8px 12px;
317
+ outline: none;
318
+ min-width: 100px;
319
+ }
320
+
321
+ #ttyd-search-input:focus {
322
+ border-color: #007acc;
323
+ }
324
+
325
+ #ttyd-search-input::placeholder {
326
+ color: #888;
327
+ }
328
+
329
+ #ttyd-search-count {
330
+ color: #888;
331
+ font-size: 12px;
332
+ white-space: nowrap;
333
+ min-width: 50px;
334
+ text-align: center;
335
+ }
336
+
337
+ #ttyd-search-bar button {
338
+ background: #3a3a3a;
339
+ border: 1px solid #555;
340
+ border-radius: 6px;
341
+ color: #fff;
342
+ cursor: pointer;
343
+ font-size: 13px;
344
+ padding: 6px 10px;
345
+ min-height: 32px;
346
+ min-width: 32px;
347
+ touch-action: manipulation;
348
+ }
349
+
350
+ #ttyd-search-bar button:hover,
351
+ #ttyd-search-bar button:active {
352
+ background: #4a4a4a;
353
+ }
354
+
355
+ #ttyd-search-bar button.modifier {
356
+ background: #2d2d2d;
357
+ font-weight: bold;
358
+ }
359
+
360
+ #ttyd-search-bar button.modifier.active {
361
+ background: #007acc;
362
+ border-color: #005a9e;
363
+ }
364
+
365
+ #ttyd-search-close {
366
+ color: #888;
367
+ }
368
+
369
+ #ttyd-search-close:hover {
370
+ color: #fff;
371
+ }
372
+
373
+ /* Visual bell effect */
374
+ .xterm.bell-flash {
375
+ animation: bell-flash 100ms ease-out;
376
+ }
377
+
378
+ @keyframes bell-flash {
379
+ 0% { filter: brightness(1); }
380
+ 50% { filter: brightness(1.5); }
381
+ 100% { filter: brightness(1); }
276
382
  }
277
383
  `;
278
384
  //# sourceMappingURL=styles.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2X5B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Terminal Toolbar HTML Template
3
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";
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-search\">\uD83D\uDD0D</button>\n <button id=\"ttyd-toolbar-notify\" title=\"Push\u901A\u77E5\">\uD83D\uDD14</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<div id=\"ttyd-search-bar\" class=\"hidden\">\n <input id=\"ttyd-search-input\" type=\"text\" placeholder=\"\u691C\u7D22...\" />\n <span id=\"ttyd-search-count\">0/0</span>\n <button id=\"ttyd-search-prev\" title=\"\u524D\u3078 (Shift+Enter)\">\u25C0</button>\n <button id=\"ttyd-search-next\" title=\"\u6B21\u3078 (Enter)\">\u25B6</button>\n <button id=\"ttyd-search-case\" class=\"modifier\" title=\"\u5927\u6587\u5B57\u5C0F\u6587\u5B57\u3092\u533A\u5225\">Aa</button>\n <button id=\"ttyd-search-regex\" class=\"modifier\" title=\"\u6B63\u898F\u8868\u73FE\">.*</button>\n <button id=\"ttyd-search-close\" title=\"\u9589\u3058\u308B (Esc)\">\u2715</button>\n</div>\n<button id=\"ttyd-toolbar-toggle\">\u2328</button>\n";
5
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
6
  //# sourceMappingURL=template.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,ytEAuCvB,CAAC;AAEF,eAAO,MAAM,cAAc,qhBAW1B,CAAC"}
@@ -19,6 +19,8 @@ export const toolbarHtml = `
19
19
  <button id="ttyd-toolbar-zoomin">A+</button>
20
20
  <button id="ttyd-toolbar-copy">Copy</button>
21
21
  <button id="ttyd-toolbar-copyall">All</button>
22
+ <button id="ttyd-toolbar-search">🔍</button>
23
+ <button id="ttyd-toolbar-notify" title="Push通知">🔔</button>
22
24
  <button id="ttyd-toolbar-send">Send</button>
23
25
  <button id="ttyd-toolbar-run">Run</button>
24
26
  <button id="ttyd-toolbar-auto" class="modifier">Auto</button>
@@ -28,6 +30,15 @@ export const toolbarHtml = `
28
30
  <textarea id="ttyd-toolbar-input" rows="1" placeholder="日本語入力 (Enter: 送信)"></textarea>
29
31
  </div>
30
32
  </div>
33
+ <div id="ttyd-search-bar" class="hidden">
34
+ <input id="ttyd-search-input" type="text" placeholder="検索..." />
35
+ <span id="ttyd-search-count">0/0</span>
36
+ <button id="ttyd-search-prev" title="前へ (Shift+Enter)">◀</button>
37
+ <button id="ttyd-search-next" title="次へ (Enter)">▶</button>
38
+ <button id="ttyd-search-case" class="modifier" title="大文字小文字を区別">Aa</button>
39
+ <button id="ttyd-search-regex" class="modifier" title="正規表現">.*</button>
40
+ <button id="ttyd-search-close" title="閉じる (Esc)">✕</button>
41
+ </div>
31
42
  <button id="ttyd-toolbar-toggle">⌨</button>
32
43
  `;
33
44
  export const onboardingHtml = `
@@ -1 +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"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/daemon/toolbar/template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuC1B,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;CAW7B,CAAC"}
@@ -2,14 +2,34 @@ import type { IncomingMessage } from 'node:http';
2
2
  import type { Socket } from 'node:net';
3
3
  import type { Config } from '../config/types.js';
4
4
  import WebSocket from 'ws';
5
+ import type { NotificationService } from './notification/index.js';
6
+ /**
7
+ * Set the notification service for output monitoring
8
+ */
9
+ export declare function setNotificationService(service: NotificationService | null): void;
10
+ /**
11
+ * Get the notification service
12
+ */
13
+ export declare function getNotificationService(): NotificationService | null;
5
14
  /**
6
15
  * Gracefully close a WebSocket connection
7
16
  */
8
17
  export declare function closeWebSocket(ws: WebSocket, code: number, reason: string): void;
18
+ /**
19
+ * Options for WebSocket forwarding
20
+ */
21
+ export interface ForwardingOptions {
22
+ /** If true, block input messages from client to backend (read-only mode) */
23
+ readOnly?: boolean;
24
+ /** Session name for notification tracking */
25
+ sessionName?: string;
26
+ /** Notification service for output monitoring */
27
+ notificationService?: NotificationService;
28
+ }
9
29
  /**
10
30
  * Setup bidirectional WebSocket forwarding
11
31
  */
12
- export declare function setupWebSocketForwarding(clientWs: WebSocket, backendWs: WebSocket): void;
32
+ export declare function setupWebSocketForwarding(clientWs: WebSocket, backendWs: WebSocket, options?: ForwardingOptions): void;
13
33
  /**
14
34
  * Handle WebSocket upgrade request
15
35
  */
@@ -1 +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"}
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;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAWnE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI,CAEhF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAEnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMhF;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AA+ED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,iBAAsB,GAC9B,IAAI,CA8DN;AAqCD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,IAAI,CAoBN"}
@@ -4,6 +4,20 @@ import { findSessionForPath } from './router.js';
4
4
  const log = createLogger('websocket');
5
5
  // Create WebSocket server (noServer mode for manual upgrade handling)
6
6
  const wss = new WebSocketServer({ noServer: true });
7
+ // Global notification service reference (set by daemon)
8
+ let globalNotificationService = null;
9
+ /**
10
+ * Set the notification service for output monitoring
11
+ */
12
+ export function setNotificationService(service) {
13
+ globalNotificationService = service;
14
+ }
15
+ /**
16
+ * Get the notification service
17
+ */
18
+ export function getNotificationService() {
19
+ return globalNotificationService;
20
+ }
7
21
  /**
8
22
  * Gracefully close a WebSocket connection
9
23
  */
@@ -15,11 +29,76 @@ export function closeWebSocket(ws, code, reason) {
15
29
  ws.terminate();
16
30
  }
17
31
  }
32
+ /**
33
+ * Check if data is a ttyd input message (command byte '0')
34
+ * ttyd protocol: first byte is command type, '0' = input
35
+ */
36
+ function isInputMessage(data) {
37
+ if (Buffer.isBuffer(data) && data.length > 0) {
38
+ // ttyd input command is '0' (0x30)
39
+ return data[0] === 0x30;
40
+ }
41
+ if (data instanceof ArrayBuffer && data.byteLength > 0) {
42
+ return new Uint8Array(data)[0] === 0x30;
43
+ }
44
+ return false;
45
+ }
46
+ /**
47
+ * Check if data is a ttyd output message (command byte '1')
48
+ * ttyd protocol: first byte is command type, '1' = output
49
+ */
50
+ function isOutputMessage(data) {
51
+ if (Buffer.isBuffer(data) && data.length > 1) {
52
+ // ttyd output command is '1' (0x31)
53
+ return data[0] === 0x31;
54
+ }
55
+ if (data instanceof ArrayBuffer && data.byteLength > 1) {
56
+ return new Uint8Array(data)[0] === 0x31;
57
+ }
58
+ return false;
59
+ }
60
+ /**
61
+ * Extract text from ttyd output message
62
+ */
63
+ function extractOutputText(data) {
64
+ // Skip first byte (command type) and decode the rest as UTF-8
65
+ return data.subarray(1).toString('utf-8');
66
+ }
67
+ // Output buffer for accumulating text before matching
68
+ const outputBuffers = new Map();
69
+ const OUTPUT_BUFFER_MAX_LENGTH = 4096;
70
+ /**
71
+ * Process terminal output for pattern matching
72
+ */
73
+ function processOutput(sessionName, text, notificationService) {
74
+ // First, check raw text for control characters (bell, etc.)
75
+ // This catches patterns that don't fall on line boundaries
76
+ notificationService.processOutput(sessionName, text);
77
+ // Also accumulate output for line-based pattern matching
78
+ let buffer = outputBuffers.get(sessionName) ?? '';
79
+ buffer += text;
80
+ // Keep buffer size manageable
81
+ if (buffer.length > OUTPUT_BUFFER_MAX_LENGTH) {
82
+ buffer = buffer.slice(-OUTPUT_BUFFER_MAX_LENGTH);
83
+ }
84
+ // Check for patterns in complete lines
85
+ const lines = buffer.split('\n');
86
+ for (let i = 0; i < lines.length - 1; i++) {
87
+ const line = lines[i]?.trim();
88
+ if (line) {
89
+ notificationService.processOutput(sessionName, line);
90
+ }
91
+ }
92
+ // Keep only the last incomplete line in buffer
93
+ const lastLine = lines[lines.length - 1] ?? '';
94
+ outputBuffers.set(sessionName, lastLine);
95
+ }
18
96
  /**
19
97
  * Setup bidirectional WebSocket forwarding
20
98
  */
21
- export function setupWebSocketForwarding(clientWs, backendWs) {
99
+ export function setupWebSocketForwarding(clientWs, backendWs, options = {}) {
22
100
  let closed = false;
101
+ const { readOnly = false, sessionName, notificationService } = options;
23
102
  const cleanup = (initiator, code, reason) => {
24
103
  if (closed) {
25
104
  return;
@@ -33,6 +112,11 @@ export function setupWebSocketForwarding(clientWs, backendWs) {
33
112
  };
34
113
  // Forward messages bidirectionally
35
114
  clientWs.on('message', (data, isBinary) => {
115
+ // In read-only mode, block input messages
116
+ if (readOnly && isBinary && isInputMessage(data)) {
117
+ log.debug('Blocked input message in read-only mode');
118
+ return;
119
+ }
36
120
  if (backendWs.readyState === WebSocket.OPEN) {
37
121
  backendWs.send(data, { binary: isBinary });
38
122
  }
@@ -41,6 +125,18 @@ export function setupWebSocketForwarding(clientWs, backendWs) {
41
125
  if (clientWs.readyState === WebSocket.OPEN) {
42
126
  clientWs.send(data, { binary: isBinary });
43
127
  }
128
+ // Process output for notification pattern matching
129
+ if (sessionName && notificationService?.isEnabled() && isBinary && isOutputMessage(data)) {
130
+ try {
131
+ const text = extractOutputText(data);
132
+ if (text) {
133
+ processOutput(sessionName, text, notificationService);
134
+ }
135
+ }
136
+ catch {
137
+ // Ignore output processing errors
138
+ }
139
+ }
44
140
  });
45
141
  // Handle close events
46
142
  clientWs.on('close', (code, reason) => cleanup('client', code, reason));
@@ -60,15 +156,15 @@ export function setupWebSocketForwarding(clientWs, backendWs) {
60
156
  /**
61
157
  * Connect to backend WebSocket and setup forwarding
62
158
  */
63
- function connectToBackend(session, url, protocol, req, socket, head) {
159
+ function connectToBackend(session, url, protocol, req, socket, head, options = {}) {
64
160
  const backendUrl = `ws://127.0.0.1:${session.port}${url}`;
65
- log.debug(`Connecting to backend WebSocket: ${backendUrl}`);
161
+ log.debug(`Connecting to backend WebSocket: ${backendUrl}${options.readOnly ? ' (read-only)' : ''}`);
66
162
  const backendWs = new WebSocket(backendUrl, protocol ? protocol.split(',').map((p) => p.trim()) : []);
67
163
  backendWs.on('open', () => {
68
164
  log.debug(`Backend WebSocket connected: ${backendUrl}`);
69
165
  // Upgrade client connection once backend is ready
70
166
  wss.handleUpgrade(req, socket, head, (clientWs) => {
71
- setupWebSocketForwarding(clientWs, backendWs);
167
+ setupWebSocketForwarding(clientWs, backendWs, options);
72
168
  });
73
169
  });
74
170
  backendWs.on('error', (err) => {
@@ -83,6 +179,8 @@ function connectToBackend(session, url, protocol, req, socket, head) {
83
179
  export function handleUpgrade(config, req, socket, head) {
84
180
  const url = req.url ?? '/';
85
181
  log.debug(`WebSocket upgrade request: ${url}`);
182
+ // Check for read-only header (set by router for share links)
183
+ const readOnly = req.headers['x-ttyd-mux-readonly'] === 'true';
86
184
  const session = findSessionForPath(config, url);
87
185
  if (!session) {
88
186
  log.warn(`WebSocket upgrade rejected - no session for: ${url}`);
@@ -90,6 +188,10 @@ export function handleUpgrade(config, req, socket, head) {
90
188
  return;
91
189
  }
92
190
  const protocol = req.headers['sec-websocket-protocol'];
93
- connectToBackend(session, url, protocol, req, socket, head);
191
+ connectToBackend(session, url, protocol, req, socket, head, {
192
+ readOnly,
193
+ sessionName: session.name,
194
+ notificationService: globalNotificationService ?? undefined
195
+ });
94
196
  }
95
197
  //# sourceMappingURL=ws-proxy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws-proxy.js","sourceRoot":"","sources":["../../src/daemon/ws-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ws-proxy.js","sourceRoot":"","sources":["../../src/daemon/ws-proxy.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { deployCommand } from './commands/deploy.js';
7
7
  import { doctorCommand } from './commands/doctor.js';
8
8
  import { downCommand } from './commands/down.js';
9
9
  import { listCommand } from './commands/list.js';
10
+ import { shareCommand, shareListCommand, shareRevokeCommand } from './commands/share.js';
10
11
  import { reloadCommand } from './commands/reload.js';
11
12
  import { restartCommand } from './commands/restart.js';
12
13
  import { shutdownCommand } from './commands/shutdown.js';
@@ -136,6 +137,23 @@ caddy
136
137
  .option('--admin-api <url>', 'Caddy Admin API URL')
137
138
  .option('-c, --config <path>', 'Config file path')
138
139
  .action((options) => caddyStatusCommand(options));
140
+ // === Session sharing ===
141
+ const share = program.command('share').description('Session sharing (read-only)');
142
+ share
143
+ .command('create <session>')
144
+ .description('Create a read-only share link for a session')
145
+ .option('-e, --expires <duration>', 'Expiration time (e.g., 1h, 30m, 7d)', '1h')
146
+ .action((session, options) => shareCommand(session, { expires: options.expires }));
147
+ share
148
+ .command('list')
149
+ .alias('ls')
150
+ .description('List active share links')
151
+ .option('--json', 'Output as JSON')
152
+ .action((options) => shareListCommand(options));
153
+ share
154
+ .command('revoke <token>')
155
+ .description('Revoke a share link')
156
+ .action((token, options) => shareRevokeCommand(token, options));
139
157
  // Parse arguments
140
158
  program.parse();
141
159
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";(()=>{var s={FONT_SIZE:"ttyd-toolbar-font-size",ONBOARDING_SHOWN:"ttyd-toolbar-onboarding-shown",AUTO_RUN:"ttyd-toolbar-auto-run",NOTIFY_SUBSCRIPTION:"ttyd-mux-notify-subscription"};var u=class{constructor(){this.active=!1;this.autoBtn=null}bindElement(t){this.autoBtn=t,this.restore()}isActive(){return this.active}toggle(){return this.active=!this.active,this.autoBtn?.classList.toggle("active",this.active),this.save(),this.active}save(){try{localStorage.setItem(s.AUTO_RUN,this.active?"1":"0")}catch(t){console.warn("[Toolbar] Failed to save auto-run state:",t)}}restore(){try{localStorage.getItem(s.AUTO_RUN)==="1"&&(this.active=!0,this.autoBtn?.classList.add("active"),console.log("[Toolbar] Restored auto-run mode: enabled"))}catch(t){console.warn("[Toolbar] Failed to load auto-run state:",t)}}};var m=class{constructor(t){this.config=t}save(t){try{localStorage.setItem(s.FONT_SIZE,String(t))}catch(e){console.warn("[Toolbar] Failed to save font size:",e)}}load(){let e=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)?this.config.font_size_default_mobile:this.config.font_size_default_pc;try{let n=localStorage.getItem(s.FONT_SIZE);if(n){let i=parseInt(n,10);if(!isNaN(i)&&i>=this.config.font_size_min&&i<=this.config.font_size_max)return i}}catch(n){console.warn("[Toolbar] Failed to load font size:",n)}return e}};var f=class{constructor(t,e){this.ws=t,this.modifiers=e}sendKey(t){if(this.modifiers.isCtrlActive()&&t.length===1){let e=t.toUpperCase().charCodeAt(0)-64;e>0&&e<32&&this.ws.sendBytes([e]),this.modifiers.resetCtrlAlt()}else if(this.modifiers.isAltActive()&&t.length===1){let e=t.charCodeAt(0);this.ws.sendBytes([27,e]),this.modifiers.resetCtrlAlt()}else this.ws.sendText(t)}sendEnter(){this.ws.sendBytes([13])}sendEsc(){this.ws.sendBytes([27])}sendTab(){this.ws.sendBytes([9])}sendArrow(t){let e={up:[27,91,65],down:[27,91,66],right:[27,91,67],left:[27,91,68]};this.ws.sendBytes(e[t])}sendPage(t){t==="up"?this.ws.sendBytes([27,91,53,126]):this.ws.sendBytes([27,91,54,126])}sendText(t){return this.ws.sendText(t)}};var p=class{constructor(){this.ctrlActive=!1;this.altActive=!1;this.shiftActive=!1;this.ctrlBtn=null;this.altBtn=null;this.shiftBtn=null}bindElements(t,e,n){this.ctrlBtn=t,this.altBtn=e,this.shiftBtn=n}isCtrlActive(){return this.ctrlActive}isAltActive(){return this.altActive}isShiftActive(){return this.shiftActive}toggle(t){switch(t){case"ctrl":return this.ctrlActive=!this.ctrlActive,this.ctrlBtn?.classList.toggle("active",this.ctrlActive),this.ctrlActive&&(this.altActive=!1,this.altBtn?.classList.remove("active")),this.ctrlActive;case"alt":return this.altActive=!this.altActive,this.altBtn?.classList.toggle("active",this.altActive),this.altActive&&(this.ctrlActive=!1,this.ctrlBtn?.classList.remove("active")),this.altActive;case"shift":return this.shiftActive=!this.shiftActive,this.shiftBtn?.classList.toggle("active",this.shiftActive),this.shiftActive}}resetCtrlAlt(){this.ctrlActive=!1,this.altActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active")}reset(){this.ctrlActive=!1,this.altActive=!1,this.shiftActive=!1,this.ctrlBtn?.classList.remove("active"),this.altBtn?.classList.remove("active"),this.shiftBtn?.classList.remove("active")}};var v=class{constructor(){this.subscribed=!1;this.subscriptionId=null;this.notifyBtn=null;this.loadSubscription()}bindElement(t){this.notifyBtn=t,this.updateButton()}getBasePath(){return"/"+(window.location.pathname.split("/")[1]||"ttyd-mux")}getSessionName(){return window.location.pathname.split("/")[2]||""}urlBase64ToUint8Array(t){let e="=".repeat((4-t.length%4)%4),n=(t+e).replace(/-/g,"+").replace(/_/g,"/"),i=atob(n),o=new Uint8Array(i.length);for(let r=0;r<i.length;++r)o[r]=i.charCodeAt(r);return o}loadSubscription(){try{let t=localStorage.getItem(s.NOTIFY_SUBSCRIPTION);if(t){let e=JSON.parse(t);this.subscriptionId=e.id,this.subscribed=!0,console.log("[Toolbar] Loaded notification subscription: "+e.id)}}catch(t){console.warn("[Toolbar] Failed to load notification subscription:",t)}}saveSubscription(t){try{localStorage.setItem(s.NOTIFY_SUBSCRIPTION,JSON.stringify({id:t}))}catch(e){console.warn("[Toolbar] Failed to save notification subscription:",e)}}clearSubscription(){try{localStorage.removeItem(s.NOTIFY_SUBSCRIPTION)}catch(t){console.warn("[Toolbar] Failed to clear notification subscription:",t)}}updateButton(){this.notifyBtn&&(this.subscribed?(this.notifyBtn.classList.add("active"),this.notifyBtn.textContent="\u{1F514}",this.notifyBtn.title="Push\u901A\u77E5: ON (\u30AF\u30EA\u30C3\u30AF\u3067\u89E3\u9664)"):(this.notifyBtn.classList.remove("active"),this.notifyBtn.textContent="\u{1F515}",this.notifyBtn.title="Push\u901A\u77E5: OFF (\u30AF\u30EA\u30C3\u30AF\u3067\u6709\u52B9\u5316)"))}isSubscribed(){return this.subscribed}async subscribe(){let t=this.getBasePath(),e=this.getSessionName();try{if(!("serviceWorker"in navigator)||!("PushManager"in window)){alert("\u3053\u306E\u30D6\u30E9\u30A6\u30B6\u306FPush\u901A\u77E5\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u3066\u3044\u307E\u305B\u3093");return}if(await Notification.requestPermission()!=="granted"){alert("\u901A\u77E5\u306E\u8A31\u53EF\u304C\u5FC5\u8981\u3067\u3059");return}let i=await fetch(t+"/api/notifications/vapid-key");if(!i.ok)throw new Error("VAPID key fetch failed");let{publicKey:o}=await i.json(),l=await(await navigator.serviceWorker.ready).pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.urlBase64ToUint8Array(o)}),d=l.getKey("p256dh"),E=l.getKey("auth");if(!d||!E)throw new Error("Failed to get subscription keys");let h=await fetch(t+"/api/notifications/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoint:l.endpoint,keys:{p256dh:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(d)))),auth:btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(E))))},sessionName:e||void 0})});if(!h.ok)throw new Error("Subscription failed");let y=await h.json();this.subscriptionId=y.id,this.subscribed=!0,this.saveSubscription(y.id),this.updateButton(),console.log("[Toolbar] Push notification subscribed: "+y.id)}catch(n){console.error("[Toolbar] Push notification subscription failed:",n),alert("Push\u901A\u77E5\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F: "+n.message)}}async unsubscribe(){let t=this.getBasePath();try{this.subscriptionId&&await fetch(t+"/api/notifications/subscribe/"+encodeURIComponent(this.subscriptionId),{method:"DELETE"});let n=await(await navigator.serviceWorker.ready).pushManager.getSubscription();n&&await n.unsubscribe(),this.subscribed=!1,this.subscriptionId=null,this.clearSubscription(),this.updateButton(),console.log("[Toolbar] Push notification unsubscribed")}catch(e){console.error("[Toolbar] Push notification unsubscribe failed:",e)}}async toggle(){this.subscribed?await this.unsubscribe():await this.subscribe()}};var M="https://cdn.jsdelivr.net/npm/@xterm/addon-search@0.15.0/lib/addon-search.min.js",g=class{constructor(t){this.searchAddon=null;this.caseSensitive=!1;this.regex=!1;this.currentMatchIndex=0;this.totalMatches=0;this.searchBar=null;this.searchInput=null;this.searchCount=null;this.searchCaseBtn=null;this.searchRegexBtn=null;this.findTerminal=t}bindElements(t,e,n,i,o){this.searchBar=t,this.searchInput=e,this.searchCount=n,this.searchCaseBtn=i,this.searchRegexBtn=o}loadAddon(){if(this.searchAddon)return Promise.resolve(this.searchAddon);if(window.SearchAddon){let t=this.findTerminal();if(t)return this.searchAddon=new window.SearchAddon.SearchAddon,t.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded"),Promise.resolve(this.searchAddon)}return new Promise((t,e)=>{let n=document.createElement("script");n.src=M,n.onload=()=>{let i=this.findTerminal();i&&window.SearchAddon?(this.searchAddon=new window.SearchAddon.SearchAddon,i.loadAddon(this.searchAddon),console.log("[Toolbar] SearchAddon loaded from CDN"),t(this.searchAddon)):e(new Error("Failed to initialize SearchAddon"))},n.onerror=()=>{e(new Error("Failed to load SearchAddon"))},document.head.appendChild(n)})}toggle(t){this.searchBar&&(typeof t=="boolean"?this.searchBar.classList.toggle("hidden",!t):this.searchBar.classList.toggle("hidden"),this.searchBar.classList.contains("hidden")?(this.searchAddon?.clearDecorations&&this.searchAddon.clearDecorations(),this.updateMatchCount(0,0),document.querySelector(".xterm-helper-textarea")?.focus()):this.loadAddon().then(()=>{this.searchInput?.focus(),this.searchInput?.select()}).catch(e=>{console.error("[Toolbar] Failed to load search:",e)}))}updateMatchCount(t,e){this.currentMatchIndex=t,this.totalMatches=e,this.searchCount&&(this.searchCount.textContent=e===0?"0/0":`${t}/${e}`)}countMatches(t){if(!this.searchAddon||!t){this.updateMatchCount(0,0);return}let e=this.findTerminal();if(!e?.buffer?.active){this.updateMatchCount(0,0);return}let n=e.buffer.active,i=this.caseSensitive?"g":"gi",o=0,r;try{r=this.regex?new RegExp(t,i):new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i)}catch{this.updateMatchCount(0,0);return}for(let l=0;l<n.length;l++){let d=n.getLine(l);if(d){let h=d.translateToString(!0).match(r);h&&(o+=h.length)}}this.updateMatchCount(this.currentMatchIndex,o)}findNext(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex,incremental:!1},e=this.searchAddon.findNext(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.min(this.currentMatchIndex+1,this.totalMatches),this.currentMatchIndex>this.totalMatches&&(this.currentMatchIndex=1),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}findPrevious(){if(!this.searchAddon||!this.searchInput?.value)return!1;let t={caseSensitive:this.caseSensitive,regex:this.regex},e=this.searchAddon.findPrevious(this.searchInput.value,t);return e&&(this.currentMatchIndex=Math.max(this.currentMatchIndex-1,1),this.currentMatchIndex<1&&(this.currentMatchIndex=this.totalMatches),this.updateMatchCount(this.currentMatchIndex,this.totalMatches)),e}doSearch(){let t=this.searchInput?.value;if(!t){this.updateMatchCount(0,0);return}this.loadAddon().then(()=>{this.countMatches(t),this.currentMatchIndex=0,this.findNext()})}toggleCaseSensitive(){return this.caseSensitive=!this.caseSensitive,this.searchCaseBtn?.classList.toggle("active",this.caseSensitive),this.doSearch(),this.caseSensitive}toggleRegex(){return this.regex=!this.regex,this.searchRegexBtn?.classList.toggle("active",this.regex),this.doSearch(),this.regex}isVisible(){return this.searchBar?!this.searchBar.classList.contains("hidden"):!1}};var b=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}getDefaultFontSize(){return this.isMobile?this.config.font_size_default_mobile:this.config.font_size_default_pc}findTerminal(){if(window.term)return window.term;let t=document.querySelector(".xterm");return t&&t._core?t._core:null}fitTerminal(){if(window.fitAddon&&typeof window.fitAddon.fit=="function"){window.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via fitAddon");return}let t=window.term;if(t&&t.fitAddon&&typeof t.fitAddon.fit=="function"){t.fitAddon.fit(),console.log("[Toolbar] Terminal fitted via term.fitAddon");return}window.dispatchEvent(new Event("resize")),console.log("[Toolbar] Dispatched resize event")}getCurrentFontSize(){let t=this.findTerminal();return t?.options?t.options.fontSize??this.getDefaultFontSize():this.getDefaultFontSize()}setFontSize(t){let e=this.findTerminal();if(!e?.options)return console.log("[Toolbar] Terminal not found for zoom"),!1;let n=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,t));return e.options.fontSize=n,this.fitTerminal(),console.log("[Toolbar] Font size changed to "+n),!0}zoomTerminal(t){let e=this.getCurrentFontSize();return this.setFontSize(e+t)}copySelection(){let t=this.findTerminal();if(!t)return console.log("[Toolbar] Terminal not found for copy"),Promise.resolve(!1);let e=t.getSelection();return e?navigator.clipboard.writeText(e).then(()=>(console.log("[Toolbar] Copied selection to clipboard"),!0)).catch(n=>(console.error("[Toolbar] Failed to copy:",n),!1)):(console.log("[Toolbar] No text selected"),Promise.resolve(!1))}copyAll(){let t=this.findTerminal();if(!t?.buffer?.active)return console.log("[Toolbar] Terminal buffer not found"),Promise.resolve(!1);let e=t.buffer.active,n=[];for(let o=0;o<e.length;o++){let r=e.getLine(o);r&&n.push(r.translateToString(!0))}let i=n.join(`
2
+ `).trimEnd();return navigator.clipboard.writeText(i).then(()=>(console.log("[Toolbar] Copied all text to clipboard"),!0)).catch(o=>(console.error("[Toolbar] Failed to copy:",o),!1))}setupBellHandler(t){let e=this.findTerminal();if(!e?.onBell){setTimeout(()=>this.setupBellHandler(t),500);return}e.onBell(()=>{console.log("[Toolbar] Bell detected (visual feedback)"),t();let n=e.element;n&&(n.classList.add("bell-flash"),setTimeout(()=>{n.classList.remove("bell-flash")},100))}),console.log("[Toolbar] Visual bell handler registered")}};var T=class{constructor(t,e,n,i){this.touchStartPos=null;this.shiftTouchActive=!1;this.scrollTouchActive=!1;this.scrollLastY=0;this.pinchStartDistance=0;this.lastTapTime=0;this.scrollActive=!1;this.scrollBtn=null;this.config=t,this.terminal=e,this.input=n,this.modifiers=i,this.pinchStartFontSize=e.getDefaultFontSize()}bindScrollButton(t){this.scrollBtn=t}toggleScrollMode(){return this.scrollActive=!this.scrollActive,this.scrollBtn?.classList.toggle("active",this.scrollActive),this.scrollActive?console.log("[Toolbar] Scroll mode enabled - drag to scroll"):console.log("[Toolbar] Scroll mode disabled"),this.scrollActive}isScrollActive(){return this.scrollActive}setup(){this.setupShiftMouseInjection(),this.setupTouchSelection(),this.setupPinchZoom(),this.setupWheelZoom(),this.setupDoubleTap()}setupShiftMouseInjection(){let t=["mousedown","mousemove","mouseup"];for(let e of t)document.addEventListener(e,n=>{if(!(n.target.closest("#ttyd-toolbar")||n.target.closest("#ttyd-toolbar-toggle"))&&this.modifiers.isShiftActive()&&!n.shiftKey){let i=new MouseEvent(n.type,{bubbles:n.bubbles,cancelable:n.cancelable,view:n.view,detail:n.detail,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:!0,metaKey:n.metaKey,button:n.button,buttons:n.buttons,relatedTarget:n.relatedTarget});n.stopImmediatePropagation(),n.preventDefault(),n.target.dispatchEvent(i)}},!0)}dispatchMouseEvent(t,e,n){let i=new MouseEvent(t,{bubbles:!0,cancelable:!0,view:window,detail:1,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,ctrlKey:!1,altKey:!1,shiftKey:n,metaKey:!1,button:0,buttons:t==="mouseup"?0:1,relatedTarget:null});e.target.dispatchEvent(i)}setupTouchSelection(){document.addEventListener("touchstart",t=>{let e=t.target;if(!(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle"))){if(t.touches.length===1&&this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.scrollLastY=n.clientY,this.scrollTouchActive=!0,t.preventDefault()}else if(t.touches.length===1&&this.modifiers.isShiftActive()){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY},this.shiftTouchActive=!0,t.preventDefault(),this.dispatchMouseEvent("mousedown",n,!0)}else if(t.touches.length===2&&(this.shiftTouchActive||this.scrollTouchActive))this.shiftTouchActive&&this.dispatchMouseEvent("mouseup",t.touches[0],!0),this.shiftTouchActive=!1,this.scrollTouchActive=!1,this.touchStartPos=null;else if(t.touches.length===1&&!this.modifiers.isShiftActive()&&!this.scrollActive){let n=t.touches[0];this.touchStartPos={x:n.clientX,y:n.clientY}}}},{passive:!1,capture:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===1&&this.scrollTouchActive){t.preventDefault();let e=t.touches[0],n=this.scrollLastY-e.clientY;Math.abs(n)>=30&&(n>0?this.input.sendPage("down"):this.input.sendPage("up"),this.scrollLastY=e.clientY)}else t.touches.length===1&&this.shiftTouchActive&&(t.preventDefault(),this.dispatchMouseEvent("mousemove",t.touches[0],!0))},{passive:!1,capture:!0}),document.addEventListener("touchend",t=>{if(this.scrollTouchActive&&t.touches.length===0)this.scrollTouchActive=!1,this.touchStartPos=null;else if(this.shiftTouchActive&&t.touches.length===0){let e=t.changedTouches[0];this.dispatchMouseEvent("mouseup",e,!0),this.shiftTouchActive=!1,this.touchStartPos=null}},{passive:!0,capture:!0})}getTouchDistance(t){let e=t[0].clientX-t[1].clientX,n=t[0].clientY-t[1].clientY;return Math.sqrt(e*e+n*n)}setupPinchZoom(){document.addEventListener("touchstart",t=>{t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&(this.pinchStartDistance=this.getTouchDistance(t.touches),this.pinchStartFontSize=this.terminal.getCurrentFontSize())},{passive:!0}),document.addEventListener("touchmove",t=>{if(t.touches.length===2&&(this.modifiers.isCtrlActive()||this.modifiers.isShiftActive())&&this.pinchStartDistance>0){t.preventDefault();let n=this.getTouchDistance(t.touches)/this.pinchStartDistance,i=Math.round(this.pinchStartFontSize*n),o=Math.max(this.config.font_size_min,Math.min(this.config.font_size_max,i));this.terminal.getCurrentFontSize()!==o&&this.terminal.setFontSize(o)}},{passive:!1}),document.addEventListener("touchend",t=>{t.touches.length<2&&(this.pinchStartDistance=0)},{passive:!0})}setupWheelZoom(){document.addEventListener("wheel",t=>{if(t.ctrlKey){t.preventDefault();let e=t.deltaY>0?-2:2;this.terminal.zoomTerminal(e)}},{passive:!1})}setupDoubleTap(){document.addEventListener("touchend",t=>{let e=t.target;if(e.closest("#ttyd-toolbar")||e.closest("#ttyd-toolbar-toggle")||t.changedTouches.length!==1)return;let n=Date.now();n-this.lastTapTime<this.config.double_tap_delay?(this.input.sendEnter(),this.lastTapTime=0):this.lastTapTime=n},{passive:!0})}};var c=window.WebSocket,B=class{constructor(){this.ws=null;this.interceptWebSocketCreation()}interceptWebSocketCreation(){let t=this;window.WebSocket=function(e,n){let i=new c(e,n);return e.includes("/ws")&&(t.ws=i),i},window.WebSocket.prototype=c.prototype,Object.defineProperty(window.WebSocket,"CONNECTING",{value:c.CONNECTING}),Object.defineProperty(window.WebSocket,"OPEN",{value:c.OPEN}),Object.defineProperty(window.WebSocket,"CLOSING",{value:c.CLOSING}),Object.defineProperty(window.WebSocket,"CLOSED",{value:c.CLOSED})}findWebSocket(){return this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws:window.socket&&window.socket.readyState===WebSocket.OPEN?(this.ws=window.socket,this.ws):null}isConnected(){return this.findWebSocket()!==null}sendText(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let i=new TextEncoder().encode(t),o=new Uint8Array(i.length+1);return o[0]=48,o.set(i,1),e.send(o),!0}sendBytes(t){let e=this.findWebSocket();if(!e)return console.error("[Toolbar] WebSocket not found"),!1;let n=new Uint8Array(t.length+1);return n[0]=48,n.set(t,1),e.send(n),!0}};var S=class{constructor(t){this.config=t,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),this.elements=this.getElements(),this.ws=new B,this.terminal=new b(t),this.modifiers=new p,this.input=new f(this.ws,this.modifiers),this.search=new g(()=>this.terminal.findTerminal()),this.notifications=new v,this.touch=new T(t,this.terminal,this.input,this.modifiers),this.fontSizeManager=new m(t),this.autoRun=new u}getElements(){return{container:document.getElementById("ttyd-toolbar"),input:document.getElementById("ttyd-toolbar-input"),sendBtn:document.getElementById("ttyd-toolbar-send"),enterBtn:document.getElementById("ttyd-toolbar-enter"),zoomInBtn:document.getElementById("ttyd-toolbar-zoomin"),zoomOutBtn:document.getElementById("ttyd-toolbar-zoomout"),runBtn:document.getElementById("ttyd-toolbar-run"),toggleBtn:document.getElementById("ttyd-toolbar-toggle"),ctrlBtn:document.getElementById("ttyd-toolbar-ctrl"),altBtn:document.getElementById("ttyd-toolbar-alt"),shiftBtn:document.getElementById("ttyd-toolbar-shift"),escBtn:document.getElementById("ttyd-toolbar-esc"),tabBtn:document.getElementById("ttyd-toolbar-tab"),upBtn:document.getElementById("ttyd-toolbar-up"),downBtn:document.getElementById("ttyd-toolbar-down"),copyBtn:document.getElementById("ttyd-toolbar-copy"),copyAllBtn:document.getElementById("ttyd-toolbar-copyall"),autoBtn:document.getElementById("ttyd-toolbar-auto"),minimizeBtn:document.getElementById("ttyd-toolbar-minimize"),scrollBtn:document.getElementById("ttyd-toolbar-scroll"),pageUpBtn:document.getElementById("ttyd-toolbar-pageup"),pageDownBtn:document.getElementById("ttyd-toolbar-pagedown"),notifyBtn:document.getElementById("ttyd-toolbar-notify"),searchBar:document.getElementById("ttyd-search-bar"),searchInput:document.getElementById("ttyd-search-input"),searchCount:document.getElementById("ttyd-search-count"),searchPrevBtn:document.getElementById("ttyd-search-prev"),searchNextBtn:document.getElementById("ttyd-search-next"),searchCaseBtn:document.getElementById("ttyd-search-case"),searchRegexBtn:document.getElementById("ttyd-search-regex"),searchCloseBtn:document.getElementById("ttyd-search-close"),searchToolbarBtn:document.getElementById("ttyd-toolbar-search")}}initialize(){this.modifiers.bindElements(this.elements.ctrlBtn,this.elements.altBtn,this.elements.shiftBtn),this.search.bindElements(this.elements.searchBar,this.elements.searchInput,this.elements.searchCount,this.elements.searchCaseBtn,this.elements.searchRegexBtn),this.notifications.bindElement(this.elements.notifyBtn),this.touch.bindScrollButton(this.elements.scrollBtn),this.autoRun.bindElement(this.elements.autoBtn),this.setupEventListeners(),this.touch.setup(),setTimeout(()=>{this.terminal.setupBellHandler(()=>{})},1e3),this.applyStoredFontSize(),this.setupVisibilityHandler(),this.isMobile&&(setTimeout(()=>this.toggleToolbar(!0),1e3),setTimeout(()=>this.showOnboarding(),1500)),console.log("[Toolbar] Loaded. "+(this.isMobile?"Mobile mode.":"Press Ctrl+J or click keyboard button to toggle."))}setupEventListeners(){let{elements:t}=this;t.sendBtn.addEventListener("click",e=>{e.preventDefault(),this.submitInput()}),t.enterBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEnter()}),t.runBtn.addEventListener("click",e=>{e.preventDefault(),this.runInput()}),t.zoomInBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.zoomOutBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.zoomTerminal(-2),this.fontSizeManager.save(this.terminal.getCurrentFontSize())}),t.ctrlBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("ctrl")}),t.altBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("alt")}),t.shiftBtn.addEventListener("click",e=>{e.preventDefault(),this.modifiers.toggle("shift")}),t.autoBtn.addEventListener("click",e=>{e.preventDefault(),this.autoRun.toggle()}),t.escBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendEsc()}),t.tabBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendTab()}),t.upBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("up")}),t.downBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendArrow("down")}),t.pageUpBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("up")}),t.pageDownBtn.addEventListener("click",e=>{e.preventDefault(),this.input.sendPage("down")}),t.copyBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copySelection()}),t.copyAllBtn.addEventListener("click",e=>{e.preventDefault(),this.terminal.copyAll()}),t.scrollBtn.addEventListener("click",e=>{e.preventDefault(),this.touch.toggleScrollMode()}),t.notifyBtn.addEventListener("click",e=>{e.preventDefault(),this.notifications.toggle()}),t.minimizeBtn.addEventListener("click",e=>{e.preventDefault(),t.container.classList.toggle("minimized"),t.minimizeBtn.textContent=t.container.classList.contains("minimized")?"\u25B2":"\u25BC",setTimeout(()=>this.terminal.fitTerminal(),100)}),t.toggleBtn.addEventListener("click",e=>{e.preventDefault(),this.toggleToolbar()}),this.setupSearchEvents(),this.setupInputEvents(),this.setupKeyboardShortcuts()}setupSearchEvents(){let{elements:t}=this;t.searchToolbarBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle()}),t.searchCloseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggle(!1)}),t.searchNextBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findNext()}),t.searchPrevBtn.addEventListener("click",e=>{e.preventDefault(),this.search.findPrevious()}),t.searchCaseBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleCaseSensitive()}),t.searchRegexBtn.addEventListener("click",e=>{e.preventDefault(),this.search.toggleRegex()}),t.searchInput.addEventListener("input",()=>{this.search.doSearch()}),t.searchInput.addEventListener("keydown",e=>{e.key==="Enter"&&!e.isComposing?(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext()):e.key==="Escape"?(e.preventDefault(),this.search.toggle(!1)):e.key==="F3"&&(e.preventDefault(),e.shiftKey?this.search.findPrevious():this.search.findNext())})}setupInputEvents(){let{input:t}=this.elements;t.addEventListener("input",()=>this.adjustTextareaHeight()),t.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&!e.isComposing?(e.preventDefault(),this.submitInput()):e.key==="Escape"&&(e.preventDefault(),this.toggleToolbar(!1))})}setupKeyboardShortcuts(){document.addEventListener("keydown",t=>{t.ctrlKey&&t.key==="j"&&(t.preventDefault(),this.toggleToolbar()),t.ctrlKey&&t.shiftKey&&t.key==="F"&&(t.preventDefault(),this.search.toggle())})}adjustTextareaHeight(){let t=this.elements.input;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,120)+"px"}submitInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),this.autoRun.isActive()&&setTimeout(()=>this.input.sendEnter(),1e3))}runInput(){let t=this.elements.input.value;t&&this.input.sendText(t)&&(this.elements.input.value="",this.adjustTextareaHeight(),setTimeout(()=>this.input.sendEnter(),1e3))}toggleToolbar(t){let{container:e,input:n}=this.elements;typeof t=="boolean"?e.classList.toggle("hidden",!t):e.classList.toggle("hidden"),e.classList.contains("hidden")?(document.querySelector(".xterm-helper-textarea")?.focus(),setTimeout(()=>this.terminal.fitTerminal(),100)):(n.focus(),setTimeout(()=>this.terminal.fitTerminal(),100))}applyStoredFontSize(){let t=()=>{let e=this.terminal.findTerminal();if(e?.options){let n=this.fontSizeManager.load();e.options.fontSize=n,this.terminal.fitTerminal(),console.log("[Toolbar] Restored font size: "+n)}};setTimeout(t,500),setTimeout(t,1500)}setupVisibilityHandler(){document.addEventListener("visibilitychange",()=>{document.hidden||this.ws.isConnected()||(console.log("[Toolbar] Connection lost, reloading..."),location.reload())})}showOnboarding(){let t=document.getElementById("ttyd-toolbar-onboarding");if(!t)return;try{if(localStorage.getItem(s.ONBOARDING_SHOWN)){t.remove();return}}catch{}t.style.display="block";let e=document.getElementById("ttyd-toolbar-onboarding-close");e&&e.addEventListener("click",()=>{t.remove();try{localStorage.setItem(s.ONBOARDING_SHOWN,"1")}catch{}}),setTimeout(()=>{if(t.parentNode){t.remove();try{localStorage.setItem(s.ONBOARDING_SHOWN,"1")}catch{}}},15e3)}},L=window.__TOOLBAR_CONFIG__;L?new S(L).initialize():console.error("[Toolbar] Configuration not found. Make sure __TOOLBAR_CONFIG__ is set.");})();
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export declare const NAME: "ttyd-mux";
2
- export declare const VERSION: "0.4.2";
2
+ export declare const VERSION: "0.4.3";
3
3
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
2
  export const NAME = 'ttyd-mux';
3
- export const VERSION = '0.4.2';
3
+ export const VERSION = '0.4.3';
4
4
  //# sourceMappingURL=version.js.map