@phenx-inc/ctlsurf 0.5.2 → 0.6.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.
Files changed (32) hide show
  1. package/electron-vite.config.ts +5 -0
  2. package/out/headless/index.mjs +2 -1
  3. package/out/headless/index.mjs.map +2 -2
  4. package/out/main/index.js +3 -0
  5. package/out/renderer/assets/{cssMode-D9-xaWSI.js → cssMode-DbMmcl1h.js} +3 -3
  6. package/out/renderer/assets/{freemarker2-CoRAVxnv.js → freemarker2-CvaHiy92.js} +1 -1
  7. package/out/renderer/assets/{handlebars-B0p9Wgkw.js → handlebars-D58lUIOu.js} +1 -1
  8. package/out/renderer/assets/{html-D_XFJJtO.js → html-D1h1aJbM.js} +1 -1
  9. package/out/renderer/assets/{htmlMode-naWw6PWr.js → htmlMode-BdkAp9qr.js} +3 -3
  10. package/out/renderer/assets/{index-DBt_rov1.js → index-B60JU1yI.js} +419 -107
  11. package/out/renderer/assets/{index-ezC-iarf.css → index-DJFYmHjz.css} +89 -0
  12. package/out/renderer/assets/{javascript-DDLsFUr-.js → javascript-CXqZcnvb.js} +2 -2
  13. package/out/renderer/assets/{jsonMode-Ixhcm5I6.js → jsonMode-BuVr-eSl.js} +3 -3
  14. package/out/renderer/assets/{liquid-BHgSYEHk.js → liquid-LKu0Wd0B.js} +1 -1
  15. package/out/renderer/assets/{lspLanguageFeatures-ClbEdD0U.js → lspLanguageFeatures-Cjr_4HGs.js} +1 -1
  16. package/out/renderer/assets/{mdx-DMngMjHR.js → mdx-Bl84ILla.js} +1 -1
  17. package/out/renderer/assets/ort-wasm-simd-threaded.asyncify-DMmc6YqF.wasm +0 -0
  18. package/out/renderer/assets/{python-D_czoeY2.js → python-0sFd9G1k.js} +1 -1
  19. package/out/renderer/assets/{razor-CLMDGvL7.js → razor-Cqcu1rLJ.js} +1 -1
  20. package/out/renderer/assets/transformers.web-DtSCnG36.js +33668 -0
  21. package/out/renderer/assets/{tsMode-EIuSGG42.js → tsMode-CYd3NUkW.js} +1 -1
  22. package/out/renderer/assets/{typescript-DQkV4kKA.js → typescript-rkc9lhpi.js} +1 -1
  23. package/out/renderer/assets/{xml-DJ0OOQTu.js → xml-EsHEUps1.js} +1 -1
  24. package/out/renderer/assets/{yaml-DxX26XLN.js → yaml-B9-nQ_s2.js} +1 -1
  25. package/out/renderer/index.html +2 -2
  26. package/package.json +2 -1
  27. package/src/main/index.ts +7 -0
  28. package/src/renderer/App.tsx +13 -1
  29. package/src/renderer/components/TerminalPanel.tsx +6 -0
  30. package/src/renderer/components/VoiceInput.tsx +313 -0
  31. package/src/renderer/lib/localWhisper.ts +88 -0
  32. package/src/renderer/styles.css +89 -0
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-D9-xaWSI.js","./lspLanguageFeatures-ClbEdD0U.js","./htmlMode-naWw6PWr.js","./jsonMode-Ixhcm5I6.js","./javascript-DDLsFUr-.js","./typescript-DQkV4kKA.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-DbMmcl1h.js","./lspLanguageFeatures-Cjr_4HGs.js","./htmlMode-BdkAp9qr.js","./jsonMode-BuVr-eSl.js","./javascript-CXqZcnvb.js","./typescript-rkc9lhpi.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,393 @@ 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 }) {
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
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "voice-input-wrap", children: [
19445
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
19446
+ "button",
19447
+ {
19448
+ type: "button",
19449
+ className: `titlebar-btn titlebar-icon-btn voice-btn ${listening ? "listening" : ""} ${busy ? "busy" : ""}`,
19450
+ disabled: !ANY_SUPPORTED,
19451
+ onPointerDown: handlePointerDown,
19452
+ onPointerUp: handlePointerUp,
19453
+ onPointerCancel: handlePointerUp,
19454
+ onContextMenu: (e) => e.preventDefault(),
19455
+ title,
19456
+ "aria-label": "Voice typing (hold to talk)",
19457
+ children: [
19458
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "voice-icon", "aria-hidden": "true", children: "🎤" }),
19459
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `voice-dot ${listening ? "on" : busy ? "busy" : "off"}` })
19460
+ ]
19461
+ }
19462
+ ),
19463
+ chip && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `voice-chip ${chip.kind}`, children: chip.text })
19464
+ ] });
19465
+ }
19076
19466
  function CtlsurfPanel({ navigate }) {
19077
19467
  const webviewRef = reactExports.useRef(null);
19078
19468
  const [url, setUrl] = reactExports.useState(null);
@@ -19725,91 +20115,6 @@ function Ve({ defaultValue: e, defaultLanguage: r, defaultPath: n2, value: t, la
19725
20115
  var fe = Ve;
19726
20116
  var de = reactExports.memo(fe);
19727
20117
  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
20118
  function getNLSMessages() {
19814
20119
  return globalThis._VSCODE_NLS_MESSAGES;
19815
20120
  }
@@ -206752,7 +207057,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
206752
207057
  modeConfigurationDefault$2
206753
207058
  );
206754
207059
  function getMode$3() {
206755
- return __vitePreload(() => import("./cssMode-D9-xaWSI.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
207060
+ return __vitePreload(() => import("./cssMode-DbMmcl1h.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
206756
207061
  }
206757
207062
  languages.onLanguage("less", () => {
206758
207063
  getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
@@ -206857,7 +207162,7 @@ const razorLanguageService = registerHTMLLanguageService(
206857
207162
  );
206858
207163
  const razorDefaults = razorLanguageService.defaults;
206859
207164
  function getMode$2() {
206860
- return __vitePreload(() => import("./htmlMode-naWw6PWr.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
207165
+ return __vitePreload(() => import("./htmlMode-BdkAp9qr.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
206861
207166
  }
206862
207167
  function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
206863
207168
  const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
@@ -206941,7 +207246,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
206941
207246
  );
206942
207247
  const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
206943
207248
  function getMode$1() {
206944
- return __vitePreload(() => import("./jsonMode-Ixhcm5I6.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
207249
+ return __vitePreload(() => import("./jsonMode-BuVr-eSl.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
206945
207250
  }
206946
207251
  languages.register({
206947
207252
  id: "json",
@@ -207187,7 +207492,7 @@ const getJavaScriptWorker = () => {
207187
207492
  return getMode().then((mode) => mode.getJavaScriptWorker());
207188
207493
  };
207189
207494
  function getMode() {
207190
- return __vitePreload(() => import("./tsMode-EIuSGG42.js"), true ? [] : void 0, import.meta.url);
207495
+ return __vitePreload(() => import("./tsMode-CYd3NUkW.js"), true ? [] : void 0, import.meta.url);
207191
207496
  }
207192
207497
  languages.onLanguage("typescript", () => {
207193
207498
  return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
@@ -207382,49 +207687,49 @@ registerLanguage({
207382
207687
  extensions: [".ftl", ".ftlh", ".ftlx"],
207383
207688
  aliases: ["FreeMarker2", "Apache FreeMarker2"],
207384
207689
  loader: () => {
207385
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
207690
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
207386
207691
  }
207387
207692
  });
207388
207693
  registerLanguage({
207389
207694
  id: "freemarker2.tag-angle.interpolation-dollar",
207390
207695
  aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
207391
207696
  loader: () => {
207392
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
207697
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
207393
207698
  }
207394
207699
  });
207395
207700
  registerLanguage({
207396
207701
  id: "freemarker2.tag-bracket.interpolation-dollar",
207397
207702
  aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
207398
207703
  loader: () => {
207399
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
207704
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
207400
207705
  }
207401
207706
  });
207402
207707
  registerLanguage({
207403
207708
  id: "freemarker2.tag-angle.interpolation-bracket",
207404
207709
  aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
207405
207710
  loader: () => {
207406
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
207711
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
207407
207712
  }
207408
207713
  });
207409
207714
  registerLanguage({
207410
207715
  id: "freemarker2.tag-bracket.interpolation-bracket",
207411
207716
  aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
207412
207717
  loader: () => {
207413
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
207718
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
207414
207719
  }
207415
207720
  });
207416
207721
  registerLanguage({
207417
207722
  id: "freemarker2.tag-auto.interpolation-dollar",
207418
207723
  aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
207419
207724
  loader: () => {
207420
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
207725
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
207421
207726
  }
207422
207727
  });
207423
207728
  registerLanguage({
207424
207729
  id: "freemarker2.tag-auto.interpolation-bracket",
207425
207730
  aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
207426
207731
  loader: () => {
207427
- return __vitePreload(() => import("./freemarker2-CoRAVxnv.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
207732
+ return __vitePreload(() => import("./freemarker2-CvaHiy92.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
207428
207733
  }
207429
207734
  });
207430
207735
  registerLanguage({
@@ -207445,7 +207750,7 @@ registerLanguage({
207445
207750
  extensions: [".handlebars", ".hbs"],
207446
207751
  aliases: ["Handlebars", "handlebars", "hbs"],
207447
207752
  mimetypes: ["text/x-handlebars-template"],
207448
- loader: () => __vitePreload(() => import("./handlebars-B0p9Wgkw.js"), true ? [] : void 0, import.meta.url)
207753
+ loader: () => __vitePreload(() => import("./handlebars-D58lUIOu.js"), true ? [] : void 0, import.meta.url)
207449
207754
  });
207450
207755
  registerLanguage({
207451
207756
  id: "hcl",
@@ -207458,7 +207763,7 @@ registerLanguage({
207458
207763
  extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
207459
207764
  aliases: ["HTML", "htm", "html", "xhtml"],
207460
207765
  mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
207461
- loader: () => __vitePreload(() => import("./html-D_XFJJtO.js"), true ? [] : void 0, import.meta.url)
207766
+ loader: () => __vitePreload(() => import("./html-D1h1aJbM.js"), true ? [] : void 0, import.meta.url)
207462
207767
  });
207463
207768
  registerLanguage({
207464
207769
  id: "ini",
@@ -207481,7 +207786,7 @@ registerLanguage({
207481
207786
  filenames: ["jakefile"],
207482
207787
  aliases: ["JavaScript", "javascript", "js"],
207483
207788
  mimetypes: ["text/javascript"],
207484
- loader: () => __vitePreload(() => import("./javascript-DDLsFUr-.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
207789
+ loader: () => __vitePreload(() => import("./javascript-CXqZcnvb.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
207485
207790
  });
207486
207791
  registerLanguage({
207487
207792
  id: "julia",
@@ -207520,7 +207825,7 @@ registerLanguage({
207520
207825
  extensions: [".liquid", ".html.liquid"],
207521
207826
  aliases: ["Liquid", "liquid"],
207522
207827
  mimetypes: ["application/liquid"],
207523
- loader: () => __vitePreload(() => import("./liquid-BHgSYEHk.js"), true ? [] : void 0, import.meta.url)
207828
+ loader: () => __vitePreload(() => import("./liquid-LKu0Wd0B.js"), true ? [] : void 0, import.meta.url)
207524
207829
  });
207525
207830
  registerLanguage({
207526
207831
  id: "m3",
@@ -207538,7 +207843,7 @@ registerLanguage({
207538
207843
  id: "mdx",
207539
207844
  extensions: [".mdx"],
207540
207845
  aliases: ["MDX", "mdx"],
207541
- loader: () => __vitePreload(() => import("./mdx-DMngMjHR.js"), true ? [] : void 0, import.meta.url)
207846
+ loader: () => __vitePreload(() => import("./mdx-Bl84ILla.js"), true ? [] : void 0, import.meta.url)
207542
207847
  });
207543
207848
  registerLanguage({
207544
207849
  id: "mips",
@@ -207637,7 +207942,7 @@ registerLanguage({
207637
207942
  extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
207638
207943
  aliases: ["Python", "py"],
207639
207944
  firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
207640
- loader: () => __vitePreload(() => import("./python-D_czoeY2.js"), true ? [] : void 0, import.meta.url)
207945
+ loader: () => __vitePreload(() => import("./python-0sFd9G1k.js"), true ? [] : void 0, import.meta.url)
207641
207946
  });
207642
207947
  registerLanguage({
207643
207948
  id: "qsharp",
@@ -207656,7 +207961,7 @@ registerLanguage({
207656
207961
  extensions: [".cshtml"],
207657
207962
  aliases: ["Razor", "razor"],
207658
207963
  mimetypes: ["text/x-cshtml"],
207659
- loader: () => __vitePreload(() => import("./razor-CLMDGvL7.js"), true ? [] : void 0, import.meta.url)
207964
+ loader: () => __vitePreload(() => import("./razor-Cqcu1rLJ.js"), true ? [] : void 0, import.meta.url)
207660
207965
  });
207661
207966
  registerLanguage({
207662
207967
  id: "redis",
@@ -207789,7 +208094,7 @@ registerLanguage({
207789
208094
  aliases: ["TypeScript", "ts", "typescript"],
207790
208095
  mimetypes: ["text/typescript"],
207791
208096
  loader: () => {
207792
- return __vitePreload(() => import("./typescript-DQkV4kKA.js"), true ? [] : void 0, import.meta.url);
208097
+ return __vitePreload(() => import("./typescript-rkc9lhpi.js"), true ? [] : void 0, import.meta.url);
207793
208098
  }
207794
208099
  });
207795
208100
  registerLanguage({
@@ -207834,14 +208139,14 @@ registerLanguage({
207834
208139
  firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
207835
208140
  aliases: ["XML", "xml"],
207836
208141
  mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
207837
- loader: () => __vitePreload(() => import("./xml-DJ0OOQTu.js"), true ? [] : void 0, import.meta.url)
208142
+ loader: () => __vitePreload(() => import("./xml-EsHEUps1.js"), true ? [] : void 0, import.meta.url)
207838
208143
  });
207839
208144
  registerLanguage({
207840
208145
  id: "yaml",
207841
208146
  extensions: [".yaml", ".yml"],
207842
208147
  aliases: ["YAML", "yaml", "YML", "yml"],
207843
208148
  mimetypes: ["application/x-yaml", "text/x-yaml"],
207844
- loader: () => __vitePreload(() => import("./yaml-DxX26XLN.js"), true ? [] : void 0, import.meta.url)
208149
+ loader: () => __vitePreload(() => import("./yaml-B9-nQ_s2.js"), true ? [] : void 0, import.meta.url)
207845
208150
  });
207846
208151
  var __defProp = Object.defineProperty;
207847
208152
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -212311,6 +212616,12 @@ function App() {
212311
212616
  console.error("[tracking] toggle failed", err);
212312
212617
  }
212313
212618
  }, [trackingActive]);
212619
+ const handleVoiceTranscript = reactExports.useCallback((text2) => {
212620
+ const trimmed = text2.trim();
212621
+ if (!trimmed) return;
212622
+ window.worker.writePty(activeTabId, trimmed);
212623
+ focusTerminal(activeTabId);
212624
+ }, [activeTabId]);
212314
212625
  const cwdRef = reactExports.useRef(null);
212315
212626
  const handleSpawn = reactExports.useCallback(async (tabId, agent) => {
212316
212627
  setTabs((prev) => prev.map((t) => t.id === tabId ? { ...t, agentStatus: "active" } : t));
@@ -212572,6 +212883,7 @@ function App() {
212572
212883
  ]
212573
212884
  }
212574
212885
  ),
212886
+ /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceInput, { onTranscript: handleVoiceTranscript }),
212575
212887
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-separator" }),
212576
212888
  agents.map((a) => {
212577
212889
  const activeTab = tabs.find((t) => t.id === activeTabId);