deel-local-cli 2.1.6 → 2.1.8
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.ko.md +4 -2
- package/README.md +4 -2
- package/package.json +1 -1
- package/src/completion.js +5 -2
- package/src/repl.js +69 -0
- package/src/safety/keystore.js +6 -1
- package/src/tools/clipboard.js +12 -0
- package/src/ui/inputbox.js +14 -0
- package/src/ui/screen.js +9 -0
package/README.ko.md
CHANGED
|
@@ -323,7 +323,7 @@ deel --offline
|
|
|
323
323
|
무엇이 어디로 갈 수 있는지는 켤 때 화면 맨 위에 늘 적혀 있습니다.
|
|
324
324
|
|
|
325
325
|
```
|
|
326
|
-
deel 2.1.
|
|
326
|
+
deel 2.1.8 ⌂ 이 안
|
|
327
327
|
보냄 이 컴퓨터 안 127.0.0.1:11434 ← 여기 말고는 어디로도 안 갑니다
|
|
328
328
|
```
|
|
329
329
|
|
|
@@ -1341,7 +1341,9 @@ zip 은 진짜 `unzip` 으로, tar 는 진짜 `tar` 가 만든 것을 읽혀 교
|
|
|
1341
1341
|
|
|
1342
1342
|
| 판 | 무엇이 바뀌었나 |
|
|
1343
1343
|
|---|---|
|
|
1344
|
-
| **[2.1.
|
|
1344
|
+
| **[2.1.8](docs/ko/releases/2.1.md#218)** | Ctrl+Z 뒤 `fg` 하면 말없이 끝나던 것을 고쳤습니다(맥 · 리눅스) — 그대로 이어지고 입력칸 · 승인 물음을 다시 그리며, 커널이 재우기를 버리는 자리(`ssh -t` · `docker run -it`)에서도 날것 모드로 돌아옵니다. 관문이 진짜 터미널에서 deel 을 몹니다 |
|
|
1345
|
+
| [2.1.7](docs/ko/releases/2.1.md#217) | 맥 기본 셸 zsh 에서 파일 이름 Tab 이 됩니다(`bad substitution` 오류였음) · 12MB 넘는 클립보드 그림은 osascript 탓이 아니라 「너무 큽니다」 · 자모로 풀린(NFD) 한글 프로필 이름이 키체인에 주인 없는 항목을 안 남김 |
|
|
1346
|
+
| [2.1.6](docs/ko/releases/2.1.md#216) | 맥에서 제대로 돌게 — 길거나 손으로 바꾼 키체인 열쇠 · 잠긴 키체인, `/tmp` · `/var`(`/private` 링크) 아래 믿은 폴더를 알아봄, 파이프가 늦게 읽어도 64KB 넘는 출력이 안 잘림(맥 · 리눅스). 관문 CI 에 맥이 들어갔습니다 |
|
|
1345
1347
|
| [2.1.5](docs/ko/releases/2.1.md#215) | 급한 보안 수정 — 셸 명령이 작업 폴더 밖으로 새던 자리를 막았습니다. 빗금 없는 `..`(`find .. -delete` · `rd /s /q ..`) · `$PWD` · `%CD%` · `$OLDPWD` · 먼저 옮긴 적 없는 `cd -` · `C:..` · 파워셸의 다른 이름(`ri` · `del` …) |
|
|
1346
1348
|
| [2.1.4](docs/ko/releases/2.1.md#214) | 브라우저로 로그인 — `deel setup` 3번이 열쇠 없이 OpenRouter 계정 로그인(OAuth PKCE)으로 붙습니다. 열쇠 하나로 Claude · GPT · Grok · Kimi. SSH 는 `--no-browser`, `sk-or-` 열쇠를 알아보고, 긴 모델 목록은 이름으로 좁힙니다 |
|
|
1347
1349
|
| [2.1.3](docs/ko/releases/2.1.md#213) | 제품 기능 — 도구를 글로 부르는 모델도 알아듣고, `deel run --continue`·`--resume`·`--events` 와 결과의 바뀐 파일(`files`)이 생겼고, git 저장소면 스크립트가 바꾼 것도 `/undo` 로 돌아가고, 언어 서버 없이도 문법을 보고, Outline 이 많이 불리는 파일부터 싣고, MCP 가 주소로 붙어 자료 · 프롬프트까지 씁니다 |
|
package/README.md
CHANGED
|
@@ -396,7 +396,7 @@ deel --offline
|
|
|
396
396
|
The destination is printed at the top of every session:
|
|
397
397
|
|
|
398
398
|
```
|
|
399
|
-
deel 2.1.
|
|
399
|
+
deel 2.1.8 ⌂ inside
|
|
400
400
|
Sends to this machine 127.0.0.1:11434 ← nowhere else
|
|
401
401
|
```
|
|
402
402
|
|
|
@@ -1424,7 +1424,9 @@ so one run tells you everything.
|
|
|
1424
1424
|
|
|
1425
1425
|
| Version | What changed |
|
|
1426
1426
|
|---|---|
|
|
1427
|
-
| **[2.1.
|
|
1427
|
+
| **[2.1.8](docs/en/releases/2.1.md#218)** | Ctrl+Z then `fg` no longer makes deel quit silently (macOS, Linux) — it carries on, redraws the input box or the approval question, and restores raw mode even where the kernel drops the suspend (`ssh -t`, `docker run -it`). The gate now drives deel in a real terminal |
|
|
1428
|
+
| [2.1.7](docs/en/releases/2.1.md#217) | Tab completion for file names works in zsh, the default shell on macOS (it printed `bad substitution`); a clipboard image over 12 MB says it is too big instead of blaming osascript; a decomposed (NFD) Korean profile name no longer leaves orphaned keychain items |
|
|
1429
|
+
| [2.1.6](docs/en/releases/2.1.md#216) | Works properly on macOS — long or hand-edited keychain keys, a locked keychain, folders under `/tmp` · `/var` (links to `/private`) recognized as trusted, and output over 64 KB no longer cut off when a pipe reads slowly (macOS and Linux). macOS joins the gate CI |
|
|
1428
1430
|
| [2.1.5](docs/en/releases/2.1.md#215) | Urgent security fix — shell commands could reach outside the working folder. Now blocked: a bare `..` (`find .. -delete`, `rd /s /q ..`), `$PWD`, `%CD%`, `$OLDPWD`, a `cd -` with no earlier move, `C:..`, and PowerShell aliases (`ri`, `del` …) |
|
|
1429
1431
|
| [2.1.4](docs/en/releases/2.1.md#214) | Log in with a browser — `deel setup` option 3 connects to OpenRouter by logging in (OAuth PKCE), no key to paste; one key for Claude, GPT, Grok and Kimi. `--no-browser` for SSH, `sk-or-` keys recognized, and long model lists narrow by name |
|
|
1430
1432
|
| [2.1.3](docs/en/releases/2.1.md#213) | Product features — models that write tool calls as text are understood, `deel run --continue`/`--resume`/`--events` and changed `files` in the result, `/undo` brings back what a script changed in a git repository, a syntax check without a language server, Outline loads the most imported files first, and MCP attaches by URL with resources and prompts |
|
package/package.json
CHANGED
package/src/completion.js
CHANGED
|
@@ -179,8 +179,11 @@ _deel_paths() {
|
|
|
179
179
|
if type compopt >/dev/null 2>&1; then
|
|
180
180
|
compopt -o filenames 2>/dev/null
|
|
181
181
|
elif [[ -z "$_deel_q" ]]; then
|
|
182
|
-
local
|
|
183
|
-
|
|
182
|
+
local _deel_x
|
|
183
|
+
local -a _deel_t
|
|
184
|
+
_deel_t=()
|
|
185
|
+
for _deel_x in "\${COMPREPLY[@]}"; do _deel_t+=("$(printf '%q' "$_deel_x")"); done
|
|
186
|
+
COMPREPLY=("\${_deel_t[@]}")
|
|
184
187
|
fi
|
|
185
188
|
return 0
|
|
186
189
|
}
|
package/src/repl.js
CHANGED
|
@@ -587,6 +587,8 @@ export async function chatLoop(opts = {}) {
|
|
|
587
587
|
let 입력기다림 = false;
|
|
588
588
|
// 되묻는 중이면 그 앞머리. 상자 대신 한 줄로 되비춘다.
|
|
589
589
|
let 묻는중 = null;
|
|
590
|
+
// 되묻는 중이면 그 앞머리 — 화면을 안 가린다(줄 화면에서도 든다). Ctrl+Z 로 재웠다 깨울 때 물음째 되찍는 데 쓴다.
|
|
591
|
+
let 물음앞 = null;
|
|
590
592
|
// 이번 틱에 다시 그리기로 이미 잡아 뒀나 (붙여넣기로 키가 쏟아질 때)
|
|
591
593
|
let 그릴예정 = false;
|
|
592
594
|
const 먹통 = { write() { return true; }, end() {}, on() {}, once() {}, emit() {}, removeListener() {} };
|
|
@@ -932,6 +934,71 @@ export async function chatLoop(opts = {}) {
|
|
|
932
934
|
process.stdout.write('\x1b[?2004h');
|
|
933
935
|
process.on('exit', () => { try { process.stdout.write('\x1b[?2004l'); } catch { /* 이미 닫혔다 */ } });
|
|
934
936
|
|
|
937
|
+
/*
|
|
938
|
+
* ── Ctrl+Z 로 재웠다가 fg 로 깨우기 ──────────────────────────────────
|
|
939
|
+
*
|
|
940
|
+
* readline 은 Ctrl+Z 를 받으면 날것 모드를 풀고 스스로 잠든다. 그런데 깨울 때는 날것 모드만 되돌리고
|
|
941
|
+
* 입력을 **멈춰 둔 채** 'SIGCONT' 를 낸다 — 그걸 받아 다시 여는 쪽이 있어야 한다는 뜻이다(Node 문서도
|
|
942
|
+
* `rl.on('SIGCONT', () => rl.prompt())` 를 짝으로 든다). 여기는 아무도 안 받았다. 그러면 붙든 것이
|
|
943
|
+
* 하나도 없어진 node 가 fg 하자마자 **조용히 끝난다** — 말 한마디 없이 셸로 떨어지고, 이어서 친 글은
|
|
944
|
+
* 셸이 명령으로 받는다(「bash: 가라: command not found」). 맥·리눅스 × node 20·22 진짜 pty 에서 넷 다
|
|
945
|
+
* 그랬고, 답이 흐르는 중에 재워도 답이 끝나는 순간 같은 자리에서 끝났다(47회차 뒤 사냥).
|
|
946
|
+
*
|
|
947
|
+
* 잠드는 일을 readline 에게 안 맡기고 여기서 한다('SIGTSTP' 를 들으면 readline 은 스스로 안 잔다).
|
|
948
|
+
* 그래야 잠들기 **전에** 우리가 켠 것을 끌 수 있다 — 붙여넣기 표지(위)와 돌림표가 숨긴 커서. 안 끄면
|
|
949
|
+
* 재워 둔 동안 셸이 그걸 물려받는다. 깨면 날것 모드 · 붙여넣기 표지를 되돌리고 입력칸을 새로 그린다.
|
|
950
|
+
* 그 사이 셸이 찍은 줄들 때문에 그려 둔 상자 자리는 이미 틀어졌다 — 잊고 지금 자리에 그린다.
|
|
951
|
+
* (윈도에는 Ctrl+Z 로 재우는 일이 없다 — readline 이 이 이벤트를 아예 안 낸다.)
|
|
952
|
+
*/
|
|
953
|
+
rl.on('SIGTSTP', () => {
|
|
954
|
+
try { process.stdout.write('\x1b[?2004l\x1b[?25h'); } catch { /* 이미 닫혔다 */ }
|
|
955
|
+
try { process.stdin.setRawMode?.(false); } catch { /* 터미널이 없어졌다 */ }
|
|
956
|
+
/*
|
|
957
|
+
* 깨우기는 **한 번만**, 그리고 두 길로 부른다.
|
|
958
|
+
*
|
|
959
|
+
* SIGCONT 만 기다리면 안 오는 판이 있다 — 고아 프로세스 그룹(`ssh -t 호스트 deel` · `docker run -it` ·
|
|
960
|
+
* `exec deel`)에서는 커널이 SIGTSTP 를 그냥 버린다. 그러면 안 잠들었는데 날것 모드만 꺼진 채 남아,
|
|
961
|
+
* 키가 엔터 전까지 안 오고 화살표·한글 지우기가 터미널 몫이 된다(readline 이 스스로 잘 때도 같았다).
|
|
962
|
+
* 자기에게 보낸 신호는 kill() 이 돌아오기 **전에** 닿는다(POSIX) — 그러니 kill 다음 차례에 오는
|
|
963
|
+
* setImmediate 는 「깨어난 뒤」 이거나 「안 잠든 것」 둘 중 하나다. 어느 쪽이든 되돌리는 것이 맞다.
|
|
964
|
+
*/
|
|
965
|
+
let 깸 = false;
|
|
966
|
+
const 깨우기 = () => {
|
|
967
|
+
if (깸) return;
|
|
968
|
+
깸 = true;
|
|
969
|
+
process.off('SIGCONT', 깨우기);
|
|
970
|
+
if (closed) return;
|
|
971
|
+
try { process.stdin.setRawMode?.(true); } catch { /* 터미널이 없어졌다 */ }
|
|
972
|
+
try { process.stdout.write('\x1b[?2004h'); } catch { /* 이미 닫혔다 */ }
|
|
973
|
+
화면.깨어남?.();
|
|
974
|
+
/*
|
|
975
|
+
* 셸이 그 사이 제 글을 찍었으니 입력칸·물음을 지금 줄에 새로 찍는다. 커서는 글 끝에 둔다 — 중간에
|
|
976
|
+
* 두려면 왼쪽으로 몇 칸을 가야 하는데, 긴 글이 접혀 여러 줄이 되면 그 셈이 줄을 못 넘는다.
|
|
977
|
+
* readline 의 커서도 끝으로 맞춘다. 화면과 어긋나면 다음에 친 글자가 엉뚱한 자리에 끼어든다.
|
|
978
|
+
*/
|
|
979
|
+
if (물음앞 !== null) {
|
|
980
|
+
// 승인 물음 — 줄 화면에서도 되찍는다(물음은 readline 이 아니라 우리가 찍은 글이라 readline 이 모른다).
|
|
981
|
+
rl.cursor = (rl.line ?? '').length;
|
|
982
|
+
process.stdout.write(`\r\x1b[2K${물음앞}${상자쓰나 ? c.white(펴기(rl.line)) : (rl.line ?? '')}`);
|
|
983
|
+
} else if (입력기다림) {
|
|
984
|
+
if (상자쓰나) {
|
|
985
|
+
// Ctrl+Z 키는 readline 다음에 우리 keypress 처리로도 가서 상자를 한 번 더 그린다. 여기서 먼저 그리는
|
|
986
|
+
// 것은 그 순서(듣개를 단 차례)에 기대지 않으려는 것이다 — 그래서 이 줄을 빼는 어긋은 지금은 안 잡힌다.
|
|
987
|
+
화면.입력갱신(session, 펴기(rl.line), rl.cursor ?? 0, 지금추천(펴기(rl.line)));
|
|
988
|
+
} else {
|
|
989
|
+
// 줄화면의 「❯」 도 readline 이 아니라 우리가 찍는다(screen.js 입력자리).
|
|
990
|
+
rl.cursor = (rl.line ?? '').length;
|
|
991
|
+
process.stdout.write(`\r\x1b[2K ${c.hcyan('❯')} ${rl.line ?? ''}`);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
// 일하는 중이면 그리지 않는다 — 상자 화면은 다음 틱의 일그리기가 잊은 자리에 새로 그리고,
|
|
995
|
+
// 줄 화면은 흘러가는 글이라 다시 그릴 것이 없다(돌림표의 커서만 깨어남 이 다시 숨긴다).
|
|
996
|
+
};
|
|
997
|
+
process.once('SIGCONT', 깨우기);
|
|
998
|
+
process.kill(process.pid, 'SIGTSTP');
|
|
999
|
+
setImmediate(깨우기);
|
|
1000
|
+
});
|
|
1001
|
+
|
|
935
1002
|
process.stdin.on('keypress', (_ch, key) => {
|
|
936
1003
|
if (key?.sequence === '\x1b[200~') {
|
|
937
1004
|
붙여넣는중 = true;
|
|
@@ -1235,6 +1302,7 @@ export async function chatLoop(opts = {}) {
|
|
|
1235
1302
|
* y 를 쳐도 화면에 아무것도 안 나타난다 — 먹은 건지 안 먹은 건지 모른다.
|
|
1236
1303
|
*/
|
|
1237
1304
|
묻는중 = 상자쓰나 ? 앞 : null;
|
|
1305
|
+
물음앞 = 앞;
|
|
1238
1306
|
/*
|
|
1239
1307
|
* 쌓아 둔 이어쓰기를 버릴 때는 **말한다.**
|
|
1240
1308
|
*
|
|
@@ -1314,6 +1382,7 @@ export async function chatLoop(opts = {}) {
|
|
|
1314
1382
|
clearTimeout(시계);
|
|
1315
1383
|
턴멈춤?.removeEventListener?.('abort', 이어멈춤);
|
|
1316
1384
|
묻는중 = null;
|
|
1385
|
+
물음앞 = null;
|
|
1317
1386
|
// 빼 뒀던 것을 앞에 되돌린다. 차례가 바뀌면 안 된다.
|
|
1318
1387
|
if (미리쳐둔.length) queue.unshift(...미리쳐둔);
|
|
1319
1388
|
}
|
package/src/safety/keystore.js
CHANGED
|
@@ -96,7 +96,12 @@ export const 기본키체인이름 = 'deel-gateway-key';
|
|
|
96
96
|
export function 키체인이름(프로필id = null) {
|
|
97
97
|
const 정한것 = process.env.DEEL_KEYCHAIN_NAME;
|
|
98
98
|
if (정한것) return 정한것;
|
|
99
|
-
|
|
99
|
+
/*
|
|
100
|
+
* 글자 모양을 NFC 로 맞춘다. 맥은 파일 이름 따위에서 한글을 자모로 푼 꼴(NFD)로 주기도 해서, 눈에는 같은
|
|
101
|
+
* `회사` 가 한 번은 `deel-gateway-key-회사`, 한 번은 해시 붙은 딴 자리로 갔다 — 다시 잠그면 옛 자리가
|
|
102
|
+
* 주인 없이 남았다(39회차 맥 실측). 읽기는 설정에 적힌 이름표로 하므로 이미 넣어 둔 열쇠는 그대로 풀린다.
|
|
103
|
+
*/
|
|
104
|
+
const 원래 = String(프로필id ?? '').normalize('NFC');
|
|
100
105
|
const id = 원래.trim().toLowerCase().replace(/[^a-z0-9가-힣._-]+/g, '-');
|
|
101
106
|
if (!id) return 기본키체인이름;
|
|
102
107
|
if (id === 원래) return `${기본키체인이름}-${id}`;
|
package/src/tools/clipboard.js
CHANGED
|
@@ -93,10 +93,21 @@ function 윈도우에서(방, 부르기) {
|
|
|
93
93
|
* PNG 512KB 만 넘어도 ENOBUFS 로 끊겼다 — 레티나 화면 캡처는 대개 그보다 커서
|
|
94
94
|
* 맥에서는 보통 캡처가 안 붙었다. 그림 한도의 두 배에 여유를 더해 잡는다.
|
|
95
95
|
*/
|
|
96
|
+
/*
|
|
97
|
+
* 받을 자리(maxBuffer)가 넘친 것은 「못 불렀다」 가 아니라 **그림이 크다** 는 뜻이다. 맥에서 12.5MB 캡처를
|
|
98
|
+
* 붙이면 「osascript 를 못 불렀습니다: spawnSync osascript ENOBUFS」 가 나왔다(42회차 맥 실측) — 사람은
|
|
99
|
+
* osascript 가 고장 난 줄 안다. 한도 넘침과 같은 말로 맞춘다.
|
|
100
|
+
*/
|
|
101
|
+
function 넘쳤나(r) { return r?.error?.code === 'ENOBUFS'; }
|
|
102
|
+
function 너무큰그림말() {
|
|
103
|
+
return `그림이 너무 큽니다 (한도 ${그림한도 / 1048576}MB 넘음) — 필요한 부분만 잘라서 다시 찍어 주세요.`;
|
|
104
|
+
}
|
|
105
|
+
|
|
96
106
|
function 맥에서(부르기) {
|
|
97
107
|
const r = 부르기('osascript', ['-e', 'the clipboard as «class PNGf»'], {
|
|
98
108
|
encoding: 'utf8', timeout: 20000, maxBuffer: 그림한도 * 2 + 1024 * 1024,
|
|
99
109
|
});
|
|
110
|
+
if (넘쳤나(r)) return { ok: false, 왜: 너무큰그림말() };
|
|
100
111
|
if (r.error) return { ok: false, 왜: `osascript 를 못 불렀습니다: ${r.error.message}` };
|
|
101
112
|
const 낸말 = String(r.stdout ?? '');
|
|
102
113
|
const m = /«data PNGf([0-9A-Fa-f]+)»/.exec(낸말);
|
|
@@ -150,6 +161,7 @@ function 리눅스에서(부르기) {
|
|
|
150
161
|
const 종류 = 부르기(x.이름, x.볼것, { encoding: 'utf8', timeout: 10000 });
|
|
151
162
|
if (!/image\/png/i.test(String(종류.stdout ?? ''))) continue;
|
|
152
163
|
const r = 부르기(x.이름, x.꺼내기, { timeout: 20000, maxBuffer: 64 * 1024 * 1024 });
|
|
164
|
+
if (넘쳤나(r)) return { ok: false, 왜: 너무큰그림말() };
|
|
153
165
|
if (r.error || !r.stdout?.length) {
|
|
154
166
|
const 탈 = r.error?.message || String(r.stderr ?? '').split('\n').find((l) => l.trim())?.trim() || '빈 응답';
|
|
155
167
|
못꺼냄 ??= `${x.이름}: ${탈}`;
|
package/src/ui/inputbox.js
CHANGED
|
@@ -576,6 +576,20 @@ export class InputBox {
|
|
|
576
576
|
});
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
+
/**
|
|
580
|
+
* 그려 둔 상자를 **잊는다** — 지우지 않고.
|
|
581
|
+
*
|
|
582
|
+
* Ctrl+Z 로 재운 동안 셸이 상자 아래에 제 글(「Stopped」 · 프롬프트 · fg 로 되찍는 명령줄)을 찍는다.
|
|
583
|
+
* 그러면 그린줄·커서위 로 올라가는 거리가 셸의 글 위로 떨어져, 다음 판이 셸 글을 덮고 옛 상자 반쪽이
|
|
584
|
+
* 남는다. 깨어난 자리는 셸이 남긴 새 줄이므로, 거기서 처음 그리듯 새로 그리게 둔다. 옛 상자는 위로
|
|
585
|
+
* 흘러간 기록이 된다(스크롤 자국일 뿐 대화를 안 지운다).
|
|
586
|
+
*/
|
|
587
|
+
잊기() {
|
|
588
|
+
this.그린줄 = 0;
|
|
589
|
+
this.커서위 = 0;
|
|
590
|
+
this.앞줄들 = null;
|
|
591
|
+
}
|
|
592
|
+
|
|
579
593
|
/** 상자를 지운다. 위쪽 대화는 안 건드린다. */
|
|
580
594
|
지우기() {
|
|
581
595
|
if (!this.그린줄) return;
|
package/src/ui/screen.js
CHANGED
|
@@ -236,6 +236,12 @@ export class LineScreen {
|
|
|
236
236
|
/** 사람이 치는 중인 글이 바뀌었다. 줄화면은 readline 이 알아서 되비춘다. */
|
|
237
237
|
입력갱신() { }
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Ctrl+Z 로 재웠다 깨어났다 (repl.js). 줄화면은 들고 있는 자리가 없다.
|
|
241
|
+
* 다만 돌림표가 도는 중이면 커서를 다시 숨긴다 — 잠들기 전에 셸 몫으로 보이게 돌려놨다.
|
|
242
|
+
*/
|
|
243
|
+
깨어남() { if (this.돌림) cursor.hide(); }
|
|
244
|
+
|
|
239
245
|
/** 일하는 중 미리 치는 글. 줄화면은 상자가 없어 보여 줄 자리가 없다. */
|
|
240
246
|
대기갱신() { }
|
|
241
247
|
|
|
@@ -393,6 +399,9 @@ export class BoxScreen extends LineScreen {
|
|
|
393
399
|
|
|
394
400
|
입력지움() { this.상자.지우기(); }
|
|
395
401
|
|
|
402
|
+
/** Ctrl+Z 로 재웠다 깨어났다 — 셸이 그 사이 글을 찍었으니 그려 둔 자리를 잊는다 (inputbox.js 의 잊기). */
|
|
403
|
+
깨어남() { super.깨어남(); this.상자.잊기(); }
|
|
404
|
+
|
|
396
405
|
close() {
|
|
397
406
|
this.상자.지우기();
|
|
398
407
|
super.close();
|