shellbase 0.14.0 → 0.14.2

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.
package/README.md CHANGED
@@ -224,22 +224,23 @@ Claude Code 가 화면을 꽉 채우고 있을 때 `git status` 같은 걸 잠
224
224
  > 끄는 건 프로세스가 계속 살아있으니 그대로 꺼져요. 컨테이너를 완전히 내리려면 컴퓨터에서
225
225
  > `docker stop shellbase-agent` 를 쓰세요.
226
226
 
227
- ### 터미널은 셸 시작 파일(rc)을 읽지 않아요
227
+ ### 터미널은 셸 시작 파일(rc)을 읽습니다
228
228
 
229
- 폰에서 여는 터미널은 `~/.bashrc`(zsh 는 `~/.zshrc`) 같은 **시작 파일을 읽지 않고** 맨 셸로 뜹니다
230
- (`bash --norc --noprofile`, `zsh --no-rcs`, `fish --no-config`, PowerShell `-NoProfile`).
229
+ 폰에서 여는 터미널도 `~/.bashrc`(zsh 는 `~/.zshrc`) 같은 **시작 파일을 그대로 읽습니다.** 프롬프트,
230
+ `ll` 같은 줄임말, 시작 파일에서 늘려둔 PATH 컴퓨터 앞에 앉았을 때와 똑같이 나옵니다.
231
231
 
232
- 시작 파일은 컴퓨터 앞에 앉은 사람이 자기 편하려고 꾸며둔 것이라, 그 컴퓨터에만 있는 명령을
233
- 가리키는 별칭이 흔합니다. 그게 딸려오면 다른 환경에서 명령이 엉뚱하게 깨져요
234
- (`bash: gnuls: command not found` 같은 증상).
232
+ > **0.14.1 에서 되돌린 기본값입니다.** 0.14.0 버전 동안만 반대로(읽지 않게) 동작했어요.
233
+ > 개인 별칭이 컨테이너에 딸려가 깨지는 문제(`bash: gnuls: command not found`) 때문이었는데,
234
+ > 시작 파일은 **PATH 늘리는 사실상 유일한 통로**이기도 해서 대가가 훨씬 컸습니다 — 에이전트를
235
+ > systemd 서비스나 런처로 띄운 컴퓨터에서는 물려받을 환경 자체가 최소 PATH 라, `~/bin` 이나
236
+ > `/usr/local/go/bin` 에 있는 `gh`·`go` 같은 명령이 폰에서 **영영 안 보이게** 됩니다.
237
+ > 0.14.0 을 쓰시다 프롬프트가 `bash-5.2$` 로 바뀌고 명령이 사라졌다면 0.14.1 로 올리세요.
235
238
 
236
- - 대신 **에이전트를 때의 환경변수(PATH 포함)를 그대로 물려받습니다.** 그래서 `shellbase`
237
- 실행할 있던 셸에서 켰다면 `claude` 같은 명령은 그대로 잘 찾습니다.
238
- - 시작 파일에서만 붙던 것(conda 초기화, 개인 별칭, 특정 도구 경로)은 안 따라옵니다.
239
- 필요하면 줄을 **에이전트를 켜는 쪽**에 넣거나, 세션 안에서 그때그때 불러 쓰세요
240
- (예: `source ~/miniconda3/etc/profile.d/conda.sh`).
241
- - 예전처럼 시작 파일을 읽게 하려면 `SHELLBASE_SHELL_RC=1 shellbase start …` 로 켜세요.
242
- - 프롬프트는 꾸밈 없는 기본값(`bash-5.2$`)이 됩니다.
239
+ 일부러 개인 설정을 떼고 셸로 띄우고 싶다면(여러 사람이 같은 폴더를 공유하는 컨테이너 등)
240
+ `SHELLBASE_NO_SHELL_RC=1 shellbase start …` 켜세요. 그러면 `bash --norc --noprofile`,
241
+ `zsh --no-rcs`, `fish --no-config`, PowerShell `-NoProfile` 뜨고 프롬프트도 꾸밈 없는
242
+ 기본값(`bash-5.2$`)이 됩니다. 이때는 **에이전트를 때의 환경변수(PATH 포함)만** 물려받으므로,
243
+ 필요한 경로는 에이전트를 켜는 쪽에 미리 넣어두세요.
243
244
 
244
245
  ## 참고
