@ictechgy/lterm 1.0.24 → 1.0.26

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 (3) hide show
  1. package/README.ko.md +97 -30
  2. package/README.md +94 -27
  3. package/package.json +5 -5
package/README.ko.md CHANGED
@@ -7,7 +7,7 @@
7
7
  - **무엇** — tmux처럼 터미널 세션을 백그라운드에서 오래 유지하는 데몬이지만, 기능 범위를 더 작게 좁힌 도구입니다. AI 에이전트 도구를 위한 tmux 호환 명령 계층을 제공하며, 세션을 이름이나 pane id로 detach·reattach할 수 있습니다.
8
8
  - **대상** — Claude Code, Codex CLI, OpenCode, GitHub Copilot CLI, Cursor Agent, Antigravity/`agy`, Kiro, Jules, Aider, Goose, Amp, Crush, Kimi, Qwen, Gemini CLI, `oh-my-codex` / `oh-my-claude` 같은 terminal-first coding agent를 쓰는 사용자와, 이를 `cmux` 안에서 실행하는 사용자.
9
9
  - **사용법** — `lterm start`로 만들고 `lterm resume`으로 (재)접속합니다. shim이 적용된 agent 실행에는 `lterm agent <profile>` / `lterm claude` / `lterm codex` / `lterm opencode` / `lterm agy` / `lterm kiro` / `lterm gemini` 같은 내장 단축 명령을 사용할 수 있습니다. tmux가 켜진 세션 안에서는 `tmux` 명령이 `lterm tmux-compat`으로 해석됩니다.
10
- - **상태** — 1.0 명령/출력 호환성 경계를 문서화한 alpha MVP입니다. 같은 OS 사용자 안에서 쓰는 편의용 데몬이며, **샌드박스도, escape-sequence sanitizer도, 완전한 tmux 대체품도 아닙니다.**
10
+ - **상태** — 문서화된 1.0 명령/출력 호환성 경계를 따르는 1.x CLI입니다. 같은 OS 사용자 안에서 쓰는 편의용 데몬이며, **샌드박스도, escape-sequence sanitizer도, 완전한 tmux 대체품도 아닙니다.**
11
11
 
12
12
  ---
13
13
 
@@ -78,7 +78,7 @@ GitHub에서 Cargo로 설치할 때는 release tag를 고정하세요. 아래
78
78
  README 릴리스 기준이며, 더 최신 tag가 있는지는 Releases 페이지에서 확인하세요:
79
79
 
80
80
  ```bash
81
- cargo install --locked --git https://github.com/ictechgy/light_terminal --tag v1.0.24
81
+ cargo install --locked --git https://github.com/ictechgy/light_terminal --tag v1.0.26
82
82
  ```
83
83
 
84
84
  저장소를 클론한 뒤 직접 빌드하려면 Rust 1.85 이상이 필요합니다.
@@ -138,6 +138,7 @@ lterm -a api
138
138
  | tmux 호환을 켠 상태로 명령 실행 | `lterm run -- codex exec "요약해줘"` | 없음 (`--no-tmux`로 opt out) |
139
139
  | 세션 열기 또는 생성 | `lterm open main` | `attach-or-new` |
140
140
  | 기존 세션 재개 | `lterm resume api` | `attach`, `a`, `-a` |
141
+ | 마지막으로 선택한 세션에 재접속 | `lterm reconnect --mobile` | 없음 |
141
142
  | 모바일에서 agent 출력 확인 | `LTERM_MOBILE=1 lterm resume codex-lterm` | transcript 강제는 `--mobile`, 기존 raw attach 강제는 `--raw` |
142
143
  | 세션 목록 보기 | `lterm sessions` | `list`, `ls` |
143
144
  | 프로세스 트리 확인 | `lterm processes api --json --orphans` | `ps` |
@@ -154,6 +155,7 @@ lterm -a api
154
155
  | 세션 종료 | `lterm close api` | `kill` |
155
156
  | 데몬과 shim 상태 진단 | `lterm doctor --json` | `status` |
156
157
  | redacted 로컬 진단 bundle 수집 | `lterm diagnose --bundle` | 없음 |
158
+ | redacted 로컬 진단 inspect | `lterm inspect --json` | 없음 |
157
159
  | 로컬 설정 단계 미리 보기 | `lterm init --shell zsh` | 없음 |
158
160
  | 지원되는 AI CLI statusline badge 설치 | `lterm install-ai-statusline` | 없음 |
159
161
  | shell completion 설치 | `lterm install-completions --shell zsh` | 없음 |
@@ -211,13 +213,17 @@ row status 표시 여부는 attach mode와는 별개입니다. `--attach-mode=au
211
213
 
212
214
  `lterm status-theme <target> <theme>`(alias: `lterm theme`)은 PTY를 재시작하지 않고 세션별 status bar theme을 저장합니다. pane id를 지정하면 해당 pane이 속한 세션에 적용됩니다. `default`, `clear`, `none`을 쓰면 세션 override를 지우고 attach하는 client의 기본값으로 돌아갑니다. 이미 attach된 client는 detach 후 다시 attach할 때 새 색을 반영합니다. 새 세션은 `lterm start --status-theme green -n api -- npm run dev`(또는 alias `--status-color`)처럼 생성 시점에 같은 metadata를 저장할 수 있습니다.
213
215
 
214
- `lterm doctor`(호환 이름: `lterm status`)는 client/daemon version, protocol 호환성, runtime/data/socket/shim path, shim directory가 `PATH`에 있는지 등을 보고합니다. 이 명령은 daemon을 시작하지 않습니다. 현재 socket에서 호환 daemon이 응답하지 않으면 `daemon_reachable=no` / `false`로 표시됩니다. 일반 client 동작 중 접근 가능한 daemon이 다른 lterm 또는 protocol version을 보고하면 stderr에 경고를 출력하며, 보통 binary upgrade 뒤 예전 daemon이 살아 있는 상황을 뜻합니다.
216
+ `lterm doctor`(호환 이름: `lterm status`)는 client/daemon version, protocol 호환성, runtime/data/socket/shim path, shim directory가 `PATH`에 있는지, count와 boolean/null `tmux_compat` summary 등을 보고합니다. 현재 build는 `tmux_compat`를 출력하지만, stable schema는 binary upgrade 중 예전 doctor output도 validate되도록 additive/optional로 유지합니다. 이 명령은 daemon을 시작하지 않습니다. 현재 socket에서 호환 daemon이 응답하지 않으면 `daemon_reachable=no` / `false`로 표시됩니다. 일반 client 동작 중 접근 가능한 daemon이 다른 lterm 또는 protocol version을 보고하면 stderr에 경고를 출력하며, 보통 binary upgrade 뒤 예전 daemon이 살아 있는 상황을 뜻합니다.
215
217
 
216
218
  `lterm diagnose --bundle`은 issue 보고와 agent handoff를 위한 local-only JSON
217
219
  진단 bundle을 출력합니다. `doctor` 데이터와 redact된 환경 변수 presence flag를
218
220
  포함하고, 기존 daemon에 접근 가능한 경우에 한해 세션 metadata와 process row를
219
221
  함께 담습니다. 이 명령은 daemon을 시작하지 않으며, 기본적으로 raw PTY bytes나
220
- scrollback은 포함하지 않습니다.
222
+ scrollback은 포함하지 않습니다. inspect-style JSON entrypoint가 필요한 도구는
223
+ 같은 redacted bundle을 출력하는 `lterm inspect --json`을 사용할 수 있으며,
224
+ `--json`이 필수입니다.
225
+
226
+ Opt-in local footprint 측정은 `python3 scripts/footprint_benchmark.py --quick --json target/footprint-baseline.json --markdown target/footprint-baseline.md`로 실행합니다. 격리된 lterm-vs-tmux 측정 방법과 해석 caveat는 [`docs/footprint-benchmark.md`](docs/footprint-benchmark.md)를 참고하세요.
221
227
 
222
228
  `lterm logs <target>`은 `--start` / `-S`와 `--end` / `-E` line offset을 받습니다. 0 이상의 값은 absolute scrollback line index이고, 음수 값은 현재 scrollback line count에서 뒤로 셉니다. `--end`는 inclusive라 `lterm logs api -S0 -E0`은 첫 번째 줄만 capture합니다. Capture 출력은 계속 정제된 text입니다. 즉 terminal control은 제거하고 한국어, CJK, emoji 같은 UTF-8 text는 보존합니다. attach된 PTY stream은 raw 그대로 유지됩니다.
223
229
 
@@ -287,38 +293,81 @@ lterm sessions --all
287
293
  lterm processes api --orphans
288
294
  lterm logs api --start=-80 --end=-1
289
295
  lterm urls api --last
296
+ lterm search api 'build failed'
290
297
  lterm compose api
291
298
  LTERM_MOBILE=1 lterm resume codex-lterm
299
+ lterm reconnect --mobile
292
300
  lterm resume --raw codex-lterm
293
301
  lterm wait api --contains READY --timeout 30s --json
294
302
  lterm watch api --exit --notify
295
303
  lterm input api 'echo hello' --enter
296
304
  ```
