openclacky 0.9.2 → 0.9.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/docs/security-design.md +109 -0
- data/lib/clacky/agent/message_compressor_helper.rb +82 -69
- data/lib/clacky/agent/session_serializer.rb +9 -1
- data/lib/clacky/agent/skill_manager.rb +7 -0
- data/lib/clacky/agent.rb +11 -3
- data/lib/clacky/banner.rb +65 -0
- data/lib/clacky/block_font.rb +331 -0
- data/lib/clacky/brand_config.rb +73 -5
- data/lib/clacky/client.rb +129 -633
- data/lib/clacky/default_skills/activate-license/SKILL.md +118 -0
- data/lib/clacky/default_skills/channel-setup/SKILL.md +10 -20
- data/lib/clacky/message_format/anthropic.rb +241 -0
- data/lib/clacky/message_format/open_ai.rb +135 -0
- data/lib/clacky/server/channel/adapters/wecom/adapter.rb +2 -0
- data/lib/clacky/server/channel/adapters/wecom/ws_client.rb +13 -0
- data/lib/clacky/server/http_server.rb +12 -2
- data/lib/clacky/session_manager.rb +7 -2
- data/lib/clacky/tools/browser.rb +109 -280
- data/lib/clacky/ui2/block_font.rb +10 -0
- data/lib/clacky/ui2/components/welcome_banner.rb +23 -22
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +588 -6
- data/lib/clacky/web/app.js +30 -15
- data/lib/clacky/web/brand.js +141 -9
- data/lib/clacky/web/i18n.js +28 -2
- data/lib/clacky/web/index.html +142 -127
- data/lib/clacky/web/onboard.js +192 -225
- data/lib/clacky/web/sessions.js +12 -8
- data/lib/clacky/web/settings.js +57 -4
- data/lib/clacky.rb +2 -0
- data/scripts/install.sh +60 -15
- metadata +8 -1
data/lib/clacky/web/settings.js
CHANGED
|
@@ -476,14 +476,16 @@ const Settings = (() => {
|
|
|
476
476
|
|
|
477
477
|
const badge = document.getElementById("brand-status-badge");
|
|
478
478
|
if (data.warning) {
|
|
479
|
-
|
|
480
|
-
|
|
479
|
+
// Distinguish between expired (red) and expiring-soon (yellow)
|
|
480
|
+
const isExpired = data.warning && data.warning.toLowerCase().includes("expired");
|
|
481
|
+
badge.textContent = isExpired ? I18n.t("settings.brand.badge.expired") : I18n.t("settings.brand.badge.warning");
|
|
482
|
+
badge.className = "brand-status-value " + (isExpired ? "badge-expired" : "badge-expiring");
|
|
481
483
|
} else {
|
|
482
|
-
badge.textContent = "
|
|
484
|
+
badge.textContent = I18n.t("settings.brand.badge.active");
|
|
483
485
|
badge.className = "brand-status-value badge-active";
|
|
484
486
|
}
|
|
485
487
|
|
|
486
|
-
// Fetch full brand info for expiry date
|
|
488
|
+
// Fetch full brand info for expiry date and support QR code
|
|
487
489
|
fetch("/api/brand").then(r => r.json()).then(info => {
|
|
488
490
|
const expiresEl = document.getElementById("brand-status-expires");
|
|
489
491
|
if (info.license_expires_at) {
|
|
@@ -491,6 +493,17 @@ const Settings = (() => {
|
|
|
491
493
|
} else {
|
|
492
494
|
expiresEl.textContent = "—";
|
|
493
495
|
}
|
|
496
|
+
|
|
497
|
+
// Show support QR code if available
|
|
498
|
+
const qrContainer = document.getElementById("brand-support-qr");
|
|
499
|
+
const qrImg = document.getElementById("brand-support-qr-img");
|
|
500
|
+
if (info.support_qr_url && qrContainer && qrImg) {
|
|
501
|
+
qrImg.src = info.support_qr_url;
|
|
502
|
+
qrContainer.style.display = "";
|
|
503
|
+
_initQrLightbox(info.support_qr_url, info.support_qr_label || null);
|
|
504
|
+
} else if (qrContainer) {
|
|
505
|
+
qrContainer.style.display = "none";
|
|
506
|
+
}
|
|
494
507
|
}).catch(() => {
|
|
495
508
|
document.getElementById("brand-status-expires").textContent = "—";
|
|
496
509
|
});
|
|
@@ -597,5 +610,45 @@ const Settings = (() => {
|
|
|
597
610
|
_initLangBtns();
|
|
598
611
|
}
|
|
599
612
|
|
|
613
|
+
// ── QR Code Lightbox ───────────────────────────────────────────────────
|
|
614
|
+
// Sets up click-to-enlarge behaviour for the support QR code.
|
|
615
|
+
// Safe to call multiple times — idempotent via a data attribute guard.
|
|
616
|
+
function _initQrLightbox(qrUrl, label) {
|
|
617
|
+
const btn = document.getElementById("brand-support-qr-btn");
|
|
618
|
+
const lightbox = document.getElementById("qr-lightbox");
|
|
619
|
+
const backdrop = document.getElementById("qr-lightbox-backdrop");
|
|
620
|
+
const closeBtn = document.getElementById("qr-lightbox-close");
|
|
621
|
+
const lbImg = document.getElementById("qr-lightbox-img");
|
|
622
|
+
const lbLabel = document.getElementById("qr-lightbox-label");
|
|
623
|
+
|
|
624
|
+
if (!btn || !lightbox) return;
|
|
625
|
+
// Avoid double-binding
|
|
626
|
+
if (btn.dataset.lightboxBound) return;
|
|
627
|
+
btn.dataset.lightboxBound = "1";
|
|
628
|
+
|
|
629
|
+
function openLightbox() {
|
|
630
|
+
lbImg.src = qrUrl;
|
|
631
|
+
if (lbLabel && label) lbLabel.textContent = label;
|
|
632
|
+
lightbox.style.display = "";
|
|
633
|
+
document.body.style.overflow = "hidden";
|
|
634
|
+
closeBtn && closeBtn.focus();
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function closeLightbox() {
|
|
638
|
+
lightbox.style.display = "none";
|
|
639
|
+
document.body.style.overflow = "";
|
|
640
|
+
btn.focus();
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
btn.addEventListener("click", openLightbox);
|
|
644
|
+
closeBtn && closeBtn.addEventListener("click", closeLightbox);
|
|
645
|
+
backdrop && backdrop.addEventListener("click", closeLightbox);
|
|
646
|
+
|
|
647
|
+
// Close on Escape key
|
|
648
|
+
document.addEventListener("keydown", e => {
|
|
649
|
+
if (e.key === "Escape" && lightbox.style.display !== "none") closeLightbox();
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
|
|
600
653
|
return { open, init, loadBrand: _loadBrand };
|
|
601
654
|
})();
|
data/lib/clacky.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "clacky/version"
|
|
4
|
+
require_relative "clacky/message_format/anthropic"
|
|
5
|
+
require_relative "clacky/message_format/open_ai"
|
|
4
6
|
require_relative "clacky/client"
|
|
5
7
|
require_relative "clacky/skill"
|
|
6
8
|
require_relative "clacky/skill_loader"
|
data/scripts/install.sh
CHANGED
|
@@ -64,6 +64,40 @@ command_exists() {
|
|
|
64
64
|
command -v "$1" >/dev/null 2>&1
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
# Detect current shell type based on $SHELL environment variable
|
|
68
|
+
# Sets CURRENT_SHELL (e.g. "zsh", "bash", "fish") and SHELL_RC (rc file path)
|
|
69
|
+
detect_shell() {
|
|
70
|
+
local shell_name
|
|
71
|
+
shell_name=$(basename "$SHELL")
|
|
72
|
+
|
|
73
|
+
case "$shell_name" in
|
|
74
|
+
zsh)
|
|
75
|
+
CURRENT_SHELL="zsh"
|
|
76
|
+
SHELL_RC="$HOME/.zshrc"
|
|
77
|
+
;;
|
|
78
|
+
bash)
|
|
79
|
+
CURRENT_SHELL="bash"
|
|
80
|
+
# macOS uses ~/.bash_profile; Linux uses ~/.bashrc
|
|
81
|
+
if [ "$OS" = "macOS" ]; then
|
|
82
|
+
SHELL_RC="$HOME/.bash_profile"
|
|
83
|
+
else
|
|
84
|
+
SHELL_RC="$HOME/.bashrc"
|
|
85
|
+
fi
|
|
86
|
+
;;
|
|
87
|
+
fish)
|
|
88
|
+
CURRENT_SHELL="fish"
|
|
89
|
+
SHELL_RC="$HOME/.config/fish/config.fish"
|
|
90
|
+
;;
|
|
91
|
+
*)
|
|
92
|
+
# Fallback: treat as bash
|
|
93
|
+
CURRENT_SHELL="bash"
|
|
94
|
+
SHELL_RC="$HOME/.bashrc"
|
|
95
|
+
;;
|
|
96
|
+
esac
|
|
97
|
+
|
|
98
|
+
print_info "Detected shell: $CURRENT_SHELL (rc file: $SHELL_RC)"
|
|
99
|
+
}
|
|
100
|
+
|
|
67
101
|
# ---------------------------------------------------------------------------
|
|
68
102
|
# Network pre-flight check
|
|
69
103
|
#
|
|
@@ -256,19 +290,23 @@ install_macos_dependencies() {
|
|
|
256
290
|
fi
|
|
257
291
|
|
|
258
292
|
# Install mise for Ruby version management
|
|
293
|
+
# Detect current shell before configuring mise
|
|
294
|
+
detect_shell
|
|
295
|
+
|
|
259
296
|
print_info "Installing mise..."
|
|
260
297
|
if ! command_exists mise; then
|
|
261
298
|
if curl https://mise.run | sh; then
|
|
262
|
-
# Add mise to shell
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
echo
|
|
299
|
+
# Add mise activation to the current shell's rc file
|
|
300
|
+
local mise_init_line='eval "$(~/.local/bin/mise activate '"$CURRENT_SHELL"')"'
|
|
301
|
+
if [ -f "$SHELL_RC" ]; then
|
|
302
|
+
echo "$mise_init_line" >> "$SHELL_RC"
|
|
303
|
+
else
|
|
304
|
+
echo "$mise_init_line" > "$SHELL_RC"
|
|
268
305
|
fi
|
|
306
|
+
print_info "Added mise activation to $SHELL_RC"
|
|
269
307
|
|
|
270
308
|
export PATH="$HOME/.local/bin:$PATH"
|
|
271
|
-
eval "$(~/.local/bin/mise activate
|
|
309
|
+
eval "$(~/.local/bin/mise activate $CURRENT_SHELL)"
|
|
272
310
|
|
|
273
311
|
print_success "mise installed successfully"
|
|
274
312
|
else
|
|
@@ -282,8 +320,8 @@ install_macos_dependencies() {
|
|
|
282
320
|
# Install Ruby 3 via mise
|
|
283
321
|
print_info "Installing Ruby 3 via mise..."
|
|
284
322
|
if ~/.local/bin/mise use -g ruby@3; then
|
|
285
|
-
# Reload mise
|
|
286
|
-
eval "$(~/.local/bin/mise activate
|
|
323
|
+
# Reload mise using the current shell
|
|
324
|
+
eval "$(~/.local/bin/mise activate $CURRENT_SHELL)"
|
|
287
325
|
print_success "Ruby 3 installed successfully"
|
|
288
326
|
else
|
|
289
327
|
print_error "Failed to install Ruby 3"
|
|
@@ -322,17 +360,24 @@ install_ubuntu_dependencies() {
|
|
|
322
360
|
return 1
|
|
323
361
|
fi
|
|
324
362
|
|
|
363
|
+
# Detect current shell before configuring mise
|
|
364
|
+
detect_shell
|
|
365
|
+
|
|
325
366
|
# Install mise for Ruby version management
|
|
326
367
|
print_info "Installing mise..."
|
|
327
368
|
if ! command_exists mise; then
|
|
328
369
|
if curl https://mise.run | sh; then
|
|
329
|
-
# Add mise to shell
|
|
330
|
-
|
|
331
|
-
|
|
370
|
+
# Add mise activation to the current shell's rc file
|
|
371
|
+
local mise_init_line='eval "$(~/.local/bin/mise activate '"$CURRENT_SHELL"')"'
|
|
372
|
+
if [ -f "$SHELL_RC" ]; then
|
|
373
|
+
echo "$mise_init_line" >> "$SHELL_RC"
|
|
374
|
+
else
|
|
375
|
+
echo "$mise_init_line" > "$SHELL_RC"
|
|
332
376
|
fi
|
|
377
|
+
print_info "Added mise activation to $SHELL_RC"
|
|
333
378
|
|
|
334
379
|
export PATH="$HOME/.local/bin:$PATH"
|
|
335
|
-
eval "$(~/.local/bin/mise activate
|
|
380
|
+
eval "$(~/.local/bin/mise activate $CURRENT_SHELL)"
|
|
336
381
|
|
|
337
382
|
print_success "mise installed successfully"
|
|
338
383
|
else
|
|
@@ -346,8 +391,8 @@ install_ubuntu_dependencies() {
|
|
|
346
391
|
# Install Ruby 3 via mise
|
|
347
392
|
print_info "Installing Ruby 3 via mise..."
|
|
348
393
|
if ~/.local/bin/mise use -g ruby@3; then
|
|
349
|
-
# Reload mise
|
|
350
|
-
eval "$(~/.local/bin/mise activate
|
|
394
|
+
# Reload mise using the current shell
|
|
395
|
+
eval "$(~/.local/bin/mise activate $CURRENT_SHELL)"
|
|
351
396
|
print_success "Ruby 3 installed successfully"
|
|
352
397
|
else
|
|
353
398
|
print_error "Failed to install Ruby 3"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openclacky
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- windy
|
|
@@ -226,6 +226,7 @@ files:
|
|
|
226
226
|
- docs/deploy_subagent_design.md
|
|
227
227
|
- docs/memory-architecture.md
|
|
228
228
|
- docs/openclacky_cloud_api_reference.md
|
|
229
|
+
- docs/security-design.md
|
|
229
230
|
- docs/session-skill-invocation.md
|
|
230
231
|
- docs/time_machine_design.md
|
|
231
232
|
- docs/ui2-architecture.md
|
|
@@ -249,6 +250,8 @@ files:
|
|
|
249
250
|
- lib/clacky/agent/tool_registry.rb
|
|
250
251
|
- lib/clacky/agent_config.rb
|
|
251
252
|
- lib/clacky/agent_profile.rb
|
|
253
|
+
- lib/clacky/banner.rb
|
|
254
|
+
- lib/clacky/block_font.rb
|
|
252
255
|
- lib/clacky/brand_config.rb
|
|
253
256
|
- lib/clacky/cli.rb
|
|
254
257
|
- lib/clacky/client.rb
|
|
@@ -259,6 +262,7 @@ files:
|
|
|
259
262
|
- lib/clacky/default_agents/coding/system_prompt.md
|
|
260
263
|
- lib/clacky/default_agents/general/profile.yml
|
|
261
264
|
- lib/clacky/default_agents/general/system_prompt.md
|
|
265
|
+
- lib/clacky/default_skills/activate-license/SKILL.md
|
|
262
266
|
- lib/clacky/default_skills/channel-setup/SKILL.md
|
|
263
267
|
- lib/clacky/default_skills/code-explorer/SKILL.md
|
|
264
268
|
- lib/clacky/default_skills/cron-task-creator/SKILL.md
|
|
@@ -300,6 +304,8 @@ files:
|
|
|
300
304
|
- lib/clacky/default_skills/skill-creator/scripts/utils.py
|
|
301
305
|
- lib/clacky/idle_compression_timer.rb
|
|
302
306
|
- lib/clacky/json_ui_controller.rb
|
|
307
|
+
- lib/clacky/message_format/anthropic.rb
|
|
308
|
+
- lib/clacky/message_format/open_ai.rb
|
|
303
309
|
- lib/clacky/plain_ui_controller.rb
|
|
304
310
|
- lib/clacky/providers.rb
|
|
305
311
|
- lib/clacky/server/channel.rb
|
|
@@ -343,6 +349,7 @@ files:
|
|
|
343
349
|
- lib/clacky/tools/write.rb
|
|
344
350
|
- lib/clacky/ui2.rb
|
|
345
351
|
- lib/clacky/ui2/README.md
|
|
352
|
+
- lib/clacky/ui2/block_font.rb
|
|
346
353
|
- lib/clacky/ui2/components/base_component.rb
|
|
347
354
|
- lib/clacky/ui2/components/command_suggestions.rb
|
|
348
355
|
- lib/clacky/ui2/components/common_component.rb
|