@neuralnomads/codenomad-dev 0.12.3-dev-20260325-a950d47d → 0.12.3-dev-20260327-0dc5867f
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/dist/index.js +4 -0
- package/dist/opencode-config/package.json +1 -1
- package/dist/server/http-server.js +2 -0
- package/dist/server/routes/settings.js +5 -4
- package/dist/server/routes/speech.js +63 -0
- package/dist/settings/public-config.js +33 -0
- package/dist/settings/service.js +3 -1
- package/dist/speech/providers/openai-compatible.js +168 -0
- package/dist/speech/service.js +58 -0
- package/package.json +2 -1
- package/public/assets/{ChangesTab-BtlO0w9X.js → ChangesTab-Cv6uUHXq.js} +2 -2
- package/public/assets/{DiffToolbar-CFLVAVwp.js → DiffToolbar-B2DpsMyv.js} +1 -1
- package/public/assets/{FilesTab-D_ESs3Yl.js → FilesTab-Cqcle9-p.js} +2 -2
- package/public/assets/{GitChangesTab-BX40u-qP.js → GitChangesTab-CTGmDrEk.js} +2 -2
- package/public/assets/{SplitFilePanel-By4WXdn3.js → SplitFilePanel-C-PYfc9E.js} +1 -1
- package/public/assets/StatusTab-BCjJ1Rol.js +1 -0
- package/public/assets/{bundle-full-BANsFd5O.js → bundle-full-B3_LQwd9.js} +1 -1
- package/public/assets/{diff-viewer-D9gO_MTh.js → diff-viewer-DKzXnQ60.js} +1 -1
- package/public/assets/{index-BXSh5nWk.js → index-8oCNPnPq.js} +1 -1
- package/public/assets/{index-C9h30Q1C.js → index-B0Gw4iLI.js} +1 -1
- package/public/assets/index-BRGJlxmW.js +1 -0
- package/public/assets/{index-BDmfLm1F.js → index-BVDzZGqc.js} +1 -1
- package/public/assets/{index-BrcWei7o.js → index-CIoOszCr.js} +1 -1
- package/public/assets/{index-ibI_csQf.js → index-CQWAxVpU.js} +1 -1
- package/public/assets/index-CvIGqlDH.js +1 -0
- package/public/assets/index-DLerCWdY.js +1 -0
- package/public/assets/index-Da6yiD1l.css +1 -0
- package/public/assets/index-DwZDftuW.js +2 -0
- package/public/assets/{loading-DpmKMdDc.js → loading-BsizLkuJ.js} +1 -1
- package/public/assets/main-CeeRTcLq.js +55 -0
- package/public/assets/{markdown-Bg4ukOG3.js → markdown-kkR-vHDQ.js} +3 -3
- package/public/assets/monaco-viewer-DF7Ts1Ni.js +15 -0
- package/public/assets/{todo-CT3Tu7MH.js → todo-B68SyWtp.js} +1 -1
- package/public/assets/tool-call-bt0dmmrt.js +60 -0
- package/public/assets/{unified-picker-BI6kgIXM.js → unified-picker-HUUdWVpv.js} +1 -1
- package/public/index.html +4 -4
- package/public/loading.html +4 -4
- package/public/sw.js +1 -1
- package/public/assets/StatusTab-ByczrXga.js +0 -1
- package/public/assets/index-BDVB0QYM.js +0 -1
- package/public/assets/index-BIthRcPq.js +0 -2
- package/public/assets/index-CI7fVW4m.js +0 -1
- package/public/assets/index-D34wb8Gr.js +0 -1
- package/public/assets/index-yjkS4m2D.css +0 -1
- package/public/assets/main-Des7GrDE.js +0 -51
- package/public/assets/monaco-viewer-C6klcblw.js +0 -15
- package/public/assets/tool-call-CJDMIc4d.js +0 -60
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import { AuthManager, BOOTSTRAP_TOKEN_STDOUT_PREFIX, DEFAULT_AUTH_USERNAME } fro
|
|
|
22
22
|
import { resolveHttpsOptions } from "./server/tls";
|
|
23
23
|
import { resolveNetworkAddresses } from "./server/network-addresses";
|
|
24
24
|
import { startDevReleaseMonitor } from "./releases/dev-release-monitor";
|
|
25
|
+
import { SpeechService } from "./speech/service";
|
|
25
26
|
const require = createRequire(import.meta.url);
|
|
26
27
|
const packageJson = require("../package.json");
|
|
27
28
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -201,6 +202,7 @@ async function main() {
|
|
|
201
202
|
});
|
|
202
203
|
const fileSystemBrowser = new FileSystemBrowser({ rootDir: options.rootDir, unrestricted: options.unrestrictedRoot });
|
|
203
204
|
const instanceStore = new InstanceStore(configLocation.instancesDir);
|
|
205
|
+
const speechService = new SpeechService(settings, logger.child({ component: "speech" }));
|
|
204
206
|
const instanceEventBridge = new InstanceEventBridge({
|
|
205
207
|
workspaceManager,
|
|
206
208
|
eventBus,
|
|
@@ -273,6 +275,7 @@ async function main() {
|
|
|
273
275
|
eventBus,
|
|
274
276
|
serverMeta,
|
|
275
277
|
instanceStore,
|
|
278
|
+
speechService,
|
|
276
279
|
authManager,
|
|
277
280
|
uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,
|
|
278
281
|
uiDevServerUrl: uiResolution.uiDevServerUrl,
|
|
@@ -292,6 +295,7 @@ async function main() {
|
|
|
292
295
|
eventBus,
|
|
293
296
|
serverMeta,
|
|
294
297
|
instanceStore,
|
|
298
|
+
speechService,
|
|
295
299
|
authManager,
|
|
296
300
|
uiStaticDir: uiResolution.uiStaticDir ?? DEFAULT_UI_STATIC_DIR,
|
|
297
301
|
uiDevServerUrl: undefined,
|
|
@@ -15,6 +15,7 @@ import { registerStorageRoutes } from "./routes/storage";
|
|
|
15
15
|
import { registerPluginRoutes } from "./routes/plugin";
|
|
16
16
|
import { registerBackgroundProcessRoutes } from "./routes/background-processes";
|
|
17
17
|
import { registerWorktreeRoutes } from "./routes/worktrees";
|
|
18
|
+
import { registerSpeechRoutes } from "./routes/speech";
|
|
18
19
|
import { BackgroundProcessManager } from "../background-processes/manager";
|
|
19
20
|
import { registerAuthRoutes } from "./routes/auth";
|
|
20
21
|
import { sendUnauthorized, wantsHtml } from "../auth/http-auth";
|
|
@@ -191,6 +192,7 @@ export function createHttpServer(deps) {
|
|
|
191
192
|
eventBus: deps.eventBus,
|
|
192
193
|
workspaceManager: deps.workspaceManager,
|
|
193
194
|
});
|
|
195
|
+
registerSpeechRoutes(app, { speechService: deps.speechService });
|
|
194
196
|
registerPluginRoutes(app, { workspaceManager: deps.workspaceManager, eventBus: deps.eventBus, logger: proxyLogger });
|
|
195
197
|
registerBackgroundProcessRoutes(app, { backgroundProcessManager });
|
|
196
198
|
registerInstanceProxyRoutes(app, { workspaceManager: deps.workspaceManager, logger: proxyLogger });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { probeBinaryVersion } from "../../workspaces/runtime";
|
|
3
|
+
import { sanitizeConfigDoc, sanitizeConfigOwner } from "../../settings/public-config";
|
|
3
4
|
const ValidateBinarySchema = z.object({
|
|
4
5
|
path: z.string(),
|
|
5
6
|
});
|
|
@@ -9,10 +10,10 @@ function validateBinaryPath(binaryPath) {
|
|
|
9
10
|
}
|
|
10
11
|
export function registerSettingsRoutes(app, deps) {
|
|
11
12
|
// Full-document access
|
|
12
|
-
app.get("/api/storage/config", async () => deps.settings.getDoc("config"));
|
|
13
|
+
app.get("/api/storage/config", async () => sanitizeConfigDoc(deps.settings.getDoc("config")));
|
|
13
14
|
app.patch("/api/storage/config", async (request, reply) => {
|
|
14
15
|
try {
|
|
15
|
-
return deps.settings.mergePatchDoc("config", request.body ?? {});
|
|
16
|
+
return sanitizeConfigDoc(deps.settings.mergePatchDoc("config", request.body ?? {}));
|
|
16
17
|
}
|
|
17
18
|
catch (error) {
|
|
18
19
|
reply.code(400);
|
|
@@ -20,11 +21,11 @@ export function registerSettingsRoutes(app, deps) {
|
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
app.get("/api/storage/config/:owner", async (request) => {
|
|
23
|
-
return deps.settings.getOwner("config", request.params.owner);
|
|
24
|
+
return sanitizeConfigOwner(request.params.owner, deps.settings.getOwner("config", request.params.owner));
|
|
24
25
|
});
|
|
25
26
|
app.patch("/api/storage/config/:owner", async (request, reply) => {
|
|
26
27
|
try {
|
|
27
|
-
return deps.settings.mergePatchOwner("config", request.params.owner, request.body ?? {});
|
|
28
|
+
return sanitizeConfigOwner(request.params.owner, deps.settings.mergePatchOwner("config", request.params.owner, request.body ?? {}));
|
|
28
29
|
}
|
|
29
30
|
catch (error) {
|
|
30
31
|
reply.code(400);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const TranscribeBodySchema = z.object({
|
|
3
|
+
audioBase64: z.string().min(1, "Audio payload is required"),
|
|
4
|
+
mimeType: z.string().min(1, "Audio MIME type is required"),
|
|
5
|
+
filename: z.string().optional(),
|
|
6
|
+
language: z.string().optional(),
|
|
7
|
+
prompt: z.string().optional(),
|
|
8
|
+
});
|
|
9
|
+
const SynthesizeBodySchema = z.object({
|
|
10
|
+
text: z.string().trim().min(1, "Text is required"),
|
|
11
|
+
format: z.enum(["mp3", "wav", "opus", "aac"]).optional(),
|
|
12
|
+
});
|
|
13
|
+
function getSpeechErrorStatus(error) {
|
|
14
|
+
if (error instanceof z.ZodError) {
|
|
15
|
+
return 400;
|
|
16
|
+
}
|
|
17
|
+
if (error instanceof Error && /not configured/i.test(error.message)) {
|
|
18
|
+
return 503;
|
|
19
|
+
}
|
|
20
|
+
return 502;
|
|
21
|
+
}
|
|
22
|
+
function getSpeechErrorMessage(error, fallback) {
|
|
23
|
+
return error instanceof Error ? error.message : fallback;
|
|
24
|
+
}
|
|
25
|
+
export function registerSpeechRoutes(app, deps) {
|
|
26
|
+
app.get("/api/speech/capabilities", async () => deps.speechService.getCapabilities());
|
|
27
|
+
app.post("/api/speech/transcribe", async (request, reply) => {
|
|
28
|
+
try {
|
|
29
|
+
const body = TranscribeBodySchema.parse(request.body ?? {});
|
|
30
|
+
return await deps.speechService.transcribe(body);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
request.log.error({ err: error }, "Failed to transcribe audio");
|
|
34
|
+
reply.code(getSpeechErrorStatus(error));
|
|
35
|
+
return { error: getSpeechErrorMessage(error, "Failed to transcribe audio") };
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
app.post("/api/speech/synthesize", async (request, reply) => {
|
|
39
|
+
try {
|
|
40
|
+
const body = SynthesizeBodySchema.parse(request.body ?? {});
|
|
41
|
+
return await deps.speechService.synthesize(body);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
request.log.error({ err: error }, "Failed to synthesize audio");
|
|
45
|
+
reply.code(getSpeechErrorStatus(error));
|
|
46
|
+
return { error: getSpeechErrorMessage(error, "Failed to synthesize audio") };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
app.post("/api/speech/synthesize/stream", async (request, reply) => {
|
|
50
|
+
try {
|
|
51
|
+
const body = SynthesizeBodySchema.parse(request.body ?? {});
|
|
52
|
+
const result = await deps.speechService.synthesizeStream(body);
|
|
53
|
+
reply.header("Content-Type", result.mimeType);
|
|
54
|
+
reply.header("Cache-Control", "no-store");
|
|
55
|
+
return reply.send(result.stream);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
request.log.error({ err: error }, "Failed to stream synthesized audio");
|
|
59
|
+
reply.code(getSpeechErrorStatus(error));
|
|
60
|
+
return { error: getSpeechErrorMessage(error, "Failed to stream synthesized audio") };
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function isPlainObject(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function sanitizeServerOwner(value) {
|
|
5
|
+
const next = { ...value };
|
|
6
|
+
const speech = isPlainObject(next.speech) ? { ...next.speech } : null;
|
|
7
|
+
if (!speech) {
|
|
8
|
+
return next;
|
|
9
|
+
}
|
|
10
|
+
const rawApiKey = typeof speech.apiKey === "string" ? speech.apiKey.trim() : "";
|
|
11
|
+
if (rawApiKey) {
|
|
12
|
+
delete speech.apiKey;
|
|
13
|
+
speech.hasApiKey = true;
|
|
14
|
+
}
|
|
15
|
+
else if (!("hasApiKey" in speech)) {
|
|
16
|
+
speech.hasApiKey = false;
|
|
17
|
+
}
|
|
18
|
+
next.speech = speech;
|
|
19
|
+
return next;
|
|
20
|
+
}
|
|
21
|
+
export function sanitizeConfigOwner(owner, value) {
|
|
22
|
+
if (owner !== "server") {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
return sanitizeServerOwner(value);
|
|
26
|
+
}
|
|
27
|
+
export function sanitizeConfigDoc(value) {
|
|
28
|
+
const next = { ...value };
|
|
29
|
+
if (isPlainObject(next.server)) {
|
|
30
|
+
next.server = sanitizeServerOwner(next.server);
|
|
31
|
+
}
|
|
32
|
+
return next;
|
|
33
|
+
}
|
package/dist/settings/service.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { YamlDocStore } from "./yaml-doc-store";
|
|
2
2
|
import { migrateSettingsLayout } from "./migrate";
|
|
3
|
+
import { sanitizeConfigOwner } from "./public-config";
|
|
3
4
|
export class SettingsService {
|
|
4
5
|
constructor(location, eventBus, logger) {
|
|
5
6
|
this.location = location;
|
|
@@ -29,10 +30,11 @@ export class SettingsService {
|
|
|
29
30
|
if (!this.eventBus)
|
|
30
31
|
return;
|
|
31
32
|
const type = kind === "config" ? "storage.configChanged" : "storage.stateChanged";
|
|
33
|
+
const nextValue = value ?? this.getOwner(kind, owner);
|
|
32
34
|
const payload = {
|
|
33
35
|
type,
|
|
34
36
|
owner,
|
|
35
|
-
value:
|
|
37
|
+
value: kind === "config" ? sanitizeConfigOwner(owner, nextValue) : nextValue,
|
|
36
38
|
};
|
|
37
39
|
this.eventBus.publish(payload);
|
|
38
40
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
import { toFile } from "openai/uploads";
|
|
4
|
+
export class OpenAICompatibleSpeechProvider {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.options = options;
|
|
7
|
+
}
|
|
8
|
+
getCapabilities() {
|
|
9
|
+
const { settings } = this.options;
|
|
10
|
+
return {
|
|
11
|
+
available: true,
|
|
12
|
+
configured: Boolean(settings.apiKey),
|
|
13
|
+
provider: settings.provider,
|
|
14
|
+
supportsStt: true,
|
|
15
|
+
supportsTts: true,
|
|
16
|
+
supportsStreamingTts: true,
|
|
17
|
+
baseUrl: settings.baseUrl,
|
|
18
|
+
sttModel: settings.sttModel,
|
|
19
|
+
ttsModel: settings.ttsModel,
|
|
20
|
+
ttsVoice: settings.ttsVoice,
|
|
21
|
+
ttsFormats: ["mp3", "wav", "opus", "aac"],
|
|
22
|
+
streamingTtsFormats: ["mp3", "wav", "opus", "aac"],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async transcribe(input) {
|
|
26
|
+
const client = this.createClient();
|
|
27
|
+
const startedAt = Date.now();
|
|
28
|
+
const extension = extensionForMime(input.mimeType);
|
|
29
|
+
const buffer = Buffer.from(input.audioBase64, "base64");
|
|
30
|
+
const filename = input.filename?.trim() || `prompt-input.${extension}`;
|
|
31
|
+
this.options.logger.info({
|
|
32
|
+
mimeType: input.mimeType,
|
|
33
|
+
bytes: buffer.byteLength,
|
|
34
|
+
language: input.language,
|
|
35
|
+
model: this.options.settings.sttModel,
|
|
36
|
+
}, "speech.transcribe");
|
|
37
|
+
const response = await this.requestTranscription(client, buffer, filename, input);
|
|
38
|
+
return {
|
|
39
|
+
text: typeof response?.text === "string" ? response.text : "",
|
|
40
|
+
language: typeof response?.language === "string" ? response.language : input.language,
|
|
41
|
+
durationMs: Number.isFinite(response?.duration) ? Math.round(Number(response.duration) * 1000) : Date.now() - startedAt,
|
|
42
|
+
segments: Array.isArray(response?.segments)
|
|
43
|
+
? response.segments
|
|
44
|
+
.filter((segment) => typeof segment?.text === "string")
|
|
45
|
+
.map((segment) => ({
|
|
46
|
+
startMs: Math.max(0, Math.round(Number(segment.start ?? 0) * 1000)),
|
|
47
|
+
endMs: Math.max(0, Math.round(Number(segment.end ?? 0) * 1000)),
|
|
48
|
+
text: String(segment.text),
|
|
49
|
+
}))
|
|
50
|
+
: undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async requestTranscription(client, buffer, filename, input) {
|
|
54
|
+
const baseRequest = {
|
|
55
|
+
model: this.options.settings.sttModel,
|
|
56
|
+
...(input.language ? { language: input.language } : {}),
|
|
57
|
+
...(input.prompt ? { prompt: input.prompt } : {}),
|
|
58
|
+
};
|
|
59
|
+
try {
|
|
60
|
+
const file = await toFile(buffer, filename, { type: input.mimeType });
|
|
61
|
+
return (await client.audio.transcriptions.create({
|
|
62
|
+
...baseRequest,
|
|
63
|
+
file,
|
|
64
|
+
response_format: "verbose_json",
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.options.logger.warn({ err: error }, "speech.transcribe verbose_json failed; retrying default format");
|
|
69
|
+
const retryFile = await toFile(buffer, filename, { type: input.mimeType });
|
|
70
|
+
return (await client.audio.transcriptions.create({
|
|
71
|
+
...baseRequest,
|
|
72
|
+
file: retryFile,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async synthesize(input) {
|
|
77
|
+
const format = input.format ?? this.options.settings.ttsFormat;
|
|
78
|
+
this.options.logger.info({
|
|
79
|
+
model: this.options.settings.ttsModel,
|
|
80
|
+
voice: this.options.settings.ttsVoice,
|
|
81
|
+
format,
|
|
82
|
+
}, "speech.synthesize");
|
|
83
|
+
const response = await this.requestSpeechAudio(input.text, format);
|
|
84
|
+
const mimeType = response.headers.get("content-type") || mimeTypeForFormat(format);
|
|
85
|
+
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
86
|
+
return {
|
|
87
|
+
audioBase64: audioBuffer.toString("base64"),
|
|
88
|
+
mimeType,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async synthesizeStream(input) {
|
|
92
|
+
const format = input.format ?? this.options.settings.ttsFormat;
|
|
93
|
+
this.options.logger.info({
|
|
94
|
+
model: this.options.settings.ttsModel,
|
|
95
|
+
voice: this.options.settings.ttsVoice,
|
|
96
|
+
format,
|
|
97
|
+
}, "speech.synthesize.stream");
|
|
98
|
+
const response = await this.requestSpeechAudio(input.text, format);
|
|
99
|
+
if (!response.body) {
|
|
100
|
+
throw new Error("Speech provider did not return a stream.");
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
stream: Readable.fromWeb(response.body),
|
|
104
|
+
mimeType: response.headers.get("content-type") || mimeTypeForFormat(format),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async requestSpeechAudio(text, format) {
|
|
108
|
+
const { settings } = this.options;
|
|
109
|
+
if (!settings.apiKey) {
|
|
110
|
+
throw new Error("Speech provider is not configured. Add an API key in Speech settings.");
|
|
111
|
+
}
|
|
112
|
+
const endpoint = new URL("audio/speech", ensureTrailingSlash(settings.baseUrl ?? "https://api.openai.com/v1"));
|
|
113
|
+
const response = await fetch(endpoint, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: {
|
|
116
|
+
Authorization: `Bearer ${settings.apiKey}`,
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify({
|
|
120
|
+
model: settings.ttsModel,
|
|
121
|
+
voice: settings.ttsVoice,
|
|
122
|
+
input: text,
|
|
123
|
+
response_format: format,
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
const detail = await response.text();
|
|
128
|
+
throw new Error(detail || `Speech synthesis failed with ${response.status}`);
|
|
129
|
+
}
|
|
130
|
+
return response;
|
|
131
|
+
}
|
|
132
|
+
createClient() {
|
|
133
|
+
const { settings } = this.options;
|
|
134
|
+
if (!settings.apiKey) {
|
|
135
|
+
throw new Error("Speech provider is not configured. Add an API key in Speech settings.");
|
|
136
|
+
}
|
|
137
|
+
return new OpenAI({
|
|
138
|
+
apiKey: settings.apiKey,
|
|
139
|
+
baseURL: settings.baseUrl,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function extensionForMime(mimeType) {
|
|
144
|
+
const normalized = mimeType.toLowerCase();
|
|
145
|
+
if (normalized.includes("webm"))
|
|
146
|
+
return "webm";
|
|
147
|
+
if (normalized.includes("ogg"))
|
|
148
|
+
return "ogg";
|
|
149
|
+
if (normalized.includes("wav"))
|
|
150
|
+
return "wav";
|
|
151
|
+
if (normalized.includes("mpeg") || normalized.includes("mp3"))
|
|
152
|
+
return "mp3";
|
|
153
|
+
if (normalized.includes("mp4") || normalized.includes("aac"))
|
|
154
|
+
return "m4a";
|
|
155
|
+
return "webm";
|
|
156
|
+
}
|
|
157
|
+
function mimeTypeForFormat(format) {
|
|
158
|
+
if (format === "wav")
|
|
159
|
+
return "audio/wav";
|
|
160
|
+
if (format === "opus")
|
|
161
|
+
return 'audio/ogg; codecs="opus"';
|
|
162
|
+
if (format === "aac")
|
|
163
|
+
return "audio/aac";
|
|
164
|
+
return "audio/mpeg";
|
|
165
|
+
}
|
|
166
|
+
function ensureTrailingSlash(value) {
|
|
167
|
+
return value.endsWith("/") ? value : `${value}/`;
|
|
168
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { OpenAICompatibleSpeechProvider } from "./providers/openai-compatible";
|
|
3
|
+
const ServerSpeechSettingsSchema = z.object({
|
|
4
|
+
speech: z
|
|
5
|
+
.object({
|
|
6
|
+
provider: z.string().optional(),
|
|
7
|
+
apiKey: z.string().optional(),
|
|
8
|
+
baseUrl: z.string().optional(),
|
|
9
|
+
sttModel: z.string().optional(),
|
|
10
|
+
ttsModel: z.string().optional(),
|
|
11
|
+
ttsVoice: z.string().optional(),
|
|
12
|
+
ttsFormat: z.enum(["mp3", "wav", "opus", "aac"]).optional(),
|
|
13
|
+
})
|
|
14
|
+
.optional(),
|
|
15
|
+
});
|
|
16
|
+
const DEFAULT_PROVIDER = "openai-compatible";
|
|
17
|
+
const DEFAULT_STT_MODEL = "gpt-4o-mini-transcribe";
|
|
18
|
+
const DEFAULT_TTS_MODEL = "gpt-4o-mini-tts";
|
|
19
|
+
const DEFAULT_TTS_VOICE = "alloy";
|
|
20
|
+
const DEFAULT_TTS_FORMAT = "mp3";
|
|
21
|
+
export class SpeechService {
|
|
22
|
+
constructor(settings, logger) {
|
|
23
|
+
this.settings = settings;
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
}
|
|
26
|
+
getCapabilities() {
|
|
27
|
+
return this.createProvider().getCapabilities();
|
|
28
|
+
}
|
|
29
|
+
async transcribe(input) {
|
|
30
|
+
return this.createProvider().transcribe(input);
|
|
31
|
+
}
|
|
32
|
+
async synthesize(input) {
|
|
33
|
+
return this.createProvider().synthesize(input);
|
|
34
|
+
}
|
|
35
|
+
async synthesizeStream(input) {
|
|
36
|
+
return this.createProvider().synthesizeStream(input);
|
|
37
|
+
}
|
|
38
|
+
createProvider() {
|
|
39
|
+
const settings = this.resolveSettings();
|
|
40
|
+
return new OpenAICompatibleSpeechProvider({
|
|
41
|
+
settings,
|
|
42
|
+
logger: this.logger.child({ provider: settings.provider }),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
resolveSettings() {
|
|
46
|
+
const parsed = ServerSpeechSettingsSchema.parse(this.settings.getOwner("config", "server") ?? {});
|
|
47
|
+
const speech = parsed.speech ?? {};
|
|
48
|
+
return {
|
|
49
|
+
provider: speech.provider?.trim() || DEFAULT_PROVIDER,
|
|
50
|
+
apiKey: speech.apiKey?.trim() || process.env.OPENAI_API_KEY,
|
|
51
|
+
baseUrl: speech.baseUrl?.trim() || process.env.OPENAI_BASE_URL || undefined,
|
|
52
|
+
sttModel: speech.sttModel?.trim() || DEFAULT_STT_MODEL,
|
|
53
|
+
ttsModel: speech.ttsModel?.trim() || DEFAULT_TTS_MODEL,
|
|
54
|
+
ttsVoice: speech.ttsVoice?.trim() || DEFAULT_TTS_VOICE,
|
|
55
|
+
ttsFormat: speech.ttsFormat ?? DEFAULT_TTS_FORMAT,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuralnomads/codenomad-dev",
|
|
3
|
-
"version": "0.12.3-dev-
|
|
3
|
+
"version": "0.12.3-dev-20260327-0dc5867f",
|
|
4
4
|
"description": "CodeNomad Server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"fastify": "^4.28.1",
|
|
33
33
|
"fuzzysort": "^2.0.4",
|
|
34
34
|
"node-forge": "^1.3.3",
|
|
35
|
+
"openai": "^6.27.0",
|
|
35
36
|
"pino": "^9.4.0",
|
|
36
37
|
"undici": "^6.19.8",
|
|
37
38
|
"yaml": "^2.4.2",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-
|
|
2
|
-
import{_ as K}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DF7Ts1Ni.js","assets/git-diff-vendor-CAv-4upN.js","assets/fast-diff-vendor-DgdwVvTQ.js","assets/highlight-vendor-8FKMu9os.js","assets/git-diff-vendor-HAZkIolJ.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as K}from"./index-DwZDftuW.js";import{m as B,t as g,i as a,d as w,a as F,f as N}from"./monaco-viewer-DF7Ts1Ni.js";import{c as f,n as c,a as L,F as T,S as W,z as j,A as q}from"./git-diff-vendor-CAv-4upN.js";import{D as G}from"./DiffToolbar-B2DpsMyv.js";import{S as H}from"./SplitFilePanel-C-PYfc9E.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";import"./main-CeeRTcLq.js";var J=g('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),E=g("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),Q=g('<div class="p-3 text-xs text-secondary">'),R=g("<div><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text></span></div><div class=file-list-item-stats><span class=file-list-item-additions>+</span><span class=file-list-item-deletions>-"),U=g("<span class=files-tab-selected-path><span class=file-path-text>"),X=g('<div class=files-tab-stats style="flex:0 0 auto"><span class="files-tab-stat files-tab-stat-additions"><span class=files-tab-stat-value>+</span></span><span class="files-tab-stat files-tab-stat-deletions"><span class=files-tab-stat-value>-'),Y=g("<div style=margin-left:auto>");const Z=q(()=>K(()=>import("./monaco-viewer-DF7Ts1Ni.js").then(e=>e.aa),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoDiffViewer}))),de=e=>{const M=f(()=>e.activeSessionId()),S=f(()=>!!(M()&&M()!=="info")),D=f(()=>S()?e.activeSessionDiffs():null),y=f(()=>{const n=D();return Array.isArray(n)?[...n].sort((i,l)=>String(i.file||"").localeCompare(String(l.file||""))):[]}),I=f(()=>y().reduce((n,i)=>(n.additions+=typeof i.additions=="number"?i.additions:0,n.deletions+=typeof i.deletions=="number"?i.deletions:0,n),{additions:0,deletions:0})),O=f(()=>{const n=y();return n.length===0?null:n.reduce((i,l)=>{const v=typeof(i==null?void 0:i.additions)=="number"?i.additions:0,m=typeof(i==null?void 0:i.deletions)=="number"?i.deletions:0,x=v+m,k=typeof(l==null?void 0:l.additions)=="number"?l.additions:0,t=typeof(l==null?void 0:l.deletions)=="number"?l.deletions:0,r=k+t;return r>x?l:r<x?i:String(l.file||"").localeCompare(String((i==null?void 0:i.file)||""))<0?l:i},n[0])}),P=f(()=>{const n=e.selectedFile(),i=y();if(n){const l=i.find(v=>v.file===n);if(l)return l}return O()}),p=f(()=>`${e.instanceId}:${S()?M():"no-session"}`),V=f(()=>{if(!S())return e.t("instanceShell.sessionChanges.noSessionSelected");const n=D();return n===void 0?e.t("instanceShell.sessionChanges.loading"):!Array.isArray(n)||n.length===0?e.t("instanceShell.sessionChanges.empty"):e.t("instanceShell.filesShell.viewerEmpty")}),A=f(()=>{const n=P();return n!=null&&n.file?String(n.file):e.t("instanceShell.rightPanel.tabs.changes")});return B(()=>{const n=y(),i=I(),l=P(),v=()=>(()=>{var t=J(),r=t.firstChild;return a(r,c(W,{get when(){return l&&S()&&n.length>0?l:null},get fallback(){return(()=>{var o=E(),s=o.firstChild;return a(s,V),o})()},children:o=>c(j,{get fallback(){return(()=>{var s=E(),u=s.firstChild;return a(u,()=>e.t("instanceInfo.loading")),s})()},get children(){return c(Z,{get scopeKey(){return p()},get path(){return String(o().file||"")},get before(){return String(o().before||"")},get after(){return String(o().after||"")},get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrap(){return e.diffWordWrapMode()}})}})})),t})(),m=()=>(()=>{var t=Q();return a(t,V),t})();return c(H,{get header(){return[(()=>{var t=U(),r=t.firstChild;return a(r,A),L(()=>w(t,"title",A())),t})(),(()=>{var t=X(),r=t.firstChild,o=r.firstChild;o.firstChild;var s=r.nextSibling,u=s.firstChild;return u.firstChild,a(o,()=>i.additions,null),a(u,()=>i.deletions,null),t})(),(()=>{var t=Y();return a(t,c(G,{get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrapMode(){return e.diffWordWrapMode()},get onViewModeChange(){return e.onViewModeChange},get onContextModeChange(){return e.onContextModeChange},get onWordWrapModeChange(){return e.onWordWrapModeChange}})),t})()]},list:{panel:()=>c(W,{get when(){return n.length>0},get fallback(){return m()},get children(){return c(T,{each:n,children:t=>(()=>{var r=R(),o=r.firstChild,s=o.firstChild,u=s.firstChild,b=s.nextSibling,h=b.firstChild;h.firstChild;var C=h.nextSibling;return C.firstChild,r.$$click=()=>{e.onSelectFile(t.file,e.isPhoneLayout())},a(u,()=>t.file),a(h,()=>t.additions,null),a(C,()=>t.deletions,null),L(d=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file;return _!==d.e&&F(r,d.e=_),$!==d.t&&w(s,"title",d.t=$),d},{e:void 0,t:void 0}),r})()})}}),overlay:()=>c(W,{get when(){return n.length>0},get fallback(){return m()},get children(){return c(T,{each:n,children:t=>(()=>{var r=R(),o=r.firstChild,s=o.firstChild,u=s.firstChild,b=s.nextSibling,h=b.firstChild;h.firstChild;var C=h.nextSibling;return C.firstChild,r.$$click=()=>{e.onSelectFile(t.file,!0)},a(u,()=>t.file),a(h,()=>t.additions,null),a(C,()=>t.deletions,null),L(d=>{var _=`file-list-item ${(l==null?void 0:l.file)===t.file?"file-list-item-active":""}`,$=t.file,z=t.file;return _!==d.e&&F(r,d.e=_),$!==d.t&&w(r,"title",d.t=$),z!==d.a&&w(s,"title",d.a=z),d},{e:void 0,t:void 0,a:void 0}),r})()})}})},get viewer(){return v()},get listOpen(){return e.listOpen()},get onToggleList(){return e.onToggleList},get splitWidth(){return e.splitWidth()},get onResizeMouseDown(){return e.onResizeMouseDown},get onResizeTouchStart(){return e.onResizeTouchStart},get isPhoneLayout(){return e.isPhoneLayout()},get overlayAriaLabel(){return e.t("instanceShell.rightPanel.tabs.changes")}})})};N(["click"]);export{de as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as $,i as c,m as S,d as n,a as T,f as C}from"./monaco-viewer-
|
|
1
|
+
import{t as $,i as c,m as S,d as n,a as T,f as C}from"./monaco-viewer-DF7Ts1Ni.js";import{u as N}from"./index-DwZDftuW.js";import{n as i,m as h,a as V}from"./git-diff-vendor-CAv-4upN.js";import{I as f,J as U,K as A}from"./main-CeeRTcLq.js";const I=[["line",{x1:"3",x2:"21",y1:"6",y2:"6",key:"4m8b97"}],["line",{x1:"3",x2:"21",y1:"12",y2:"12",key:"10d38w"}],["line",{x1:"3",x2:"21",y1:"18",y2:"18",key:"kwyyxn"}]],J=t=>i(f,h(t,{name:"AlignJustify",iconNode:I})),j=[["path",{d:"M12 22v-6",key:"6o8u61"}],["path",{d:"M12 8V2",key:"1wkif3"}],["path",{d:"M4 12H2",key:"rhcxmi"}],["path",{d:"M10 12H8",key:"s88cx1"}],["path",{d:"M16 12h-2",key:"10asgb"}],["path",{d:"M22 12h-2",key:"14jgyd"}],["path",{d:"m15 19-3 3-3-3",key:"11eu04"}],["path",{d:"m15 5-3-3-3 3",key:"itvq4r"}]],D=t=>i(f,h(t,{name:"UnfoldVertical",iconNode:j})),E=[["line",{x1:"3",x2:"21",y1:"6",y2:"6",key:"4m8b97"}],["path",{d:"M3 12h15a3 3 0 1 1 0 6h-4",key:"1cl7v7"}],["polyline",{points:"16 16 14 18 16 20",key:"1jznyi"}],["line",{x1:"3",x2:"10",y1:"18",y2:"18",key:"1h33wv"}]],F=t=>i(f,h(t,{name:"WrapText",iconNode:E}));var H=$("<div class=file-viewer-toolbar><button type=button class=file-viewer-toolbar-icon-button></button><button type=button class=file-viewer-toolbar-icon-button></button><button type=button>");const R=t=>{const{t:o}=N(),s=()=>t.viewMode==="split"?"unified":"split",r=()=>t.contextMode==="collapsed"?"expanded":"collapsed",y=()=>t.wordWrapMode==="on"?"off":"on",v=()=>s()==="split"?o("instanceShell.diff.switchToSplit"):o("instanceShell.diff.switchToUnified"),u=()=>r()==="collapsed"?o("instanceShell.diff.hideUnchanged"):o("instanceShell.diff.showFull"),b=()=>y()==="on"?o("instanceShell.diff.enableWordWrap"):o("instanceShell.diff.disableWordWrap");return(()=>{var x=H(),a=x.firstChild,l=a.nextSibling,d=l.nextSibling;return a.$$click=()=>t.onViewModeChange(s()),c(a,(()=>{var e=S(()=>s()==="split");return()=>e()?i(U,{class:"h-4 w-4","aria-hidden":"true"}):i(J,{class:"h-4 w-4","aria-hidden":"true"})})()),l.$$click=()=>t.onContextModeChange(r()),c(l,(()=>{var e=S(()=>r()==="collapsed");return()=>e()?i(A,{class:"h-4 w-4","aria-hidden":"true"}):i(D,{class:"h-4 w-4","aria-hidden":"true"})})()),d.$$click=()=>t.onWordWrapModeChange(y()),c(d,i(F,{class:"h-4 w-4","aria-hidden":"true"})),V(e=>{var m=v(),w=v(),k=u(),M=u(),p=`file-viewer-toolbar-icon-button${t.wordWrapMode==="on"?" active":""}`,W=b(),g=b();return m!==e.e&&n(a,"aria-label",e.e=m),w!==e.t&&n(a,"title",e.t=w),k!==e.a&&n(l,"aria-label",e.a=k),M!==e.o&&n(l,"title",e.o=M),p!==e.i&&T(d,e.i=p),W!==e.n&&n(d,"aria-label",e.n=W),g!==e.s&&n(d,"title",e.s=g),e},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0,n:void 0,s:void 0}),x})()};C(["click"]);export{R as D};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-
|
|
2
|
-
import{_ as E}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DF7Ts1Ni.js","assets/git-diff-vendor-CAv-4upN.js","assets/fast-diff-vendor-DgdwVvTQ.js","assets/highlight-vendor-8FKMu9os.js","assets/git-diff-vendor-HAZkIolJ.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as E}from"./index-DwZDftuW.js";import{m as y,t as c,i,d as h,a as R,f as k}from"./monaco-viewer-DF7Ts1Ni.js";import{n as s,S as d,a as f,F as z,z as F,A as D}from"./git-diff-vendor-CAv-4upN.js";import{S as I}from"./SplitFilePanel-C-PYfc9E.js";import{R as T}from"./main-CeeRTcLq.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";var v=c("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),V=c('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),M=c('<div class="p-3 text-xs text-secondary">'),A=c("<div class=file-list-item><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text>.."),O=c('<div><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text></span></div><div class=file-list-item-stats><span class="text-[10px] text-secondary">'),K=c("<span>"),W=c("<div class=files-tab-stats><span class=files-tab-stat><span class=files-tab-selected-path><span class=file-path-text>"),N=c("<button type=button class=files-header-icon-button style=margin-inline-start:auto>"),j=c("<span class=text-error>");const q=D(()=>E(()=>import("./monaco-viewer-DF7Ts1Ni.js").then(e=>e.ab),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoFileViewer}))),p=e=>y(()=>{const g=e.browserEntries(),S=[...g||[]].sort((t,r)=>{const n=t.type==="directory"?0:1,l=r.type==="directory"?0:1;return n!==l?n-l:String(t.name||"").localeCompare(String(r.name||""))}),C=e.parentPath(),m=()=>e.browserSelectedPath()||e.browserPath(),L=()=>e.browserLoading()&&g===null?e.t("instanceInfo.loading"):e.t("instanceShell.filesShell.viewerEmpty"),P=()=>(()=>{var t=V(),r=t.firstChild;return i(r,s(d,{get when(){return e.browserSelectedLoading()},get fallback(){return s(d,{get when(){return e.browserSelectedError()},get fallback(){return s(d,{get when(){return y(()=>!!(e.browserSelectedPath()&&e.browserSelectedContent()!==null))()?{path:e.browserSelectedPath(),content:e.browserSelectedContent()}:null},get fallback(){return(()=>{var n=v(),l=n.firstChild;return i(l,L),n})()},children:n=>s(F,{get fallback(){return(()=>{var l=v(),a=l.firstChild;return i(a,()=>e.t("instanceInfo.loading")),l})()},get children(){return s(q,{get scopeKey(){return e.scopeKey()},get path(){return n().path},get content(){return n().content}})}})})},children:n=>(()=>{var l=v(),a=l.firstChild;return i(a,n),l})()})},get children(){var n=v(),l=n.firstChild;return i(l,()=>e.t("instanceInfo.loading")),n}})),t})(),w=()=>[s(d,{when:C,children:t=>(()=>{var r=A(),n=r.firstChild,l=n.firstChild;return r.$$click=()=>e.onLoadEntries(t()),f(()=>h(l,"title",t())),r})()}),s(d,{get when(){return e.browserLoading()&&g===null},get children(){var t=M();return i(t,()=>e.t("instanceInfo.loading")),t}}),s(z,{each:S,children:t=>(()=>{var r=O(),n=r.firstChild,l=n.firstChild,a=l.firstChild,u=l.nextSibling,x=u.firstChild;return r.$$click=()=>{if(t.type==="directory"){e.onLoadEntries(t.path);return}e.onOpenFile(t.path)},i(a,()=>t.name),i(x,()=>t.type),f(o=>{var _=`file-list-item ${e.browserSelectedPath()===t.path?"file-list-item-active":""}`,$=t.path,b=t.path;return _!==o.e&&R(r,o.e=_),$!==o.t&&h(r,"title",o.t=$),b!==o.a&&h(l,"title",o.a=b),o},{e:void 0,t:void 0,a:void 0}),r})()})];return s(I,{get header(){return[(()=>{var t=W(),r=t.firstChild,n=r.firstChild,l=n.firstChild;return i(l,m),i(t,s(d,{get when(){return e.browserLoading()},get children(){var a=K();return i(a,()=>e.t("instanceInfo.loading")),a}}),null),i(t,s(d,{get when(){return e.browserError()},children:a=>(()=>{var u=j();return i(u,a),u})()}),null),f(()=>h(n,"title",m())),t})(),(()=>{var t=N();return t.$$click=()=>e.onRefresh(),i(t,s(T,{get class(){return`h-4 w-4${e.browserLoading()?" animate-spin":""}`}})),f(r=>{var n=e.t("instanceShell.rightPanel.actions.refresh"),l=e.t("instanceShell.rightPanel.actions.refresh"),a=e.browserLoading();return n!==r.e&&h(t,"title",r.e=n),l!==r.t&&h(t,"aria-label",r.t=l),a!==r.a&&(t.disabled=r.a=a),r},{e:void 0,t:void 0,a:void 0}),t})()]},list:{panel:w,overlay:w},get viewer(){return P()},get listOpen(){return e.listOpen()},get onToggleList(){return e.onToggleList},get splitWidth(){return e.splitWidth()},get onResizeMouseDown(){return e.onResizeMouseDown},get onResizeTouchStart(){return e.onResizeTouchStart},get isPhoneLayout(){return e.isPhoneLayout()},get overlayAriaLabel(){return e.t("instanceShell.rightPanel.tabs.files")}})});k(["click"]);export{p as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-
|
|
2
|
-
import{_ as B}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-DF7Ts1Ni.js","assets/git-diff-vendor-CAv-4upN.js","assets/fast-diff-vendor-DgdwVvTQ.js","assets/highlight-vendor-8FKMu9os.js","assets/git-diff-vendor-HAZkIolJ.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as B}from"./index-DwZDftuW.js";import{m as V,t as h,i as r,d as $,a as D,f as K}from"./monaco-viewer-DF7Ts1Ni.js";import{c as f,n as d,a as w,S as c,F as R,z as G,A as N}from"./git-diff-vendor-CAv-4upN.js";import{D as j}from"./DiffToolbar-B2DpsMyv.js";import{S as q}from"./SplitFilePanel-C-PYfc9E.js";import{R as H}from"./main-CeeRTcLq.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";var S=h("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),J=h('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),Q=h('<div class="p-3 text-xs text-secondary">'),A=h('<span class="text-[10px] text-secondary">'),z=h("<span class=file-list-item-additions>+"),O=h("<span class=file-list-item-deletions>-"),T=h("<div><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text></span></div><div class=file-list-item-stats>"),U=h("<span class=files-tab-selected-path><span class=file-path-text>"),X=h('<div class=files-tab-stats style="flex:0 0 auto"><span class="files-tab-stat files-tab-stat-additions"><span class=files-tab-stat-value>+</span></span><span class="files-tab-stat files-tab-stat-deletions"><span class=files-tab-stat-value>-'),Y=h("<button type=button class=files-header-icon-button style=margin-left:auto>"),Z=h("<span class=text-error>");const p=N(()=>B(()=>import("./monaco-viewer-DF7Ts1Ni.js").then(e=>e.aa),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoDiffViewer}))),he=e=>{const P=f(()=>e.activeSessionId()),y=f(()=>!!(P()&&P()!=="info")),M=f(()=>y()?e.entries():null),b=f(()=>{const o=M();return Array.isArray(o)?[...o].sort((s,g)=>String(s.path||"").localeCompare(String(g.path||""))):[]}),F=f(()=>b().reduce((o,s)=>(o.additions+=typeof s.added=="number"?s.added:0,o.deletions+=typeof s.removed=="number"?s.removed:0,o),{additions:0,deletions:0})),L=f(()=>b().filter(o=>o&&o.status!=="deleted")),I=f(()=>{const o=b(),s=e.selectedPath(),g=e.mostChangedPath();return(o.find(_=>_.path===s)||(g?o.find(_=>_.path===g):void 0))??null}),W=f(()=>y()?M()===null?e.t("instanceShell.gitChanges.loading"):L().length===0?e.t("instanceShell.gitChanges.empty"):e.t("instanceShell.filesShell.viewerEmpty"):e.t("instanceShell.gitChanges.noSessionSelected"));return V(()=>{const o=F(),s=I(),g=b(),x=L(),_=()=>(()=>{var t=J(),l=t.firstChild;return r(l,d(c,{get when(){return e.selectedLoading()},get fallback(){return d(c,{get when(){return e.selectedError()},get fallback(){return d(c,{get when(){return V(()=>!!(s&&e.selectedBefore()!==null&&e.selectedAfter()!==null&&s.status!=="deleted"))()?{path:s.path,before:e.selectedBefore(),after:e.selectedAfter()}:null},get fallback(){return(()=>{var i=S(),a=i.firstChild;return r(a,W),i})()},children:i=>d(G,{get fallback(){return(()=>{var a=S(),u=a.firstChild;return r(u,()=>e.t("instanceInfo.loading")),a})()},get children(){return d(p,{get scopeKey(){return e.scopeKey()},get path(){return String(i().path||"")},get before(){return String(i().before||"")},get after(){return String(i().after||"")},get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrap(){return e.diffWordWrapMode()}})}})})},children:i=>(()=>{var a=S(),u=a.firstChild;return r(u,i),a})()})},get children(){var i=S(),a=i.firstChild;return r(a,()=>e.t("instanceInfo.loading")),i}})),t})(),k=()=>(()=>{var t=Q();return r(t,W),t})();return d(q,{get header(){return[(()=>{var t=U(),l=t.firstChild;return r(l,()=>(s==null?void 0:s.path)||e.t("instanceShell.rightPanel.tabs.gitChanges")),w(()=>$(t,"title",(s==null?void 0:s.path)||e.t("instanceShell.rightPanel.tabs.gitChanges"))),t})(),(()=>{var t=X(),l=t.firstChild,i=l.firstChild;i.firstChild;var a=l.nextSibling,u=a.firstChild;return u.firstChild,r(i,()=>o.additions,null),r(u,()=>o.deletions,null),r(t,d(c,{get when(){return e.statusError()},children:v=>(()=>{var n=Z();return r(n,v),n})()}),null),t})(),(()=>{var t=Y();return t.$$click=()=>e.onRefresh(),r(t,d(H,{get class(){return`h-4 w-4${e.statusLoading()?" animate-spin":""}`}})),w(l=>{var i=e.t("instanceShell.rightPanel.actions.refresh"),a=e.t("instanceShell.rightPanel.actions.refresh"),u=!y()||e.statusLoading()||M()===null;return i!==l.e&&$(t,"title",l.e=i),a!==l.t&&$(t,"aria-label",l.t=a),u!==l.a&&(t.disabled=l.a=u),l},{e:void 0,t:void 0,a:void 0}),t})(),d(j,{get viewMode(){return e.diffViewMode()},get contextMode(){return e.diffContextMode()},get wordWrapMode(){return e.diffWordWrapMode()},get onViewModeChange(){return e.onViewModeChange},get onContextModeChange(){return e.onContextModeChange},get onWordWrapModeChange(){return e.onWordWrapModeChange}})]},list:{panel:()=>d(c,{get when(){return x.length>0},get fallback(){return k()},get children(){return d(R,{each:g,children:t=>(()=>{var l=T(),i=l.firstChild,a=i.firstChild,u=a.firstChild,v=a.nextSibling;return l.$$click=()=>{e.onOpenFile(t.path)},r(u,()=>t.path),r(v,d(c,{get when(){return t.status==="deleted"},get children(){var n=A();return r(n,()=>e.t("instanceShell.gitChanges.deleted")),n}}),null),r(v,d(c,{get when(){return t.status!=="deleted"},get children(){return[(()=>{var n=z();return n.firstChild,r(n,()=>t.added,null),n})(),(()=>{var n=O();return n.firstChild,r(n,()=>t.removed,null),n})()]}}),null),w(n=>{var C=`file-list-item ${e.selectedPath()===t.path?"file-list-item-active":""}`,m=t.path;return C!==n.e&&D(l,n.e=C),m!==n.t&&$(a,"title",n.t=m),n},{e:void 0,t:void 0}),l})()})}}),overlay:()=>d(c,{get when(){return x.length>0},get fallback(){return k()},get children(){return d(R,{each:g,children:t=>(()=>{var l=T(),i=l.firstChild,a=i.firstChild,u=a.firstChild,v=a.nextSibling;return l.$$click=()=>e.onOpenFile(t.path),r(u,()=>t.path),r(v,d(c,{get when(){return t.status==="deleted"},get children(){var n=A();return r(n,()=>e.t("instanceShell.gitChanges.deleted")),n}}),null),r(v,d(c,{get when(){return t.status!=="deleted"},get children(){return[(()=>{var n=z();return n.firstChild,r(n,()=>t.added,null),n})(),(()=>{var n=O();return n.firstChild,r(n,()=>t.removed,null),n})()]}}),null),w(n=>{var C=`file-list-item ${e.selectedPath()===t.path?"file-list-item-active":""}`,m=t.path,E=t.path;return C!==n.e&&D(l,n.e=C),m!==n.t&&$(l,"title",n.t=m),E!==n.a&&$(a,"title",n.a=E),n},{e:void 0,t:void 0,a:void 0}),l})()})}})},get viewer(){return _()},get listOpen(){return e.listOpen()},get onToggleList(){return e.onToggleList},get splitWidth(){return e.splitWidth()},get onResizeMouseDown(){return e.onResizeMouseDown},get onResizeTouchStart(){return e.onResizeTouchStart},get isPhoneLayout(){return e.isPhoneLayout()},get overlayAriaLabel(){return e.t("instanceShell.rightPanel.tabs.gitChanges")}})})};K(["click"]);export{he as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as d,i as l,d as m,j as s,m as b,g as _,f as w}from"./monaco-viewer-
|
|
1
|
+
import{t as d,i as l,d as m,j as s,m as b,g as _,f as w}from"./monaco-viewer-DF7Ts1Ni.js";import{a as g,n as r,S as n}from"./git-diff-vendor-CAv-4upN.js";import{u as S}from"./index-DwZDftuW.js";var y=d("<div class=file-list-overlay role=dialog><div class=file-list-scroll>");const L=e=>(()=>{var t=y(),a=t.firstChild;return l(a,()=>e.children),g(()=>m(t,"aria-label",e.ariaLabel)),t})();var C=d('<div class=files-split><div class=file-list-panel><div class=file-list-scroll></div></div><div class=file-split-handle role=separator aria-orientation=vertical aria-label="Resize file list">'),x=d("<div class=files-tab-container><div class=files-tab-header><div class=files-tab-header-row><button type=button class=files-toggle-button></button></div></div><div class=files-tab-body>");const z=e=>{const{t}=S();return(()=>{var a=x(),c=a.firstChild,o=c.firstChild,u=o.firstChild,h=c.nextSibling;return s(u,"click",e.onToggleList,!0),l(u,(()=>{var i=b(()=>!!e.listOpen);return()=>i()?t("instanceShell.filesShell.hideFiles"):t("instanceShell.filesShell.showFiles")})()),l(o,()=>e.header,null),l(h,r(n,{get when(){return b(()=>!e.isPhoneLayout)()&&e.listOpen},get fallback(){return e.viewer},get children(){var i=C(),v=i.firstChild,$=v.firstChild,f=v.nextSibling;return l($,()=>e.list.panel()),s(f,"touchstart",e.onResizeTouchStart,!0),s(f,"mousedown",e.onResizeMouseDown,!0),l(i,()=>e.viewer,null),g(O=>_(i,"--files-pane-width",`${e.splitWidth}px`)),i}}),null),l(h,r(n,{get when(){return e.isPhoneLayout},get children(){return r(n,{get when(){return e.listOpen},get children(){return r(L,{get ariaLabel(){return e.overlayAriaLabel},get children(){return e.list.overlay()}})}})}}),null),a})()};w(["click","mousedown","touchstart"]);export{z as S};
|