@phenx-inc/ctlsurf 0.5.2 → 0.7.0
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/electron-vite.config.ts +5 -0
- package/out/headless/index.mjs +2 -1
- package/out/headless/index.mjs.map +2 -2
- package/out/main/index.js +3 -0
- package/out/renderer/assets/{cssMode-D9-xaWSI.js → cssMode-eTXVdAkZ.js} +3 -3
- package/out/renderer/assets/{freemarker2-CoRAVxnv.js → freemarker2-B5BKaiK4.js} +1 -1
- package/out/renderer/assets/{handlebars-B0p9Wgkw.js → handlebars-BIdLd2wU.js} +1 -1
- package/out/renderer/assets/{html-D_XFJJtO.js → html-BXL4cnLS.js} +1 -1
- package/out/renderer/assets/{htmlMode-naWw6PWr.js → htmlMode-46N3XG2c.js} +3 -3
- package/out/renderer/assets/{index-ezC-iarf.css → index-Cf-RsxoC.css} +163 -0
- package/out/renderer/assets/{index-DBt_rov1.js → index-dRvutfbl.js} +572 -107
- package/out/renderer/assets/{javascript-DDLsFUr-.js → javascript-n_iZZzDX.js} +2 -2
- package/out/renderer/assets/{jsonMode-Ixhcm5I6.js → jsonMode-DXDczSNu.js} +3 -3
- package/out/renderer/assets/{liquid-BHgSYEHk.js → liquid-B1QweUh7.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-ClbEdD0U.js → lspLanguageFeatures-DqzMqkRk.js} +1 -1
- package/out/renderer/assets/{mdx-DMngMjHR.js → mdx-BCv8lm5e.js} +1 -1
- package/out/renderer/assets/ort-wasm-simd-threaded.asyncify-DMmc6YqF.wasm +0 -0
- package/out/renderer/assets/{python-D_czoeY2.js → python-BLNzYwDv.js} +1 -1
- package/out/renderer/assets/{razor-CLMDGvL7.js → razor-CvAww8bG.js} +1 -1
- package/out/renderer/assets/transformers.web-DtSCnG36.js +33668 -0
- package/out/renderer/assets/{tsMode-EIuSGG42.js → tsMode-C7m6Kr5E.js} +1 -1
- package/out/renderer/assets/{typescript-DQkV4kKA.js → typescript-DhPw4VVg.js} +1 -1
- package/out/renderer/assets/{xml-DJ0OOQTu.js → xml-B0WLFJ2U.js} +1 -1
- package/out/renderer/assets/{yaml-DxX26XLN.js → yaml-BWyn9Wd7.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +2 -1
- package/src/main/index.ts +7 -0
- package/src/renderer/App.tsx +41 -1
- package/src/renderer/components/FloatingMic.tsx +128 -0
- package/src/renderer/components/TerminalPanel.tsx +6 -0
- package/src/renderer/components/VoiceInput.tsx +321 -0
- package/src/renderer/lib/localWhisper.ts +88 -0
- package/src/renderer/styles.css +163 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-eTXVdAkZ.js","./lspLanguageFeatures-DqzMqkRk.js","./htmlMode-46N3XG2c.js","./jsonMode-DXDczSNu.js","./javascript-n_iZZzDX.js","./typescript-DhPw4VVg.js"])))=>i.map(i=>d[i]);
|
|
2
2
|
function getDefaultExportFromCjs(x) {
|
|
3
3
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
4
4
|
}
|
|
@@ -18940,6 +18940,9 @@ function getOrCreateTerminal(tabId, onExit) {
|
|
|
18940
18940
|
_terminals.set(tabId, state);
|
|
18941
18941
|
return { terminal, fitAddon };
|
|
18942
18942
|
}
|
|
18943
|
+
function focusTerminal(tabId) {
|
|
18944
|
+
_terminals.get(tabId)?.terminal.focus();
|
|
18945
|
+
}
|
|
18943
18946
|
function destroyTerminal(tabId) {
|
|
18944
18947
|
const state = _terminals.get(tabId);
|
|
18945
18948
|
if (!state) return;
|
|
@@ -19073,6 +19076,497 @@ function TerminalPanel({ tabId, agent, onSpawn, onExit, isActive }) {
|
|
|
19073
19076
|
toast && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "term-toast", children: toast })
|
|
19074
19077
|
] });
|
|
19075
19078
|
}
|
|
19079
|
+
const scriptRel = /* @__PURE__ */ (function detectScriptRel() {
|
|
19080
|
+
const relList = typeof document !== "undefined" && document.createElement("link").relList;
|
|
19081
|
+
return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
|
|
19082
|
+
})();
|
|
19083
|
+
const assetsURL = function(dep, importerUrl) {
|
|
19084
|
+
return new URL(dep, importerUrl).href;
|
|
19085
|
+
};
|
|
19086
|
+
const seen = {};
|
|
19087
|
+
const __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
19088
|
+
let promise = Promise.resolve();
|
|
19089
|
+
if (deps && deps.length > 0) {
|
|
19090
|
+
let allSettled2 = function(promises) {
|
|
19091
|
+
return Promise.all(
|
|
19092
|
+
promises.map(
|
|
19093
|
+
(p) => Promise.resolve(p).then(
|
|
19094
|
+
(value) => ({ status: "fulfilled", value }),
|
|
19095
|
+
(reason) => ({ status: "rejected", reason })
|
|
19096
|
+
)
|
|
19097
|
+
)
|
|
19098
|
+
);
|
|
19099
|
+
};
|
|
19100
|
+
const links = document.getElementsByTagName("link");
|
|
19101
|
+
const cspNonceMeta = document.querySelector(
|
|
19102
|
+
"meta[property=csp-nonce]"
|
|
19103
|
+
);
|
|
19104
|
+
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
19105
|
+
promise = allSettled2(
|
|
19106
|
+
deps.map((dep) => {
|
|
19107
|
+
dep = assetsURL(dep, importerUrl);
|
|
19108
|
+
if (dep in seen) return;
|
|
19109
|
+
seen[dep] = true;
|
|
19110
|
+
const isCss = dep.endsWith(".css");
|
|
19111
|
+
const cssSelector = isCss ? '[rel="stylesheet"]' : "";
|
|
19112
|
+
const isBaseRelative = !!importerUrl;
|
|
19113
|
+
if (isBaseRelative) {
|
|
19114
|
+
for (let i2 = links.length - 1; i2 >= 0; i2--) {
|
|
19115
|
+
const link22 = links[i2];
|
|
19116
|
+
if (link22.href === dep && (!isCss || link22.rel === "stylesheet")) {
|
|
19117
|
+
return;
|
|
19118
|
+
}
|
|
19119
|
+
}
|
|
19120
|
+
} else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
|
|
19121
|
+
return;
|
|
19122
|
+
}
|
|
19123
|
+
const link2 = document.createElement("link");
|
|
19124
|
+
link2.rel = isCss ? "stylesheet" : scriptRel;
|
|
19125
|
+
if (!isCss) {
|
|
19126
|
+
link2.as = "script";
|
|
19127
|
+
}
|
|
19128
|
+
link2.crossOrigin = "";
|
|
19129
|
+
link2.href = dep;
|
|
19130
|
+
if (cspNonce) {
|
|
19131
|
+
link2.setAttribute("nonce", cspNonce);
|
|
19132
|
+
}
|
|
19133
|
+
document.head.appendChild(link2);
|
|
19134
|
+
if (isCss) {
|
|
19135
|
+
return new Promise((res, rej) => {
|
|
19136
|
+
link2.addEventListener("load", res);
|
|
19137
|
+
link2.addEventListener(
|
|
19138
|
+
"error",
|
|
19139
|
+
() => rej(new Error(`Unable to preload CSS for ${dep}`))
|
|
19140
|
+
);
|
|
19141
|
+
});
|
|
19142
|
+
}
|
|
19143
|
+
})
|
|
19144
|
+
);
|
|
19145
|
+
}
|
|
19146
|
+
function handlePreloadError(err) {
|
|
19147
|
+
const e = new Event("vite:preloadError", {
|
|
19148
|
+
cancelable: true
|
|
19149
|
+
});
|
|
19150
|
+
e.payload = err;
|
|
19151
|
+
window.dispatchEvent(e);
|
|
19152
|
+
if (!e.defaultPrevented) {
|
|
19153
|
+
throw err;
|
|
19154
|
+
}
|
|
19155
|
+
}
|
|
19156
|
+
return promise.then((res) => {
|
|
19157
|
+
for (const item of res || []) {
|
|
19158
|
+
if (item.status !== "rejected") continue;
|
|
19159
|
+
handlePreloadError(item.reason);
|
|
19160
|
+
}
|
|
19161
|
+
return baseModule().catch(handlePreloadError);
|
|
19162
|
+
});
|
|
19163
|
+
};
|
|
19164
|
+
const MODEL = "Xenova/whisper-base";
|
|
19165
|
+
const TARGET_SAMPLE_RATE = 16e3;
|
|
19166
|
+
let transcriberPromise = null;
|
|
19167
|
+
async function loadTranscriber(onProgress) {
|
|
19168
|
+
if (!transcriberPromise) {
|
|
19169
|
+
transcriberPromise = (async () => {
|
|
19170
|
+
const { pipeline, env: env2 } = await __vitePreload(async () => {
|
|
19171
|
+
const { pipeline: pipeline2, env: env3 } = await import("./transformers.web-DtSCnG36.js");
|
|
19172
|
+
return { pipeline: pipeline2, env: env3 };
|
|
19173
|
+
}, true ? [] : void 0, import.meta.url);
|
|
19174
|
+
env2.allowLocalModels = false;
|
|
19175
|
+
const common = { progress_callback: onProgress };
|
|
19176
|
+
const hasWebGpu = typeof navigator !== "undefined" && "gpu" in navigator;
|
|
19177
|
+
if (hasWebGpu) {
|
|
19178
|
+
try {
|
|
19179
|
+
return await pipeline("automatic-speech-recognition", MODEL, { ...common, device: "webgpu" });
|
|
19180
|
+
} catch (err) {
|
|
19181
|
+
console.warn("[voice] WebGPU backend failed, falling back to WASM", err);
|
|
19182
|
+
}
|
|
19183
|
+
}
|
|
19184
|
+
return await pipeline("automatic-speech-recognition", MODEL, common);
|
|
19185
|
+
})();
|
|
19186
|
+
transcriberPromise.catch(() => {
|
|
19187
|
+
transcriberPromise = null;
|
|
19188
|
+
});
|
|
19189
|
+
}
|
|
19190
|
+
return transcriberPromise;
|
|
19191
|
+
}
|
|
19192
|
+
async function blobToPcm16k(blob) {
|
|
19193
|
+
if (blob.size === 0) return null;
|
|
19194
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
19195
|
+
const AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
19196
|
+
const ctx = new AudioCtx();
|
|
19197
|
+
let decoded;
|
|
19198
|
+
try {
|
|
19199
|
+
decoded = await ctx.decodeAudioData(arrayBuffer);
|
|
19200
|
+
} catch {
|
|
19201
|
+
return null;
|
|
19202
|
+
} finally {
|
|
19203
|
+
ctx.close();
|
|
19204
|
+
}
|
|
19205
|
+
const length = Math.ceil(decoded.duration * TARGET_SAMPLE_RATE);
|
|
19206
|
+
if (length < 1) return null;
|
|
19207
|
+
const offline = new OfflineAudioContext(1, length, TARGET_SAMPLE_RATE);
|
|
19208
|
+
const source = offline.createBufferSource();
|
|
19209
|
+
source.buffer = decoded;
|
|
19210
|
+
source.connect(offline.destination);
|
|
19211
|
+
source.start();
|
|
19212
|
+
const rendered = await offline.startRendering();
|
|
19213
|
+
return rendered.getChannelData(0);
|
|
19214
|
+
}
|
|
19215
|
+
async function transcribeBlob(blob, onProgress) {
|
|
19216
|
+
const transcriber = await loadTranscriber(onProgress);
|
|
19217
|
+
const pcm = await blobToPcm16k(blob);
|
|
19218
|
+
if (!pcm) return "";
|
|
19219
|
+
const result = await transcriber(pcm);
|
|
19220
|
+
const text2 = Array.isArray(result) ? result.map((r) => r.text).join(" ") : result?.text;
|
|
19221
|
+
return (text2 || "").trim();
|
|
19222
|
+
}
|
|
19223
|
+
function getRecognitionCtor() {
|
|
19224
|
+
const w = window;
|
|
19225
|
+
return w.SpeechRecognition || w.webkitSpeechRecognition || null;
|
|
19226
|
+
}
|
|
19227
|
+
const ENGINE_KEY = "ctlsurf.voiceEngine";
|
|
19228
|
+
const WEB_SPEECH_SUPPORTED = getRecognitionCtor() !== null;
|
|
19229
|
+
const LOCAL_SUPPORTED = typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia && typeof MediaRecorder !== "undefined" && typeof OfflineAudioContext !== "undefined";
|
|
19230
|
+
const ANY_SUPPORTED = WEB_SPEECH_SUPPORTED || LOCAL_SUPPORTED;
|
|
19231
|
+
function loadInitialEngine() {
|
|
19232
|
+
if (!WEB_SPEECH_SUPPORTED && LOCAL_SUPPORTED) return "local";
|
|
19233
|
+
try {
|
|
19234
|
+
if (localStorage.getItem(ENGINE_KEY) === "local" && LOCAL_SUPPORTED) return "local";
|
|
19235
|
+
} catch {
|
|
19236
|
+
}
|
|
19237
|
+
return WEB_SPEECH_SUPPORTED ? "web-speech" : "local";
|
|
19238
|
+
}
|
|
19239
|
+
function isEngineUnavailable(code) {
|
|
19240
|
+
return code === "network" || code === "service-not-allowed";
|
|
19241
|
+
}
|
|
19242
|
+
function describeMicError(err) {
|
|
19243
|
+
const name = err?.name;
|
|
19244
|
+
if (name === "NotAllowedError" || name === "SecurityError") return "Microphone access denied";
|
|
19245
|
+
if (name === "NotFoundError") return "No microphone found";
|
|
19246
|
+
return "Could not start microphone";
|
|
19247
|
+
}
|
|
19248
|
+
function VoiceInput({ onTranscript, variant = "titlebar" }) {
|
|
19249
|
+
const [engine, setEngine] = reactExports.useState(loadInitialEngine);
|
|
19250
|
+
const [phase, setPhase] = reactExports.useState("idle");
|
|
19251
|
+
const [interim, setInterim] = reactExports.useState("");
|
|
19252
|
+
const [modelPct, setModelPct] = reactExports.useState(null);
|
|
19253
|
+
const [error, setError] = reactExports.useState(null);
|
|
19254
|
+
const [notice, setNotice] = reactExports.useState(null);
|
|
19255
|
+
const recognitionRef = reactExports.useRef(null);
|
|
19256
|
+
const finalRef = reactExports.useRef("");
|
|
19257
|
+
const streamRef = reactExports.useRef(null);
|
|
19258
|
+
const recorderRef = reactExports.useRef(null);
|
|
19259
|
+
const chunksRef = reactExports.useRef([]);
|
|
19260
|
+
const cancelGestureRef = reactExports.useRef(false);
|
|
19261
|
+
const engineRef = reactExports.useRef(engine);
|
|
19262
|
+
reactExports.useEffect(() => {
|
|
19263
|
+
engineRef.current = engine;
|
|
19264
|
+
}, [engine]);
|
|
19265
|
+
const onTranscriptRef = reactExports.useRef(onTranscript);
|
|
19266
|
+
reactExports.useEffect(() => {
|
|
19267
|
+
onTranscriptRef.current = onTranscript;
|
|
19268
|
+
}, [onTranscript]);
|
|
19269
|
+
reactExports.useEffect(() => {
|
|
19270
|
+
if (!error) return;
|
|
19271
|
+
const t = setTimeout(() => setError(null), 4500);
|
|
19272
|
+
return () => clearTimeout(t);
|
|
19273
|
+
}, [error]);
|
|
19274
|
+
reactExports.useEffect(() => {
|
|
19275
|
+
if (!notice) return;
|
|
19276
|
+
const t = setTimeout(() => setNotice(null), 5e3);
|
|
19277
|
+
return () => clearTimeout(t);
|
|
19278
|
+
}, [notice]);
|
|
19279
|
+
const switchToLocal = reactExports.useCallback((reason) => {
|
|
19280
|
+
try {
|
|
19281
|
+
localStorage.setItem(ENGINE_KEY, "local");
|
|
19282
|
+
} catch {
|
|
19283
|
+
}
|
|
19284
|
+
setEngine("local");
|
|
19285
|
+
setNotice(reason);
|
|
19286
|
+
}, []);
|
|
19287
|
+
const stopStream = reactExports.useCallback(() => {
|
|
19288
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
19289
|
+
streamRef.current = null;
|
|
19290
|
+
}, []);
|
|
19291
|
+
const startWebSpeech = reactExports.useCallback(() => {
|
|
19292
|
+
const Ctor = getRecognitionCtor();
|
|
19293
|
+
if (!Ctor || recognitionRef.current) return;
|
|
19294
|
+
setError(null);
|
|
19295
|
+
setNotice(null);
|
|
19296
|
+
setInterim("");
|
|
19297
|
+
finalRef.current = "";
|
|
19298
|
+
const rec = new Ctor();
|
|
19299
|
+
rec.lang = navigator.language || "en-US";
|
|
19300
|
+
rec.continuous = true;
|
|
19301
|
+
rec.interimResults = true;
|
|
19302
|
+
rec.onresult = (event) => {
|
|
19303
|
+
let finalText = "";
|
|
19304
|
+
let interimText = "";
|
|
19305
|
+
for (let i2 = 0; i2 < event.results.length; i2++) {
|
|
19306
|
+
const res = event.results[i2];
|
|
19307
|
+
if (res.isFinal) finalText += res[0].transcript;
|
|
19308
|
+
else interimText += res[0].transcript;
|
|
19309
|
+
}
|
|
19310
|
+
finalRef.current = finalText;
|
|
19311
|
+
setInterim(interimText);
|
|
19312
|
+
};
|
|
19313
|
+
rec.onerror = (event) => {
|
|
19314
|
+
if (isEngineUnavailable(event.error) && LOCAL_SUPPORTED) {
|
|
19315
|
+
finalRef.current = "";
|
|
19316
|
+
switchToLocal("Voice service unavailable — switched to on-device. Press again.");
|
|
19317
|
+
} else if (event.error !== "no-speech" && event.error !== "aborted") {
|
|
19318
|
+
setError(event.error === "not-allowed" ? "Microphone access denied" : `Voice error: ${event.error}`);
|
|
19319
|
+
}
|
|
19320
|
+
};
|
|
19321
|
+
rec.onend = () => {
|
|
19322
|
+
const text2 = finalRef.current.trim();
|
|
19323
|
+
recognitionRef.current = null;
|
|
19324
|
+
setPhase("idle");
|
|
19325
|
+
setInterim("");
|
|
19326
|
+
if (text2) onTranscriptRef.current(text2);
|
|
19327
|
+
};
|
|
19328
|
+
recognitionRef.current = rec;
|
|
19329
|
+
try {
|
|
19330
|
+
rec.start();
|
|
19331
|
+
setPhase("listening");
|
|
19332
|
+
} catch (err) {
|
|
19333
|
+
recognitionRef.current = null;
|
|
19334
|
+
setPhase("idle");
|
|
19335
|
+
setError("Could not start microphone");
|
|
19336
|
+
console.error("[voice] web speech start failed", err);
|
|
19337
|
+
}
|
|
19338
|
+
}, [switchToLocal]);
|
|
19339
|
+
const stopWebSpeech = reactExports.useCallback(() => {
|
|
19340
|
+
try {
|
|
19341
|
+
recognitionRef.current?.stop();
|
|
19342
|
+
} catch {
|
|
19343
|
+
}
|
|
19344
|
+
}, []);
|
|
19345
|
+
const handleModelProgress = reactExports.useCallback((p) => {
|
|
19346
|
+
if (p.status === "progress" && typeof p.progress === "number") {
|
|
19347
|
+
setModelPct(Math.min(100, Math.round(p.progress)));
|
|
19348
|
+
}
|
|
19349
|
+
}, []);
|
|
19350
|
+
const runLocalTranscription = reactExports.useCallback(async (rec) => {
|
|
19351
|
+
stopStream();
|
|
19352
|
+
const blob = new Blob(chunksRef.current, { type: rec.mimeType || "audio/webm" });
|
|
19353
|
+
chunksRef.current = [];
|
|
19354
|
+
recorderRef.current = null;
|
|
19355
|
+
if (blob.size === 0) {
|
|
19356
|
+
setPhase("idle");
|
|
19357
|
+
return;
|
|
19358
|
+
}
|
|
19359
|
+
setPhase("transcribing");
|
|
19360
|
+
setInterim("");
|
|
19361
|
+
try {
|
|
19362
|
+
const text2 = await transcribeBlob(blob, handleModelProgress);
|
|
19363
|
+
if (text2) onTranscriptRef.current(text2);
|
|
19364
|
+
} catch (err) {
|
|
19365
|
+
setError("On-device transcription failed");
|
|
19366
|
+
console.error("[voice] local transcription failed", err);
|
|
19367
|
+
} finally {
|
|
19368
|
+
setPhase("idle");
|
|
19369
|
+
setModelPct(null);
|
|
19370
|
+
}
|
|
19371
|
+
}, [stopStream, handleModelProgress]);
|
|
19372
|
+
const startLocal = reactExports.useCallback(async () => {
|
|
19373
|
+
setError(null);
|
|
19374
|
+
setNotice(null);
|
|
19375
|
+
setInterim("");
|
|
19376
|
+
cancelGestureRef.current = false;
|
|
19377
|
+
try {
|
|
19378
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
19379
|
+
if (cancelGestureRef.current) {
|
|
19380
|
+
stream.getTracks().forEach((t) => t.stop());
|
|
19381
|
+
setPhase("idle");
|
|
19382
|
+
return;
|
|
19383
|
+
}
|
|
19384
|
+
streamRef.current = stream;
|
|
19385
|
+
chunksRef.current = [];
|
|
19386
|
+
const rec = new MediaRecorder(stream);
|
|
19387
|
+
rec.ondataavailable = (e) => {
|
|
19388
|
+
if (e.data.size) chunksRef.current.push(e.data);
|
|
19389
|
+
};
|
|
19390
|
+
rec.onstop = () => {
|
|
19391
|
+
void runLocalTranscription(rec);
|
|
19392
|
+
};
|
|
19393
|
+
recorderRef.current = rec;
|
|
19394
|
+
rec.start();
|
|
19395
|
+
setPhase("listening");
|
|
19396
|
+
} catch (err) {
|
|
19397
|
+
stopStream();
|
|
19398
|
+
setPhase("idle");
|
|
19399
|
+
setError(describeMicError(err));
|
|
19400
|
+
console.error("[voice] getUserMedia failed", err);
|
|
19401
|
+
}
|
|
19402
|
+
}, [runLocalTranscription, stopStream]);
|
|
19403
|
+
const stopLocal = reactExports.useCallback(() => {
|
|
19404
|
+
cancelGestureRef.current = true;
|
|
19405
|
+
const rec = recorderRef.current;
|
|
19406
|
+
if (rec && rec.state !== "inactive") {
|
|
19407
|
+
try {
|
|
19408
|
+
rec.stop();
|
|
19409
|
+
} catch {
|
|
19410
|
+
}
|
|
19411
|
+
}
|
|
19412
|
+
}, []);
|
|
19413
|
+
const handlePointerDown = (e) => {
|
|
19414
|
+
if (!ANY_SUPPORTED || phase !== "idle") return;
|
|
19415
|
+
e.preventDefault();
|
|
19416
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
19417
|
+
if (engineRef.current === "web-speech" && WEB_SPEECH_SUPPORTED) startWebSpeech();
|
|
19418
|
+
else if (LOCAL_SUPPORTED) void startLocal();
|
|
19419
|
+
};
|
|
19420
|
+
const handlePointerUp = (e) => {
|
|
19421
|
+
e.currentTarget.releasePointerCapture?.(e.pointerId);
|
|
19422
|
+
if (engineRef.current === "web-speech") stopWebSpeech();
|
|
19423
|
+
else stopLocal();
|
|
19424
|
+
};
|
|
19425
|
+
reactExports.useEffect(() => () => {
|
|
19426
|
+
try {
|
|
19427
|
+
recognitionRef.current?.abort();
|
|
19428
|
+
} catch {
|
|
19429
|
+
}
|
|
19430
|
+
try {
|
|
19431
|
+
recorderRef.current?.stop();
|
|
19432
|
+
} catch {
|
|
19433
|
+
}
|
|
19434
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
19435
|
+
}, []);
|
|
19436
|
+
const listening = phase === "listening";
|
|
19437
|
+
const busy = phase === "transcribing";
|
|
19438
|
+
const title = !ANY_SUPPORTED ? "Voice typing not supported in this build" : listening ? "Listening… release to insert" : busy ? "Transcribing…" : engine === "local" ? "Hold to talk (on-device) — speech is typed into the terminal" : "Hold to talk — speech is typed into the terminal";
|
|
19439
|
+
let chip = null;
|
|
19440
|
+
if (error && phase === "idle") chip = { kind: "error", text: error };
|
|
19441
|
+
else if (notice && phase === "idle") chip = { kind: "notice", text: notice };
|
|
19442
|
+
else if (listening) chip = { kind: "listening", text: interim || (engine === "local" ? "Recording…" : "Listening…") };
|
|
19443
|
+
else if (busy) chip = { kind: "busy", text: modelPct !== null ? `Downloading voice model… ${modelPct}%` : "Transcribing…" };
|
|
19444
|
+
const floating = variant === "floating";
|
|
19445
|
+
const btnClass = floating ? `voice-btn voice-btn-floating ${listening ? "listening" : ""} ${busy ? "busy" : ""}` : `titlebar-btn titlebar-icon-btn voice-btn ${listening ? "listening" : ""} ${busy ? "busy" : ""}`;
|
|
19446
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "voice-input-wrap", children: [
|
|
19447
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
19448
|
+
"button",
|
|
19449
|
+
{
|
|
19450
|
+
type: "button",
|
|
19451
|
+
className: btnClass,
|
|
19452
|
+
disabled: !ANY_SUPPORTED,
|
|
19453
|
+
onPointerDown: handlePointerDown,
|
|
19454
|
+
onPointerUp: handlePointerUp,
|
|
19455
|
+
onPointerCancel: handlePointerUp,
|
|
19456
|
+
onContextMenu: (e) => e.preventDefault(),
|
|
19457
|
+
title,
|
|
19458
|
+
"aria-label": "Voice typing (hold to talk)",
|
|
19459
|
+
children: [
|
|
19460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "voice-icon", "aria-hidden": "true", children: "🎤" }),
|
|
19461
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `voice-dot ${listening ? "on" : busy ? "busy" : "off"}` })
|
|
19462
|
+
]
|
|
19463
|
+
}
|
|
19464
|
+
),
|
|
19465
|
+
chip && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `voice-chip ${chip.kind} ${floating ? "voice-chip-floating" : ""}`, children: chip.text })
|
|
19466
|
+
] });
|
|
19467
|
+
}
|
|
19468
|
+
const POS_KEY = "ctlsurf.floatingMicPos";
|
|
19469
|
+
const EDGE = 20;
|
|
19470
|
+
const TOP_MIN = 46;
|
|
19471
|
+
const BOTTOM_GAP = 36;
|
|
19472
|
+
function loadPos() {
|
|
19473
|
+
try {
|
|
19474
|
+
const raw = localStorage.getItem(POS_KEY);
|
|
19475
|
+
if (raw) {
|
|
19476
|
+
const p = JSON.parse(raw);
|
|
19477
|
+
if (typeof p.x === "number" && typeof p.y === "number") return { x: p.x, y: p.y };
|
|
19478
|
+
}
|
|
19479
|
+
} catch {
|
|
19480
|
+
}
|
|
19481
|
+
return null;
|
|
19482
|
+
}
|
|
19483
|
+
function FloatingMic({ onTranscript, onHide }) {
|
|
19484
|
+
const [pos, setPos] = reactExports.useState(loadPos);
|
|
19485
|
+
const elRef = reactExports.useRef(null);
|
|
19486
|
+
const dragRef = reactExports.useRef(null);
|
|
19487
|
+
const clamp2 = reactExports.useCallback((x, y) => {
|
|
19488
|
+
const el = elRef.current;
|
|
19489
|
+
const w = el?.offsetWidth ?? 64;
|
|
19490
|
+
const h2 = el?.offsetHeight ?? 90;
|
|
19491
|
+
return {
|
|
19492
|
+
x: Math.max(EDGE, Math.min(x, window.innerWidth - w - EDGE)),
|
|
19493
|
+
y: Math.max(TOP_MIN, Math.min(y, window.innerHeight - h2 - BOTTOM_GAP))
|
|
19494
|
+
};
|
|
19495
|
+
}, []);
|
|
19496
|
+
reactExports.useEffect(() => {
|
|
19497
|
+
if (pos) return;
|
|
19498
|
+
const el = elRef.current;
|
|
19499
|
+
const w = el?.offsetWidth ?? 64;
|
|
19500
|
+
const h2 = el?.offsetHeight ?? 90;
|
|
19501
|
+
setPos({
|
|
19502
|
+
x: window.innerWidth - w - EDGE,
|
|
19503
|
+
y: window.innerHeight - h2 - BOTTOM_GAP
|
|
19504
|
+
});
|
|
19505
|
+
}, [pos]);
|
|
19506
|
+
reactExports.useEffect(() => {
|
|
19507
|
+
const onResize = () => setPos((p) => p ? clamp2(p.x, p.y) : p);
|
|
19508
|
+
window.addEventListener("resize", onResize);
|
|
19509
|
+
return () => window.removeEventListener("resize", onResize);
|
|
19510
|
+
}, [clamp2]);
|
|
19511
|
+
const onHandleDown = reactExports.useCallback((e) => {
|
|
19512
|
+
const el = elRef.current;
|
|
19513
|
+
if (!el) return;
|
|
19514
|
+
e.preventDefault();
|
|
19515
|
+
const rect = el.getBoundingClientRect();
|
|
19516
|
+
dragRef.current = { dx: e.clientX - rect.left, dy: e.clientY - rect.top };
|
|
19517
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
19518
|
+
}, []);
|
|
19519
|
+
const onHandleMove = reactExports.useCallback((e) => {
|
|
19520
|
+
const d = dragRef.current;
|
|
19521
|
+
if (!d) return;
|
|
19522
|
+
setPos(clamp2(e.clientX - d.dx, e.clientY - d.dy));
|
|
19523
|
+
}, [clamp2]);
|
|
19524
|
+
const onHandleUp = reactExports.useCallback((e) => {
|
|
19525
|
+
if (!dragRef.current) return;
|
|
19526
|
+
dragRef.current = null;
|
|
19527
|
+
e.currentTarget.releasePointerCapture?.(e.pointerId);
|
|
19528
|
+
setPos((p) => {
|
|
19529
|
+
if (p) {
|
|
19530
|
+
try {
|
|
19531
|
+
localStorage.setItem(POS_KEY, JSON.stringify(p));
|
|
19532
|
+
} catch {
|
|
19533
|
+
}
|
|
19534
|
+
}
|
|
19535
|
+
return p;
|
|
19536
|
+
});
|
|
19537
|
+
}, []);
|
|
19538
|
+
const style = pos ? { left: pos.x, top: pos.y } : { left: -9999, top: -9999, visibility: "hidden" };
|
|
19539
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: elRef, className: "floating-mic", style, children: [
|
|
19540
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
19541
|
+
"div",
|
|
19542
|
+
{
|
|
19543
|
+
className: "floating-mic-handle",
|
|
19544
|
+
onPointerDown: onHandleDown,
|
|
19545
|
+
onPointerMove: onHandleMove,
|
|
19546
|
+
onPointerUp: onHandleUp,
|
|
19547
|
+
onPointerCancel: onHandleUp,
|
|
19548
|
+
title: "Drag to move",
|
|
19549
|
+
"aria-label": "Drag floating mic",
|
|
19550
|
+
children: [
|
|
19551
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "floating-mic-grip", "aria-hidden": "true", children: "⠿" }),
|
|
19552
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19553
|
+
"button",
|
|
19554
|
+
{
|
|
19555
|
+
type: "button",
|
|
19556
|
+
className: "floating-mic-hide",
|
|
19557
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
19558
|
+
onClick: onHide,
|
|
19559
|
+
title: "Hide floating mic",
|
|
19560
|
+
"aria-label": "Hide floating mic",
|
|
19561
|
+
children: "×"
|
|
19562
|
+
}
|
|
19563
|
+
)
|
|
19564
|
+
]
|
|
19565
|
+
}
|
|
19566
|
+
),
|
|
19567
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(VoiceInput, { variant: "floating", onTranscript })
|
|
19568
|
+
] });
|
|
19569
|
+
}
|
|
19076
19570
|
function CtlsurfPanel({ navigate }) {
|
|
19077
19571
|
const webviewRef = reactExports.useRef(null);
|
|
19078
19572
|
const [url, setUrl] = reactExports.useState(null);
|
|
@@ -19725,91 +20219,6 @@ function Ve({ defaultValue: e, defaultLanguage: r, defaultPath: n2, value: t, la
|
|
|
19725
20219
|
var fe = Ve;
|
|
19726
20220
|
var de = reactExports.memo(fe);
|
|
19727
20221
|
var Ft = de;
|
|
19728
|
-
const scriptRel = /* @__PURE__ */ (function detectScriptRel() {
|
|
19729
|
-
const relList = typeof document !== "undefined" && document.createElement("link").relList;
|
|
19730
|
-
return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
|
|
19731
|
-
})();
|
|
19732
|
-
const assetsURL = function(dep, importerUrl) {
|
|
19733
|
-
return new URL(dep, importerUrl).href;
|
|
19734
|
-
};
|
|
19735
|
-
const seen = {};
|
|
19736
|
-
const __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
19737
|
-
let promise = Promise.resolve();
|
|
19738
|
-
if (deps && deps.length > 0) {
|
|
19739
|
-
let allSettled2 = function(promises) {
|
|
19740
|
-
return Promise.all(
|
|
19741
|
-
promises.map(
|
|
19742
|
-
(p) => Promise.resolve(p).then(
|
|
19743
|
-
(value) => ({ status: "fulfilled", value }),
|
|
19744
|
-
(reason) => ({ status: "rejected", reason })
|
|
19745
|
-
)
|
|
19746
|
-
)
|
|
19747
|
-
);
|
|
19748
|
-
};
|
|
19749
|
-
const links = document.getElementsByTagName("link");
|
|
19750
|
-
const cspNonceMeta = document.querySelector(
|
|
19751
|
-
"meta[property=csp-nonce]"
|
|
19752
|
-
);
|
|
19753
|
-
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
19754
|
-
promise = allSettled2(
|
|
19755
|
-
deps.map((dep) => {
|
|
19756
|
-
dep = assetsURL(dep, importerUrl);
|
|
19757
|
-
if (dep in seen) return;
|
|
19758
|
-
seen[dep] = true;
|
|
19759
|
-
const isCss = dep.endsWith(".css");
|
|
19760
|
-
const cssSelector = isCss ? '[rel="stylesheet"]' : "";
|
|
19761
|
-
const isBaseRelative = !!importerUrl;
|
|
19762
|
-
if (isBaseRelative) {
|
|
19763
|
-
for (let i2 = links.length - 1; i2 >= 0; i2--) {
|
|
19764
|
-
const link22 = links[i2];
|
|
19765
|
-
if (link22.href === dep && (!isCss || link22.rel === "stylesheet")) {
|
|
19766
|
-
return;
|
|
19767
|
-
}
|
|
19768
|
-
}
|
|
19769
|
-
} else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
|
|
19770
|
-
return;
|
|
19771
|
-
}
|
|
19772
|
-
const link2 = document.createElement("link");
|
|
19773
|
-
link2.rel = isCss ? "stylesheet" : scriptRel;
|
|
19774
|
-
if (!isCss) {
|
|
19775
|
-
link2.as = "script";
|
|
19776
|
-
}
|
|
19777
|
-
link2.crossOrigin = "";
|
|
19778
|
-
link2.href = dep;
|
|
19779
|
-
if (cspNonce) {
|
|
19780
|
-
link2.setAttribute("nonce", cspNonce);
|
|
19781
|
-
}
|
|
19782
|
-
document.head.appendChild(link2);
|
|
19783
|
-
if (isCss) {
|
|
19784
|
-
return new Promise((res, rej) => {
|
|
19785
|
-
link2.addEventListener("load", res);
|
|
19786
|
-
link2.addEventListener(
|
|
19787
|
-
"error",
|
|
19788
|
-
() => rej(new Error(`Unable to preload CSS for ${dep}`))
|
|
19789
|
-
);
|
|
19790
|
-
});
|
|
19791
|
-
}
|
|
19792
|
-
})
|
|
19793
|
-
);
|
|
19794
|
-
}
|
|
19795
|
-
function handlePreloadError(err) {
|
|
19796
|
-
const e = new Event("vite:preloadError", {
|
|
19797
|
-
cancelable: true
|
|
19798
|
-
});
|
|
19799
|
-
e.payload = err;
|
|
19800
|
-
window.dispatchEvent(e);
|
|
19801
|
-
if (!e.defaultPrevented) {
|
|
19802
|
-
throw err;
|
|
19803
|
-
}
|
|
19804
|
-
}
|
|
19805
|
-
return promise.then((res) => {
|
|
19806
|
-
for (const item of res || []) {
|
|
19807
|
-
if (item.status !== "rejected") continue;
|
|
19808
|
-
handlePreloadError(item.reason);
|
|
19809
|
-
}
|
|
19810
|
-
return baseModule().catch(handlePreloadError);
|
|
19811
|
-
});
|
|
19812
|
-
};
|
|
19813
20222
|
function getNLSMessages() {
|
|
19814
20223
|
return globalThis._VSCODE_NLS_MESSAGES;
|
|
19815
20224
|
}
|
|
@@ -206752,7 +207161,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
|
|
|
206752
207161
|
modeConfigurationDefault$2
|
|
206753
207162
|
);
|
|
206754
207163
|
function getMode$3() {
|
|
206755
|
-
return __vitePreload(() => import("./cssMode-
|
|
207164
|
+
return __vitePreload(() => import("./cssMode-eTXVdAkZ.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
|
|
206756
207165
|
}
|
|
206757
207166
|
languages.onLanguage("less", () => {
|
|
206758
207167
|
getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
|
|
@@ -206857,7 +207266,7 @@ const razorLanguageService = registerHTMLLanguageService(
|
|
|
206857
207266
|
);
|
|
206858
207267
|
const razorDefaults = razorLanguageService.defaults;
|
|
206859
207268
|
function getMode$2() {
|
|
206860
|
-
return __vitePreload(() => import("./htmlMode-
|
|
207269
|
+
return __vitePreload(() => import("./htmlMode-46N3XG2c.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
|
|
206861
207270
|
}
|
|
206862
207271
|
function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
|
|
206863
207272
|
const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
|
|
@@ -206941,7 +207350,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
|
|
|
206941
207350
|
);
|
|
206942
207351
|
const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
|
|
206943
207352
|
function getMode$1() {
|
|
206944
|
-
return __vitePreload(() => import("./jsonMode-
|
|
207353
|
+
return __vitePreload(() => import("./jsonMode-DXDczSNu.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
|
|
206945
207354
|
}
|
|
206946
207355
|
languages.register({
|
|
206947
207356
|
id: "json",
|
|
@@ -207187,7 +207596,7 @@ const getJavaScriptWorker = () => {
|
|
|
207187
207596
|
return getMode().then((mode) => mode.getJavaScriptWorker());
|
|
207188
207597
|
};
|
|
207189
207598
|
function getMode() {
|
|
207190
|
-
return __vitePreload(() => import("./tsMode-
|
|
207599
|
+
return __vitePreload(() => import("./tsMode-C7m6Kr5E.js"), true ? [] : void 0, import.meta.url);
|
|
207191
207600
|
}
|
|
207192
207601
|
languages.onLanguage("typescript", () => {
|
|
207193
207602
|
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
|
|
@@ -207382,49 +207791,49 @@ registerLanguage({
|
|
|
207382
207791
|
extensions: [".ftl", ".ftlh", ".ftlx"],
|
|
207383
207792
|
aliases: ["FreeMarker2", "Apache FreeMarker2"],
|
|
207384
207793
|
loader: () => {
|
|
207385
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207794
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207386
207795
|
}
|
|
207387
207796
|
});
|
|
207388
207797
|
registerLanguage({
|
|
207389
207798
|
id: "freemarker2.tag-angle.interpolation-dollar",
|
|
207390
207799
|
aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
|
|
207391
207800
|
loader: () => {
|
|
207392
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207801
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
|
|
207393
207802
|
}
|
|
207394
207803
|
});
|
|
207395
207804
|
registerLanguage({
|
|
207396
207805
|
id: "freemarker2.tag-bracket.interpolation-dollar",
|
|
207397
207806
|
aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
|
|
207398
207807
|
loader: () => {
|
|
207399
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207808
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
|
|
207400
207809
|
}
|
|
207401
207810
|
});
|
|
207402
207811
|
registerLanguage({
|
|
207403
207812
|
id: "freemarker2.tag-angle.interpolation-bracket",
|
|
207404
207813
|
aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
|
|
207405
207814
|
loader: () => {
|
|
207406
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207815
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
|
|
207407
207816
|
}
|
|
207408
207817
|
});
|
|
207409
207818
|
registerLanguage({
|
|
207410
207819
|
id: "freemarker2.tag-bracket.interpolation-bracket",
|
|
207411
207820
|
aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
|
|
207412
207821
|
loader: () => {
|
|
207413
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207822
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
|
|
207414
207823
|
}
|
|
207415
207824
|
});
|
|
207416
207825
|
registerLanguage({
|
|
207417
207826
|
id: "freemarker2.tag-auto.interpolation-dollar",
|
|
207418
207827
|
aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
|
|
207419
207828
|
loader: () => {
|
|
207420
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207829
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207421
207830
|
}
|
|
207422
207831
|
});
|
|
207423
207832
|
registerLanguage({
|
|
207424
207833
|
id: "freemarker2.tag-auto.interpolation-bracket",
|
|
207425
207834
|
aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
|
|
207426
207835
|
loader: () => {
|
|
207427
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207836
|
+
return __vitePreload(() => import("./freemarker2-B5BKaiK4.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
|
|
207428
207837
|
}
|
|
207429
207838
|
});
|
|
207430
207839
|
registerLanguage({
|
|
@@ -207445,7 +207854,7 @@ registerLanguage({
|
|
|
207445
207854
|
extensions: [".handlebars", ".hbs"],
|
|
207446
207855
|
aliases: ["Handlebars", "handlebars", "hbs"],
|
|
207447
207856
|
mimetypes: ["text/x-handlebars-template"],
|
|
207448
|
-
loader: () => __vitePreload(() => import("./handlebars-
|
|
207857
|
+
loader: () => __vitePreload(() => import("./handlebars-BIdLd2wU.js"), true ? [] : void 0, import.meta.url)
|
|
207449
207858
|
});
|
|
207450
207859
|
registerLanguage({
|
|
207451
207860
|
id: "hcl",
|
|
@@ -207458,7 +207867,7 @@ registerLanguage({
|
|
|
207458
207867
|
extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
|
|
207459
207868
|
aliases: ["HTML", "htm", "html", "xhtml"],
|
|
207460
207869
|
mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
|
|
207461
|
-
loader: () => __vitePreload(() => import("./html-
|
|
207870
|
+
loader: () => __vitePreload(() => import("./html-BXL4cnLS.js"), true ? [] : void 0, import.meta.url)
|
|
207462
207871
|
});
|
|
207463
207872
|
registerLanguage({
|
|
207464
207873
|
id: "ini",
|
|
@@ -207481,7 +207890,7 @@ registerLanguage({
|
|
|
207481
207890
|
filenames: ["jakefile"],
|
|
207482
207891
|
aliases: ["JavaScript", "javascript", "js"],
|
|
207483
207892
|
mimetypes: ["text/javascript"],
|
|
207484
|
-
loader: () => __vitePreload(() => import("./javascript-
|
|
207893
|
+
loader: () => __vitePreload(() => import("./javascript-n_iZZzDX.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
|
|
207485
207894
|
});
|
|
207486
207895
|
registerLanguage({
|
|
207487
207896
|
id: "julia",
|
|
@@ -207520,7 +207929,7 @@ registerLanguage({
|
|
|
207520
207929
|
extensions: [".liquid", ".html.liquid"],
|
|
207521
207930
|
aliases: ["Liquid", "liquid"],
|
|
207522
207931
|
mimetypes: ["application/liquid"],
|
|
207523
|
-
loader: () => __vitePreload(() => import("./liquid-
|
|
207932
|
+
loader: () => __vitePreload(() => import("./liquid-B1QweUh7.js"), true ? [] : void 0, import.meta.url)
|
|
207524
207933
|
});
|
|
207525
207934
|
registerLanguage({
|
|
207526
207935
|
id: "m3",
|
|
@@ -207538,7 +207947,7 @@ registerLanguage({
|
|
|
207538
207947
|
id: "mdx",
|
|
207539
207948
|
extensions: [".mdx"],
|
|
207540
207949
|
aliases: ["MDX", "mdx"],
|
|
207541
|
-
loader: () => __vitePreload(() => import("./mdx-
|
|
207950
|
+
loader: () => __vitePreload(() => import("./mdx-BCv8lm5e.js"), true ? [] : void 0, import.meta.url)
|
|
207542
207951
|
});
|
|
207543
207952
|
registerLanguage({
|
|
207544
207953
|
id: "mips",
|
|
@@ -207637,7 +208046,7 @@ registerLanguage({
|
|
|
207637
208046
|
extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
|
|
207638
208047
|
aliases: ["Python", "py"],
|
|
207639
208048
|
firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
|
|
207640
|
-
loader: () => __vitePreload(() => import("./python-
|
|
208049
|
+
loader: () => __vitePreload(() => import("./python-BLNzYwDv.js"), true ? [] : void 0, import.meta.url)
|
|
207641
208050
|
});
|
|
207642
208051
|
registerLanguage({
|
|
207643
208052
|
id: "qsharp",
|
|
@@ -207656,7 +208065,7 @@ registerLanguage({
|
|
|
207656
208065
|
extensions: [".cshtml"],
|
|
207657
208066
|
aliases: ["Razor", "razor"],
|
|
207658
208067
|
mimetypes: ["text/x-cshtml"],
|
|
207659
|
-
loader: () => __vitePreload(() => import("./razor-
|
|
208068
|
+
loader: () => __vitePreload(() => import("./razor-CvAww8bG.js"), true ? [] : void 0, import.meta.url)
|
|
207660
208069
|
});
|
|
207661
208070
|
registerLanguage({
|
|
207662
208071
|
id: "redis",
|
|
@@ -207789,7 +208198,7 @@ registerLanguage({
|
|
|
207789
208198
|
aliases: ["TypeScript", "ts", "typescript"],
|
|
207790
208199
|
mimetypes: ["text/typescript"],
|
|
207791
208200
|
loader: () => {
|
|
207792
|
-
return __vitePreload(() => import("./typescript-
|
|
208201
|
+
return __vitePreload(() => import("./typescript-DhPw4VVg.js"), true ? [] : void 0, import.meta.url);
|
|
207793
208202
|
}
|
|
207794
208203
|
});
|
|
207795
208204
|
registerLanguage({
|
|
@@ -207834,14 +208243,14 @@ registerLanguage({
|
|
|
207834
208243
|
firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
|
|
207835
208244
|
aliases: ["XML", "xml"],
|
|
207836
208245
|
mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
|
|
207837
|
-
loader: () => __vitePreload(() => import("./xml-
|
|
208246
|
+
loader: () => __vitePreload(() => import("./xml-B0WLFJ2U.js"), true ? [] : void 0, import.meta.url)
|
|
207838
208247
|
});
|
|
207839
208248
|
registerLanguage({
|
|
207840
208249
|
id: "yaml",
|
|
207841
208250
|
extensions: [".yaml", ".yml"],
|
|
207842
208251
|
aliases: ["YAML", "yaml", "YML", "yml"],
|
|
207843
208252
|
mimetypes: ["application/x-yaml", "text/x-yaml"],
|
|
207844
|
-
loader: () => __vitePreload(() => import("./yaml-
|
|
208253
|
+
loader: () => __vitePreload(() => import("./yaml-BWyn9Wd7.js"), true ? [] : void 0, import.meta.url)
|
|
207845
208254
|
});
|
|
207846
208255
|
var __defProp = Object.defineProperty;
|
|
207847
208256
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -212244,6 +212653,20 @@ function App() {
|
|
|
212244
212653
|
const [activeTabId, setActiveTabId] = reactExports.useState(tabs[0].id);
|
|
212245
212654
|
const [trackingActive, setTrackingActive] = reactExports.useState(false);
|
|
212246
212655
|
const [showTicketPanel, setShowTicketPanel] = reactExports.useState(false);
|
|
212656
|
+
const [showFloatingMic, setShowFloatingMic] = reactExports.useState(() => {
|
|
212657
|
+
try {
|
|
212658
|
+
return localStorage.getItem("ctlsurf.floatingMicVisible") !== "false";
|
|
212659
|
+
} catch {
|
|
212660
|
+
return true;
|
|
212661
|
+
}
|
|
212662
|
+
});
|
|
212663
|
+
const setFloatingMicVisible = reactExports.useCallback((v2) => {
|
|
212664
|
+
setShowFloatingMic(v2);
|
|
212665
|
+
try {
|
|
212666
|
+
localStorage.setItem("ctlsurf.floatingMicVisible", String(v2));
|
|
212667
|
+
} catch {
|
|
212668
|
+
}
|
|
212669
|
+
}, []);
|
|
212247
212670
|
const [pickerTargetTabId, setPickerTargetTabId] = reactExports.useState(tabs[0].id);
|
|
212248
212671
|
const [showAgentPicker, setShowAgentPicker] = reactExports.useState(true);
|
|
212249
212672
|
const visiblePaneIds = findPaneIds(layout2);
|
|
@@ -212311,6 +212734,12 @@ function App() {
|
|
|
212311
212734
|
console.error("[tracking] toggle failed", err);
|
|
212312
212735
|
}
|
|
212313
212736
|
}, [trackingActive]);
|
|
212737
|
+
const handleVoiceTranscript = reactExports.useCallback((text2) => {
|
|
212738
|
+
const trimmed = text2.trim();
|
|
212739
|
+
if (!trimmed) return;
|
|
212740
|
+
window.worker.writePty(activeTabId, trimmed + "\r");
|
|
212741
|
+
focusTerminal(activeTabId);
|
|
212742
|
+
}, [activeTabId]);
|
|
212314
212743
|
const cwdRef = reactExports.useRef(null);
|
|
212315
212744
|
const handleSpawn = reactExports.useCallback(async (tabId, agent) => {
|
|
212316
212745
|
setTabs((prev) => prev.map((t) => t.id === tabId ? { ...t, agentStatus: "active" } : t));
|
|
@@ -212572,6 +213001,35 @@ function App() {
|
|
|
212572
213001
|
]
|
|
212573
213002
|
}
|
|
212574
213003
|
),
|
|
213004
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
213005
|
+
"button",
|
|
213006
|
+
{
|
|
213007
|
+
className: `titlebar-btn titlebar-icon-btn ${showFloatingMic ? "active" : ""}`,
|
|
213008
|
+
onClick: () => setFloatingMicVisible(!showFloatingMic),
|
|
213009
|
+
title: showFloatingMic ? "Hide floating mic" : "Show floating mic",
|
|
213010
|
+
"aria-label": "Toggle floating mic",
|
|
213011
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
213012
|
+
"svg",
|
|
213013
|
+
{
|
|
213014
|
+
viewBox: "0 0 24 24",
|
|
213015
|
+
width: "13",
|
|
213016
|
+
height: "13",
|
|
213017
|
+
fill: "none",
|
|
213018
|
+
stroke: "currentColor",
|
|
213019
|
+
strokeWidth: "2",
|
|
213020
|
+
strokeLinecap: "round",
|
|
213021
|
+
strokeLinejoin: "round",
|
|
213022
|
+
"aria-hidden": "true",
|
|
213023
|
+
children: [
|
|
213024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
|
|
213025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
213026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
|
|
213027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
|
|
213028
|
+
]
|
|
213029
|
+
}
|
|
213030
|
+
)
|
|
213031
|
+
}
|
|
213032
|
+
),
|
|
212575
213033
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-separator" }),
|
|
212576
213034
|
agents.map((a) => {
|
|
212577
213035
|
const activeTab = tabs.find((t) => t.id === activeTabId);
|
|
@@ -212625,6 +213083,13 @@ function App() {
|
|
|
212625
213083
|
}
|
|
212626
213084
|
}
|
|
212627
213085
|
}
|
|
213086
|
+
),
|
|
213087
|
+
showFloatingMic && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
213088
|
+
FloatingMic,
|
|
213089
|
+
{
|
|
213090
|
+
onTranscript: handleVoiceTranscript,
|
|
213091
|
+
onHide: () => setFloatingMicVisible(false)
|
|
213092
|
+
}
|
|
212628
213093
|
)
|
|
212629
213094
|
] });
|
|
212630
213095
|
}
|