ptn 0.3.2__py3-none-any.whl → 0.4.2__py3-none-any.whl

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 (38) hide show
  1. porterminal/_version.py +2 -2
  2. porterminal/application/services/management_service.py +28 -52
  3. porterminal/application/services/session_service.py +3 -11
  4. porterminal/application/services/terminal_service.py +97 -56
  5. porterminal/cli/args.py +39 -31
  6. porterminal/cli/display.py +18 -16
  7. porterminal/cli/script_discovery.py +112 -0
  8. porterminal/composition.py +2 -7
  9. porterminal/config.py +4 -2
  10. porterminal/domain/__init__.py +0 -9
  11. porterminal/domain/entities/output_buffer.py +56 -1
  12. porterminal/domain/entities/tab.py +11 -10
  13. porterminal/domain/services/__init__.py +0 -2
  14. porterminal/domain/values/__init__.py +0 -4
  15. porterminal/domain/values/environment_rules.py +3 -0
  16. porterminal/infrastructure/cloudflared.py +13 -11
  17. porterminal/infrastructure/config/shell_detector.py +86 -20
  18. porterminal/infrastructure/repositories/in_memory_session.py +1 -4
  19. porterminal/infrastructure/repositories/in_memory_tab.py +2 -10
  20. porterminal/pty/env.py +16 -78
  21. porterminal/pty/manager.py +6 -4
  22. porterminal/static/assets/app-DlWNJWFE.js +87 -0
  23. porterminal/static/assets/app-xPAM7YhQ.css +1 -0
  24. porterminal/static/index.html +2 -2
  25. porterminal/updater.py +13 -5
  26. {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/METADATA +54 -16
  27. {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/RECORD +30 -35
  28. porterminal/static/assets/app-BkHv5qu0.css +0 -32
  29. porterminal/static/assets/app-CaIGfw7i.js +0 -72
  30. porterminal/static/assets/app-D9ELFbEO.js +0 -72
  31. porterminal/static/assets/app-DF3nl_io.js +0 -72
  32. porterminal/static/assets/app-DQePboVd.css +0 -32
  33. porterminal/static/assets/app-DoBiVkTD.js +0 -72
  34. porterminal/static/assets/app-azbHOsRw.css +0 -32
  35. porterminal/static/assets/app-nMNFwMa6.css +0 -32
  36. {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/WHEEL +0 -0
  37. {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/entry_points.txt +0 -0
  38. {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/licenses/LICENSE +0 -0
@@ -44,16 +44,8 @@ class InMemoryTabRepository(TabRepository):
44
44
  session_id = str(tab.session_id)
45
45
 
46
46
  self._tabs[tab_id] = tab
47
-
48
- # Index by user
49
- if user_id not in self._user_tabs:
50
- self._user_tabs[user_id] = set()
51
- self._user_tabs[user_id].add(tab_id)
52
-
53
- # Index by session
54
- if session_id not in self._session_tabs:
55
- self._session_tabs[session_id] = set()
56
- self._session_tabs[session_id].add(tab_id)
47
+ self._user_tabs.setdefault(user_id, set()).add(tab_id)
48
+ self._session_tabs.setdefault(session_id, set()).add(tab_id)
57
49
 
58
50
  def update(self, tab: Tab) -> None:
59
51
  """Update an existing tab (name, last_accessed)."""
porterminal/pty/env.py CHANGED
@@ -1,94 +1,32 @@
1
- """Environment variable sanitization for PTY processes."""
1
+ """Environment variable sanitization for PTY processes.
2
+
3
+ This module re-exports the environment rules from the domain layer
4
+ and provides the build_safe_environment() function for PTY spawning.
5
+ """
2
6
 
3
7
  import os
4
8
 
5
- # Environment variables to allowlist (safe to pass to shell)
6
- SAFE_ENV_VARS: frozenset[str] = frozenset(
7
- {
8
- # System paths
9
- "PATH",
10
- "PATHEXT",
11
- "SYSTEMROOT",
12
- "WINDIR",
13
- "TEMP",
14
- "TMP",
15
- "COMSPEC",
16
- # User directories
17
- "HOME",
18
- "USERPROFILE",
19
- "HOMEDRIVE",
20
- "HOMEPATH",
21
- "LOCALAPPDATA",
22
- "APPDATA",
23
- "PROGRAMFILES",
24
- "PROGRAMFILES(X86)",
25
- "COMMONPROGRAMFILES",
26
- # System info
27
- "COMPUTERNAME",
28
- "USERNAME",
29
- "USERDOMAIN",
30
- "OS",
31
- "PROCESSOR_ARCHITECTURE",
32
- "NUMBER_OF_PROCESSORS",
33
- # Terminal
34
- "TERM",
35
- # Locale settings for proper text rendering
36
- "LANG",
37
- "LC_ALL",
38
- "LC_CTYPE",
39
- }
9
+ from porterminal.domain.values.environment_rules import (
10
+ DEFAULT_BLOCKED_VARS as BLOCKED_ENV_VARS,
40
11
  )
41
-
42
- # Environment variables to explicitly block (secrets)
43
- BLOCKED_ENV_VARS: frozenset[str] = frozenset(
44
- {
45
- # AWS
46
- "AWS_ACCESS_KEY_ID",
47
- "AWS_SECRET_ACCESS_KEY",
48
- "AWS_SESSION_TOKEN",
49
- # Azure
50
- "AZURE_CLIENT_SECRET",
51
- "AZURE_CLIENT_ID",
52
- # Git/GitHub/GitLab
53
- "GH_TOKEN",
54
- "GITHUB_TOKEN",
55
- "GITLAB_TOKEN",
56
- # Package managers
57
- "NPM_TOKEN",
58
- # AI APIs
59
- "ANTHROPIC_API_KEY",
60
- "OPENAI_API_KEY",
61
- "GOOGLE_API_KEY",
62
- # Payment
63
- "STRIPE_SECRET_KEY",
64
- # Database
65
- "DATABASE_URL",
66
- "DB_PASSWORD",
67
- # Generic secrets
68
- "SECRET_KEY",
69
- "API_KEY",
70
- "API_SECRET",
71
- "PRIVATE_KEY",
72
- }
12
+ from porterminal.domain.values.environment_rules import (
13
+ DEFAULT_SAFE_VARS as SAFE_ENV_VARS,
73
14
  )
74
15
 
16
+ # Re-export for backward compatibility
17
+ __all__ = ["SAFE_ENV_VARS", "BLOCKED_ENV_VARS", "build_safe_environment"]
18
+
75
19
 
76
20
  def build_safe_environment() -> dict[str, str]:
77
21
  """Build a sanitized environment for the PTY.
78
22
 
23
+ Uses allowlist approach - only SAFE_ENV_VARS are copied,
24
+ so BLOCKED_ENV_VARS can never be included.
25
+
79
26
  Returns:
80
27
  Dictionary of safe environment variables.
81
28
  """
82
- safe_env: dict[str, str] = {}
83
-
84
- # Copy only allowed variables
85
- for var in SAFE_ENV_VARS:
86
- if var in os.environ:
87
- safe_env[var] = os.environ[var]
88
-
89
- # Ensure blocked vars are not included (defense in depth)
90
- for var in BLOCKED_ENV_VARS:
91
- safe_env.pop(var, None)
29
+ safe_env = {var: os.environ[var] for var in SAFE_ENV_VARS if var in os.environ}
92
30
 
93
31
  # Set custom variables for audit trail
94
32
  safe_env["TERM"] = "xterm-256color"
@@ -5,6 +5,8 @@ import shutil
5
5
  from pathlib import Path
6
6
  from typing import TYPE_CHECKING
7
7
 
8
+ from porterminal.domain.values import MAX_COLS, MAX_ROWS, MIN_COLS, MIN_ROWS
9
+
8
10
  from .env import build_safe_environment
9
11
  from .protocol import PTYBackend
10
12
 
@@ -43,8 +45,8 @@ class SecurePTYManager:
43
45
  """
44
46
  self._backend = backend
45
47
  self.shell_config = shell_config
46
- self.cols = max(40, min(cols, 500))
47
- self.rows = max(10, min(rows, 200))
48
+ self.cols = max(MIN_COLS, min(cols, MAX_COLS))
49
+ self.rows = max(MIN_ROWS, min(rows, MAX_ROWS))
48
50
  self.cwd = cwd
49
51
  self._closed = False
50
52
 
@@ -133,8 +135,8 @@ class SecurePTYManager:
133
135
  if self._closed:
134
136
  return
135
137
 
136
- cols = max(40, min(cols, 500))
137
- rows = max(10, min(rows, 200))
138
+ cols = max(MIN_COLS, min(cols, MAX_COLS))
139
+ rows = max(MIN_ROWS, min(rows, MAX_ROWS))
138
140
 
139
141
  try:
140
142
  self._backend.resize(rows, cols)