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.
- package/README.md +8 -4
- package/dist/bin/commands/doctor.js +48 -0
- package/dist/bin/commands/doctor.js.map +1 -1
- package/dist/bin/commands/init.js +2 -1
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/postinstall.js +66 -1
- package/dist/bin/postinstall.js.map +1 -1
- package/dist/server.js +8 -3
- package/dist/server.js.map +1 -1
- package/dist/src/agent/spawn.js +38 -9
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +4 -1
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/parser.js +2 -1
- package/dist/src/orchestrator/parser.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +5 -96
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/state-machine.js +11 -14
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/prompt/builder.js +5 -15
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +33 -32
- package/dist/src/prompt/templates/employee.md +7 -3
- package/dist/src/prompt/templates/orchestration.md +13 -37
- package/package.json +7 -1
- package/public/css/chat.css +12 -0
- package/public/dist/assets/employees-B11suLXa.js +39 -0
- package/public/dist/assets/index-C3xIEYRH.css +1 -0
- package/public/dist/assets/index-CMUmeewA.js +49 -0
- package/public/dist/assets/render-C5gpc065.js +25 -0
- package/public/dist/assets/{settings-BJR-IGM5.js → settings-BbG1hQmA.js} +14 -14
- package/public/dist/assets/settings-tOEsbIIs.js +1 -0
- package/public/dist/assets/skills-DL7wTirZ.js +12 -0
- package/public/dist/assets/skills-kOx6rq1X.js +1 -0
- package/public/dist/assets/slash-commands-C5vUKzNP.js +1 -0
- package/public/dist/assets/{slash-commands-DWvL-VDU.js → slash-commands-D_tV86er.js} +1 -1
- package/public/dist/assets/ui-ByJAyywC.js +1 -0
- package/public/dist/assets/ui-ORW7tzea.js +131 -0
- package/public/dist/assets/ws-CDrAtY9-.js +2 -0
- package/public/dist/index.html +2 -2
- package/public/js/features/chat.ts +3 -1
- package/public/js/render.ts +65 -22
- package/public/js/streaming-render.ts +33 -10
- package/public/js/ui.ts +45 -13
- package/public/js/virtual-scroll.ts +50 -16
- package/public/js/ws.ts +2 -1
- package/scripts/ensure-native-modules.cjs +54 -0
- package/scripts/install-officecli.ps1 +96 -0
- package/scripts/install-officecli.sh +37 -3
- package/scripts/install-wsl.sh +113 -27
- package/public/dist/assets/employees-D5n7mX5v.js +0 -39
- package/public/dist/assets/index-CLd0BsAu.js +0 -49
- package/public/dist/assets/index-D6ci1wCN.css +0 -1
- package/public/dist/assets/render-C8N0rp4L.js +0 -25
- package/public/dist/assets/settings-Dm6OnPmY.js +0 -1
- package/public/dist/assets/skills-D6jv9AIs.js +0 -1
- package/public/dist/assets/skills-uywskdFh.js +0 -12
- package/public/dist/assets/slash-commands-CCDonT40.js +0 -1
- package/public/dist/assets/ui-C1daR00l.js +0 -1
- package/public/dist/assets/ui-D-oFkXed.js +0 -131
- 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}')
|
package/scripts/install-wsl.sh
CHANGED
|
@@ -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
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|
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);
|