297
305
 
298
- 위의 일반 alias는 tmux 용어를 몰라도 agent terminal을 일상적으로 다룰 수 있게 해 주는 명령 집합입니다. `sessions`는 영속 작업을 나열하고, `processes`는 child process tree를 확인하고, `logs`는 정제된 scrollback을 읽고, `compose`는 정제된 scrollback과 하단 고정 prompt로 텍스트를 commit할 수 있게 하며, 모바일 transcript attach는 긴 agent 출력을 휴대폰의 기본 scrollback으로 읽을 수 있게 해 줍니다. `wait` / `watch`는 marker 또는 종료 조건을 script와 agent가 관측할 수 있게 하고, `input`은 대상 PTY에 텍스트를 씁니다. `lterm mobile`은 `lterm compose`의 visible alias이고, 별개의 attach flag인 `--mobile`은 normal-screen transcript attach 경로를 선택합니다. 호환 이름 `list` / `ls`, `ps`, `capture`, `send`는 스크립트와 기존 사용 습관에서도 계속 사용할 수 있습니다.
299
-
300
- `lterm urls <target>`은 raw attach PTY stream을 건드리지 않고, 마지막 120개
301
- 정제된 scrollback line에서 `http://` / `https://` link를 추출합니다. 기본
302
- 출력은 link마다 `N<TAB>URL` 줄이고, `--last`는 휴대폰에서 복사하기 쉽도록
303
- 가장 최근의 유효한 URL 하나만 출력합니다. `--json`은 JSON array를 출력하고,
304
- `--tail N`으로 scan 범위를 바꿀 수 있습니다. text mode에서 URL이 없으면 성공
305
- 종료하면서 출력하지 않고, JSON mode는 `[]`를 출력합니다. 추출은 unique ASCII
306
- URL token 256개로 제한되며, 4096 byte를 넘는 raw URL candidate는 잘라 내지
307
- 않고 건너뜁니다. 모바일 transcript mode에서는 `/links` 또는 `/urls`를 입력하면
308
- numbered list를 로컬로 보여 주며, 해당 입력은 PTY로 전달되지 않습니다.
309
- Claude/OAuth 로그인 URL을 Termius 같은 모바일 SSH client에서 복사해야 할 때
310
- 유용합니다. Claude 전용 모바일 제어가 목적이라면 Claude Code Remote Control
311
- 흐름도 URL 복사 왕복을 줄이는 우회책이 있습니다.
312
-
313
- 추출된 link는 신뢰할 수 없는 terminal output으로 취급하세요. 악성 프로그램은
314
- 피싱 URL을 출력할 있고, OAuth, magic-login, device-code link에는 짧게 살아
315
- 있는 secret이 포함될 있습니다. 예상한 link 열고, 공유 로그나 채팅에
316
- 그대로 붙여넣지 말고, `--last`는 최신 link가 의도한 대상임을 알고 있을 때만
317
- 사용하는 것이 안전합니다.
318
-
319
- 자동화와 테스트에는 `lterm compose api --once --message 'hello'`를 사용하면 번의 정제된 capture/send 사이클을 실행합니다. `logs`와 같은 session-or-pane target 모델에서 마지막 `--tail` 정제 라인(기본값: 80)을 capture한 뒤, 기본으로 Enter(`\r`)를 붙여 `lterm input --enter`와 맞추며, `--no-enter`를 추가하면 message byte만 정확히 보냅니다. `compose` / `mobile`은 attach client가 아니며 attached-client 수나 PTY geometry를 바꾸지 않습니다.
320
- Interactive compose 화면은 `--refresh`(기본값: 500ms), 로컬 입력, 터미널 resize 이벤트마다 갱신됩니다. Enter누르면 현재 입력 buffer를 commit하고(빈 buffer도 commit됨), 위 one-shot 규칙처럼 기본으로 `\r`을 덧붙입니다. Ctrl-C, Ctrl-D, EscPTY로 전달하지 않고 로컬 composer를 종료합니다.
321
- `lterm compose api --transcript`를 사용하면 모바일 auto attach가 쓰는 것과 같은 normal-screen transcript UI를 직접 열 수 있습니다. alternate-screen composer 없이 정제된 scrollback과 간단한 line input만 쓰고 싶을 때 적합합니다. 출력만 보고 싶으면 `--read-only`를 추가하세요. Transcript-local command에는 `/refresh`, `/raw`, `/links` / `/urls`, `/exit` / `/quit`가 있고, `/links`와 `/urls`는 로컬에서만 처리되어 PTY로 전달되지 않습니다. link가 없으면 `No URLs found in current transcript.`를 출력하며, 이외의 줄은 PTY로 전달됩니다.
306
+ 위의 일반 alias는 tmux 용어를 몰라도 agent terminal을 일상적으로 다룰 수 있게 해 주는 명령 집합입니다. `sessions`는 영속 작업을 나열하고, `processes`는 child process tree를 확인하고, `logs`는 정제된 scrollback을 읽고, `compose`는 정제된 scrollback과 하단 고정 prompt로 텍스트를 commit할 수 있게 하며, 모바일 transcript attach는 긴 agent 출력을 휴대폰의 기본 scrollback으로 읽을 수 있게 해 줍니다. `reconnect`는 SSH 재접속 뒤 마지막으로 선택했던 로컬 lterm 세션을 다시 엽니다. `wait` / `watch`는 marker 또는 종료 조건을 script와 agent가 관측할 수 있게 하고, `input`은 대상 PTY에 텍스트를 씁니다. `lterm mobile`은 `lterm compose`의 visible alias이고, 별개의 attach flag인 `--mobile`은 normal-screen transcript attach 경로를 선택합니다. 호환 이름 `list` / `ls`, `ps`, `capture`, `send`는 스크립트와 기존 사용 습관에서도 계속 사용할 수 있습니다.
307
+
308
+ `lterm reconnect [fallback]`는 마지막으로 선택한 세션을 가리키는 비공개
309
+ 최소 pointer(`session_id`, pane id, 사용자가 붙인 session name, timestamp)만
310
+ 저장하고, 다음 실행 pointer를 사용합니다. pointer가 없거나 손상됐거나
311
+ 오래되어 이상 맞지 않으면 `fallback`(기본값: `main`)으로 돌아가며,
312
+ 동작은 `lterm open`과 같은 attach-or-create 방식입니다.
313
+
314
+ 세션 이름에는 secret을 넣지 마세요. `reconnect`도 raw attach가 가능하므로,
315
+ 휴대폰 SSH client에서 정제된 normal-screen transcript를 원하면 `--mobile`을
316
+ 함께 사용하세요. 모바일 SSH 로그인용 optional snippet은
317
+ `lterm init --mobile-reconnect --shell zsh`(`bash`, `fish`, `posix`도 가능)로
318
+ 미리 있고, `--shell`을 생략하면 `$SHELL`에서 감지합니다. snippet은
319
+ 자동 설치되지 않습니다. 검토한 직접 복사하고, 되돌릴 때는 복사한 block을
320
+ 삭제하거나 `LTERM_RECONNECT_DISABLE=1`로 건너뛰세요.
321
+
322
+ `lterm urls <target>`는 raw attach PTY stream을 건드리지 않고, 마지막
323
+ 120줄의 정제된 scrollback에서 `http://`와 `https://` link 추출합니다.
324
+ 기본 출력은 link마다 줄씩 `N<TAB>URL`입니다. 최신 유효 URL만 보려면
325
+ `--last`, JSON 배열이 필요하면 `--json`, 검색 범위를 바꾸려면 `--tail N`을
326
+ 사용하세요. text mode에서 link가 없으면 성공 종료하며 아무것도 출력하지 않고,
327
+ JSON mode에서는 `[]`를 출력합니다. URL 추출은 unique ASCII URL token 256개로
328
+ 제한되며, 4096 byte넘는 raw candidate자르지 않고 건너뜁니다.
329
+
330
+ mobile transcript mode에서는 `/links` 또는 `/urls`를 입력하면 같은 번호 목록을
331
+ PTY로 보내지 않고 로컬에서 보여 줍니다. Termius 계열 모바일 SSH client에서
332
+ Claude/OAuth login URL을 복사할 때 유용하며, Claude 전용 모바일
333
+ 제어에는 Claude Code Remote Control flow가 URL 복사 왕복을 줄여 줄 수도
334
+ 있습니다. 추출된 link는 신뢰할 수 없는 terminal output으로 취급하세요. 악성
335
+ 프로그램이 피싱 URL을 출력할 수 있고, OAuth/magic-login/device-code link는
336
+ 짧게 살아 있는 secret을 포함할 수 있습니다. 예상한 link만 열고, 공유 로그나
337
+ 채팅에 붙여 넣지 말며, `--last`는 최신 link가 원하는 link임을 알 때만
338
+ 사용하세요.
339
+
340
+ `lterm search <target> QUERY`는 raw attach PTY stream을 건드리지 않고,
341
+ 마지막 120줄의 정제된 scrollback에서 대소문자를 구분하는 literal match를
342
+ 찾습니다. 기본 출력은 1부터 시작하는 번호를 붙인 `N<TAB>LINE`입니다. `--json`은
343
+ 같은 정제된 match를 JSON 배열로 출력하고, `--tail N`은 검색 범위를
344
+ 바꿉니다. text mode에서 match가 없으면 성공 종료하며 아무것도 출력하지 않고,
345
+ 빈 `QUERY`는 거부합니다. mobile transcript mode에서는 `/grep QUERY`를 입력해
346
+ active transcript tail window의 match를 PTY로 보내지 않고 로컬에서 볼 수
347
+ 있습니다. query 없는 `/grep`은 `Usage: /grep QUERY`를 출력하고, match가 없으면
348
+ `No matches found in current transcript.`를 출력합니다.
349
+
350
+ 자동화와 테스트에서 `lterm compose api --once --message 'hello'`는 정제된
351
+ capture/send cycle을 한 번 수행합니다. `logs`와 같은 session-or-pane target
352
+ 모델로 마지막 `--tail`줄(기본값: 80)의 정제된 output을 캡처한 뒤, 기본적으로
353
+ Enter(`\r`)를 덧붙여 `lterm input --enter`와 같은 방식으로 보냅니다. 정확한
354
+ message byte만 보내려면 `--no-enter`를 추가하세요. `compose` / `mobile`은 attach
355
+ client가 아니며 attached-client 수나 PTY geometry를 바꾸지 않습니다.
356
+
357
+ interactive compose에서는 `--refresh`(기본값: 500ms), local input, resize event에
358
+ 맞춰 view를 갱신합니다. Enter는 현재 input buffer를 commit하며, 빈 buffer도
359
+ commit 대상입니다. 기본적으로 `\r`을 덧붙입니다. Ctrl-C, Ctrl-D, Esc는 PTY로
360
+ 전달하지 않고 local composer를 종료합니다.
361
+
362
+ `lterm compose api --transcript`는 mobile auto attach와 같은 normal-screen
363
+ transcript UI를 엽니다. alternate-screen composer 없이 정제된 scrollback과
364
+ 간단한 line input만 쓰고 싶을 때 사용하고, 출력만 보려면 `--read-only`를
365
+ 추가하세요. transcript-local command는 `/refresh`, `/raw`, `/links` / `/urls`,
366
+ `/grep QUERY`, `/exit` / `/quit`입니다. `/links`, `/urls`, `/grep`은 로컬에서만
367
+ 처리되고 PTY로 전달되지 않습니다. link가 없으면 `No URLs found in current
368
+ transcript.`를 출력하고, query 없는 `/grep`은 `Usage: /grep QUERY`, match가
369
+ 없으면 `No matches found in current transcript.`를 출력합니다. 알 수 없는 줄은
370
+ PTY로 전송됩니다.
322
371
 
