deel-local-cli 1.5.2 → 1.5.4
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.en.md +6 -3
- package/README.md +6 -3
- package/package.json +1 -1
- package/src/commands.js +99 -0
- package/src/i18n/en.js +16 -1
- package/src/i18n/index.js +52 -3
- package/src/i18n/ko.js +18 -3
- package/src/repl.js +14 -1
- package/src/ui/inputbox.js +16 -1
- package/src/ui/motion.js +20 -1
- package/src/ui/office.js +161 -16
- package/src/ui/screen.js +340 -319
package/src/ui/office.js
CHANGED
|
@@ -78,9 +78,18 @@ const C = {
|
|
|
78
78
|
화면: 45, 화면꺼짐: 239, 화면글: 123, 살: 223,
|
|
79
79
|
머리: [52, 240, 94, 130], 옷: [67, 131, 71, 97],
|
|
80
80
|
밤: 17, 별: 226, 낮: 111, 구름: 255,
|
|
81
|
+
새벽: 153, 노을: 173, 노을구름: 217, 별흐림: 250,
|
|
82
|
+
해: 226, 아침해: 229, 노을해: 208, 달: 230,
|
|
83
|
+
시계판: 253, 머그: 254, 커피: 94,
|
|
81
84
|
종이: 255, 종이어둠: 250, 쪽지: 227, 쪽지끝: 120, 초록: 46, 넘침: 208,
|
|
82
85
|
};
|
|
83
86
|
|
|
87
|
+
// 하루가 가면 방도 저문다. [벽, 바닥]
|
|
88
|
+
const 방색 = {
|
|
89
|
+
아침: [C.벽, C.바닥], 낮: [C.벽, C.바닥],
|
|
90
|
+
노을: [237, 137], 밤: [236, C.바닥줄],
|
|
91
|
+
};
|
|
92
|
+
|
|
84
93
|
// ── 픽셀 판 ─────────────────────────────────────────────────────────────
|
|
85
94
|
class 판 {
|
|
86
95
|
constructor(가로, 세로칸) {
|
|
@@ -187,16 +196,27 @@ function 자리색(자세, 머리, 옷) {
|
|
|
187
196
|
export function 사무실줄들(상태, 폭) {
|
|
188
197
|
const {
|
|
189
198
|
일꾼들 = [], 읽은파일 = 0, 고친파일 = 0, 할일 = 0, 끝난일 = 0,
|
|
190
|
-
부른횟수 = 0, 창 = 0, 틱 = 0,
|
|
199
|
+
부른횟수 = 0, 창 = 0, 틱 = 0, 걸린초 = 0,
|
|
191
200
|
} = 상태;
|
|
192
201
|
|
|
193
202
|
const 가로 = Math.max(60, 폭);
|
|
194
203
|
const p = new 판(가로, 세로);
|
|
195
|
-
p.칠하기(0, 0, 가로, 벽, C.벽);
|
|
196
|
-
p.칠하기(0, 벽, 가로, 1, C.굽도리);
|
|
197
|
-
p.칠하기(0, 벽 + 1, 가로, 세로 - 벽 - 1, C.바닥);
|
|
198
204
|
|
|
199
|
-
|
|
205
|
+
// 컨텍스트가 차는 만큼 하루가 간다. 넷으로 나눈다 — 둘이면 5% 와 50% 가
|
|
206
|
+
// 똑같은 대낮이라 창이 아무 말도 안 하게 된다.
|
|
207
|
+
const 하늘 = 창 >= 0.8 ? '밤' : 창 >= 0.55 ? '노을' : 창 >= 0.25 ? '낮' : '아침';
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
* 방 안도 같이 저문다. 창만 어두워지고 벽은 대낮이면 창이 그림 액자처럼
|
|
211
|
+
* 보인다 — 저 창이 이 방의 창이라는 것이 안 읽힌다.
|
|
212
|
+
*
|
|
213
|
+
* 사람과 책상은 안 어둡게 한다. 이 방을 켠 이유가 자리를 읽는 것인데,
|
|
214
|
+
* 밤이라고 그게 안 보이면 분위기를 위해 본문을 버린 셈이 된다.
|
|
215
|
+
*/
|
|
216
|
+
const [벽색, 바닥색] = 방색[하늘];
|
|
217
|
+
p.칠하기(0, 0, 가로, 벽, 벽색);
|
|
218
|
+
p.칠하기(0, 벽, 가로, 1, C.굽도리);
|
|
219
|
+
p.칠하기(0, 벽 + 1, 가로, 세로 - 벽 - 1, 바닥색);
|
|
200
220
|
|
|
201
221
|
// 화이트보드 18×5 — 할 일. 끝난 것은 초록, 남은 것은 노랑.
|
|
202
222
|
{
|
|
@@ -246,25 +266,100 @@ export function 사무실줄들(상태, 폭) {
|
|
|
246
266
|
p.올리기(가로 - 15, 0, 그림, { R: C.검정, L: C.초록, l: C.쇠진, O: C.넘침 });
|
|
247
267
|
}
|
|
248
268
|
|
|
249
|
-
|
|
269
|
+
/*
|
|
270
|
+
* ── 창밖 — 컨텍스트가 차는 만큼 하루가 간다 ──────────────────────────
|
|
271
|
+
*
|
|
272
|
+
* 아침 → 낮 → 노을 → 밤. 넷은 꾸밈이 아니라 **컨텍스트가 얼마나 찼는가**
|
|
273
|
+
* 하나를 네 칸으로 나눈 것이다. 노을이 들면 슬슬 접을 때고, 밤이면 이미
|
|
274
|
+
* 늦은 것이다 — 숫자를 안 읽고 곁눈으로 봐도 그게 보인다.
|
|
275
|
+
*
|
|
276
|
+
* 예전에는 낮/밤 둘뿐이라 5% 와 50% 가 똑같이 환한 대낮이었다. 컨텍스트가
|
|
277
|
+
* 반이나 찬 것과 거의 안 찬 것이 같은 그림이면, 이 창은 아무 말도 안 한다.
|
|
278
|
+
*/
|
|
250
279
|
{
|
|
251
280
|
const 시작 = 21;
|
|
252
281
|
const 남 = 가로 - 15 - 시작;
|
|
253
282
|
const 창수 = Math.max(0, Math.floor(남 / 18));
|
|
283
|
+
|
|
284
|
+
/*
|
|
285
|
+
* 해는 동쪽에서 낮게 떠 한낮에 높이 오고, 서쪽으로 기울었다가 달로 바뀐다.
|
|
286
|
+
* 자리가 곧 시각이라, 세 칸짜리 하늘에서도 하루가 도는 것이 보인다.
|
|
287
|
+
* 3×2 로 그린다 — 2×1 짜리 점은 구름과 구별이 안 됐다.
|
|
288
|
+
*/
|
|
289
|
+
const 하늘것 = {
|
|
290
|
+
아침: { k: 2, r: 1 }, 낮: { k: 4, r: 0 }, 노을: { k: 9, r: 1 }, 밤: { k: 10, r: 0 },
|
|
291
|
+
}[하늘];
|
|
292
|
+
const 칠 = {
|
|
293
|
+
아침: { F: C.쇠어둠, S: C.새벽, c: C.구름, o: C.아침해 },
|
|
294
|
+
낮: { F: C.쇠어둠, S: C.낮, c: C.구름, o: C.해 },
|
|
295
|
+
노을: { F: C.쇠어둠, S: C.노을, c: C.노을구름, o: C.노을해 },
|
|
296
|
+
밤: { F: C.쇠어둠, S: C.밤, c: C.별, o: C.달 },
|
|
297
|
+
}[하늘];
|
|
298
|
+
|
|
299
|
+
/*
|
|
300
|
+
* 구름은 흐르고 별은 깜빡인다. 이 둘만은 숫자가 아니다 — 방이 멈춰 있지
|
|
301
|
+
* 않다는 것만 말한다. 그래서 아주 느리게 둔다(구름 14판, 별 9판에 한 번).
|
|
302
|
+
* 빨리 움직이면 눈이 그쪽으로 끌려가서, 정작 읽어야 할 자리·쪽지·불빛을
|
|
303
|
+
* 안 보게 된다.
|
|
304
|
+
*
|
|
305
|
+
* 구름은 **덩어리**여야 한다. 칸마다 따로 주사위를 굴렸더니 흰 점이
|
|
306
|
+
* 흩뿌려져서, 구름이 아니라 화면 잡티로 보였다. 가운데 줄을 넓게 잡아
|
|
307
|
+
* 뭉게구름 모양을 만든다.
|
|
308
|
+
*/
|
|
309
|
+
const 흐름 = Math.floor(틱 / 14);
|
|
310
|
+
const 깜빡 = Math.floor(틱 / 9);
|
|
311
|
+
const 구름폭 = [1, 3, 2];
|
|
312
|
+
const 구름인가 = (i, r, k) => {
|
|
313
|
+
for (const b of [0, 1]) {
|
|
314
|
+
const 중심 = ((i * 9 + b * 11 + 흐름) % 22) - 4;
|
|
315
|
+
if (Math.abs(k - 중심) <= 구름폭[r]) return true;
|
|
316
|
+
}
|
|
317
|
+
return false;
|
|
318
|
+
};
|
|
319
|
+
|
|
254
320
|
for (let i = 0; i < 창수; i++) {
|
|
255
321
|
const 그림 = ['FFFFFFFFFFFFFFFF'];
|
|
256
322
|
for (let r = 0; r < 3; r++) {
|
|
257
323
|
let 줄 = 'F';
|
|
258
324
|
for (let k = 0; k < 14; k++) {
|
|
259
|
-
|
|
260
|
-
|
|
325
|
+
if (k === 7) { 줄 += 'F'; continue; } // 창틀 세로대
|
|
326
|
+
const 해자리 = (r === 하늘것.r || r === 하늘것.r + 1)
|
|
327
|
+
&& k >= 하늘것.k && k < 하늘것.k + 3;
|
|
328
|
+
if (해자리) { 줄 += 'o'; continue; }
|
|
329
|
+
if (하늘 === '밤') {
|
|
330
|
+
const h = (i * 37 + r * 19 + k * 11) % 31;
|
|
331
|
+
줄 += (h < 4 && (h + 깜빡) % 4 !== 0) ? 'c' : 'S';
|
|
332
|
+
} else {
|
|
333
|
+
줄 += 구름인가(i, r, k) ? 'c' : 'S';
|
|
334
|
+
}
|
|
261
335
|
}
|
|
262
336
|
그림.push(줄 + 'F');
|
|
263
337
|
}
|
|
264
338
|
그림.push('FFFFFFFFFFFFFFFF');
|
|
265
|
-
p.올리기(시작 + i * 18, 0, 그림,
|
|
266
|
-
|
|
267
|
-
|
|
339
|
+
p.올리기(시작 + i * 18, 0, 그림, 칠);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/*
|
|
343
|
+
* 벽시계 — 이번 턴이 얼마나 걸렸나.
|
|
344
|
+
*
|
|
345
|
+
* 상자 오른쪽 끝에 걸린 시간이 이미 초로 찍히지만, 그건 읽어야 보인다.
|
|
346
|
+
* 바늘은 안 읽어도 보인다 — 한 바퀴가 1분이라, 두 바퀴째면 "오래 걸리는
|
|
347
|
+
* 중이구나" 가 숫자를 세기 전에 온다.
|
|
348
|
+
*
|
|
349
|
+
* 창을 놓고 남는 자리에만 건다. 좁은 터미널에서 시계 때문에 창이 하나
|
|
350
|
+
* 줄면 그건 손해다 — 창이 이 방의 본문이다.
|
|
351
|
+
*/
|
|
352
|
+
const 남은칸 = 남 - 창수 * 18;
|
|
353
|
+
if (남은칸 >= 8) {
|
|
354
|
+
const cx = 시작 + 창수 * 18 + Math.floor((남은칸 - 7) / 2);
|
|
355
|
+
p.올리기(cx, 0, [' TTTTT ', 'TWWWWWT', 'TWWWWWT', 'TWWWWWT', ' TTTTT '],
|
|
356
|
+
{ T: C.검정, W: C.시계판 });
|
|
357
|
+
// 한 바퀴에 1분. 7.5초마다 한 칸씩 — 도는 것이 보이면서도 매 판 다시
|
|
358
|
+
// 그릴 만큼 부산하지는 않다.
|
|
359
|
+
const 칸 = Math.floor((걸린초 % 60) / 7.5) % 8;
|
|
360
|
+
const [dx, dy] = [[0, -2], [1, -1], [2, 0], [1, 1], [0, 2], [-1, 1], [-2, 0], [-1, -1]][칸];
|
|
361
|
+
p.찍기(cx + 3, 2, C.검정);
|
|
362
|
+
p.찍기(cx + 3 + dx, 2 + dy, C.검정);
|
|
268
363
|
}
|
|
269
364
|
}
|
|
270
365
|
|
|
@@ -310,10 +405,29 @@ export function 사무실줄들(상태, 폭) {
|
|
|
310
405
|
if (넘친자리 && i === 자리수 - 1) p.칠하기(x + 자리폭 - 2, y + 자리높이 - 3, 2, 2, C.넘침);
|
|
311
406
|
// 조는 사람 머리 위 z
|
|
312
407
|
if (자세 === '졸기' && 짝) p.칠하기(x + 13, y + 2, 2, 1, C.종이);
|
|
313
|
-
|
|
314
|
-
|
|
408
|
+
/*
|
|
409
|
+
* 조는 자리에는 식은 커피가 있다.
|
|
410
|
+
*
|
|
411
|
+
* 이것도 지어낸 것이 아니라 조는 것과 **같은 수**(45초 넘김)를 한 번 더
|
|
412
|
+
* 다르게 보인 것이다. 자는 사람이 화면 뒤로 반쯤 숨는 자세라, 좁은
|
|
413
|
+
* 터미널에서는 조는지 자리를 비운 것인지 헷갈렸다. 머그는 안 숨는다.
|
|
414
|
+
*/
|
|
415
|
+
if (자세 === '졸기') {
|
|
416
|
+
p.칠하기(x + 2, y + 10, 2, 2, C.머그);
|
|
417
|
+
p.칠하기(x + 2, y + 10, 2, 1, C.커피);
|
|
418
|
+
}
|
|
419
|
+
/*
|
|
420
|
+
* 고친 파일은 책상 위 종이로. 한 자리에 두 장까지.
|
|
421
|
+
*
|
|
422
|
+
* 전에는 자리마다 한 장이라 다섯 자리짜리 방에서 다섯 장이 상한이었고,
|
|
423
|
+
* 여섯 개를 고치나 스무 개를 고치나 같은 그림이었다. 자리당 두 장으로
|
|
424
|
+
* 두면 눈금이 두 배가 된다 — 없는 자리를 만들지 않으면서.
|
|
425
|
+
*/
|
|
426
|
+
const 종이몫 = Math.min(2, Math.max(0, 고친파일 - i * 2));
|
|
427
|
+
for (let n = 0; n < 종이몫; n++) p.칠하기(x + 13 - n * 4, y + 9, 3, 1, C.종이);
|
|
315
428
|
}
|
|
316
429
|
|
|
430
|
+
|
|
317
431
|
return p.줄들();
|
|
318
432
|
}
|
|
319
433
|
|
|
@@ -350,9 +464,22 @@ export const 최소폭 = 60;
|
|
|
350
464
|
* 정해야지 화면 높이로 정하면 안 된다. 창을 줄였다 늘였다 할 때마다 상자 안
|
|
351
465
|
* 그림이 기사였다 돌림표였다 하면 무슨 규칙인지 아무도 모른다.
|
|
352
466
|
*/
|
|
467
|
+
/*
|
|
468
|
+
* 설정 파일에서 켜 뒀나. `/motion 사무실` 이 여기에 넣는다.
|
|
469
|
+
*
|
|
470
|
+
* motion.js 와 같은 이유로 파일을 여기서 안 읽는다 — 판마다 불리는 자리다.
|
|
471
|
+
* 환경변수가 이긴다(한 번만 다르게 보고 싶을 때, 그리고 검사가 쓰는 길).
|
|
472
|
+
*/
|
|
473
|
+
let 설정으로켰나 = false;
|
|
474
|
+
export function 사무실설정(켬) { 설정으로켰나 = !!켬; }
|
|
475
|
+
|
|
353
476
|
export function 켜달라했나() {
|
|
354
|
-
const
|
|
355
|
-
|
|
477
|
+
const raw = process.env.DEEL_OFFICE;
|
|
478
|
+
if (raw !== undefined) {
|
|
479
|
+
const v = String(raw).trim().toLowerCase();
|
|
480
|
+
return v === '1' || v === 'on' || v === '켬' || v === '사무실';
|
|
481
|
+
}
|
|
482
|
+
return 설정으로켰나;
|
|
356
483
|
}
|
|
357
484
|
|
|
358
485
|
export function 켜나(rows = process.stdout.rows, cols = process.stdout.columns) {
|
|
@@ -373,7 +500,7 @@ export function 켜나(rows = process.stdout.rows, cols = process.stdout.columns
|
|
|
373
500
|
* @param {object} 일감 지금 도는 일 (없으면 null)
|
|
374
501
|
* @param {number} 틱
|
|
375
502
|
*/
|
|
376
|
-
export function 상태만들기(session, 일감, 틱 = 0, 할일들 = [], 도는하위 = 0) {
|
|
503
|
+
export function 상태만들기(session, 일감, 틱 = 0, 할일들 = [], 도는하위 = 0, 함께도는 = 0) {
|
|
377
504
|
const s = session ?? {};
|
|
378
505
|
const 쓴것 = s.usage ?? {};
|
|
379
506
|
const 총토큰 = (쓴것.in ?? 0) + (쓴것.out ?? 0);
|
|
@@ -386,6 +513,8 @@ export function 상태만들기(session, 일감, 틱 = 0, 할일들 = [], 도는
|
|
|
386
513
|
* 것을 그대로 쓴다 — motion.js 가 쓰는 그 갈래다.
|
|
387
514
|
*/
|
|
388
515
|
const 일꾼들 = [];
|
|
516
|
+
// 벽시계가 볼 값. 일이 없으면 0 — 바늘이 12 시에 선다.
|
|
517
|
+
let 걸린초 = 0;
|
|
389
518
|
if (일감) {
|
|
390
519
|
/*
|
|
391
520
|
* 오래 끌면 존다.
|
|
@@ -398,6 +527,7 @@ export function 상태만들기(session, 일감, 틱 = 0, 할일들 = [], 도는
|
|
|
398
527
|
*/
|
|
399
528
|
const 지난 = Number.isFinite(일감.시작) ? Date.now() - 일감.시작 : 0;
|
|
400
529
|
const 오래됐나 = 일감.갈래 === '느긋' || 지난 >= 느긋해질때;
|
|
530
|
+
걸린초 = Math.floor(지난 / 1000);
|
|
401
531
|
const 갈래 = 오래됐나 ? '졸기'
|
|
402
532
|
: ['읽기', '웹'].includes(일감.갈래) ? '읽기'
|
|
403
533
|
: ['쓰기', '명령', '답'].includes(일감.갈래) ? '쓰기' : '대기';
|
|
@@ -414,11 +544,26 @@ export function 상태만들기(session, 일감, 틱 = 0, 할일들 = [], 도는
|
|
|
414
544
|
* 모른다고 두는 편이 낫다 — 자리가 찼다는 사실은 그대로 보인다.
|
|
415
545
|
*/
|
|
416
546
|
일꾼들.push({ 갈래 });
|
|
547
|
+
/*
|
|
548
|
+
* 읽기 도구를 한꺼번에 돌리면 그만큼 진짜로 동시에 돈다.
|
|
549
|
+
*
|
|
550
|
+
* 방이 늘 한 명짜리로 보이던 진짜 이유가 여기 있었다. 하위 작업은
|
|
551
|
+
* loop.js 가 `for await` 로 기다리므로 **순서대로** 돈다 — 도는하위 는
|
|
552
|
+
* 사실상 0 아니면 1 이고, 겹치는 것은 하위가 또 하위를 떼어 낼 때뿐이다.
|
|
553
|
+
* 정작 동시에 도는 것은 읽기 묶음(loop.js 의 Promise.all)인데, 그 개수는
|
|
554
|
+
* 화면에 「3개를 함께 돌립니다」로 이미 찍히고 있었는데도 방만 안 봤다.
|
|
555
|
+
*
|
|
556
|
+
* 자세는 지어내는 것이 아니다. 묶어서 돌리는 것은 읽기 전용 도구뿐이라
|
|
557
|
+
* (Read·Glob·Grep·Skill·WebFetch) 저 자리는 전부 읽는 중인 게 맞다.
|
|
558
|
+
* 첫 자리는 이미 위에서 넣었으므로 하나를 뺀다.
|
|
559
|
+
*/
|
|
560
|
+
for (let i = 1; i < Math.max(0, 함께도는); i++) 일꾼들.push({ 갈래: '읽기' });
|
|
417
561
|
for (let i = 0; i < Math.max(0, 도는하위); i++) 일꾼들.push({ 갈래: '대기' });
|
|
418
562
|
}
|
|
419
563
|
|
|
420
564
|
return {
|
|
421
565
|
일꾼들,
|
|
566
|
+
걸린초,
|
|
422
567
|
읽은파일: s.filesRead?.size ?? 0,
|
|
423
568
|
고친파일: s.changes?.size ?? 0,
|
|
424
569
|
끝난일: 할일들.filter((t) => t.state === 'done').length,
|