cli-jaw 1.6.3 → 1.6.6

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 (61) hide show
  1. package/README.md +8 -4
  2. package/dist/bin/commands/doctor.js +48 -0
  3. package/dist/bin/commands/doctor.js.map +1 -1
  4. package/dist/bin/commands/init.js +2 -1
  5. package/dist/bin/commands/init.js.map +1 -1
  6. package/dist/bin/postinstall.js +66 -1
  7. package/dist/bin/postinstall.js.map +1 -1
  8. package/dist/server.js +8 -3
  9. package/dist/server.js.map +1 -1
  10. package/dist/src/agent/spawn.js +38 -9
  11. package/dist/src/agent/spawn.js.map +1 -1
  12. package/dist/src/orchestrator/distribute.js +4 -1
  13. package/dist/src/orchestrator/distribute.js.map +1 -1
  14. package/dist/src/orchestrator/parser.js +2 -1
  15. package/dist/src/orchestrator/parser.js.map +1 -1
  16. package/dist/src/orchestrator/pipeline.js +5 -96
  17. package/dist/src/orchestrator/pipeline.js.map +1 -1
  18. package/dist/src/orchestrator/state-machine.js +11 -14
  19. package/dist/src/orchestrator/state-machine.js.map +1 -1
  20. package/dist/src/prompt/builder.js +5 -15
  21. package/dist/src/prompt/builder.js.map +1 -1
  22. package/dist/src/prompt/templates/a1-system.md +33 -32
  23. package/dist/src/prompt/templates/employee.md +7 -3
  24. package/dist/src/prompt/templates/orchestration.md +13 -37
  25. package/package.json +7 -1
  26. package/public/css/chat.css +12 -0
  27. package/public/dist/assets/employees-B11suLXa.js +39 -0
  28. package/public/dist/assets/index-C3xIEYRH.css +1 -0
  29. package/public/dist/assets/index-CMUmeewA.js +49 -0
  30. package/public/dist/assets/render-C5gpc065.js +25 -0
  31. package/public/dist/assets/{settings-BJR-IGM5.js → settings-BbG1hQmA.js} +14 -14
  32. package/public/dist/assets/settings-tOEsbIIs.js +1 -0
  33. package/public/dist/assets/skills-DL7wTirZ.js +12 -0
  34. package/public/dist/assets/skills-kOx6rq1X.js +1 -0
  35. package/public/dist/assets/slash-commands-C5vUKzNP.js +1 -0
  36. package/public/dist/assets/{slash-commands-DWvL-VDU.js → slash-commands-D_tV86er.js} +1 -1
  37. package/public/dist/assets/ui-ByJAyywC.js +1 -0
  38. package/public/dist/assets/ui-ORW7tzea.js +131 -0
  39. package/public/dist/assets/ws-CDrAtY9-.js +2 -0
  40. package/public/dist/index.html +2 -2
  41. package/public/js/features/chat.ts +3 -1
  42. package/public/js/render.ts +65 -22
  43. package/public/js/streaming-render.ts +33 -10
  44. package/public/js/ui.ts +45 -13
  45. package/public/js/virtual-scroll.ts +50 -16
  46. package/public/js/ws.ts +2 -1
  47. package/scripts/ensure-native-modules.cjs +54 -0
  48. package/scripts/install-officecli.ps1 +96 -0
  49. package/scripts/install-officecli.sh +37 -3
  50. package/scripts/install-wsl.sh +113 -27
  51. package/public/dist/assets/employees-D5n7mX5v.js +0 -39
  52. package/public/dist/assets/index-CLd0BsAu.js +0 -49
  53. package/public/dist/assets/index-D6ci1wCN.css +0 -1
  54. package/public/dist/assets/render-C8N0rp4L.js +0 -25
  55. package/public/dist/assets/settings-Dm6OnPmY.js +0 -1
  56. package/public/dist/assets/skills-D6jv9AIs.js +0 -1
  57. package/public/dist/assets/skills-uywskdFh.js +0 -12
  58. package/public/dist/assets/slash-commands-CCDonT40.js +0 -1
  59. package/public/dist/assets/ui-C1daR00l.js +0 -1
  60. package/public/dist/assets/ui-D-oFkXed.js +0 -131
  61. package/public/dist/assets/ws-Dnn8HG8B.js +0 -2
@@ -0,0 +1,96 @@
1
+ param(
2
+ [switch]$Force,
3
+ [switch]$Update,
4
+ [switch]$Upstream,
5
+ [string]$Repo = $env:OFFICECLI_REPO
6
+ )
7
+
8
+ $ErrorActionPreference = "Stop"
9
+
10
+ function Write-Info($msg) { Write-Host "▸ $msg" -ForegroundColor Cyan }
11
+ function Write-Ok($msg) { Write-Host "✔ $msg" -ForegroundColor Green }
12
+ function Write-Warn($msg) { Write-Host "⚠ $msg" -ForegroundColor Yellow }
13
+ function Fail($msg) { Write-Host "✖ $msg" -ForegroundColor Red; exit 1 }
14
+
15
+ if ($Upstream -and $env:OFFICECLI_REPO) {
16
+ Fail "--upstream cannot be combined with OFFICECLI_REPO"
17
+ }
18
+
19
+ if (-not $Repo) {
20
+ $Repo = "lidge-jun/OfficeCLI"
21
+ }
22
+ if ($Upstream) {
23
+ $Repo = "iOfficeAI/OfficeCLI"
24
+ }
25
+
26
+ $installDir = Join-Path $env:LOCALAPPDATA "OfficeCli"
27
+ $targetBin = Join-Path $installDir "officecli.exe"
28
+ $downloadBin = Join-Path $installDir "officecli.download.exe"
29
+
30
+ $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant()
31
+ switch ($arch) {
32
+ "x64" { $asset = "officecli-win-x64.exe" }
33
+ "arm64" { $asset = "officecli-win-arm64.exe" }
34
+ default { Fail "Unsupported Windows architecture: $arch" }
35
+ }
36
+
37
+ function Normalize-Version([string]$version) {
38
+ if (-not $version) { return "" }
39
+ return $version.Trim().TrimStart('v')
40
+ }
41
+
42
+ function Get-LatestTag([string]$repoName) {
43
+ $release = Invoke-RestMethod -Uri "https://api.github.com/repos/$repoName/releases/latest" -Headers @{ "User-Agent" = "cli-jaw-postinstall" }
44
+ return [string]$release.tag_name
45
+ }
46
+
47
+ Write-Info "Platform: win32/$arch -> $asset"
48
+
49
+ if ((Test-Path $targetBin) -and -not $Force -and -not $Update) {
50
+ try {
51
+ $current = & $targetBin --version 2>$null
52
+ Write-Ok "officecli already installed: v$($current.Trim())"
53
+ Write-Host " Use -Force to reinstall or -Update to refresh only when outdated"
54
+ exit 0
55
+ } catch {
56
+ Write-Warn "Existing officecli is not executable; reinstalling"
57
+ }
58
+ }
59
+
60
+ if ((Test-Path $targetBin) -and -not $Force -and $Update) {
61
+ $current = ""
62
+ $latest = ""
63
+ try { $current = & $targetBin --version 2>$null } catch { }
64
+ try { $latest = Get-LatestTag $Repo } catch { }
65
+ if ($current -and $latest -and (Normalize-Version $current) -eq (Normalize-Version $latest)) {
66
+ Write-Ok "officecli already up to date: v$(Normalize-Version $current)"
67
+ exit 0
68
+ }
69
+ if ($current -and $latest) {
70
+ Write-Info "Updating officecli v$(Normalize-Version $current) -> v$(Normalize-Version $latest)"
71
+ } else {
72
+ Write-Warn "Could not compare installed version with latest release; reinstalling"
73
+ }
74
+ }
75
+
76
+ New-Item -ItemType Directory -Force -Path $installDir | Out-Null
77
+ $downloadUrl = "https://github.com/$Repo/releases/latest/download/$asset"
78
+
79
+ Write-Info "Downloading officecli from $Repo..."
80
+ Invoke-WebRequest -Uri $downloadUrl -OutFile $downloadBin
81
+
82
+ try {
83
+ $version = (& $downloadBin --version 2>$null).Trim()
84
+ } catch {
85
+ Remove-Item -Force $downloadBin -ErrorAction SilentlyContinue
86
+ Fail "Binary exists but won't execute"
87
+ }
88
+
89
+ Move-Item -Force $downloadBin $targetBin
90
+ Write-Ok "officecli v$version installed -> $targetBin"
91
+
92
+ $pathEntries = (($env:PATH -split ';') | ForEach-Object { $_.Trim() }) | Where-Object { $_ }
93
+ if (-not ($pathEntries -contains $installDir)) {
94
+ Write-Warn "officecli is not on PATH. Add this location if you want to run it directly:"
95
+ Write-Host " $installDir"
96
+ }
@@ -24,6 +24,7 @@ DOWNLOAD_BIN="${INSTALL_DIR}/officecli.download"
24
24
 