323
372
  **세션 종료:**
324
373
 
@@ -386,11 +435,23 @@ lterm codex --mobile --tail 200 --refresh 1s --read-only
386
435
  lterm agy --status -- -p "lterm status를 유지해줘"
387
436
  ```
388
437
 
438
+ [`mat`](https://github.com/ictechgy/multi-account-tool)도 사용한다면, 지원되는 launcher에서 separator 앞에 `--mat-profile`(canonical) 또는 `--profile`(짧은 UX alias)을 붙여 child command를 일시 profile swap으로 감쌀 수 있습니다.
439
+
440
+ ```bash
441
+ lterm claude --profile work -- --help
442
+ lterm codex --mat-profile personal -- exec "이 저장소를 요약해줘"
443
+ lterm claude --profile work -- --profile native
444
+ ```
445
+
446
+ 이 기능은 lterm session command를 `mat exec <cli> <profile> -- <agent-binary> ...`로 만듭니다. 따라서 mat가 그 세션 안에서 agent child를 실행하기 전에 설정된 account material로 swap한 뒤 원복합니다. 이는 lterm 자체 credential isolation이 아니며, mat의 temporal swap/restore/freshness/per-CLI lock 한계를 그대로 따릅니다. mat wrapper는 mat가 지원하는 built-in allowlist(`claude`, `codex`, `opencode`, `aider`, `goose`, `crush`, `gemini`, `kimi`, `qwen`)에만 의도적으로 열려 있습니다. `agy`, Copilot, Cursor Agent, Jules, Kiro, Amp, OMX/OMC, custom profile, configured profile처럼 blocked/unsupported인 agent는 command resolution 전에 `--mat-profile` / `--profile`을 거부합니다. 현재 지원 계약은 `mat support <cli>`로 확인하세요. Claude 자체 `--profile`처럼 agent-native option을 넘길 때는 두 번째 `--` 뒤에 두어야 lterm이 mat profile selector로 해석하지 않습니다.
447
+
448
+ `--mat-profile`과 별개로, lterm은 client→daemon hop을 건널 때 Codex profile home 신호 하나만 좁게 보존합니다. 실행한 client에 `CODEX_HOME`이 설정되어 있으면 새 세션은 명시적인 session env가 이미 `CODEX_HOME`을 제공하지 않는 한 그 값을 상속합니다. 이는 의도적으로 broad environment forwarding이 아닙니다.
449
+
389
450
  Claude/Codex/OpenCode/Copilot/Cursor Agent/Antigravity/Kiro/Jules/Aider/Goose/Amp/Crush/Kimi/Qwen/Gemini/OMX/OMC profile의 기본 attach 정책은 `auto`입니다. 데스크톱에서는 lterm status bar를 끈 raw full-terminal attach를 사용하므로 각 도구의 자체 TUI/status/alternate-screen 렌더링이 그대로 동작합니다. 이후 해당 agent 세션을 `lterm resume` 또는 `lterm open`으로 다시 붙을 때도 같은 row-off 기본값을 유지합니다. Termius 계열 모바일 클라이언트에서는 `auto`가 위에서 설명한 normal-screen transcript로 전환되어 긴 agent 출력을 모바일 기본 scrollback으로 읽을 수 있습니다. raw attach를 강제하려면 `--raw`, transcript를 강제하려면 `--mobile`을 사용하세요. `--status`는 직접 agent launch의 raw 경로에서 lterm status bar를 요청하고, raw launch/profile에서 표시되는 status bar는 `--no-status`로 숨길 수 있습니다. `--status`는 agent 디버깅용 best-effort override라 agent TUI와 충돌할 수 있으며, `--mobile --status`는 mobile transcript가 자체 UI를 소유하므로 raw status row를 만들지 않습니다. agent에 넘길 인자가 lterm launch option처럼 보일 수 있으면 앞에 `--`를 두세요. `lterm agent <name>`은 `PATH`에서 찾을 수 있는 안전한 bare command name이면 바로 동작하므로, 예를 들어 `lterm agent qwen-code`처럼 미래/서드파티 agent도 쓸 수 있습니다. `lterm run -- <command>`는 더 낮은 수준의 tmux-compatible primitive를 직접 쓰고 싶을 때만 사용하세요.
390
451
 
391
452
  Agent launcher는 색상 관련 환경 변수도 host 쪽과 agent child 쪽을 분리해 다룹니다. lterm은 클라이언트나 장기 실행 daemon에 설정된 `NO_COLOR`, `FORCE_COLOR`, `CLICOLOR`, `CLICOLOR_FORCE`를 `LTERM_AGENT` metadata가 있는 세션으로는 전달하지 않습니다. 모바일 SSH renderer나 host status 설정이 full-screen agent TUI를 의도치 않게 monochrome 출력으로 고정할 수 있기 때문입니다. 일반 non-agent 세션(`lterm start` / `lterm new` / `lterm run`)은 이 변수들을 계속 child process에 보존하며, lterm 자체 status style도 `NO_COLOR`를 계속 존중합니다.
392
453
 
393
- launcher 제어 옵션은 agent의 흔한 short flag(`-c` 등)를 빼앗지 않도록 long-only(`--name`, `--cwd`, `--detach`, `--status`, `--no-status`, `--status-theme`, `--status-color`, `--attach-mode`, `--raw`, `--mobile`, `--tail`, `--refresh`, `--read-only`)입니다. 이 옵션들은 `claude`, `codex`, `opencode`, `copilot`, `cursor-agent`, `agy`, `kiro`, `jules`, `aider`, `goose`, `amp`, `crush`, `kimi`, `qwen`, `gemini`, `omx`, `omc`, `agent <profile>`에 동일하게 적용됩니다. 해당 agent 세션이 이후 attach에서도 특정 lterm status 색을 유지하게 하려면 `--status-theme` / `--status-color`를 사용하세요.
454
+ launcher 제어 옵션은 agent의 흔한 short flag(`-c` 등)를 빼앗지 않도록 long-only(`--name`, `--cwd`, `--mat-profile` / `--profile`, `--detach`, `--status`, `--no-status`, `--status-theme`, `--status-color`, `--attach-mode`, `--raw`, `--mobile`, `--tail`, `--refresh`, `--read-only`)입니다. 이 옵션들은 `claude`, `codex`, `opencode`, `copilot`, `cursor-agent`, `agy`, `kiro`, `jules`, `aider`, `goose`, `amp`, `crush`, `kimi`, `qwen`, `gemini`, `omx`, `omc`, `agent <profile>`에 동일하게 적용되지만, `--mat-profile` / `--profile`은 위 mat-supported allowlist에서만 성공합니다. 해당 agent 세션이 이후 attach에서도 특정 lterm status 색을 유지하게 하려면 `--status-theme` / `--status-color`를 사용하세요.
394
455
  `--detach`는 각 field의 control character와 Unicode line/paragraph separator를 공백으로 바꾼 `name<TAB>pane<TAB>command`를 출력하며, 나중에 `lterm resume <name>` 또는 호환 이름 `lterm attach <name>`으로 다시 붙으면 됩니다. detach record에는 `--cwd`가 포함되지 않으므로 나중에 필요하면 session을 조회하세요.
395
456
  명시한 `--name`은 lterm의 일반 session-name 문법을 따르고 사용 중이지 않아야 합니다. 충돌 시 자동 suffix를 붙이지 않고 conflict error로 실패합니다.
396
457
  이름에는 ASCII 문자/숫자와 `.`, `_`, `-`만 사용할 수 있고, `-` 또는 `%`로 시작할 수 없으며, 숫자만으로 이뤄질 수 없고, UUID처럼 보이면 안 되고, 128바이트를 넘을 수 없습니다.
@@ -524,6 +585,11 @@ lterm ssh user@host main
524
585
  lterm ssh devbox main -- -p 2222 -i ~/.ssh/id_ed25519
525
586
  ```
