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.
@@ -476,14 +476,16 @@ const Settings = (() => {
476
476
 
477
477
  const badge = document.getElementById("brand-status-badge");
478
478
  if (data.warning) {
479
- badge.textContent = "Warning";
480
- badge.className = "brand-status-value badge-expired";
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 = "Active";
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
- if [ -f ~/.zshrc ]; then
264
- echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.zshrc
265
- fi
266
- if [ -f ~/.bash_profile ]; then
267
- echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bash_profile
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 bash)"
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 bash)"
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
- if [ -f ~/.bashrc ]; then
331
- echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
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 bash)"
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 bash)"
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.2
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