25
25
  UPSTREAM=false
26
26
  FORCE=false
27
+ UPDATE=false
27
28
  for arg in "$@"; do
28
29
  case "$arg" in
29
30
  --upstream)
@@ -34,12 +35,14 @@ for arg in "$@"; do
34
35
  REPO="iOfficeAI/OfficeCLI"
35
36
  ;;
36
37
  --force) FORCE=true ;;
38
+ --update) UPDATE=true ;;
37
39
  -h|--help)
38
40
  cat <<'EOF'
39
- Usage: ./scripts/install-officecli.sh [--force] [--upstream]
41
+ Usage: ./scripts/install-officecli.sh [--force] [--update] [--upstream]
40
42
 
41
43
  Options:
42
44
  --force Reinstall even when officecli already exists
45
+ --update Reinstall only when the installed version is older than latest
43
46
  --upstream Use vanilla iOfficeAI/OfficeCLI instead of the CJK-enhanced fork
44
47
  EOF
45
48
  exit 0
@@ -84,17 +87,39 @@ esac
84
87
 
85
88
  info "Platform: ${OS}/${ARCH} → ${ASSET}"
86
89
 
90
+ normalize_version() {
91
+ printf '%s' "${1:-}" | sed 's/^v//'
92
+ }
93
+
94
+ get_latest_version() {
95
+ curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" 2>/dev/null | sed -nE 's/.*"tag_name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' | head -n 1
96
+ }
97
+
87
98
  # ── Check existing installation ──
88
- if [ -f "$TARGET_BIN" ] && [ "$FORCE" = "false" ]; then
99
+ if [ -f "$TARGET_BIN" ] && [ "$FORCE" = "false" ] && [ "$UPDATE" = "false" ]; then
89
100
  if CURRENT=$("$TARGET_BIN" --version 2>/dev/null); then
90
101
  ok "officecli already installed: v${CURRENT}"
91
- echo " Use --force to reinstall"
102
+ echo " Use --force to reinstall or --update to refresh only when outdated"
92
103
  exit 0
93
104
  fi
94
105
 
95
106
  warn "Existing officecli is not executable; reinstalling"
96
107
  fi
97
108
 
109
+ if [ -f "$TARGET_BIN" ] && [ "$FORCE" = "false" ] && [ "$UPDATE" = "true" ]; then
110
+ CURRENT=$("$TARGET_BIN" --version 2>/dev/null || true)
111
+ LATEST=$(get_latest_version)
112
+ if [ -n "$CURRENT" ] && [ -n "$LATEST" ] && [ "$(normalize_version "$CURRENT")" = "$(normalize_version "$LATEST")" ]; then
113
+ ok "officecli already up to date: v$(normalize_version "$CURRENT")"
114
+ exit 0
115
+ fi
116
+ if [ -n "$CURRENT" ] && [ -n "$LATEST" ]; then
117
+ info "Updating officecli v$(normalize_version "$CURRENT") → v$(normalize_version "$LATEST")"
118
+ else
119
+ warn "Could not compare installed version with latest release; reinstalling"
120
+ fi
121
+ fi
122
+
98
123
  # ── Download ──
99
124
  mkdir -p "$INSTALL_DIR"
100
125
  DOWNLOAD_URL="https://github.com/${REPO}/releases/latest/download/${ASSET}"
@@ -105,6 +130,15 @@ trap 'rm -f "$DOWNLOAD_BIN"' EXIT
105
130
  curl -fsSL "$DOWNLOAD_URL" -o "$DOWNLOAD_BIN" || fail "Download failed: $DOWNLOAD_URL"
106
131
  chmod +x "$DOWNLOAD_BIN"
107
132
 
133
+ if [ "$OS" = "darwin" ]; then
134
+ if command -v xattr >/dev/null 2>&1; then
135
+ xattr -d com.apple.quarantine "$DOWNLOAD_BIN" >/dev/null 2>&1 || true
136
+ fi
137
+ if command -v codesign >/dev/null 2>&1; then
138
+ codesign --force --deep --sign - "$DOWNLOAD_BIN" >/dev/null 2>&1 || warn "Ad-hoc codesign failed; continuing"
139
+ fi
140
+ fi
141
+
108
142
  # ── Verify checksum (best-effort) ──
109
143
  if command -v shasum &>/dev/null || command -v sha256sum &>/dev/null; then
110
144
  EXPECTED=$(curl -fsSL "$CHECKSUM_URL" 2>/dev/null | grep "$ASSET" | awk '{print $1}')
@@ -32,23 +32,59 @@ echo -e "${DIM} WSL One-Click Installer${NC}"
32
32
  echo ""
33
33
 
34
34
  NODE_MAJOR=22
35
+ SUDO=""
36
+ HAS_SUDO=false
37
+
38
+ ensure_sudo() {
39
+ if [ "$(id -u)" -eq 0 ]; then
40
+ HAS_SUDO=true
41
+ SUDO=""
42
+ ok "Running as root — full system install available"
43
+ return 0
44
+ fi
45
+
46
+ if ! command -v sudo &>/dev/null; then
47
+ warn "sudo not found — system package install will be skipped"
48
+ return 0
49
+ fi
50
+
51
+ info "Requesting sudo once for WSL system setup..."
52
+ if sudo -v; then
53
+ HAS_SUDO=true
54
+ SUDO="sudo"
55
+ ok "sudo ready — system dependencies can be installed"
56
+ else
57
+ warn "sudo authentication failed — continuing with user-space setup only"
58
+ fi
59
+ }
35
60
 
36
61
  # ═══════════════════════════════════════
37
62
  # Step 0: System prerequisites
38
63
  # ═══════════════════════════════════════