526
587
 
588
+ 일반 모바일 SSH로 호스트에 로그인한 뒤에는 `lterm reconnect --mobile`을 실행해
589
+ 그 호스트에서 마지막으로 선택했던 lterm 세션을 다시 열 수 있습니다. `lterm ssh`
590
+ 자체는 구버전 원격 설치와의 호환성을 위해 기존 `attach-or-new` wire command를
591
+ 그대로 유지합니다.
592
+
527
593
  ## 구조
528
594
 
529
595
  - **데몬** — 사용자별 Unix socket 하나를 `$XDG_RUNTIME_DIR` 아래에 만들고, 없으면 `/tmp` 아래 소유자 전용 fallback 경로를 사용합니다.
@@ -540,7 +606,7 @@ lterm ssh devbox main -- -p 2222 -i ~/.ssh/id_ed25519
540
606
 
541
607
  **터미널 출력은 그대로 전달됩니다.** `lterm resume`(호환 이름: `lterm attach`)은 full-screen 터미널 프로그램과 cmux/OSC 알림이 정상 동작하도록 PTY byte를 그대로 통과시킵니다. 로컬 상태 바는 클라이언트 쪽 표시 요소일 뿐이며, 완전한 raw 모드 터미널이 필요하면 `--no-status`를 사용하세요. nested agent row suspension은 host-side geometry/status 관리일 뿐 attach된 PTY byte를 정제하거나 다시 쓰지 않습니다. 신뢰할 수 없는 child 프로그램은 tmux/screen에서와 마찬가지로 attach된 터미널에 escape sequence를 출력할 수 있습니다. **`lterm`을 escape-sequence sanitizer나 sandbox로 사용하지 마세요.**
