devez-vibe 1.6.35 → 1.6.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 +115 -24
- package/package.json +1 -1
package/bin/dvz.exe
CHANGED
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { createReadStream, existsSync, readdirSync } from "node:fs";
|
|
6
|
-
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
9
9
|
import { createInterface } from "node:readline";
|
|
@@ -2681,9 +2681,101 @@ async function transcriptCwd(id) {
|
|
|
2681
2681
|
|
|
2682
2682
|
/** The cwd to read `id`'s transcript with: the one the transcript itself records,
|
|
2683
2683
|
* falling back to the host's when no transcript is on disk. */
|
|
2684
|
-
async function readableCwd(id, cwd) {
|
|
2685
|
-
return await transcriptCwd(id) || cwd;
|
|
2686
|
-
}
|
|
2684
|
+
async function readableCwd(id, cwd) {
|
|
2685
|
+
return await transcriptCwd(id) || cwd;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
function sameCwd(left, right) {
|
|
2689
|
+
if (!left || !right) return !left && !right;
|
|
2690
|
+
const normalize = (value) => value.replaceAll("\\", "/").replace(/\/$/, "");
|
|
2691
|
+
const normalizedLeft = normalize(left);
|
|
2692
|
+
const normalizedRight = normalize(right);
|
|
2693
|
+
return process.platform === "win32"
|
|
2694
|
+
? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase()
|
|
2695
|
+
: normalizedLeft === normalizedRight;
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
function transcriptPreview(messages) {
|
|
2699
|
+
const prompt = historyTurns(messages)
|
|
2700
|
+
.flatMap((turn) => turn.items || [])
|
|
2701
|
+
.find((item) => item.type === "userMessage");
|
|
2702
|
+
return prompt?.content?.find((item) => item.type === "text")?.text || "Untitled Claude session";
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
async function transcriptSessions(cwd) {
|
|
2706
|
+
if (!cwd) return [];
|
|
2707
|
+
let projects;
|
|
2708
|
+
try {
|
|
2709
|
+
projects = await readdir(claudeProjectsDir(), { withFileTypes: true });
|
|
2710
|
+
} catch {
|
|
2711
|
+
return [];
|
|
2712
|
+
}
|
|
2713
|
+
const rows = new Map();
|
|
2714
|
+
for (const project of projects) {
|
|
2715
|
+
if (!project.isDirectory()) continue;
|
|
2716
|
+
const dir = join(claudeProjectsDir(), project.name);
|
|
2717
|
+
let files;
|
|
2718
|
+
try {
|
|
2719
|
+
files = await readdir(dir, { withFileTypes: true });
|
|
2720
|
+
} catch {
|
|
2721
|
+
continue;
|
|
2722
|
+
}
|
|
2723
|
+
for (const file of files) {
|
|
2724
|
+
if (!file.isFile() || !/^[0-9a-f-]{36}\.jsonl$/i.test(file.name)) continue;
|
|
2725
|
+
const path = join(dir, file.name);
|
|
2726
|
+
let recordedCwd;
|
|
2727
|
+
try {
|
|
2728
|
+
recordedCwd = await readTranscriptCwd(path);
|
|
2729
|
+
} catch {
|
|
2730
|
+
continue;
|
|
2731
|
+
}
|
|
2732
|
+
if (!recordedCwd || (cwd && !sameCwd(recordedCwd, cwd))) continue;
|
|
2733
|
+
const id = file.name.slice(0, -".jsonl".length);
|
|
2734
|
+
try {
|
|
2735
|
+
const [messages, metadata] = await Promise.all([
|
|
2736
|
+
getSessionMessages(id, { dir: recordedCwd, includeSystemMessages: true }),
|
|
2737
|
+
stat(path),
|
|
2738
|
+
]);
|
|
2739
|
+
if (!messages.length) continue;
|
|
2740
|
+
const row = {
|
|
2741
|
+
id: visibleSession(id),
|
|
2742
|
+
preview: transcriptPreview(messages),
|
|
2743
|
+
cwd: recordedCwd,
|
|
2744
|
+
updatedAt: Math.floor(metadata.mtimeMs / 1000),
|
|
2745
|
+
};
|
|
2746
|
+
const previous = rows.get(row.id);
|
|
2747
|
+
if (!previous || row.updatedAt >= previous.updatedAt) rows.set(row.id, row);
|
|
2748
|
+
} catch {
|
|
2749
|
+
continue;
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
return [...rows.values()];
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
async function claudeSessionList(params) {
|
|
2757
|
+
const offset = params.offset || 0;
|
|
2758
|
+
const limit = params.limit || 100;
|
|
2759
|
+
const found = await listSessions({
|
|
2760
|
+
dir: params.cwd,
|
|
2761
|
+
limit: offset + limit,
|
|
2762
|
+
offset: 0,
|
|
2763
|
+
includeProgrammatic: true,
|
|
2764
|
+
});
|
|
2765
|
+
const rows = new Map(found.map((session) => [visibleSession(session.sessionId), {
|
|
2766
|
+
id: visibleSession(session.sessionId),
|
|
2767
|
+
name: session.customTitle || undefined,
|
|
2768
|
+
preview: session.summary || session.firstPrompt || "Untitled Claude session",
|
|
2769
|
+
cwd: session.cwd || params.cwd || "",
|
|
2770
|
+
updatedAt: Math.floor((session.lastModified || 0) / 1000),
|
|
2771
|
+
}]));
|
|
2772
|
+
for (const row of await transcriptSessions(params.cwd)) {
|
|
2773
|
+
if (!rows.has(row.id)) rows.set(row.id, row);
|
|
2774
|
+
}
|
|
2775
|
+
return [...rows.values()]
|
|
2776
|
+
.sort((left, right) => right.updatedAt - left.updatedAt)
|
|
2777
|
+
.slice(offset, offset + limit);
|
|
2778
|
+
}
|
|
2687
2779
|
|
|
2688
2780
|
async function dispatch(method, params = {}) {
|
|
2689
2781
|
if (method === "model/list") return loadModelCatalog(params);
|
|
@@ -2842,24 +2934,12 @@ async function dispatch(method, params = {}) {
|
|
|
2842
2934
|
usage,
|
|
2843
2935
|
tokenUsage,
|
|
2844
2936
|
};
|
|
2845
|
-
}
|
|
2846
|
-
if (method === "session/list") {
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
includeProgrammatic: true,
|
|
2852
|
-
});
|
|
2853
|
-
return {
|
|
2854
|
-
data: found.map((session) => ({
|
|
2855
|
-
id: visibleSession(session.sessionId),
|
|
2856
|
-
name: session.customTitle || undefined,
|
|
2857
|
-
preview: session.summary || session.firstPrompt || "Untitled Claude session",
|
|
2858
|
-
cwd: session.cwd || params.cwd || "",
|
|
2859
|
-
updatedAt: Math.floor((session.lastModified || 0) / 1000),
|
|
2860
|
-
})),
|
|
2861
|
-
nextCursor: null,
|
|
2862
|
-
};
|
|
2937
|
+
}
|
|
2938
|
+
if (method === "session/list") {
|
|
2939
|
+
return {
|
|
2940
|
+
data: await claudeSessionList(params),
|
|
2941
|
+
nextCursor: null,
|
|
2942
|
+
};
|
|
2863
2943
|
}
|
|
2864
2944
|
if (method === "session/history") {
|
|
2865
2945
|
const id = liveSessionId(params.sessionId);
|
|
@@ -2938,8 +3018,19 @@ async function dispatch(method, params = {}) {
|
|
|
2938
3018
|
throw new Error(`지원하지 않는 Claude 브리지 메서드: ${method}`);
|
|
2939
3019
|
}
|
|
2940
3020
|
|
|
2941
|
-
async function runSelfTest() {
|
|
2942
|
-
|
|
3021
|
+
async function runSelfTest() {
|
|
3022
|
+
const equivalentCwd = process.platform === "win32"
|
|
3023
|
+
? sameCwd("D:\\Repo", "d:/repo/")
|
|
3024
|
+
: sameCwd("/tmp/repo", "/tmp/repo/");
|
|
3025
|
+
const preview = transcriptPreview([{
|
|
3026
|
+
type: "user",
|
|
3027
|
+
uuid: "session-list-prompt",
|
|
3028
|
+
message: { content: "세션 목록 질문" },
|
|
3029
|
+
}]);
|
|
3030
|
+
if (!equivalentCwd || preview !== "세션 목록 질문") {
|
|
3031
|
+
throw new Error(`Claude session list self-test failed: ${JSON.stringify({ equivalentCwd, preview })}`);
|
|
3032
|
+
}
|
|
3033
|
+
if (permissionMode("dontAsk") !== "dontAsk"
|
|
2943
3034
|
|| permissionMode("not-a-mode", "auto") !== "auto") {
|
|
2944
3035
|
throw new Error("Claude permission mode self-test failed");
|
|
2945
3036
|
}
|