deel-local-cli 1.20.10 → 1.20.11

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/src/ui/intro.js CHANGED
@@ -35,6 +35,7 @@
35
35
  import { c, cursor, width } from './ansi.js';
36
36
  import { 말 } from '../i18n/index.js';
37
37
  import * as 큰이름 from './banner.js';
38
+ import { 끄라는값인가 } from './office.js';
38
39
 
39
40
  const 앞 = 'deel';
40
41
  const 꼬리 = '-local';
@@ -42,7 +43,7 @@ const 이름폭 = 앞.length + 꼬리.length; // 10
42
43
  const 들여 = ' ';
43
44
 
44
45
  /** 모션을 끄는 스위치. 그림 돌림표(motion.js)와 같은 스위치를 함께 본다. */
45
- export const 끔 = () => !!(process.env.DEEL_NO_INTRO || process.env.DEEL_NO_MOTION);
46
+ export const 끔 = () => 끄라는값인가(process.env.DEEL_NO_INTRO) || 끄라는값인가();
46
47
 
47
48
  /**
48
49
  * 한 틀에 얼마나 머무나.
package/src/ui/motion.js CHANGED
@@ -28,7 +28,7 @@
28
28
  * 그림을 점자 코드로 직접 적으면 나중에 아무도 못 고친다. 그래서 눈에 보이는
29
29
  * 대로 '#' 과 '.' 으로 적고, 켜질 때 한 번 점자로 바꾼다.
30
30
  */
31
- import { 켜달라했나 as 사무실켜달라했나 } from './office.js';
31
+ import { 켜달라했나 as 사무실켜달라했나, 끄라는값인가 } from './office.js';
32
32
 
33
33
  // 점 번호와 자리. 점자는 이렇게 번호가 매겨져 있다 —
34
34
  // 1 4