542
608
 
543
- **Capture 출력은 표시/로깅 전에 terminal control sequence를 제거합니다.** `lterm logs`(호환 이름: `lterm capture`), `lterm compose`(alias: `lterm mobile`), `tmux capture-pane`은 captured scrollback 출력할 raw 또는 UTF-8 encoded C1 control을 포함한 터미널 제어 시퀀스를 제거합니다. 정상 UTF-8 text인 한국어, CJK, emoji는 보존합니다. 그래도 scrollback text는 신뢰할 수 없는 프로그램 출력일 수 있으므로 사람이나 agent에게 넘기기 전에 확인하세요. `compose`는 attach가 아닌 view에서 기존 input/send 경로로 텍스트를 commit하며, raw attached PTY stream을 변환하지 않습니다.
609
+ **Capture report 출력은 표시/로깅 전에 terminal control sequence를 제거합니다.** `lterm logs`(호환 이름: `lterm capture`), `lterm compose`(alias: `lterm mobile`), `lterm search`, `lterm urls`, 진단 출력, `tmux capture-pane`은 scrollback에서 나온 text를 출력하기 전에 raw 또는 UTF-8 encoded C1 control을 포함한 터미널 제어 시퀀스를 제거합니다. 정상 UTF-8 text인 한국어, CJK, emoji는 보존합니다. 그래도 scrollback text는 신뢰할 수 없는 프로그램 출력일 수 있으므로 사람이나 agent에게 넘기기 전에 확인하세요. `compose`는 attach가 아닌 view에서 기존 input/send 경로로 텍스트를 commit하며, raw attach PTY stream을 변환하지 않습니다.
544
610
 
545
611
  **프로세스 가시성.** `lterm processes [session]`(호환 이름: `lterm ps [session]`)은 process-group id와 함께 각 세션 child 아래의 process tree를 보여 줍니다. `--orphans`를 추가하면 기록된 session root의 descendant가 아니지만 같은 process group에 남아 있는 row도 함께 보여 주므로, Codex/OMX/MCP subprocess가 누적되어 메모리 누수처럼 커지기 전에 확인할 수 있습니다. 시스템 `ps`는 절대 경로로 호출하며, 형식이 잘못된 process row는 추측하지 않고 건너뜁니다.
546
612
 
@@ -601,6 +667,7 @@ PATH="$HOME/.cargo/bin:$PATH" scripts/release-preflight.sh --allow-occupied-skip
601
667
  scripts/dependency-minor-dry-run.sh
602
668
  ```
603
669
 
670
+ 기본 `cargo test` suite에는 짧은 automated soak smoke profile이 포함됩니다.
604
671
  `scripts/release-preflight.sh`의 `--run-soak`은 manual release-gate soak
605
672
  profile에서만 사용하세요. Tagging 또는 publishing 전에 release, toolchain
606
673
  provenance, audit, contract, dependency, soak evidence를 남길 때는
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  - **What** — A persistent terminal session daemon (like tmux, but smaller) with a tmux-compatible command layer for AI-agent tooling. Detach and reattach by name or pane id.
8
8
  - **Who it's for** — Terminal-first coding agents such as Claude Code, Codex CLI, OpenCode, GitHub Copilot CLI, Cursor Agent, Antigravity/`agy`, Kiro, Jules, Aider, Goose, Amp, Crush, Kimi, Qwen, Gemini CLI, `oh-my-codex` / `oh-my-claude`, and users running them inside `cmux`.
9
9
  - **How** — Use `lterm start` to create a session, `lterm resume` to reconnect, and `lterm agent <profile>` / `lterm claude` / `lterm codex` / `lterm opencode` / `lterm agy` / `lterm kiro` / `lterm gemini` for built-in shimmed agent launchers. Inside a tmux-enabled session, the `tmux` command resolves to `lterm tmux-compat`.
10
- - **Status** — Alpha MVP with a documented 1.0 command/output compatibility boundary. It is a same-user convenience daemon — **not** a sandbox, an escape-sequence sanitizer, or a full tmux replacement.
10
+ - **Status** — 1.x CLI with a documented 1.0 command/output compatibility boundary. It is a same-user convenience daemon — **not** a sandbox, an escape-sequence sanitizer, or a full tmux replacement.
11
11
 
12
12
  ---
13
13
 
@@ -81,7 +81,7 @@ With Cargo from GitHub, pin a release tag. The example below uses the current
81
81
  README release; check the Releases page for newer tags:
82
82
 
83
83
  ```bash
