@neuralnomads/codenomad-dev 0.13.1-dev-20260330-37b3f85e → 0.13.1-dev-20260331-64ac8851
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/clients/connection-manager.js +93 -0
- package/dist/opencode-config/plugin/codenomad.ts +30 -0
- package/dist/plugins/voice-mode.js +77 -0
- package/dist/server/http-server.js +24 -2
- package/dist/server/routes/events.js +24 -1
- package/dist/server/routes/plugin.js +18 -4
- package/dist/ui/__tests__/remote-ui.test.js +21 -0
- package/dist/ui/remote-ui.js +2 -2
- package/package.json +1 -1
- package/public/assets/{ChangesTab-DReBtiCD.js → ChangesTab-RTdJ_Y1y.js} +2 -2
- package/public/assets/{DiffToolbar-zFp8QctV.js → DiffToolbar-C1xO2z35.js} +1 -1
- package/public/assets/{FilesTab-ondRgka_.js → FilesTab-07IkVogN.js} +2 -2
- package/public/assets/{GitChangesTab-BOcSmEC0.js → GitChangesTab-fjdsfZUU.js} +2 -2
- package/public/assets/{SplitFilePanel-CclMrjYs.js → SplitFilePanel-D0HTUMZ8.js} +1 -1
- package/public/assets/StatusTab-CcKxUIUL.js +1 -0
- package/public/assets/{bundle-full-DaR4-84s.js → bundle-full-BOM3Ly92.js} +1 -1
- package/public/assets/{diff-viewer-NJrs1tpM.js → diff-viewer-DOx_14Jw.js} +1 -1
- package/public/assets/index--5k23mCQ.js +1 -0
- package/public/assets/index-9PXn07aX.js +2 -0
- package/public/assets/index-B7X7f2WF.js +1 -0
- package/public/assets/index-BNyw4BqI.js +1 -0
- package/public/assets/{index-C2RrcFJ5.css → index-CDoHZhl9.css} +1 -1
- package/public/assets/{index-9dJbqHxs.js → index-CssW65fw.js} +1 -1
- package/public/assets/index-DtbKZTUc.js +1 -0
- package/public/assets/index-RGo94eU_.js +1 -0
- package/public/assets/index-Z9-T3Z05.js +1 -0
- package/public/assets/{index-C96iOm92.js → index-mkwJJU52.js} +1 -1
- package/public/assets/{loading-DDlbjmrg.js → loading-B_dejC1m.js} +1 -1
- package/public/assets/main-CJ6AzDA8.js +56 -0
- package/public/assets/{markdown-tZ1CDnLU.js → markdown-BtFDy3nR.js} +18 -18
- package/public/assets/monaco-viewer-UU9TfOpS.js +15 -0
- package/public/assets/{todo-CW64L-p2.js → todo-DRKp_1_C.js} +1 -1
- package/public/assets/{tool-call-l0vsLPTC.js → tool-call-B4P-PiNS.js} +3 -3
- package/public/assets/{unified-picker-Dw7fMG5X.js → unified-picker-DEBwixc1.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-BVcDbQI8.js +0 -1
- package/public/assets/index-B5yK9f1K.js +0 -1
- package/public/assets/index-BGfH2XEf.js +0 -1
- package/public/assets/index-Bc4VzU8i.js +0 -1
- package/public/assets/index-Bjox8T8a.js +0 -2
- package/public/assets/index-DWVFDb6o.js +0 -1
- package/public/assets/index-DahNWccx.js +0 -1
- package/public/assets/index-Dcri1TSs.js +0 -1
- package/public/assets/main-By_B3-BG.js +0 -56
- package/public/assets/monaco-viewer-DTwkOabu.js +0 -15
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const STALE_CONNECTION_TIMEOUT_MS = 45000;
|
|
2
|
+
const STALE_SWEEP_INTERVAL_MS = 5000;
|
|
3
|
+
export class ClientConnectionManager {
|
|
4
|
+
constructor(logger) {
|
|
5
|
+
this.logger = logger;
|
|
6
|
+
this.connections = new Map();
|
|
7
|
+
this.subscribers = new Set();
|
|
8
|
+
this.sweepTimer = setInterval(() => this.sweepStaleConnections(), STALE_SWEEP_INTERVAL_MS);
|
|
9
|
+
this.sweepTimer.unref?.();
|
|
10
|
+
}
|
|
11
|
+
shutdown() {
|
|
12
|
+
clearInterval(this.sweepTimer);
|
|
13
|
+
for (const connection of Array.from(this.connections.values())) {
|
|
14
|
+
this.disconnect(connection.key, "shutdown", false);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
subscribe(listener) {
|
|
18
|
+
this.subscribers.add(listener);
|
|
19
|
+
return () => this.subscribers.delete(listener);
|
|
20
|
+
}
|
|
21
|
+
register(input) {
|
|
22
|
+
const key = getConnectionKey(input);
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const existing = this.connections.get(key);
|
|
25
|
+
if (existing) {
|
|
26
|
+
this.logger.debug({ clientId: input.clientId, connectionId: input.connectionId }, "Replacing existing client connection");
|
|
27
|
+
this.disconnect(key, "replaced");
|
|
28
|
+
}
|
|
29
|
+
const connection = {
|
|
30
|
+
key,
|
|
31
|
+
clientId: input.clientId,
|
|
32
|
+
connectionId: input.connectionId,
|
|
33
|
+
connectedAt: now,
|
|
34
|
+
lastSeenAt: now,
|
|
35
|
+
close: input.close,
|
|
36
|
+
};
|
|
37
|
+
this.connections.set(key, connection);
|
|
38
|
+
this.logger.debug({ clientId: input.clientId, connectionId: input.connectionId }, "Client connected");
|
|
39
|
+
this.notify({ type: "connected", connection });
|
|
40
|
+
return () => this.disconnect(key, "closed");
|
|
41
|
+
}
|
|
42
|
+
pong(input) {
|
|
43
|
+
const key = getConnectionKey(input);
|
|
44
|
+
const connection = this.connections.get(key);
|
|
45
|
+
if (!connection) {
|
|
46
|
+
this.logger.debug({ clientId: input.clientId, connectionId: input.connectionId }, "Ignoring pong for unknown client connection");
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
connection.lastSeenAt = Date.now();
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
isConnected(input) {
|
|
53
|
+
return this.connections.has(getConnectionKey(input));
|
|
54
|
+
}
|
|
55
|
+
sweepStaleConnections() {
|
|
56
|
+
const cutoff = Date.now() - STALE_CONNECTION_TIMEOUT_MS;
|
|
57
|
+
for (const connection of Array.from(this.connections.values())) {
|
|
58
|
+
if (connection.lastSeenAt > cutoff)
|
|
59
|
+
continue;
|
|
60
|
+
this.logger.debug({ clientId: connection.clientId, connectionId: connection.connectionId }, "Client connection timed out");
|
|
61
|
+
this.disconnect(connection.key, "timeout");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
disconnect(key, reason, invokeClose = true) {
|
|
65
|
+
const connection = this.connections.get(key);
|
|
66
|
+
if (!connection)
|
|
67
|
+
return;
|
|
68
|
+
this.connections.delete(key);
|
|
69
|
+
this.logger.debug({ clientId: connection.clientId, connectionId: connection.connectionId, reason }, "Client disconnected");
|
|
70
|
+
if (invokeClose) {
|
|
71
|
+
try {
|
|
72
|
+
connection.close();
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
this.logger.warn({ err: error, clientId: connection.clientId, connectionId: connection.connectionId }, "Failed to close stale client connection");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.notify({ type: "disconnected", connection, reason });
|
|
79
|
+
}
|
|
80
|
+
notify(event) {
|
|
81
|
+
for (const subscriber of this.subscribers) {
|
|
82
|
+
try {
|
|
83
|
+
subscriber(event);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.logger.warn({ err: error, eventType: event.type }, "Client connection subscriber failed");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function getConnectionKey(input) {
|
|
92
|
+
return `${input.clientId}:${input.connectionId}`;
|
|
93
|
+
}
|
|
@@ -2,6 +2,8 @@ import type { PluginInput } from "@opencode-ai/plugin"
|
|
|
2
2
|
import { createCodeNomadClient, getCodeNomadConfig } from "./lib/client"
|
|
3
3
|
import { createBackgroundProcessTools } from "./lib/background-process"
|
|
4
4
|
|
|
5
|
+
let voiceModeEnabled = false
|
|
6
|
+
|
|
5
7
|
export async function CodeNomadPlugin(input: PluginInput) {
|
|
6
8
|
const config = getCodeNomadConfig()
|
|
7
9
|
const client = createCodeNomadClient(config)
|
|
@@ -16,6 +18,11 @@ export async function CodeNomadPlugin(input: PluginInput) {
|
|
|
16
18
|
pingTs: (event.properties as any)?.ts,
|
|
17
19
|
},
|
|
18
20
|
}).catch(() => {})
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (event.type === "codenomad.voiceMode") {
|
|
25
|
+
voiceModeEnabled = Boolean((event.properties as { enabled?: unknown } | undefined)?.enabled)
|
|
19
26
|
}
|
|
20
27
|
})
|
|
21
28
|
|
|
@@ -23,6 +30,13 @@ export async function CodeNomadPlugin(input: PluginInput) {
|
|
|
23
30
|
tool: {
|
|
24
31
|
...backgroundProcessTools,
|
|
25
32
|
},
|
|
33
|
+
async "chat.message"(_input: { sessionID: string }, output: { message: { system?: string } }) {
|
|
34
|
+
if (!voiceModeEnabled) {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
output.message.system = [output.message.system, buildVoiceModePrompt()].filter(Boolean).join("\n\n")
|
|
39
|
+
},
|
|
26
40
|
async event(input: { event: any }) {
|
|
27
41
|
const opencodeEvent = input?.event
|
|
28
42
|
if (!opencodeEvent || typeof opencodeEvent !== "object") return
|
|
@@ -30,3 +44,19 @@ export async function CodeNomadPlugin(input: PluginInput) {
|
|
|
30
44
|
},
|
|
31
45
|
}
|
|
32
46
|
}
|
|
47
|
+
|
|
48
|
+
function buildVoiceModePrompt(): string {
|
|
49
|
+
return [
|
|
50
|
+
"Voice conversation mode is enabled.",
|
|
51
|
+
"Prepend your reply with a fenced code block using language `spoken`.",
|
|
52
|
+
"The `spoken` block should be the natural conversational reply you would say out loud to the user. It should be a concise spoken gist of the full response in 2 to 4 natural sentences.",
|
|
53
|
+
"In the spoken block, summarize the main outcome, recommendation, or next step. Sound conversational and natural, not like a document summary.",
|
|
54
|
+
"Do not include code, bullet lists, markdown formatting, or long technical detail in the spoken block.",
|
|
55
|
+
"Do not add generic phrases about whether the user should read more.",
|
|
56
|
+
"Only mention additional written detail when there is something specific that may matter for the user's next response, such as a tradeoff, caveat, risk, open question, exact diff, or test result.",
|
|
57
|
+
"When referring to that written detail, say `below` or `in the message` rather than `detailed section`.",
|
|
58
|
+
"After the `spoken` block, continue with your normal detailed response.",
|
|
59
|
+
"Example:",
|
|
60
|
+
"```spoken\nI implemented the relay-based voice-mode flow and it works with the current plugin bridge. The reconnect caveat is explained below.\n```",
|
|
61
|
+
].join("\n\n")
|
|
62
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export class VoiceModeManager {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.options = options;
|
|
4
|
+
this.enabledConnectionsByInstance = new Map();
|
|
5
|
+
this.aggregateByInstance = new Map();
|
|
6
|
+
this.options.connections.subscribe((event) => {
|
|
7
|
+
if (event.type !== "disconnected")
|
|
8
|
+
return;
|
|
9
|
+
this.clearConnection(event.connection);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
setEnabled(instanceId, connection, enabled) {
|
|
13
|
+
if (enabled && !this.options.connections.isConnected(connection)) {
|
|
14
|
+
this.options.logger.debug({ instanceId, clientId: connection.clientId, connectionId: connection.connectionId }, "Ignoring voice mode enable for disconnected client connection");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const key = getConnectionKey(connection);
|
|
18
|
+
const current = this.enabledConnectionsByInstance.get(instanceId) ?? new Set();
|
|
19
|
+
if (enabled) {
|
|
20
|
+
current.add(key);
|
|
21
|
+
this.enabledConnectionsByInstance.set(instanceId, current);
|
|
22
|
+
}
|
|
23
|
+
else if (current.delete(key)) {
|
|
24
|
+
if (current.size === 0) {
|
|
25
|
+
this.enabledConnectionsByInstance.delete(instanceId);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.enabledConnectionsByInstance.set(instanceId, current);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
this.options.logger.debug({ instanceId, clientId: connection.clientId, connectionId: connection.connectionId, enabled }, "Voice mode updated for client connection");
|
|
32
|
+
this.publishIfChanged(instanceId);
|
|
33
|
+
}
|
|
34
|
+
syncInstance(instanceId) {
|
|
35
|
+
this.options.channel.send(instanceId, buildVoiceModeEvent(this.isEnabled(instanceId)));
|
|
36
|
+
}
|
|
37
|
+
isEnabled(instanceId) {
|
|
38
|
+
return this.aggregateByInstance.get(instanceId) === true;
|
|
39
|
+
}
|
|
40
|
+
clearConnection(connection) {
|
|
41
|
+
const key = getConnectionKey(connection);
|
|
42
|
+
for (const [instanceId, enabledConnections] of Array.from(this.enabledConnectionsByInstance.entries())) {
|
|
43
|
+
if (!enabledConnections.delete(key))
|
|
44
|
+
continue;
|
|
45
|
+
if (enabledConnections.size === 0) {
|
|
46
|
+
this.enabledConnectionsByInstance.delete(instanceId);
|
|
47
|
+
}
|
|
48
|
+
this.publishIfChanged(instanceId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
publishIfChanged(instanceId) {
|
|
52
|
+
const enabled = (this.enabledConnectionsByInstance.get(instanceId)?.size ?? 0) > 0;
|
|
53
|
+
const previous = this.aggregateByInstance.get(instanceId) === true;
|
|
54
|
+
if (enabled === previous)
|
|
55
|
+
return;
|
|
56
|
+
if (enabled) {
|
|
57
|
+
this.aggregateByInstance.set(instanceId, true);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.aggregateByInstance.delete(instanceId);
|
|
61
|
+
}
|
|
62
|
+
this.options.logger.debug({ instanceId, enabled }, "Broadcasting aggregate voice mode");
|
|
63
|
+
this.options.channel.send(instanceId, buildVoiceModeEvent(enabled));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function buildVoiceModeEvent(enabled) {
|
|
67
|
+
return {
|
|
68
|
+
type: "codenomad.voiceMode",
|
|
69
|
+
properties: {
|
|
70
|
+
enabled,
|
|
71
|
+
formatVersion: "v1",
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getConnectionKey(connection) {
|
|
76
|
+
return `${connection.clientId}:${connection.connectionId}`;
|
|
77
|
+
}
|
|
@@ -19,6 +19,9 @@ import { registerSpeechRoutes } from "./routes/speech";
|
|
|
19
19
|
import { BackgroundProcessManager } from "../background-processes/manager";
|
|
20
20
|
import { registerAuthRoutes } from "./routes/auth";
|
|
21
21
|
import { sendUnauthorized, wantsHtml } from "../auth/http-auth";
|
|
22
|
+
import { ClientConnectionManager } from "../clients/connection-manager";
|
|
23
|
+
import { PluginChannelManager } from "../plugins/channel";
|
|
24
|
+
import { VoiceModeManager } from "../plugins/voice-mode";
|
|
22
25
|
export function createHttpServer(deps) {
|
|
23
26
|
// Fastify's type-level RawServer inference gets noisy when toggling HTTP vs HTTPS.
|
|
24
27
|
// We keep the runtime behavior correct and cast the instance to a generic FastifyInstance.
|
|
@@ -125,6 +128,13 @@ export function createHttpServer(deps) {
|
|
|
125
128
|
eventBus: deps.eventBus,
|
|
126
129
|
logger: deps.logger.child({ component: "background-processes" }),
|
|
127
130
|
});
|
|
131
|
+
const clientConnectionManager = new ClientConnectionManager(deps.logger.child({ component: "client-connections" }));
|
|
132
|
+
const pluginChannel = new PluginChannelManager(deps.logger.child({ component: "plugin-channel" }));
|
|
133
|
+
const voiceModeManager = new VoiceModeManager({
|
|
134
|
+
connections: clientConnectionManager,
|
|
135
|
+
channel: pluginChannel,
|
|
136
|
+
logger: deps.logger.child({ component: "voice-mode" }),
|
|
137
|
+
});
|
|
128
138
|
registerAuthRoutes(app, { authManager: deps.authManager });
|
|
129
139
|
app.addHook("preHandler", (request, reply, done) => {
|
|
130
140
|
const rawUrl = request.raw.url ?? request.url;
|
|
@@ -185,7 +195,12 @@ export function createHttpServer(deps) {
|
|
|
185
195
|
registerSettingsRoutes(app, { settings: deps.settings, logger: apiLogger });
|
|
186
196
|
registerFilesystemRoutes(app, { fileSystemBrowser: deps.fileSystemBrowser });
|
|
187
197
|
registerMetaRoutes(app, { serverMeta: deps.serverMeta });
|
|
188
|
-
registerEventRoutes(app, {
|
|
198
|
+
registerEventRoutes(app, {
|
|
199
|
+
eventBus: deps.eventBus,
|
|
200
|
+
registerClient: registerSseClient,
|
|
201
|
+
logger: sseLogger,
|
|
202
|
+
connectionManager: clientConnectionManager,
|
|
203
|
+
});
|
|
189
204
|
registerWorktreeRoutes(app, { workspaceManager: deps.workspaceManager });
|
|
190
205
|
registerStorageRoutes(app, {
|
|
191
206
|
instanceStore: deps.instanceStore,
|
|
@@ -193,7 +208,13 @@ export function createHttpServer(deps) {
|
|
|
193
208
|
workspaceManager: deps.workspaceManager,
|
|
194
209
|
});
|
|
195
210
|
registerSpeechRoutes(app, { speechService: deps.speechService });
|
|
196
|
-
registerPluginRoutes(app, {
|
|
211
|
+
registerPluginRoutes(app, {
|
|
212
|
+
workspaceManager: deps.workspaceManager,
|
|
213
|
+
eventBus: deps.eventBus,
|
|
214
|
+
logger: proxyLogger,
|
|
215
|
+
channel: pluginChannel,
|
|
216
|
+
voiceModeManager,
|
|
217
|
+
});
|
|
197
218
|
registerBackgroundProcessRoutes(app, { backgroundProcessManager });
|
|
198
219
|
registerInstanceProxyRoutes(app, { workspaceManager: deps.workspaceManager, logger: proxyLogger });
|
|
199
220
|
if (deps.uiDevServerUrl) {
|
|
@@ -251,6 +272,7 @@ export function createHttpServer(deps) {
|
|
|
251
272
|
},
|
|
252
273
|
stop: () => {
|
|
253
274
|
closeSseClients();
|
|
275
|
+
clientConnectionManager.shutdown();
|
|
254
276
|
return app.close();
|
|
255
277
|
},
|
|
256
278
|
};
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
let nextClientId = 0;
|
|
3
|
+
const ConnectionQuerySchema = z.object({
|
|
4
|
+
clientId: z.string().trim().min(1),
|
|
5
|
+
connectionId: z.string().trim().min(1),
|
|
6
|
+
});
|
|
7
|
+
const PongBodySchema = ConnectionQuerySchema.extend({
|
|
8
|
+
pingTs: z.number().optional(),
|
|
9
|
+
});
|
|
2
10
|
export function registerEventRoutes(app, deps) {
|
|
3
11
|
app.get("/api/events", (request, reply) => {
|
|
4
12
|
const clientId = ++nextClientId;
|
|
13
|
+
const connection = ConnectionQuerySchema.parse(request.query ?? {});
|
|
5
14
|
deps.logger.debug({ clientId }, "SSE client connected");
|
|
6
15
|
const origin = request.headers.origin ?? "*";
|
|
7
16
|
reply.raw.setHeader("Access-Control-Allow-Origin", origin);
|
|
@@ -20,7 +29,8 @@ export function registerEventRoutes(app, deps) {
|
|
|
20
29
|
};
|
|
21
30
|
const unsubscribe = deps.eventBus.onEvent(send);
|
|
22
31
|
const heartbeat = setInterval(() => {
|
|
23
|
-
|
|
32
|
+
const ping = { ts: Date.now() };
|
|
33
|
+
reply.raw.write(`event: codenomad.client.ping\ndata: ${JSON.stringify(ping)}\n\n`);
|
|
24
34
|
}, 15000);
|
|
25
35
|
let closed = false;
|
|
26
36
|
const close = () => {
|
|
@@ -33,11 +43,24 @@ export function registerEventRoutes(app, deps) {
|
|
|
33
43
|
deps.logger.debug({ clientId }, "SSE client disconnected");
|
|
34
44
|
};
|
|
35
45
|
const unregister = deps.registerClient(close);
|
|
46
|
+
const unregisterConnection = deps.connectionManager.register({
|
|
47
|
+
...connection,
|
|
48
|
+
close,
|
|
49
|
+
});
|
|
36
50
|
const handleClose = () => {
|
|
37
51
|
close();
|
|
38
52
|
unregister();
|
|
53
|
+
unregisterConnection();
|
|
39
54
|
};
|
|
40
55
|
request.raw.on("close", handleClose);
|
|
41
56
|
request.raw.on("error", handleClose);
|
|
42
57
|
});
|
|
58
|
+
app.post("/api/client-connections/pong", (request, reply) => {
|
|
59
|
+
const body = PongBodySchema.parse(request.body ?? {});
|
|
60
|
+
if (!deps.connectionManager.pong(body)) {
|
|
61
|
+
reply.code(404).send({ error: "Client connection not found" });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
reply.code(204).send();
|
|
65
|
+
});
|
|
43
66
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { PluginChannelManager } from "../../plugins/channel";
|
|
3
2
|
import { buildPingEvent, handlePluginEvent } from "../../plugins/handlers";
|
|
4
3
|
const PluginEventSchema = z.object({
|
|
5
4
|
type: z.string().min(1),
|
|
6
5
|
properties: z.record(z.unknown()).optional(),
|
|
7
6
|
});
|
|
7
|
+
const VoiceModeStateSchema = z.object({
|
|
8
|
+
enabled: z.boolean(),
|
|
9
|
+
clientId: z.string().trim().min(1),
|
|
10
|
+
connectionId: z.string().trim().min(1),
|
|
11
|
+
});
|
|
8
12
|
export function registerPluginRoutes(app, deps) {
|
|
9
|
-
const channel = new PluginChannelManager(deps.logger.child({ component: "plugin-channel" }));
|
|
10
13
|
app.get("/workspaces/:id/plugin/events", (request, reply) => {
|
|
11
14
|
const workspace = deps.workspaceManager.get(request.params.id);
|
|
12
15
|
if (!workspace) {
|
|
@@ -18,9 +21,10 @@ export function registerPluginRoutes(app, deps) {
|
|
|
18
21
|
reply.raw.setHeader("Connection", "keep-alive");
|
|
19
22
|
reply.raw.flushHeaders?.();
|
|
20
23
|
reply.hijack();
|
|
21
|
-
const registration = channel.register(request.params.id, reply);
|
|
24
|
+
const registration = deps.channel.register(request.params.id, reply);
|
|
25
|
+
deps.voiceModeManager.syncInstance(request.params.id);
|
|
22
26
|
const heartbeat = setInterval(() => {
|
|
23
|
-
channel.send(request.params.id, buildPingEvent());
|
|
27
|
+
deps.channel.send(request.params.id, buildPingEvent());
|
|
24
28
|
}, 15000);
|
|
25
29
|
const close = () => {
|
|
26
30
|
clearInterval(heartbeat);
|
|
@@ -30,6 +34,16 @@ export function registerPluginRoutes(app, deps) {
|
|
|
30
34
|
request.raw.on("close", close);
|
|
31
35
|
request.raw.on("error", close);
|
|
32
36
|
});
|
|
37
|
+
app.post("/workspaces/:id/plugin/voice-mode", (request, reply) => {
|
|
38
|
+
const workspace = deps.workspaceManager.get(request.params.id);
|
|
39
|
+
if (!workspace) {
|
|
40
|
+
reply.code(404).send({ error: "Workspace not found" });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const payload = VoiceModeStateSchema.parse(request.body ?? {});
|
|
44
|
+
deps.voiceModeManager.setEnabled(request.params.id, { clientId: payload.clientId, connectionId: payload.connectionId }, payload.enabled);
|
|
45
|
+
return { enabled: payload.enabled };
|
|
46
|
+
});
|
|
33
47
|
const handleWildcard = async (request, reply) => {
|
|
34
48
|
const workspaceId = request.params.id;
|
|
35
49
|
const workspace = deps.workspaceManager.get(workspaceId);
|
|
@@ -43,4 +43,25 @@ describe("resolveUi local version preference", () => {
|
|
|
43
43
|
assert.equal(result.uiStaticDir, bundledDir);
|
|
44
44
|
assert.equal(result.uiVersion, "0.8.1");
|
|
45
45
|
});
|
|
46
|
+
it("prefers bundled when bundled and downloaded versions are equal", async () => {
|
|
47
|
+
const bundledDir = path.join(tempRoot, "bundled");
|
|
48
|
+
const configDir = path.join(tempRoot, "config");
|
|
49
|
+
const currentDir = path.join(configDir, "ui", "current");
|
|
50
|
+
await mkdir(bundledDir, { recursive: true });
|
|
51
|
+
await mkdir(currentDir, { recursive: true });
|
|
52
|
+
writeFileSync(path.join(bundledDir, "index.html"), "<html>bundled</html>");
|
|
53
|
+
writeFileSync(path.join(bundledDir, "ui-version.json"), JSON.stringify({ uiVersion: "0.8.1" }));
|
|
54
|
+
writeFileSync(path.join(currentDir, "index.html"), "<html>current</html>");
|
|
55
|
+
writeFileSync(path.join(currentDir, "ui-version.json"), JSON.stringify({ uiVersion: "0.8.1" }));
|
|
56
|
+
const result = await resolveUi({
|
|
57
|
+
serverVersion: "0.8.1",
|
|
58
|
+
bundledUiDir: bundledDir,
|
|
59
|
+
autoUpdate: false,
|
|
60
|
+
configDir,
|
|
61
|
+
logger: noopLogger,
|
|
62
|
+
});
|
|
63
|
+
assert.equal(result.source, "bundled");
|
|
64
|
+
assert.equal(result.uiStaticDir, bundledDir);
|
|
65
|
+
assert.equal(result.uiVersion, "0.8.1");
|
|
66
|
+
});
|
|
46
67
|
});
|
package/dist/ui/remote-ui.js
CHANGED
|
@@ -179,7 +179,7 @@ async function pickBestLocalUi(args) {
|
|
|
179
179
|
uiStaticDir: currentResolved,
|
|
180
180
|
source: "downloaded",
|
|
181
181
|
uiVersion: await readUiVersion(currentResolved),
|
|
182
|
-
priority:
|
|
182
|
+
priority: 1,
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
const bundledResolved = await resolveStaticUiDir(args.bundledUiDir);
|
|
@@ -188,7 +188,7 @@ async function pickBestLocalUi(args) {
|
|
|
188
188
|
uiStaticDir: bundledResolved,
|
|
189
189
|
source: "bundled",
|
|
190
190
|
uiVersion: await readUiVersion(bundledResolved),
|
|
191
|
-
priority:
|
|
191
|
+
priority: 2,
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
194
|
const previousResolved = await resolveStaticUiDir(args.previousDir);
|
package/package.json
CHANGED
|
@@ -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-UU9TfOpS.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-9PXn07aX.js";import{m as B,t as g,i as a,d as w,a as F,f as N}from"./monaco-viewer-UU9TfOpS.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-C1xO2z35.js";import{S as H}from"./SplitFilePanel-D0HTUMZ8.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";import"./main-CJ6AzDA8.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-UU9TfOpS.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-UU9TfOpS.js";import{u as N}from"./index-9PXn07aX.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-CJ6AzDA8.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 R}from"./index-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/monaco-viewer-UU9TfOpS.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 R}from"./index-9PXn07aX.js";import{m as _,t as o,i as s,d as c,a as z,f as I}from"./monaco-viewer-UU9TfOpS.js";import{n as i,m as D,S as d,a as v,F,z as V,A as M}from"./git-diff-vendor-CAv-4upN.js";import{S as T}from"./SplitFilePanel-D0HTUMZ8.js";import{I as A,R as y}from"./main-CJ6AzDA8.js";import"./fast-diff-vendor-DgdwVvTQ.js";import"./highlight-vendor-8FKMu9os.js";const O=[["path",{d:"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z",key:"1owoqh"}],["polyline",{points:"17 21 17 13 7 13 7 21",key:"1md35c"}],["polyline",{points:"7 3 7 8 15 8",key:"8nz8an"}]],q=e=>i(A,D(e,{name:"Save",iconNode:O}));var g=o("<div class=file-viewer-empty><span class=file-viewer-empty-text>"),K=o('<div class="file-viewer-panel flex-1"><div class="file-viewer-content file-viewer-content--monaco">'),N=o('<div class="p-3 text-xs text-secondary">'),W=o("<div class=file-list-item><div class=file-list-item-content><div class=file-list-item-path><span class=file-path-text>.."),H=o('<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">'),j=o("<span>"),B=o("<div class=files-tab-stats><span class=files-tab-stat><span class=files-tab-selected-path><span class=file-path-text>"),G=o("<button type=button class=files-header-icon-button style=margin-inline-start:auto>"),J=o("<button type=button class=files-header-icon-button>"),Q=o("<span class=text-error>");const U=M(()=>R(()=>import("./monaco-viewer-UU9TfOpS.js").then(e=>e.ab),__vite__mapDeps([0,1,2,3,4])).then(e=>({default:e.MonacoFileViewer}))),ae=e=>{const C=()=>{const h=e.browserSelectedContent();h!=null&&e.onSave(h)};return _(()=>{const h=e.browserEntries(),P=[...h||[]].sort((t,n)=>{const r=t.type==="directory"?0:1,l=n.type==="directory"?0:1;return r!==l?r-l:String(t.name||"").localeCompare(String(n.name||""))}),L=e.parentPath(),w=()=>e.browserSelectedPath()||e.browserPath(),x=()=>e.browserLoading()&&h===null?e.t("instanceInfo.loading"):e.t("instanceShell.filesShell.viewerEmpty"),k=()=>(()=>{var t=K(),n=t.firstChild;return s(n,i(d,{get when(){return e.browserSelectedLoading()},get fallback(){return i(d,{get when(){return e.browserSelectedError()},get fallback(){return i(d,{get when(){return _(()=>!!(e.browserSelectedPath()&&e.browserSelectedContent()!==null))()?{path:e.browserSelectedPath(),content:e.browserSelectedContent()}:null},get fallback(){return(()=>{var r=g(),l=r.firstChild;return s(l,x),r})()},children:r=>i(V,{get fallback(){return(()=>{var l=g(),a=l.firstChild;return s(a,()=>e.t("instanceInfo.loading")),l})()},get children(){return i(U,{get scopeKey(){return e.scopeKey()},get path(){return r().path},get content(){return r().content},get onSave(){return e.onSave},get onContentChange(){return e.onContentChange}})}})})},children:r=>(()=>{var l=g(),a=l.firstChild;return s(a,r),l})()})},get children(){var r=g(),l=r.firstChild;return s(l,()=>e.t("instanceInfo.loading")),r}})),t})(),m=()=>[i(d,{when:L,children:t=>(()=>{var n=W(),r=n.firstChild,l=r.firstChild;return n.$$click=()=>e.onLoadEntries(t()),v(()=>c(l,"title",t())),n})()}),i(d,{get when(){return e.browserLoading()&&h===null},get children(){var t=N();return s(t,()=>e.t("instanceInfo.loading")),t}}),i(F,{each:P,children:t=>(()=>{var n=H(),r=n.firstChild,l=r.firstChild,a=l.firstChild,f=l.nextSibling,E=f.firstChild;return n.$$click=()=>{if(t.type==="directory"){e.onLoadEntries(t.path);return}e.onRequestOpenFile(t.path)},s(a,()=>t.name),s(E,()=>t.type),v(u=>{var b=`file-list-item ${e.browserSelectedPath()===t.path?"file-list-item-active":""}`,S=t.path,$=t.path;return b!==u.e&&z(n,u.e=b),S!==u.t&&c(n,"title",u.t=S),$!==u.a&&c(l,"title",u.a=$),u},{e:void 0,t:void 0,a:void 0}),n})()})];return i(T,{get header(){return[(()=>{var t=B(),n=t.firstChild,r=n.firstChild,l=r.firstChild;return s(l,w),s(t,i(d,{get when(){return e.browserLoading()},get children(){var a=j();return s(a,()=>e.t("instanceInfo.loading")),a}}),null),s(t,i(d,{get when(){return e.browserError()},children:a=>(()=>{var f=Q();return s(f,a),f})()}),null),v(()=>c(r,"title",w())),t})(),(()=>{var t=G();return t.$$click=C,s(t,i(d,{get when(){return e.browserSelectedSaving()},get fallback(){return i(q,{class:"h-4 w-4"})},get children(){return i(y,{class:"h-4 w-4 animate-spin"})}})),v(n=>{var r=e.t("instanceShell.rightPanel.actions.save")||"Save (Ctrl+S)",l=e.t("instanceShell.rightPanel.actions.save")||"Save",a=e.browserSelectedSaving()||!e.browserSelectedDirty();return r!==n.e&&c(t,"title",n.e=r),l!==n.t&&c(t,"aria-label",n.t=l),a!==n.a&&(t.disabled=n.a=a),n},{e:void 0,t:void 0,a:void 0}),t})(),(()=>{var t=J();return t.$$click=()=>e.onRefresh(),s(t,i(y,{get class(){return`h-4 w-4${e.browserLoading()?" animate-spin":""}`}})),v(n=>{var r=e.t("instanceShell.rightPanel.actions.refresh"),l=e.t("instanceShell.rightPanel.actions.refresh"),a=e.browserLoading();return r!==n.e&&c(t,"title",n.e=r),l!==n.t&&c(t,"aria-label",n.t=l),a!==n.a&&(t.disabled=n.a=a),n},{e:void 0,t:void 0,a:void 0}),t})()]},list:{panel:m,overlay:m},get viewer(){return k()},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")}})})};I(["click"]);export{ae 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-UU9TfOpS.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-9PXn07aX.js";import{m as V,t as h,i as r,d as $,a as D,f as K}from"./monaco-viewer-UU9TfOpS.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-C1xO2z35.js";import{S as q}from"./SplitFilePanel-D0HTUMZ8.js";import{R as H}from"./main-CJ6AzDA8.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-UU9TfOpS.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-UU9TfOpS.js";import{a as g,n as r,S as n}from"./git-diff-vendor-CAv-4upN.js";import{u as S}from"./index-9PXn07aX.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};
|