nimbie-shell 0.0.1.dev0__tar.gz → 0.0.2.dev0__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.
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/PKG-INFO +3 -2
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/pyproject.toml +3 -4
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/browser_gateway.py +1 -1
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/shared/remote_shell_support.py +74 -11
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/v2/repl_app.py +4 -85
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/v3/repl_app.py +1 -3
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/README.md +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/__init__.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/cli.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/command_policy.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/config.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/model.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/summary_entry.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/system.md +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/system_prompt.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/__init__.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/__init__.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/file_patcher.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/selection_prompt.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/set_result.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/shell_runner.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/tool_runtime.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/gateway_textual.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/incremental_markdown.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/process_overview_textual.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/selection_panel_textual.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/session_history_inspector_textual.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/streaming_tail.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/terminal_markdown.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/v2/output_hub.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/v2/renderer.py +0 -0
- {nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/v2/slash_commands.py +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nimbie-shell
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2.dev0
|
|
4
4
|
Summary: Lightweight agent loop and context manager (standalone)
|
|
5
5
|
Requires-Dist: click>=8.1.7
|
|
6
6
|
Requires-Dist: httpx[http2]>=0.28.1
|
|
7
7
|
Requires-Dist: litellm>=1.81.11
|
|
8
8
|
Requires-Dist: chronml>=0.1.0
|
|
9
|
-
Requires-Dist:
|
|
9
|
+
Requires-Dist: oturn>=0.1.0
|
|
10
|
+
Requires-Dist: nimbie-flash>=0.0.2.dev0
|
|
10
11
|
Requires-Dist: prompt-toolkit>=3.0.39
|
|
11
12
|
Requires-Dist: rich>=13.7.0
|
|
12
13
|
Requires-Dist: textual>=0.80.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nimbie-shell"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.2.dev0"
|
|
4
4
|
description = "Lightweight agent loop and context manager (standalone)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -9,7 +9,8 @@ dependencies = [
|
|
|
9
9
|
"httpx[http2]>=0.28.1",
|
|
10
10
|
"litellm>=1.81.11",
|
|
11
11
|
"chronml>=0.1.0",
|
|
12
|
-
"
|
|
12
|
+
"oturn>=0.1.0",
|
|
13
|
+
"nimbie_flash>=0.0.2.dev0",
|
|
13
14
|
"prompt_toolkit>=3.0.39",
|
|
14
15
|
"rich>=13.7.0",
|
|
15
16
|
"textual>=0.80.0",
|
|
@@ -25,9 +26,7 @@ build-backend = "uv_build"
|
|
|
25
26
|
[tool.uv.build-backend]
|
|
26
27
|
module-name = "nimbie"
|
|
27
28
|
source-exclude = [
|
|
28
|
-
"**/.cyf/**",
|
|
29
29
|
"**/.nimbie/**",
|
|
30
|
-
"src/nimbie/.cyf/**",
|
|
31
30
|
"src/nimbie/.nimbie/**",
|
|
32
31
|
"src/nimbie/**/__pycache__/**",
|
|
33
32
|
"src/nimbie/**/*.pyc",
|
|
@@ -215,7 +215,7 @@ class BrowserGatewayServer:
|
|
|
215
215
|
self.work_dir = work_dir
|
|
216
216
|
self._repo_root = Path(__file__).resolve().parents[2]
|
|
217
217
|
self._frontend_root = self._repo_root / "frontend-app"
|
|
218
|
-
self.token = token or os.environ.get("
|
|
218
|
+
self.token = token or os.environ.get("NIMBIE_WEB_TOKEN") or f"t_{random.randint(100000, 999999)}"
|
|
219
219
|
self.port = _pick_free_port(8413, 8419)
|
|
220
220
|
self.vite_port = _pick_free_port(5173, 5183)
|
|
221
221
|
self._app = FastAPI()
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/shared/remote_shell_support.py
RENAMED
|
@@ -46,16 +46,17 @@ class RemoteShellSupport:
|
|
|
46
46
|
self._prompt_build_executor = ThreadPoolExecutor(max_workers=1)
|
|
47
47
|
self._prompt_env_cache: Dict[str, str] = {}
|
|
48
48
|
self._prompt_env_cache_backend: str = ''
|
|
49
|
+
self._flash_executor_kind: Optional[str] = None
|
|
49
50
|
|
|
50
51
|
def set_output_sink(self, sink) -> None:
|
|
51
52
|
self._output_sink = sink
|
|
52
53
|
|
|
53
54
|
def _executor_debug_enabled(self) -> bool:
|
|
54
|
-
v = str(os.getenv('
|
|
55
|
+
v = str(os.getenv('NIMBIE_EXECUTOR_DEBUG', '')).strip().lower()
|
|
55
56
|
return v in {'1', 'true', 'yes', 'on'}
|
|
56
57
|
|
|
57
58
|
def _executor_debug_verbose(self) -> bool:
|
|
58
|
-
v = str(os.getenv('
|
|
59
|
+
v = str(os.getenv('NIMBIE_EXECUTOR_DEBUG_VERBOSE', '')).strip().lower()
|
|
59
60
|
return v in {'1', 'true', 'yes', 'on'}
|
|
60
61
|
|
|
61
62
|
def _emit_executor_debug(self, msg: str) -> None:
|
|
@@ -88,9 +89,7 @@ class RemoteShellSupport:
|
|
|
88
89
|
except Exception as e:
|
|
89
90
|
raise RuntimeError(f'failed to import nimbie_flash for prompt rendering: {e}') from e
|
|
90
91
|
self._sync_flash_backend_env()
|
|
91
|
-
|
|
92
|
-
self._flash_executor = flash.LocalExecutor()
|
|
93
|
-
executor = self._flash_executor
|
|
92
|
+
executor = self._ensure_flash_executor(flash, remote=(self._build_remote_ssh_command() is not None))
|
|
94
93
|
if not hasattr(flash, 'build_prompt_from_env'):
|
|
95
94
|
raise RuntimeError('nimbie_flash.build_prompt_from_env is not available')
|
|
96
95
|
backend_key = str(self.remote_status_text() or 'local')
|
|
@@ -127,7 +126,7 @@ class RemoteShellSupport:
|
|
|
127
126
|
def build_prompt(self) -> str:
|
|
128
127
|
timeout_s = 3.0
|
|
129
128
|
try:
|
|
130
|
-
timeout_s = max(0.2, float(os.getenv('
|
|
129
|
+
timeout_s = max(0.2, float(os.getenv('NIMBIE_PROMPT_TIMEOUT_S', '3')))
|
|
131
130
|
except Exception:
|
|
132
131
|
timeout_s = 3.0
|
|
133
132
|
fut = self._prompt_build_executor.submit(self._build_prompt_impl)
|
|
@@ -187,9 +186,12 @@ class RemoteShellSupport:
|
|
|
187
186
|
seen.add(rp)
|
|
188
187
|
meta = self._executor_meta_from_path(pp)
|
|
189
188
|
out.append({'path': pp, 'source': source, 'meta': meta})
|
|
190
|
-
|
|
191
|
-
if
|
|
192
|
-
_add_candidate(Path(
|
|
189
|
+
local_override = os.getenv('NIMBIE_FLASH_STDIO_EXECUTOR_LOCAL_BIN', '').strip()
|
|
190
|
+
if local_override:
|
|
191
|
+
_add_candidate(Path(local_override), 'env:NIMBIE_FLASH_STDIO_EXECUTOR_LOCAL_BIN')
|
|
192
|
+
flash_override = os.getenv('FLASH_STDIO_EXECUTOR_LOCAL_BIN', '').strip()
|
|
193
|
+
if flash_override:
|
|
194
|
+
_add_candidate(Path(flash_override), 'env:FLASH_STDIO_EXECUTOR_LOCAL_BIN')
|
|
193
195
|
try:
|
|
194
196
|
import nimbie_flash
|
|
195
197
|
except Exception:
|
|
@@ -201,12 +203,12 @@ class RemoteShellSupport:
|
|
|
201
203
|
bundled = None
|
|
202
204
|
if bundled is not None:
|
|
203
205
|
_add_candidate(Path(bundled), 'python-package:nimbie_flash')
|
|
204
|
-
multi = os.getenv('
|
|
206
|
+
multi = os.getenv('FLASH_STDIO_EXECUTOR_CANDIDATES', '').strip()
|
|
205
207
|
if multi:
|
|
206
208
|
for item in multi.split(os.pathsep):
|
|
207
209
|
it = item.strip()
|
|
208
210
|
if it:
|
|
209
|
-
_add_candidate(Path(it), 'env:
|
|
211
|
+
_add_candidate(Path(it), 'env:FLASH_STDIO_EXECUTOR_CANDIDATES')
|
|
210
212
|
repo_root = Path(__file__).resolve().parents[4]
|
|
211
213
|
candidates = [repo_root / 'flash' / 'target' / 'x86_64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'x86_64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'aarch64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'aarch64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'x86_64-apple-darwin' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'aarch64-apple-darwin' / 'release' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'maturin' / 'flash-stdio-executor', repo_root / 'flash' / 'target' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'x86_64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'x86_64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'aarch64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'aarch64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'x86_64-apple-darwin' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'aarch64-apple-darwin' / 'release' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'maturin' / 'flash-stdio-executor', Path.cwd() / 'flash' / 'target' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'x86_64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'x86_64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'aarch64-unknown-linux-musl' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'aarch64-unknown-linux-gnu' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'x86_64-apple-darwin' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'aarch64-apple-darwin' / 'release' / 'flash-stdio-executor', Path.cwd() / 'target' / 'maturin' / 'flash-stdio-executor', Path.cwd() / 'target' / 'release' / 'flash-stdio-executor']
|
|
212
214
|
for c in candidates:
|
|
@@ -216,6 +218,52 @@ class RemoteShellSupport:
|
|
|
216
218
|
_add_candidate(Path(which), 'PATH')
|
|
217
219
|
return out
|
|
218
220
|
|
|
221
|
+
def _resolve_local_stdio_executor_binary(self) -> Tuple[Optional[str], Dict[str, Any]]:
|
|
222
|
+
info: Dict[str, Any] = {
|
|
223
|
+
'explicit_bin': os.getenv('FLASH_STDIO_EXECUTOR_BIN', '').strip(),
|
|
224
|
+
'nimbie_local_override': os.getenv('NIMBIE_FLASH_STDIO_EXECUTOR_LOCAL_BIN', '').strip(),
|
|
225
|
+
'flash_local_override': os.getenv('FLASH_STDIO_EXECUTOR_LOCAL_BIN', '').strip(),
|
|
226
|
+
'bundled_path': None,
|
|
227
|
+
'bundled_exists': False,
|
|
228
|
+
'bundled_executable': False,
|
|
229
|
+
'bundled_error': '',
|
|
230
|
+
'selected_source': '',
|
|
231
|
+
'candidates': [],
|
|
232
|
+
}
|
|
233
|
+
selected = info['explicit_bin'] or info['nimbie_local_override'] or info['flash_local_override']
|
|
234
|
+
if info['explicit_bin']:
|
|
235
|
+
info['selected_source'] = 'env:FLASH_STDIO_EXECUTOR_BIN'
|
|
236
|
+
elif info['nimbie_local_override']:
|
|
237
|
+
info['selected_source'] = 'env:NIMBIE_FLASH_STDIO_EXECUTOR_LOCAL_BIN'
|
|
238
|
+
elif info['flash_local_override']:
|
|
239
|
+
info['selected_source'] = 'env:FLASH_STDIO_EXECUTOR_LOCAL_BIN'
|
|
240
|
+
try:
|
|
241
|
+
import nimbie_flash
|
|
242
|
+
except Exception as e:
|
|
243
|
+
info['bundled_error'] = str(e)
|
|
244
|
+
nimbie_flash = None
|
|
245
|
+
if nimbie_flash is not None:
|
|
246
|
+
try:
|
|
247
|
+
bundled = nimbie_flash.bundled_stdio_executor_path()
|
|
248
|
+
except Exception as e:
|
|
249
|
+
bundled = None
|
|
250
|
+
info['bundled_error'] = str(e)
|
|
251
|
+
if bundled is not None:
|
|
252
|
+
bundled_path = Path(bundled)
|
|
253
|
+
info['bundled_path'] = str(bundled_path)
|
|
254
|
+
try:
|
|
255
|
+
info['bundled_exists'] = bundled_path.exists()
|
|
256
|
+
info['bundled_executable'] = os.access(bundled_path, os.X_OK)
|
|
257
|
+
except Exception:
|
|
258
|
+
info['bundled_exists'] = False
|
|
259
|
+
info['bundled_executable'] = False
|
|
260
|
+
if (not selected) and info['bundled_exists'] and info['bundled_executable']:
|
|
261
|
+
selected = str(bundled_path)
|
|
262
|
+
info['selected_source'] = 'python-package:nimbie_flash'
|
|
263
|
+
candidates = self._collect_local_stdio_executor_binaries()
|
|
264
|
+
info['candidates'] = [{'path': str(item.get('path')), 'source': str(item.get('source') or '')} for item in candidates]
|
|
265
|
+
return (str(selected) if selected else None, info)
|
|
266
|
+
|
|
219
267
|
def _rank_executor_candidates(self, candidates: List[Dict[str, Any]], *, remote_arch: str, remote_libc: str, remote_os: str, remote_glibc_version: str) -> List[Dict[str, Any]]:
|
|
220
268
|
|
|
221
269
|
def _parse_ver(v: str) -> Tuple[int, ...]:
|
|
@@ -348,6 +396,19 @@ class RemoteShellSupport:
|
|
|
348
396
|
os.environ.pop('FLASH_REMOTE_ENV_JSON', None)
|
|
349
397
|
os.environ['FLASH_DISABLE_BACKEND_IDENTITY_PROBE'] = '1'
|
|
350
398
|
|
|
399
|
+
def _ensure_flash_executor(self, flash: Any, *, remote: bool) -> Any:
|
|
400
|
+
want = 'stdio' if remote else 'local'
|
|
401
|
+
if self._flash_executor is not None and self._flash_executor_kind == want:
|
|
402
|
+
return self._flash_executor
|
|
403
|
+
if remote:
|
|
404
|
+
if not hasattr(flash, 'StdioExecutor'):
|
|
405
|
+
raise RuntimeError('nimbie_flash.StdioExecutor is not available')
|
|
406
|
+
self._flash_executor = flash.StdioExecutor()
|
|
407
|
+
else:
|
|
408
|
+
self._flash_executor = flash.LocalExecutor()
|
|
409
|
+
self._flash_executor_kind = want
|
|
410
|
+
return self._flash_executor
|
|
411
|
+
|
|
351
412
|
def disconnect_ssh(self) -> None:
|
|
352
413
|
self._emit_executor_debug('disconnect ssh backend')
|
|
353
414
|
self._remote_ssh_host = None
|
|
@@ -366,6 +427,7 @@ class RemoteShellSupport:
|
|
|
366
427
|
self._sync_flash_backend_env()
|
|
367
428
|
self._flash_interp = None
|
|
368
429
|
self._flash_executor = None
|
|
430
|
+
self._flash_executor_kind = None
|
|
369
431
|
self._prompt_env_cache = {}
|
|
370
432
|
self._prompt_env_cache_backend = ''
|
|
371
433
|
|
|
@@ -573,6 +635,7 @@ class RemoteShellSupport:
|
|
|
573
635
|
self._sync_flash_backend_env()
|
|
574
636
|
self._flash_interp = None
|
|
575
637
|
self._flash_executor = None
|
|
638
|
+
self._flash_executor_kind = None
|
|
576
639
|
self._prompt_env_cache = {}
|
|
577
640
|
self._prompt_env_cache_backend = ''
|
|
578
641
|
user_prefix = f'{user}@' if user else ''
|
|
@@ -631,14 +631,12 @@ class ShellAdapter(RemoteShellSupport):
|
|
|
631
631
|
import nimbie_flash as flash
|
|
632
632
|
if self._flash_interp is None:
|
|
633
633
|
self._flash_interp = flash.FlashInterpreter()
|
|
634
|
-
|
|
635
|
-
|
|
634
|
+
custom_env_builder = getattr(self, '_build_remote_ssh_command', None)
|
|
635
|
+
custom_env = custom_env_builder() if callable(custom_env_builder) else None
|
|
636
636
|
interp = self._flash_interp
|
|
637
|
-
executor = self.
|
|
637
|
+
executor = self._ensure_flash_executor(flash, remote=(custom_env is not None))
|
|
638
638
|
old_bin = os.environ.get('FLASH_STDIO_EXECUTOR_BIN')
|
|
639
639
|
old_args = os.environ.get('FLASH_STDIO_EXECUTOR_ARGS_JSON')
|
|
640
|
-
custom_env_builder = getattr(self, '_build_remote_ssh_command', None)
|
|
641
|
-
custom_env = custom_env_builder() if callable(custom_env_builder) else None
|
|
642
640
|
if custom_env is not None:
|
|
643
641
|
bin_name, args = custom_env
|
|
644
642
|
os.environ['FLASH_STDIO_EXECUTOR_BIN'] = bin_name
|
|
@@ -743,89 +741,10 @@ class ShellAdapter(RemoteShellSupport):
|
|
|
743
741
|
self._emit_executor_debug(f"stream event type={ev_type} bytes={len(data.encode('utf-8', errors='ignore'))}")
|
|
744
742
|
if data:
|
|
745
743
|
_emit_text(fix_surrogate(data))
|
|
746
|
-
direct_run_started = False
|
|
747
744
|
try:
|
|
748
|
-
result =
|
|
749
|
-
if proxy_stdin and hasattr(executor, 'start_run') and hasattr(executor, 'poll_event'):
|
|
750
|
-
try:
|
|
751
|
-
cwd = os.getcwd()
|
|
752
|
-
try:
|
|
753
|
-
cwd = str(getattr(interp, 'cwd', None) or cwd)
|
|
754
|
-
except Exception:
|
|
755
|
-
pass
|
|
756
|
-
active_run_id = str(executor.start_run(cmd, cwd))
|
|
757
|
-
direct_run_started = True
|
|
758
|
-
stdout_acc: list[str] = []
|
|
759
|
-
stderr_acc: list[str] = []
|
|
760
|
-
exit_code = 1
|
|
761
|
-
while True:
|
|
762
|
-
ev_line = executor.poll_event(0)
|
|
763
|
-
if ev_line is None:
|
|
764
|
-
if not bool(executor.is_running()):
|
|
765
|
-
for _ in range(5):
|
|
766
|
-
ev_line = executor.poll_event(20)
|
|
767
|
-
if ev_line is None:
|
|
768
|
-
continue
|
|
769
|
-
break
|
|
770
|
-
if ev_line is None:
|
|
771
|
-
break
|
|
772
|
-
else:
|
|
773
|
-
time.sleep(0.02)
|
|
774
|
-
continue
|
|
775
|
-
try:
|
|
776
|
-
ev_json = json.loads(str(ev_line))
|
|
777
|
-
except Exception:
|
|
778
|
-
ev_json = {'type': 'raw', 'data': str(ev_line)}
|
|
779
|
-
_on_event(ev_json)
|
|
780
|
-
ev_type = str(ev_json.get('type') or '')
|
|
781
|
-
if ev_type == 'stdout':
|
|
782
|
-
stdout_acc.append(str(ev_json.get('data') or ev_json.get('stdout') or ''))
|
|
783
|
-
elif ev_type == 'stderr':
|
|
784
|
-
stderr_acc.append(str(ev_json.get('data') or ev_json.get('stderr') or ''))
|
|
785
|
-
elif ev_type == 'exit':
|
|
786
|
-
try:
|
|
787
|
-
raw_exit = ev_json.get('exit_code')
|
|
788
|
-
exit_code = int(raw_exit) if raw_exit is not None else 1
|
|
789
|
-
except Exception:
|
|
790
|
-
exit_code = 1
|
|
791
|
-
break
|
|
792
|
-
else:
|
|
793
|
-
if ev_json.get('stdout'):
|
|
794
|
-
stdout_acc.append(str(ev_json.get('stdout') or ''))
|
|
795
|
-
if ev_json.get('stderr'):
|
|
796
|
-
stderr_acc.append(str(ev_json.get('stderr') or ''))
|
|
797
|
-
if ev_json.get('exit_code') is not None:
|
|
798
|
-
try:
|
|
799
|
-
raw_exit = ev_json.get('exit_code')
|
|
800
|
-
exit_code = int(raw_exit) if raw_exit is not None else 1
|
|
801
|
-
except Exception:
|
|
802
|
-
exit_code = 1
|
|
803
|
-
break
|
|
804
|
-
try:
|
|
805
|
-
executor.flush(active_run_id, 50)
|
|
806
|
-
except Exception:
|
|
807
|
-
pass
|
|
808
|
-
|
|
809
|
-
class _DirectResult:
|
|
810
|
-
|
|
811
|
-
def __init__(self, stdout: str, stderr: str, exit_code: int) -> None:
|
|
812
|
-
self.stdout = stdout
|
|
813
|
-
self.stderr = stderr
|
|
814
|
-
self.exit_code = exit_code
|
|
815
|
-
result = _DirectResult(''.join(stdout_acc), ''.join(stderr_acc), exit_code)
|
|
816
|
-
except Exception as direct_err:
|
|
817
|
-
self._emit_executor_debug(f'direct run fallback err={direct_err}')
|
|
818
|
-
direct_run_started = False
|
|
819
|
-
active_run_id = None
|
|
820
|
-
if result is None:
|
|
821
|
-
result = interp.run_shell_stream(cmd, executor, _on_event)
|
|
745
|
+
result = interp.run_shell_stream(cmd, executor, _on_event)
|
|
822
746
|
finally:
|
|
823
747
|
_cleanup_input_thread()
|
|
824
|
-
if direct_run_started and active_run_id is not None:
|
|
825
|
-
try:
|
|
826
|
-
executor.close_run()
|
|
827
|
-
except Exception:
|
|
828
|
-
pass
|
|
829
748
|
if old_bin is not None:
|
|
830
749
|
os.environ['FLASH_STDIO_EXECUTOR_BIN'] = old_bin
|
|
831
750
|
else:
|
|
@@ -697,11 +697,9 @@ class ShellAdapter(RemoteShellSupport):
|
|
|
697
697
|
import nimbie_flash as flash
|
|
698
698
|
if self._flash_interp is None:
|
|
699
699
|
self._flash_interp = flash.FlashInterpreter()
|
|
700
|
-
if self._flash_executor is None:
|
|
701
|
-
self._flash_executor = flash.LocalExecutor()
|
|
702
700
|
interp = self._flash_interp
|
|
703
|
-
executor = self._flash_executor
|
|
704
701
|
custom_env = self._build_remote_ssh_command()
|
|
702
|
+
executor = self._ensure_flash_executor(flash, remote=(custom_env is not None))
|
|
705
703
|
self._emit_executor_debug(f"backend_route={('remote' if custom_env is not None else 'local')}")
|
|
706
704
|
old_bin = os.environ.get('FLASH_STDIO_EXECUTOR_BIN')
|
|
707
705
|
old_args = os.environ.get('FLASH_STDIO_EXECUTOR_ARGS_JSON')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/file_patcher.py
RENAMED
|
File without changes
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/selection_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/tools/internal/shell_runner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/process_overview_textual.py
RENAMED
|
File without changes
|
{nimbie_shell-0.0.1.dev0 → nimbie_shell-0.0.2.dev0}/src/nimbie/ui/selection_panel_textual.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|