openclacky 1.2.9 → 1.2.10
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 +23 -0
- data/lib/clacky/agent/llm_caller.rb +3 -0
- data/lib/clacky/agent/message_compressor_helper.rb +6 -5
- data/lib/clacky/agent/session_serializer.rb +4 -0
- data/lib/clacky/agent.rb +9 -0
- data/lib/clacky/agent_config.rb +20 -1
- data/lib/clacky/brand_config.rb +1 -0
- data/lib/clacky/cli.rb +49 -22
- data/lib/clacky/idle_compression_timer.rb +38 -15
- data/lib/clacky/providers.rb +7 -2
- data/lib/clacky/rich_ui_controller.rb +1549 -0
- data/lib/clacky/server/channel/adapters/weixin/adapter.rb +24 -2
- data/lib/clacky/server/channel/channel_manager.rb +89 -2
- data/lib/clacky/server/http_server.rb +124 -9
- data/lib/clacky/session_manager.rb +9 -8
- data/lib/clacky/telemetry.rb +16 -2
- data/lib/clacky/ui2/layout_manager.rb +11 -7
- data/lib/clacky/ui2/ui_controller.rb +2 -2
- data/lib/clacky/ui_interface.rb +1 -1
- data/lib/clacky/utils/model_pricing.rb +75 -53
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +221 -2
- data/lib/clacky/web/billing.js +1 -1
- data/lib/clacky/web/i18n.js +28 -4
- data/lib/clacky/web/index.html +9 -1
- data/lib/clacky/web/sessions.js +443 -2
- data/lib/clacky/web/settings.js +50 -0
- data/lib/clacky/web/workspace.js +9 -1
- data/scripts/build/lib/network.sh +3 -3
- data/scripts/install.ps1 +16 -4
- data/scripts/install.sh +3 -3
- data/scripts/install_browser.sh +3 -3
- data/scripts/install_full.sh +3 -3
- data/scripts/install_rails_deps.sh +3 -3
- data/scripts/install_system_deps.sh +3 -3
- metadata +6 -2
|
@@ -350,80 +350,104 @@ module Clacky
|
|
|
350
350
|
cache: { write: 0.30, read: 0.03 }
|
|
351
351
|
},
|
|
352
352
|
|
|
353
|
+
# M3 (released 2026-06-01) is MiniMax's multimodal flagship. Official
|
|
354
|
+
# pricing is tiered by context length (≤512K vs 512K–1M); per the
|
|
355
|
+
# project's "displayed ≤ actual" convention we record only the lowest
|
|
356
|
+
# (≤512K) tier as a flat rate — the global TIERED_PRICING_THRESHOLD is
|
|
357
|
+
# 200K, so applying the 512K–1M rate to the 200K–512K band would over-
|
|
358
|
+
# charge. Listed at original (non-promotional) prices: input $0.60,
|
|
359
|
+
# output $2.40, cache read $0.12 per 1M tokens.
|
|
360
|
+
"minimax-m3" => {
|
|
361
|
+
input: { default: 0.60, over_200k: 0.60 },
|
|
362
|
+
output: { default: 2.40, over_200k: 2.40 },
|
|
363
|
+
cache: { write: 0.60, read: 0.12 }
|
|
364
|
+
},
|
|
365
|
+
|
|
353
366
|
"minimax-m2.7" => {
|
|
354
367
|
input: { default: 0.30, over_200k: 0.30 },
|
|
355
368
|
output: { default: 1.20, over_200k: 1.20 },
|
|
356
369
|
cache: { write: 0.30, read: 0.06 }
|
|
357
370
|
},
|
|
358
371
|
|
|
359
|
-
# Qwen (Alibaba DashScope)
|
|
360
|
-
# Source: Alibaba Cloud Model Studio international
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
#
|
|
365
|
-
#
|
|
366
|
-
#
|
|
367
|
-
#
|
|
368
|
-
#
|
|
372
|
+
# Qwen (Alibaba DashScope) - USD per 1M tokens, international (Singapore) list price.
|
|
373
|
+
# Source: Alibaba Cloud Model Studio international console per-model pages.
|
|
374
|
+
#
|
|
375
|
+
# Pricing convention:
|
|
376
|
+
# - These rates are used for user-facing cost ESTIMATION, so we always use
|
|
377
|
+
# the standard LIST price and intentionally ignore any limited-time promo
|
|
378
|
+
# discounts. A promo lowers the user's actual bill, never raises it, so
|
|
379
|
+
# estimating at list price keeps the estimate a safe upper bound and avoids
|
|
380
|
+
# churn whenever a promo starts or ends.
|
|
381
|
+
# - We record the model's LOWEST context tier (e.g. input<=256k / <=128k) as a
|
|
382
|
+
# flat rate, since the global TIERED_PRICING_THRESHOLD is 200K and does not
|
|
383
|
+
# match Qwen's per-model breakpoints.
|
|
384
|
+
# - cache.write = official explicit-cache-create price.
|
|
385
|
+
# - cache.read = official explicit-cache-hit price.
|
|
386
|
+
# - When a model has NO published explicit-cache price (e.g. qwen3.6-27b,
|
|
387
|
+
# qwen-plus-latest), cache.write/read fall back to the input rate.
|
|
388
|
+
# qwen3.7-max: NOT tiered (single flat tier per Alibaba's definition).
|
|
389
|
+
# List price: input 2.5, output 7.5, explicit write 3.125, explicit read 0.25.
|
|
369
390
|
"qwen3.7-max" => {
|
|
370
|
-
input: { default:
|
|
371
|
-
output: { default:
|
|
372
|
-
cache: { write:
|
|
391
|
+
input: { default: 2.5, over_200k: 2.5 },
|
|
392
|
+
output: { default: 7.5, over_200k: 7.5 },
|
|
393
|
+
cache: { write: 3.125, read: 0.25 }
|
|
373
394
|
},
|
|
374
395
|
|
|
396
|
+
# qwen3.7-plus: list price (<=256k tier):
|
|
397
|
+
# input 0.4, output 1.6, explicit write 0.5, explicit read 0.04.
|
|
375
398
|
"qwen3.7-plus" => {
|
|
376
|
-
input: { default: 0.
|
|
377
|
-
output: { default:
|
|
378
|
-
cache: { write: 0.
|
|
379
|
-
},
|
|
380
|
-
|
|
381
|
-
"qwen3.7-flash" => {
|
|
382
|
-
input: { default: 0.15, over_200k: 0.15 },
|
|
383
|
-
output: { default: 0.90, over_200k: 0.90 },
|
|
384
|
-
cache: { write: 0.15, read: 0.03 }
|
|
399
|
+
input: { default: 0.4, over_200k: 0.4 },
|
|
400
|
+
output: { default: 1.6, over_200k: 1.6 },
|
|
401
|
+
cache: { write: 0.5, read: 0.04 }
|
|
385
402
|
},
|
|
386
403
|
|
|
404
|
+
# qwen3.6-plus: list price (<=256k tier). Official explicit-cache prices.
|
|
405
|
+
# input 0.50, output 3.00, explicit write 0.625, explicit read 0.05
|
|
387
406
|
"qwen3.6-plus" => {
|
|
388
|
-
input: { default: 0.
|
|
389
|
-
output: { default:
|
|
390
|
-
cache: { write: 0.
|
|
407
|
+
input: { default: 0.50, over_200k: 0.50 },
|
|
408
|
+
output: { default: 3.00, over_200k: 3.00 },
|
|
409
|
+
cache: { write: 0.625, read: 0.05 }
|
|
391
410
|
},
|
|
392
411
|
|
|
412
|
+
# qwen3.6-max (qwen3.6-max-preview): list price (<=128k tier).
|
|
413
|
+
# input 1.30, output 7.80, explicit write 1.625, explicit read 0.13
|
|
393
414
|
"qwen3.6-max" => {
|
|
394
|
-
input: { default: 1.
|
|
395
|
-
output: { default:
|
|
396
|
-
cache: { write: 1.
|
|
415
|
+
input: { default: 1.30, over_200k: 1.30 },
|
|
416
|
+
output: { default: 7.80, over_200k: 7.80 },
|
|
417
|
+
cache: { write: 1.625, read: 0.13 }
|
|
397
418
|
},
|
|
398
419
|
|
|
420
|
+
# qwen3.6-27b: list price, no explicit-cache pricing published.
|
|
421
|
+
# Cache write/read fall back to the input rate (no cache discount).
|
|
399
422
|
"qwen3.6-27b" => {
|
|
400
|
-
input: { default: 0.
|
|
401
|
-
output: { default:
|
|
402
|
-
cache: { write: 0.
|
|
423
|
+
input: { default: 0.60, over_200k: 0.60 },
|
|
424
|
+
output: { default: 3.60, over_200k: 3.60 },
|
|
425
|
+
cache: { write: 0.60, read: 0.60 }
|
|
403
426
|
},
|
|
404
427
|
|
|
428
|
+
# qwen3.6-flash: list price (<=256k tier).
|
|
429
|
+
# input 0.25, output 1.50, explicit write 0.3125, explicit read 0.025
|
|
405
430
|
"qwen3.6-flash" => {
|
|
406
|
-
input: { default: 0.
|
|
407
|
-
output: { default:
|
|
408
|
-
cache: { write: 0.
|
|
431
|
+
input: { default: 0.25, over_200k: 0.25 },
|
|
432
|
+
output: { default: 1.50, over_200k: 1.50 },
|
|
433
|
+
cache: { write: 0.3125, read: 0.025 }
|
|
409
434
|
},
|
|
410
435
|
|
|
436
|
+
# qwen-plus-latest: list price (<=256k tier), no explicit-cache pricing.
|
|
437
|
+
# Cache write/read fall back to the input rate (no cache discount).
|
|
411
438
|
"qwen-plus-latest" => {
|
|
412
439
|
input: { default: 0.40, over_200k: 0.40 },
|
|
413
440
|
output: { default: 1.20, over_200k: 1.20 },
|
|
414
|
-
cache: { write: 0.40, read: 0.
|
|
415
|
-
},
|
|
416
|
-
|
|
417
|
-
"qwen-vl-plus" => {
|
|
418
|
-
input: { default: 0.14, over_200k: 0.14 },
|
|
419
|
-
output: { default: 0.41, over_200k: 0.41 },
|
|
420
|
-
cache: { write: 0.14, read: 0.028 }
|
|
441
|
+
cache: { write: 0.40, read: 0.40 }
|
|
421
442
|
},
|
|
422
443
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
444
|
+
# qwen3-vl-plus: replaces the retiring qwen-vl-plus. List price
|
|
445
|
+
# (128k<input<=256k tier). input 0.60, output 4.80,
|
|
446
|
+
# explicit write 0.75, explicit read 0.06.
|
|
447
|
+
"qwen3-vl-plus" => {
|
|
448
|
+
input: { default: 0.60, over_200k: 0.60 },
|
|
449
|
+
output: { default: 4.80, over_200k: 4.80 },
|
|
450
|
+
cache: { write: 0.75, read: 0.06 }
|
|
427
451
|
},
|
|
428
452
|
|
|
429
453
|
}.freeze
|
|
@@ -583,6 +607,8 @@ module Clacky
|
|
|
583
607
|
"glm-4.7"
|
|
584
608
|
# MiniMax — model ids in providers.rb use capitalised "MiniMax-M2.x"
|
|
585
609
|
# but we match case-insensitively and map to the lowercased table key.
|
|
610
|
+
when /^minimax-m3$/i
|
|
611
|
+
"minimax-m3"
|
|
586
612
|
when /^minimax-m2\.5$/i
|
|
587
613
|
"minimax-m2.5"
|
|
588
614
|
when /^minimax-m2\.7$/i
|
|
@@ -591,14 +617,12 @@ module Clacky
|
|
|
591
617
|
# Qwen (Alibaba DashScope) — strict anchored match per registered
|
|
592
618
|
# model id in providers.rb. qwen3.7-* is the latest flagship line;
|
|
593
619
|
# qwen3.6-* are the previous generation; qwen-plus-latest is the
|
|
594
|
-
# rolling alias for the latest Qwen-Plus release;
|
|
595
|
-
# the multimodal
|
|
620
|
+
# rolling alias for the latest Qwen-Plus release; qwen3-vl-plus is
|
|
621
|
+
# the multimodal SKU (replaces the retired qwen-vl-plus/max).
|
|
596
622
|
when /^qwen3\.7-max$/i
|
|
597
623
|
"qwen3.7-max"
|
|
598
624
|
when /^qwen3\.7-plus$/i
|
|
599
625
|
"qwen3.7-plus"
|
|
600
|
-
when /^qwen3\.7-flash$/i
|
|
601
|
-
"qwen3.7-flash"
|
|
602
626
|
when /^qwen3\.6-plus$/i
|
|
603
627
|
"qwen3.6-plus"
|
|
604
628
|
when /^qwen3\.6-max$/i
|
|
@@ -609,10 +633,8 @@ module Clacky
|
|
|
609
633
|
"qwen3.6-flash"
|
|
610
634
|
when /^qwen-plus-latest$/i
|
|
611
635
|
"qwen-plus-latest"
|
|
612
|
-
when /^
|
|
613
|
-
"
|
|
614
|
-
when /^qwen-vl-max$/i
|
|
615
|
-
"qwen-vl-max"
|
|
636
|
+
when /^qwen3-vl-plus$/i
|
|
637
|
+
"qwen3-vl-plus"
|
|
616
638
|
|
|
617
639
|
# OpenAI GPT-5.x models — match various dashed/dotted/compact forms
|
|
618
640
|
# (e.g. "gpt-5.5", "gpt-5-5", "gpt5.5", "gpt55")
|
data/lib/clacky/version.rb
CHANGED
data/lib/clacky/web/app.css
CHANGED
|
@@ -4108,6 +4108,175 @@ body {
|
|
|
4108
4108
|
border-color: var(--color-border-secondary);
|
|
4109
4109
|
}
|
|
4110
4110
|
|
|
4111
|
+
/* ── Directory Picker Modal (tree-based) ─────────────────────────────────── */
|
|
4112
|
+
.modal-title {
|
|
4113
|
+
padding: 1rem 1.25rem;
|
|
4114
|
+
border-bottom: 1px solid var(--color-border-primary);
|
|
4115
|
+
font-size: 1.0625rem;
|
|
4116
|
+
font-weight: 600;
|
|
4117
|
+
color: var(--color-text-primary);
|
|
4118
|
+
}
|
|
4119
|
+
.modal-buttons {
|
|
4120
|
+
display: flex;
|
|
4121
|
+
align-items: center;
|
|
4122
|
+
justify-content: flex-end;
|
|
4123
|
+
gap: 0.625rem;
|
|
4124
|
+
padding: 1rem 1.25rem;
|
|
4125
|
+
border-top: 1px solid var(--color-border-primary);
|
|
4126
|
+
}
|
|
4127
|
+
.dir-picker-input {
|
|
4128
|
+
width: 100%;
|
|
4129
|
+
padding: 0.5rem 0.75rem;
|
|
4130
|
+
border: 1px solid var(--color-border-primary);
|
|
4131
|
+
border-radius: 6px;
|
|
4132
|
+
background: var(--color-bg-primary);
|
|
4133
|
+
color: var(--color-text-primary);
|
|
4134
|
+
font-size: 0.875rem;
|
|
4135
|
+
font-family: var(--font-mono, monospace);
|
|
4136
|
+
transition: border-color 0.15s;
|
|
4137
|
+
box-sizing: border-box;
|
|
4138
|
+
}.dir-picker-input:focus {
|
|
4139
|
+
outline: none;
|
|
4140
|
+
border-color: var(--color-accent);
|
|
4141
|
+
}
|
|
4142
|
+
.dir-picker-input::placeholder {
|
|
4143
|
+
color: var(--color-text-tertiary);
|
|
4144
|
+
}
|
|
4145
|
+
/* Preset buttons row */
|
|
4146
|
+
.dp-presets {
|
|
4147
|
+
display: flex;
|
|
4148
|
+
gap: 0.5rem;
|
|
4149
|
+
flex-wrap: wrap;
|
|
4150
|
+
}
|
|
4151
|
+
.dp-presets .btn-sm {
|
|
4152
|
+
padding: 0.25rem 0.625rem;
|
|
4153
|
+
font-size: 0.75rem;
|
|
4154
|
+
}
|
|
4155
|
+
/* Path input container */
|
|
4156
|
+
.dp-path-container {
|
|
4157
|
+
flex-shrink: 0;
|
|
4158
|
+
position: relative;
|
|
4159
|
+
}/* Autocomplete dropdown */
|
|
4160
|
+
.dp-autocomplete {
|
|
4161
|
+
position: absolute;
|
|
4162
|
+
top: 100%;
|
|
4163
|
+
left: 0;
|
|
4164
|
+
right: 0;
|
|
4165
|
+
z-index: 10;
|
|
4166
|
+
max-height: 200px;
|
|
4167
|
+
overflow-y: auto;
|
|
4168
|
+
background: var(--color-bg-primary);
|
|
4169
|
+
border: 1px solid var(--color-border-primary);
|
|
4170
|
+
border-top: none;
|
|
4171
|
+
border-radius: 0 0 6px 6px;
|
|
4172
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
4173
|
+
}
|
|
4174
|
+
.dp-ac-item {
|
|
4175
|
+
display: flex;
|
|
4176
|
+
align-items: center;
|
|
4177
|
+
gap: 0.5rem;
|
|
4178
|
+
padding: 0.4rem 0.75rem;
|
|
4179
|
+
cursor: pointer;
|
|
4180
|
+
font-size: 0.8125rem;
|
|
4181
|
+
color: var(--color-text-primary);
|
|
4182
|
+
transition: background 0.1s;
|
|
4183
|
+
}
|
|
4184
|
+
.dp-ac-item:hover,
|
|
4185
|
+
.dp-ac-item.active {
|
|
4186
|
+
background: var(--color-bg-hover);
|
|
4187
|
+
}
|
|
4188
|
+
.dp-ac-icon {
|
|
4189
|
+
display: inline-flex;
|
|
4190
|
+
align-items: center;
|
|
4191
|
+
flex-shrink: 0;
|
|
4192
|
+
color: var(--color-text-secondary);
|
|
4193
|
+
}
|
|
4194
|
+
.dp-ac-name {
|
|
4195
|
+
overflow: hidden;
|
|
4196
|
+
text-overflow: ellipsis;
|
|
4197
|
+
white-space: nowrap;
|
|
4198
|
+
}
|
|
4199
|
+
/* Tree container */
|
|
4200
|
+
.dp-tree {
|
|
4201
|
+
border: 1px solid var(--color-border-primary);
|
|
4202
|
+
border-radius: 6px;
|
|
4203
|
+
background: var(--color-bg-secondary);
|
|
4204
|
+
min-height: 200px;
|
|
4205
|
+
max-height: 340px;
|
|
4206
|
+
overflow: auto;
|
|
4207
|
+
font-size: 0.8125rem;
|
|
4208
|
+
}
|
|
4209
|
+
/* Tree node */
|
|
4210
|
+
.dp-node {
|
|
4211
|
+
user-select: none;
|
|
4212
|
+
}
|
|
4213
|
+
.dp-row {
|
|
4214
|
+
display: flex;
|
|
4215
|
+
align-items: center;
|
|
4216
|
+
gap: 0.375rem;
|
|
4217
|
+
padding: 0.375rem 0.5rem;
|
|
4218
|
+
cursor: pointer;
|
|
4219
|
+
border-radius: 4px;
|
|
4220
|
+
transition: background 0.1s;
|
|
4221
|
+
}
|
|
4222
|
+
.dp-row:hover {
|
|
4223
|
+
background: var(--color-bg-hover);
|
|
4224
|
+
}
|
|
4225
|
+
.dp-row.selected {
|
|
4226
|
+
background: var(--color-accent-subtle, rgba(59, 130, 246, 0.12));
|
|
4227
|
+
}
|
|
4228
|
+
.dp-row.selected .dp-name {
|
|
4229
|
+
color: var(--color-accent);
|
|
4230
|
+
font-weight: 500;
|
|
4231
|
+
}
|
|
4232
|
+
/* Caret */
|
|
4233
|
+
.dp-caret {
|
|
4234
|
+
display: inline-flex;
|
|
4235
|
+
align-items: center;
|
|
4236
|
+
justify-content: center;
|
|
4237
|
+
width: 16px;
|
|
4238
|
+
height: 16px;
|
|
4239
|
+
flex-shrink: 0;
|
|
4240
|
+
color: var(--color-text-tertiary);
|
|
4241
|
+
transition: transform 0.15s;
|
|
4242
|
+
}
|
|
4243
|
+
.dp-caret.open {
|
|
4244
|
+
transform: rotate(90deg);
|
|
4245
|
+
}
|
|
4246
|
+
/* Folder icon */
|
|
4247
|
+
.dp-icon {
|
|
4248
|
+
display: inline-flex;
|
|
4249
|
+
align-items: center;
|
|
4250
|
+
flex-shrink: 0;
|
|
4251
|
+
color: var(--color-text-secondary);
|
|
4252
|
+
}
|
|
4253
|
+
.dp-row.selected .dp-icon {
|
|
4254
|
+
color: var(--color-accent);
|
|
4255
|
+
}
|
|
4256
|
+
/* Name */
|
|
4257
|
+
.dp-name {
|
|
4258
|
+
flex: 1;
|
|
4259
|
+
overflow: hidden;
|
|
4260
|
+
text-overflow: ellipsis;
|
|
4261
|
+
white-space: nowrap;
|
|
4262
|
+
color: var(--color-text-primary);
|
|
4263
|
+
}
|
|
4264
|
+
/* Children container */
|
|
4265
|
+
.dp-children {
|
|
4266
|
+
display: flex;
|
|
4267
|
+
flex-direction: column;
|
|
4268
|
+
}/* Loading / empty / error states */
|
|
4269
|
+
.dp-loading,
|
|
4270
|
+
.dp-empty,
|
|
4271
|
+
.dp-error {
|
|
4272
|
+
padding: 0.5rem 1rem;
|
|
4273
|
+
color: var(--color-text-tertiary);
|
|
4274
|
+
font-size: 0.75rem;
|
|
4275
|
+
font-style: italic;
|
|
4276
|
+
}
|
|
4277
|
+
.dp-error {
|
|
4278
|
+
color: var(--color-text-danger, #ef4444);
|
|
4279
|
+
}
|
|
4111
4280
|
/* Model name combobox */
|
|
4112
4281
|
.model-name-combobox {
|
|
4113
4282
|
position: relative;
|
|
@@ -9069,11 +9238,14 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9069
9238
|
.tooltip-date {
|
|
9070
9239
|
font-weight: 600;
|
|
9071
9240
|
color: var(--color-text-primary);
|
|
9241
|
+
white-space: nowrap;
|
|
9072
9242
|
}
|
|
9073
|
-
.tooltip-total {
|
|
9243
|
+
.tooltip-total-value {
|
|
9074
9244
|
font-size: 0.875rem;
|
|
9075
9245
|
color: var(--color-accent);
|
|
9076
|
-
font-weight:
|
|
9246
|
+
font-weight: 600;
|
|
9247
|
+
white-space: nowrap;
|
|
9248
|
+
margin-left: 0.75rem;
|
|
9077
9249
|
}
|
|
9078
9250
|
.tooltip-row {
|
|
9079
9251
|
display: flex;
|
|
@@ -9571,6 +9743,53 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9571
9743
|
color: var(--color-text-secondary);
|
|
9572
9744
|
font-weight: 500;
|
|
9573
9745
|
}
|
|
9746
|
+
.settings-exchange-rate-refresh {
|
|
9747
|
+
display: inline-flex;
|
|
9748
|
+
align-items: center;
|
|
9749
|
+
justify-content: center;
|
|
9750
|
+
gap: 0.35rem;
|
|
9751
|
+
min-height: 34px;
|
|
9752
|
+
padding: 0.45rem 0.8rem;
|
|
9753
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-primary) 28%, var(--color-border));
|
|
9754
|
+
border-radius: 999px;
|
|
9755
|
+
background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-bg-secondary));
|
|
9756
|
+
color: var(--color-accent-primary);
|
|
9757
|
+
font-size: 0.8125rem;
|
|
9758
|
+
font-weight: 600;
|
|
9759
|
+
line-height: 1;
|
|
9760
|
+
white-space: nowrap;
|
|
9761
|
+
cursor: pointer;
|
|
9762
|
+
transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
|
|
9763
|
+
}
|
|
9764
|
+
.settings-exchange-rate-refresh svg {
|
|
9765
|
+
flex: 0 0 auto;
|
|
9766
|
+
}
|
|
9767
|
+
.settings-exchange-rate-refresh:hover:not(:disabled) {
|
|
9768
|
+
border-color: color-mix(in srgb, var(--color-accent-primary) 52%, var(--color-border));
|
|
9769
|
+
background: color-mix(in srgb, var(--color-accent-primary) 12%, var(--color-bg-secondary));
|
|
9770
|
+
box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent-primary) 16%, transparent);
|
|
9771
|
+
transform: translateY(-1px);
|
|
9772
|
+
}
|
|
9773
|
+
.settings-exchange-rate-refresh:active:not(:disabled) {
|
|
9774
|
+
transform: translateY(0);
|
|
9775
|
+
}
|
|
9776
|
+
.settings-exchange-rate-refresh:disabled {
|
|
9777
|
+
opacity: 0.6;
|
|
9778
|
+
cursor: not-allowed;
|
|
9779
|
+
transform: none;
|
|
9780
|
+
}
|
|
9781
|
+
.settings-exchange-rate-status {
|
|
9782
|
+
min-height: 1.1rem;
|
|
9783
|
+
margin-top: 0.4rem;
|
|
9784
|
+
font-size: 0.8125rem;
|
|
9785
|
+
color: var(--color-text-secondary);
|
|
9786
|
+
}
|
|
9787
|
+
.settings-exchange-rate-status.success {
|
|
9788
|
+
color: var(--color-success, #2e7d32);
|
|
9789
|
+
}
|
|
9790
|
+
.settings-exchange-rate-status.error {
|
|
9791
|
+
color: var(--color-error, #d33);
|
|
9792
|
+
}
|
|
9574
9793
|
|
|
9575
9794
|
/* ── Sessions List ───────────────────────────────────────────────────── */
|
|
9576
9795
|
.billing-sessions-row {
|
data/lib/clacky/web/billing.js
CHANGED
|
@@ -226,7 +226,7 @@ const Billing = (() => {
|
|
|
226
226
|
tooltip.innerHTML = `
|
|
227
227
|
<div class="tooltip-header">
|
|
228
228
|
<span class="tooltip-date">${date}</span>
|
|
229
|
-
<span class="tooltip-total">${total} tokens</span>
|
|
229
|
+
<span class="tooltip-total-value">${total} tokens</span>
|
|
230
230
|
</div>
|
|
231
231
|
<div class="tooltip-row">
|
|
232
232
|
<span class="tooltip-dot tooltip-total"></span>
|
data/lib/clacky/web/i18n.js
CHANGED
|
@@ -80,8 +80,16 @@ const I18n = (() => {
|
|
|
80
80
|
"sessions.actions.download": "Download session files",
|
|
81
81
|
"sessions.actions.downloadHint": "for debugging",
|
|
82
82
|
"sib.dir.tooltip": "Click to change directory",
|
|
83
|
-
"sib.dir.changePrompt": "Change working directory
|
|
84
|
-
"
|
|
83
|
+
"sib.dir.changePrompt": "Change working directory",
|
|
84
|
+
"sib.dir.home": "Home",
|
|
85
|
+
"sib.dir.root": "Root",
|
|
86
|
+
"sib.dir.default": "Default workspace",
|
|
87
|
+
"sib.dir.current": "Current workspace", "sib.dir.inputPlaceholder": "Type or select a directory path",
|
|
88
|
+
"sib.dir.loading": "Loading…",
|
|
89
|
+
"sib.dir.empty": "Empty directory",
|
|
90
|
+
"sib.dir.loadError": "Failed to load",
|
|
91
|
+
"sib.dir.confirm": "Confirm",
|
|
92
|
+
"sib.dir.cancel": "Cancel", "workspace.title": "Workspace",
|
|
85
93
|
"workspace.expand": "Open workspace",
|
|
86
94
|
"workspace.collapse": "Collapse workspace",
|
|
87
95
|
"workspace.refresh": "Refresh",
|
|
@@ -624,6 +632,10 @@ const I18n = (() => {
|
|
|
624
632
|
"settings.currency.usd": "$ USD",
|
|
625
633
|
"settings.currency.cny": "¥ CNY",
|
|
626
634
|
"settings.currency.exchangeRate": "Exchange Rate (1 USD =)",
|
|
635
|
+
"settings.currency.updateLatest": "Update latest",
|
|
636
|
+
"settings.currency.updating": "Updating…",
|
|
637
|
+
"settings.currency.updated": "Updated from {{source}} on {{date}}",
|
|
638
|
+
"settings.currency.updateFailed": "Failed to fetch the latest rate. You can still enter it manually.",
|
|
627
639
|
|
|
628
640
|
// ── Onboard ──
|
|
629
641
|
"onboard.title": "Welcome to {{brand}}",
|
|
@@ -800,8 +812,16 @@ const I18n = (() => {
|
|
|
800
812
|
"sessions.actions.download": "下载会话文件",
|
|
801
813
|
"sessions.actions.downloadHint": "用于调试",
|
|
802
814
|
"sib.dir.tooltip": "点击切换工作目录",
|
|
803
|
-
"sib.dir.changePrompt": "
|
|
804
|
-
"
|
|
815
|
+
"sib.dir.changePrompt": "切换工作目录",
|
|
816
|
+
"sib.dir.home": "主目录",
|
|
817
|
+
"sib.dir.root": "根目录",
|
|
818
|
+
"sib.dir.default": "默认工作目录",
|
|
819
|
+
"sib.dir.current": "当前工作目录", "sib.dir.inputPlaceholder": "输入或选择目录路径",
|
|
820
|
+
"sib.dir.loading": "加载中…",
|
|
821
|
+
"sib.dir.empty": "空目录",
|
|
822
|
+
"sib.dir.loadError": "加载失败",
|
|
823
|
+
"sib.dir.confirm": "确认",
|
|
824
|
+
"sib.dir.cancel": "取消", "workspace.title": "工作区",
|
|
805
825
|
"workspace.expand": "打开工作区",
|
|
806
826
|
"workspace.collapse": "收起工作区",
|
|
807
827
|
"workspace.refresh": "刷新",
|
|
@@ -1343,6 +1363,10 @@ const I18n = (() => {
|
|
|
1343
1363
|
"settings.currency.usd": "$ 美元",
|
|
1344
1364
|
"settings.currency.cny": "¥ 人民币",
|
|
1345
1365
|
"settings.currency.exchangeRate": "汇率 (1 美元 =)",
|
|
1366
|
+
"settings.currency.updateLatest": "获取最新汇率",
|
|
1367
|
+
"settings.currency.updating": "获取中…",
|
|
1368
|
+
"settings.currency.updated": "已从 {{source}} 更新,日期 {{date}}",
|
|
1369
|
+
"settings.currency.updateFailed": "获取最新汇率失败,仍可手动输入。",
|
|
1346
1370
|
|
|
1347
1371
|
// ── Onboard ──
|
|
1348
1372
|
"onboard.title": "欢迎使用 {{brand}}",
|
data/lib/clacky/web/index.html
CHANGED
|
@@ -384,7 +384,7 @@
|
|
|
384
384
|
<div id="image-preview-strip" style="display:none"></div>
|
|
385
385
|
<div id="input-bar">
|
|
386
386
|
<!-- Hidden file picker -->
|
|
387
|
-
<input type="file" id="image-file-input" accept="
|
|
387
|
+
<input type="file" id="image-file-input" accept="*/*" multiple style="display:none">
|
|
388
388
|
<button id="btn-attach" title="Attach file (image, pdf, docx, md, tar.gz…) — drag & drop / Ctrl+V also work">
|
|
389
389
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
390
390
|
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66L9.41 17.41a2 2 0 0 1-2.83-2.83l8.49-8.48"/>
|
|
@@ -824,7 +824,15 @@
|
|
|
824
824
|
<div class="settings-exchange-rate-input-wrapper">
|
|
825
825
|
<input type="number" id="settings-exchange-rate" class="settings-exchange-rate-input" step="0.0001" min="0.0001" placeholder="6.7944">
|
|
826
826
|
<span class="settings-exchange-rate-unit">CNY</span>
|
|
827
|
+
<button type="button" id="btn-update-exchange-rate" class="settings-exchange-rate-refresh">
|
|
828
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
829
|
+
<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/>
|
|
830
|
+
<path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>
|
|
831
|
+
</svg>
|
|
832
|
+
<span data-i18n="settings.currency.updateLatest">Update latest</span>
|
|
833
|
+
</button>
|
|
827
834
|
</div>
|
|
835
|
+
<div id="settings-exchange-rate-status" class="settings-exchange-rate-status"></div>
|
|
828
836
|
</label>
|
|
829
837
|
</div>
|
|
830
838
|
</section>
|