@autocode-cli/autocode 0.1.31 → 0.1.33
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/README.md +33 -3
- package/dist/cli/commands/health.d.ts +9 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +101 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.js +1 -1
- package/dist/cli/commands/move.d.ts.map +1 -1
- package/dist/cli/commands/move.js +14 -7
- package/dist/cli/commands/move.js.map +1 -1
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +2 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/core/hierarchy.d.ts +24 -0
- package/dist/core/hierarchy.d.ts.map +1 -1
- package/dist/core/hierarchy.js +76 -0
- package/dist/core/hierarchy.js.map +1 -1
- package/dist/core/issue.d.ts.map +1 -1
- package/dist/core/issue.js +11 -3
- package/dist/core/issue.js.map +1 -1
- package/dist/core/loop-detector.d.ts +45 -0
- package/dist/core/loop-detector.d.ts.map +1 -0
- package/dist/core/loop-detector.js +81 -0
- package/dist/core/loop-detector.js.map +1 -0
- package/dist/core/validation.d.ts +26 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +67 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/core/workflow.d.ts.map +1 -1
- package/dist/core/workflow.js +34 -1
- package/dist/core/workflow.js.map +1 -1
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +23 -2
- package/dist/server/api.js.map +1 -1
- package/dist/server/dashboard/pages/changelog.js +2 -2
- package/dist/server/dashboard/pages/changelog.js.map +1 -1
- package/dist/server/dashboard/pages/main-dashboard.js +1 -1
- package/dist/server/dashboard/pages/main-dashboard.js.map +1 -1
- package/dist/server/dashboard/pages/new-issue.d.ts.map +1 -1
- package/dist/server/dashboard/pages/new-issue.js +347 -3
- package/dist/server/dashboard/pages/new-issue.js.map +1 -1
- package/dist/server/dashboard/pages/new-issue.test.js +475 -0
- package/dist/server/dashboard/pages/new-issue.test.js.map +1 -1
- package/dist/server/watcher.d.ts +1 -1
- package/dist/server/watcher.js +1 -1
- package/dist/services/issue-io.d.ts +1 -1
- package/dist/services/issue-io.js +1 -1
- package/dist/services/monitoring.d.ts +47 -0
- package/dist/services/monitoring.d.ts.map +1 -0
- package/dist/services/monitoring.js +136 -0
- package/dist/services/monitoring.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/config.js +2 -2
- package/dist/utils/config.js.map +1 -1
- package/package.json +2 -1
- package/templates/prompts/in-progress.en.md +25 -9
- package/templates/prompts/in-progress.fr.md +25 -9
|
@@ -248,12 +248,114 @@ export function generateNewIssuePage(lang) {
|
|
|
248
248
|
animation: spin 0.8s linear infinite;
|
|
249
249
|
}
|
|
250
250
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
251
|
+
@keyframes pulse-recording {
|
|
252
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
|
|
253
|
+
50% { box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }
|
|
254
|
+
}
|
|
255
|
+
.btn-mic {
|
|
256
|
+
background: var(--bg);
|
|
257
|
+
border: 1px solid var(--border);
|
|
258
|
+
color: var(--muted);
|
|
259
|
+
width: 42px;
|
|
260
|
+
height: 42px;
|
|
261
|
+
border-radius: 8px;
|
|
262
|
+
cursor: pointer;
|
|
263
|
+
display: flex;
|
|
264
|
+
align-items: center;
|
|
265
|
+
justify-content: center;
|
|
266
|
+
transition: all 0.2s;
|
|
267
|
+
flex-shrink: 0;
|
|
268
|
+
}
|
|
269
|
+
.btn-mic:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
|
|
270
|
+
.btn-mic:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
271
|
+
.btn-mic.recording {
|
|
272
|
+
background: var(--red);
|
|
273
|
+
border-color: var(--red);
|
|
274
|
+
color: white;
|
|
275
|
+
animation: pulse-recording 1.5s ease-in-out infinite;
|
|
276
|
+
}
|
|
277
|
+
.btn-mic svg { width: 18px; height: 18px; }
|
|
278
|
+
.description-row {
|
|
279
|
+
display: flex;
|
|
280
|
+
gap: 8px;
|
|
281
|
+
align-items: flex-start;
|
|
282
|
+
}
|
|
283
|
+
.description-row .form-group { flex: 1; margin-bottom: 0; }
|
|
251
284
|
.title-row {
|
|
252
285
|
display: flex;
|
|
253
286
|
gap: 12px;
|
|
254
287
|
align-items: flex-end;
|
|
255
288
|
}
|
|
256
289
|
.title-row .form-group { flex: 1; margin-bottom: 0; }
|
|
290
|
+
.title-input-row {
|
|
291
|
+
display: flex;
|
|
292
|
+
gap: 8px;
|
|
293
|
+
align-items: center;
|
|
294
|
+
}
|
|
295
|
+
.title-input-row input { flex: 1; }
|
|
296
|
+
.autocomplete-countdown {
|
|
297
|
+
position: fixed;
|
|
298
|
+
bottom: 80px;
|
|
299
|
+
right: 24px;
|
|
300
|
+
background: var(--bg-card);
|
|
301
|
+
border: 1px solid var(--accent);
|
|
302
|
+
border-radius: 12px;
|
|
303
|
+
padding: 16px 20px;
|
|
304
|
+
z-index: 100;
|
|
305
|
+
display: none;
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
gap: 12px;
|
|
308
|
+
min-width: 280px;
|
|
309
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
|
310
|
+
}
|
|
311
|
+
.autocomplete-countdown.show { display: flex; }
|
|
312
|
+
.countdown-header {
|
|
313
|
+
display: flex;
|
|
314
|
+
align-items: center;
|
|
315
|
+
justify-content: space-between;
|
|
316
|
+
gap: 12px;
|
|
317
|
+
}
|
|
318
|
+
.countdown-text {
|
|
319
|
+
font-size: 14px;
|
|
320
|
+
color: var(--fg);
|
|
321
|
+
}
|
|
322
|
+
.countdown-timer {
|
|
323
|
+
font-weight: 600;
|
|
324
|
+
color: var(--accent);
|
|
325
|
+
font-size: 18px;
|
|
326
|
+
}
|
|
327
|
+
.countdown-progress {
|
|
328
|
+
height: 4px;
|
|
329
|
+
background: var(--border);
|
|
330
|
+
border-radius: 2px;
|
|
331
|
+
overflow: hidden;
|
|
332
|
+
}
|
|
333
|
+
.countdown-progress-bar {
|
|
334
|
+
height: 100%;
|
|
335
|
+
background: var(--accent);
|
|
336
|
+
transition: width 0.1s linear;
|
|
337
|
+
}
|
|
338
|
+
.countdown-actions {
|
|
339
|
+
display: flex;
|
|
340
|
+
gap: 8px;
|
|
341
|
+
}
|
|
342
|
+
.btn-countdown {
|
|
343
|
+
flex: 1;
|
|
344
|
+
padding: 8px 12px;
|
|
345
|
+
border-radius: 6px;
|
|
346
|
+
font-size: 13px;
|
|
347
|
+
cursor: pointer;
|
|
348
|
+
border: 1px solid var(--border);
|
|
349
|
+
background: var(--bg);
|
|
350
|
+
color: var(--fg);
|
|
351
|
+
}
|
|
352
|
+
.btn-countdown:hover { border-color: var(--accent); }
|
|
353
|
+
.btn-countdown.primary {
|
|
354
|
+
background: var(--accent);
|
|
355
|
+
border-color: var(--accent);
|
|
356
|
+
color: white;
|
|
357
|
+
}
|
|
358
|
+
.btn-countdown.primary:hover { opacity: 0.9; }
|
|
257
359
|
.btn-secondary {
|
|
258
360
|
background: var(--bg);
|
|
259
361
|
color: var(--fg);
|
|
@@ -294,7 +396,16 @@ export function generateNewIssuePage(lang) {
|
|
|
294
396
|
<div class="title-row">
|
|
295
397
|
<div class="form-group">
|
|
296
398
|
<label for="issue-title" data-i18n="newIssue.titleLabel">Title *</label>
|
|
297
|
-
<
|
|
399
|
+
<div class="title-input-row">
|
|
400
|
+
<input type="text" id="issue-title" placeholder="E.g.: Fix the login bug" data-i18n-placeholder="newIssue.titlePlaceholder">
|
|
401
|
+
<button type="button" class="btn-mic" id="btn-mic" onclick="toggleSpeechToText()" title="Speech to text">
|
|
402
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
403
|
+
<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/>
|
|
404
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
405
|
+
<line x1="12" x2="12" y1="19" y2="22"/>
|
|
406
|
+
</svg>
|
|
407
|
+
</button>
|
|
408
|
+
</div>
|
|
298
409
|
</div>
|
|
299
410
|
<button type="button" class="btn-autocomplete" id="btn-autocomplete" onclick="autocomplete()" title="Auto-fill fields using AI">
|
|
300
411
|
<span id="autocomplete-icon">✨</span>
|
|
@@ -371,6 +482,20 @@ export function generateNewIssuePage(lang) {
|
|
|
371
482
|
|
|
372
483
|
<div class="notification" id="notification"></div>
|
|
373
484
|
|
|
485
|
+
<div class="autocomplete-countdown" id="autocomplete-countdown">
|
|
486
|
+
<div class="countdown-header">
|
|
487
|
+
<span class="countdown-text" data-i18n="countdown.autocompletingIn">AutoComplete in</span>
|
|
488
|
+
<span class="countdown-timer" id="countdown-timer">3</span>
|
|
489
|
+
</div>
|
|
490
|
+
<div class="countdown-progress">
|
|
491
|
+
<div class="countdown-progress-bar" id="countdown-progress-bar" style="width: 100%"></div>
|
|
492
|
+
</div>
|
|
493
|
+
<div class="countdown-actions">
|
|
494
|
+
<button class="btn-countdown" onclick="cancelAutocompleteCountdown()" data-i18n="countdown.cancel">Cancel</button>
|
|
495
|
+
<button class="btn-countdown primary" onclick="triggerAutocompleteNow()" data-i18n="countdown.now">Now</button>
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
|
|
374
499
|
<script>
|
|
375
500
|
const STORAGE_KEY = 'autocode-lang';
|
|
376
501
|
let currentLang = localStorage.getItem(STORAGE_KEY) || 'fr';
|
|
@@ -407,7 +532,20 @@ export function generateNewIssuePage(lang) {
|
|
|
407
532
|
'notify.error': 'Error',
|
|
408
533
|
'notify.titleRequired': 'Title is required',
|
|
409
534
|
'notify.autocompleteSuccess': 'Fields auto-filled!',
|
|
410
|
-
'notify.autocompleteTitleRequired': 'Enter a title first'
|
|
535
|
+
'notify.autocompleteTitleRequired': 'Enter a title first',
|
|
536
|
+
'mic.title': 'Speech to text',
|
|
537
|
+
'mic.titleRecording': 'Recording... Click to stop',
|
|
538
|
+
'mic.notSupported': 'Speech recognition not supported',
|
|
539
|
+
'notify.micNotSupported': 'Speech recognition is not supported by your browser',
|
|
540
|
+
'notify.micError': 'Speech recognition error',
|
|
541
|
+
'notify.micErrorNetwork': 'Network error: Speech recognition requires an internet connection. Make sure you are connected and try again.',
|
|
542
|
+
'notify.micErrorNotAllowed': 'Microphone access denied. Please allow microphone access in your browser settings.',
|
|
543
|
+
'notify.micErrorNoSpeech': 'No speech detected. Please speak louder or closer to the microphone.',
|
|
544
|
+
'notify.micRetrying': 'Network error, retrying...',
|
|
545
|
+
'countdown.autocompletingIn': 'AutoComplete in',
|
|
546
|
+
'countdown.cancel': 'Cancel',
|
|
547
|
+
'countdown.now': 'Now',
|
|
548
|
+
'countdown.seconds': 's'
|
|
411
549
|
},
|
|
412
550
|
fr: {
|
|
413
551
|
'newIssue.title': 'Nouveau ticket',
|
|
@@ -439,7 +577,20 @@ export function generateNewIssuePage(lang) {
|
|
|
439
577
|
'notify.error': 'Erreur',
|
|
440
578
|
'notify.titleRequired': 'Le titre est requis',
|
|
441
579
|
'notify.autocompleteSuccess': 'Champs remplis automatiquement !',
|
|
442
|
-
'notify.autocompleteTitleRequired': 'Entrez un titre d\\'abord'
|
|
580
|
+
'notify.autocompleteTitleRequired': 'Entrez un titre d\\'abord',
|
|
581
|
+
'mic.title': 'Dictée vocale',
|
|
582
|
+
'mic.titleRecording': 'Enregistrement... Cliquer pour arrêter',
|
|
583
|
+
'mic.notSupported': 'Reconnaissance vocale non supportée',
|
|
584
|
+
'notify.micNotSupported': 'La reconnaissance vocale n\\'est pas supportée par votre navigateur',
|
|
585
|
+
'notify.micError': 'Erreur de reconnaissance vocale',
|
|
586
|
+
'notify.micErrorNetwork': 'Erreur réseau : La reconnaissance vocale nécessite une connexion internet. Vérifiez votre connexion et réessayez.',
|
|
587
|
+
'notify.micErrorNotAllowed': 'Accès au microphone refusé. Veuillez autoriser l\\'accès au microphone dans les paramètres de votre navigateur.',
|
|
588
|
+
'notify.micErrorNoSpeech': 'Aucune parole détectée. Parlez plus fort ou rapprochez-vous du microphone.',
|
|
589
|
+
'notify.micRetrying': 'Erreur réseau, nouvelle tentative...',
|
|
590
|
+
'countdown.autocompletingIn': 'AutoComplete dans',
|
|
591
|
+
'countdown.cancel': 'Annuler',
|
|
592
|
+
'countdown.now': 'Maintenant',
|
|
593
|
+
'countdown.seconds': 's'
|
|
443
594
|
}
|
|
444
595
|
};
|
|
445
596
|
|
|
@@ -561,6 +712,7 @@ export function generateNewIssuePage(lang) {
|
|
|
561
712
|
currentLang = newLang;
|
|
562
713
|
localStorage.setItem(STORAGE_KEY, newLang);
|
|
563
714
|
updateLangUI();
|
|
715
|
+
updateMicButton();
|
|
564
716
|
}
|
|
565
717
|
});
|
|
566
718
|
});
|
|
@@ -639,8 +791,200 @@ export function generateNewIssuePage(lang) {
|
|
|
639
791
|
}
|
|
640
792
|
}
|
|
641
793
|
|
|
794
|
+
// Speech-to-text
|
|
795
|
+
let recognition = null;
|
|
796
|
+
let isRecording = false;
|
|
797
|
+
let autocompleteCountdownTimer = null;
|
|
798
|
+
let autocompleteCountdownInterval = null;
|
|
799
|
+
const AUTOCOMPLETE_DELAY_SECONDS = 3;
|
|
800
|
+
let speechRetryCount = 0;
|
|
801
|
+
const MAX_SPEECH_RETRIES = 2;
|
|
802
|
+
const SPEECH_RETRY_DELAY_MS = 1000;
|
|
803
|
+
|
|
804
|
+
function isSpeechSupported() {
|
|
805
|
+
return 'SpeechRecognition' in window || 'webkitSpeechRecognition' in window;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
function initSpeechRecognition() {
|
|
809
|
+
if (!isSpeechSupported()) return null;
|
|
810
|
+
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
811
|
+
const rec = new SpeechRecognition();
|
|
812
|
+
rec.continuous = true;
|
|
813
|
+
rec.interimResults = true;
|
|
814
|
+
rec.lang = currentLang === 'fr' ? 'fr-FR' : 'en-US';
|
|
815
|
+
return rec;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
function updateMicButton() {
|
|
819
|
+
const btn = document.getElementById('btn-mic');
|
|
820
|
+
if (!isSpeechSupported()) {
|
|
821
|
+
btn.disabled = true;
|
|
822
|
+
btn.title = t('mic.notSupported');
|
|
823
|
+
} else {
|
|
824
|
+
btn.disabled = false;
|
|
825
|
+
btn.title = isRecording ? t('mic.titleRecording') : t('mic.title');
|
|
826
|
+
btn.classList.toggle('recording', isRecording);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
function handleSpeechResult(event, titleInput, state) {
|
|
831
|
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
832
|
+
const result = event.results[i];
|
|
833
|
+
if (result.isFinal) {
|
|
834
|
+
const text = result[0].transcript;
|
|
835
|
+
state.finalTranscript += (state.finalTranscript ? ' ' : '') + text;
|
|
836
|
+
titleInput.value = state.finalTranscript;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function getErrorMessage(errorType) {
|
|
842
|
+
switch (errorType) {
|
|
843
|
+
case 'network':
|
|
844
|
+
return t('notify.micErrorNetwork');
|
|
845
|
+
case 'not-allowed':
|
|
846
|
+
case 'service-not-allowed':
|
|
847
|
+
return t('notify.micErrorNotAllowed');
|
|
848
|
+
case 'no-speech':
|
|
849
|
+
return t('notify.micErrorNoSpeech');
|
|
850
|
+
case 'aborted':
|
|
851
|
+
return null; // Don't show notification for aborted
|
|
852
|
+
default:
|
|
853
|
+
return t('notify.micError') + ': ' + errorType;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function handleSpeechError(event) {
|
|
858
|
+
const errorType = event.error;
|
|
859
|
+
|
|
860
|
+
// Handle network errors with retry
|
|
861
|
+
if (errorType === 'network' && speechRetryCount < MAX_SPEECH_RETRIES) {
|
|
862
|
+
speechRetryCount++;
|
|
863
|
+
showNotification(t('notify.micRetrying') + ' (' + speechRetryCount + '/' + MAX_SPEECH_RETRIES + ')', true);
|
|
864
|
+
|
|
865
|
+
// Retry after a delay
|
|
866
|
+
setTimeout(function() {
|
|
867
|
+
if (isRecording) {
|
|
868
|
+
recognition = initSpeechRecognition();
|
|
869
|
+
if (recognition) {
|
|
870
|
+
const titleInput = document.getElementById('issue-title');
|
|
871
|
+
const state = { finalTranscript: titleInput.value };
|
|
872
|
+
recognition.onresult = function(event) { handleSpeechResult(event, titleInput, state); };
|
|
873
|
+
recognition.onerror = handleSpeechError;
|
|
874
|
+
recognition.onend = handleSpeechEnd;
|
|
875
|
+
try {
|
|
876
|
+
recognition.start();
|
|
877
|
+
} catch (e) {
|
|
878
|
+
// If start fails, show the network error
|
|
879
|
+
showNotification(getErrorMessage('network'), true);
|
|
880
|
+
isRecording = false;
|
|
881
|
+
updateMicButton();
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}, SPEECH_RETRY_DELAY_MS);
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// Show appropriate error message
|
|
890
|
+
const errorMessage = getErrorMessage(errorType);
|
|
891
|
+
if (errorMessage) {
|
|
892
|
+
showNotification(errorMessage, true);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// Reset state
|
|
896
|
+
isRecording = false;
|
|
897
|
+
speechRetryCount = 0;
|
|
898
|
+
updateMicButton();
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function handleSpeechEnd() {
|
|
902
|
+
isRecording = false;
|
|
903
|
+
updateMicButton();
|
|
904
|
+
const title = document.getElementById('issue-title').value.trim();
|
|
905
|
+
if (title) {
|
|
906
|
+
startAutocompleteCountdown();
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
function startAutocompleteCountdown() {
|
|
911
|
+
const countdown = document.getElementById('autocomplete-countdown');
|
|
912
|
+
const timerEl = document.getElementById('countdown-timer');
|
|
913
|
+
const progressBar = document.getElementById('countdown-progress-bar');
|
|
914
|
+
|
|
915
|
+
let remaining = AUTOCOMPLETE_DELAY_SECONDS;
|
|
916
|
+
timerEl.textContent = remaining + t('countdown.seconds');
|
|
917
|
+
progressBar.style.width = '100%';
|
|
918
|
+
countdown.classList.add('show');
|
|
919
|
+
|
|
920
|
+
autocompleteCountdownInterval = setInterval(function() {
|
|
921
|
+
remaining -= 0.1;
|
|
922
|
+
const percentage = (remaining / AUTOCOMPLETE_DELAY_SECONDS) * 100;
|
|
923
|
+
progressBar.style.width = percentage + '%';
|
|
924
|
+
if (remaining <= 0) {
|
|
925
|
+
remaining = 0;
|
|
926
|
+
}
|
|
927
|
+
timerEl.textContent = Math.ceil(remaining) + t('countdown.seconds');
|
|
928
|
+
}, 100);
|
|
929
|
+
|
|
930
|
+
autocompleteCountdownTimer = setTimeout(function() {
|
|
931
|
+
hideAutocompleteCountdown();
|
|
932
|
+
autocomplete();
|
|
933
|
+
}, AUTOCOMPLETE_DELAY_SECONDS * 1000);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
function hideAutocompleteCountdown() {
|
|
937
|
+
const countdown = document.getElementById('autocomplete-countdown');
|
|
938
|
+
countdown.classList.remove('show');
|
|
939
|
+
if (autocompleteCountdownTimer) {
|
|
940
|
+
clearTimeout(autocompleteCountdownTimer);
|
|
941
|
+
autocompleteCountdownTimer = null;
|
|
942
|
+
}
|
|
943
|
+
if (autocompleteCountdownInterval) {
|
|
944
|
+
clearInterval(autocompleteCountdownInterval);
|
|
945
|
+
autocompleteCountdownInterval = null;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
function cancelAutocompleteCountdown() {
|
|
950
|
+
hideAutocompleteCountdown();
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function triggerAutocompleteNow() {
|
|
954
|
+
hideAutocompleteCountdown();
|
|
955
|
+
autocomplete();
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
function toggleSpeechToText() {
|
|
959
|
+
if (!isSpeechSupported()) {
|
|
960
|
+
showNotification(t('notify.micNotSupported'), true);
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (isRecording && recognition) {
|
|
965
|
+
recognition.stop();
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
recognition = initSpeechRecognition();
|
|
970
|
+
if (!recognition) return;
|
|
971
|
+
|
|
972
|
+
const titleInput = document.getElementById('issue-title');
|
|
973
|
+
const state = { finalTranscript: titleInput.value };
|
|
974
|
+
|
|
975
|
+
recognition.onresult = function(event) { handleSpeechResult(event, titleInput, state); };
|
|
976
|
+
recognition.onerror = handleSpeechError;
|
|
977
|
+
recognition.onend = handleSpeechEnd;
|
|
978
|
+
|
|
979
|
+
speechRetryCount = 0; // Reset retry count on new recording
|
|
980
|
+
recognition.start();
|
|
981
|
+
isRecording = true;
|
|
982
|
+
updateMicButton();
|
|
983
|
+
}
|
|
984
|
+
|
|
642
985
|
// Init
|
|
643
986
|
updateLangUI();
|
|
987
|
+
updateMicButton();
|
|
644
988
|
</script>
|
|
645
989
|
</body>
|
|
646
990
|
</html>`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-issue.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/new-issue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAErE,OAAO;cACK,IAAI
|
|
1
|
+
{"version":3,"file":"new-issue.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/new-issue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAErE,OAAO;cACK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkbJ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAkB,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAgiBjJ,CAAC;AACT,CAAC"}
|