84
- cargo install --locked --git https://github.com/ictechgy/light_terminal --tag v1.0.24
84
+ cargo install --locked --git https://github.com/ictechgy/light_terminal --tag v1.0.26
85
85
  ```
86
86
 
87
87
  Building from this checkout requires Rust 1.85 or newer:
@@ -141,6 +141,7 @@ lterm -a api
141
141
  | Run a command with tmux compatibility enabled | `lterm run -- codex exec "summarize"` | None (`--no-tmux` opts out) |
142
142
  | Open or create a session | `lterm open main` | `attach-or-new` |
143
143
  | Resume an existing session | `lterm resume api` | `attach`, `a`, `-a` |
144
+ | Reconnect to the last selected session | `lterm reconnect --mobile` | None |
144
145
  | Review an agent session in mobile scrollback | `LTERM_MOBILE=1 lterm resume codex-lterm` | Force with `--mobile`; force raw with `--raw` |
145
146
  | List sessions | `lterm sessions` | `list`, `ls` |
146
147
  | Inspect process trees | `lterm processes api --json --orphans` | `ps` |
@@ -157,6 +158,7 @@ lterm -a api
157
158
  | Stop a session | `lterm close api` | `kill` |
158
159
  | Diagnose daemon and shim state | `lterm doctor --json` | `status` |
159
160
  | Collect a redacted local diagnostic bundle | `lterm diagnose --bundle` | None |
161
+ | Inspect redacted local diagnostics | `lterm inspect --json` | None |
160
162
  | Preview local setup steps | `lterm init --shell zsh` | None |
161
163
  | Install supported AI CLI statusline badges | `lterm install-ai-statusline` | None |
162
164
  | Install shell completions | `lterm install-completions --shell zsh` | None |
@@ -211,13 +213,16 @@ Every lterm session also exports `LTERM_SESSION` and `LTERM_PANE` inside the chi
211
213
 
212
214
  `lterm status-theme <target> <theme>` (alias: `lterm theme`) stores a per-session status bar theme without restarting the PTY; pane ids resolve to their session. Use `default`, `clear`, or `none` to remove the session override and return to the attaching client's default. Already-attached clients keep their current status color until they detach and reattach. New sessions can set the same metadata at creation time with `lterm start --status-theme green -n api -- npm run dev` (or alias `--status-color`).
213
215
 
214
- `lterm doctor` (compatibility name: `lterm status`) reports client/daemon versions, protocol compatibility, runtime/data/socket/shim paths, and whether the shim directory is on `PATH`. It does not start the daemon; `daemon_reachable=no` / `false` means no compatible daemon answered on the current socket. Normal client operations warn on stderr when a reachable daemon reports a different lterm or protocol version, which usually means an old daemon survived a binary upgrade.
216
+ `lterm doctor` (compatibility name: `lterm status`) reports client/daemon versions, protocol compatibility, runtime/data/socket/shim paths, whether the shim directory is on `PATH`, and a count plus boolean/null `tmux_compat` summary. Current builds emit `tmux_compat`, but the stable schema keeps it additive/optional so older doctor outputs still validate during mixed-version upgrades. It does not start the daemon; `daemon_reachable=no` / `false` means no compatible daemon answered on the current socket. Normal client operations warn on stderr when a reachable daemon reports a different lterm or protocol version, which usually means an old daemon survived a binary upgrade.
215
217
 
216
218
  `lterm diagnose --bundle` prints a local-only JSON diagnostic bundle for issues
217
219
  and agent handoffs. It includes `doctor` data, redacted environment presence
218
220
  flags, and — only when an existing daemon is reachable — session metadata plus
219
221
  process rows. It does not start the daemon and does not include raw PTY bytes or
220
- scrollback by default.
222
+ scrollback by default. `lterm inspect --json` prints the same redacted bundle for
223
+ tools that expect an inspect-style JSON entrypoint; it requires `--json`.
224
+
225
+ For opt-in local footprint measurements, run `python3 scripts/footprint_benchmark.py --quick --json target/footprint-baseline.json --markdown target/footprint-baseline.md`. See [`docs/footprint-benchmark.md`](docs/footprint-benchmark.md) for the isolated lterm-vs-tmux methodology and interpretation caveats.
221
226
 
222
227
  `lterm logs <target>` accepts `--start` / `-S` and `--end` / `-E` line offsets. Non-negative values are absolute scrollback line indexes; negative values count back from the current scrollback line count. `--end` is inclusive, so `lterm logs api -S0 -E0` captures only the first line. Capture output remains sanitized text: terminal controls are removed, while UTF-8 text such as Korean, CJK, and emoji is preserved. Attached PTY streams remain raw.
223
228
 
@@ -288,38 +293,82 @@ lterm sessions --all
288
293
  lterm processes api --orphans
289
294
  lterm logs api --start=-80 --end=-1
290
295
  lterm urls api --last
296
+ lterm search api 'build failed'
291
297
  lterm compose api
292
298
  LTERM_MOBILE=1 lterm resume codex-lterm
299
+ lterm reconnect --mobile
293
300
  lterm resume --raw codex-lterm
294
301
  lterm wait api --contains READY --timeout 30s --json
295
302
  lterm watch api --exit --notify
296
303
  lterm input api 'echo hello' --enter
297
304
  ```
298
305
 
299
- The generic aliases above are meant for day-to-day agent-terminal use: `sessions` lists persistent work, `processes` inspects child process trees, `logs` reads sanitized scrollback, `compose` shows sanitized scrollback with a fixed bottom prompt for committing text, mobile transcript attach gives phone clients native scrollback for long agent output, `wait` / `watch` make marker-or-exit conditions observable for scripts and agents, and `input` writes text to the target PTY. `lterm mobile` is a visible alias for `lterm compose`; separately, the `--mobile` attach flag selects the normal-screen transcript attach path. The compatibility names `list` / `ls`, `ps`, `capture`, and `send` remain available for scripts and muscle memory.
306
+ The generic aliases above are meant for day-to-day agent-terminal use: `sessions` lists persistent work, `processes` inspects child process trees, `logs` reads sanitized scrollback, `compose` shows sanitized scrollback with a fixed bottom prompt for committing text, mobile transcript attach gives phone clients native scrollback for long agent output, `reconnect` resumes the last selected local lterm session after an SSH reconnect, `wait` / `watch` make marker-or-exit conditions observable for scripts and agents, and `input` writes text to the target PTY. `lterm mobile` is a visible alias for `lterm compose`; separately, the `--mobile` attach flag selects the normal-screen transcript attach path. The compatibility names `list` / `ls`, `ps`, `capture`, and `send` remain available for scripts and muscle memory.
307
+
308
+ `lterm reconnect [fallback]` stores a private, minimal pointer to the last
309
+ selected session (`session_id`, pane id, user-chosen session name, and
310
+ timestamp), then uses that pointer on the next run. Missing, corrupt, or stale
311
+ pointers fall back to `fallback` (default: `main`) with the same
312
+ attach-or-create behavior as `lterm open`.
313
+
314
+ Do not put secrets in session names. `reconnect` can still raw-attach, so use
315
+ `--mobile` on phone SSH clients when you want the sanitized normal-screen
316
+ transcript instead of the raw PTY stream. Preview the optional SSH-login snippet
317
+ with `lterm init --mobile-reconnect --shell zsh` (or `bash`, `fish`, `posix`);
318
+ omit `--shell` to detect from `$SHELL`. The snippet is not installed
319
+ automatically: copy it only after review, remove the copied block to undo it, or
320
+ set `LTERM_RECONNECT_DISABLE=1` to skip it.
300
321
 
301
322
  `lterm urls <target>` extracts `http://` and `https://` links from the last
302
323
  120 sanitized scrollback lines without touching the raw attached PTY stream.