245
246
 
@@ -288,12 +289,18 @@ systemctl --user daemon-reload
288
289
  systemctl --user enable --now shellbase.service
289
290
  ```
290
291
 
291
- > **주의할 점 2가지 (직접 겪은 문제라 적어둡니다):**
292
+ > **주의할 점 3가지 (직접 겪은 문제라 적어둡니다):**
292
293
  > 1. `ExecStart` 의 `shellbase` 경로는 `which shellbase` 로 직접 확인해서 넣으세요 — systemd 서비스는
293
294
  > 평소 터미널의 PATH를 그대로 물려받지 않아서, node/shellbase를 못 찾는 경우가 흔해요.
294
295
  > (`Environment=PATH=...` 에도 같은 폴더를 넣어야 해요.)
295
296
  > 2. 로그인 세션 없이(원격 SSH 접속도 안 하고) 완전히 백그라운드로 계속 떠있게 하려면
296
297
  > `loginctl enable-linger $(whoami)` 도 한 번 실행해야 해요. 안 하면 로그아웃할 때 같이 꺼져요.
298
+ > 3. **메모리 지킴이(`earlyoom`)가 도는 컴퓨터라면 0.14.2 이상을 쓰세요.** 지킴이 설정에는 보통
299
+ > "빌드 도구를 먼저 죽여라"는 뜻으로 `--prefer ^(cc1|gcc|node|npm|vite|tsc|...)$` 가 들어 있는데,
300
+ > 이 규칙은 명령줄이 아니라 **프로세스 이름만** 봅니다 — Node 로 만든 것은 전부 이름이 `node` 라
301
+ > 에이전트가 수십 MB 만 쓰고 있어도 1순위 사살 대상이 돼요(실측: oom_score 800 + 이름 보너스 300
302
+ > = 1100 으로, 500MB 쓰는 프로세스보다 높았습니다). 에이전트가 죽으면 **그 안의 세션이 전부 함께**
303
+ > 죽습니다. 0.14.2 부터는 프로세스 이름을 `shellbase` 로 바꿔서 이 규칙에 안 걸려요.
297
304
  >
298
305
  > 승인 옵션은 넣지 마세요 — 기본이 "내 계정이면 바로 입력 가능"이라 무인 서버에 그대로 맞습니다.
299
306
  > (`--require-approval` 을 넣으면 접속할 때마다 이 컴퓨터에서 `y` 를 눌러야 하는데, 화면을 안 보는
package/dist/agent.js CHANGED
@@ -186,14 +186,21 @@ function resolveShell() {
186
186
  return process.env.COMSPEC ?? 'powershell.exe';
187
187
  return process.env.SHELL ?? '/bin/bash';
188
188
  }
189
- // 폰에서 여는 터미널은 셸의 '시작 파일'(bash 의 ~/.bashrc, zsh 의 ~/.zshrc 같은 것)을 읽지 않는다.
190
- // 시작 파일은 컴퓨터의 사람이 앉아서 쓰려고 꾸며둔 것이라, 컴퓨터에만 있는 명령을 가리키는
191
- // 별칭이 흔하다. 그게 그대로 딸려오면 엉뚱한 곳에서 명령이 깨진다 (`gnuls: command not found`
192
- // 사건 PLAN.md §8.12). 그래서 껍데기 셸만 띄우고, 실행에 필요한 경로·환경변수는 시작 파일이
193
- // 아니라 **에이전트를 때의 환경**을 그대로 물려주는 쪽으로 통일한다 (sessionEnv 참고).
194
- // 예전처럼 시작 파일을 읽게 하려면 SHELLBASE_SHELL_RC=1 주고 에이전트를 다시 시작하면 된다.
189
+ // 폰에서 여는 터미널도 셸의 '시작 파일'(bash 의 ~/.bashrc, zsh 의 ~/.zshrc 같은 것)을 그대로 읽는다.
190
+ // ssh·tmux·VS Code 터미널이 전부 읽는 것이 정상이고, 폰이라고 다를 이유가 없다.
191
+ //
192
+ // 0.14.0 에서 잠깐 반대로(읽지 않게) 했었다. 개인 별칭이 컨테이너에 딸려가 깨지는 사건
193
+ // (`gnuls: command not found` PLAN.md §8.12) 때문이었는데, 그건 이미 §8.21 에서 그 컴퓨터의
194
+ // ~/.bashrc "있으면 쓰고 없으면 그냥 넘어가게" 고쳐 **근본 해결한 뒤**였다. 이미 막힌 구멍에
195
+ // 안전망을 한 겹 더 친 셈이었고, 대가가 컸다 (§8.57):
196
+ // 시작 파일은 프롬프트만 꾸미는 곳이 아니라 **PATH 를 늘리는 사실상 유일한 통로**다.
197
+ // 에이전트가 systemd 서비스로 뜨는 컴퓨터에서는 물려받을 환경 자체가 최소 PATH 라,
198
+ // gh·go 처럼 ~/bin · /usr/local/go/bin 에 있는 명령이 폰에서 **영영 안 보이게** 된다.
199
+ // 그래서 기본값을 되돌린다. 일부러 개인 설정을 떼고 맨몸 셸을 띄우고 싶은 환경(공용 컨테이너 등)
200
+ // 에서만 SHELLBASE_NO_SHELL_RC=1 을 주고 에이전트를 다시 시작하면 된다.
201
+ // (0.14.0 때 안내했던 SHELLBASE_SHELL_RC=1 은 이제 기본 동작이라 붙어 있어도 해가 없다.)
195
202
  function shellArgs(shell) {
196
- if (process.env.SHELLBASE_SHELL_RC)
203
+ if (!process.env.SHELLBASE_NO_SHELL_RC)
197
204
  return [];
198
205
  const name = path.basename(shell).toLowerCase();
199
206
  // 로그인용 파일(~/.profile 등)은 애초에 로그인 셸일 때만 읽히지만, 혹시 몰라 같이 막아둔다
@@ -213,7 +220,7 @@ function shellArgs(shell) {
213
220
  // 알림이 왔을 때 어느 세션인지 바로 알 수 있다 (notify.ts).
214
221
  function sessionEnv(deviceId) {
215
222
  const env = { ...process.env, [SESSION_ENV]: deviceId };
216
- if (!process.env.SHELLBASE_SHELL_RC) {
223
+ if (process.env.SHELLBASE_NO_SHELL_RC) {
217
224
  // sh·dash·ksh 계열은 옵션 대신 이 변수에 적힌 파일을 시작하면서 읽는다 — 같이 비운다
218
225
  delete env.ENV;
219
226
  delete env.BASH_ENV;
package/dist/cli.js CHANGED
@@ -14,6 +14,15 @@ if (major < 22) {
14
14
  'https://nodejs.org 에서 최신 버전을 설치하거나, nvm 을 쓰신다면 `nvm install 22 && nvm use 22` 후 다시 시도해주세요.');
15
15
  process.exit(1);
16
16
  }
17
+ // 프로세스 이름을 'node' 가 아닌 'shellbase' 로 바꾼다.
18
+ // 리눅스의 메모리 지킴이(earlyoom 등)는 흔히 "빌드 도구를 먼저 죽여라" 는 뜻으로
19
+ // `--prefer ^(cc1|gcc|node|npm|vite|tsc|...)$` 를 걸어두는데, 이 규칙은 명령줄이 아니라
20
+ // 프로세스 이름(/proc/<pid>/comm)만 본다 — Node 로 만든 것은 전부 이름이 'node' 라
21
+ // 에이전트가 겨우 수십 MB 를 쓰고 있어도 우선 사살 대상으로 뽑힌다.
22
+ // (실측: 에이전트 oom_score 800 + 이름 보너스 300 = 1100 으로, 500MB 쓰는 프로세스보다 높았다)
23
+ // 에이전트가 죽으면 그 안의 세션이 전부 함께 죽으므로 이름부터 빼둔다.
24
+ // 명령줄은 그대로 남겨서 `ps` 에서는 여전히 --dir/--name 이 보인다.
25
+ process.title = ['shellbase', ...process.argv.slice(2)].join(' ');
17
26
  // 설치 스크립트가 "제대로 깔렸는지" 확인할 때 `shellbase --version` 을 부른다.
18
27
  const require = createRequire(import.meta.url);
19
28
  const { version } = require('../package.json');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellbase",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "내 컴퓨터 터미널(특히 Claude Code 세션)을 폰 브라우저로 실시간 접속하게 해주는 데스크톱 에이전트",
5
5
  "type": "module",
6
6
  "bin": {