sshler 0.7.0__tar.gz → 0.7.2__tar.gz
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.
- {sshler-0.7.0 → sshler-0.7.2}/MANIFEST.in +1 -0
- {sshler-0.7.0/sshler.egg-info → sshler-0.7.2}/PKG-INFO +1 -1
- {sshler-0.7.0 → sshler-0.7.2}/pyproject.toml +2 -1
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/files.py +28 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/models.py +1 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/recovery.py +7 -2
- sshler-0.7.2/sshler/static/dist/assets/Alert-C0caXY3O.js +48 -0
- sshler-0.7.2/sshler/static/dist/assets/BoxesView-Cw5NiFP6.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/BoxesView-DCsH8F6Q.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/DirectoryPickerModal-CVB_AH0M.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/DirectoryPickerModal-DlIkiyp1.js +27 -0
- sshler-0.7.2/sshler/static/dist/assets/FilesView-BFEnr1Va.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/FilesView-jrF0GwSm.js +799 -0
- sshler-0.7.2/sshler/static/dist/assets/Grid-B_OzHEym.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/InputNumber-XDnEotgL.js +13 -0
- sshler-0.7.2/sshler/static/dist/assets/LoginView-BLrnakeI.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/LoginView-C2biy_5H.js +110 -0
- sshler-0.7.2/sshler/static/dist/assets/MultiTerminalView-C8x4yNn3.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/MultiTerminalView-UnOQ5utL.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/NotFoundView-DYaoqkDb.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/NotFoundView-D_GMBtkq.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/OverviewView-BSwVX2Hs.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/OverviewView-SxVVVBkg.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/PhCircle.vue-BD-yU_HB.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/PhHouse.vue-BwwabvLx.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/PhPlus.vue-ChJ-UG0M.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/PhPushPinSimple.vue-DBP-0k94.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/PhTrash.vue-N4dJGebi.js +153 -0
- sshler-0.7.2/sshler/static/dist/assets/SettingsView-DCCByJuu.js +74 -0
- sshler-0.7.2/sshler/static/dist/assets/SettingsView-xrtebMdI.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/Spin-13rKpfWM.js +43 -0
- sshler-0.7.2/sshler/static/dist/assets/Switch-DsrNJCg_.js +102 -0
- sshler-0.7.2/sshler/static/dist/assets/TerminalView--aIl3nME.js +2 -0
- sshler-0.7.2/sshler/static/dist/assets/TerminalView-DKOHtH_z.css +1 -0
- sshler-0.7.2/sshler/static/dist/assets/favorites-CJMYgFyA.js +1 -0
- sshler-0.7.2/sshler/static/dist/assets/index-BCipBsn9.js +1813 -0
- sshler-0.7.2/sshler/static/dist/assets/index-Cwi9_lHU.css +1 -0
- sshler-0.7.2/sshler/static/dist/fonts/MonaspaceNeon-Bold.woff2 +0 -0
- sshler-0.7.2/sshler/static/dist/fonts/MonaspaceNeon-Regular.woff2 +0 -0
- sshler-0.7.2/sshler/static/dist/fonts/MonaspaceNeon-Variable.woff2 +0 -0
- sshler-0.7.2/sshler/static/dist/icon-192.png +0 -0
- sshler-0.7.2/sshler/static/dist/icon-512-maskable.png +0 -0
- sshler-0.7.2/sshler/static/dist/icon-512.png +0 -0
- sshler-0.7.2/sshler/static/dist/index.html +22 -0
- sshler-0.7.2/sshler/static/dist/manifest.webmanifest +29 -0
- sshler-0.7.2/sshler/static/favicon.png +0 -0
- sshler-0.7.2/sshler/static/logo.png +0 -0
- {sshler-0.7.0 → sshler-0.7.2/sshler.egg-info}/PKG-INFO +1 -1
- {sshler-0.7.0 → sshler-0.7.2}/sshler.egg-info/SOURCES.txt +41 -0
- {sshler-0.7.0 → sshler-0.7.2}/LICENSE +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/README.md +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/scripts/check_frontend_dist.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/setup.cfg +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/__init__.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/__init__.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/archive.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/auth.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/batch.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/boxes.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/config.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/dependencies.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/grep.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/helpers.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/rate_limiting.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/search.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/sessions.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/snippets.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/terminal.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/api/tunnels.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/auth.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/cli.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/config.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/config_cache.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/rate_limit.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/scripts/install-sshler-task.ps1 +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/scripts/remove-sshler-task.ps1 +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/scripts/run-sshler.ps1 +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/session.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/settings.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/snapshot.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/spa.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/ssh.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/ssh_config.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/ssh_pool.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/state.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/base.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/command-palette.js +0 -0
- {sshler-0.7.0/sshler/static → sshler-0.7.2/sshler/static/dist}/favicon.png +0 -0
- {sshler-0.7.0/sshler/static → sshler-0.7.2/sshler/static/dist}/logo.png +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/favicon-terminal-local.svg +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/favicon-terminal.svg +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/favicon.svg +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/file-browser.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/file-edit.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/file-view.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/manifest.json +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/multi-session.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/style.css +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/sw.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/term.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/vendor/xterm/xterm-addon-fit.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/vendor/xterm/xterm-addon-search.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/vendor/xterm/xterm.css +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/static/vendor/xterm/xterm.js +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/validation.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler/webapp.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler.egg-info/dependency_links.txt +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler.egg-info/entry_points.txt +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler.egg-info/requires.txt +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/sshler.egg-info/top_level.txt +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_api_v1.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_archive.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_basic.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_batch_ops.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_command_injection.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_config.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_database_indexes.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_dev_workflow.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_grep.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_handshake_status.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_httpx_ws.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_path_validation.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_rate_limit.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_search.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_session_auth.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_snippets.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_ssh.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_tunnels.py +0 -0
- {sshler-0.7.0 → sshler-0.7.2}/tests/test_websocket.py +0 -0
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "sshler"
|
|
8
|
-
version = "0.7.
|
|
8
|
+
version = "0.7.2"
|
|
9
9
|
description = "A local FastAPI-powered SSH multiplexer for tmux-in-browser — from your laptop only."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.12"
|
|
@@ -69,6 +69,7 @@ dev = [
|
|
|
69
69
|
"mypy>=1.19.1",
|
|
70
70
|
"types-pyyaml>=6.0.12.20250915",
|
|
71
71
|
"pre-commit>=4.0.0",
|
|
72
|
+
"build>=1.4.0",
|
|
72
73
|
]
|
|
73
74
|
|
|
74
75
|
[project.scripts]
|
|
@@ -66,6 +66,25 @@ def _cleanup_temp(path: str) -> BackgroundTask:
|
|
|
66
66
|
return BackgroundTask(_remove)
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
async def _get_gitignored_names(directory: str, names: list[str]) -> set[str]:
|
|
70
|
+
"""Check which filenames in a directory are gitignored. Returns set of ignored names."""
|
|
71
|
+
try:
|
|
72
|
+
proc = await asyncio.create_subprocess_exec(
|
|
73
|
+
"git", "check-ignore", "--stdin",
|
|
74
|
+
stdin=asyncio.subprocess.PIPE,
|
|
75
|
+
stdout=asyncio.subprocess.PIPE,
|
|
76
|
+
stderr=asyncio.subprocess.PIPE,
|
|
77
|
+
cwd=directory,
|
|
78
|
+
)
|
|
79
|
+
input_data = "\n".join(names).encode()
|
|
80
|
+
stdout, _ = await proc.communicate(input=input_data)
|
|
81
|
+
if proc.returncode not in (0, 1): # 1 means none matched, 128 means not a git repo
|
|
82
|
+
return set()
|
|
83
|
+
return set(line.strip() for line in stdout.decode().splitlines() if line.strip())
|
|
84
|
+
except Exception:
|
|
85
|
+
return set()
|
|
86
|
+
|
|
87
|
+
|
|
69
88
|
def get_router(deps: APIDependencies) -> APIRouter:
|
|
70
89
|
router = APIRouter()
|
|
71
90
|
|
|
@@ -95,6 +114,14 @@ def get_router(deps: APIDependencies) -> APIRouter:
|
|
|
95
114
|
except OSError:
|
|
96
115
|
continue # broken symlink or deleted between iterdir and stat
|
|
97
116
|
children.sort(key=lambda item: (not item[1], item[0].name.lower()))
|
|
117
|
+
|
|
118
|
+
# Check gitignored status for all entries in one batch
|
|
119
|
+
ignored_names: set[str] = set()
|
|
120
|
+
if children:
|
|
121
|
+
ignored_names = await _get_gitignored_names(
|
|
122
|
+
normalized, [c.name for c, _ in children]
|
|
123
|
+
)
|
|
124
|
+
|
|
98
125
|
for child, is_dir in children:
|
|
99
126
|
try:
|
|
100
127
|
stats = child.stat()
|
|
@@ -108,6 +135,7 @@ def get_router(deps: APIDependencies) -> APIRouter:
|
|
|
108
135
|
size=stats.st_size if child.is_file() else None,
|
|
109
136
|
modified=stats.st_mtime,
|
|
110
137
|
mode=stats.st_mode & 0o7777,
|
|
138
|
+
gitignored=child.name in ignored_names,
|
|
111
139
|
)
|
|
112
140
|
)
|
|
113
141
|
return APIDirectoryListing(box=box.name, directory=normalized, entries=entries)
|
|
@@ -61,15 +61,20 @@ def get_router(deps: APIDependencies) -> APIRouter:
|
|
|
61
61
|
|
|
62
62
|
@router.post("/recovery/{session_id}/dismiss", response_model=APISimpleMessage)
|
|
63
63
|
async def api_dismiss_single(session_id: str) -> APISimpleMessage:
|
|
64
|
-
"""Dismiss a single recovery session."""
|
|
64
|
+
"""Dismiss a single recovery session permanently."""
|
|
65
65
|
lost = get_recovery_sessions()
|
|
66
66
|
set_recovery_sessions([s for s in lost if s["id"] != session_id])
|
|
67
|
+
# Mark inactive in DB so the snapshot loop stops re-detecting it
|
|
68
|
+
await state.update_session_activity_async(session_id, active=False)
|
|
67
69
|
return APISimpleMessage(status="ok", message="Dismissed")
|
|
68
70
|
|
|
69
71
|
@router.post("/recovery/dismiss", response_model=APISimpleMessage)
|
|
70
72
|
async def api_dismiss_recovery() -> APISimpleMessage:
|
|
71
|
-
"""Dismiss all recovery notifications."""
|
|
73
|
+
"""Dismiss all recovery notifications permanently."""
|
|
72
74
|
lost = get_recovery_sessions()
|
|
75
|
+
# Mark all as inactive so they don't get re-detected
|
|
76
|
+
for s in lost:
|
|
77
|
+
await state.update_session_activity_async(s["id"], active=False)
|
|
73
78
|
set_recovery_sessions([])
|
|
74
79
|
logger.info("Dismissed %d recovery session(s)", len(lost))
|
|
75
80
|
return APISimpleMessage(status="ok", message=f"Dismissed {len(lost)} session(s)")
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import{ap as d,at as t,as as u,cA as H,ao as j,d as F,a1 as r,m as M,cB as N,aQ as O,av as V,cC as W,a5 as D,ax as C,az as G,c as p,cD as K,aA as i,aB as Q,g as q,cE as J,aS as U,cF as X,ce as Y,cG as Z,cH as ee}from"./index-BCipBsn9.js";const oe=d("alert",`
|
|
2
|
+
line-height: var(--n-line-height);
|
|
3
|
+
border-radius: var(--n-border-radius);
|
|
4
|
+
position: relative;
|
|
5
|
+
transition: background-color .3s var(--n-bezier);
|
|
6
|
+
background-color: var(--n-color);
|
|
7
|
+
text-align: start;
|
|
8
|
+
word-break: break-word;
|
|
9
|
+
`,[t("border",`
|
|
10
|
+
border-radius: inherit;
|
|
11
|
+
position: absolute;
|
|
12
|
+
left: 0;
|
|
13
|
+
right: 0;
|
|
14
|
+
top: 0;
|
|
15
|
+
bottom: 0;
|
|
16
|
+
transition: border-color .3s var(--n-bezier);
|
|
17
|
+
border: var(--n-border);
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
`),u("closable",[d("alert-body",[t("title",`
|
|
20
|
+
padding-right: 24px;
|
|
21
|
+
`)])]),t("icon",{color:"var(--n-icon-color)"}),d("alert-body",{padding:"var(--n-padding)"},[t("title",{color:"var(--n-title-text-color)"}),t("content",{color:"var(--n-content-text-color)"})]),H({originalTransition:"transform .3s var(--n-bezier)",enterToProps:{transform:"scale(1)"},leaveToProps:{transform:"scale(0.9)"}}),t("icon",`
|
|
22
|
+
position: absolute;
|
|
23
|
+
left: 0;
|
|
24
|
+
top: 0;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
display: flex;
|
|
28
|
+
width: var(--n-icon-size);
|
|
29
|
+
height: var(--n-icon-size);
|
|
30
|
+
font-size: var(--n-icon-size);
|
|
31
|
+
margin: var(--n-icon-margin);
|
|
32
|
+
`),t("close",`
|
|
33
|
+
transition:
|
|
34
|
+
color .3s var(--n-bezier),
|
|
35
|
+
background-color .3s var(--n-bezier);
|
|
36
|
+
position: absolute;
|
|
37
|
+
right: 0;
|
|
38
|
+
top: 0;
|
|
39
|
+
margin: var(--n-close-margin);
|
|
40
|
+
`),u("show-icon",[d("alert-body",{paddingLeft:"calc(var(--n-icon-margin-left) + var(--n-icon-size) + var(--n-icon-margin-right))"})]),u("right-adjust",[d("alert-body",{paddingRight:"calc(var(--n-close-size) + var(--n-padding) + 2px)"})]),d("alert-body",`
|
|
41
|
+
border-radius: var(--n-border-radius);
|
|
42
|
+
transition: border-color .3s var(--n-bezier);
|
|
43
|
+
`,[t("title",`
|
|
44
|
+
transition: color .3s var(--n-bezier);
|
|
45
|
+
font-size: 16px;
|
|
46
|
+
line-height: 19px;
|
|
47
|
+
font-weight: var(--n-title-font-weight);
|
|
48
|
+
`,[j("& +",[t("content",{marginTop:"9px"})])]),t("content",{transition:"color .3s var(--n-bezier)",fontSize:"var(--n-font-size)"})]),t("icon",{transition:"color .3s var(--n-bezier)"})]),re=Object.assign(Object.assign({},C.props),{title:String,showIcon:{type:Boolean,default:!0},type:{type:String,default:"default"},bordered:{type:Boolean,default:!0},closable:Boolean,onClose:Function,onAfterLeave:Function,onAfterHide:Function}),ie=F({name:"Alert",inheritAttrs:!1,props:re,slots:Object,setup(n){const{mergedClsPrefixRef:e,mergedBorderedRef:l,inlineThemeDisabled:g,mergedRtlRef:v}=D(n),h=C("Alert","-alert",oe,J,n,e),z=G("Alert",v,e),b=p(()=>{const{common:{cubicBezierEaseInOut:a},self:o}=h.value,{fontSize:y,borderRadius:R,titleFontWeight:A,lineHeight:I,iconSize:$,iconMargin:m,iconMarginRtl:w,closeIconSize:B,closeBorderRadius:P,closeSize:T,closeMargin:_,closeMarginRtl:S,padding:k}=o,{type:s}=n,{left:E,right:L}=K(m);return{"--n-bezier":a,"--n-color":o[i("color",s)],"--n-close-icon-size":B,"--n-close-border-radius":P,"--n-close-color-hover":o[i("closeColorHover",s)],"--n-close-color-pressed":o[i("closeColorPressed",s)],"--n-close-icon-color":o[i("closeIconColor",s)],"--n-close-icon-color-hover":o[i("closeIconColorHover",s)],"--n-close-icon-color-pressed":o[i("closeIconColorPressed",s)],"--n-icon-color":o[i("iconColor",s)],"--n-border":o[i("border",s)],"--n-title-text-color":o[i("titleTextColor",s)],"--n-content-text-color":o[i("contentTextColor",s)],"--n-line-height":I,"--n-border-radius":R,"--n-font-size":y,"--n-title-font-weight":A,"--n-icon-size":$,"--n-icon-margin":m,"--n-icon-margin-rtl":w,"--n-close-size":T,"--n-close-margin":_,"--n-close-margin-rtl":S,"--n-padding":k,"--n-icon-margin-left":E,"--n-icon-margin-right":L}}),c=g?Q("alert",p(()=>n.type[0]),b,n):void 0,f=q(!0),x=()=>{const{onAfterLeave:a,onAfterHide:o}=n;a&&a(),o&&o()};return{rtlEnabled:z,mergedClsPrefix:e,mergedBordered:l,visible:f,handleCloseClick:()=>{var a;Promise.resolve((a=n.onClose)===null||a===void 0?void 0:a.call(n)).then(o=>{o!==!1&&(f.value=!1)})},handleAfterLeave:()=>{x()},mergedTheme:h,cssVars:g?void 0:b,themeClass:c?.themeClass,onRender:c?.onRender}},render(){var n;return(n=this.onRender)===null||n===void 0||n.call(this),r(W,{onAfterLeave:this.handleAfterLeave},{default:()=>{const{mergedClsPrefix:e,$slots:l}=this,g={class:[`${e}-alert`,this.themeClass,this.closable&&`${e}-alert--closable`,this.showIcon&&`${e}-alert--show-icon`,!this.title&&this.closable&&`${e}-alert--right-adjust`,this.rtlEnabled&&`${e}-alert--rtl`],style:this.cssVars,role:"alert"};return this.visible?r("div",Object.assign({},M(this.$attrs,g)),this.closable&&r(N,{clsPrefix:e,class:`${e}-alert__close`,onClick:this.handleCloseClick}),this.bordered&&r("div",{class:`${e}-alert__border`}),this.showIcon&&r("div",{class:`${e}-alert__icon`,"aria-hidden":"true"},O(l.icon,()=>[r(U,{clsPrefix:e},{default:()=>{switch(this.type){case"success":return r(ee,null);case"info":return r(Z,null);case"warning":return r(Y,null);case"error":return r(X,null);default:return null}}})])),r("div",{class:[`${e}-alert-body`,this.mergedBordered&&`${e}-alert-body--bordered`]},V(l.header,v=>{const h=v||this.title;return h?r("div",{class:`${e}-alert-body__title`},h):null}),l.default&&r("div",{class:`${e}-alert-body__content`},l))):null}})}});export{ie as N};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.page[data-v-60b8424c]{display:flex;flex-direction:column;gap:16px}.page-header[data-v-60b8424c]{display:flex;flex-direction:column;gap:4px}.eyebrow[data-v-60b8424c]{text-transform:uppercase;letter-spacing:.4px;font-size:12px;margin:0;color:var(--muted)}.small[data-v-60b8424c]{font-size:12px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as V,k as $,l as G,u as I,j as P,c as j,n as A,a as w,e as c,s,y as k,b as E,v as r,t as e,w as a,F as L,x as M,K as q,N as y,U as B,L as D,V as C,I as f,J as d,W as H,H as J,X as K,o as h,_ as T}from"./index-BCipBsn9.js";import{G as U}from"./PhPushPinSimple.vue-DBP-0k94.js";import{u as W}from"./favorites-CJMYgFyA.js";import{N as x}from"./Alert-C0caXY3O.js";import{N as X,a as O}from"./Grid-B_OzHEym.js";const Q={class:"page"},R={class:"page-header"},Y={class:"eyebrow"},Z={class:"text-muted"},ee={class:"card-title"},te={class:"text-muted small"},se=V({__name:"BoxesView",setup(ae){const m=$(),u=G(),i=W(),p=I(),{t:n}=P(),_=j(()=>m.token||m.payload?.token||null);async function z(){!m.payload&&!m.loading&&await m.bootstrap(),!u.items.length&&!u.loading&&await u.load(_.value),u.items.length&&i.hydrateFromBoxes(u.items)}function v(o,l){u.setBoxes(u.items.map(t=>t.name===o?{...t,...l}:t))}async function F(o){const l=await i.setPinned(o,_.value);if(i.error){p.error(i.error);return}v(o,{pinned:l}),p.success(n(l?"boxes.pinned":"boxes.unpinned"))}async function S(o,l){const t=!i.isFavorite(o,l),N=await i.setFavorite(o,l,t,_.value);if(i.error){p.error(i.error);return}const g=await i.loadBox(o,_.value);g?v(o,{favorites:g.favorites,pinned:g.pinned}):v(o,{favorites:Array.from(i.favoritesForBox(o).values())}),p.success(n(N?"boxes.favorited":"boxes.unfavorited"))}async function b(o){const l=await K(o,_.value);p.info(n("boxes.status_info",{status:l.status,latency:String(l.latency_ms||0)}))}return A(async()=>{await z()}),(o,l)=>(h(),w("div",Q,[c("header",R,[c("div",null,[c("p",Y,r(e(n)("boxes.title")),1),c("h1",null,r(e(n)("boxes.subtitle")),1),c("p",Z,r(e(n)("boxes.description")),1)])]),s(e(X),{"x-gap":12,"y-gap":12,cols:3},{default:a(()=>[(h(!0),w(L,null,M(e(u).items,t=>(h(),k(e(O),{key:t.name},{default:a(()=>[s(e(q),{class:"surface-card",size:"small"},{default:a(()=>[c("div",ee,[s(e(y),{size:"16"},{default:a(()=>[s(e(B),{weight:"duotone"})]),_:1}),c("span",null,r(e(D)(t.name))+" "+r(t.name),1)]),c("p",te,r(t.host)+" • "+r(t.transport),1),s(e(C),{size:"small",style:{"margin-bottom":"8px"}},{default:a(()=>[s(e(f),{size:"tiny",type:"primary",onClick:()=>o.$router.push(`/files?box=${t.name}`)},{default:a(()=>[s(e(y),{size:"14"},{default:a(()=>[s(e(B),{weight:"duotone"})]),_:1}),d(" "+r(e(n)("boxes.files")),1)]),_:1},8,["onClick"]),s(e(f),{size:"tiny",type:"primary",onClick:()=>o.$router.push(`/terminal?box=${t.name}`)},{default:a(()=>[s(e(y),{size:"14"},{default:a(()=>[s(e(H),{weight:"duotone"})]),_:1}),d(" "+r(e(n)("boxes.terminal")),1)]),_:1},8,["onClick"]),s(e(f),{size:"tiny",onClick:()=>o.$router.push(`/multi-terminal?box=${t.name}`)},{default:a(()=>[d(r(e(n)("boxes.multi")),1)]),_:1},8,["onClick"])]),_:2},1024),s(e(C),{size:"small"},{default:a(()=>[s(e(f),{size:"tiny",secondary:"",onClick:()=>F(t.name)},{default:a(()=>[s(e(y),{size:"14"},{default:a(()=>[s(e(U),{weight:"duotone"})]),_:1}),d(" "+r(e(i).isPinned(t.name)?e(n)("boxes.unpin"):e(n)("boxes.pin")),1)]),_:2},1032,["onClick"]),s(e(f),{size:"tiny",secondary:"",onClick:()=>S(t.name,t.default_dir||"/")},{default:a(()=>[s(e(y),{size:"14"},{default:a(()=>[s(e(J),{weight:"duotone"})]),_:1}),d(" "+r(e(i).isFavorite(t.name,t.default_dir||"/")?e(n)("boxes.unfavorite"):e(n)("boxes.favorite")),1)]),_:2},1032,["onClick"]),s(e(f),{size:"tiny",quaternary:"",onClick:()=>b(t.name)},{default:a(()=>[d(r(e(n)("common.status")),1)]),_:1},8,["onClick"])]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1}),e(u).error?(h(),k(e(x),{key:0,type:"error",closable:""},{default:a(()=>[d(r(e(u).error),1)]),_:1})):e(i).error?(h(),k(e(x),{key:1,type:"error",closable:""},{default:a(()=>[d(r(e(i).error),1)]),_:1})):E("",!0)]))}}),ue=T(se,[["__scopeId","data-v-60b8424c"]]);export{ue as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.terminal-wrapper[data-v-24a9756b]{position:relative;width:100%;height:100%;min-width:0;min-height:0;display:flex;flex-direction:column;border-radius:14px;overflow:hidden;background:var(--surface);border:1px solid var(--stroke);box-shadow:0 2px 12px var(--shadow),0 1px 4px var(--shadow);transition:box-shadow .3s ease,border-color .3s ease}.terminal-wrapper[data-v-24a9756b]:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-bg),0 2px 12px var(--shadow)}.terminal-wrapper.has-activity[data-v-24a9756b]{border-color:var(--warning);box-shadow:0 0 0 2px var(--warning-bg),0 2px 12px var(--shadow)}.terminal-titlebar[data-v-24a9756b]{display:flex;align-items:center;justify-content:space-between;height:36px;padding:0 12px;background:var(--surface-variant);border-bottom:1px solid var(--stroke);-webkit-user-select:none;user-select:none;flex-shrink:0}.titlebar-left[data-v-24a9756b],.titlebar-right[data-v-24a9756b]{display:flex;align-items:center;gap:6px;min-width:80px}.titlebar-right[data-v-24a9756b]{justify-content:flex-end}.titlebar-center[data-v-24a9756b]{display:flex;align-items:center;gap:8px;flex:1;justify-content:center}.titlebar-text[data-v-24a9756b]{font-size:12px;font-weight:500;color:var(--muted);letter-spacing:.02em}.toolbar-group[data-v-24a9756b]{display:flex;align-items:center;gap:1px;border-radius:8px;overflow:hidden;padding:2px}.toolbar-yellow[data-v-24a9756b]{background:#fac8501a}.toolbar-purple[data-v-24a9756b]{background:#b482fa1a}.toolbar-red[data-v-24a9756b]{background:#fa64641a}.toolbar-btn[data-v-24a9756b]{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;border-radius:6px;background:transparent;cursor:pointer;transition:all .12s ease;color:inherit}.toolbar-yellow .toolbar-btn[data-v-24a9756b]{color:#fac850b3}.toolbar-yellow .toolbar-btn[data-v-24a9756b]:hover{background:#fac85033;color:#fac850}.toolbar-purple .toolbar-btn[data-v-24a9756b]{color:#b482fab3}.toolbar-purple .toolbar-btn[data-v-24a9756b]:hover{background:#b482fa33;color:#b482fa}.toolbar-red .toolbar-btn[data-v-24a9756b]{color:#fa6464b3}.toolbar-red .toolbar-btn[data-v-24a9756b]:hover{background:#fa646433;color:#fa6464}.toolbar-btn-danger[data-v-24a9756b]{opacity:.85}.toolbar-btn-danger[data-v-24a9756b]:hover{opacity:1}.toolbar-btn[data-v-24a9756b]:disabled{opacity:.3;cursor:default;pointer-events:none}.connection-indicator[data-v-24a9756b]{width:6px;height:6px;border-radius:50%;background:#ff5f56;margin-left:8px;transition:all .3s ease}.connection-indicator.connected[data-v-24a9756b]{background:#27c93f;animation:breathe-24a9756b 2s ease-in-out infinite}.connection-indicator.connecting[data-v-24a9756b]{background:#ffbd2e;animation:pulse-24a9756b 1s ease-in-out infinite}.snapshot-indicator[data-v-24a9756b]{width:6px;height:6px;border-radius:50%;margin-left:4px;transition:background 1s ease,box-shadow 1s ease}.terminal-titlebar-collapsed[data-v-24a9756b]{display:flex;align-items:center;gap:8px;height:20px;padding:0 12px;background:var(--surface-variant);border-bottom:1px solid var(--stroke);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s ease}.terminal-titlebar-collapsed[data-v-24a9756b]:hover{background:var(--surface-hover)}.terminal-titlebar-collapsed .connection-indicator[data-v-24a9756b]{width:6px;height:6px;margin-left:0}.collapsed-text[data-v-24a9756b]{font-size:11px;color:var(--muted)}.expand-hint[data-v-24a9756b]{font-size:10px;color:var(--muted);opacity:.6;margin-left:auto}.terminal-wrapper.is-fullscreen[data-v-24a9756b],.terminal-wrapper.is-fullscreen .terminal-titlebar[data-v-24a9756b]{border-radius:0}@keyframes breathe-24a9756b{0%,to{box-shadow:0 0 #27c93f66;transform:scale(1)}50%{box-shadow:0 0 0 4px #27c93f00;transform:scale(1.05)}}@keyframes pulse-24a9756b{0%,to{opacity:1}50%{opacity:.5}}.titlebar-btn[data-v-24a9756b]{display:flex;align-items:center;justify-content:center;width:26px;height:26px;border:none;border-radius:6px;background:transparent;color:var(--muted);cursor:pointer;transition:all .15s ease}.titlebar-btn[data-v-24a9756b]:hover{background:var(--hover-overlay);color:var(--text)}.titlebar-btn[data-v-24a9756b]:disabled{opacity:.3;cursor:default;pointer-events:none}.help-btn[data-v-24a9756b]{opacity:.5;margin-left:2px;border-left:1px solid var(--hover-overlay);padding-left:4px;border-radius:0 6px 6px 0}.help-btn[data-v-24a9756b]:hover{opacity:1}.mouse-btn[data-v-24a9756b]{position:relative}.mouse-status-dot[data-v-24a9756b]{position:absolute;bottom:3px;right:3px;width:5px;height:5px;border-radius:50%;transition:background .2s ease}.mouse-btn.mouse-on .mouse-status-dot[data-v-24a9756b]{background:#27c93f;box-shadow:0 0 4px #27c93f80}.mouse-btn.mouse-off .mouse-status-dot[data-v-24a9756b]{background:#ff5f56;box-shadow:0 0 4px #ff5f5680}.mouse-btn.mouse-on[data-v-24a9756b]{color:#27c93fb3}.mouse-btn.mouse-off[data-v-24a9756b]{color:#ff5f56b3}.mouse-btn.mouse-on[data-v-24a9756b]:hover{background:#27c93f26;color:#27c93f}.mouse-btn.mouse-off[data-v-24a9756b]:hover{background:#ff5f5626;color:#ff5f56}.terminal-container[data-v-24a9756b]{position:relative;flex:1;min-width:0;min-height:0;padding:8px 12px 12px;overflow:hidden}.terminal-container.no-titlebar[data-v-24a9756b]{border-radius:14px 14px 0 0}.scanlines[data-v-24a9756b]{position:absolute;inset:0;pointer-events:none;z-index:10;background:repeating-linear-gradient(0deg,rgba(0,0,0,.02) 0px,rgba(0,0,0,.02) 1px,transparent 1px,transparent 2px);mask-image:radial-gradient(ellipse 80% 80% at 50% 50%,black 60%,transparent 100%);-webkit-mask-image:radial-gradient(ellipse 80% 80% at 50% 50%,black 60%,transparent 100%)}.terminal[data-v-24a9756b]{width:100%;height:100%;min-width:0;min-height:0}.terminal[data-v-24a9756b] .xterm{width:100%!important;height:100%!important}.terminal[data-v-24a9756b] .xterm-viewport,.terminal[data-v-24a9756b] .xterm-screen{width:100%!important}.terminal[data-v-24a9756b] .xterm-rows{text-shadow:0 0 1px currentColor}.terminal[data-v-24a9756b] .xterm-selection,.terminal[data-v-24a9756b] .xterm-selection div{background:#53bdfa59!important}.terminal[data-v-24a9756b] .xterm-viewport::-webkit-scrollbar{width:8px}.terminal[data-v-24a9756b] .xterm-viewport::-webkit-scrollbar-track{background:transparent;border-radius:4px}.terminal[data-v-24a9756b] .xterm-viewport::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#ffffff1f,#ffffff14);border-radius:4px;border:2px solid transparent;background-clip:padding-box}.terminal[data-v-24a9756b] .xterm-viewport::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#fff3,#ffffff26)}.terminal[data-v-24a9756b] .xterm-viewport{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.1) transparent}.activity-line[data-v-24a9756b]{position:absolute;bottom:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,rgba(230,180,80,.3),transparent);opacity:0;transition:opacity .15s ease}.activity-line.active[data-v-24a9756b]{opacity:1;animation:line-glow-24a9756b .3s ease}@keyframes line-glow-24a9756b{0%{background:linear-gradient(90deg,transparent,rgba(230,180,80,.8),transparent)}to{background:linear-gradient(90deg,transparent,rgba(230,180,80,.3),transparent)}}.terminal-overlay[data-v-24a9756b]{position:absolute;inset:0;background:var(--panel-bg-translucent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;color:var(--muted);font-family:"Monaspace Neon",var(--font-mono);z-index:20}.connecting-indicator[data-v-24a9756b],.disconnected-indicator[data-v-24a9756b]{display:flex;flex-direction:column;align-items:center;gap:12px}.connecting-indicator small[data-v-24a9756b]{display:block;font-size:12px;opacity:.7;margin-top:4px}.spinner[data-v-24a9756b]{width:24px;height:24px;border:2px solid rgba(230,180,80,.2);border-top:2px solid #e6b450;border-radius:50%;animation:spin-24a9756b 1s linear infinite}.reconnect-btn[data-v-24a9756b]{padding:8px 16px;background:#53bdfa26;color:#53bdfa;border:1px solid rgba(83,189,250,.3);border-radius:6px;cursor:pointer;font-size:14px;font-family:inherit;transition:all .2s ease}.reconnect-btn[data-v-24a9756b]:hover{background:#53bdfa40;border-color:#53bdfa80;box-shadow:0 0 20px #53bdfa26}@keyframes spin-24a9756b{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:768px){.terminal-wrapper[data-v-24a9756b]{border-radius:0;border:none;box-shadow:none;background:var(--panel-bg)}.terminal-wrapper[data-v-24a9756b]:focus-within{border-color:transparent;box-shadow:none}.terminal-titlebar[data-v-24a9756b]{height:28px;padding:0 6px}.titlebar-text[data-v-24a9756b]{font-size:10px}.toolbar-group[data-v-24a9756b]{display:none}.titlebar-btn[data-v-24a9756b]{width:28px;height:28px}.titlebar-right .titlebar-btn[data-v-24a9756b]:nth-child(2),.titlebar-right .titlebar-btn[data-v-24a9756b]:nth-child(3){display:none}.terminal-container[data-v-24a9756b]{padding:2px 2px 0}.terminal[data-v-24a9756b] .xterm-rows{text-shadow:none}.scanlines[data-v-24a9756b]{display:none}.terminal[data-v-24a9756b] .xterm-viewport{touch-action:pan-y pinch-zoom}.terminal[data-v-24a9756b] .xterm-screen{touch-action:pan-y}.terminal[data-v-24a9756b] .xterm-viewport::-webkit-scrollbar{width:0}.terminal[data-v-24a9756b] .xterm-viewport{scrollbar-width:none}}@media(prefers-contrast:high){.terminal-wrapper[data-v-24a9756b]{border:2px solid var(--stroke)}.scanlines[data-v-24a9756b]{display:none}}@media(prefers-reduced-motion:reduce){.spinner[data-v-24a9756b],.connection-indicator.connected[data-v-24a9756b],.connection-indicator.connecting[data-v-24a9756b],.activity-line.active[data-v-24a9756b]{animation:none}.terminal-wrapper[data-v-24a9756b],.terminal-wrapper[data-v-24a9756b]:focus-within,.terminal-wrapper.has-activity[data-v-24a9756b]{transition:none}}.terminal-search-bar[data-v-24a9756b]{position:absolute;top:0;right:8px;display:flex;align-items:center;gap:4px;padding:4px 8px;background:var(--surface, #1e1e2e);border:1px solid var(--stroke, rgba(255, 255, 255, .1));border-top:none;border-radius:0 0 6px 6px;z-index:20;box-shadow:0 2px 8px #0000004d}.search-input[data-v-24a9756b]{flex:1;padding:4px 8px;font-size:13px;font-family:var(--font-mono);background:var(--surface-variant, rgba(255, 255, 255, .05));border:1px solid var(--stroke, rgba(255, 255, 255, .15));border-radius:4px;color:var(--text, #cdd6f4);outline:none}.search-input[data-v-24a9756b]:focus{border-color:var(--accent, #7c5dff)}.search-input.no-match[data-v-24a9756b]{border-color:#e88080;background:#e880801a}.search-no-match[data-v-24a9756b]{font-size:11px;color:#e88080;white-space:nowrap}.search-btn[data-v-24a9756b]{display:flex;align-items:center;justify-content:center;width:28px;height:28px;background:none;border:none;border-radius:4px;color:var(--muted, #888);cursor:pointer}.search-btn[data-v-24a9756b]:hover{background:var(--hover-overlay, rgba(255, 255, 255, .08));color:var(--text, #cdd6f4)}.titlebar-btn.active[data-v-24a9756b]{color:var(--accent, #7c5dff);background:var(--accent-bg, rgba(124, 93, 255, .15))}[data-theme=light] .scanlines{display:none}[data-theme=light] .terminal .xterm-rows{text-shadow:none}[data-theme=light] .terminal-wrapper{box-shadow:0 2px 12px #0000001a,0 1px 4px #0000000f}[data-theme=light] .terminal .xterm-viewport{scrollbar-color:rgba(0,0,0,.15) transparent}[data-theme=light] .terminal .xterm-viewport::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#0000001f,#00000014)}[data-theme=light] .terminal .xterm-viewport::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#0003,#00000026)}.directory-picker[data-v-8a2864f1]{display:flex;flex-direction:column;gap:16px}.nav-bar[data-v-8a2864f1]{display:flex;align-items:center;gap:8px;padding:8px;background:var(--surface);border-radius:6px}.current-path[data-v-8a2864f1]{flex:1;font-family:var(--font-mono);font-size:13px;padding:4px 8px;background:var(--bg);border-radius:4px;cursor:text;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.favorites-section[data-v-8a2864f1]{padding:8px;background:#faad141a;border-radius:6px;border:1px solid rgba(250,173,20,.2)}.section-label[data-v-8a2864f1]{font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin-bottom:8px}.favorites-list[data-v-8a2864f1]{display:flex;flex-direction:column;gap:4px}.favorite-item[data-v-8a2864f1]{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;cursor:pointer;transition:background .15s ease}.favorite-item[data-v-8a2864f1]:hover{background:#faad1426}.fav-path[data-v-8a2864f1]{font-family:var(--font-mono);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.directory-list[data-v-8a2864f1]{max-height:300px;overflow-y:auto;border:1px solid var(--stroke);border-radius:6px}.loading-state[data-v-8a2864f1]{display:flex;justify-content:center;padding:32px}.directory-item[data-v-8a2864f1]{display:flex;align-items:center;gap:8px;padding:10px 12px;cursor:pointer;transition:background .15s ease;border-bottom:1px solid var(--stroke)}.directory-item[data-v-8a2864f1]:last-child{border-bottom:none}.directory-item[data-v-8a2864f1]:hover{background:var(--surface)}.folder-icon[data-v-8a2864f1]{color:var(--accent);flex-shrink:0}.dir-name[data-v-8a2864f1]{flex:1;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.star-btn[data-v-8a2864f1]{opacity:0;transition:opacity .15s ease}.directory-item:hover .star-btn[data-v-8a2864f1]{opacity:1}@media(hover:none)and (pointer:coarse){.star-btn[data-v-8a2864f1]{opacity:1}.directory-item[data-v-8a2864f1]{padding:14px 12px;min-height:48px}.favorite-item[data-v-8a2864f1]{padding:10px 8px;min-height:48px}}.footer-actions[data-v-8a2864f1]{display:flex;justify-content:flex-end;gap:8px;padding-top:8px;border-top:1px solid var(--stroke)}
|