303
- Default output is `N<TAB>URL`, one link per line; `--last` prints only the
304
- newest valid URL occurrence for phone-friendly copy/paste, `--json` emits a
305
- JSON array, and `--tail N` changes the scan range. Empty text modes exit
306
- successfully with no output, while JSON mode prints `[]`. Extraction is bounded
307
- to 256 unique ASCII URL tokens and skips raw URL candidates longer than 4096
308
- bytes instead of truncating them. In mobile transcript mode, type `/links` or
309
- `/urls` to show the same numbered list locally instead of sending that text to
310
- the PTY. This is useful for Claude/OAuth login URLs on Termius-style mobile SSH
311
- clients; for Claude-specific mobile control, Claude Code's Remote Control flow
312
- can also reduce URL-copy round trips.
313
-
314
- Treat extracted links as untrusted terminal output. A malicious program can
315
- print phishing URLs, and OAuth, magic-login, or device-code links may carry
316
- short-lived secrets. Open only links you expect, avoid pasting them into shared
317
- logs or chat, and prefer `--last` only when you know the newest link is the one
318
- you intend to use.
319
-
320
- For automation and tests, `lterm compose api --once --message 'hello'` performs one sanitized capture/send cycle. It captures the last `--tail` sanitized lines (default: 80) from the same session-or-pane target model as `logs`, then appends Enter (`\r`) by default, matching `lterm input --enter`; add `--no-enter` to send the exact message bytes. `compose` / `mobile` is not an attach client and does not change attached-client counts or PTY geometry.
321
- In interactive compose, the view refreshes on `--refresh` (default: 500ms) and after local input or resize events. Pressing Enter commits the current input buffer (empty buffers are committed too) and appends `\r` by default, matching the one-shot rule above. Ctrl-C, Ctrl-D, and Esc exit the local composer instead of forwarding to the PTY.
322
- `lterm compose api --transcript` opens the same normal-screen transcript UI used by mobile auto attach. It is useful when you want sanitized scrollback and simple line input without the alternate-screen composer; add `--read-only` when you only want to watch output. Transcript-local commands include `/refresh`, `/raw`, `/links` / `/urls`, and `/exit` / `/quit`; `/links` and `/urls` are handled locally and are never forwarded to the PTY. When no links are present they print `No URLs found in current transcript.`; unrecognized lines are sent to the PTY.
324
+ Default output is `N<TAB>URL`, one link per line. Use `--last` for the newest
325
+ valid URL, `--json` for a JSON array, and `--tail N` to change the scan range.
326
+ Empty text modes exit successfully with no output; JSON mode prints `[]`. URL
327
+ extraction is bounded to 256 unique ASCII URL tokens and skips raw candidates
328
+ longer than 4096 bytes instead of truncating them.
329
+
330
+ In mobile transcript mode, type `/links` or `/urls` to show the same numbered
331
+ list locally instead of sending that text to the PTY. This is useful for
332
+ Claude/OAuth login URLs on Termius-style mobile SSH clients; for
333
+ Claude-specific mobile control, Claude Code's Remote Control flow can also
334
+ reduce URL-copy round trips. Treat extracted links as untrusted terminal
335
+ output: a malicious program can print phishing URLs, and OAuth, magic-login, or
336
+ device-code links may carry short-lived secrets. Open only links you expect,
337
+ avoid pasting them into shared logs or chat, and use `--last` only when you
338
+ know the newest link is the one you intend to open.
339
+
340
+ `lterm search <target> QUERY` searches the last 120 sanitized scrollback lines
341
+ for case-sensitive literal matches without touching the raw attached PTY stream.
342
+ Default output is `N<TAB>LINE` with 1-based numbering; `--json` emits the same
343
+ sanitized matching lines as a JSON array, and `--tail N` changes the scan range.
344
+ No-match text mode exits successfully with no output, while an empty `QUERY` is
345
+ rejected. In mobile transcript mode, type `/grep QUERY` to show matching lines
346
+ from the active transcript tail window locally instead of sending that text to
347
+ the PTY. `/grep` without a query prints `Usage: /grep QUERY`; no matches print
348
+ `No matches found in current transcript.`
349
+
350
+ For automation and tests, `lterm compose api --once --message 'hello'` performs
351
+ one sanitized capture/send cycle. It captures the last `--tail` sanitized lines
352
+ (default: 80) from the same session-or-pane target model as `logs`, then appends
353
+ Enter (`\r`) by default, matching `lterm input --enter`; add `--no-enter` to
354
+ send the exact message bytes. `compose` / `mobile` is not an attach client and
355
+ does not change attached-client counts or PTY geometry.
356
+
357
+ In interactive compose, the view refreshes on `--refresh` (default: 500ms) and
358
+ after local input or resize events. Pressing Enter commits the current input
359
+ buffer, including an empty buffer, and appends `\r` by default. Ctrl-C, Ctrl-D,
360
+ and Esc exit the local composer instead of forwarding to the PTY.
361
+
362
+ `lterm compose api --transcript` opens the same normal-screen transcript UI used
363
+ by mobile auto attach. Use it when you want sanitized scrollback and simple line
364
+ input without the alternate-screen composer; add `--read-only` when you only
365
+ want to watch output. Transcript-local commands include `/refresh`, `/raw`,
366
+ `/links` / `/urls`, `/grep QUERY`, and `/exit` / `/quit`. `/links`, `/urls`,
367
+ and `/grep` are handled locally and are never forwarded to the PTY. When no
368
+ links are present they print `No URLs found in current transcript.`; `/grep`
369
+ without a query prints `Usage: /grep QUERY`; no matches print
370
+ `No matches found in current transcript.` Unrecognized lines are sent to the
371
+ PTY.
323
372
 
324
373
  **Stop a session:**
325
374
 
@@ -387,11 +436,23 @@ lterm codex --mobile --tail 200 --refresh 1s --read-only
387
436
  lterm agy --status -- -p "keep lterm status visible"