39
64
  install_prerequisites() {
40
- local missing=()
41
- for cmd in curl unzip git; do
42
- command -v "$cmd" &>/dev/null || missing+=("$cmd")
43
- done
44
-
45
- if [ ${#missing[@]} -gt 0 ]; then
46
- info "Installing system prerequisites: ${missing[*]}..."
47
- sudo apt-get update -qq
48
- sudo apt-get install -y -qq "${missing[@]}"
49
- ok "Prerequisites installed: ${missing[*]}"
65
+ local packages=(
66
+ curl
67
+ unzip
68
+ git
69
+ ca-certificates
70
+ build-essential
71
+ python3
72
+ make
73
+ g++
74
+ pkg-config
75
+ xdg-utils
76
+ file
77
+ fonts-noto-cjk
78
+ )
79
+
80
+ if [ "$HAS_SUDO" = true ]; then
81
+ info "Installing WSL system prerequisites..."
82
+ $SUDO apt-get update -qq
83
+ $SUDO apt-get install -y -qq "${packages[@]}"
84
+ ok "System prerequisites installed"
50
85
  else
51
- ok "System prerequisites already satisfied (curl, unzip, git)"
86
+ warn "Skipping apt prerequisites (sudo unavailable)"
87
+ warn "Recommended packages: ${packages[*]}"
52
88
  fi
53
89
  }
54
90
 
@@ -98,7 +134,30 @@ install_node() {
98
134
  }
99
135
 
100
136
  # ═══════════════════════════════════════
101
- # Step 2: Install cli-jaw
137
+ # Step 2: Configure user-local npm prefix
138
+ # ═══════════════════════════════════════
139
+ configure_npm_prefix() {
140
+ local prefix="$HOME/.local"
141
+ mkdir -p "$prefix/bin" "$prefix/lib"
142
+ npm config set prefix "$prefix"
143
+ export PATH="$prefix/bin:$PATH"
144
+
145
+ local profile="$HOME/.bashrc"
146
+ [ -f "$HOME/.zshrc" ] && profile="$HOME/.zshrc"
147
+ if ! grep -q 'export PATH="$HOME/.local/bin:$PATH"' "$profile" 2>/dev/null; then
148
+ {
149
+ echo ''
150
+ echo '# CLI-JAW: user-local npm global bin'
151
+ echo 'export PATH="$HOME/.local/bin:$PATH"'
152
+ } >> "$profile"
153
+ ok "Added ~/.local/bin to $profile"
154
+ fi
155
+
156
+ ok "npm global prefix set to $(npm config get prefix)"
157
+ }
158
+
159
+ # ═══════════════════════════════════════
160
+ # Step 3: Install cli-jaw
102
161
  # ═══════════════════════════════════════
103
162
  install_jaw() {
104
163
  if command -v jaw &>/dev/null; then
@@ -111,26 +170,41 @@ install_jaw() {
111
170
  fi
112
171
 
113
172
  ok "cli-jaw installed: $(jaw --version 2>/dev/null || echo 'done')"
173
+ }
114
174
 
115
- # Ensure npm global bin is in PATH
116
- local npm_bin
117
- npm_bin="$(npm config get prefix 2>/dev/null)/bin"
118
- if [ -d "$npm_bin" ] && [[ ":$PATH:" != *":$npm_bin:"* ]]; then
119
- export PATH="$npm_bin:$PATH"
120
- # Persist to shell profile
121
- local profile="$HOME/.bashrc"
122
- [ -f "$HOME/.zshrc" ] && profile="$HOME/.zshrc"
123
- if ! grep -q "npm config get prefix" "$profile" 2>/dev/null; then
124
- echo '' >> "$profile"
125
- echo '# CLI-JAW: npm global bin' >> "$profile"
126
- echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> "$profile"
127
- ok "Added npm global bin to $profile"
128
- fi
175
+ # ═══════════════════════════════════════
176
+ # Step 4: Browser + Office dependencies
177
+ # ═══════════════════════════════════════
178
+ install_browser_deps() {
179
+ info "Installing browser dependencies..."
180
+ npm install -g playwright-core
181
+ ok "playwright-core installed"
182
+
183
+ if [ "$HAS_SUDO" = true ]; then
184
+ info "Installing Chromium (best effort)..."
185
+ $SUDO apt-get install -y -qq chromium-browser 2>/dev/null \
186
+ || $SUDO apt-get install -y -qq chromium 2>/dev/null \
187
+ || warn "Chromium package unavailable Windows Chrome fallback will be used if present"
188
+ else
189
+ warn "Skipping Chromium apt install (sudo unavailable)"
129
190
  fi
130
191
  }
131
192
 
193
+ install_officecli() {
194
+ local global_root
195
+ global_root="$(npm root -g 2>/dev/null || true)"
196
+ local installer="${global_root}/cli-jaw/scripts/install-officecli.sh"
197
+ if [ ! -f "$installer" ]; then
198
+ warn "OfficeCLI installer not found in global package — skipping"
199
+ return 0
200
+ fi
201
+
202
+ info "Installing OfficeCLI..."
203
+ bash "$installer" || warn "OfficeCLI install failed — rerun later: bash \"$installer\""
204
+ }
205
+
132
206
  # ═══════════════════════════════════════
133
- # Step 3: Doctor check
207
+ # Step 5: Doctor check
134
208
  # ═══════════════════════════════════════
135
209
  run_doctor() {
136
210
  info "Running diagnostics..."
@@ -144,15 +218,27 @@ main() {
144
218
  info "Starting CLI-JAW installation on WSL..."
145
219
  echo ""
146
220
 
221
+ ensure_sudo
222
+ echo ""
223
+
147
224
  install_prerequisites
148
225
  echo ""
149
226
 
150
227
  install_node
151
228
  echo ""
152
229
 
230
+ configure_npm_prefix
231
+ echo ""
232
+
153
233
  install_jaw
154
234
  echo ""
155
235
 
236
+ install_browser_deps
237
+ echo ""
238
+
239
+ install_officecli
240
+ echo ""
241
+
156
242
  run_doctor
157
243
  echo ""
158
244
 
@@ -1,39 +0,0 @@
1
- import{t as e}from"./state-O6NVkWcL.js";import{a as t,p as n,t as r}from"./render-C8N0rp4L.js";import{n as i,r as a,t as o}from"./api-Ci-lgwRp.js";import{n as s}from"./ws-Dnn8HG8B.js";import{n as c,r as l,t as u}from"./constants-C8_0OtK2.js";var d={"React/Vue 기반 UI 컴포넌트 개발, 스타일링":`frontend`,"API 서버, DB 스키마, 비즈니스 로직 구현":`backend`,"프론트엔드와 백엔드 모두 담당":`frontend`,"CI/CD, Docker, 인프라 자동화":`backend`,"테스트 작성, 버그 재현, 품질 관리":`custom`,"데이터 파이프라인, ETL, 분석 쿼리":`data`,"API 문서화, README, 가이드 작성":`docs`,"UI/UX 구현, CSS, 컴포넌트 개발":`frontend`,"API, DB, 서버 로직 구현":`backend`,"데이터 파이프라인, 분석, ML":`data`,"문서화, README, API docs":`docs`,"UI/UX, CSS, components":`frontend`,"API, DB, server logic":`backend`,"Search, codebase exploration, uncertainty reduction, read-only reports":`research`,"Search, codebase exploration, uncertainty reduction, read-only":`research`,"Data pipeline, analysis, ML":`data`,"Documentation, README, API docs":`docs`},f={1:`#60a5fa`,2:`#a78bfa`,3:`#34d399`,4:`#fbbf24`,5:`#f472b6`};async function p(){e.employees=await o(`/api/employees`)||[],m()}function m(){let i=document.getElementById(`employeesList`);if(!i)return;let a=e.employees;if(a.length===0){i.innerHTML=`<div style="color:var(--text-dim);font-size:11px;padding:4px 0">${n(`emp.addPrompt`)}</div>`;return}let o=l();i.innerHTML=a.map(e=>{let i=u[e.cli]||[],a=d[e.role||``],l=a?c.find(e=>e.value===a):c.find(t=>t.prompt===e.role),p=l?l.value:e.role?`custom`:`frontend`,m=p===`custom`,h=s(e.id),g=h?.phase||e.phase,_=h?.phaseLabel||e.phaseLabel,v=g?`<span style="background:${f[g]||`#888`};color:#000;padding:1px 6px;border-radius:9px;font-size:9px">${r(_||`P`+g)}</span>`:``;return`
2
- <div class="settings-group" style="margin-bottom:8px;padding:8px 10px">
3
- <div style="display:flex;align-items:center;gap:6px;margin-bottom:6px">
4
- <span style="width:8px;height:8px;border-radius:50%;background:var(--accent);display:inline-block;flex-shrink:0"></span>
5
- <input style="flex:1;background:none;border:none;color:var(--text);font-size:12px;font-weight:600;font-family:inherit;outline:none"
6
- value="${r(e.name||`Agent`)}"
7
- data-emp-name="${r(e.id)}">
8
- <button style="background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:12px" data-emp-delete="${r(e.id)}" title="${n(`emp.delete`)}">${t.close}</button>
9
- </div>
10
- <div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-bottom:4px">
11
- <div>
12
- <label>CLI</label>
13
- <select data-emp-cli="${r(e.id)}">
14
- ${o.map(t=>`<option${e.cli===t?` selected`:``}>${r(t)}</option>`).join(``)}
15
- </select>
16
- </div>
17
- <div>
18
- <label>Model</label>
19
- <select data-emp-model="${r(e.id)}">
20
- <option value="default"${!e.model||e.model===`default`?` selected`:``}>default</option>
21
- ${i.map(t=>`<option${e.model===t?` selected`:``}>${r(t)}</option>`).join(``)}
22
- ${e.model&&e.model!==`default`&&!i.includes(e.model)?`<option selected>${r(e.model)}</option>`:``}
23
- <option value="__custom__">${n(`emp.customModel`)}</option>
24
- </select>
25
- </div>
26
- </div>
27
- <div>
28
- <label>Role</label>
29
- <select data-emp-role="${r(e.id)}">
30
- ${c.map(e=>`<option value="${e.value}"${p===e.value?` selected`:``}>${e.label}</option>`).join(``)}
31
- </select>
32
- <textarea data-emp-custom="${r(e.id)}" style="display:${m?`block`:`none`};margin-top:4px;width:100%;height:40px;background:var(--bg);border:1px solid var(--border);color:var(--text);padding:4px 6px;border-radius:4px;font-size:10px;font-family:inherit;resize:vertical"
33
- placeholder="${n(`emp.customRole`)}">${m?r(e.role||``):``}</textarea>
34
- </div>
35
- <div style="margin-top:4px;font-size:10px;display:flex;align-items:center;gap:6px">
36
- <span style="color:${e.status===`running`?`#fbbf24`:`var(--green)`}"><span style="display:inline-block;width:6px;height:6px;border-radius:50%;background:currentColor;vertical-align:middle;margin-right:4px"></span>${r(e.status||`idle`)}</span>
37
- ${v}
38
- </div>
39
- </div>`}).join(``)}async function h(){await a(`/api/employees`,`POST`,{})}async function g(e,t){await a(`/api/employees/${e}`,`PUT`,t)}async function _(e){i(`/api/employees/${e}`,`DELETE`)}function v(e,t){let i=u[t]||[],a=document.querySelector(`[data-emp-model="${e}"]`);a&&(a.innerHTML=`<option value="default" selected>default</option>`+i.map(e=>`<option>${r(e)}</option>`).join(``)+`<option value="__custom__">${n(`emp.customModel`)}</option>`),g(e,{cli:t,model:t===`claude`?`sonnet`:`default`})}function y(e,t){let n=c.find(e=>e.value===t),r=document.querySelector(`[data-emp-custom="${e}"]`);r&&(t===`custom`?(r.style.display=`block`,r.focus()):(r.style.display=`none`,r.value=``,g(e,{role:n?.prompt||``})))}export{h as addEmployee,_ as deleteEmployee,p as loadEmployees,v as onEmpCliChange,y as onEmpRoleChange,m as renderEmployees,g as updateEmployee};
@@ -1,49 +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{Z as r}from"./vendor-mermaid-lvHqQdfg.js";import{a as i,c as a,d as o,f as s,p as c,r as l,t as u,u as d}from"./render-C8N0rp4L.js";import{_ as ee,g as te,h as ne,n as f,o as re,p as ie,s as ae,t as p,v as oe}from"./ui-D-oFkXed.js";import{n as se,r as m,t as h}from"./api-Ci-lgwRp.js";import{t as ce}from"./ws-Dnn8HG8B.js";import{t as le}from"./locale-DIXc-_34.js";import{a as ue,i as de,n as fe,o as pe,r as me,t as he}from"./slash-commands-DWvL-VDU.js";import{i as ge,t as _e}from"./skills-uywskdFh.js";import{a as ve,r as ye}from"./constants-C8_0OtK2.js";import{A as be,D as xe,E as g,M as Se,N as Ce,O as we,S as Te,T as Ee,a as De,b as Oe,c as ke,f as Ae,g as _,h as je,i as Me,j as Ne,k as Pe,l as Fe,m as Ie,n as Le,o as Re,p as ze,r as Be,s as Ve,t as v,u as He,w as Ue,y as We}from"./settings-BJR-IGM5.js";var y=[];function Ge(e){return/^\/compact(?:\s|$)/i.test(String(e||``).trim())?300*1e3:1e4}async function b(){let e=document.getElementById(`chatInput`),t=document.getElementById(`btnSend`);if(!e||!t)return;let a=document.activeElement===t;if(t.classList.contains(`stop-mode`)&&a&&!e.value.trim()&&!n.attachedFiles.length){se(`/api/stop`,`POST`);return}let o=e.value.trim();if(!o&&!n.attachedFiles.length)return;let s=o.slice(1).trim().split(/\s+/)[0]||``,l=s.includes(`/`)||s.includes(`\\`);if(o.startsWith(`/`)&&!n.attachedFiles.length&&!l){e.value=``,w(),he();try{let e,t,n=Ge(o);if(typeof AbortSignal?.timeout==`function`)e=AbortSignal.timeout(n);else{let r=new AbortController;e=r.signal,t=setTimeout(()=>r.abort(),n)}let r=le(),i=await fetch(`/api/command`,{method:`POST`,headers:{"Content-Type":`application/json`,"Accept-Language":r},body:JSON.stringify({text:o,locale:r}),signal:e});t&&clearTimeout(t);let a=await i.json().catch(()=>({}));if(a?.code===`not_command`){p(`user`,o),await m(`/api/message`,`POST`,{prompt:o});return}if(!i.ok&&!a?.text)throw Error(`HTTP ${i.status}`);if(a?.code===`clear_screen`){te().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``)}a?.text&&f(u(a.text),``,a.type)}catch(e){f(c(`chat.cmd.fail`,{msg:e.message}),``,`error`)}return}if(n.attachedFiles.length){p(`user`,`📎 [${n.attachedFiles.map(e=>e.name).join(`, `)}] ${o}`),e.value=``,w();try{let e=(await Promise.all(n.attachedFiles.map(e=>qe(e)))).map(e=>c(`chat.file.sent`,{path:e})).join(`
3
- `);o&&(e+=c(`chat.file.sentWithMsg`,{text:o})),S(),await m(`/api/message`,`POST`,{prompt:e})}catch(e){f(c(`chat.file.uploadFail`,{msg:e.message})),S()}}else{p(`user`,o),e.value=``,w();let t=await fetch(`/api/message`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:o})}),n=await t.json().catch(()=>({}));if(!t.ok){f(`${i.error} ${u(n.error||c(`chat.requestFail`,{status:t.status}))}`,``,`error`);return}if(n.queued){let{updateQueueBadge:e}=await r(async()=>{let{updateQueueBadge:e}=await import(`./ui-C1daR00l.js`);return{updateQueueBadge:e}},__vite__mapDeps([0]));e(n.pending||1)}else n.continued&&f(c(`chat.continue`))}}function Ke(e){e.key===`Enter`&&!e.shiftKey&&!e.isComposing&&(e.preventDefault(),b())}async function qe(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 x(e){for(let t of e)n.attachedFiles.some(e=>e.name===t.name)||n.attachedFiles.push(t);C(),document.getElementById(`chatInput`)?.focus()}function Je(e){n.attachedFiles.splice(e,1),C()}function S(){y.forEach(e=>URL.revokeObjectURL(e)),y=[],n.attachedFiles=[],C();let e=document.getElementById(`fileInput`);e&&(e.value=``)}function C(){let e=document.getElementById(`filePreview`),t=document.getElementById(`filePreviewList`);if(e){if(y.forEach(e=>URL.revokeObjectURL(e)),y=[],!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/`),a=``;if(r){let t=URL.createObjectURL(e);y.push(t),a=`<img src="${t}" class="file-chip-thumb" alt="">`}return`<div class="file-chip">
4
- ${a}
5
- <span class="file-chip-name">${i.paperclip} ${u(e.name)} (${n}KB)</span>
6
- <button class="file-chip-remove" data-file-idx="${t}" title="Remove">${i.close}</button>
7
- </div>`}).join(``))}}async function Ye(){se(`/api/clear`,`POST`),te().clear();let e=document.getElementById(`chatMessages`);e&&(e.innerHTML=``);let{cleanupToolActivity:t}=await r(async()=>{let{cleanupToolActivity:e}=await import(`./ui-C1daR00l.js`);return{cleanupToolActivity:e}},__vite__mapDeps([0]));t(),ee().catch(()=>{})}var Xe=0;function Ze(e){Xe||=requestAnimationFrame(()=>{Xe=0,e.style.height=`auto`,e.style.height=e.scrollHeight+`px`})}function Qe(){let e=document.getElementById(`chatInput`);e&&e.addEventListener(`input`,()=>Ze(e))}function w(){let e=document.getElementById(`chatInput`);e&&(e.style.height=`auto`)}function $e(){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&&x(r)}),document.getElementById(`fileInput`)?.addEventListener(`change`,e=>{let t=e.target,n=[...t.files||[]];n.length&&x(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(),x(n))})}async function et(e,t,r){let a=document.getElementById(`chatInput`),o=a?.value.trim()||``,s=[...n.attachedFiles],l=[`🎤 [음성 메시지]`];s.length&&l.push(`📎 [${s.map(e=>e.name).join(`, `)}]`),o&&l.push(o),p(`user`,l.join(` `)),a&&o&&(a.value=``,w()),s.length&&S();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 a=await n.json().catch(()=>null);if(!a?.text)throw Error(`Empty STT result`);f(`${i.mic} STT (${u(a.engine||``)}, ${a.elapsed?.toFixed(1)}s): "${u(a.text.slice(0,100))}"`,``,`info`);let l=[];s.length&&(l=await Promise.all(s.map(e=>qe(e))));let d=[];for(let e of l)d.push(c(`chat.file.sent`,{path:e}));d.push(`🎤 ${a.text}`),o&&d.push(o),await m(`/api/message`,`POST`,{prompt:d.join(`
8
- `)})}catch(e){f(c(`voice.sttFail`,{msg:e.message}),``,`error`)}}var tt={sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},nt={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 rt(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 it(e){let t=e&&typeof e==`object`?e:{},n=t.kind,r=typeof t.timeZone==`string`?t.timeZone.trim():``,i=rt(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=at(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 at(e){try{let[t,n,r,i,a]=ot(e);return T(t,{min:0,max:59}),T(n,{min:0,max:23}),T(r,{min:1,max:31}),T(i,{min:1,max:12,aliases:nt}),T(a,{min:0,max:7,aliases:tt,normalize:lt}),null}catch(e){return e.message}}function ot(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 T(e,t){for(let n of e.split(`,`))st(n.trim(),t)}function st(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,ct(r,`invalid cron step "${r}"`)}if(n!==`*`){if(n.includes(`-`)){let[e,r,...i]=n.split(`-`);if(!e||!r||i.length>0||E(e,t)>E(r,t))throw Error(`invalid cron range "${n}"`);return}E(n,t)}}function E(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(!ut(i,t.min,t.max))throw Error(`cron value "${e}" out of range ${t.min}-${t.max}`);return i}function ct(e,t){let n=Number(e);if(!Number.isInteger(n)||n<=0)throw Error(t);return n}function lt(e){return e===7?0:e}function ut(e,t,n){return e>=t&&e<=n}async function dt(){n.heartbeatJobs=((await h(`/api/heartbeat`))?.jobs||[]).map(k),n.heartbeatErrors=j(n.heartbeatJobs),D(),document.getElementById(`heartbeatModal`)?.classList.add(`open`)}function ft(e){e&&e.target!==e.currentTarget||document.getElementById(`heartbeatModal`)?.classList.remove(`open`)}function D(){let e=document.getElementById(`hbJobsList`);if(!e)return;let t=n.heartbeatJobs.map(k);n.heartbeatJobs=t,n.heartbeatErrors=j(t),t.length===0?e.innerHTML=`<p style="color:var(--text-dim);font-size:12px;text-align:center">${c(`hb.empty`)}</p>`:e.innerHTML=t.map((e,t)=>{let r=_t(e.schedule),a=r.kind===`cron`,o=n.heartbeatErrors[e.id],s=o||Ct(r),l=o?`hb-schedule-meta hb-error`:`hb-schedule-meta hb-help`,d=a?`<input type="text" value="${u(r.cron)}" placeholder="${u(c(`hb.cronPlaceholder`))}"
9
- data-hb-cron="${t}">`:`<input type="number" value="${r.minutes}" min="1" data-hb-minutes="${t}">`,ee=a?`<span class="hb-chip">${u(c(`hb.cronLabel`))}</span>`:`<span class="hb-chip">${u(c(`hb.minutesLabel`))}</span>`;return`
10
- <div class="hb-job-card">
11
- <div class="hb-job-header">
12
- <input type="text" value="${u(String(e.name||``))}" placeholder="${u(c(`hb.name`))}"
13
- data-hb-name="${t}">
14
- <button class="hb-toggle ${e.enabled?`on`:`off`}"
15
- data-hb-toggle="${t}" aria-label="${u(String(e.name||`job`)+` toggle`)}"></button>
16
- <button class="hb-del" data-hb-remove="${t}">${i.close}</button>
17
- </div>
18
- <div class="hb-job-schedule">
19
- <select data-hb-kind="${t}">
20
- <option value="every"${a?``:` selected`}>${u(c(`hb.kindEvery`))}</option>
21
- <option value="cron"${a?` selected`:``}>${u(c(`hb.kindCron`))}</option>
22
- </select>
23
- ${d}
24
- ${ee}
25
- <input type="text" value="${u(r.timeZone||``)}" placeholder="${u(bt())}"
26
- data-hb-timezone="${t}">
27
- </div>
28
- <p class="${l}">${u(s)}</p>
29
- <textarea class="hb-prompt" rows="2" placeholder="${u(c(`hb.prompt`))}"
30
- data-hb-prompt="${t}">${u(String(e.prompt||``))}</textarea>
31
- </div>
32
- `}).join(``);let r=t.filter(e=>e.enabled).length,a=document.getElementById(`hbSidebarBtn`);a&&(a.innerHTML=`${i.heartPulse} Heartbeat (${r})`)}function pt(){n.heartbeatJobs.push({id:`hb_`+Date.now(),name:``,enabled:!0,schedule:yt({kind:`every`,minutes:5}),prompt:``}),D(),O()}function mt(e){n.heartbeatJobs.splice(e,1),D(),O()}function ht(e){let t=n.heartbeatJobs[e];t&&(t.enabled=!t.enabled,D(),O())}async function O(){let e=n.heartbeatJobs.map(k);if(n.heartbeatJobs=e,n.heartbeatErrors=j(e),Object.keys(n.heartbeatErrors).length>0){D();return}let t=await m(`/api/heartbeat`,`PUT`,{jobs:e});t?.jobs&&(n.heartbeatJobs=t.jobs.map(k),n.heartbeatErrors=j(n.heartbeatJobs),D())}async function gt(){try{let e=((await h(`/api/heartbeat`))?.jobs||[]).map(k).filter(e=>e.enabled).length,t=document.getElementById(`hbSidebarBtn`);t&&(t.innerHTML=`${i.heartPulse} Heartbeat (${e})`)}catch{}}function k(e){return{id:String(e.id||`hb_${Date.now()}`),name:String(e.name||``),enabled:e.enabled!==!1,schedule:_t(e.schedule),prompt:String(e.prompt||``)}}function _t(e){let t=vt(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 vt(e){return(typeof e==`string`?e.trim():``)||void 0}function yt(e){let t=A();return t?{...e,timeZone:t}:e}function A(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||void 0}catch{return}}function bt(){let e=A();return e?`${c(`hb.timezoneAuto`)} ${e}`:c(`hb.timezoneAuto`)}function j(e){let t={};for(let n of e){let e=xt(n);e&&(t[n.id]=e)}return t}function xt(e){let t=it(e.schedule);return t.ok?null:St(t.code,t.error)}function St(e,t){switch(e){case`invalid_cron`:return c(`hb.invalidCron`);case`invalid_timezone`:return c(`hb.invalidTimeZone`);case`invalid_minutes`:return c(`hb.invalidMinutes`);default:return t||c(`hb.invalidSchedule`)}}function Ct(e){let t=e.timeZone||A()||`Asia/Seoul`;return e.kind===`cron`?c(`hb.scheduleHintCron`,{cron:`0 9 * * *`,timeZone:t}):c(`hb.scheduleHintEvery`,{minutes:e.minutes,timeZone:t})}function M(e){return document.getElementById(e)}function N(e,t){let n=M(e);n&&(n.textContent=t==null?``:String(t))}function P(e,t){let n=M(e);n&&(n.value=t==null?``:String(t))}function wt(e,t){let n=M(`memorySidebarBtn`);if(!n)return;let r=e?.indexState===`ready`?`Ready`:e?.state===`not_initialized`?`Indexing`:e?.state||`(${t})`;n.innerHTML=`${i.brain} Memory · ${u(r)}`}function Tt(e){let t=M(`advStatusBanner`);if(t){if(!e?.enabled){t.style.display=`none`,t.textContent=``;return}if(t.style.display=``,e.state===`not_initialized`){t.textContent=`Integrated memory is preparing its index. Temporary fallback memory context is active until initialization completes.`;return}if(e.indexState===`not_indexed`){t.textContent=`Integrated memory is configured. Indexed search/read will activate after indexing becomes available.`;return}t.textContent=`Memory active. search/read=${e.routing?.searchRead||`basic`} / save=${e.routing?.save||`basic`}`}}function Et(e,t=!0){let n=M(`advStatusBanner`);n&&(n.style.display=t?``:`none`,n.textContent=e)}function F(e){for(let t of[`advBootstrapBtn`,`advReindexBtn`,`advReimportBtn`,`advOpenCorruptedBtn`]){let n=M(t);n&&(n.disabled=e)}}function Dt(e){M(`memOn`)?.classList.toggle(`active`,e.enabled),M(`memOff`)?.classList.toggle(`active`,!e.enabled),P(`memFlushEvery`,e.flushEvery),P(`memCli`,e.cli||``),P(`memModel`,e.model||``),P(`memRetention`,e.retentionDays),N(`memPath`,e.path),N(`memCounter`,e.counter),N(`memThreshold`,e.flushEvery)}function Ot(e){let t=M(`memTabBtnSettings`),n=M(`memTabSettings`);!t||!n||(t.style.display=``,n.style.display||(n.style.display=``))}function kt(e){N(`advIndexState`,e?.indexState||e?.state||`-`),N(`advStorageRoot`,e?.storageRoot||`-`),N(`advIndexedFiles`,e?.indexedFiles||0),N(`advIndexedChunks`,e?.indexedChunks||0),N(`advLastIndexedAt`,e?.lastIndexedAt||`-`),N(`advImportStatus`,e?.importStatus||`-`),N(`advCorruptedCount`,e?.corruptedCount||0),N(`advLastExpansion`,(e?.lastExpansion||[]).join(`, `)||`-`),N(`advLastError`,e?.lastError||`-`);let t=e?.importedCounts||{};N(`advImportStatus`,`${e?.importStatus||`-`} (core:${t.core||0} md:${t.markdown||0} kv:${t.kv||0} claude:${t.claude||0})`)}function At(e){let t=M(`basicMemoryFiles`);if(t){if(!e?.length){t.innerHTML=`<p style="color:var(--text-dim);font-size:12px;text-align:center">No memory files yet</p>`;return}t.innerHTML=e.map(e=>`
33
- <div style="display:flex;align-items:center;justify-content:space-between;padding:6px 8px;border:1px solid var(--border);border-radius:4px;margin-bottom:4px;cursor:pointer"
34
- data-mem-view="${u(e.name)}">
35
- <div>
36
- <span style="font-size:12px;font-family:monospace">${u(e.name)}</span>
37
- <span style="font-size:10px;color:var(--accent);margin-left:6px">${e.entries} entries</span>
38
- </div>
39
- <button data-mem-delete="${u(e.name)}" style="background:none;border:none;color:#f55;cursor:pointer;font-size:14px">${i.trash}</button>
40
- </div>
41
- `).join(``)}}function I(e,t){let n=M(e);if(n){if(!t?.length){n.innerHTML=`<p style="color:var(--text-dim);font-size:12px;text-align:center">No files</p>`;return}n.innerHTML=t.map(e=>`<div style="padding:6px 8px;border:1px solid var(--border);border-radius:4px;margin-bottom:4px">
42
- <span style="font-size:12px;font-family:monospace">${u(e)}</span>
43
- </div>`).join(``)}}function jt(e){I(`advancedMemoryFiles`,[...e?.sections?.profile||[],...e?.sections?.shared||[],...e?.sections?.episodes||[],...e?.sections?.semantic||[],...e?.sections?.procedures||[],...e?.sections?.sessions||[]]),I(`corruptedMemoryFiles`,e?.sections?.corrupted||[]),I(`legacyUnmappedFiles`,e?.sections?.legacyUnmapped||[])}function Mt(){return{importCore:M(`advImportCore`)?.checked!==!1,importMarkdown:M(`advImportMarkdown`)?.checked!==!1,importKv:M(`advImportKv`)?.checked!==!1,importClaudeSession:M(`advImportClaudeSession`)?.checked!==!1}}async function Nt(){let[e,t,n]=await Promise.all([h(`/api/memory-files`),h(`/api/memory/status`),h(`/api/memory/files`)]);return{basic:e,status:t,files:n}}async function L(){let{basic:e,status:t,files:n}=await Nt();e&&(Dt(e),Ot(t),Tt(t),kt(t),At(e.files),jt(n),wt(t,e.files.length),M(`memoryModal`)?.classList.add(`open`),R(`status`))}function Pt(e){e&&e.target!==e.currentTarget||M(`memoryModal`)?.classList.remove(`open`)}function R(e){let t={settings:`memTabSettings`,status:`memTabAdvOps`,files:`memTabFiles`};for(let n of Object.values(t)){let r=M(n);r&&(r.style.display=n===t[e]?``:`none`)}M(`memTabBtnSettings`)?.classList.toggle(`active`,e===`settings`),M(`memTabBtnAdvOps`)?.classList.toggle(`active`,e===`status`),M(`memTabBtnFiles`)?.classList.toggle(`active`,e===`files`),M(`memTabBtnSettings`)?.setAttribute(`aria-selected`,String(e===`settings`)),M(`memTabBtnAdvOps`)?.setAttribute(`aria-selected`,String(e===`status`)),M(`memTabBtnFiles`)?.setAttribute(`aria-selected`,String(e===`files`))}async function Ft(e){M(`memOn`)?.classList.toggle(`active`,e),M(`memOff`)?.classList.toggle(`active`,!e),await m(`/api/memory-files/settings`,`PUT`,{enabled:e})}async function z(){let e=M(`memFlushEvery`),t=M(`memCli`),n=M(`memModel`),r=M(`memRetention`);await m(`/api/memory-files/settings`,`PUT`,{flushEvery:+(e?.value||10),cli:t?.value||``,model:n?.value||``,retentionDays:+(r?.value||30)});let i=M(`memThreshold`);i&&e&&(i.textContent=e.value)}async function It(){F(!0),Et(`메모리 bootstrap을 다시 실행하는 중...`,!0);let e=await m(`/api/memory/bootstrap`,`POST`,Mt());F(!1),e?.message&&alert(e.message),await L(),R(`status`)}async function Lt(){F(!0),Et(`메모리 인덱스를 재생성하는 중...`,!0);let e=await m(`/api/memory/reindex`,`POST`,{});F(!1),e?.message&&alert(e.message),await L(),R(`status`)}function Rt(){let e=M(`advStorageRoot`)?.textContent||``,t=e?`${e}/corrupted`:`JAW_HOME/memory/structured/corrupted`;navigator.clipboard?.writeText&&navigator.clipboard.writeText(t).catch(()=>{}),alert(`Corrupted folder path copied/shown:\n${t}`)}async function zt(e){confirm(`Delete `+e+`?`)&&(await m(`/api/memory-file?path=`+encodeURIComponent(e),`DELETE`,{}),L())}async function Bt(e){let t=await h(`/api/memory-file?path=`+encodeURIComponent(e));if(!t)return;let n=M(`basicMemoryFiles`);n&&(n.innerHTML=`
44
- <div style="margin-bottom:8px;display:flex;justify-content:space-between;align-items:center">
45
- <span style="font-size:12px;font-weight:600">${u(t.name)}</span>
46
- <button data-mem-back style="background:none;border:none;color:var(--accent);cursor:pointer;font-size:11px">${i.arrowLeft} back</button>
47
- </div>
48
- <pre style="background:var(--bg);padding:8px;border-radius:4px;font-size:11px;white-space:pre-wrap;max-height:50vh;overflow-y:auto;color:var(--text)">${u(t.content)}</pre>
49
- `)}var B=`sidebarState`,Vt=900,Ht=768;function Ut(){return window.innerWidth<=Ht}function V(){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(B)||`{}`)}catch{}e.left&&document.body.classList.add(`left-collapsed`),e.right&&document.body.classList.add(`right-collapsed`);let t=Ut();document.getElementById(`toggleLeft`)?.addEventListener(`click`,U),document.getElementById(`toggleRight`)?.addEventListener(`click`,W),window.addEventListener(`resize`,()=>{let e=Ut();if(window.innerWidth>Vt){V();let e={};try{e=JSON.parse(localStorage.getItem(B)||`{}`)}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&&V();t=e,G()}),window.innerWidth<=Vt&&(document.body.classList.remove(`left-collapsed`,`right-collapsed`),Ut()&&V()),G()}function H(){return window.innerWidth<=Vt}function U(){H()?Wt(`left`):document.body.classList.toggle(`left-collapsed`),Jt(),G()}function W(){H()?Wt(`right`):document.body.classList.toggle(`right-collapsed`),Jt(),G()}function Kt(){return H()?document.body.classList.contains(`left-expanded`):!document.body.classList.contains(`left-collapsed`)}function qt(){return H()?document.body.classList.contains(`right-expanded`):!document.body.classList.contains(`right-collapsed`)}function G(){let e=document.getElementById(`toggleLeft`),t=document.getElementById(`toggleRight`);e&&(e.innerHTML=Kt()?i.chevronLeft:i.chevronRight),t&&(t.innerHTML=qt()?i.chevronRight:i.chevronLeft)}function Jt(){localStorage.setItem(B,JSON.stringify({left:document.body.classList.contains(`left-collapsed`),right:document.body.classList.contains(`right-collapsed`)}))}var Yt=`theme`,K=null;function Xt(n){let r=n===`light`?t:e;K||(K=document.createElement(`style`),K.id=`hljsTheme`,document.head.appendChild(K)),K.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),ne(),l()}var en=50,tn=30,nn=80,rn=500,q=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`),q={startX:t.clientX,startY:t.clientY,startTime:Date.now(),isEdge:r}}function cn(e){if(!q)return;let t=e.changedTouches[0],n=t.clientX-q.startX,r=Math.abs(t.clientY-q.startY),i=Date.now()-q.startTime,a=q;q=null,!(r>nn||i>rn||Math.abs(n)<en)&&(n>0&&a.isEdge===`left`&&U(),n<0&&a.isEdge===`right`&&W())}var J=!1,Y=null,X=[],Z=null,ln=null,un=0;function dn(){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 fn(e){let t=e;switch(t.name){case`NotAllowedError`:return c(`voice.micDenied`);case`NotFoundError`:return c(`voice.micNotFound`);case`NotReadableError`:case`AbortError`:return c(`voice.micBusy`);default:return t instanceof TypeError||!navigator.mediaDevices?c(`voice.httpsRequired`):c(`voice.micDenied`)}}async function pn(){if(n.isRecording)return;if(typeof MediaRecorder>`u`||!navigator.mediaDevices?.getUserMedia){f(c(`voice.unsupported`),``,`error`);return}try{Z=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){f(fn(e),``,`error`);return}let e=dn();Y=new MediaRecorder(Z,e?{mimeType:e}:{}),X=[],Y.ondataavailable=e=>{e.data.size>0&&X.push(e.data)},Y.onerror=()=>{mn(),f(c(`voice.interrupted`),``,`error`)},Y.onstop=async()=>{if(J){X=[],_n(),J=!1;return}let t=Y?.mimeType||e||`audio/webm`,n=t.includes(`mp4`)?`.m4a`:t.includes(`ogg`)?`.ogg`:`.webm`,r=new Blob(X,{type:t});if(X=[],_n(),r.size>20*1024*1024){f(c(`voice.tooLarge`),``,`error`);return}if(r.size<1e3){f(c(`voice.tooShort`),``,`error`);return}await et(r,n,t)},Y.start(),n.isRecording=!0,un=Date.now(),bn(!0),vn()}function mn(){!n.isRecording||!Y||(Y.state===`recording`&&Y.stop(),n.isRecording=!1,yn(),bn(!1))}function hn(){!n.isRecording||!Y||(J=!0,Y.state===`recording`&&Y.stop(),n.isRecording=!1,yn(),bn(!1))}function gn(){n.isRecording?mn():pn()}function _n(){Z?.getTracks().forEach(e=>e.stop()),Z=null}function vn(){let e=document.getElementById(`voiceTimer`);e&&(e.style.display=`inline`,ln=setInterval(()=>{let t=Math.floor((Date.now()-un)/1e3);e.textContent=`${String(Math.floor(t/60)).padStart(2,`0`)}:${String(t%60).padStart(2,`0`)}`},500))}function yn(){ln&&=(clearInterval(ln),null);let e=document.getElementById(`voiceTimer`);e&&(e.style.display=`none`,e.textContent=`00:00`)}function bn(e){let t=document.getElementById(`btnVoice`),n=document.getElementById(`btnVoiceCancel`);t&&(t.classList.toggle(`recording`,e),t.innerHTML=e?i.stop:i.mic,t.title=c(e?`voice.stop`:`voice.start`)),n&&(n.style.display=e?`inline-block`:`none`)}window.addEventListener(`unhandledrejection`,e=>{console.error(`[unhandled]`,e.reason),e.preventDefault()}),window.addEventListener(`error`,e=>{console.error(`[error]`,e.message,e.filename,e.lineno)});var{loadEmployees:xn,addEmployee:Sn,deleteEmployee:Cn,updateEmployee:Q,onEmpCliChange:wn,onEmpRoleChange:Tn}=await r(async()=>{let{loadEmployees:e,addEmployee:t,deleteEmployee:n,updateEmployee:r,onEmpCliChange:i,onEmpRoleChange:a}=await import(`./employees-D5n7mX5v.js`);return{loadEmployees:e,addEmployee:t,deleteEmployee:n,updateEmployee:r,onEmpCliChange:i,onEmpRoleChange:a}},__vite__mapDeps([0]));document.getElementById(`btnSend`)?.addEventListener(`click`,b);var En=document.getElementById(`chatInput`);En?.addEventListener(`keydown`,e=>{me(e)||Ke(e)});var $=0;En?.addEventListener(`input`,e=>{e.isComposing||($&&cancelAnimationFrame($),$=requestAnimationFrame(()=>{pe(e.target?.value||``),$=0}))}),En?.addEventListener(`cmd-execute`,()=>{b()}),document.getElementById(`cmdDropdown`)?.addEventListener(`click`,fe),document.addEventListener(`click`,de),document.getElementById(`filePreviewClear`)?.addEventListener(`click`,S),document.getElementById(`filePreviewList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-file-idx]`);t&&Je(+(t.dataset.fileIdx||`0`))}),document.querySelector(`.btn-attach`)?.addEventListener(`click`,()=>{document.getElementById(`fileInput`)?.click()}),document.getElementById(`btnVoice`)?.addEventListener(`click`,()=>gn()),document.getElementById(`btnVoiceCancel`)?.addEventListener(`click`,()=>hn()),document.getElementById(`memorySidebarBtn`)?.addEventListener(`click`,L),document.getElementById(`btnClearChat`)?.addEventListener(`click`,Ye),document.getElementById(`hbSidebarBtn`)?.addEventListener(`click`,dt),document.getElementById(`langToggle`)?.addEventListener(`click`,async()=>{let e=d()===`ko`?`en`:`ko`;await s(e);let t=document.getElementById(`langToggle`);t&&(t.innerHTML=`${i.web} ${c(`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]&&ie(r[n],t)}),document.querySelector(`.sidebar-save-bar .btn-save`)?.addEventListener(`click`,re),document.getElementById(`selCli`)?.addEventListener(`change`,()=>Ie()),document.getElementById(`selModel`)?.addEventListener(`change`,()=>je()),document.getElementById(`selEffort`)?.addEventListener(`change`,()=>je()),document.querySelector(`[data-action="addEmployee"]`)?.addEventListener(`click`,Sn),document.getElementById(`employeesList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-emp-delete]`);if(t){Cn(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){wn(r.dataset.empCli||``,t.value);return}let i=t.closest(`[data-emp-model]`);if(i){if(t.value===`__custom__`){let e=prompt(c(`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){Tn(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&&ge(t.dataset.skillId||``,t.dataset.skillEnabled===`true`)}),document.querySelector(`#tabSkills`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`.skill-filter`);t&&_e(t.dataset.filter||`all`,t)}),document.querySelector(`[data-action="openPrompt"]`)?.addEventListener(`click`,Be),document.getElementById(`tgOff`)?.addEventListener(`click`,()=>Ce(!1)),document.getElementById(`tgOn`)?.addEventListener(`click`,()=>Ce(!0)),document.getElementById(`tgForwardOff`)?.addEventListener(`click`,()=>Se(!1)),document.getElementById(`tgForwardOn`)?.addEventListener(`click`,()=>Se(!0)),document.getElementById(`tgToken`)?.addEventListener(`change`,Ne),document.getElementById(`tgChatIds`)?.addEventListener(`change`,Ne),document.getElementById(`chTelegram`)?.addEventListener(`click`,()=>Ee(`telegram`)),document.getElementById(`chDiscord`)?.addEventListener(`click`,()=>Ee(`discord`)),document.getElementById(`dcOff`)?.addEventListener(`click`,()=>xe(!1)),document.getElementById(`dcOn`)?.addEventListener(`click`,()=>xe(!0)),document.getElementById(`dcForwardOff`)?.addEventListener(`click`,()=>Pe(!1)),document.getElementById(`dcForwardOn`)?.addEventListener(`click`,()=>Pe(!0)),document.getElementById(`dcAllowBotsOff`)?.addEventListener(`click`,()=>we(!1)),document.getElementById(`dcAllowBotsOn`)?.addEventListener(`click`,()=>we(!0)),document.getElementById(`dcMentionOff`)?.addEventListener(`click`,()=>be(!1)),document.getElementById(`dcMentionOn`)?.addEventListener(`click`,()=>be(!0)),document.getElementById(`dcToken`)?.addEventListener(`change`,g),document.getElementById(`dcGuildId`)?.addEventListener(`change`,g),document.getElementById(`dcChannelIds`)?.addEventListener(`change`,g),document.getElementById(`fallbackOrderList`)?.addEventListener(`change`,Ue);function Dn(e){let t=document.getElementById(`codexFastOn`),n=document.getElementById(`codexFastOff`);t&&n&&(t.classList.toggle(`active`,e),n.classList.toggle(`active`,!e)),_()}document.getElementById(`codexFastOn`)?.addEventListener(`click`,()=>Dn(!0)),document.getElementById(`codexFastOff`)?.addEventListener(`click`,()=>Dn(!1));function On(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`),_()}document.getElementById(`codexCtxOn`)?.addEventListener(`click`,()=>On(!0)),document.getElementById(`codexCtxOff`)?.addEventListener(`click`,()=>On(!1)),document.getElementById(`codexCtxWindow`)?.addEventListener(`change`,_),document.getElementById(`codexCtxCompact`)?.addEventListener(`change`,_);function kn(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)),_()}document.getElementById(`claude1mOn`)?.addEventListener(`click`,()=>kn(!0)),document.getElementById(`claude1mOff`)?.addEventListener(`click`,()=>kn(!1));function An(){for(let e of ye()){let t=e.charAt(0).toUpperCase()+e.slice(1),n=document.getElementById(`model`+t);n&&n.addEventListener(`change`,function(){Ae(e,this)});let r=document.getElementById(`customModel`+t);r&&r.addEventListener(`change`,function(){He(e,this)});let i=document.getElementById(`effort`+t);i&&i.addEventListener(`change`,_)}}document.querySelector(`[data-action="syncMcp"]`)?.addEventListener(`click`,Te),document.querySelector(`[data-action="installMcp"]`)?.addEventListener(`click`,Oe),document.querySelector(`[data-action="refreshCli"]`)?.addEventListener(`click`,()=>Fe(!0)),document.getElementById(`cliStatusInterval`)?.addEventListener(`change`,function(){localStorage.setItem(`cliStatusInterval`,this.value)}),document.getElementById(`promptModal`)?.addEventListener(`click`,e=>v(e)),document.querySelector(`#promptModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closePrompt"]`)?.addEventListener(`click`,()=>v()),document.querySelector(`[data-action="cancelPrompt"]`)?.addEventListener(`click`,()=>v()),document.querySelector(`[data-action="savePrompt"]`)?.addEventListener(`click`,De),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&!n.isRecording&&v()}),document.querySelector(`[data-action="openTemplates"]`)?.addEventListener(`click`,Me),document.querySelector(`[data-action="saveTemplate"]`)?.addEventListener(`click`,Re),document.querySelector(`[data-action="closeTemplate"]`)?.addEventListener(`click`,()=>Le()),document.getElementById(`templateModal`)?.addEventListener(`click`,e=>Le(e)),document.querySelector(`#templateModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.getElementById(`templateBack`)?.addEventListener(`click`,Ve),document.getElementById(`templateDevToggle`)?.addEventListener(`click`,ke),document.getElementById(`heartbeatModal`)?.addEventListener(`click`,e=>ft(e)),document.querySelector(`#heartbeatModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closeHeartbeat"]`)?.addEventListener(`click`,()=>ft()),document.querySelector(`[data-action="addHeartbeat"]`)?.addEventListener(`click`,pt),document.getElementById(`hbJobsList`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-hb-toggle]`);if(t){ht(+(t.dataset.hbToggle||`0`));return}let n=e.target?.closest(`[data-hb-remove]`);if(n){mt(+(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,O();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}:{}},D(),O();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}:{}},D(),O();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}:{}},D(),O();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()}:{}},D(),O();return}let c=t.closest(`[data-hb-prompt]`);if(c){n.heartbeatJobs[+(c.dataset.hbPrompt||`0`)].prompt=t.value,O();return}}),document.getElementById(`memoryModal`)?.addEventListener(`click`,e=>Pt(e)),document.querySelector(`#memoryModal .modal-box`)?.addEventListener(`click`,e=>e.stopPropagation()),document.querySelector(`[data-action="closeMemory"]`)?.addEventListener(`click`,()=>Pt()),document.getElementById(`memTabBtnSettings`)?.addEventListener(`click`,()=>R(`settings`)),document.getElementById(`memTabBtnAdvOps`)?.addEventListener(`click`,()=>R(`status`)),document.getElementById(`memTabBtnFiles`)?.addEventListener(`click`,()=>R(`files`)),document.getElementById(`memOn`)?.addEventListener(`click`,()=>Ft(!0)),document.getElementById(`memOff`)?.addEventListener(`click`,()=>Ft(!1)),document.getElementById(`memFlushEvery`)?.addEventListener(`change`,z),document.getElementById(`memCli`)?.addEventListener(`change`,z),document.getElementById(`memModel`)?.addEventListener(`change`,z),document.getElementById(`memRetention`)?.addEventListener(`change`,z),document.getElementById(`advBootstrapBtn`)?.addEventListener(`click`,It),document.getElementById(`advReindexBtn`)?.addEventListener(`click`,Lt),document.getElementById(`advReimportBtn`)?.addEventListener(`click`,It),document.getElementById(`advOpenCorruptedBtn`)?.addEventListener(`click`,Rt),document.getElementById(`basicMemoryFiles`)?.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-mem-delete]`);if(t){e.stopPropagation(),zt(t.dataset.memDelete||``);return}let n=e.target?.closest(`[data-mem-view]`);if(n){Bt(n.dataset.memView||``);return}if(e.target?.closest(`[data-mem-back]`)){L();return}});async function jn(){a(),We(),await o();let e=document.getElementById(`langToggle`);e&&(e.innerHTML=`${i.web} ${c(`lang.`+d())}`),await ve(),An(),ce(),$e(),Qe(),await ue(),await ze(),Fe(),xn(),gt(),oe(),Gt(),Zt(),ae(),on(),`serviceWorker`in navigator&&navigator.serviceWorker.register(`/sw.js`).catch(()=>{})}jn().catch(e=>{console.error(`[bootstrap]`,e)}),document.addEventListener(`keydown`,e=>{if(e.key===`Escape`){if(n.isRecording){e.preventDefault(),hn();return}document.querySelectorAll(`.modal-overlay.open`).forEach(e=>{e.classList.remove(`open`)})}(e.ctrlKey||e.metaKey)&&e.shiftKey&&e.code===`Space`&&(e.preventDefault(),gn())}),document.getElementById(`mobileMenuLeft`)?.addEventListener(`click`,U),document.getElementById(`mobileMenuRight`)?.addEventListener(`click`,W);