privateboard 0.1.22 → 0.1.24
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/dist/boot.js +140 -113
- package/dist/boot.js.map +1 -1
- package/dist/cli.js +140 -113
- package/dist/cli.js.map +1 -1
- package/dist/server.js +140 -113
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/public/agent-overlay.js +4 -6
- package/public/agent-profile.js +10 -12
- package/public/app-updater.css +318 -0
- package/public/app-updater.js +247 -0
- package/public/app.js +66 -21
- package/public/home.html +1 -1
- package/public/i18n.js +60 -0
- package/public/index.html +168 -32
- package/public/mention-picker.js +527 -0
- package/public/new-agent.js +10 -5
package/public/app.js
CHANGED
|
@@ -19,22 +19,21 @@
|
|
|
19
19
|
const MODEL_LABELS = {
|
|
20
20
|
"sonnet-4-6": "Sonnet 4.6",
|
|
21
21
|
"opus-4-7": "Opus 4.7",
|
|
22
|
-
"opus-4-6": "Opus 4.6",
|
|
23
22
|
"opus-4-6-fast": "Opus 4.6 Fast",
|
|
24
23
|
"haiku-4-5": "Haiku 4.5",
|
|
25
24
|
"gpt-5-5": "GPT-5.5",
|
|
26
25
|
"gpt-5-4": "GPT-5.4",
|
|
27
26
|
"gpt-5-4-mini": "GPT-5.4 Mini",
|
|
28
|
-
"gpt-5-5-pro": "GPT-5.5 Pro",
|
|
29
27
|
"codex-5-4": "ChatGPT Codex 5.4",
|
|
30
28
|
"gemini-3-1": "Gemini 3.1 Pro",
|
|
31
29
|
"gemini-3-flash": "Gemini 3 Flash",
|
|
32
30
|
"gemini-3-1-flash": "Gemini 3.1 Flash Lite",
|
|
33
|
-
"grok-4-3": "Grok 4.3",
|
|
34
|
-
"grok-4-1-fast": "Grok 4.1 Fast",
|
|
35
|
-
"grok-4-20": "Grok 4.20",
|
|
36
31
|
"deepseek-v4-pro": "DeepSeek V4 Pro",
|
|
37
32
|
"deepseek-v4-flash": "DeepSeek Lite",
|
|
33
|
+
"glm-5-1": "GLM 5.1",
|
|
34
|
+
"kimi-k2-6": "Kimi K2.6",
|
|
35
|
+
"minimax-m2-7": "MiniMax M2.7",
|
|
36
|
+
"minimax-m2-5": "MiniMax M2.5",
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
/** Full model catalog for the new-agent composer dropdown. Mirrors
|
|
@@ -46,9 +45,8 @@
|
|
|
46
45
|
const AGENT_COMPOSER_MODELS = [
|
|
47
46
|
{ v: "opus-4-7", label: "Claude Opus 4.7", provider: "Anthropic", deck: "deep reasoning" },
|
|
48
47
|
{ v: "sonnet-4-6", label: "Claude Sonnet 4.6", provider: "Anthropic", deck: "balanced · default" },
|
|
49
|
-
{ v: "opus-4-6", label: "Claude Opus 4.6", provider: "Anthropic", deck: "prior-gen flagship" },
|
|
50
48
|
{ v: "opus-4-6-fast", label: "Claude Opus 4.6 Fast", provider: "Anthropic", deck: "faster 4.6 · same intelligence" },
|
|
51
|
-
{ v: "haiku-4-5", label: "Claude Haiku 4.5", provider: "Anthropic", deck: "fast · low-cost" },
|
|
49
|
+
{ v: "haiku-4-5", label: "Claude Haiku 4.5", provider: "Anthropic", deck: "fast · low-cost" },
|
|
52
50
|
{ v: "gpt-5-5", label: "GPT-5.5", provider: "OpenAI", deck: "1M ctx" },
|
|
53
51
|
{ v: "gpt-5-4", label: "GPT-5.4", provider: "OpenAI", deck: "general · 1M ctx" },
|
|
54
52
|
{ v: "gpt-5-4-mini", label: "GPT-5.4 Mini", provider: "OpenAI", deck: "fast · 400k ctx" },
|
|
@@ -56,11 +54,12 @@
|
|
|
56
54
|
{ v: "gemini-3-1", label: "Gemini 3.1 Pro", provider: "Google", deck: "flagship · 1M ctx" },
|
|
57
55
|
{ v: "gemini-3-flash", label: "Gemini 3 Flash", provider: "Google", deck: "frontier flash · 1M ctx" },
|
|
58
56
|
{ v: "gemini-3-1-flash", label: "Gemini 3.1 Flash Lite", provider: "Google", deck: "fast · 1M ctx" },
|
|
59
|
-
{ v: "grok-4-3", label: "Grok 4.3", provider: "xAI", deck: "flagship · 1M ctx" },
|
|
60
|
-
{ v: "grok-4-1-fast", label: "Grok 4.1 Fast", provider: "xAI", deck: "fast · 256k ctx" },
|
|
61
|
-
{ v: "grok-4-20", label: "Grok 4.20", provider: "xAI", deck: "2M ctx · big context" },
|
|
62
57
|
{ v: "deepseek-v4-pro", label: "DeepSeek V4 Pro", provider: "DeepSeek", deck: "reasoning · open weights" },
|
|
63
58
|
{ v: "deepseek-v4-flash", label: "DeepSeek Lite", provider: "DeepSeek", deck: "V4 Flash · fast · 1M ctx" },
|
|
59
|
+
{ v: "glm-5-1", label: "GLM 5.1", provider: "Zhipu", deck: "Zhipu flagship · 200k ctx" },
|
|
60
|
+
{ v: "kimi-k2-6", label: "Kimi K2.6", provider: "Moonshot", deck: "long-context" },
|
|
61
|
+
{ v: "minimax-m2-7", label: "MiniMax M2.7", provider: "MiniMax", deck: "flagship · long-context" },
|
|
62
|
+
{ v: "minimax-m2-5", label: "MiniMax M2.5", provider: "MiniMax", deck: "prior · long-context" },
|
|
64
63
|
];
|
|
65
64
|
|
|
66
65
|
/** Tone tooltips · short, user-readable summary of how each tone
|
|
@@ -789,6 +788,12 @@
|
|
|
789
788
|
|
|
790
789
|
// ── Room lifecycle ────────────────────────────────────────
|
|
791
790
|
async openRoom(roomId) {
|
|
791
|
+
// Close the @-mention picker if open · its director list is
|
|
792
|
+
// scoped to the previous room and would point at a stale cast
|
|
793
|
+
// mid-navigation. Idempotent · no-op when already closed.
|
|
794
|
+
if (window.MentionPicker && typeof window.MentionPicker.close === "function") {
|
|
795
|
+
window.MentionPicker.close();
|
|
796
|
+
}
|
|
792
797
|
// Hand off SSE to a background tracker BEFORE closing the
|
|
793
798
|
// foreground · openRoom is the room-to-room nav path
|
|
794
799
|
// (closeRoom only fires when going back to "no room") so
|
|
@@ -2662,9 +2667,24 @@
|
|
|
2662
2667
|
// If a director is mid-turn AND we don't already have a queued
|
|
2663
2668
|
// message, ask the user how to proceed.
|
|
2664
2669
|
if (this.isAgentSpeaking() && !this.pendingUserMessage) {
|
|
2665
|
-
|
|
2670
|
+
// Drain @-mentions NOW so the choice modal can carry them
|
|
2671
|
+
// along to interrupt / queue · waiting until handleSendChoice
|
|
2672
|
+
// would be too late (the textarea is cleared by then, and
|
|
2673
|
+
// the mention-picker filters by handle-still-present-in-text).
|
|
2674
|
+
const midTurnMentions = (window.MentionPicker && typeof window.MentionPicker.consumePendingMentions === "function")
|
|
2675
|
+
? window.MentionPicker.consumePendingMentions(text)
|
|
2676
|
+
: [];
|
|
2677
|
+
this.openSendChoiceModal(text, midTurnMentions);
|
|
2666
2678
|
return true;
|
|
2667
2679
|
}
|
|
2680
|
+
// Drain any pending @-mentions the user picked via the
|
|
2681
|
+
// mention-picker overlay. The picker filters out handles the
|
|
2682
|
+
// user later backspaced out, so the resulting id list is
|
|
2683
|
+
// already consistent with the text body. Falls back to an
|
|
2684
|
+
// empty array when mention-picker.js hasn't loaded yet.
|
|
2685
|
+
const mentions = (window.MentionPicker && typeof window.MentionPicker.consumePendingMentions === "function")
|
|
2686
|
+
? window.MentionPicker.consumePendingMentions(text)
|
|
2687
|
+
: [];
|
|
2668
2688
|
input.value = "";
|
|
2669
2689
|
// Shrink the textarea back to its single-line baseline ·
|
|
2670
2690
|
// typed content may have grown the field, and the cleared
|
|
@@ -2674,7 +2694,7 @@
|
|
|
2674
2694
|
if (input.matches?.(".ib-textarea[data-send-input]")) {
|
|
2675
2695
|
this.autosizeRoomInputTextarea();
|
|
2676
2696
|
}
|
|
2677
|
-
this.sendMessage(text).catch((err) => alert("Send failed: " + err.message));
|
|
2697
|
+
this.sendMessage(text, mentions).catch((err) => alert("Send failed: " + err.message));
|
|
2678
2698
|
return true;
|
|
2679
2699
|
},
|
|
2680
2700
|
|
|
@@ -2989,8 +3009,12 @@
|
|
|
2989
3009
|
/** Modal · "an agent is speaking · interrupt or wait?". Mirrors the
|
|
2990
3010
|
* pause-choice overlay's chrome (.pc-overlay / .pc-modal) so the
|
|
2991
3011
|
* visual treatment is consistent across modal prompts. */
|
|
2992
|
-
openSendChoiceModal(text) {
|
|
3012
|
+
openSendChoiceModal(text, mentions) {
|
|
2993
3013
|
this.closeSendChoiceModal();
|
|
3014
|
+
// Stash mentions alongside text so handleSendChoice forwards
|
|
3015
|
+
// them on interrupt / queue. Falls back to [] when called from
|
|
3016
|
+
// legacy / non-mention paths.
|
|
3017
|
+
this._sendChoiceMentions = Array.isArray(mentions) ? mentions.slice() : [];
|
|
2994
3018
|
const speaker = this.currentQueue[0]
|
|
2995
3019
|
? this.agentsById[this.currentQueue[0].agentId]
|
|
2996
3020
|
: null;
|
|
@@ -3037,10 +3061,12 @@
|
|
|
3037
3061
|
if (el) el.remove();
|
|
3038
3062
|
this._sendChoiceText = null;
|
|
3039
3063
|
this._sendChoiceSpeakerId = null;
|
|
3064
|
+
this._sendChoiceMentions = null;
|
|
3040
3065
|
},
|
|
3041
3066
|
handleSendChoice(choice) {
|
|
3042
3067
|
const text = this._sendChoiceText || "";
|
|
3043
3068
|
const speakerId = this._sendChoiceSpeakerId;
|
|
3069
|
+
const mentions = Array.isArray(this._sendChoiceMentions) ? this._sendChoiceMentions.slice() : [];
|
|
3044
3070
|
const input = document.querySelector('.input-bar input, [data-send-input]');
|
|
3045
3071
|
this.closeSendChoiceModal();
|
|
3046
3072
|
if (choice === "cancel" || !text.trim()) return;
|
|
@@ -3048,7 +3074,7 @@
|
|
|
3048
3074
|
input.value = "";
|
|
3049
3075
|
}
|
|
3050
3076
|
if (choice === "interrupt") {
|
|
3051
|
-
this.sendMessage(text).catch((err) => alert("Send failed: " + err.message));
|
|
3077
|
+
this.sendMessage(text, mentions).catch((err) => alert("Send failed: " + err.message));
|
|
3052
3078
|
return;
|
|
3053
3079
|
}
|
|
3054
3080
|
if (choice === "queue") {
|
|
@@ -3064,7 +3090,7 @@
|
|
|
3064
3090
|
// turns, AFTER current speaker finishes and BEFORE the next
|
|
3065
3091
|
// speaker starts. The placeholder clears when the
|
|
3066
3092
|
// message-appended SSE comes back.
|
|
3067
|
-
this.sendMessage(text,
|
|
3093
|
+
this.sendMessage(text, mentions, "after-speaker").catch((err) => {
|
|
3068
3094
|
alert("Queue failed: " + err.message);
|
|
3069
3095
|
this.pendingUserMessage = null;
|
|
3070
3096
|
this.pendingForSpeakerId = null;
|
|
@@ -6251,11 +6277,14 @@
|
|
|
6251
6277
|
// base provider colour. Append-only — adding a new variant just
|
|
6252
6278
|
// requires its modelV at the appropriate position.
|
|
6253
6279
|
const MODEL_SHADE_ORDER = {
|
|
6254
|
-
anthropic: ["opus-4-7", "
|
|
6255
|
-
openai: ["gpt-5-5", "gpt-5-4-mini", "codex-5-4"],
|
|
6280
|
+
anthropic: ["opus-4-7", "sonnet-4-6", "opus-4-6-fast", "haiku-4-5"],
|
|
6281
|
+
openai: ["gpt-5-5", "gpt-5-4", "gpt-5-4-mini", "codex-5-4"],
|
|
6256
6282
|
google: ["gemini-3-1", "gemini-3-flash", "gemini-3-1-flash"],
|
|
6257
|
-
xai
|
|
6258
|
-
deepseek: ["deepseek-v4-pro", "deepseek-v4-flash"
|
|
6283
|
+
// xai · no Grok models in registry currently.
|
|
6284
|
+
deepseek: ["deepseek-v4-pro", "deepseek-v4-flash"],
|
|
6285
|
+
zhipu: ["glm-5-1"],
|
|
6286
|
+
moonshot: ["kimi-k2-6"],
|
|
6287
|
+
minimax: ["minimax-m2-7", "minimax-m2-5"],
|
|
6259
6288
|
};
|
|
6260
6289
|
const providerOf = (modelV) => {
|
|
6261
6290
|
const hit = reachable.find((m) => m.modelV === modelV);
|
|
@@ -13957,8 +13986,24 @@
|
|
|
13957
13986
|
source = null;
|
|
13958
13987
|
}
|
|
13959
13988
|
}
|
|
13960
|
-
|
|
13961
|
-
|
|
13989
|
+
// Visibility · hide only when the user is actively viewing the
|
|
13990
|
+
// same room as the playing source. "Actively viewing" means BOTH
|
|
13991
|
+
// currentRoomId matches AND the sidebar's active tab is rooms.
|
|
13992
|
+
// When the user switches to the Agents tab (or any non-rooms
|
|
13993
|
+
// tab), currentRoomId stays sticky to the last-opened room, but
|
|
13994
|
+
// the user is no longer looking at the room's stream — the
|
|
13995
|
+
// player is now their only anchor back to the live audio, so it
|
|
13996
|
+
// has to surface even though the ids match.
|
|
13997
|
+
const activeTabEl = document.querySelector(".sidebar-tab.active[data-sidebar-tab]");
|
|
13998
|
+
const activeTab = activeTabEl ? activeTabEl.dataset.sidebarTab : null;
|
|
13999
|
+
const viewingRoomsTab = !activeTab || activeTab === "rooms";
|
|
14000
|
+
const viewingSameRoom = !!(
|
|
14001
|
+
source &&
|
|
14002
|
+
source.roomId &&
|
|
14003
|
+
source.roomId === this.currentRoomId &&
|
|
14004
|
+
viewingRoomsTab
|
|
14005
|
+
);
|
|
14006
|
+
if (!source || viewingSameRoom) {
|
|
13962
14007
|
el.hidden = true;
|
|
13963
14008
|
el.removeAttribute("data-mini-player-room-id");
|
|
13964
14009
|
el.removeAttribute("data-mini-player-kind");
|
package/public/home.html
CHANGED
|
@@ -1802,7 +1802,7 @@
|
|
|
1802
1802
|
|
|
1803
1803
|
<div class="hero-actions">
|
|
1804
1804
|
<a href="#install" class="big-btn primary">[ ◆ Convene a Room ]</a>
|
|
1805
|
-
<a href="https://github.com/kaysaith1900/privateboard/releases/download/v0.1.
|
|
1805
|
+
<a href="https://github.com/kaysaith1900/privateboard/releases/download/v0.1.23/PrivateBoard-0.1.23-arm64.dmg"
|
|
1806
1806
|
class="big-btn secondary"
|
|
1807
1807
|
download
|
|
1808
1808
|
aria-label="Download PrivateBoard for macOS (Apple Silicon)"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 3v12"/><polyline points="6 11 12 17 18 11"/><path d="M5 21h14"/></svg> Download for Mac</a>
|
package/public/i18n.js
CHANGED
|
@@ -531,6 +531,21 @@
|
|
|
531
531
|
vonb_theme_nintendo_name: "CRITIQUE",
|
|
532
532
|
vonb_theme_nintendo_deck: "burgundy carpet · formal",
|
|
533
533
|
|
|
534
|
+
upd_classification_left: "app update",
|
|
535
|
+
upd_classification_right: "// privateboard",
|
|
536
|
+
upd_meta_label: "// release",
|
|
537
|
+
upd_meta_live: "available",
|
|
538
|
+
upd_title: "A new version of PrivateBoard is available.",
|
|
539
|
+
upd_available_deck: "Download now and apply on restart. You can keep working while it downloads.",
|
|
540
|
+
upd_progress_preparing: "preparing…",
|
|
541
|
+
upd_ready_deck: "Download complete. Restart PrivateBoard to apply the update.",
|
|
542
|
+
upd_error_deck: "Could not reach the update server. Check your connection and try again later, or download manually from GitHub Releases.",
|
|
543
|
+
upd_btn_update_now: "Update now",
|
|
544
|
+
upd_btn_later: "Later",
|
|
545
|
+
upd_btn_hide: "Hide",
|
|
546
|
+
upd_btn_restart_now: "Restart to update",
|
|
547
|
+
upd_btn_close: "Close",
|
|
548
|
+
|
|
534
549
|
onb_v2_classification_left: "first run · welcome",
|
|
535
550
|
onb_v2_classification_right: "// local · ~60 seconds",
|
|
536
551
|
onb_v2_back: "[ ◂ Back ]",
|
|
@@ -1507,6 +1522,21 @@ When the room ___, raise an objection.`,
|
|
|
1507
1522
|
vonb_theme_nintendo_name: "批评",
|
|
1508
1523
|
vonb_theme_nintendo_deck: "酒红地毯 · 正式",
|
|
1509
1524
|
|
|
1525
|
+
upd_classification_left: "应用更新",
|
|
1526
|
+
upd_classification_right: "// privateboard",
|
|
1527
|
+
upd_meta_label: "// 新版本",
|
|
1528
|
+
upd_meta_live: "可用",
|
|
1529
|
+
upd_title: "PrivateBoard 有新版本可用",
|
|
1530
|
+
upd_available_deck: "立即下载,重启后生效。下载过程中你可以继续使用。",
|
|
1531
|
+
upd_progress_preparing: "准备中…",
|
|
1532
|
+
upd_ready_deck: "下载完成,重启 PrivateBoard 即可应用新版本。",
|
|
1533
|
+
upd_error_deck: "无法连接到更新服务器。请检查网络后重试,或前往 GitHub Releases 手动下载。",
|
|
1534
|
+
upd_btn_update_now: "现在更新",
|
|
1535
|
+
upd_btn_later: "稍后",
|
|
1536
|
+
upd_btn_hide: "隐藏",
|
|
1537
|
+
upd_btn_restart_now: "重启以更新",
|
|
1538
|
+
upd_btn_close: "关闭",
|
|
1539
|
+
|
|
1510
1540
|
onb_v2_classification_left: "首次进入 · 欢迎",
|
|
1511
1541
|
onb_v2_classification_right: "// 本地 · 约 60 秒",
|
|
1512
1542
|
onb_v2_back: "[ ◂ 上一步 ]",
|
|
@@ -2459,6 +2489,21 @@ When the room ___, raise an objection.`,
|
|
|
2459
2489
|
vonb_theme_nintendo_name: "クリティーク",
|
|
2460
2490
|
vonb_theme_nintendo_deck: "バーガンディ絨毯 · フォーマル",
|
|
2461
2491
|
|
|
2492
|
+
upd_classification_left: "アプリ更新",
|
|
2493
|
+
upd_classification_right: "// privateboard",
|
|
2494
|
+
upd_meta_label: "// リリース",
|
|
2495
|
+
upd_meta_live: "利用可能",
|
|
2496
|
+
upd_title: "PrivateBoard の新しいバージョンがあります。",
|
|
2497
|
+
upd_available_deck: "今すぐダウンロードし、再起動で適用されます。ダウンロード中も作業を続けられます。",
|
|
2498
|
+
upd_progress_preparing: "準備中…",
|
|
2499
|
+
upd_ready_deck: "ダウンロード完了。PrivateBoard を再起動して更新を適用してください。",
|
|
2500
|
+
upd_error_deck: "更新サーバーに接続できません。接続を確認して再試行するか、GitHub Releases から手動でダウンロードしてください。",
|
|
2501
|
+
upd_btn_update_now: "今すぐ更新",
|
|
2502
|
+
upd_btn_later: "後で",
|
|
2503
|
+
upd_btn_hide: "隠す",
|
|
2504
|
+
upd_btn_restart_now: "再起動して更新",
|
|
2505
|
+
upd_btn_close: "閉じる",
|
|
2506
|
+
|
|
2462
2507
|
onb_v2_classification_left: "初回 · ようこそ",
|
|
2463
2508
|
onb_v2_classification_right: "// ローカル · 約 60 秒",
|
|
2464
2509
|
onb_v2_back: "[ ◂ 戻る ]",
|
|
@@ -3231,6 +3276,21 @@ When the room ___, raise an objection.`,
|
|
|
3231
3276
|
vonb_theme_nintendo_name: "CRÍTICA",
|
|
3232
3277
|
vonb_theme_nintendo_deck: "alfombra burdeos · formal",
|
|
3233
3278
|
|
|
3279
|
+
upd_classification_left: "actualización de la app",
|
|
3280
|
+
upd_classification_right: "// privateboard",
|
|
3281
|
+
upd_meta_label: "// versión",
|
|
3282
|
+
upd_meta_live: "disponible",
|
|
3283
|
+
upd_title: "Hay una nueva versión de PrivateBoard.",
|
|
3284
|
+
upd_available_deck: "Descárgala ahora y se aplicará al reiniciar. Puedes seguir trabajando mientras tanto.",
|
|
3285
|
+
upd_progress_preparing: "preparando…",
|
|
3286
|
+
upd_ready_deck: "Descarga completa. Reinicia PrivateBoard para aplicar la actualización.",
|
|
3287
|
+
upd_error_deck: "No se pudo conectar al servidor de actualizaciones. Revisa tu conexión o descarga manualmente desde GitHub Releases.",
|
|
3288
|
+
upd_btn_update_now: "Actualizar ahora",
|
|
3289
|
+
upd_btn_later: "Más tarde",
|
|
3290
|
+
upd_btn_hide: "Ocultar",
|
|
3291
|
+
upd_btn_restart_now: "Reiniciar para actualizar",
|
|
3292
|
+
upd_btn_close: "Cerrar",
|
|
3293
|
+
|
|
3234
3294
|
onb_v2_classification_left: "primera vez · bienvenida",
|
|
3235
3295
|
onb_v2_classification_right: "// local · ~60 segundos",
|
|
3236
3296
|
onb_v2_back: "[ ◂ Atrás ]",
|
package/public/index.html
CHANGED
|
@@ -523,6 +523,14 @@
|
|
|
523
523
|
html.is-electron-mac .room-head .head-cast img {
|
|
524
524
|
-webkit-app-region: no-drag;
|
|
525
525
|
}
|
|
526
|
+
/* The expand-btn's ::after halo paints OUTSIDE the button rect
|
|
527
|
+
(inset: -16px), so it doesn't inherit the button's no-drag and
|
|
528
|
+
gets eaten by `.room-head { drag }` above. Stamp no-drag on the
|
|
529
|
+
pseudo directly so the 48×48 hit zone keeps registering clicks.
|
|
530
|
+
(Same shape as the sidebar-collapse-btn::after override.) */
|
|
531
|
+
html.is-electron-mac .room-head .room-head-expand::after {
|
|
532
|
+
-webkit-app-region: no-drag;
|
|
533
|
+
}
|
|
526
534
|
/* ─── macOS Electron · top-strip drag coverage for non-room views.
|
|
527
535
|
When the room view is hidden (All Reports / All Notes / Search /
|
|
528
536
|
Agent Profile) or the room view is shown with no current room (the
|
|
@@ -817,42 +825,65 @@
|
|
|
817
825
|
|
|
818
826
|
/* ─── In-header expand button ───
|
|
819
827
|
Lives at the leading edge of `.room-head` (rendered by
|
|
820
|
-
renderHeader() in app.js).
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
828
|
+
renderHeader() in app.js). Visual twin of `.sidebar-collapse-btn`
|
|
829
|
+
so the collapse/expand pair reads as the SAME control across
|
|
830
|
+
the two places it can appear (in-sidebar when open · in-header
|
|
831
|
+
when sidebar collapsed AND a room is loaded). Icon-only · no
|
|
832
|
+
chrome · same Lucide PanelLeft mask · same hover-lime cascade.
|
|
833
|
+
Always rendered in the mirrored variant (panel folded to the
|
|
834
|
+
right edge) since this button only ever appears in the collapsed
|
|
835
|
+
state · clicking it expands the sidebar back. */
|
|
825
836
|
.room-head-expand {
|
|
826
837
|
appearance: none;
|
|
827
|
-
background:
|
|
828
|
-
border: 0
|
|
838
|
+
background: transparent;
|
|
839
|
+
border: 0;
|
|
829
840
|
color: var(--text-soft);
|
|
830
841
|
cursor: pointer;
|
|
831
|
-
width:
|
|
832
|
-
height:
|
|
842
|
+
width: 16px;
|
|
843
|
+
height: 16px;
|
|
833
844
|
padding: 0;
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
/* position: relative so the ::after tooltip anchors to the
|
|
839
|
-
button rather than escaping into the room-head's layout. */
|
|
845
|
+
flex-shrink: 0;
|
|
846
|
+
transition: color 0.12s;
|
|
847
|
+
/* position: relative anchors the ::after hit-area expander so
|
|
848
|
+
the cursor doesn't have to land precisely on the 16px icon. */
|
|
840
849
|
position: relative;
|
|
841
850
|
display: none;
|
|
842
|
-
align-items: center;
|
|
843
|
-
justify-content: center;
|
|
844
|
-
transition: color 0.12s, background 0.12s, border-color 0.12s;
|
|
845
|
-
flex-shrink: 0;
|
|
846
851
|
}
|
|
847
|
-
.room-head-expand::before {
|
|
848
|
-
|
|
849
|
-
display:
|
|
852
|
+
.room-head-expand::before {
|
|
853
|
+
content: "";
|
|
854
|
+
display: block;
|
|
855
|
+
width: 16px;
|
|
856
|
+
height: 16px;
|
|
857
|
+
background-color: currentColor;
|
|
858
|
+
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><path d='M9 3v18'/><path d='M5 8h2'/><path d='M5 12h2'/><path d='M5 16h2'/></svg>");
|
|
859
|
+
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2'/><path d='M9 3v18'/><path d='M5 8h2'/><path d='M5 12h2'/><path d='M5 16h2'/></svg>");
|
|
860
|
+
-webkit-mask-repeat: no-repeat;
|
|
861
|
+
mask-repeat: no-repeat;
|
|
862
|
+
-webkit-mask-position: center;
|
|
863
|
+
mask-position: center;
|
|
864
|
+
-webkit-mask-size: 16px 16px;
|
|
865
|
+
mask-size: 16px 16px;
|
|
866
|
+
/* Same scaleX(-1) the sidebar-collapse-btn uses when
|
|
867
|
+
body.sidebar-collapsed · since this button is ONLY visible
|
|
868
|
+
in the collapsed state, the flip is unconditional here. */
|
|
869
|
+
transform: scaleX(-1);
|
|
850
870
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
871
|
+
/* Invisible hit-area expander · matches `.sidebar-collapse-btn::after`
|
|
872
|
+
so the click rectangle grows to 48×48 around the 16px icon. */
|
|
873
|
+
.room-head-expand::after {
|
|
874
|
+
content: "";
|
|
875
|
+
position: absolute;
|
|
876
|
+
inset: -16px;
|
|
877
|
+
}
|
|
878
|
+
body.sidebar-collapsed .room-head-expand {
|
|
879
|
+
display: block;
|
|
880
|
+
/* Extra 5px breathing room between the icon and the title cluster
|
|
881
|
+
on top of the room-head's own 12px column gap · the icon sat
|
|
882
|
+
too close to the kicker / subject otherwise. Scoped to the
|
|
883
|
+
collapsed state since the button itself only exists then. */
|
|
884
|
+
margin-right: 5px;
|
|
855
885
|
}
|
|
886
|
+
.room-head-expand:hover { color: var(--lime); }
|
|
856
887
|
|
|
857
888
|
/* ─── Sidebar tabs (Rooms / Agents) — segmented control with icon ─── */
|
|
858
889
|
.sidebar-tabs {
|
|
@@ -2752,7 +2783,12 @@
|
|
|
2752
2783
|
transition: background-color 5000s ease-in-out 0s;
|
|
2753
2784
|
}
|
|
2754
2785
|
.search-page.has-results .search-input {
|
|
2755
|
-
padding
|
|
2786
|
+
/* Horizontal padding matches the new-room composer's `.cmp-input`
|
|
2787
|
+
(14 px each side) so the text-to-input-box gutter reads the same
|
|
2788
|
+
across the two surfaces. The earlier 6 px was visibly tighter
|
|
2789
|
+
than the new-room textarea and made the head-row input feel
|
|
2790
|
+
cramped against its panel-2 pill. */
|
|
2791
|
+
padding: 9px 14px;
|
|
2756
2792
|
font-size: 13px;
|
|
2757
2793
|
}
|
|
2758
2794
|
.search-input::placeholder {
|
|
@@ -11773,11 +11809,11 @@
|
|
|
11773
11809
|
align-items: center;
|
|
11774
11810
|
gap: 8px;
|
|
11775
11811
|
padding: 6px 10px;
|
|
11776
|
-
/* Bottombar
|
|
11777
|
-
|
|
11778
|
-
|
|
11779
|
-
|
|
11780
|
-
|
|
11812
|
+
/* Bottombar floats transparently over the input frame — no fill,
|
|
11813
|
+
no top hairline. Only the topbar carries the brand-tinted strip
|
|
11814
|
+
treatment; the bottom controls read as buttons-on-the-input,
|
|
11815
|
+
not a second chrome band. */
|
|
11816
|
+
background: transparent;
|
|
11781
11817
|
min-height: 48px;
|
|
11782
11818
|
/* Establish a size container · child elements (notably the
|
|
11783
11819
|
voice-mode toggle's text) can respond to the toolbar's width
|
|
@@ -15692,11 +15728,14 @@
|
|
|
15692
15728
|
<script src="user-settings.js" defer></script>
|
|
15693
15729
|
<link rel="stylesheet" href="voice-replay.css">
|
|
15694
15730
|
<script src="voice-replay.js" defer></script>
|
|
15731
|
+
<script src="mention-picker.js" defer></script>
|
|
15695
15732
|
<script src="auto-hide-scroll.js" defer></script>
|
|
15696
15733
|
<link rel="stylesheet" href="onboarding.css">
|
|
15697
15734
|
<script src="onboarding.js" defer></script>
|
|
15698
15735
|
<link rel="stylesheet" href="voice-onboarding.css">
|
|
15699
15736
|
<script src="voice-onboarding.js" defer></script>
|
|
15737
|
+
<link rel="stylesheet" href="app-updater.css">
|
|
15738
|
+
<script src="app-updater.js" defer></script>
|
|
15700
15739
|
<link rel="stylesheet" href="quote-cta.css">
|
|
15701
15740
|
<script src="quote-cta.js" defer></script>
|
|
15702
15741
|
<script src="typing-sfx.js" defer></script>
|
|
@@ -16946,6 +16985,16 @@
|
|
|
16946
16985
|
else if (which === "agents") applyAgentsSubState(lsGet(AGENTS_KEY) || "new");
|
|
16947
16986
|
|
|
16948
16987
|
if (persist) lsSet(TAB_KEY, which);
|
|
16988
|
+
|
|
16989
|
+
// Voice mini-player visibility depends on the active sidebar
|
|
16990
|
+
// tab (refreshMiniPlayer in app.js gates on it). A bare tab
|
|
16991
|
+
// switch doesn't fire any of the boardroom:replay-* events, so
|
|
16992
|
+
// we trigger the refresh explicitly here — otherwise the player
|
|
16993
|
+
// sticks in whichever state it was last evaluated under (most
|
|
16994
|
+
// visibly: hidden when entering Agents from the playing room).
|
|
16995
|
+
if (window.app && typeof window.app.refreshMiniPlayer === "function") {
|
|
16996
|
+
window.app.refreshMiniPlayer();
|
|
16997
|
+
}
|
|
16949
16998
|
}
|
|
16950
16999
|
|
|
16951
17000
|
/* ─── Capture-phase tracker for sidebar agent rows ─────────────
|
|
@@ -17424,6 +17473,93 @@
|
|
|
17424
17473
|
</article>
|
|
17425
17474
|
</template>
|
|
17426
17475
|
|
|
17476
|
+
<div class="upd-overlay" id="upd-overlay" role="dialog" aria-modal="true" aria-hidden="true">
|
|
17477
|
+
<div class="upd-backdrop" data-upd-close></div>
|
|
17478
|
+
<div class="upd-modal" role="document">
|
|
17479
|
+
|
|
17480
|
+
<div class="upd-classification">
|
|
17481
|
+
<span><span class="dot">●</span> <span data-i18n="upd_classification_left">app update</span></span>
|
|
17482
|
+
<span class="right" data-i18n="upd_classification_right">// privateboard</span>
|
|
17483
|
+
</div>
|
|
17484
|
+
|
|
17485
|
+
<header class="upd-head">
|
|
17486
|
+
<div class="upd-head-text">
|
|
17487
|
+
<div class="meta">
|
|
17488
|
+
<span data-i18n="upd_meta_label">// release</span>
|
|
17489
|
+
<span>·</span>
|
|
17490
|
+
<span class="live" data-i18n="upd_meta_live">available</span>
|
|
17491
|
+
</div>
|
|
17492
|
+
<div class="title" data-upd-title data-i18n="upd_title">A new version of PrivateBoard is available.</div>
|
|
17493
|
+
</div>
|
|
17494
|
+
<button type="button" class="close-btn" data-upd-close aria-label="Close">✕</button>
|
|
17495
|
+
</header>
|
|
17496
|
+
|
|
17497
|
+
<div class="upd-body">
|
|
17498
|
+
|
|
17499
|
+
<!-- AVAILABLE · prompt the user to start the download -->
|
|
17500
|
+
<div class="upd-state upd-state-available">
|
|
17501
|
+
<div class="upd-version">
|
|
17502
|
+
<span class="from" data-upd-from-version>v0.0.0</span>
|
|
17503
|
+
<span class="arrow">→</span>
|
|
17504
|
+
<span class="to" data-upd-to-version>v0.0.0</span>
|
|
17505
|
+
</div>
|
|
17506
|
+
<p class="upd-deck" data-i18n="upd_available_deck">Download now and apply on restart. You can keep working while it downloads.</p>
|
|
17507
|
+
</div>
|
|
17508
|
+
|
|
17509
|
+
<!-- DOWNLOADING · live progress -->
|
|
17510
|
+
<div class="upd-state upd-state-downloading">
|
|
17511
|
+
<div class="upd-version">
|
|
17512
|
+
<span class="from" data-upd-from-version-d>v0.0.0</span>
|
|
17513
|
+
<span class="arrow">→</span>
|
|
17514
|
+
<span class="to" data-upd-to-version-d>v0.0.0</span>
|
|
17515
|
+
</div>
|
|
17516
|
+
<div class="upd-progress-card">
|
|
17517
|
+
<div class="upd-progress-head">
|
|
17518
|
+
<span class="upd-progress-pct" data-upd-pct>0%</span>
|
|
17519
|
+
<span class="upd-progress-rate" data-upd-rate>—</span>
|
|
17520
|
+
</div>
|
|
17521
|
+
<div class="upd-progress-bar indeterminate" data-upd-bar><span></span></div>
|
|
17522
|
+
<div class="upd-progress-bytes" data-upd-bytes data-i18n="upd_progress_preparing">preparing…</div>
|
|
17523
|
+
</div>
|
|
17524
|
+
</div>
|
|
17525
|
+
|
|
17526
|
+
<!-- READY · download complete, prompt restart -->
|
|
17527
|
+
<div class="upd-state upd-state-ready">
|
|
17528
|
+
<div class="upd-version">
|
|
17529
|
+
<span class="from" data-upd-from-version-r>v0.0.0</span>
|
|
17530
|
+
<span class="arrow">→</span>
|
|
17531
|
+
<span class="to" data-upd-to-version-r>v0.0.0</span>
|
|
17532
|
+
</div>
|
|
17533
|
+
<p class="upd-deck" data-i18n="upd_ready_deck">Download complete. Restart PrivateBoard to apply the update.</p>
|
|
17534
|
+
</div>
|
|
17535
|
+
|
|
17536
|
+
<!-- ERROR -->
|
|
17537
|
+
<div class="upd-state upd-state-error">
|
|
17538
|
+
<div class="upd-error" data-upd-error-message>—</div>
|
|
17539
|
+
<p class="upd-deck" data-i18n="upd_error_deck">Could not reach the update server. Check your connection and try again later, or download manually from GitHub Releases.</p>
|
|
17540
|
+
</div>
|
|
17541
|
+
|
|
17542
|
+
</div>
|
|
17543
|
+
|
|
17544
|
+
<footer class="upd-foot">
|
|
17545
|
+
<span class="upd-foot-state upd-foot-state-available">
|
|
17546
|
+
<button type="button" class="upd-btn" data-upd-dismiss data-i18n="upd_btn_later">Later</button>
|
|
17547
|
+
<button type="button" class="upd-btn primary" data-upd-download data-i18n="upd_btn_update_now">Update now</button>
|
|
17548
|
+
</span>
|
|
17549
|
+
<span class="upd-foot-state upd-foot-state-downloading">
|
|
17550
|
+
<button type="button" class="upd-btn" data-upd-dismiss data-i18n="upd_btn_hide">Hide</button>
|
|
17551
|
+
</span>
|
|
17552
|
+
<span class="upd-foot-state upd-foot-state-ready">
|
|
17553
|
+
<button type="button" class="upd-btn" data-upd-dismiss data-i18n="upd_btn_later">Later</button>
|
|
17554
|
+
<button type="button" class="upd-btn primary" data-upd-install data-i18n="upd_btn_restart_now">Restart to update</button>
|
|
17555
|
+
</span>
|
|
17556
|
+
<span class="upd-foot-state upd-foot-state-error">
|
|
17557
|
+
<button type="button" class="upd-btn" data-upd-dismiss data-i18n="upd_btn_close">Close</button>
|
|
17558
|
+
</span>
|
|
17559
|
+
</footer>
|
|
17560
|
+
</div>
|
|
17561
|
+
</div>
|
|
17562
|
+
|
|
17427
17563
|
<div class="vonb-overlay" id="vonb-overlay" role="dialog" aria-modal="true" aria-hidden="true">
|
|
17428
17564
|
<div class="vonb-backdrop" data-vonb-close></div>
|
|
17429
17565
|
<div class="vonb-modal" role="document">
|