388
437
  ```
389
438
 
439
+ If you also use [`mat`](https://github.com/ictechgy/multi-account-tool), supported launchers can wrap the child command in a temporal profile swap by passing `--mat-profile` (canonical) or `--profile` (shorter UX alias) before the separator:
440
+
441
+ ```bash
442
+ lterm claude --profile work -- --help
443
+ lterm codex --mat-profile personal -- exec "summarize this repo"
444
+ lterm claude --profile work -- --profile native
445
+ ```
446
+
447
+ The lterm session command becomes `mat exec <cli> <profile> -- <agent-binary> ...`, so mat swaps the configured account material before launching the agent child in that session and restores it afterward. It is not lterm-native credential isolation and it inherits mat's temporal swap, restore, freshness, and per-CLI lock limits. The mat wrapper is intentionally allowlisted to mat-supported built-ins (`claude`, `codex`, `opencode`, `aider`, `goose`, `crush`, `gemini`, `kimi`, and `qwen`); blocked or unsupported agents such as `agy`, Copilot, Cursor Agent, Jules, Kiro, Amp, OMX/OMC, custom profiles, and configured profiles reject `--mat-profile` / `--profile` before command resolution. Use `mat support <cli>` to inspect the current support contract. Put a second `--` before agent-native options such as Claude's own `--profile` so lterm does not treat them as the mat profile selector.
448
+
449
+ Independently of `--mat-profile`, lterm preserves a narrow Codex profile-home signal across the client→daemon hop: if the launching client has `CODEX_HOME` set, new sessions inherit that value unless an explicit session env already provided `CODEX_HOME`. This is intentionally not broad environment forwarding.
450
+
390
451
  Known Claude/Codex/OpenCode/Copilot/Cursor Agent/Antigravity/Kiro/Jules/Aider/Goose/Amp/Crush/Kimi/Qwen/Gemini/OMX/OMC profiles default to the `auto` attach policy. On desktop, that means a raw full-terminal attach without the lterm status bar, so the agent's own TUI, status, and alternate-screen rendering stay in control. Reattaching those agent sessions later with `lterm resume` or `lterm open` keeps the same row-off default. On Termius-style mobile clients, `auto` uses the normal-screen transcript described above so long agent output can be reviewed with native mobile scrollback. Use `--raw` to force raw attach, `--mobile` to force transcript attach, `--status` to request the lterm status bar on the raw path during direct agent launch, or `--no-status` to suppress it for any raw launch/profile that would otherwise show it. `--status` is intentionally a best-effort override for agent debugging and can still conflict with agent TUIs; `--mobile --status` does not create a raw status row because mobile transcript owns its own UI. Put `--` before agent arguments that could be parsed as lterm launch options. `lterm agent <name>` also works for any safe bare command name available in `PATH` (for example `lterm agent qwen-code`); use `lterm run -- <command>` only when you want the lower-level tmux-compatible primitive directly.
391
452
 
392
453
  Agent launchers also keep host/application color policy separate from the agent child. Ambient `NO_COLOR`, `FORCE_COLOR`, `CLICOLOR`, and `CLICOLOR_FORCE` from the client or long-lived daemon are not forwarded to sessions marked with `LTERM_AGENT`, because mobile SSH or host status preferences can otherwise force full-screen agent TUIs into monochrome output. Ordinary non-agent sessions (`lterm start` / `lterm new` / `lterm run`) still preserve those variables for child processes, and lterm's own status style continues to honor `NO_COLOR`.
393
454
 
394
- Launcher controls are long-only (`--name`, `--cwd`, `--detach`, `--status`, `--no-status`, `--status-theme`, `--status-color`, `--attach-mode`, `--raw`, `--mobile`, `--tail`, `--refresh`, `--read-only`) so common agent short flags such as `-c` pass through naturally. They apply uniformly to built-in agent shortcuts such as `claude`, `codex`, `opencode`, `copilot`, `cursor-agent`, `agy`, `kiro`, `jules`, `aider`, `goose`, `amp`, `crush`, `kimi`, `qwen`, `gemini`, `omx`, `omc`, and `agent <profile>`. Use `--status-theme` / `--status-color` on agent launches when you want that session to keep a specific lterm status color across future attaches.
455
+ Launcher controls are long-only (`--name`, `--cwd`, `--mat-profile` / `--profile`, `--detach`, `--status`, `--no-status`, `--status-theme`, `--status-color`, `--attach-mode`, `--raw`, `--mobile`, `--tail`, `--refresh`, `--read-only`) so common agent short flags such as `-c` pass through naturally. They apply uniformly to built-in agent shortcuts such as `claude`, `codex`, `opencode`, `copilot`, `cursor-agent`, `agy`, `kiro`, `jules`, `aider`, `goose`, `amp`, `crush`, `kimi`, `qwen`, `gemini`, `omx`, `omc`, and `agent <profile>`, though `--mat-profile` / `--profile` only succeeds for the mat-supported allowlist above. Use `--status-theme` / `--status-color` on agent launches when you want that session to keep a specific lterm status color across future attaches.
395
456
  `--detach` prints `name<TAB>pane<TAB>command` with control characters and Unicode line/paragraph separators in each field replaced by spaces; resume later with `lterm resume <name>` or compatibility name `lterm attach <name>`. The detach record does not echo `--cwd`; query the session if you need to inspect it later.
396
457
  Explicit `--name` values use lterm's normal session-name syntax and must not already be in use; they do not auto-suffix on conflict, so an in-use name fails with a conflict error.
397
458
  Names may contain ASCII letters, digits, `.`, `_`, and `-`, must not start with `-` or `%`, must not consist only of digits, must not look like a UUID, and are limited to 128 bytes.
@@ -516,6 +577,11 @@ This uses the same attach-or-create behavior as `lterm open main` on the remote
516
577
  lterm ssh devbox main -- -p 2222 -i ~/.ssh/id_ed25519
517
578
  ```
518
579
 
580
+ After a plain mobile SSH login to a host, run `lterm reconnect --mobile` to
581
+ resume the last lterm session selected on that host. `lterm ssh` itself keeps
582
+ the legacy `attach-or-new` remote command for compatibility with older remote
583
+ installs.
584
+
519
585
  ## Architecture
520
586
 
521
587
  - **Daemon** — one Unix socket per user under `$XDG_RUNTIME_DIR`, with an owner-only fallback under `/tmp`.
@@ -532,7 +598,7 @@ the old code until they are stopped.
532
598
 
533
599
  **Terminal output is forwarded as-is.** `lterm resume` (compatibility name: `lterm attach`) passes PTY bytes through so full-screen terminal programs and cmux/OSC notifications keep working. The local status bar is purely a client-side decoration; use `--no-status` for a fully raw terminal surface. Any nested-agent row suspension is host-side geometry/status management only and does not sanitize or rewrite attached PTY bytes. Untrusted child programs can still emit terminal escape sequences to an attached terminal — exactly as under tmux/screen. **Do not use `lterm` as an escape-sequence sanitizer or sandbox.**
534
600
 
535
- **Capture output is terminal-control-sanitized before display/logging.** `lterm logs` (compatibility name: `lterm capture`), `lterm compose` (alias: `lterm mobile`), and `tmux capture-pane` strip terminal control sequences, including raw or UTF-8-encoded C1 controls, before printing scrollback. Valid UTF-8 text such as Korean, CJK, and emoji is preserved. Scrollback text can still be untrusted program output, so review it before feeding it to humans or agents. `compose` is a non-attached view that commits text through the existing input/send path; it does not transform raw attached PTY streams.
601
+ **Capture and report output is terminal-control-sanitized before display/logging.** `lterm logs` (compatibility name: `lterm capture`), `lterm compose` (alias: `lterm mobile`), `lterm search`, `lterm urls`, diagnostics, and `tmux capture-pane` strip terminal control sequences, including raw or UTF-8-encoded C1 controls, before printing scrollback-derived text. Valid UTF-8 text such as Korean, CJK, and emoji is preserved. Scrollback text can still be untrusted program output, so review it before feeding it to humans or agents. `compose` is a non-attached view that commits text through the existing input/send path; it does not transform raw attached PTY streams.
536
602
 
537
603
  **Process visibility.** `lterm processes [session]` (or compatibility name `lterm ps [session]`) shows the process tree rooted at each session child, including process-group ids. Add `--orphans` to also include same-process-group rows that are no longer descendants of the recorded session root, so long-running Codex/OMX/MCP subprocess buildup stays visible before it becomes a memory-leak surprise. The system `ps` is invoked by absolute path, and malformed process rows are skipped rather than guessed at.
538
604
 
@@ -592,6 +658,7 @@ PATH="$HOME/.cargo/bin:$PATH" scripts/release-preflight.sh --allow-occupied-skip
592
658
  scripts/dependency-minor-dry-run.sh
593
659
  ```
594
660
 
661
+ The default `cargo test` suite includes a short automated soak smoke profile.
595
662
  Use `--run-soak` on `scripts/release-preflight.sh` only for the manual
596
663
  release-gate soak profile. Use
597
664
  [`docs/release-evidence-template.md`](docs/release-evidence-template.md) to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ictechgy/lterm",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "Lightweight tmux-compatible terminal session daemon with cmux-friendly notifications.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "homepage": "https://github.com/ictechgy/light_terminal#readme",
@@ -36,10 +36,10 @@
36
36
  "scripts/validate_npm_packages.mjs"
37
37
  ],
38
38
  "optionalDependencies": {
39
- "lterm-darwin-arm64": "1.0.24",
40
- "lterm-darwin-x64": "1.0.24",
41
- "lterm-linux-arm64": "1.0.24",
42
- "lterm-linux-x64": "1.0.24"
39
+ "lterm-darwin-arm64": "1.0.26",
40
+ "lterm-darwin-x64": "1.0.26",
41
+ "lterm-linux-arm64": "1.0.26",
42
+ "lterm-linux-x64": "1.0.26"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=16"