@@ -183,7 +183,11 @@ export const 그림들 = {
183
183
  * 한쪽으로만 지나가는 것과 왔다 갔다 하는 것은 느낌이 다르다. 앞의 것은
184
184
  * '진행 중' 으로 읽히고, 뒤의 것은 '기다리는 중' 으로 읽힌다. 45초가 넘은
185
185
  * 자리에서 진행 중인 척하면 곧 끝날 것처럼 보여서 오히려 답답해진다.
186
- * 열 장이라 한 바퀴가 0.9초 — 다른 것들보다 느긋하다.
186
+ *
187
+ * 여덟 장이라 한 바퀴가 0.72초 — 이 테마에서 제일 길다(다음이 다섯 장).
188
+ * 기사·동물 쪽 느긋은 열 장(0.9초)인데, 그쪽은 넘어졌다 일어나는 그림이라
189
+ * 한 동작에 장이 더 든다. 세 테마가 같을 이유는 없고, 검사가 재는 것도
190
+ * 「제 테마 안에서 느긋이 제일 길다」 이지 장수 자체가 아니다.
187
191
  */
188
192
  느긋: [
189
193
  ['......', '##....', '##....', '......'],
@@ -510,13 +514,31 @@ const 이름표 = {
510
514
  */
511
515
  let 고른그림 = null;
512
516
  export function 그림고르기설정(값) {
513
- 고른그림 = 이름표[String(값 ?? '').trim().toLowerCase()] ?? 이름표[String(값 ?? '').trim()] ?? null;
517
+ // 소문자로 번만 찾는다. 이름표에는 대문자 열쇠가 하나도 없어서, 원본
518
+ // 그대로 한 번 더 찾던 자리는 어떤 입력에도 안 걸리는 죽은 규칙이었다.
519
+ 고른그림 = 이름표[String(값 ?? '').trim().toLowerCase()] ?? null;
520
+ }
521
+
522
+ /**
523
+ * `DEEL_MOTION` 이 **실제로 이기고 있나.**
524
+ *
525
+ * `/motion` 은 「환경변수가 켜져 있어 그쪽이 이깁니다」 를 `process.env.DEEL_MOTION`
526
+ * 이 비어 있지 않다는 것만 보고 띄우고 있었다. 그런데 `DEEL_MOTION=cat` 은
527
+ * 우리가 아는 이름이 아니라 **그냥 무시되고 설정 파일이 그대로 쓰인다.**
528
+ * 그러면 화면이 하는 말이 사실과 반대다 — 사람은 설정을 바꿔도 소용없다고
529
+ * 믿고 손을 떼는데, 정작 이기고 있는 것은 그 설정이다.
530
+ *
531
+ * @returns {null|{값: string, 이름: string|null, 이김: boolean}}
532
+ * 안 적혀 있으면 null. 적혀 있으면 그 값과, 우리가 아는 이름인지.
533
+ */
534
+ export function 환경그림() {
535
+ const 값 = String(process.env.DEEL_MOTION ?? '').trim();
536
+ if (!값) return null;
537
+ const 이름 = 이름표[값.toLowerCase()] ?? null;
538
+ return { 값, 이름, 이김: 이름 !== null };
514
539
  }
515
540
 
516
- export const 테마이름 = () => 이름표[String(process.env.DEEL_MOTION ?? '').trim().toLowerCase()]
517
- ?? 이름표[String(process.env.DEEL_MOTION ?? '').trim()]
518
- ?? 고른그림
519
- ?? '기본';
541
+ export const 테마이름 = () => 환경그림()?.이름 ?? 고른그림 ?? '기본';
520
542
  export const 테마 = () => 테마들[테마이름()] ?? 테마들.기본;
521
543
 
522
544
  /*
@@ -529,7 +551,15 @@ export const 테마 = () => 테마들[테마이름()] ?? 테마들.기본;
529
551
  let 설정으로껐나 = false;
530
552
  /** `/motion 끔` 이 여기에 넣는다. 환경변수는 따로 살아 있고, 둘 중 하나면 꺼진다. */
531
553
  export function 끔설정(값) { 설정으로껐나 = !!값; }
532
- export const 끔 = () => !!process.env.DEEL_NO_MOTION || 설정으로껐나;
554
+ /**
555
+ * 환경변수 쪽이 꺼 놨나. `/motion` 이 「바꿨습니다」 라고 말해도 되는지 여기서 본다.
556
+ *
557
+ * 끔() 하나로는 모자란다 — 그건 「설정으로 껐다」 와 「환경변수가 껐다」 를
558
+ * 뭉쳐서 준다. 앞엣것은 방금 사람이 고른 것이고, 뒤엣것은 사람이 무엇을 골라도
559
+ * 안 바뀌는 것이다. 둘을 뭉치면 「고른 것이 안 먹힌다」 를 말해 줄 수가 없다.
560
+ */
561
+ export const 환경으로껐나 = () => 끄라는값인가();
562
+ export const 끔 = () => 환경으로껐나() || 설정으로껐나;
533
563
 
534
564
  // 못 끄는 자리에서 쓸 한 칸짜리. working.js 의 돌림틀과 같은 것이다.
535
565
  const 한칸 = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
@@ -542,7 +572,8 @@ const 한칸 = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '
542
572
  *
543
573
  * @param {string} 갈래 working.js 의 갈래 이름
544
574
  * @param {number} 틱 90ms 마다 하나씩 오르는 수
545
- * @returns {string} 점자 글자 (끈 상태면 한 글자)
575
+ * @returns {string} 그 테마의 칸수만큼 점자 기본은 글자, 기사·동물은
576
+ * 여섯 글자다(넓은칸수). 끈 상태·사무실이면 한 글자.
546
577
  */
547
578
  export function 그림고르기(갈래, 틱 = 0) {
548
579
  const n = Math.trunc(틱) || 0;
package/src/ui/office.js CHANGED
@@ -555,9 +555,30 @@ export function 켜달라했나() {
555
555
  return 설정으로켰나;
556
556
  }
557
557
 
558
+ /*
559
+ * `DEEL_NO_MOTION` 을 「끄라는 말」 로 읽어도 되나.
560
+ *
561
+ * `!!process.env.DEEL_NO_MOTION` 로 두고 있었다. 그러면 `DEEL_NO_MOTION=0` 도
562
+ * 끈다 — **끄지 말라고 적은 값이 끄는 것이다.** 바로 위 켜달라했나() 는 값을
563
+ * 읽어서 `DEEL_OFFICE=0` 을 껐다로 보므로, 같은 .env 에 둘을 나란히 적으면
564
+ * 하나만 말을 듣고 다른 하나는 반대로 간다. 그런데 화면에는 아무 말도 안 뜬다.
565
+ *
566
+ * 그래서 여기도 값을 읽는다. 안 적혀 있거나 0·false·off·no·빈 값이면 안 끈다.
567
+ * 그 밖의 값(1·true·yes·아무 글자)은 다 끄는 것으로 본다 — 끄려고 적었는데
568
+ * 철자가 달라서 안 꺼지는 쪽이 더 나쁘다.
569
+ *
570
+ * 이 자리에 두는 까닭: 이 값을 읽는 데가 셋(여기·motion.js·intro.js)인데,
571
+ * motion.js 가 이 파일을 가져다 쓰므로 반대로 가져오면 고리가 생긴다.
572
+ */
573
+ const 안끄는값 = new Set(['', '0', 'false', 'off', 'no']);
574
+ export function 끄라는값인가(raw = process.env.DEEL_NO_MOTION) {
575
+ if (raw === undefined || raw === null) return false;
576
+ return !안끄는값.has(String(raw).trim().toLowerCase());
577
+ }
578
+
558
579
  export function 켜나(rows = process.stdout.rows, cols = process.stdout.columns) {
559
580
  if (!켜달라했나()) return false;
560
- if (process.env.DEEL_NO_MOTION) return false;
581
+ if (끄라는값인가()) return false;
561
582
  if (!색충분한가()) return false;
562
583
  if ((cols ?? 0) < 최소폭) return false;
563
584
  return (rows ?? 0) >= 최소높이;
package/src/ui/screen.js CHANGED
@@ -46,13 +46,39 @@ import { spin } from './spinner.js';
46
46
  */
47
47
  export function 상자쓸까({ tui = null } = {}) {
48
48
  if (tui === false) return false; // deel --no-tui
49
- if (!process.stdout.isTTY) return false; // 파이프·기록·CI
49
+
50
+ /*
51
+ * ── 여기까지가 **그릴 데가 아예 없는** 자리다 ──────────────────────────
52
+ *
53
+ * 앞자리가 터미널이 아니면 커서를 위로 올릴 수가 없다. 제어문자가 글에
54
+ * 그대로 섞여 파이프·기록을 망친다. `--tui` 로도 못 넘는다 — bin/deel.js 의
55
+ * 설명도 「**터미널이면** 무조건」 이라고 적어 두고 있다.
56
+ */
57
+ if (!process.stdout.isTTY) return false; // 파이프·기록
50
58
  if (!process.stdin.isTTY) return false; // 입력이 파이프로 들어옴 (검사·데모)
59
+
60
+ /*
61
+ * ── 아래는 「아마 아닐 것」 인 자리다. `--tui` 는 여기를 넘으라고 있다 ──
62
+ *
63
+ * 이 줄이 없었다. `if (tui === true) return true;` 가 아래 세 가지를 **전부
64
+ * 지난 뒤**에 있었고, 그 바로 다음 줄이 무조건 `return true` 였다. 그러니
65
+ * `--tui` 는 어디에도 안 붙어 있었다 — 켜지는 자리에서는 어차피 켜지고,
66
+ * 안 켜지는 자리에서는 줘도 안 켜졌다.
67
+ *
68
+ * 그런데 이 깃발은 `deel --help` 에도 자동완성에도 「입력 상자를 켠다」
69
+ * (completion.js: force the input box on) 라고 적혀 있다. CI 값이 남아 있는
70
+ * 터미널이나 39칸짜리 창에서 `deel --tui` 를 치면 아무 말 없이 줄 화면이
71
+ * 뜬다. 스위치가 있다고 적어 놓고 선이 안 이어져 있던 것이다.
72
+ *
73
+ * 넘게 두는 것이 맞다. 셋 다 「대개 이럴 것」 이라는 짐작이고, 짐작을
74
+ * 사람이 손으로 뒤집겠다고 한 자리다. 좁은 창에서 테두리가 어긋나 보이는
75
+ * 것은 달라고 해서 준 결과이니 놀랄 일이 아니다.
76
+ */
77
+ if (tui === true) return true;
51
78
  if (process.env.TERM === 'dumb') return false;
52
79
  if (process.env.CI) return false;
53
80
  // 너무 좁으면 상자 안에 남는 자리가 없다. 테두리만 남고 글이 안 보인다.
54
81
  if ((process.stdout.columns ?? 0) < 40) return false;
55
- if (tui === true) return true;
56
82
  return true;
57
83
  }
58
84
 
@@ -100,8 +126,25 @@ export class LineScreen {
100
126
  */
101
127
  #안내() { return this.깊이 ? c.gray(' │').repeat(this.깊이) : ''; }
102
128
 
103
- /** 한 줄. 이미 색이 입혀진 글을 받는다. */
104
- 줄(s = '') { this.임시지움(); say(this.깊이 && s ? this.#안내() + s : s); }
129
+ /**
130
+ * 줄. 이미 색이 입혀진 글을 받는다.
131
+ *
132
+ * 하위 작업 구간에서는 **빈 줄과 여러 줄에도** 세로줄을 세운다.
133
+ *
134
+ * 처음에는 `this.깊이 && s` 였다. 그래서 빈 줄에는 안 붙었는데, repl.js 는
135
+ * 도구가 뜰 때마다 `say('')` 를 한 번씩 넣는다 — 세로줄이 도구마다 끊겨
136
+ * 점선이 됐다. 여러 줄짜리 글도 첫 줄에만 붙어서, 하위가 뱉은 나머지 줄이
137
+ * 구간 밖으로 삐져나왔다.
138
+ *
139
+ * 「훑는 것만으로 구간이 잡힌다」 가 이 줄을 그리는 이유다. 끊겨 있으면
140
+ * 그 이유가 사라진다.
141
+ */
142
+ 줄(s = '') {
143
+ this.임시지움();
144
+ if (!this.깊이) return say(s);
145
+ const 안내 = this.#안내();
146
+ say(String(s).split('\n').map((l) => 안내 + l).join('\n'));
147
+ }
105
148
 
106
149
  /** 줄바꿈 없이 이어 붙인다 — 스트리밍으로 오는 답. */
107
150
  붙임(s) { this.임시지움(); process.stdout.write(s); }
package/src/ui/working.js CHANGED
@@ -119,7 +119,10 @@ export function 갈래고르기(도구이름) {
119
119
  */
120
120
  export function 문구고르기(갈래, 회차 = 0) {
121
121
  const 목록 = 문구[갈래] ?? 문구.기본;
122
- const i = ((Math.trunc(회차) % 목록.length) + 목록.length) % 목록.length;
122
+ // `|| 0` NaN 막이다. 바로 옆에서 같이 불리는 motion.js 의 그림고르기 는
123
+ // 이걸 하고 있었는데 여기만 안 했다 — 둘이 같은 값을 받는 자리라, 한쪽만
124
+ // undefined 를 돌려주면 그림은 도는데 문구 자리만 빈다.
125
+ const i = (((Math.trunc(회차) || 0) % 목록.length) + 목록.length) % 목록.length;
123
126
  return 목록[i];
124
127
  }
125
128