devez-vibe 1.2.34 → 1.2.36
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/bin/dvz.exe +0 -0
- package/bridge/claude-agent-sdk-bridge.mjs +84 -31
- package/package.json +41 -41
package/bin/dvz.exe
CHANGED
|
Binary file
|
|
@@ -55,9 +55,9 @@ class AsyncQueue {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
function write(message) {
|
|
59
|
-
process.stdout.write(`${JSON.stringify(message)}\n
|
|
60
|
-
}
|
|
58
|
+
function write(message) {
|
|
59
|
+
process.stdout.write(`${JSON.stringify(message)}\n`, "utf8");
|
|
60
|
+
}
|
|
61
61
|
|
|
62
62
|
function notify(method, params) {
|
|
63
63
|
write({ method, params });
|
|
@@ -70,24 +70,34 @@ function rpcError(error) {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function hostRequest(method, params, signal) {
|
|
74
|
-
const id = `claude-host-${nextHostRequest++}`;
|
|
75
|
-
return new Promise((resolve, reject) => {
|
|
73
|
+
function hostRequest(method, params, signal) {
|
|
74
|
+
const id = `claude-host-${nextHostRequest++}`;
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
76
|
const abort = () => {
|
|
77
77
|
pendingHostRequests.delete(id);
|
|
78
78
|
reject(new Error("사용자 입력 요청이 취소되었습니다."));
|
|
79
79
|
};
|
|
80
80
|
if (signal?.aborted) return abort();
|
|
81
81
|
signal?.addEventListener("abort", abort, { once: true });
|
|
82
|
-
pendingHostRequests.set(id, {
|
|
83
|
-
resolve: (value) => {
|
|
84
|
-
signal?.removeEventListener("abort", abort);
|
|
85
|
-
resolve(value);
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
82
|
+
pendingHostRequests.set(id, {
|
|
83
|
+
resolve: (value) => {
|
|
84
|
+
signal?.removeEventListener("abort", abort);
|
|
85
|
+
resolve(value);
|
|
86
|
+
},
|
|
87
|
+
reject: (error) => {
|
|
88
|
+
signal?.removeEventListener("abort", abort);
|
|
89
|
+
reject(error);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
try {
|
|
93
|
+
write({ id, method, params });
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (!pendingHostRequests.delete(id)) return;
|
|
96
|
+
signal?.removeEventListener("abort", abort);
|
|
97
|
+
reject(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
91
101
|
|
|
92
102
|
function sanitizedEnvironment() {
|
|
93
103
|
const env = { ...process.env };
|
|
@@ -356,11 +366,29 @@ async function requestToolPermission(toolName, input, permission) {
|
|
|
356
366
|
isOther: true,
|
|
357
367
|
multiSelect: Boolean(question.multiSelect),
|
|
358
368
|
}));
|
|
359
|
-
const
|
|
360
|
-
"item/tool/requestUserInput",
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
369
|
+
const requestQuestions = () => hostRequest(
|
|
370
|
+
"item/tool/requestUserInput",
|
|
371
|
+
// Keep model-provided text out of the NDJSON envelope. This protects
|
|
372
|
+
// Korean text, backslashes, and malformed Unicode from a partial escape
|
|
373
|
+
// corrupting the request line before the host can open its dialog.
|
|
374
|
+
{
|
|
375
|
+
encoding: "base64-json",
|
|
376
|
+
payload: Buffer.from(JSON.stringify({ questions }), "utf8").toString("base64"),
|
|
377
|
+
},
|
|
378
|
+
permission.signal,
|
|
379
|
+
);
|
|
380
|
+
let response;
|
|
381
|
+
try {
|
|
382
|
+
response = await requestQuestions();
|
|
383
|
+
} catch (error) {
|
|
384
|
+
if (!isQuestionDeliveryError(error)) throw error;
|
|
385
|
+
try {
|
|
386
|
+
response = await requestQuestions();
|
|
387
|
+
} catch (retryError) {
|
|
388
|
+
if (!isQuestionDeliveryError(retryError)) throw retryError;
|
|
389
|
+
return { behavior: "deny", message: questionFallbackMessage(questions) };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
364
392
|
const answers = {};
|
|
365
393
|
for (let index = 0; index < questions.length; index += 1) {
|
|
366
394
|
const selected = response?.answers?.[`q${index}`]?.answers;
|
|
@@ -418,9 +446,28 @@ async function requestToolPermission(toolName, input, permission) {
|
|
|
418
446
|
? { updatedPermissions: permission.suggestions }
|
|
419
447
|
: {}),
|
|
420
448
|
};
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function isQuestionDeliveryError(error) {
|
|
452
|
+
return error?.code === -32700
|
|
453
|
+
|| String(error?.message || error).includes("사용자 입력 화면에 전달하지 못했습니다");
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function questionFallbackMessage(questions) {
|
|
457
|
+
const text = questions.map((question, index) => {
|
|
458
|
+
const options = question.options
|
|
459
|
+
.map((option, optionIndex) => `${optionIndex + 1}. ${option.label}`)
|
|
460
|
+
.join(" / ");
|
|
461
|
+
return `${index + 1}. ${question.question}${options ? ` (${options})` : ""}`;
|
|
462
|
+
}).join("\n");
|
|
463
|
+
return [
|
|
464
|
+
"사용자 입력 창을 두 번 표시하지 못했습니다.",
|
|
465
|
+
"도구를 다시 호출하지 말고 다음 질문을 일반 텍스트로 사용자에게 제시한 뒤 답변을 기다리세요:",
|
|
466
|
+
text,
|
|
467
|
+
].join("\n");
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async function createSession(params, resumeId) {
|
|
424
471
|
const id = resumeId || randomUUID();
|
|
425
472
|
const queue = new AsyncQueue();
|
|
426
473
|
const session = {
|
|
@@ -2420,14 +2467,20 @@ lines.on("line", async (line) => {
|
|
|
2420
2467
|
write({ method: "warning", params: { provider: "Claude", message: `Claude 브리지 JSON 해석 실패: ${error.message}` } });
|
|
2421
2468
|
return;
|
|
2422
2469
|
}
|
|
2423
|
-
if (typeof message.id === "string" && ("result" in message || "error" in message)) {
|
|
2424
|
-
const pending = pendingHostRequests.get(message.id);
|
|
2425
|
-
if (pending) {
|
|
2426
|
-
pendingHostRequests.delete(message.id);
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2470
|
+
if (typeof message.id === "string" && ("result" in message || "error" in message)) {
|
|
2471
|
+
const pending = pendingHostRequests.get(message.id);
|
|
2472
|
+
if (pending) {
|
|
2473
|
+
pendingHostRequests.delete(message.id);
|
|
2474
|
+
if (message.error) {
|
|
2475
|
+
const error = new Error(message.error.message || "호스트 요청이 거부되었습니다.");
|
|
2476
|
+
error.code = message.error.code;
|
|
2477
|
+
pending.reject(error);
|
|
2478
|
+
} else {
|
|
2479
|
+
pending.resolve(message.result ?? { decision: "decline" });
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
return;
|
|
2483
|
+
}
|
|
2431
2484
|
if (typeof message.id !== "number" || typeof message.method !== "string") return;
|
|
2432
2485
|
try { write({ id: message.id, result: await dispatch(message.method, message.params) }); }
|
|
2433
2486
|
catch (error) { write({ id: message.id, error: rpcError(error) }); }
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "devez-vibe",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "Stable terminal UI for Codex and Claude Agent SDK",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"codex",
|
|
7
|
-
"cli",
|
|
8
|
-
"tui",
|
|
9
|
-
"terminal",
|
|
10
|
-
"app-server",
|
|
11
|
-
"claude-agent-sdk"
|
|
12
|
-
],
|
|
13
|
-
"homepage": "https://github.com/MrHoje/Devez-vibe#readme",
|
|
14
|
-
"bugs": "https://github.com/MrHoje/Devez-vibe/issues",
|
|
15
|
-
"repository": {
|
|
16
|
-
"type": "git",
|
|
17
|
-
"url": "git+https://github.com/MrHoje/Devez-vibe.git"
|
|
18
|
-
},
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"bin": {
|
|
21
|
-
"dvz": "bin/dvz.exe"
|
|
22
|
-
},
|
|
23
|
-
"files": [
|
|
24
|
-
"bin/dvz.exe",
|
|
25
|
-
"bridge/claude-agent-sdk-bridge.mjs",
|
|
26
|
-
"README.md",
|
|
27
|
-
"LICENSE"
|
|
28
|
-
],
|
|
29
|
-
"os": [
|
|
30
|
-
"win32"
|
|
31
|
-
],
|
|
32
|
-
"cpu": [
|
|
33
|
-
"x64"
|
|
34
|
-
],
|
|
35
|
-
"engines": {
|
|
36
|
-
"node": ">=18"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.223"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "devez-vibe",
|
|
3
|
+
"version": "1.2.36",
|
|
4
|
+
"description": "Stable terminal UI for Codex and Claude Agent SDK",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"codex",
|
|
7
|
+
"cli",
|
|
8
|
+
"tui",
|
|
9
|
+
"terminal",
|
|
10
|
+
"app-server",
|
|
11
|
+
"claude-agent-sdk"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/MrHoje/Devez-vibe#readme",
|
|
14
|
+
"bugs": "https://github.com/MrHoje/Devez-vibe/issues",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/MrHoje/Devez-vibe.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"bin": {
|
|
21
|
+
"dvz": "bin/dvz.exe"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/dvz.exe",
|
|
25
|
+
"bridge/claude-agent-sdk-bridge.mjs",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"os": [
|
|
30
|
+
"win32"
|
|
31
|
+
],
|
|
32
|
+
"cpu": [
|
|
33
|
+
"x64"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.223"
|
|
40
|
+
}
|
|
41
|
+
}
|