cli-jaw 1.7.30 → 1.7.31

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 (70) hide show
  1. package/dist/server.js +9 -1
  2. package/dist/server.js.map +1 -1
  3. package/dist/src/agent/events.js +7 -3
  4. package/dist/src/agent/events.js.map +1 -1
  5. package/dist/src/agent/lifecycle-handler.js +54 -6
  6. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  7. package/dist/src/agent/spawn.js +37 -28
  8. package/dist/src/agent/spawn.js.map +1 -1
  9. package/dist/src/cli/claude-models.js +16 -13
  10. package/dist/src/cli/claude-models.js.map +1 -1
  11. package/dist/src/cli/handlers-runtime.js +21 -5
  12. package/dist/src/cli/handlers-runtime.js.map +1 -1
  13. package/dist/src/core/compact.js +55 -4
  14. package/dist/src/core/compact.js.map +1 -1
  15. package/dist/src/core/main-session.js +50 -6
  16. package/dist/src/core/main-session.js.map +1 -1
  17. package/dist/src/core/runtime-settings.js +33 -3
  18. package/dist/src/core/runtime-settings.js.map +1 -1
  19. package/dist/src/memory/runtime.js +19 -2
  20. package/dist/src/memory/runtime.js.map +1 -1
  21. package/dist/src/memory/worklog.js +25 -2
  22. package/dist/src/memory/worklog.js.map +1 -1
  23. package/dist/src/orchestrator/distribute.js +6 -3
  24. package/dist/src/orchestrator/distribute.js.map +1 -1
  25. package/dist/src/orchestrator/pipeline.js +17 -3
  26. package/dist/src/orchestrator/pipeline.js.map +1 -1
  27. package/dist/src/orchestrator/state-machine.js +83 -6
  28. package/dist/src/orchestrator/state-machine.js.map +1 -1
  29. package/dist/src/prompt/builder.js +17 -1
  30. package/dist/src/prompt/builder.js.map +1 -1
  31. package/dist/src/prompt/soul-bootstrap-prompt.js +5 -2
  32. package/dist/src/prompt/soul-bootstrap-prompt.js.map +1 -1
  33. package/dist/src/prompt/templates/orchestration.md +21 -0
  34. package/dist/src/routes/jaw-memory.js +4 -2
  35. package/dist/src/routes/jaw-memory.js.map +1 -1
  36. package/dist/src/routes/orchestrate.js +81 -7
  37. package/dist/src/routes/orchestrate.js.map +1 -1
  38. package/package.json +1 -1
  39. package/public/css/markdown.css +25 -0
  40. package/public/dist/assets/constants-2eOyiA6N.js +1 -0
  41. package/public/dist/assets/{employees-DEAsLiuH.js → employees-lW91UfoX.js} +7 -7
  42. package/public/dist/assets/index-CHueOQjp.js +32 -0
  43. package/public/dist/assets/{index-CmogXq5K.css → index-DVAk6-ox.css} +1 -1
  44. package/public/dist/assets/memory-COqTr9_E.js +1 -0
  45. package/public/dist/assets/{memory-Da0JJE5y.js → memory-D6jlo74U.js} +9 -9
  46. package/public/dist/assets/{render-DtJkRgLi.js → render-DHNtorUk.js} +16 -11
  47. package/public/dist/assets/settings-BIbs7gYB.js +1 -0
  48. package/public/dist/assets/{settings-DO7YNchG.js → settings-BXig0Fq7.js} +13 -13
  49. package/public/dist/assets/skills-BRn8vpdf.js +1 -0
  50. package/public/dist/assets/{skills-_cb0eUR_.js → skills-BrXYVU1p.js} +6 -6
  51. package/public/dist/assets/{slash-commands-BnZWVFWF.js → slash-commands-DAObyBB2.js} +1 -1
  52. package/public/dist/assets/slash-commands-zrcxH6-n.js +1 -0
  53. package/public/dist/assets/ui-BUfs2YT6.js +130 -0
  54. package/public/dist/assets/ui-CMkGUYqS.js +1 -0
  55. package/public/dist/assets/{ws-DQw_dOlE.js → ws-wAkHWH8w.js} +7 -7
  56. package/public/dist/index.html +2 -2
  57. package/public/js/constants.ts +1 -1
  58. package/public/js/features/employees.ts +14 -7
  59. package/public/js/features/settings-core.ts +13 -6
  60. package/public/js/main.ts +6 -1
  61. package/public/js/render.ts +64 -6
  62. package/public/js/ui.ts +15 -0
  63. package/public/dist/assets/constants-CAm2valm.js +0 -1
  64. package/public/dist/assets/index-DEsjdzlb.js +0 -32
  65. package/public/dist/assets/memory-DxI8fiPv.js +0 -1
  66. package/public/dist/assets/settings-DyrQgYnt.js +0 -1
  67. package/public/dist/assets/skills-CyNBQeIq.js +0 -1
  68. package/public/dist/assets/slash-commands-BuZgvznw.js +0 -1
  69. package/public/dist/assets/ui-3SVmPEWt.js +0 -130
  70. package/public/dist/assets/ui-b08BeDGQ.js +0 -1
@@ -25,9 +25,9 @@
25
25
  href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Outfit:wght@400;500;600;700&display=swap"
26
26
  rel="stylesheet">
27
27
  <!-- Vite handles module bundling in dev (HMR) and production (build) -->
28
- <script type="module" crossorigin src="/dist/assets/index-DEsjdzlb.js"></script>
28
+ <script type="module" crossorigin src="/dist/assets/index-CHueOQjp.js"></script>
29
29
  <link rel="stylesheet" crossorigin href="/dist/assets/vendor-render-Bjnw0wQ6.css">
30
- <link rel="stylesheet" crossorigin href="/dist/assets/index-CmogXq5K.css">
30
+ <link rel="stylesheet" crossorigin href="/dist/assets/index-DVAk6-ox.css">
31
31
  </head>
32
32
 
33
33
  <body>
