deel-local-cli 1.20.6 → 1.20.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/agent/compact.js +103 -8
- package/src/agent/evolve.js +18 -1
- package/src/backend/adapter.js +93 -9
- package/src/backend/http.js +52 -8
- package/src/backend/mcp.js +108 -13
- package/src/backend/probe.js +108 -14
- package/src/backend/wire.js +323 -18
- package/src/commands.js +49 -3
- package/src/i18n/en.js +1 -0
- package/src/i18n/ko.js +1 -0
- package/src/repl.js +3 -2
- package/src/tools/jobs.js +85 -7
package/src/tools/jobs.js
CHANGED
|
@@ -384,6 +384,35 @@ class 일감 {
|
|
|
384
384
|
while (this.바이트 > 출력상한 && this.조각들.length > 1) {
|
|
385
385
|
this.바이트 -= this.조각들.shift().length;
|
|
386
386
|
}
|
|
387
|
+
/*
|
|
388
|
+
* 한 조각이 **혼자** 상한을 넘으면 그 조각의 뒤만 남긴다.
|
|
389
|
+
*
|
|
390
|
+
* 위 되풀이는 조각이 둘 이상일 때만 버린다. 그래서 한 조각이 혼자 넘치면
|
|
391
|
+
* **아무것도 못 버리는데 아래에서 잘렸다고 적는다.** 그 사이에 읽으면
|
|
392
|
+
* 멀쩡한 글에 "앞이 잘렸습니다" 가 붙고 읽은 자리도 0 으로 돌아간다 —
|
|
393
|
+
* 모델은 없는 앞을 찾으러 처음부터 다시 읽는다. (다음 조각이 들어오면
|
|
394
|
+
* 그때는 둘이 되어 버려지므로, 거짓말은 그 한 판만이다. 그래도 그 한
|
|
395
|
+
* 판이 되풀이를 부르는 자리다 — 읽기() 머리말 참고.)
|
|
396
|
+
*
|
|
397
|
+
* 그리고 버릴 수 있게 만들어 두는 것이 맞다. 상한 위에 남겨 두면 그
|
|
398
|
+
* 다음 조각 하나에 256KB 가 통째로 날아간다.
|
|
399
|
+
*
|
|
400
|
+
* 베껴 담는다. subarray 는 원래 덩이를 그대로 붙잡고 있어서, 큰 조각
|
|
401
|
+
* 하나가 들어온 판에서는 놓으려는 그 메모리가 안 놓인다.
|
|
402
|
+
*/
|
|
403
|
+
if (this.바이트 > 출력상한 && this.조각들.length === 1) {
|
|
404
|
+
const 하나 = this.조각들[0];
|
|
405
|
+
this.조각들[0] = Buffer.from(하나.subarray(하나.length - 출력상한));
|
|
406
|
+
this.바이트 = this.조각들[0].length;
|
|
407
|
+
}
|
|
408
|
+
/*
|
|
409
|
+
* 여기 오면 **반드시 무엇인가 버렸다** — 그래서 「안 버렸으면」 갈래를
|
|
410
|
+
* 두지 않는다. 위에서 상한을 넘은 것을 확인했고, 조각이 둘 이상이면
|
|
411
|
+
* 되풀이가 버리고 하나뿐이면 그 하나를 줄였다. 늘 참인 조건을 남기면
|
|
412
|
+
* 어긋내기가 「그 줄을 지워도 아무 검사도 안 깨진다」 고 말하는데, 그건
|
|
413
|
+
* 맞는 말이라 고칠 수도 없다 — 대신 읽는 사람은 안 버리는 길이 따로
|
|
414
|
+
* 있는 줄로 읽는다.
|
|
415
|
+
*/
|
|
387
416
|
this.앞잘림 = true;
|
|
388
417
|
this.막버렸다 = true;
|
|
389
418
|
this.읽은글자 = 0;
|
|
@@ -516,10 +545,24 @@ export async function 띄우기(명령, { cwd, 설명 = null, 기다림 = 1500,
|
|
|
516
545
|
|
|
517
546
|
kid.stdout?.on('data', (b) => j.담기(b));
|
|
518
547
|
kid.stderr?.on('data', (b) => j.담기(b));
|
|
519
|
-
kid.on('error', (err) => {
|
|
548
|
+
kid.on('error', (err) => {
|
|
549
|
+
j.담기(Buffer.from(`\n[띄우기 실패: ${err.message}]\n`));
|
|
550
|
+
j.상태 = '끝남';
|
|
551
|
+
j.종료코드 = -1;
|
|
552
|
+
// 왜 표를 세우나 — 바로 아래 close 머리말.
|
|
553
|
+
j.띄우기실패 = true;
|
|
554
|
+
});
|
|
520
555
|
kid.on('close', (code, sig) => {
|
|
521
556
|
if (j.상태 === '죽임') return;
|
|
522
557
|
j.상태 = '끝남';
|
|
558
|
+
/*
|
|
559
|
+
* 띄우기 자체가 실패한 판은 **덮지 않는다.**
|
|
560
|
+
*
|
|
561
|
+
* 명령이 없으면(ENOENT) Node 는 error 를 낸 다음 close 를 code=null 로
|
|
562
|
+
* 부른다. 그러면 위에서 세워 둔 -1 이 null 로 덮이고, null 은 이 자리에서
|
|
563
|
+
* 「시그널로 죽었다」 와 구별이 안 된다. 안 뜬 까닭이 종료코드에서 지워진다.
|
|
564
|
+
*/
|
|
565
|
+
if (j.띄우기실패) { 끝난것치우기(); return; }
|
|
523
566
|
j.종료코드 = sig ? null : code;
|
|
524
567
|
j.시그널 = sig ?? null;
|
|
525
568
|
// 끝난 것이 쌓이지 않게. 도는 것은 최대일감 이 따로 막는다.
|
|
@@ -628,7 +671,17 @@ export async function 끝내기(번호) {
|
|
|
628
671
|
*/
|
|
629
672
|
await 죽는말기다리기(j.kid, 죽는말기다림);
|
|
630
673
|
}
|
|
631
|
-
|
|
674
|
+
/*
|
|
675
|
+
* ── 안 죽은 놈의 파이프는 **끊지 않는다** ──────────────────────────────
|
|
676
|
+
*
|
|
677
|
+
* 여기서 늘 끊고 있었다. 그런데 바로 아래에서 「그러고도 안 죽었으면 목록에
|
|
678
|
+
* 남긴다 — 다시 시킬 수 있어야 한다」 고 한다. 파이프를 이미 끊어 놓고
|
|
679
|
+
* 남기면, 목록에는 `도는중` 으로 뜨는데 그놈이 뱉는 말은 다시는 안 들어온다.
|
|
680
|
+
* 사람은 화면을 보며 기다리고, 자식은 다음 쓰기에서 EPIPE 를 맞는다.
|
|
681
|
+
* 남겨 두기로 한 까닭이 「다시 볼 수 있게」 인데 정작 볼 길을 끊던 셈이다.
|
|
682
|
+
*/
|
|
683
|
+
const 죽었나 = !아직사나(j.kid);
|
|
684
|
+
if (죽었나) 파이프끊기(j.kid);
|
|
632
685
|
const 남은 = j.읽기({});
|
|
633
686
|
/*
|
|
634
687
|
* ★ 그러고도 안 죽었으면 **그렇다고 말한다.**
|
|
@@ -640,7 +693,7 @@ export async function 끝내기(번호) {
|
|
|
640
693
|
*
|
|
641
694
|
* 안 죽었으면 목록에 남긴다. 그래야 사람이 한 번 더 시킬 수 있다.
|
|
642
695
|
*/
|
|
643
|
-
if (
|
|
696
|
+
if (!죽었나) {
|
|
644
697
|
j.상태 = '도는중'; // 지우지 않는다 — 다시 시킬 수 있어야 한다
|
|
645
698
|
return { 이미: false, 안죽음: true, 명령: j.명령, 초: j.산햇수(), 남은: 남은.글 };
|
|
646
699
|
}
|
|
@@ -723,6 +776,8 @@ export function 일감인자(args) {
|
|
|
723
776
|
};
|
|
724
777
|
const 날번호 = 하나씩('번호');
|
|
725
778
|
return {
|
|
779
|
+
// 날것을 같이 내놓는다 — 숫자가 아닐 때 **무엇을 받았는지** 적어야 한다.
|
|
780
|
+
날번호,
|
|
726
781
|
번호: 날번호 == null ? null : Number(날번호),
|
|
727
782
|
끝내기: !!하나씩('끝내기'),
|
|
728
783
|
처음부터: !!하나씩('처음부터'),
|
|
@@ -791,11 +846,34 @@ export const JOBS_TOOL = {
|
|
|
791
846
|
+ ' 번호 없이 부르면 목록입니다.',
|
|
792
847
|
};
|
|
793
848
|
}
|
|
849
|
+
/*
|
|
850
|
+
* 몇 개만 못 알아들은 판도 **말해 준다.**
|
|
851
|
+
*
|
|
852
|
+
* 위 갈래는 「하나도」 못 알아들었을 때만 걸린다. 그래서
|
|
853
|
+
* `{job: 1, action: 'stop'}` 은 걸리지 않고 — `action` 을 조용히 버린 뒤
|
|
854
|
+
* 출력만 읽어 **성공으로** 돌려줬다. 끄라고 시킨 모델은 껐다고 여기고
|
|
855
|
+
* 넘어가는데 서버는 그대로 돈다. 위 머리말이 없애겠다고 적어 둔 바로 그
|
|
856
|
+
* 고장이, 인자를 하나 더 붙인 판에 그대로 남아 있었다 (34차 리뷰).
|
|
857
|
+
*
|
|
858
|
+
* 오류로 막지는 않는다 — 알아들은 것은 하라고 시킨 것이 맞다. 대신 버린
|
|
859
|
+
* 이름을 적어 보내서, 뜻이 거기 있었으면 다음 걸음에서 고쳐 부르게 한다.
|
|
860
|
+
*/
|
|
861
|
+
const 버린말 = 받은것.모르는것.length
|
|
862
|
+
? `\n(못 알아들어 버린 인자: ${받은것.모르는것.join(', ')} — Jobs 는 job · stop · from_start 만 받습니다.`
|
|
863
|
+
+ ' 끝내려던 것이면 stop: true 로 다시 불러라.)'
|
|
864
|
+
: '';
|
|
794
865
|
const 번호 = 받은것.번호;
|
|
795
866
|
// 숫자가 아닌 것을 받으면 NaN 이 되고, 그대로 두면 `NaN번 일감이 없습니다`
|
|
796
867
|
// 라는 말이 모델에게 나간다. 무엇이 잘못됐는지 안 알려 주는 오류다.
|
|
797
868
|
if (번호 != null && !Number.isFinite(번호)) {
|
|
798
|
-
|
|
869
|
+
/*
|
|
870
|
+
* 받은 것을 **실제로 읽은 그 칸**에서 적는다.
|
|
871
|
+
*
|
|
872
|
+
* 여기가 `args?.번호` 였다. 설명서에 실린 이름은 `job` 이라 모델은 거의
|
|
873
|
+
* 늘 `job` 으로 보내는데, 그러면 이 말은 `(받은 것: undefined)` 가 된다.
|
|
874
|
+
* 무엇을 잘못 보냈는지 알려 주려고 있는 줄이 정작 그것만 안 알려 줬다.
|
|
875
|
+
*/
|
|
876
|
+
return { error: `번호는 숫자여야 합니다 (받은 것: ${JSON.stringify(받은것.날번호)}). 번호 없이 Jobs 를 불러 목록을 보세요.` };
|
|
799
877
|
}
|
|
800
878
|
|
|
801
879
|
if (번호 == null) {
|
|
@@ -830,7 +908,7 @@ export const JOBS_TOOL = {
|
|
|
830
908
|
* 그러면 포트가 물려서 안 뜨고, 왜 안 되는지도 모른다.
|
|
831
909
|
*/
|
|
832
910
|
if (치운것) 줄들.push(` (오래된 것 ${치운것}개는 자리를 위해 지웠습니다)`);
|
|
833
|
-
return { content: 줄들.join('\n')
|
|
911
|
+
return { content: 줄들.join('\n') + 버린말, summary: 세말('count', ls.length), 일감수: ls.length };
|
|
834
912
|
}
|
|
835
913
|
|
|
836
914
|
if (받은것.끝내기) {
|
|
@@ -854,7 +932,7 @@ export const JOBS_TOOL = {
|
|
|
854
932
|
}
|
|
855
933
|
return {
|
|
856
934
|
content: `${번호}번을 끝냈습니다 (${r.초}초 돌았습니다): ${r.명령}`
|
|
857
|
-
+ (r.남은 ? `\n\n마지막 출력:\n${뒤만(r.남은, 2000).글}` : '')
|
|
935
|
+
+ (r.남은 ? `\n\n마지막 출력:\n${뒤만(r.남은, 2000).글}` : '') + 버린말,
|
|
858
936
|
summary: 이어(말('sum.jobStopped'), 말('unit.sec', { n: r.초 })),
|
|
859
937
|
};
|
|
860
938
|
}
|
|
@@ -870,7 +948,7 @@ export const JOBS_TOOL = {
|
|
|
870
948
|
? (r.앞잘림 ? '(앞부분은 너무 길어 잘렸습니다 — 뒤쪽만 남았습니다)\n' : '') + 잘라낸.글
|
|
871
949
|
: '(지난번 읽은 뒤로 새 출력이 없습니다)';
|
|
872
950
|
return {
|
|
873
|
-
content: `${머리}\n\n${몸}`,
|
|
951
|
+
content: `${머리}\n\n${몸}${버린말}`,
|
|
874
952
|
summary: (r.상태 === '도는중' ? 이어(말('sum.jobRunning'), 말('unit.sec', { n: r.초 })) : 끝난말(r))
|
|
875
953
|
+ (잘라낸.줄임 ? ' · 일부만' : ''),
|
|
876
954
|
// 끝난 일감이 종료코드 0 이 아니면 실패로 물들인다 — Bash 와 같은 규칙이다.
|