deel-local-cli 1.0.2 → 1.1.0
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 +381 -7
- package/README.md +407 -7
- package/bin/deel.js +266 -234
- package/package.json +4 -3
- package/src/agent/budget.js +167 -0
- package/src/agent/grade.js +207 -0
- package/src/agent/loop.js +778 -574
- package/src/agent/modes.js +109 -28
- package/src/agent/project.js +171 -0
- package/src/agent/session.js +131 -12
- package/src/backend/learn.js +46 -4
- package/src/commands.js +73 -0
- package/src/oneshot.js +390 -327
- package/src/repl.js +1074 -887
- package/src/safety/audit.js +3 -1
- package/src/tools/index.js +500 -107
- package/src/tools/jobs.js +670 -0
- package/src/tools/outline.js +331 -0
- package/src/tools/task.js +153 -0
- package/src/tools/verify.js +306 -0
- package/src/tools/webfetch.js +152 -16
- package/src/ui/inputbox.js +97 -5
- package/src/ui/screen.js +51 -3
- package/src/ui/status.js +69 -4
- package/src/ui/working.js +8 -1
package/src/ui/screen.js
CHANGED
|
@@ -69,12 +69,36 @@ export class LineScreen {
|
|
|
69
69
|
// 다음에 오는 짧은 글이 그 줄 위에 겹쳐 찍힌다.
|
|
70
70
|
this.임시중 = false;
|
|
71
71
|
this.돌림 = null;
|
|
72
|
+
/*
|
|
73
|
+
* 하위 작업 안쪽인가 — 그렇다면 몇 겹인가.
|
|
74
|
+
*
|
|
75
|
+
* 하위 작업(tools/task.js)은 제 대화에서 따로 돌지만 화면은 하나다.
|
|
76
|
+
* 표시가 없으면 하위가 부른 도구 줄이 부모 것과 똑같이 찍혀서, 사람은
|
|
77
|
+
* 부모가 파일 열두 개를 읽은 줄로 본다. 한 단 들여 그으면 어디부터
|
|
78
|
+
* 어디까지가 떼어 낸 일인지가 그냥 보인다.
|
|
79
|
+
*
|
|
80
|
+
* 여기 한 군데서만 붙인다. repl.js 의 say() 자리 예순 곳을 고치는 대신
|
|
81
|
+
* 이벤트가 들고 온 깊이를 화면에 알려 주는 쪽이 안 빠뜨린다.
|
|
82
|
+
*/
|
|
83
|
+
this.깊이 = 0;
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
// ── 흘러가는 글 ────────────────────────────────────────────────────────
|
|
75
87
|
|
|
88
|
+
/** 지금부터 찍는 줄이 몇 겹 안쪽인지. 0 이면 평소대로. */
|
|
89
|
+
들여쓰기(n) { this.깊이 = Math.max(0, Number(n) || 0); }
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
* 하위 작업 구간에 세로줄을 세운다.
|
|
93
|
+
*
|
|
94
|
+
* 빈 칸으로만 밀면 어디서 시작해 어디서 끝났는지가 안 보인다 — 특히 하위가
|
|
95
|
+
* 파일을 열 개 만지고 나면, 스크롤을 올려 여는 줄을 찾아야 그게 하위였는지
|
|
96
|
+
* 안다. 세로줄 한 칸이면 훑는 것만으로 구간이 잡힌다.
|
|
97
|
+
*/
|
|
98
|
+
#안내() { return this.깊이 ? c.gray(' │').repeat(this.깊이) : ''; }
|
|
99
|
+
|
|
76
100
|
/** 한 줄. 이미 색이 입혀진 글을 받는다. */
|
|
77
|
-
줄(s = '') { this.임시지움(); say(s); }
|
|
101
|
+
줄(s = '') { this.임시지움(); say(this.깊이 && s ? this.#안내() + s : s); }
|
|
78
102
|
|
|
79
103
|
/** 줄바꿈 없이 이어 붙인다 — 스트리밍으로 오는 답. */
|
|
80
104
|
붙임(s) { this.임시지움(); process.stdout.write(s); }
|
|
@@ -150,6 +174,12 @@ export class LineScreen {
|
|
|
150
174
|
/** 사람이 치는 중인 글이 바뀌었다. 줄화면은 readline 이 알아서 되비춘다. */
|
|
151
175
|
입력갱신() { }
|
|
152
176
|
|
|
177
|
+
/** 일하는 중 미리 치는 글. 줄화면은 상자가 없어 보여 줄 자리가 없다. */
|
|
178
|
+
대기갱신() { }
|
|
179
|
+
|
|
180
|
+
/** 줄화면은 붙여 쓰기 전에 임시글만 지우면 되므로 따로 셀 것이 없다. */
|
|
181
|
+
줄중간인가() { return false; }
|
|
182
|
+
|
|
153
183
|
/*
|
|
154
184
|
* 일하는 중 표시. 줄화면은 안 그린다.
|
|
155
185
|
*
|
|
@@ -189,7 +219,13 @@ export class BoxScreen extends LineScreen {
|
|
|
189
219
|
* 찍히는 순간 상자가 사라지고, 그 뒤로는 일이 끝날 때까지 화면 아래가
|
|
190
220
|
* 텅 빈 채로 남는다 — 정확히 그게 "밋밋해 보인다" 는 상태다.
|
|
191
221
|
*/
|
|
192
|
-
줄(s = '') {
|
|
222
|
+
줄(s = '') {
|
|
223
|
+
this.상자.지우기();
|
|
224
|
+
super.줄(s);
|
|
225
|
+
// 줄이 끝났다 — 이제 아래에 상자를 세워도 대화를 안 덮는다.
|
|
226
|
+
this.상자.줄끝남();
|
|
227
|
+
this.상자.일그리기();
|
|
228
|
+
}
|
|
193
229
|
|
|
194
230
|
/*
|
|
195
231
|
* 스트리밍으로 이어 붙이는 글은 다시 안 세운다.
|
|
@@ -198,13 +234,25 @@ export class BoxScreen extends LineScreen {
|
|
|
198
234
|
* 위아래로 튄다. 답이 흘러나오는 동안에는 그 자체가 살아 있다는 신호라
|
|
199
235
|
* 상자가 없어도 밋밋하지 않다. 답이 끝나면 repl.js 가 다시 세운다.
|
|
200
236
|
*/
|
|
201
|
-
붙임(s) {
|
|
237
|
+
붙임(s) {
|
|
238
|
+
// 상자를 걷고, **줄 중간에 멈춰 있다고 표시한다.** 이 표시가 없으면
|
|
239
|
+
// 돌아가는 표시가 90ms 뒤에 제 시계로 상자를 답 줄 위에 그려 버리고,
|
|
240
|
+
// 그 다음 지우기가 답까지 같이 지운다.
|
|
241
|
+
this.상자.줄중간표시();
|
|
242
|
+
super.붙임(s);
|
|
243
|
+
}
|
|
202
244
|
|
|
203
245
|
/** 일하기 시작·바뀜·끝. 상자 안엣것만 바뀐다 (ui/working.js 의 문구). */
|
|
204
246
|
일시작(session, 갈래) { this.임시지움(); this.상자.일시작(session, 갈래); }
|
|
205
247
|
일바꿈(갈래, 곁정보) { this.상자.일바꿈(갈래, 곁정보); }
|
|
206
248
|
일끝() { this.상자.일끝(); }
|
|
207
249
|
|
|
250
|
+
/** 일하는 도중에 미리 치고 있는 글 · 예약해 둔 개수. */
|
|
251
|
+
대기갱신(글, 예약수) { this.상자.대기갱신(글, 예약수); }
|
|
252
|
+
|
|
253
|
+
/** 대화가 줄 중간에 멈춰 있나 (답이 흘러나오는 중). */
|
|
254
|
+
줄중간인가() { return this.상자.줄중간; }
|
|
255
|
+
|
|
208
256
|
/*
|
|
209
257
|
* 줄화면에서 '생각 중…' 을 한 줄로 흘리던 자리.
|
|
210
258
|
*
|
package/src/ui/status.js
CHANGED
|
@@ -30,6 +30,28 @@ export const SEGMENTS = {
|
|
|
30
30
|
short: (s) => c.hcyan(clip(s.conn.model, 14)),
|
|
31
31
|
},
|
|
32
32
|
|
|
33
|
+
/*
|
|
34
|
+
* 모델 급 — 얼마나 알아서 하나 (agent/grade.js).
|
|
35
|
+
*
|
|
36
|
+
* 컨텍스트 게이지 바로 옆에 둔다. 그 둘이 다른 축이라는 것이 화면에서
|
|
37
|
+
* 나란히 보여야 한다 — 창이 128k 인데 급이 '작음' 인 경우가 실제로 있고,
|
|
38
|
+
* 그때 "왜 이렇게 조심스럽게 하지" 의 답이 이 한 글자다.
|
|
39
|
+
*
|
|
40
|
+
* 짐작일 때는 흐리게 그린다. 정한 것과 짐작한 것을 같은 색으로 보여주면,
|
|
41
|
+
* 사람은 프로그램이 확인한 사실이라고 읽는다.
|
|
42
|
+
*/
|
|
43
|
+
grade: {
|
|
44
|
+
desc: '모델 급 (얼마나 알아서 하나)',
|
|
45
|
+
make: (s) => {
|
|
46
|
+
const g = 볼만한급(s);
|
|
47
|
+
return g ? (g.짐작 ? c.gray(`◈ ${g.급}?`) : c.white(`◈ ${g.급}`)) : '';
|
|
48
|
+
},
|
|
49
|
+
short: (s) => {
|
|
50
|
+
const g = 볼만한급(s);
|
|
51
|
+
return g ? (g.짐작 ? c.gray(`◈${g.급[0]}?`) : c.white(`◈${g.급[0]}`)) : '';
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
|
|
33
55
|
ctx: {
|
|
34
56
|
desc: '컨텍스트 사용량',
|
|
35
57
|
make: (s) => {
|
|
@@ -117,7 +139,7 @@ export const SEGMENTS = {
|
|
|
117
139
|
*/
|
|
118
140
|
export const SEGMENT_GROUPS = [
|
|
119
141
|
['dir', 'model'],
|
|
120
|
-
['ctx'],
|
|
142
|
+
['ctx', 'grade'],
|
|
121
143
|
['work', 'think', 'mode'],
|
|
122
144
|
['tok'],
|
|
123
145
|
];
|
|
@@ -125,6 +147,23 @@ export const SEGMENT_GROUPS = [
|
|
|
125
147
|
// 옛 이름. 조각 이름을 직접 넘기던 자리(검사·설정)가 그대로 돌게 남긴다.
|
|
126
148
|
export const DEFAULT_SEGMENTS = SEGMENT_GROUPS.flat();
|
|
127
149
|
|
|
150
|
+
/**
|
|
151
|
+
* 이 급을 화면에 낼 값어치가 있나.
|
|
152
|
+
*
|
|
153
|
+
* '보통' 을 짐작으로 잡은 것은 **아무것도 못 알아낸 상태**다. 사내 게이트웨이가
|
|
154
|
+
* 그렇고, 그건 기본값이지 알아낸 사실이 아니다. 그걸 상태줄에 적으면 자리만
|
|
155
|
+
* 먹고, 좁은 터미널에서는 그 한 조각 때문에 승인 방식이 밀려 사라진다 —
|
|
156
|
+
* 내 파일이 안 물어보고 바뀌는지가 화면에서 없어지는 것이라 훨씬 비싸다.
|
|
157
|
+
*
|
|
158
|
+
* 알아낸 것이 있거나(짐작이 아님) 기본이 아닌 급일 때만 낸다.
|
|
159
|
+
*/
|
|
160
|
+
function 볼만한급(s) {
|
|
161
|
+
if (typeof s.급 !== 'function') return null;
|
|
162
|
+
const g = s.급();
|
|
163
|
+
if (g.급 === '보통' && g.짐작) return null;
|
|
164
|
+
return g;
|
|
165
|
+
}
|
|
166
|
+
|
|
128
167
|
// 컨텍스트 게이지가 쓰는 숫자. 자세한 꼴과 짧은 꼴이 같은 값을 봐야 한다.
|
|
129
168
|
function 참값(s) {
|
|
130
169
|
const b = s.breakdown();
|
|
@@ -167,9 +206,10 @@ export function statusLine(session, { segments = null, max = cols() - 2 } = {})
|
|
|
167
206
|
? segments.map((k) => [k])
|
|
168
207
|
: SEGMENT_GROUPS;
|
|
169
208
|
|
|
170
|
-
const 그리기 = (
|
|
209
|
+
const 그리기 = (짧게, 뺄것 = null) => 덩이들
|
|
171
210
|
.map((그룹) => 그룹
|
|
172
211
|
.map((k) => {
|
|
212
|
+
if (뺄것?.has(k)) return null;
|
|
173
213
|
const seg = SEGMENTS[k];
|
|
174
214
|
if (!seg) return null;
|
|
175
215
|
return 짧게 && seg.short ? seg.short(session) : seg.make(session);
|
|
@@ -194,7 +234,16 @@ export function statusLine(session, { segments = null, max = cols() - 2 } = {})
|
|
|
194
234
|
let parts = 그리기(false);
|
|
195
235
|
if (!맞나(parts)) parts = 그리기(true);
|
|
196
236
|
|
|
197
|
-
|
|
237
|
+
/*
|
|
238
|
+
* 그래도 모자라면 **급부터** 접는다.
|
|
239
|
+
*
|
|
240
|
+
* 뒤에서부터 떨구면 승인 방식이 먼저 사라진다. 모델 급은 알아 두면 좋은
|
|
241
|
+
* 것이고, 승인 방식은 지금 봐야 하는 것이다 — 내 파일이 안 물어보고 바뀌는지가
|
|
242
|
+
* 거기 적혀 있다. 둘 중 하나를 접어야 하면 언제나 이쪽이다.
|
|
243
|
+
*/
|
|
244
|
+
if (!맞나(parts) && !segments) parts = 그리기(true, new Set(['grade']));
|
|
245
|
+
|
|
246
|
+
// 여전히 모자라면 뒤에서부터 떨군다. 앞쪽(폴더·모델·컨텍스트)이 마지막까지 남는다.
|
|
198
247
|
while (parts.length > 1 && !맞나(parts)) parts.pop();
|
|
199
248
|
|
|
200
249
|
return ` ${c.gray('▏')}${parts.join(칸막이)}`;
|
|
@@ -212,6 +261,13 @@ export function contextWarning(session) {
|
|
|
212
261
|
/**
|
|
213
262
|
* 켤 때 한 번 그리는 머리말 상자 안쪽 줄들.
|
|
214
263
|
*/
|
|
264
|
+
/** 머리말 모델 줄에 붙는 급 표시. 못 매기면 아무것도 안 붙는다. */
|
|
265
|
+
function 급머리말(session) {
|
|
266
|
+
if (typeof session.급 !== 'function') return '';
|
|
267
|
+
const g = session.급();
|
|
268
|
+
return c.gray(` · 급 ${g.급}${g.짐작 ? ' 짐작' : ''}`);
|
|
269
|
+
}
|
|
270
|
+
|
|
215
271
|
export function headerLines(session, found) {
|
|
216
272
|
const conn = session.conn;
|
|
217
273
|
const 능력 = [
|
|
@@ -232,7 +288,16 @@ export function headerLines(session, found) {
|
|
|
232
288
|
const lines = [
|
|
233
289
|
`${c.hcyan(c.bold('deel'))} ${c.gray(conn.kind === 'ollama' ? 'Ollama 규격' : 'OpenAI 호환 규격')}`,
|
|
234
290
|
'',
|
|
235
|
-
|
|
291
|
+
/*
|
|
292
|
+
* 모델 줄에 급을 같이 적는다.
|
|
293
|
+
*
|
|
294
|
+
* 창 크기(토큰)와 급은 다른 축인데, 켤 때 이 둘을 나란히 보지 않으면
|
|
295
|
+
* 나중에 상태줄의 `◈ 작음?` 이 무슨 뜻인지 알 길이 없다. 여기서 한 번
|
|
296
|
+
* 같이 읽고 나면 그 다음부터는 글자만 봐도 안다.
|
|
297
|
+
* 짐작이면 그렇다고 적는다 — 알아낸 사실과 같은 낯으로 내밀면 안 된다.
|
|
298
|
+
*/
|
|
299
|
+
`${c.gray('모델')} ${c.white(conn.model)} ${c.gray('(' + short(conn.ctx) + ' 토큰')}`
|
|
300
|
+
+ `${급머리말(session)}${c.gray(')')}`,
|
|
236
301
|
`${c.gray('보냄')} ${목적지} ${c.gray('← 여기 말고는 어디로도 안 갑니다')}`,
|
|
237
302
|
`${c.gray('연결')} ${능력}`,
|
|
238
303
|
`${c.gray('폴더')} ${c.white(clip(session.root, 56))}`,
|
package/src/ui/working.js
CHANGED
|
@@ -54,6 +54,12 @@ export const 문구 = {
|
|
|
54
54
|
'지난 대화 접는 중',
|
|
55
55
|
'자리 만드는 중',
|
|
56
56
|
],
|
|
57
|
+
// 하위 작업을 돌리는 중. 부모는 기다리기만 하니, 무엇을 기다리는지 말해 준다.
|
|
58
|
+
하위: [
|
|
59
|
+
'떼어 낸 일 맡기는 중',
|
|
60
|
+
'하위 작업 도는 중',
|
|
61
|
+
'한 덩이씩 끝내는 중',
|
|
62
|
+
],
|
|
57
63
|
// 무슨 일인지 아직 모를 때. 첫 걸음과 도구 사이의 짧은 틈이다.
|
|
58
64
|
기본: [
|
|
59
65
|
'열심히 일하는 중',
|
|
@@ -79,7 +85,8 @@ export const 문구 = {
|
|
|
79
85
|
const 도구갈래 = {
|
|
80
86
|
Read: '읽기', Glob: '읽기', Grep: '읽기', Skill: '읽기', Recall: '읽기',
|
|
81
87
|
Write: '쓰기', Edit: '쓰기', Append: '쓰기', Remember: '쓰기', TodoWrite: '쓰기',
|
|
82
|
-
Bash: '명령',
|
|
88
|
+
Bash: '명령', Jobs: '명령',
|
|
89
|
+
Task: '하위',
|
|
83
90
|
WebFetch: '웹',
|
|
84
91
|
};
|
|
85
92
|
|