@@ -14,7 +14,7 @@ const FALLBACK_CLI_REGISTRY: CliRegistry = {
14
14
  claude: {
15
15
  label: 'Claude',
16
16
  efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
17
- models: ['claude-opus-4-6[1m]', 'claude-opus-4-6', 'claude-opus-4-7[1m]', 'claude-opus-4-7', 'claude-sonnet-4-6[1m]', 'claude-sonnet-4-6', 'claude-haiku-4-5'],
17
+ models: ['opus', 'sonnet', 'sonnet[1m]', 'haiku'],
18
18
  },
19
19
  codex: {
20
20
  label: 'Codex',
@@ -45,18 +45,25 @@ const PHASE_COLORS: Record<string, string> = {
45
45
 
46
46
  function normalizeEmployeeModel(cli: string, model?: string): string {
47
47
  if (cli !== 'claude') return model || 'default';
48
- switch ((model || '').trim()) {
49
- case 'sonnet': return 'claude-sonnet-4-6';
50
- case 'opus': return 'claude-opus-4-6';
51
- case 'sonnet[1m]': return 'claude-sonnet-4-6[1m]';
52
- case 'opus[1m]': return 'claude-opus-4-6[1m]';
53
- default: return model || 'default';
48
+ const trimmed = (model || '').trim();
49
+ switch (trimmed) {
50
+ case 'claude-opus-4-6[1m]':
51
+ case 'claude-opus-4-6':
52
+ case 'claude-opus-4-7[1m]':
53
+ case 'claude-opus-4-7':
54
+ case 'opus[1m]': return 'opus';
55
+ case 'claude-sonnet-4-6[1m]': return 'sonnet[1m]';
56
+ case 'claude-sonnet-4-6':
57
+ case 'claude-sonnet-4-5': return 'sonnet';
58
+ case 'claude-haiku-4-5':
59
+ case 'claude-haiku-4-5-20251001': return 'haiku';
60
+ default: return trimmed || 'default';
54
61
  }
55
62
  }
56
63
 
57
64
  function getDefaultEmployeeModel(cli: string, models: string[]): string {
58
65
  if (cli !== 'claude') return 'default';
59
- if (models.includes('claude-sonnet-4-6')) return 'claude-sonnet-4-6';
66
+ if (models.includes('sonnet')) return 'sonnet';
60
67
  return models[0] || 'default';
61
68
  }
62
69
 
@@ -75,12 +75,19 @@ function syncCliOptionSelects(settings: SettingsData | null = null): void {
75
75
 
76
76
  function normalizeModelForDisplay(cli: string, model: string): string {
77
77
  if (cli !== 'claude') return model;
78
- switch ((model || '').trim()) {
79
- case 'sonnet': return 'claude-sonnet-4-6';
80
- case 'opus': return 'claude-opus-4-6';
81
- case 'sonnet[1m]': return 'claude-sonnet-4-6[1m]';
82
- case 'opus[1m]': return 'claude-opus-4-6[1m]';
83
- default: return model;
78
+ const trimmed = (model || '').trim();
79
+ switch (trimmed) {
80
+ case 'claude-opus-4-6[1m]':
81
+ case 'claude-opus-4-6':
82
+ case 'claude-opus-4-7[1m]':
83
+ case 'claude-opus-4-7':
84
+ case 'opus[1m]': return 'opus';
85
+ case 'claude-sonnet-4-6[1m]': return 'sonnet[1m]';
86
+ case 'claude-sonnet-4-6':
87
+ case 'claude-sonnet-4-5': return 'sonnet';
88
+ case 'claude-haiku-4-5':
89
+ case 'claude-haiku-4-5-20251001': return 'haiku';
90
+ default: return trimmed;
84
91
  }
85
92
  }
86
93
 
package/public/js/main.ts CHANGED
@@ -39,6 +39,7 @@ window.addEventListener('error', (e) => {
39
39
 
40
40
  import { connect } from './ws.js';
41
41
  import { switchTab, handleSave, loadMessages, initMsgCopy } from './ui.js';
42
+ import { prewarmMermaid } from './render.js';
42
43
  import { sendMessage, handleKey, clearAttachedFiles, removeAttachedFile, clearChat, initDragDrop, initAutoResize } from './features/chat.js';
43
44
  import {
44
45
  loadCommands, update as updateSlashDropdown, handleKeydown as handleSlashKeydown,
@@ -68,7 +69,7 @@ import {
68
69
  openMemoryModal, closeMemoryModal, switchMemTab, setMemEnabled,
69
70
  saveMemSettings, deleteMemFile, viewMemFile,
70
71
  rerunAdvancedBootstrap, reindexAdvancedMemory, upgradeSoulMemory, synthesizeSoul, openCorruptedFolder,
71
- bindAdvancedProviderUi, triggerFlushNow
72
+ bindAdvancedProviderUi, triggerFlushNow, refreshMemorySidebar
72
73
  } from './features/memory.js';
73
74
  import { state } from './state.js';
74
75
  import { loadCliRegistry, getCliKeys } from './constants.js';
@@ -458,6 +459,7 @@ async function bootstrap(): Promise<void> {
458
459
  // loadMessages() is handled by ws.js onopen (clear + reload)
459
460
  loadEmployees();
460
461
  initHeartbeatBadge();
462
+ void refreshMemorySidebar();
461
463
  initAppName();
462
464
  await initAvatar();
463
465
  initSidebar();
@@ -465,6 +467,9 @@ async function bootstrap(): Promise<void> {
465
467
  initGestures();
466
468
  try { sessionStorage.removeItem(STALE_BUNDLE_RELOAD_KEY); } catch {}
467
469
 
470
+ // Phase 127-F2: prewarm Mermaid at idle so first diagram renders fast
471
+ prewarmMermaid();
472
+
468
473
  // Register Service Worker (production only — Vite HMR handles dev)
469
474
  if ('serviceWorker' in navigator && !import.meta.env.DEV) {
470
475
  navigator.serviceWorker.register('/sw.js').catch(() => {});
@@ -169,7 +169,7 @@ export function sanitizeHtml(html: string): string {
169
169
  'background'], // legacy HTML attr that triggers remote fetch
170
170
  ADD_TAGS: ['use'],
171
171
  ADD_ATTR: ['aria-hidden', 'xmlns', 'viewBox', 'role', 'aria-label',
172
- 'data-jaw-svg', 'data-jaw-kind'],
172
+ 'data-jaw-svg', 'data-jaw-kind', 'data-mermaid-code-raw'],
173
173
  });
174
174
  }
175
175
 
@@ -390,7 +390,9 @@ function renderMermaidError(el: HTMLElement, code: string, errMsg: string): void
390
390
 
391
391
  async function renderSingleMermaidImpl(el: HTMLElement): Promise<void> {
392
392
  el.classList.remove('mermaid-pending');
393
- const code = el.textContent || '';
393
+ // Phase 127-F1: raw source lives in data attribute (skeleton DOM has no source text).
394
+ const encoded = el.dataset.mermaidCodeRaw || '';
395
+ const code = encoded ? decodeURIComponent(encoded) : (el.textContent || '');
394
396
  el.dataset.mermaidCode = code;
395
397
  const id = `mermaid-${++mermaidId}`;
396
398
  try {
@@ -412,19 +414,67 @@ async function renderSingleMermaidImpl(el: HTMLElement): Promise<void> {
412
414
  // Serialise renders to prevent concurrent Mermaid operations from
413
415
  // corrupting shared internal state (theme config, diagram registry).
414
416
  function renderSingleMermaid(el: HTMLElement): void {
415
- mermaidQueue = mermaidQueue.then(() => renderSingleMermaidImpl(el));
417
+ // Phase 127-N2: synchronous queued guard prevents duplicate enqueueing when
418
+ // renderMermaidBlocks immediate mode fires repeatedly (e.g. VS onPostRender
419
+ // on every scroll). Class/dataset is set right away so the next pass skips.
420
+ if (el.dataset.mermaidQueued === '1') return;
421
+ el.dataset.mermaidQueued = '1';
422
+ // Phase 127-F6: .catch tail keeps the queue alive after any rejection so
423
+ // one bad render cannot permanently block subsequent diagrams.
424
+ mermaidQueue = mermaidQueue
425
+ .then(() => renderSingleMermaidImpl(el))
426
+ .catch(err => {
427
+ console.error('[mermaid:queue] render failed, keeping queue alive:', err);
428
+ });
416
429
  }
417
430
 
418
- async function renderMermaidBlocks(scope?: HTMLElement | Document): Promise<void> {
431
+ /**
432
+ * Phase 127-F5: exposed so streaming finalize / virtual-scroll hooks can push
433
+ * new mermaid blocks through the pipeline without waiting for schedulePostRender.
434
+ *
435
+ * @param scope DOM subtree to scan (defaults to whole document)
436
+ * @param opts.immediate if true, render blocks already in (or near) viewport
437
+ * right now instead of waiting for the observer.
438
+ */
439
+ export async function renderMermaidBlocks(
440
+ scope?: HTMLElement | Document,
441
+ opts: { immediate?: boolean } = {},
442
+ ): Promise<void> {
419
443
  const root = scope || document;
420
- const pending = root.querySelectorAll('.mermaid-pending');
444
+ const pending = root.querySelectorAll<HTMLElement>('.mermaid-pending');
421
445
  if (!pending.length) return;
422
446
  ensureMermaidObserver();
423
447
  for (const el of pending) {
448
+ if (el.dataset.mermaidQueued === '1') continue; // N2 guard
449
+ if (opts.immediate) {
450
+ const rect = el.getBoundingClientRect();
451
+ const vh = window.innerHeight || document.documentElement.clientHeight;
452
+ const inView = rect.bottom >= -200 && rect.top <= vh + 200;
453
+ if (inView) {
454
+ mermaidObserver!.unobserve(el);
455
+ renderSingleMermaid(el);
456
+ continue;
457
+ }
458
+ }
424
459
  mermaidObserver!.observe(el);
425
460
  }
426
461
  }
427
462
 
463
+ /**
464
+ * Phase 127-F2: prewarm Mermaid module at idle time so the first diagram's
465
+ * cold-start does not block rendering. Safe to call multiple times.
466
+ */
467
+ export function prewarmMermaid(): void {
468
+ if (mermaidModule) return;
469
+ const run = () => { void ensureMermaidLoaded().catch(() => { /* silent */ }); };
470
+ if (typeof (window as unknown as { requestIdleCallback?: unknown }).requestIdleCallback === 'function') {
471
+ (window as unknown as { requestIdleCallback: (cb: () => void, opts?: { timeout?: number }) => void })
472
+ .requestIdleCallback(run, { timeout: 2000 });
473
+ } else {
474
+ setTimeout(run, 500);
475
+ }
476
+ }
477
+
428
478
  // ── marked.js configuration (ES module — always available) ──
429
479
  let markedReady = false;
430
480
 
@@ -436,7 +486,15 @@ function ensureMarked(): boolean {
436
486
  // Code blocks: highlight.js + mermaid + diagram-html detection
437
487
  renderer.code = function ({ text, lang }: { text: string; lang?: string }) {
438
488
  if (lang === 'mermaid') {
439
- return `<div class="mermaid-container mermaid-pending">${escapeHtml(text)}</div>`;
489
+ // Phase 127-F1: store raw source in data attribute, render a skeleton
490
+ // placeholder so users never see raw Mermaid syntax while the diagram loads.
491
+ const encodedCode = encodeURIComponent(text);
492
+ return `<div class="mermaid-container mermaid-pending" data-mermaid-code-raw="${encodedCode}" role="status" aria-label="Diagram loading">
493
+ <div class="mermaid-skeleton">
494
+ <div class="mermaid-skeleton-spinner"></div>
495
+ <div class="mermaid-skeleton-text">Rendering diagram…</div>
496
+ </div>
497
+ </div>`;
440
498
  }
441
499
  // diagram-html: encode as base64, Phase 2 activateWidgets() inflates to sandboxed iframe
442
500
  if (lang?.trim().toLowerCase() === 'diagram-html') {
package/public/js/ui.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  // ── UI Utilities ──
2
2
  import { state } from './state.js';
3
3
  import { renderMarkdown, escapeHtml, stripOrchestration, linkifyFilePaths } from './render.js';
4
+ import { renderMermaidBlocks } from './render.js';
4
5
  import { generateId } from './uuid.js';
5
6
  import { getAppName } from './features/appname.js';
6
7
  import { getAgentAvatarMarkup, getUserAvatarMarkup } from './features/avatar.js';
@@ -291,6 +292,12 @@ export function finalizeAgent(text: string, toolLog?: ToolLogEntry[]): void {
291
292
  if (content) content.innerHTML = toolHtml + renderMarkdown(finalText);
292
293
  if (content) content.setAttribute('data-raw', stripOrchestration(finalText));
293
294
  if (content) activateWidgets(content as HTMLElement);
295
+ // Phase 127-F5: kick off mermaid render immediately for this message's scope —
296
+ // bypasses the 100ms postRender debounce so the just-finished answer doesn't
297
+ // sit in the "Rendering diagram…" skeleton longer than needed.
298
+ if (content) {
299
+ void renderMermaidBlocks(content as HTMLElement, { immediate: true });
300
+ }
294
301
 
295
302
  // Promote streaming div from real DOM into VS if active.
296
303
  // Revert activated widgets back to pending state so VS can
@@ -396,6 +403,8 @@ export function addMessage(role: string, text: string, cli?: string | null): HTM
396
403
  vs.onPostRender = (viewport: HTMLElement) => {
397
404
  activateWidgets(viewport);
398
405
  linkifyFilePaths(viewport);
406
+ // Phase 127-F7b: render mermaid in newly mounted VS viewport
407
+ void renderMermaidBlocks(viewport, { immediate: true });
399
408
  };
400
409
  }
401
410
  }
@@ -509,6 +518,8 @@ function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>)
509
518
  el.innerHTML = raw ? renderMarkdown(raw) : '';
510
519
  el.classList.remove('lazy-pending');
511
520
  activateWidgets(el);
521
+ // Phase 127-F7a: lazy-rendered blocks (fresh markdown just converted)
522
+ void renderMermaidBlocks(el, { immediate: true });
512
523
  const msgEl = el.closest('[data-vs-idx]') as HTMLElement | null;
513
524
  if (msgEl) {
514
525
  const idx = Number(msgEl.dataset.vsIdx);
@@ -519,6 +530,10 @@ function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>)
519
530
  vs.onPostRender = (viewport: HTMLElement) => {
520
531
  activateWidgets(viewport);
521
532
  linkifyFilePaths(viewport);
533
+ // Phase 127-F7b: mounted viewport scope — handles VS items that arrive
534
+ // pre-rendered with .mermaid-pending (buildVirtualHistoryItems path,
535
+ // addMessage append path). These are NOT .lazy-pending so F7a misses them.
536
+ void renderMermaidBlocks(viewport, { immediate: true });
522
537
  };
523
538
  }
524
539
 
@@ -1 +0,0 @@
1
- import{t as e}from"./api-DygAf_G_.js";var t={claude:{label:`Claude`,efforts:[`low`,`medium`,`high`,`xhigh`,`max`],models:[`claude-opus-4-6[1m]`,`claude-opus-4-6`,`claude-opus-4-7[1m]`,`claude-opus-4-7`,`claude-sonnet-4-6[1m]`,`claude-sonnet-4-6`,`claude-haiku-4-5`]},codex:{label:`Codex`,efforts:[`low`,`medium`,`high`,`xhigh`],models:[`gpt-5.5`,`gpt-5.4`,`gpt-5.3-codex`,`gpt-5.3-codex-spark`,`gpt-5.2-codex`,`gpt-5.1-codex-max`,`gpt-5.1-codex-mini`]},gemini:{label:`Gemini`,efforts:[],models:[`gemini-3.0-pro-preview`,`gemini-3.1-pro-preview`,`gemini-2.5-pro`,`gemini-3-flash-preview`,`gemini-2.5-flash`]},opencode:{label:`OpenCode`,efforts:[`minimal`,`low`,`high`,`max`],models:[`anthropic/claude-opus-4-6-thinking`,`anthropic/claude-sonnet-4-6-thinking`,`anthropic/claude-sonnet-4-6`,`openai/gpt-5.4-xhigh`,`openai/gpt-5.4-high`,`openai/gpt-5.3-codex-xhigh`,`openai/gpt-5.3-codex-high`,`opencode/big-pickle`,`opencode-go/glm-5`,`opencode-go/glm-5.1`,`opencode-go/kimi-k2.5`,`opencode-go/kimi-k2.6`,`opencode-go/mimo-v2-pro`,`opencode-go/mimo-v2-omni`,`opencode-go/minimax-m2.5`,`opencode-go/minimax-m2.7`,`opencode/GLM-5 Free`,`opencode/MiniMax M2.5 Free`,`opencode/Kimi K2.5 Free`,`opencode/GPT 5 Nano Free`,`opencode/Grok Code Fast 1 Free`]},copilot:{label:`Copilot`,efforts:[`low`,`medium`,`high`],effortNote:`-> ~/.copilot/config.json`,models:[`gpt-5.5`,`claude-sonnet-4.6`,`claude-haiku-4.5`,`gpt-5.4`,`gpt-5.3-codex`,`gpt-5.2-codex`,`gpt-5.1-codex`,`gpt-4.1`,`gpt-5-mini`,`gemini-3-pro-preview`]}};function n(e){let t={};for(let[n,r]of Object.entries(e))t[n]=Array.isArray(r?.models)?[...r.models]:[];return t}function r(e){let t={};for(let[n,r]of Object.entries(e||{})){if(!r||typeof r!=`object`)continue;let e=r,i={label:e.label||n,efforts:Array.isArray(e.efforts)?[...e.efforts]:[],models:Array.isArray(e.models)?[...e.models]:[]};typeof e.effortNote==`string`&&e.effortNote.trim()&&(i.effortNote=e.effortNote),t[n]=i}return t}var i=r(t),a=Object.keys(i),o=n(i);function s(e){let t=r(e);return Object.keys(t).length?(i=t,a=Object.keys(t),o=n(t),!0):!1}async function c(){try{let t=await e(`/api/cli-registry`);if(!t||!s(t))throw Error(`invalid registry`)}catch(e){console.warn(`[cli-registry] fallback:`,e.message),s(t)}return i}function l(){return a}function u(e){return i[e]||null}var d=[{value:`frontend`,labelKey:`role.label.frontend`,label:`Frontend`,prompt:`Frontend employee — UI/UX, CSS, components`,skill:`dev-frontend`},{value:`backend`,labelKey:`role.label.backend`,label:`Backend`,prompt:`Backend employee — API, DB, server logic`,skill:`dev-backend`},{value:`data`,labelKey:`role.label.data`,label:`Data`,prompt:`Data employee — data pipeline, analysis, ML`,skill:`dev-data`},{value:`docs`,labelKey:`role.label.docs`,label:`Docs`,prompt:`Docs employee — documentation, README, API docs`,skill:`documentation`},{value:`custom`,labelKey:`role.label.custom`,label:`Custom...`,prompt:``,skill:null}];export{c as a,u as i,d as n,l as r,o as t};
@@ -1,32 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-render-Bjnw0wQ6.css"])))=>i.map(i=>d[i]);
2
- import{n as e,t}from"./vendor-render-D2YP6GiF.js";import{t as n}from"./state-O6NVkWcL.js";import{i as r,n as i,r as a,t as o}from"./api-DygAf_G_.js";import{Z as s}from"./vendor-mermaid-UktBx7L0.js";import{a as c,f as l,h as u,m as ee,n as d,p as te,s as f,t as ne,u as re}from"./render-DtJkRgLi.js";import{_ as ie,b as ae,h as oe,l as se,n as p,s as ce,t as m,v as le,y as ue}from"./ui-3SVmPEWt.js";import{a as h,n as de}from"./idb-cache-DbK81tgv.js";import{r as fe,t as pe}from"./ws-DQw_dOlE.js";import{t as me}from"./locale-CxI5nTcf.js";import{a as he,i as ge,n as _e,o as ve,r as ye,t as be}from"./slash-commands-BnZWVFWF.js";import{i as xe,t as Se}from"./skills-_cb0eUR_.js";import{a as Ce,r as we}from"./constants-CAm2valm.js";import{A as Te,D as Ee,E as De,F as Oe,I as ke,M as Ae,N as je,O as g,P as Me,S as Ne,_ as Pe,a as Fe,c as Ie,f as Le,g as Re,h as ze,i as Be,j as Ve,k as He,l as Ue,m as We,n as Ge,o as Ke,p as qe,r as Je,s as Ye,t as _,u as Xe,v,w as Ze,x as Qe}from"./settings-DO7YNchG.js";import{c as y,d as $e,f as et,i as tt,l as nt,m as rt,n as it,o as at,p as ot,r as st,s as ct,t as lt,u as b}from"./memory-Da0JJE5y.js";var x=[];function ut(e){return/^\/compact(?:\s|$)/i.test(String(e||``).trim())?300*1e3:1e4}var S=!1;async function C(){let e=document.getElementById(`chatInput`),t=document.getElementById(`btnSend`);if(!e||!t)return;let o=document.activeElement===t;if(t.classList.contains(`stop-mode`)&&o&&!e.value.trim()&&!n.attachedFiles.length){i(`/api/stop`,`POST`);return}if(S)return;let c=e.value.trim();if(!c&&!n.attachedFiles.length)return;S=!0;let l=t,ee=l.disabled;l.disabled=!0;try{let t=c.slice(1).trim().split(/\s+/)[0]||``,i=t.includes(`/`)||t.includes(`\\`);if(c.startsWith(`/`)&&!n.attachedFiles.length&&!i){e.value=``,D(),be();try{let e,t,n=ut(c);if(typeof AbortSignal?.timeout==`function`)e=AbortSignal.timeout(n);else{let r=new AbortController;e=r.signal,t=setTimeout(()=>r.abort(),n)}let i=me(),o=await r(),s=await fetch(`/api/command`,{method:`POST`,headers:{"Content-Type":`application/json`,"Accept-Language":i,...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify({text:c,locale:i}),signal:e});t&&clearTimeout(t);let l=await s.json().catch(()=>({}));if(l?.code===`not_command`){m(`user`,c),h({role:`user`,content:c,timestamp:Date.now()}),await a(`/api/message`,`POST`,{prompt:c});return}if(!s.ok&&!l?.text)throw Error(`HTTP ${s.status}`);if(l?.code===`clear_screen`){ne(),le().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``)}l?.text&&p(d(l.text),``,l.type)}catch(e){p(u(`chat.cmd.fail`,{msg:e.message}),``,`error`)}return}if(n.attachedFiles.length){let t=`📎 [${n.attachedFiles.map(e=>e.name).join(`, `)}] ${c}`;m(`user`,t),h({role:`user`,content:t,timestamp:Date.now()}),e.value=``,D();try{let e=(await Promise.all(n.attachedFiles.map(e=>ft(e)))).map(e=>u(`chat.file.sent`,{path:e})).join(`
3
- `);c&&(e+=u(`chat.file.sentWithMsg`,{text:c})),T(),await a(`/api/message`,`POST`,{prompt:e})}catch(e){p(u(`chat.file.uploadFail`,{msg:e.message})),T()}}else{e.value=``,D();let t=await fetch(`/api/message`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:c})}),n=await t.json().catch(()=>({}));if(t.status===409&&n?.error===`duplicate`)return;if(!t.ok){p(`${f.error} ${d(n.error||u(`chat.requestFail`,{status:t.status}))}`,``,`error`);return}if(n.queued){let{updateQueueBadge:e}=await s(async()=>{let{updateQueueBadge:e}=await import(`./ui-b08BeDGQ.js`);return{updateQueueBadge:e}},__vite__mapDeps([0]));e(n.pending||1)}else n.continued?(m(`user`,c),h({role:`user`,content:c,timestamp:Date.now()}),p(u(`chat.continue`))):(m(`user`,c),h({role:`user`,content:c,timestamp:Date.now()}))}}finally{S=!1,l.disabled=ee}}function dt(e){e.key===`Enter`&&!e.shiftKey&&!e.isComposing&&(e.preventDefault(),C())}async function ft(e){let t=await fetch(`/api/upload`,{method:`POST`,headers:{"X-Filename":encodeURIComponent(e.name)},body:e});if(!t.ok)throw Error(`upload failed`);return(await t.json()).path}function w(e){for(let t of e)n.attachedFiles.some(e=>e.name===t.name)||n.attachedFiles.push(t);E(),document.getElementById(`chatInput`)?.focus()}function pt(e){n.attachedFiles.splice(e,1),E()}function T(){x.forEach(e=>URL.revokeObjectURL(e)),x=[],n.attachedFiles=[],E();let e=document.getElementById(`fileInput`);e&&(e.value=``)}function E(){let e=document.getElementById(`filePreview`),t=document.getElementById(`filePreviewList`);if(e){if(x.forEach(e=>URL.revokeObjectURL(e)),x=[],!n.attachedFiles.length){e.classList.remove(`visible`),t&&(t.innerHTML=``);return}e.classList.add(`visible`),t&&(t.innerHTML=n.attachedFiles.map((e,t)=>{let n=(e.size/1024).toFixed(1),r=e.type.startsWith(`image/`),i=``;if(r){let t=URL.createObjectURL(e);x.push(t),i=`<img src="${t}" class="file-chip-thumb" alt="">`}return`<div class="file-chip">
4
- ${i}
5
- <span class="file-chip-name">${f.paperclip} ${d(e.name)} (${n}KB)</span>
6
- <button class="file-chip-remove" data-file-idx="${t}" title="Remove">${f.close}</button>
7
- </div>`}).join(``))}}async function mt(){ne(),le().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``);let{cleanupToolActivity:t}=await s(async()=>{let{cleanupToolActivity:e}=await import(`./ui-b08BeDGQ.js`);return{cleanupToolActivity:e}},__vite__mapDeps([0]));t(),de().catch(()=>{})}var ht=0;function gt(e){ht||=requestAnimationFrame(()=>{ht=0,e.style.height=`auto`,e.style.height=e.scrollHeight+`px`})}function _t(){let e=document.getElementById(`chatInput`);e&&e.addEventListener(`input`,()=>gt(e))}function D(){let e=document.getElementById(`chatInput`);e&&(e.style.height=`auto`)}function vt(){let e=document.querySelector(`.chat-area`),t=document.getElementById(`dragOverlay`);if(!e||!t)return;let n=0;e.addEventListener(`dragenter`,e=>{e.preventDefault(),n++,t.classList.add(`visible`)}),e.addEventListener(`dragleave`,e=>{e.preventDefault(),n--,n<=0&&(n=0,t.classList.remove(`visible`))}),e.addEventListener(`dragover`,e=>e.preventDefault()),e.addEventListener(`drop`,e=>{e.preventDefault(),n=0,t.classList.remove(`visible`);let r=[...e.dataTransfer?.files||[]];r.length&&w(r)}),document.getElementById(`fileInput`)?.addEventListener(`change`,e=>{let t=e.target,n=[...t.files||[]];n.length&&w(n),t.value=``}),document.addEventListener(`paste`,e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e of t){if(e.kind!==`file`)continue;let t=e.getAsFile();if(t)if(!t.name||t.name===`image.png`){let e=new Date().toISOString().replace(/[:.]/g,`-`),r=t.type.split(`/`)[1]||`png`,i=new File([t],`pasted-${e}.${r}`,{type:t.type});n.push(i)}else n.push(t)}n.length&&(e.preventDefault(),w(n))})}async function yt(e,t,r){let i=document.getElementById(`chatInput`),o=i?.value.trim()||``,s=[...n.attachedFiles],c=[`🎤 [음성 메시지]`];s.length&&c.push(`📎 [${s.map(e=>e.name).join(`, `)}]`),o&&c.push(o),m(`user`,c.join(` `)),h({role:`user`,content:c.join(` `),timestamp:Date.now()}),i&&o&&(i.value=``,D()),s.length&&T();try{let n=await fetch(`/api/voice`,{method:`POST`,headers:{"Content-Type":r,"X-Voice-Ext":t,"X-STT-Only":`true`},body:e});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error||`HTTP ${n.status}`)}let i=await n.json().catch(()=>null);if(!i?.text)throw Error(`Empty STT result`);p(`${f.mic} STT (${d(i.engine||``)}, ${i.elapsed?.toFixed(1)}s): "${d(i.text.slice(0,100))}"`,``,`info`);let c=[];s.length&&(c=await Promise.all(s.map(e=>ft(e))));let l=[];for(let e of c)l.push(u(`chat.file.sent`,{path:e}));l.push(`🎤 ${i.text}`),o&&l.push(o),await a(`/api/message`,`POST`,{prompt:l.join(`
8
- `)})}catch(e){p(u(`voice.sttFail`,{msg:e.message}),``,`error`)}}var bt={sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},xt={jan:1,feb:2,mar:3,apr:4,may:5,jun:6,jul:7,aug:8,sep:9,oct:10,nov:11,dec:12};function St(e){let t=typeof e==`string`?e.trim():``;if(t)try{return new Intl.DateTimeFormat(`en-US`,{timeZone:t}).format(new Date),t}catch{return}}function Ct(e){let t=e&&typeof e==`object`?e:{},n=t.kind,r=typeof t.timeZone==`string`?t.timeZone.trim():``,i=St(t.timeZone);if(r&&!i)return{ok:!1,code:`invalid_timezone`,error:`invalid timeZone "${r}"`};if(n===`cron`){let e=typeof t.cron==`string`?t.cron.trim().replace(/\s+/g,` `):``;if(!e)return{ok:!1,code:`invalid_cron`,error:`cron expression required`};let n=wt(e);return n?{ok:!1,code:`invalid_cron`,error:n}:{ok:!0,schedule:i?{kind:`cron`,cron:e,timeZone:i}:{kind:`cron`,cron:e}}}if(n==null||n===`every`){let e=typeof t.minutes==`number`?t.minutes:Number(t.minutes);if(!Number.isInteger(e)||e<1)return{ok:!1,code:`invalid_minutes`,error:`minutes must be an integer >= 1`};let n=Math.max(1,Math.floor(e));return{ok:!0,schedule:i?{kind:`every`,minutes:n,timeZone:i}:{kind:`every`,minutes:n}}}return{ok:!1,code:`invalid_kind`,error:`invalid heartbeat schedule kind "${String(n)}"`}}function wt(e){try{let[t,n,r,i,a]=Tt(e);return O(t,{min:0,max:59}),O(n,{min:0,max:23}),O(r,{min:1,max:31}),O(i,{min:1,max:12,aliases:xt}),O(a,{min:0,max:7,aliases:bt,normalize:Ot}),null}catch(e){return e.message}}function Tt(e){let t=String(e||``).trim().replace(/\s+/g,` `).split(` `);if(t.length!==5)throw Error(`cron must have 5 fields, got ${t.length}`);return t}function O(e,t){for(let n of e.split(`,`))Et(n.trim(),t)}function Et(e,t){if(!e)throw Error(`empty cron segment`);let n=e;if(e.includes(`/`)){let[t,r,...i]=e.split(`/`);if(!t||!r||i.length>0)throw Error(`invalid cron step segment "${e}"`);n=t,Dt(r,`invalid cron step "${r}"`)}if(n!==`*`){if(n.includes(`-`)){let[e,r,...i]=n.split(`-`);if(!e||!r||i.length>0||k(e,t)>k(r,t))throw Error(`invalid cron range "${n}"`);return}k(n,t)}}function k(e,t){let n=e.trim().toLowerCase(),r=t.aliases?.[n]??Number(n);if(!Number.isInteger(r))throw Error(`invalid cron value "${e}"`);let i=t.normalize?t.normalize(r):r;if(!kt(i,t.min,t.max))throw Error(`cron value "${e}" out of range ${t.min}-${t.max}`);return i}function Dt(e,t){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw Error(t);return n}function Ot(e){return e===7?0:e}function kt(e,t,n){return e>=t&&e<=n}async function At(){n.heartbeatJobs=((await o(`/api/heartbeat`))?.jobs||[]).map(M),n.heartbeatErrors=P(n.heartbeatJobs),A(),document.getElementById(`heartbeatModal`)?.classList.add(`open`)}function jt(e){e&&e.target!==e.currentTarget||document.getElementById(`heartbeatModal`)?.classList.remove(`open`)}function A(){let e=document.getElementById(`hbJobsList`);if(!e)return;let t=n.heartbeatJobs.map(M);n.heartbeatJobs=t,n.heartbeatErrors=P(t),t.length===0?e.innerHTML=`<p style="color:var(--text-dim);font-size:12px;text-align:center">${u(`hb.empty`)}</p>`:e.innerHTML=t.map((e,t)=>{let r=It(e.schedule),i=r.kind===`cron`,a=n.heartbeatErrors[e.id],o=a||Ht(r),s=a?`hb-schedule-meta hb-error`:`hb-schedule-meta hb-help`,c=i?`<input type="text" value="${d(r.cron)}" placeholder="${d(u(`hb.cronPlaceholder`))}"
9
- data-hb-cron="${t}">`:`<input type="number" value="${r.minutes}" min="1" data-hb-minutes="${t}">`,l=i?`<span class="hb-chip">${d(u(`hb.cronLabel`))}</span>`:`<span class="hb-chip">${d(u(`hb.minutesLabel`))}</span>`;return`
10
- <div class="hb-job-card">
11
- <div class="hb-job-header">
12
- <input type="text" value="${d(String(e.name||``))}" placeholder="${d(u(`hb.name`))}"
13
- data-hb-name="${t}">
14
- <button class="hb-toggle ${e.enabled?`on`:`off`}"
15
- data-hb-toggle="${t}" aria-label="${d(String(e.name||`job`)+` toggle`)}"></button>
16
- <button class="hb-del" data-hb-remove="${t}">${f.close}</button>
17
- </div>
18
- <div class="hb-job-schedule">
19
- <select data-hb-kind="${t}">
20
- <option value="every"${i?``:` selected`}>${d(u(`hb.kindEvery`))}</option>
21
- <option value="cron"${i?` selected`:``}>${d(u(`hb.kindCron`))}</option>
22
- </select>
23
- ${c}
24
- ${l}
25
- <input type="text" value="${d(r.timeZone||``)}" placeholder="${d(zt())}"
26
- data-hb-timezone="${t}">
27
- </div>
28
- <p class="${s}">${d(o)}</p>
29
- <textarea class="hb-prompt" rows="2" placeholder="${d(u(`hb.prompt`))}"
30
- data-hb-prompt="${t}">${d(String(e.prompt||``))}</textarea>
31
- </div>
32
- `}).join(``);let r=t.filter(e=>e.enabled).length,i=document.getElementById(`hbSidebarBtn`);i&&(i.innerHTML=`${f.heartPulse} Heartbeat (${r})`)}function Mt(){n.heartbeatJobs.push({id:`hb_`+Date.now(),name:``,enabled:!0,schedule:Rt({kind:`every`,minutes:5}),prompt:``}),A(),j()}function Nt(e){n.heartbeatJobs.splice(e,1),A(),j()}function Pt(e){let t=n.heartbeatJobs[e];t&&(t.enabled=!t.enabled,A(),j())}async function j(){let e=n.heartbeatJobs.map(M);if(n.heartbeatJobs=e,n.heartbeatErrors=P(e),Object.keys(n.heartbeatErrors).length>0){A();return}let t=await a(`/api/heartbeat`,`PUT`,{jobs:e});t?.jobs&&(n.heartbeatJobs=t.jobs.map(M),n.heartbeatErrors=P(n.heartbeatJobs),A())}async function Ft(){try{let e=((await o(`/api/heartbeat`))?.jobs||[]).map(M).filter(e=>e.enabled).length,t=document.getElementById(`hbSidebarBtn`);t&&(t.innerHTML=`${f.heartPulse} Heartbeat (${e})`)}catch{}}function M(e){return{id:String(e.id||`hb_${Date.now()}`),name:String(e.name||``),enabled:e.enabled!==!1,schedule:It(e.schedule),prompt:String(e.prompt||``)}}function It(e){let t=Lt(e?.timeZone);if(e?.kind===`cron`){let n=typeof e.cron==`string`?e.cron.trim().replace(/\s+/g,` `):`0 9 * * *`;return t?{kind:`cron`,cron:n,timeZone:t}:{kind:`cron`,cron:n}}let n=typeof e?.minutes==`number`&&Number.isFinite(e.minutes)&&e.minutes>0?Math.max(1,Math.floor(e.minutes)):5;return t?{kind:`every`,minutes:n,timeZone:t}:{kind:`every`,minutes:n}}function Lt(e){return(typeof e==`string`?e.trim():``)||void 0}function Rt(e){let t=N();return t?{...e,timeZone:t}:e}function N(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function zt(){let e=N();return e?`${u(`hb.timezoneAuto`)} ${e}`:u(`hb.timezoneAuto`)}function P(e){let t={};for(let n of e){let e=Bt(n);e&&(t[n.id]=e)}return t}function Bt(e){let t=Ct(e.schedule);return t.ok?null:Vt(t.code,t.error)}function Vt(e,t){switch(e){case`invalid_cron`:return u(`hb.invalidCron`);case`invalid_timezone`:return u(`hb.invalidTimeZone`);case`invalid_minutes`:return u(`hb.invalidMinutes`);default:return t||u(`hb.invalidSchedule`)}}function Ht(e){let t=e.timeZone||N()||`Asia/Seoul`;return e.kind===`cron`?u(`hb.scheduleHintCron`,{cron:`0 9 * * *`,timeZone:t}):u(`hb.scheduleHintEvery`,{minutes:e.minutes,timeZone:t})}var F=`sidebarState`,I=900,Ut=768;function L(){return window.innerWidth<=Ut}function R(){document.body.classList.remove(`left-expanded`,`right-expanded`)}function Wt(e){let t=`${e}-expanded`,n=e===`left`?`right-expanded`:`left-expanded`,r=!document.body.classList.contains(t);document.body.classList.remove(n),document.body.classList.toggle(t,r)}function Gt(){let e={};try{e=JSON.parse(localStorage.getItem(F)||`{}`)}catch{}e.left&&document.body.classList.add(`left-collapsed`),e.right&&document.body.classList.add(`right-collapsed`);let t=L();document.getElementById(`toggleLeft`)?.addEventListener(`click`,B),document.getElementById(`toggleRight`)?.addEventListener(`click`,V),window.addEventListener(`resize`,()=>{let e=L();if(window.innerWidth>I){R();let e={};try{e=JSON.parse(localStorage.getItem(F)||`{}`)}catch{}document.body.classList.toggle(`left-collapsed`,!!e.left),document.body.classList.toggle(`right-collapsed`,!!e.right)}else document.body.classList.remove(`left-collapsed`,`right-collapsed`),e!==t&&R();t=e,H()}),window.innerWidth<=I&&(document.body.classList.remove(`left-collapsed`,`right-collapsed`),L()&&R()),H()}function z(){return window.innerWidth<=I}function B(){z()?Wt(`left`):document.body.classList.toggle(`left-collapsed`),Jt(),H()}function V(){z()?Wt(`right`):document.body.classList.toggle(`right-collapsed`),Jt(),H()}function Kt(){return z()?document.body.classList.contains(`left-expanded`):!document.body.classList.contains(`left-collapsed`)}function qt(){return z()?document.body.classList.contains(`right-expanded`):!document.body.classList.contains(`right-collapsed`)}function H(){let e=document.getElementById(`toggleLeft`),t=document.getElementById(`toggleRight`);e&&(e.innerHTML=Kt()?f.chevronLeft:f.chevronRight),t&&(t.innerHTML=qt()?f.chevronRight:f.chevronLeft)}function Jt(){localStorage.setItem(F,JSON.stringify({left:document.body.classList.contains(`left-collapsed`),right:document.body.classList.contains(`right-collapsed`)}))}var Yt=`theme`,U=null;function Xt(n){let r=n===`light`?t:e;U||(U=document.createElement(`style`),U.id=`hljsTheme`,document.head.appendChild(U)),U.textContent=r}function Zt(){let e=localStorage.getItem(Yt),t=window.matchMedia(`(prefers-color-scheme: light)`).matches?`light`:`dark`;$t(e||t),document.getElementById(`toggleTheme`)?.addEventListener(`click`,Qt)}function Qt(){let e=(document.documentElement.getAttribute(`data-theme`)||`dark`)===`dark`?`light`:`dark`;$t(e),localStorage.setItem(Yt,e)}function $t(e){document.documentElement.setAttribute(`data-theme`,e);let t=document.getElementById(`toggleTheme`);t&&t.classList.toggle(`is-light`,e===`light`),Xt(e),ie(),c()}var en=50,tn=30,nn=80,rn=500,W=null,an=!1;function on(){if(an||!(`ontouchstart`in window))return;an=!0;let e=document.querySelector(`.chat-area`);e&&(e.addEventListener(`touchstart`,sn,{passive:!0}),e.addEventListener(`touchend`,cn,{passive:!0}))}function sn(e){let t=e.touches[0],n=window.innerWidth,r=null;t.clientX<tn?r=`left`:t.clientX>n-tn&&(r=`right`),W={startX:t.clientX,startY:t.clientY,startTime:Date.now(),isEdge:r}}function cn(e){if(!W)return;let t=e.changedTouches[0],n=t.clientX-W.startX,r=Math.abs(t.clientY-W.startY),i=Date.now()-W.startTime,a=W;W=null,!(r>nn||i>rn||Math.abs(n)<en)&&(n>0&&a.isEdge===`left`&&B(),n<0&&a.isEdge===`right`&&V())}var G=!1,K=null,q=[],J=null,Y=null,ln=0;function un(){if(typeof MediaRecorder>`u`)return``;for(let e of[`audio/webm;codecs=opus`,`audio/mp4`,`audio/ogg;codecs=opus`])if(MediaRecorder.isTypeSupported(e))return e;return``}function dn(e){let t=e;switch(t.name){case`NotAllowedError`:return u(`voice.micDenied`);case`NotFoundError`:return u(`voice.micNotFound`);case`NotReadableError`:case`AbortError`:return u(`voice.micBusy`);default:return t instanceof TypeError||!navigator.mediaDevices?u(`voice.httpsRequired`):u(`voice.micDenied`)}}async function fn(){if(n.isRecording)return;if(typeof MediaRecorder>`u`||!navigator.mediaDevices?.getUserMedia){p(u(`voice.unsupported`),``,`error`);return}try{J=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){p(dn(e),``,`error`);return}let e=un();K=new MediaRecorder(J,e?{mimeType:e}:{}),q=[],K.ondataavailable=e=>{e.data.size>0&&q.push(e.data)},K.onerror=()=>{pn(),p(u(`voice.interrupted`),``,`error`)},K.onstop=async()=>{if(G){q=[],gn(),G=!1;return}let t=K?.mimeType||e||`audio/webm`,n=t.includes(`mp4`)?`.m4a`:t.includes(`ogg`)?`.ogg`:`.webm`,r=new Blob(q,{type:t});if(q=[],gn(),r.size>20*1024*1024){p(u(`voice.tooLarge`),``,`error`);return}if(r.size<1e3){p(u(`voice.tooShort`),``,`error`);return}await yt(r,n,t)},K.start(),n.isRecording=!0,ln=Date.now(),X(!0),_n()}function pn(){!n.isRecording||!K||(K.state===`recording`&&K.stop(),n.isRecording=!1,vn(),X(!1))}function mn(){!n.isRecording||!K||(G=!0,K.state===`recording`&&K.stop(),n.isRecording=!1,vn(),X(!1))}function hn(){n.isRecording?pn():fn()}function gn(){J?.getTracks().forEach(e=>e.stop()),J=null}function _n(){let e=document.getElementById(`voiceTimer`);e&&(e.style.display=`inline`,Y=setInterval(()=>{let t=Math.floor((Date.now()-ln)/1e3);e.textContent=`${String(Math.floor(t/60)).padStart(2,`0`)}:${String(t%60).padStart(2,`0`)}`},500))}function vn(){Y&&=(clearInterval(Y),null);let e=document.getElementById(`voiceTimer`);e&&(e.style.display=`none`,e.textContent=`00:00`)}function X(e){let t=document.getElementById(`btnVoice`),n=document.getElementById(`btnVoiceCancel`);t&&(t.classList.toggle(`recording`,e),t.innerHTML=e?f.stop:f.mic,t.title=u(e?`voice.stop`:`voice.start`)),n&&(n.style.display=e?`inline-block`:`none`)}var Z=`jaw:stale-bundle-reload-pending`;function yn(e){let t=typeof e==`string`?e:e instanceof Error||typeof e?.message==`string`?e.message:``;if(!/(failed to fetch dynamically imported module|error loading dynamically imported module|importing a module script failed|chunkloaderror)/i.test(t))return!1;console.warn(`[stale-bundle] detected dynamic import failure:`,t);try{if(sessionStorage.getItem(Z)===`1`)return!0;sessionStorage.setItem(Z,`1`)}catch{}let n=()=>window.location.reload();return`serviceWorker`in navigator?(navigator.serviceWorker.getRegistration().then(e=>e?.update()).catch(()=>{}).finally(n),!0):(n(),!0)}window.addEventListener(`unhandledrejection`,e=>{if(yn(e.reason)){e.preventDefault();return}console.error(`[unhandled]`,e.reason),e.preventDefault()}),window.addEventListener(`error`,e=>{if(yn(e.error||e.message)){e.preventDefault();return}console.error(`[error]`,e.message,e.filename,e.lineno)});var{loadEmployees:bn,addEmployee:xn,deleteEmployee:Sn,updateEmployee:Q,onEmpCliChange:Cn,onEmpRoleChange:wn}=await s(async()=>{let{loadEmployees:e,addEmployee:t,deleteEmployee:n,updateEmployee:r,onEmpCliChange:i,onEmpRoleChange:a}=await import(`./employees-DEAsLiuH.js`);return{loadEmployees:e,addEmployee:t,deleteEmployee:n,updateEmployee:r,onEmpCliChange:i,onEmpRoleChange:a}},__vite__mapDeps([0]));document.getElementById(`btnSend`)?.addEventListener(`click`,C);var Tn=document.getElementById(`chatInput`);Tn?.addEventListener(`keydown`,e=>{ye(e)||dt(e)});var $=0;Tn?.addEventListener(`input`,e=>{e.isComposing||($&&cancelAnimationFrame($),$=requestAnimationFrame(()=>{ve(e.target?.value||``),$=0}))}),Tn?.addEventListener(`cmd-execute`,()=>{C()}),document.getElementById(`cmdDropdown`)?.addEventListener(`click`,_e),document.addEventListener(`click`,ge),fe(),document.getElementById(`filePreviewClear`)?.addEventListener(`click`,T),document.getElementById(`filePreviewList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-file-idx]`);t&&pt(+(t.dataset.fileIdx||`0`))}),document.querySelector(`.btn-attach`)?.addEventListener(`click`,()=>{document.getElementById(`fileInput`)?.click()}),document.getElementById(`btnVoice`)?.addEventListener(`click`,()=>hn()),document.getElementById(`btnVoiceCancel`)?.addEventListener(`click`,()=>mn()),document.getElementById(`memorySidebarBtn`)?.addEventListener(`click`,tt),document.getElementById(`btnClearChat`)?.addEventListener(`click`,mt),document.getElementById(`hbSidebarBtn`)?.addEventListener(`click`,At),document.getElementById(`langToggle`)?.addEventListener(`click`,async()=>{let e=l()===`ko`?`en`:`ko`;await ee(e);let t=document.getElementById(`langToggle`);t&&(t.innerHTML=`${f.web} ${u(`lang.`+e)}`),n.ws&&n.ws.close()}),document.querySelector(`.tab-bar`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`.tab-btn`);if(!t)return;let n=[...t.parentElement?.children||[]].filter(e=>e.classList.contains(`tab-btn`)).indexOf(t),r=[`agents`,`skills`,`settings`];r[n]&&oe(r[n],t)}),document.querySelector(`.sidebar-save-bar .btn-save`)?.addEventListener(`click`,ce),document.getElementById(`selCli`)?.addEventListener(`change`,()=>ze()),document.getElementById(`selModel`)?.addEventListener(`change`,()=>Pe()),document.getElementById(`selEffort`)?.addEventListener(`change`,()=>Pe()),document.getElementById(`flushCli`)?.addEventListener(`change`,()=>Re()),document.getElementById(`flushModel`)?.addEventListener(`change`,()=>Re()),document.querySelector(`[data-action="addEmployee"]`)?.addEventListener(`click`,xn),document.getElementById(`employeesList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-emp-delete]`);if(t){Sn(t.dataset.empDelete||``);return}}),document.getElementById(`employeesList`)?.addEventListener(`change`,e=>{let t=e.target,n=t.closest(`[data-emp-name]`);if(n){Q(n.dataset.empName||``,{name:t.value});return}let r=t.closest(`[data-emp-cli]`);if(r){Cn(r.dataset.empCli||``,t.value);return}let i=t.closest(`[data-emp-model]`);if(i){if(t.value===`__custom__`){let e=prompt(u(`model.promptInput`));if(e?.trim()){let n=document.createElement(`option`);n.value=e.trim(),n.textContent=e.trim();let r=t.querySelector(`option[value="__custom__"]`);r&&t.insertBefore(n,r),t.value=e.trim(),Q(i.dataset.empModel||``,{model:e.trim()})}else t.value=`default`}else Q(i.dataset.empModel||``,{model:t.value});return}let a=t.closest(`[data-emp-role]`);if(a){wn(a.dataset.empRole||``,t.value);return}let o=t.closest(`[data-emp-custom]`);if(o){Q(o.dataset.empCustom||``,{role:t.value});return}}),document.getElementById(`skillsList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-skill-id]`);t&&xe(t.dataset.skillId||``,t.dataset.skillEnabled===`true`)}),document.querySelector(`#tabSkills`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`.skill-filter`);t&&Se(t.dataset.filter||`all`,t)}),document.querySelector(`[data-action="openPrompt"]`)?.addEventListener(`click`,Je),document.getElementById(`tgOff`)?.addEventListener(`click`,()=>Oe(!1)),document.getElementById(`tgOn`)?.addEventListener(`click`,()=>Oe(!0)),document.getElementById(`tgForwardOff`)?.addEventListener(`click`,()=>Me(!1)),document.getElementById(`tgForwardOn`)?.addEventListener(`click`,()=>Me(!0)),document.getElementById(`tgMentionOff`)?.addEventListener(`click`,()=>ke(!1)),document.getElementById(`tgMentionOn`)?.addEventListener(`click`,()=>ke(!0)),document.getElementById(`tgToken`)?.addEventListener(`change`,je),document.getElementById(`tgChatIds`)?.addEventListener(`change`,je),document.getElementById(`chTelegram`)?.addEventListener(`click`,()=>Ee(`telegram`)),document.getElementById(`chDiscord`)?.addEventListener(`click`,()=>Ee(`discord`)),document.getElementById(`dcOff`)?.addEventListener(`click`,()=>He(!1)),document.getElementById(`dcOn`)?.addEventListener(`click`,()=>He(!0)),document.getElementById(`dcForwardOff`)?.addEventListener(`click`,()=>Ve(!1)),document.getElementById(`dcForwardOn`)?.addEventListener(`click`,()=>Ve(!0)),document.getElementById(`dcAllowBotsOff`)?.addEventListener(`click`,()=>Te(!1)),document.getElementById(`dcAllowBotsOn`)?.addEventListener(`click`,()=>Te(!0)),document.getElementById(`dcMentionOff`)?.addEventListener(`click`,()=>Ae(!1)),document.getElementById(`dcMentionOn`)?.addEventListener(`click`,()=>Ae(!0)),document.getElementById(`dcToken`)?.addEventListener(`change`,g),document.getElementById(`dcGuildId`)?.addEventListener(`change`,g),document.getElementById(`dcChannelIds`)?.addEventListener(`change`,g),document.getElementById(`fallbackOrderList`)?.addEventListener(`change`,De);function En(e){let t=document.getElementById(`codexFastOn`),n=document.getElementById(`codexFastOff`);t&&n&&(t.classList.toggle(`active`,e),n.classList.toggle(`active`,!e)),v()}document.getElementById(`codexFastOn`)?.addEventListener(`click`,()=>En(!0)),document.getElementById(`codexFastOff`)?.addEventListener(`click`,()=>En(!1));function Dn(e){let t=document.getElementById(`codexCtxOn`),n=document.getElementById(`codexCtxOff`),r=document.getElementById(`codexCtxValues`);t&&n&&(t.classList.toggle(`active`,e),n.classList.toggle(`active`,!e)),r&&(r.style.display=e?``:`none`),v()}document.getElementById(`codexCtxOn`)?.addEventListener(`click`,()=>Dn(!0)),document.getElementById(`codexCtxOff`)?.addEventListener(`click`,()=>Dn(!1)),document.getElementById(`codexCtxWindow`)?.addEventListener(`change`,v),document.getElementById(`codexCtxCompact`)?.addEventListener(`change`,v);function On(e){let t=document.getElementById(`claude1mOn`),n=document.getElementById(`claude1mOff`),r=document.getElementById(`modelClaude`),i=e;if(r){let t=r.value||``;if(e&&!t.endsWith(`[1m]`)){let e=t+`[1m]`;Array.from(r.options).some(t=>t.value===e)?r.value=e:i=!1}else if(!e&&t.endsWith(`[1m]`)){let e=t.replace(/\[1m\]$/,``);Array.from(r.options).some(t=>t.value===e)?r.value=e:i=!0}else i=t.endsWith(`[1m]`)}t&&n&&(t.classList.toggle(`active`,i),n.classList.toggle(`active`,!i)),v()}document.getElementById(`claude1mOn`)?.addEventListener(`click`,()=>On(!0)),document.getElementById(`claude1mOff`)?.addEventListener(`click`,()=>On(!1));function kn(){for(let e of we()){let t=e.charAt(0).toUpperCase()+e.slice(1),n=document.getElementById(`model`+t);n&&n.addEventListener(`change`,function(){Le(e,this)});let r=document.getElementById(`customModel`+t);r&&r.addEventListener(`change`,function(){Xe(e,this)});let i=document.getElementById(`effort`+t);i&&i.addEventListener(`change`,v)}}document.querySelector(`[data-action="syncMcp"]`)?.addEventListener(`click`,Ze),document.querySelector(`[data-action="installMcp"]`)?.addEventListener(`click`,Ne),document.querySelector(`[data-action="refreshCli"]`)?.addEventListener(`click`,()=>Ue(!0)),document.getElementById(`cliStatusInterval`)?.addEventListener(`change`,function(){localStorage.setItem(`cliStatusInterval`,this.value)}),document.getElementById(`promptModal`)?.addEventListener(`click`,e=>_(e)),document.querySelector(`#promptModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closePrompt"]`)?.addEventListener(`click`,()=>_()),document.querySelector(`[data-action="cancelPrompt"]`)?.addEventListener(`click`,()=>_()),document.querySelector(`[data-action="savePrompt"]`)?.addEventListener(`click`,Fe),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&!n.isRecording&&_()}),document.querySelector(`[data-action="openTemplates"]`)?.addEventListener(`click`,Be),document.querySelector(`[data-action="saveTemplate"]`)?.addEventListener(`click`,Ke),document.querySelector(`[data-action="closeTemplate"]`)?.addEventListener(`click`,()=>Ge()),document.getElementById(`templateModal`)?.addEventListener(`click`,e=>Ge(e)),document.querySelector(`#templateModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.getElementById(`templateBack`)?.addEventListener(`click`,Ye),document.getElementById(`templateDevToggle`)?.addEventListener(`click`,Ie),document.getElementById(`heartbeatModal`)?.addEventListener(`click`,e=>jt(e)),document.querySelector(`#heartbeatModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closeHeartbeat"]`)?.addEventListener(`click`,()=>jt()),document.querySelector(`[data-action="addHeartbeat"]`)?.addEventListener(`click`,Mt),document.getElementById(`hbJobsList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-hb-toggle]`);if(t){Pt(+(t.dataset.hbToggle||`0`));return}let n=e.target?.closest(`[data-hb-remove]`);if(n){Nt(+(n.dataset.hbRemove||`0`));return}}),document.getElementById(`hbJobsList`)?.addEventListener(`change`,e=>{let t=e.target,r=t.closest(`[data-hb-name]`);if(r){n.heartbeatJobs[+(r.dataset.hbName||`0`)].name=t.value,j();return}let i=t.closest(`[data-hb-kind]`);if(i){let e=+(i.dataset.hbKind||`0`),r=n.heartbeatJobs[e]?.schedule,a=typeof r?.timeZone==`string`?r.timeZone:void 0;n.heartbeatJobs[e].schedule=t.value===`cron`?{kind:`cron`,cron:typeof r?.cron==`string`&&r.cron.trim()?r.cron:`0 9 * * *`,...a?{timeZone:a}:{}}:{kind:`every`,minutes:typeof r?.minutes==`number`&&r.minutes>0?Math.floor(r.minutes):5,...a?{timeZone:a}:{}},A(),j();return}let a=t.closest(`[data-hb-minutes]`);if(a){let e=+(a.dataset.hbMinutes||`0`),r=n.heartbeatJobs[e]?.schedule,i=Math.max(1,Math.floor(Number(t.value)||5)),o=typeof r?.timeZone==`string`?r.timeZone:void 0;n.heartbeatJobs[e].schedule={kind:`every`,minutes:i,...o?{timeZone:o}:{}},A(),j();return}let o=t.closest(`[data-hb-cron]`);if(o){let e=+(o.dataset.hbCron||`0`),r=n.heartbeatJobs[e]?.schedule,i=typeof r?.timeZone==`string`?r.timeZone:void 0,a=t.value.trim().replace(/\s+/g,` `);n.heartbeatJobs[e].schedule={kind:`cron`,cron:a,...i?{timeZone:i}:{}},A(),j();return}let s=t.closest(`[data-hb-timezone]`);if(s){let e=+(s.dataset.hbTimezone||`0`),r=n.heartbeatJobs[e]?.schedule;r?.kind===`cron`?n.heartbeatJobs[e].schedule={kind:`cron`,cron:typeof r.cron==`string`&&r.cron.trim()?r.cron:`0 9 * * *`,...t.value.trim()?{timeZone:t.value.trim()}:{}}:n.heartbeatJobs[e].schedule={kind:`every`,minutes:typeof r?.minutes==`number`&&r.minutes>0?Math.floor(r.minutes):5,...t.value.trim()?{timeZone:t.value.trim()}:{}},A(),j();return}let c=t.closest(`[data-hb-prompt]`);if(c){n.heartbeatJobs[+(c.dataset.hbPrompt||`0`)].prompt=t.value,j();return}}),document.getElementById(`memoryModal`)?.addEventListener(`click`,e=>lt(e)),document.querySelector(`#memoryModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closeMemory"]`)?.addEventListener(`click`,()=>lt()),document.getElementById(`memTabBtnSettings`)?.addEventListener(`click`,()=>b(`settings`)),document.getElementById(`memTabBtnAdvOps`)?.addEventListener(`click`,()=>b(`status`)),document.getElementById(`memTabBtnFiles`)?.addEventListener(`click`,()=>b(`files`)),document.getElementById(`memOn`)?.addEventListener(`click`,()=>nt(!0)),document.getElementById(`memOff`)?.addEventListener(`click`,()=>nt(!1)),document.getElementById(`memFlushEvery`)?.addEventListener(`change`,y),document.getElementById(`memRetention`)?.addEventListener(`change`,y),document.getElementById(`memFlushLang`)?.addEventListener(`change`,y),document.getElementById(`memFlushNowBtn`)?.addEventListener(`click`,et),document.getElementById(`advBootstrapBtn`)?.addEventListener(`click`,ct),document.getElementById(`advReindexBtn`)?.addEventListener(`click`,at),document.getElementById(`advReimportBtn`)?.addEventListener(`click`,ct),document.getElementById(`advOpenCorruptedBtn`)?.addEventListener(`click`,st),document.getElementById(`advStatusBanner`)?.addEventListener(`click`,e=>{e.target?.id===`advUpgradeSoulBtn`&&ot(),e.target?.id===`advSynthesizeSoulBtn`&&$e()}),document.getElementById(`basicMemoryFiles`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-mem-delete]`);if(t){e.stopPropagation(),it(t.dataset.memDelete||``);return}let n=e.target?.closest(`[data-mem-view]`);if(n){rt(n.dataset.memView||``);return}if(e.target?.closest(`[data-mem-back]`)){tt();return}});async function An(){re(),Qe(),Zt(),await te();let e=document.getElementById(`langToggle`);e&&(e.innerHTML=`${f.web} ${u(`lang.`+l())}`),await Ce(),kn(),pe(),vt(),_t(),await he(),await We(),qe(),Ue(),bn(),Ft(),ae(),await ue(),Gt(),se(),on();try{sessionStorage.removeItem(Z)}catch{}`serviceWorker`in navigator&&navigator.serviceWorker.register(`/sw.js`).catch(()=>{})}An().catch(e=>{console.error(`[bootstrap]`,e)}),document.addEventListener(`keydown`,e=>{if(e.key===`Escape`){if(n.isRecording){e.preventDefault(),mn();return}document.querySelectorAll(`.modal-overlay.open`).forEach(e=>{e.classList.remove(`open`)})}(e.ctrlKey||e.metaKey)&&e.shiftKey&&e.code===`Space`&&(e.preventDefault(),hn())}),document.getElementById(`mobileMenuLeft`)?.addEventListener(`click`,B),document.getElementById(`mobileMenuRight`)?.addEventListener(`click`,V);
@@ -1 +0,0 @@
1
- import{a as e}from"./memory-Da0JJE5y.js";export{e as refreshMemorySidebar};
@@ -1 +0,0 @@
1
- import{b as e,m as t,v as n}from"./settings-DO7YNchG.js";export{t as loadSettings,n as savePerCli,e as updateSettings};
@@ -1 +0,0 @@
1
- import{n as e}from"./skills-_cb0eUR_.js";export{e as loadSkills};
@@ -1 +0,0 @@
1
- import{a as e}from"./slash-commands-BnZWVFWF.js";export{e as loadCommands};