@silicaclaw/cli 2026.3.20-14 → 2026.3.20-16
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/CHANGELOG.md +7 -1
- package/VERSION +1 -1
- package/apps/local-console/dist/apps/local-console/src/server.d.ts +1 -5
- package/apps/local-console/dist/apps/local-console/src/server.js +23 -39
- package/apps/local-console/public/app/app.js +5 -129
- package/apps/local-console/public/app/social.js +2 -29
- package/apps/local-console/public/app/styles.css +21 -42
- package/apps/local-console/public/app/template.js +0 -21
- package/apps/local-console/public/app/translations.js +0 -6
- package/apps/local-console/src/server.ts +14 -33
- package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
- package/openclaw-skills/silicaclaw-broadcast/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/silicaclaw-gateway.mjs +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## v1.0 beta - 2026-03-20
|
|
4
4
|
|
|
5
|
-
### 2026.3.20-
|
|
5
|
+
### 2026.3.20-16
|
|
6
|
+
|
|
7
|
+
- release build:
|
|
8
|
+
- prepared another fresh latest-channel package build without publishing
|
|
9
|
+
- regenerated the npm tarball through the verified release packing workflow
|
|
10
|
+
|
|
11
|
+
### 2026.3.20-15
|
|
6
12
|
|
|
7
13
|
- release build:
|
|
8
14
|
- prepared another fresh latest-channel package build without publishing
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v2026.3.20-
|
|
1
|
+
v2026.3.20-16
|
|
@@ -623,7 +623,6 @@ export declare class LocalNodeService {
|
|
|
623
623
|
getIdentity(): AgentIdentity | null;
|
|
624
624
|
getSocialMessages(limit?: number, options?: {
|
|
625
625
|
agent_id?: string | null;
|
|
626
|
-
offset?: number | null;
|
|
627
626
|
}): {
|
|
628
627
|
total: number;
|
|
629
628
|
items: SocialMessageView[];
|
|
@@ -657,10 +656,7 @@ export declare class LocalNodeService {
|
|
|
657
656
|
last_message_at: number | null;
|
|
658
657
|
unread_count: number;
|
|
659
658
|
}>;
|
|
660
|
-
getPrivateMessages(conversationId: string, limit?: number
|
|
661
|
-
total: number;
|
|
662
|
-
items: PrivateMessageView[];
|
|
663
|
-
};
|
|
659
|
+
getPrivateMessages(conversationId: string, limit?: number): PrivateMessageView[];
|
|
664
660
|
sendPrivateMessage(input: {
|
|
665
661
|
to_agent_id: string;
|
|
666
662
|
recipient_encryption_public_key: string;
|
|
@@ -1580,7 +1580,6 @@ class LocalNodeService {
|
|
|
1580
1580
|
}
|
|
1581
1581
|
getSocialMessages(limit = 50, options) {
|
|
1582
1582
|
const resolvedLimit = Math.max(1, Math.min(200, Number(limit) || 50));
|
|
1583
|
-
const resolvedOffset = Math.max(0, Number(options?.offset) || 0);
|
|
1584
1583
|
this.ensureLocalDirectoryBaseline();
|
|
1585
1584
|
this.compactCacheInMemory();
|
|
1586
1585
|
const agentId = String(options?.agent_id || "").trim();
|
|
@@ -1589,7 +1588,7 @@ class LocalNodeService {
|
|
|
1589
1588
|
: this.socialMessages;
|
|
1590
1589
|
return {
|
|
1591
1590
|
total: filtered.length,
|
|
1592
|
-
items: filtered.slice(
|
|
1591
|
+
items: filtered.slice(0, resolvedLimit).map((message) => {
|
|
1593
1592
|
const profile = this.directory.profiles[message.agent_id];
|
|
1594
1593
|
const lastSeenAt = this.directory.presence[message.agent_id] ?? 0;
|
|
1595
1594
|
const observations = this.socialMessageObservations.filter((item) => item.message_id === message.message_id);
|
|
@@ -1651,12 +1650,11 @@ class LocalNodeService {
|
|
|
1651
1650
|
}
|
|
1652
1651
|
return Array.from(conversations.values()).sort((a, b) => (b.last_message_at || 0) - (a.last_message_at || 0));
|
|
1653
1652
|
}
|
|
1654
|
-
getPrivateMessages(conversationId, limit = PRIVATE_MESSAGE_QUERY_LIMIT
|
|
1653
|
+
getPrivateMessages(conversationId, limit = PRIVATE_MESSAGE_QUERY_LIMIT) {
|
|
1655
1654
|
const normalizedConversationId = String(conversationId || "").trim();
|
|
1656
1655
|
const resolvedLimit = Math.max(1, Math.min(PRIVATE_MESSAGE_QUERY_LIMIT, Number(limit) || PRIVATE_MESSAGE_QUERY_LIMIT));
|
|
1657
|
-
const resolvedOffset = Math.max(0, Number(offset) || 0);
|
|
1658
1656
|
const receiptsByMessageId = new Map(this.privateMessageReceipts.map((receipt) => [receipt.message_id, receipt.status]));
|
|
1659
|
-
|
|
1657
|
+
return this.privateMessages
|
|
1660
1658
|
.filter((message) => {
|
|
1661
1659
|
if (message.from_agent_id === message.to_agent_id) {
|
|
1662
1660
|
return false;
|
|
@@ -1667,24 +1665,20 @@ class LocalNodeService {
|
|
|
1667
1665
|
}
|
|
1668
1666
|
return !normalizedConversationId || message.conversation_id === normalizedConversationId;
|
|
1669
1667
|
})
|
|
1670
|
-
.sort((a, b) => a.created_at - b.created_at)
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
this.privateMessageDeliveryStatusCache.get(message.message_id) ||
|
|
1685
|
-
(message.from_agent_id === this.identity?.agent_id ? "fallback-sent" : "sent"),
|
|
1686
|
-
})),
|
|
1687
|
-
};
|
|
1668
|
+
.sort((a, b) => a.created_at - b.created_at)
|
|
1669
|
+
.slice(-resolvedLimit)
|
|
1670
|
+
.map((message) => ({
|
|
1671
|
+
message_id: message.message_id,
|
|
1672
|
+
conversation_id: message.conversation_id,
|
|
1673
|
+
from_agent_id: message.from_agent_id,
|
|
1674
|
+
to_agent_id: message.to_agent_id,
|
|
1675
|
+
body: this.decryptPrivateMessageBody(message),
|
|
1676
|
+
created_at: message.created_at,
|
|
1677
|
+
is_self: message.from_agent_id === this.identity?.agent_id,
|
|
1678
|
+
delivery_status: receiptsByMessageId.get(message.message_id) ||
|
|
1679
|
+
this.privateMessageDeliveryStatusCache.get(message.message_id) ||
|
|
1680
|
+
(message.from_agent_id === this.identity?.agent_id ? "fallback-sent" : "sent"),
|
|
1681
|
+
}));
|
|
1688
1682
|
}
|
|
1689
1683
|
async sendPrivateMessage(input) {
|
|
1690
1684
|
if (!this.identity || !this.privateEncryptionKeyPair) {
|
|
@@ -1733,7 +1727,7 @@ class LocalNodeService {
|
|
|
1733
1727
|
await this.publish(PRIVATE_MESSAGE_TOPIC, message);
|
|
1734
1728
|
}
|
|
1735
1729
|
this.privateMessageDeliveryStatusCache.set(message.message_id, reason);
|
|
1736
|
-
const view = this.getPrivateMessages(message.conversation_id
|
|
1730
|
+
const view = this.getPrivateMessages(message.conversation_id).find((item) => item.message_id === message.message_id);
|
|
1737
1731
|
if (view) {
|
|
1738
1732
|
view.delivery_status = reason;
|
|
1739
1733
|
}
|
|
@@ -3720,7 +3714,7 @@ async function main() {
|
|
|
3720
3714
|
catch {
|
|
3721
3715
|
// best effort after response has been sent
|
|
3722
3716
|
}
|
|
3723
|
-
},
|
|
3717
|
+
}, 150);
|
|
3724
3718
|
}));
|
|
3725
3719
|
app.put("/api/profile", asyncRoute(async (req, res) => {
|
|
3726
3720
|
const body = req.body;
|
|
@@ -3817,9 +3811,8 @@ async function main() {
|
|
|
3817
3811
|
}));
|
|
3818
3812
|
app.get("/api/messages", (req, res) => {
|
|
3819
3813
|
const limit = Number(req.query.limit ?? 50);
|
|
3820
|
-
const offset = Number(req.query.offset ?? 0);
|
|
3821
3814
|
const agentId = String(req.query.agent_id ?? "").trim();
|
|
3822
|
-
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null
|
|
3815
|
+
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null }));
|
|
3823
3816
|
});
|
|
3824
3817
|
app.get("/api/private/state", (_req, res) => {
|
|
3825
3818
|
sendOk(res, node.getPrivateMessagingState());
|
|
@@ -3830,8 +3823,7 @@ async function main() {
|
|
|
3830
3823
|
app.get("/api/private/messages", (req, res) => {
|
|
3831
3824
|
const conversationId = String(req.query.conversation_id ?? "").trim();
|
|
3832
3825
|
const limit = Number(req.query.limit ?? PRIVATE_MESSAGE_QUERY_LIMIT);
|
|
3833
|
-
|
|
3834
|
-
sendOk(res, node.getPrivateMessages(conversationId, limit, offset));
|
|
3826
|
+
sendOk(res, node.getPrivateMessages(conversationId, limit));
|
|
3835
3827
|
});
|
|
3836
3828
|
app.post("/api/private/messages/send", asyncRoute(async (req, res) => {
|
|
3837
3829
|
const result = await node.sendPrivateMessage({
|
|
@@ -3858,9 +3850,8 @@ async function main() {
|
|
|
3858
3850
|
});
|
|
3859
3851
|
app.get("/api/openclaw/bridge/messages", (req, res) => {
|
|
3860
3852
|
const limit = Number(req.query.limit ?? 50);
|
|
3861
|
-
const offset = Number(req.query.offset ?? 0);
|
|
3862
3853
|
const agentId = String(req.query.agent_id ?? "").trim();
|
|
3863
|
-
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null
|
|
3854
|
+
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null }));
|
|
3864
3855
|
});
|
|
3865
3856
|
app.post("/api/openclaw/bridge/message", asyncRoute(async (req, res) => {
|
|
3866
3857
|
const body = String(req.body?.body || "");
|
|
@@ -3976,16 +3967,9 @@ async function main() {
|
|
|
3976
3967
|
let html = (0, fs_1.readFileSync)(staticIndexFile, "utf8");
|
|
3977
3968
|
html = html.replace("</body>", `${renderBootstrapScript(payload)}\n</body>`);
|
|
3978
3969
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
3979
|
-
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
|
|
3980
3970
|
res.send(html);
|
|
3981
3971
|
});
|
|
3982
|
-
app.use(express_1.default.static(staticDir
|
|
3983
|
-
etag: false,
|
|
3984
|
-
lastModified: false,
|
|
3985
|
-
setHeaders: (res) => {
|
|
3986
|
-
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
|
|
3987
|
-
},
|
|
3988
|
-
}));
|
|
3972
|
+
app.use(express_1.default.static(staticDir));
|
|
3989
3973
|
app.use((error, _req, res, _next) => {
|
|
3990
3974
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
3991
3975
|
sendError(res, 500, "INTERNAL_ERROR", message);
|
|
@@ -28,7 +28,6 @@ if (!root) {
|
|
|
28
28
|
}
|
|
29
29
|
root.innerHTML = appTemplate;
|
|
30
30
|
const APP_UPDATE_SESSION_KEY = 'silicaclaw_pending_updated_version';
|
|
31
|
-
const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
32
31
|
|
|
33
32
|
const i18n = createI18n(TRANSLATIONS);
|
|
34
33
|
const DEFAULT_LOCALE = i18n.DEFAULT_LOCALE;
|
|
@@ -53,9 +52,7 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
53
52
|
summary.setAttribute('data-i18n-closed-label', t('labels.show'));
|
|
54
53
|
summary.setAttribute('data-i18n-open-label', t('labels.hide'));
|
|
55
54
|
});
|
|
56
|
-
setText('.nav-section__label', t('common.
|
|
57
|
-
setText('.nav-section__label', t('common.messages'), 1);
|
|
58
|
-
setText('.nav-section__label', t('common.networkGroup'), 2);
|
|
55
|
+
setText('.nav-section__label', t('common.control'));
|
|
59
56
|
setText('[data-tab="overview"] .tab-title', t('pageMeta.overview.title'));
|
|
60
57
|
setText('[data-tab="overview"] .tab-copy', t('labels.overviewTabCopy'));
|
|
61
58
|
setText('[data-tab="agent"] .tab-title', t('pageMeta.agent.title'));
|
|
@@ -123,12 +120,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
123
120
|
document.getElementById('privateTargetIdLabel').textContent = t('social.agentId');
|
|
124
121
|
document.getElementById('privateMessageSendBtn').textContent = t('actions.sendPrivateMessage');
|
|
125
122
|
document.getElementById('privateRefreshBtn').textContent = t('actions.refreshPrivate');
|
|
126
|
-
document.getElementById('socialMessagePrevPageBtn').textContent = t('overview.prevPage');
|
|
127
|
-
document.getElementById('socialMessageNextPageBtn').textContent = t('overview.nextPage');
|
|
128
|
-
document.getElementById('privateConversationPrevPageBtn').textContent = t('overview.prevPage');
|
|
129
|
-
document.getElementById('privateConversationNextPageBtn').textContent = t('overview.nextPage');
|
|
130
|
-
document.getElementById('privateMessagePrevPageBtn').textContent = t('overview.prevPage');
|
|
131
|
-
document.getElementById('privateMessageNextPageBtn').textContent = t('overview.nextPage');
|
|
132
123
|
document.getElementById('chatFeedHint').textContent = t('hints.chatFeedHint');
|
|
133
124
|
document.getElementById('overviewGuideTitle').textContent = t('overview.guideTitle');
|
|
134
125
|
document.getElementById('overviewGuideBody').textContent = t('overview.guideBody');
|
|
@@ -561,7 +552,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
561
552
|
let activeTab = 'overview';
|
|
562
553
|
let logsCache = [];
|
|
563
554
|
let socialMessagesCache = [];
|
|
564
|
-
let socialMessagePage = 1;
|
|
565
555
|
let logLevelFilter = 'all';
|
|
566
556
|
let socialTemplate = '';
|
|
567
557
|
let socialModeDirty = false;
|
|
@@ -572,11 +562,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
572
562
|
let privateState = null;
|
|
573
563
|
let privateConversations = [];
|
|
574
564
|
let privateMessages = [];
|
|
575
|
-
let privateConversationPage = 1;
|
|
576
|
-
const PRIVATE_CONVERSATION_PAGE_SIZE = 12;
|
|
577
|
-
let privateMessagesTotal = 0;
|
|
578
|
-
let privateMessagePage = 1;
|
|
579
|
-
const PRIVATE_MESSAGE_PAGE_SIZE = 20;
|
|
580
565
|
let privateTarget = null;
|
|
581
566
|
let selectedPrivateConversationId = '';
|
|
582
567
|
let overviewMode = 'lan';
|
|
@@ -585,29 +570,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
585
570
|
const AGENTS_PAGE_SIZE = 10;
|
|
586
571
|
const pageMeta = TRANSLATIONS[currentLocale].pageMeta || TRANSLATIONS[DEFAULT_LOCALE].pageMeta;
|
|
587
572
|
|
|
588
|
-
function loadPagingState() {
|
|
589
|
-
try {
|
|
590
|
-
const raw = localStorage.getItem(PAGING_STATE_STORAGE_KEY);
|
|
591
|
-
if (!raw) return null;
|
|
592
|
-
return JSON.parse(raw);
|
|
593
|
-
} catch {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
function savePagingState() {
|
|
599
|
-
try {
|
|
600
|
-
localStorage.setItem(PAGING_STATE_STORAGE_KEY, JSON.stringify({
|
|
601
|
-
socialMessagePage,
|
|
602
|
-
privateConversationPage,
|
|
603
|
-
privateMessagePage,
|
|
604
|
-
selectedPrivateConversationId,
|
|
605
|
-
}));
|
|
606
|
-
} catch {
|
|
607
|
-
// ignore localStorage failures
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
573
|
async function api(path, options = {}) {
|
|
612
574
|
const res = await fetch(path, { headers: { 'Content-Type': 'application/json' }, ...options });
|
|
613
575
|
const json = await res.json().catch(() => null);
|
|
@@ -742,12 +704,8 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
742
704
|
: 'Private messaging unavailable';
|
|
743
705
|
document.getElementById('privateTargetName').value = privateTarget?.display_name || '';
|
|
744
706
|
document.getElementById('privateTargetAgentId').value = privateTarget?.agent_id || '';
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const conversationOffset = Math.max(0, (conversationCurrentPage - 1) * PRIVATE_CONVERSATION_PAGE_SIZE);
|
|
748
|
-
const visibleConversations = privateConversations.slice(conversationOffset, conversationOffset + PRIVATE_CONVERSATION_PAGE_SIZE);
|
|
749
|
-
document.getElementById('privateConversationList').innerHTML = visibleConversations.length
|
|
750
|
-
? visibleConversations.map((item) => `
|
|
707
|
+
document.getElementById('privateConversationList').innerHTML = privateConversations.length
|
|
708
|
+
? privateConversations.map((item) => `
|
|
751
709
|
<button class="agent-card" type="button" data-private-conversation="${escapeHtml(item.conversation_id)}">
|
|
752
710
|
<div class="agent-card__avatar-fallback">${escapeHtml(((item.peer_display_name || item.peer_agent_id || '?')[0] || '?').toUpperCase())}</div>
|
|
753
711
|
<div class="agent-card__main">
|
|
@@ -759,12 +717,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
759
717
|
</button>
|
|
760
718
|
`).join('')
|
|
761
719
|
: `<div class="empty-state">No private conversations yet.</div>`;
|
|
762
|
-
document.getElementById('privateConversationPageMeta').textContent = t('overview.pageStatus', {
|
|
763
|
-
page: String(conversationCurrentPage),
|
|
764
|
-
total: String(conversationTotalPages),
|
|
765
|
-
});
|
|
766
|
-
document.getElementById('privateConversationPrevPageBtn').disabled = conversationCurrentPage <= 1;
|
|
767
|
-
document.getElementById('privateConversationNextPageBtn').disabled = conversationCurrentPage >= conversationTotalPages;
|
|
768
720
|
document.getElementById('privateMessageList').innerHTML = privateMessages.length
|
|
769
721
|
? privateMessages.map((item) => `
|
|
770
722
|
<div class="log-item">
|
|
@@ -779,14 +731,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
779
731
|
</div>
|
|
780
732
|
`).join('')
|
|
781
733
|
: `<div class="empty-state">No private messages yet.</div>`;
|
|
782
|
-
const totalPages = Math.max(1, Math.ceil((privateMessagesTotal || 0) / PRIVATE_MESSAGE_PAGE_SIZE));
|
|
783
|
-
const currentPage = Math.min(privateMessagePage, totalPages);
|
|
784
|
-
document.getElementById('privateMessagePageMeta').textContent = t('overview.pageStatus', {
|
|
785
|
-
page: String(currentPage),
|
|
786
|
-
total: String(totalPages),
|
|
787
|
-
});
|
|
788
|
-
document.getElementById('privateMessagePrevPageBtn').disabled = currentPage <= 1;
|
|
789
|
-
document.getElementById('privateMessageNextPageBtn').disabled = currentPage >= totalPages;
|
|
790
734
|
}
|
|
791
735
|
|
|
792
736
|
async function refreshPrivate() {
|
|
@@ -796,8 +740,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
796
740
|
]);
|
|
797
741
|
privateState = stateRes.data || null;
|
|
798
742
|
privateConversations = Array.isArray(conversationsRes.data) ? conversationsRes.data : [];
|
|
799
|
-
const conversationTotalPages = Math.max(1, Math.ceil((privateConversations.length || 0) / PRIVATE_CONVERSATION_PAGE_SIZE));
|
|
800
|
-
privateConversationPage = Math.min(privateConversationPage, conversationTotalPages);
|
|
801
743
|
if ((!privateTarget || privateTarget.agent_id === privateState?.agent_id) && privateConversations[0]) {
|
|
802
744
|
const first = privateConversations[0];
|
|
803
745
|
privateTarget = {
|
|
@@ -816,22 +758,16 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
816
758
|
};
|
|
817
759
|
}
|
|
818
760
|
if (selectedPrivateConversationId) {
|
|
819
|
-
const
|
|
820
|
-
|
|
821
|
-
privateMessages = Array.isArray(messageRes.data?.items) ? messageRes.data.items : [];
|
|
822
|
-
privateMessagesTotal = Number(messageRes.data?.total || 0);
|
|
761
|
+
const messageRes = await api(`/api/private/messages?conversation_id=${encodeURIComponent(selectedPrivateConversationId)}&limit=100`);
|
|
762
|
+
privateMessages = Array.isArray(messageRes.data) ? messageRes.data : [];
|
|
823
763
|
} else {
|
|
824
764
|
privateMessages = [];
|
|
825
|
-
privateMessagesTotal = 0;
|
|
826
765
|
}
|
|
827
766
|
renderPrivate();
|
|
828
767
|
}
|
|
829
768
|
|
|
830
769
|
const renderSocialMessages = socialController.renderSocialMessages;
|
|
831
770
|
const refreshMessages = socialController.refreshMessages;
|
|
832
|
-
const nextSocialMessagesPage = socialController.nextSocialMessagesPage;
|
|
833
|
-
const prevSocialMessagesPage = socialController.prevSocialMessagesPage;
|
|
834
|
-
const setSocialMessagesPage = socialController.setSocialMessagesPage;
|
|
835
771
|
|
|
836
772
|
const refreshNetwork = networkController.refreshNetwork;
|
|
837
773
|
const refreshPeers = networkController.refreshPeers;
|
|
@@ -934,9 +870,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
934
870
|
display_name: String(button.getAttribute('data-private-name') || ''),
|
|
935
871
|
private_encryption_public_key: String(button.getAttribute('data-private-key') || ''),
|
|
936
872
|
};
|
|
937
|
-
privateConversationPage = 1;
|
|
938
|
-
privateMessagePage = 1;
|
|
939
|
-
savePagingState();
|
|
940
873
|
selectedPrivateConversationId = [privateState?.agent_id || '', privateTarget.agent_id].sort().join(':');
|
|
941
874
|
switchTab('private');
|
|
942
875
|
});
|
|
@@ -953,8 +886,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
953
886
|
private_encryption_public_key: selectedConversation.peer_public_key,
|
|
954
887
|
};
|
|
955
888
|
}
|
|
956
|
-
privateMessagePage = 1;
|
|
957
|
-
savePagingState();
|
|
958
889
|
await refreshPrivate();
|
|
959
890
|
});
|
|
960
891
|
|
|
@@ -962,36 +893,6 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
962
893
|
await refreshPrivate();
|
|
963
894
|
});
|
|
964
895
|
|
|
965
|
-
document.getElementById('privateConversationPrevPageBtn').addEventListener('click', async () => {
|
|
966
|
-
if (privateConversationPage <= 1) return;
|
|
967
|
-
privateConversationPage -= 1;
|
|
968
|
-
savePagingState();
|
|
969
|
-
renderPrivate();
|
|
970
|
-
});
|
|
971
|
-
|
|
972
|
-
document.getElementById('privateConversationNextPageBtn').addEventListener('click', async () => {
|
|
973
|
-
const totalPages = Math.max(1, Math.ceil((privateConversations.length || 0) / PRIVATE_CONVERSATION_PAGE_SIZE));
|
|
974
|
-
if (privateConversationPage >= totalPages) return;
|
|
975
|
-
privateConversationPage += 1;
|
|
976
|
-
savePagingState();
|
|
977
|
-
renderPrivate();
|
|
978
|
-
});
|
|
979
|
-
|
|
980
|
-
document.getElementById('privateMessagePrevPageBtn').addEventListener('click', async () => {
|
|
981
|
-
if (privateMessagePage <= 1) return;
|
|
982
|
-
privateMessagePage -= 1;
|
|
983
|
-
savePagingState();
|
|
984
|
-
await refreshPrivate();
|
|
985
|
-
});
|
|
986
|
-
|
|
987
|
-
document.getElementById('privateMessageNextPageBtn').addEventListener('click', async () => {
|
|
988
|
-
const totalPages = Math.max(1, Math.ceil((privateMessagesTotal || 0) / PRIVATE_MESSAGE_PAGE_SIZE));
|
|
989
|
-
if (privateMessagePage >= totalPages) return;
|
|
990
|
-
privateMessagePage += 1;
|
|
991
|
-
savePagingState();
|
|
992
|
-
await refreshPrivate();
|
|
993
|
-
});
|
|
994
|
-
|
|
995
896
|
document.getElementById('privateMessageSendBtn').addEventListener('click', async () => {
|
|
996
897
|
const body = String(document.getElementById('privateMessageInput').value || '').trim();
|
|
997
898
|
if (!privateTarget?.agent_id || !privateTarget?.private_encryption_public_key) {
|
|
@@ -1018,37 +919,12 @@ const PAGING_STATE_STORAGE_KEY = 'silicaclaw_ui_paging_state';
|
|
|
1018
919
|
});
|
|
1019
920
|
document.getElementById('privateMessageInput').value = '';
|
|
1020
921
|
setFeedback('privateFeedback', result.meta?.message || 'Private message sent.');
|
|
1021
|
-
privateMessagePage = 1;
|
|
1022
|
-
savePagingState();
|
|
1023
922
|
await refreshPrivate();
|
|
1024
923
|
} catch (error) {
|
|
1025
924
|
setFeedback('privateFeedback', error instanceof Error ? error.message : 'Private message failed.', 'error');
|
|
1026
925
|
}
|
|
1027
926
|
});
|
|
1028
927
|
|
|
1029
|
-
document.getElementById('socialMessagePrevPageBtn').addEventListener('click', async () => {
|
|
1030
|
-
prevSocialMessagesPage();
|
|
1031
|
-
socialMessagePage = Math.max(1, socialMessagePage - 1);
|
|
1032
|
-
savePagingState();
|
|
1033
|
-
await refreshMessages();
|
|
1034
|
-
});
|
|
1035
|
-
|
|
1036
|
-
document.getElementById('socialMessageNextPageBtn').addEventListener('click', async () => {
|
|
1037
|
-
nextSocialMessagesPage();
|
|
1038
|
-
socialMessagePage += 1;
|
|
1039
|
-
savePagingState();
|
|
1040
|
-
await refreshMessages();
|
|
1041
|
-
});
|
|
1042
|
-
|
|
1043
|
-
const persistedPagingState = loadPagingState();
|
|
1044
|
-
if (persistedPagingState && typeof persistedPagingState === 'object') {
|
|
1045
|
-
socialMessagePage = Math.max(1, Number(persistedPagingState.socialMessagePage) || 1);
|
|
1046
|
-
privateConversationPage = Math.max(1, Number(persistedPagingState.privateConversationPage) || 1);
|
|
1047
|
-
privateMessagePage = Math.max(1, Number(persistedPagingState.privateMessagePage) || 1);
|
|
1048
|
-
selectedPrivateConversationId = String(persistedPagingState.selectedPrivateConversationId || '').trim();
|
|
1049
|
-
setSocialMessagesPage(socialMessagePage);
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
928
|
applyTheme(localStorage.getItem('silicaclaw_theme_mode') || 'dark');
|
|
1053
929
|
hydrateCachedShell();
|
|
1054
930
|
document.getElementById('brandUpdateBtn').addEventListener('click', () => {
|
|
@@ -26,11 +26,8 @@ export function createSocialController({
|
|
|
26
26
|
}) {
|
|
27
27
|
const SKILLS_SECTION_LIMIT = 4;
|
|
28
28
|
const SKILLS_DIALOGUE_LIMIT = 1;
|
|
29
|
-
const SOCIAL_MESSAGE_PAGE_SIZE = 20;
|
|
30
29
|
let lastMessagesRenderKey = "";
|
|
31
30
|
let lastLogsRenderKey = "";
|
|
32
|
-
let socialMessagesPage = 1;
|
|
33
|
-
let socialMessagesTotal = 0;
|
|
34
31
|
const sectionRenderCache = new Map();
|
|
35
32
|
let skillsQuery = "";
|
|
36
33
|
let skillsFilter = "all";
|
|
@@ -168,18 +165,6 @@ export function createSocialController({
|
|
|
168
165
|
seconds: String(Math.floor((governance.send_limit?.window_ms || 60000) / 1000)),
|
|
169
166
|
})}`
|
|
170
167
|
: t("overview.messageHint");
|
|
171
|
-
const totalPages = Math.max(1, Math.ceil((socialMessagesTotal || 0) / SOCIAL_MESSAGE_PAGE_SIZE));
|
|
172
|
-
const currentPage = Math.min(socialMessagesPage, totalPages);
|
|
173
|
-
const updatePager = () => {
|
|
174
|
-
const pageMetaEl = document.getElementById("socialMessagePageMeta");
|
|
175
|
-
const prevBtn = document.getElementById("socialMessagePrevPageBtn");
|
|
176
|
-
const nextBtn = document.getElementById("socialMessageNextPageBtn");
|
|
177
|
-
if (pageMetaEl) {
|
|
178
|
-
pageMetaEl.textContent = t("overview.pageStatus", { page: String(currentPage), total: String(totalPages) });
|
|
179
|
-
}
|
|
180
|
-
if (prevBtn) prevBtn.disabled = currentPage <= 1;
|
|
181
|
-
if (nextBtn) nextBtn.disabled = currentPage >= totalPages;
|
|
182
|
-
};
|
|
183
168
|
if (!socialMessagesCache.length) {
|
|
184
169
|
const nextMeta = t("overview.noMessagesMeta");
|
|
185
170
|
const nextHtml = `<div class="empty-state">${t("overview.noMessagesEmpty")}</div>`;
|
|
@@ -188,7 +173,6 @@ export function createSocialController({
|
|
|
188
173
|
hintEl.textContent = governanceHint;
|
|
189
174
|
metaEl.textContent = nextMeta;
|
|
190
175
|
listEl.innerHTML = nextHtml;
|
|
191
|
-
updatePager();
|
|
192
176
|
lastMessagesRenderKey = renderKey;
|
|
193
177
|
}
|
|
194
178
|
return;
|
|
@@ -210,6 +194,7 @@ export function createSocialController({
|
|
|
210
194
|
})}`
|
|
211
195
|
: "";
|
|
212
196
|
const nextMeta = `${baseMeta}${governanceMeta}`;
|
|
197
|
+
|
|
213
198
|
if (!filteredMessages.length) {
|
|
214
199
|
const nextHtml = `<div class="empty-state">${t("overview.noMessagesEmpty")}</div>`;
|
|
215
200
|
const renderKey = JSON.stringify({ hint: governanceHint, meta: nextMeta, html: nextHtml });
|
|
@@ -217,7 +202,6 @@ export function createSocialController({
|
|
|
217
202
|
hintEl.textContent = governanceHint;
|
|
218
203
|
metaEl.textContent = nextMeta;
|
|
219
204
|
listEl.innerHTML = nextHtml;
|
|
220
|
-
updatePager();
|
|
221
205
|
lastMessagesRenderKey = renderKey;
|
|
222
206
|
}
|
|
223
207
|
return;
|
|
@@ -301,16 +285,13 @@ export function createSocialController({
|
|
|
301
285
|
hintEl.textContent = governanceHint;
|
|
302
286
|
metaEl.textContent = nextMeta;
|
|
303
287
|
listEl.innerHTML = nextHtml;
|
|
304
|
-
updatePager();
|
|
305
288
|
lastMessagesRenderKey = renderKey;
|
|
306
289
|
}
|
|
307
290
|
|
|
308
291
|
async function refreshMessages() {
|
|
309
|
-
const
|
|
310
|
-
const result = await api(`/api/messages?limit=${SOCIAL_MESSAGE_PAGE_SIZE}&offset=${offset}`);
|
|
292
|
+
const result = await api("/api/messages?limit=50");
|
|
311
293
|
setSocialMessagesCache(Array.isArray(result.data?.items) ? result.data.items : []);
|
|
312
294
|
setSocialMessageGovernance(result.data?.governance || null);
|
|
313
|
-
socialMessagesTotal = Number(result.data?.total || 0);
|
|
314
295
|
renderSocialMessages();
|
|
315
296
|
}
|
|
316
297
|
|
|
@@ -898,14 +879,6 @@ export function createSocialController({
|
|
|
898
879
|
refreshSocial,
|
|
899
880
|
renderLogs,
|
|
900
881
|
renderSocialMessages,
|
|
901
|
-
nextSocialMessagesPage: () => {
|
|
902
|
-
const totalPages = Math.max(1, Math.ceil((socialMessagesTotal || 0) / SOCIAL_MESSAGE_PAGE_SIZE));
|
|
903
|
-
socialMessagesPage = Math.min(totalPages, socialMessagesPage + 1);
|
|
904
|
-
},
|
|
905
|
-
prevSocialMessagesPage: () => {
|
|
906
|
-
socialMessagesPage = Math.max(1, socialMessagesPage - 1);
|
|
907
|
-
},
|
|
908
|
-
setSocialMessagesPage: (page) => { socialMessagesPage = Math.max(1, Number(page) || 1); },
|
|
909
882
|
setSkillsFilter,
|
|
910
883
|
setSkillsQuery,
|
|
911
884
|
setLogLevelFilter,
|
|
@@ -334,17 +334,6 @@
|
|
|
334
334
|
width: 18px;
|
|
335
335
|
height: 18px;
|
|
336
336
|
}
|
|
337
|
-
.app.nav-collapsed .nav button.active::before {
|
|
338
|
-
content: "";
|
|
339
|
-
position: absolute;
|
|
340
|
-
left: 8px;
|
|
341
|
-
top: 10px;
|
|
342
|
-
bottom: 10px;
|
|
343
|
-
width: 3px;
|
|
344
|
-
border-radius: 999px;
|
|
345
|
-
background: color-mix(in srgb, var(--accent) 86%, transparent);
|
|
346
|
-
box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 34%, transparent);
|
|
347
|
-
}
|
|
348
337
|
.app.nav-collapsed .sidebar-shell__footer {
|
|
349
338
|
padding: 8px 0 2px;
|
|
350
339
|
display: grid;
|
|
@@ -395,7 +384,15 @@
|
|
|
395
384
|
display: grid;
|
|
396
385
|
align-content: start;
|
|
397
386
|
gap: 8px;
|
|
398
|
-
margin-bottom:
|
|
387
|
+
margin-bottom: 12px;
|
|
388
|
+
padding: 10px;
|
|
389
|
+
border-radius: 18px;
|
|
390
|
+
background:
|
|
391
|
+
linear-gradient(180deg, color-mix(in srgb, var(--bg-elevated) 88%, transparent) 0%, color-mix(in srgb, var(--bg) 94%, transparent) 100%);
|
|
392
|
+
border: 1px solid color-mix(in srgb, var(--border) 54%, transparent);
|
|
393
|
+
box-shadow:
|
|
394
|
+
inset 0 1px 0 color-mix(in srgb, white 8%, transparent),
|
|
395
|
+
0 10px 24px color-mix(in srgb, black 8%, transparent);
|
|
399
396
|
}
|
|
400
397
|
.nav-section:last-child {
|
|
401
398
|
margin-bottom: 0;
|
|
@@ -406,19 +403,18 @@
|
|
|
406
403
|
justify-content: space-between;
|
|
407
404
|
gap: 8px;
|
|
408
405
|
width: 100%;
|
|
409
|
-
min-height:
|
|
410
|
-
padding: 0
|
|
411
|
-
color: var(--
|
|
412
|
-
font-size:
|
|
406
|
+
min-height: 24px;
|
|
407
|
+
padding: 0 4px;
|
|
408
|
+
color: color-mix(in srgb, var(--text) 78%, transparent);
|
|
409
|
+
font-size: 11px;
|
|
413
410
|
font-weight: 700;
|
|
414
|
-
letter-spacing: 0.
|
|
411
|
+
letter-spacing: 0.12em;
|
|
415
412
|
text-transform: uppercase;
|
|
416
413
|
}
|
|
417
414
|
.nav-section__items {
|
|
418
415
|
display: grid;
|
|
419
416
|
align-content: start;
|
|
420
417
|
gap: 4px;
|
|
421
|
-
padding: 2px 0 0;
|
|
422
418
|
}
|
|
423
419
|
.nav button {
|
|
424
420
|
position: relative;
|
|
@@ -426,13 +422,13 @@
|
|
|
426
422
|
align-items: flex-start;
|
|
427
423
|
justify-content: flex-start;
|
|
428
424
|
gap: 10px;
|
|
429
|
-
min-height:
|
|
425
|
+
min-height: 54px;
|
|
430
426
|
text-align: left;
|
|
431
|
-
border: 1px solid transparent;
|
|
432
|
-
background: transparent;
|
|
427
|
+
border: 1px solid color-mix(in srgb, var(--border) 42%, transparent);
|
|
428
|
+
background: color-mix(in srgb, var(--bg) 92%, transparent);
|
|
433
429
|
color: var(--muted);
|
|
434
430
|
padding: 10px 12px;
|
|
435
|
-
border-radius:
|
|
431
|
+
border-radius: 15px;
|
|
436
432
|
cursor: pointer;
|
|
437
433
|
font: inherit;
|
|
438
434
|
line-height: 1;
|
|
@@ -489,17 +485,6 @@
|
|
|
489
485
|
inset 0 1px 0 color-mix(in srgb, white 10%, transparent),
|
|
490
486
|
0 10px 18px color-mix(in srgb, black 8%, transparent);
|
|
491
487
|
}
|
|
492
|
-
.nav button.active::before {
|
|
493
|
-
content: "";
|
|
494
|
-
position: absolute;
|
|
495
|
-
left: 8px;
|
|
496
|
-
top: 9px;
|
|
497
|
-
bottom: 9px;
|
|
498
|
-
width: 3px;
|
|
499
|
-
border-radius: 999px;
|
|
500
|
-
background: color-mix(in srgb, var(--accent) 86%, transparent);
|
|
501
|
-
box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 28%, transparent);
|
|
502
|
-
}
|
|
503
488
|
.nav button.active .tab-icon {
|
|
504
489
|
opacity: 1;
|
|
505
490
|
color: var(--accent);
|
|
@@ -509,8 +494,9 @@
|
|
|
509
494
|
}
|
|
510
495
|
.nav button:hover {
|
|
511
496
|
color: var(--text);
|
|
512
|
-
background: color-mix(in srgb, var(--bg-hover)
|
|
513
|
-
border-color: color-mix(in srgb, var(--
|
|
497
|
+
background: color-mix(in srgb, var(--bg-hover) 82%, transparent);
|
|
498
|
+
border-color: color-mix(in srgb, var(--accent) 26%, var(--border) 74%);
|
|
499
|
+
transform: translateY(-1px);
|
|
514
500
|
}
|
|
515
501
|
.nav button:hover .tab-icon {
|
|
516
502
|
opacity: 1;
|
|
@@ -2566,13 +2552,6 @@
|
|
|
2566
2552
|
background: color-mix(in srgb, var(--bg-elevated) 84%, transparent);
|
|
2567
2553
|
border-color: color-mix(in srgb, var(--border) 72%, transparent);
|
|
2568
2554
|
}
|
|
2569
|
-
.nav button.active::before {
|
|
2570
|
-
left: 10px;
|
|
2571
|
-
top: auto;
|
|
2572
|
-
bottom: 6px;
|
|
2573
|
-
width: calc(100% - 20px);
|
|
2574
|
-
height: 3px;
|
|
2575
|
-
}
|
|
2576
2555
|
.grid,
|
|
2577
2556
|
#view-network #networkCards,
|
|
2578
2557
|
#socialPrimaryCards,
|
|
@@ -387,13 +387,6 @@ export const appTemplate = String.raw`<div class="app" id="appShell">
|
|
|
387
387
|
</div>
|
|
388
388
|
</div>
|
|
389
389
|
<div class="logs" id="socialMessageList"></div>
|
|
390
|
-
<div class="agent-list__footer">
|
|
391
|
-
<div class="agent-list__page" id="socialMessagePageMeta">Page 1 / 1</div>
|
|
392
|
-
<div class="agent-list__pager">
|
|
393
|
-
<button class="secondary" type="button" id="socialMessagePrevPageBtn">Prev</button>
|
|
394
|
-
<button class="secondary" type="button" id="socialMessageNextPageBtn">Next</button>
|
|
395
|
-
</div>
|
|
396
|
-
</div>
|
|
397
390
|
</div>
|
|
398
391
|
</div>
|
|
399
392
|
</div>
|
|
@@ -423,13 +416,6 @@ export const appTemplate = String.raw`<div class="app" id="appShell">
|
|
|
423
416
|
</div>
|
|
424
417
|
</div>
|
|
425
418
|
<div class="logs" id="privateConversationList"></div>
|
|
426
|
-
<div class="agent-list__footer">
|
|
427
|
-
<div class="agent-list__page" id="privateConversationPageMeta">Page 1 / 1</div>
|
|
428
|
-
<div class="agent-list__pager">
|
|
429
|
-
<button class="secondary" type="button" id="privateConversationPrevPageBtn">Prev</button>
|
|
430
|
-
<button class="secondary" type="button" id="privateConversationNextPageBtn">Next</button>
|
|
431
|
-
</div>
|
|
432
|
-
</div>
|
|
433
419
|
</div>
|
|
434
420
|
<div class="card stack">
|
|
435
421
|
<div class="overview-panel-header">
|
|
@@ -455,13 +441,6 @@ export const appTemplate = String.raw`<div class="app" id="appShell">
|
|
|
455
441
|
</div>
|
|
456
442
|
<div id="privateFeedback" class="feedback">Ready.</div>
|
|
457
443
|
<div class="logs" id="privateMessageList"></div>
|
|
458
|
-
<div class="agent-list__footer">
|
|
459
|
-
<div class="agent-list__page" id="privateMessagePageMeta">Page 1 / 1</div>
|
|
460
|
-
<div class="agent-list__pager">
|
|
461
|
-
<button class="secondary" type="button" id="privateMessagePrevPageBtn">Prev</button>
|
|
462
|
-
<button class="secondary" type="button" id="privateMessageNextPageBtn">Next</button>
|
|
463
|
-
</div>
|
|
464
|
-
</div>
|
|
465
444
|
</div>
|
|
466
445
|
</div>
|
|
467
446
|
</div>
|
|
@@ -8,9 +8,6 @@ export const TRANSLATIONS = {
|
|
|
8
8
|
},
|
|
9
9
|
common: {
|
|
10
10
|
control: 'Control',
|
|
11
|
-
workspace: 'Workspace',
|
|
12
|
-
messages: 'Messages',
|
|
13
|
-
networkGroup: 'Network',
|
|
14
11
|
version: 'Version',
|
|
15
12
|
localConsole: 'Local Console',
|
|
16
13
|
subtitle: 'Manage identity, discovery, and broadcasts',
|
|
@@ -629,9 +626,6 @@ export const TRANSLATIONS = {
|
|
|
629
626
|
},
|
|
630
627
|
common: {
|
|
631
628
|
control: '控制',
|
|
632
|
-
workspace: '工作区',
|
|
633
|
-
messages: '消息',
|
|
634
|
-
networkGroup: '网络',
|
|
635
629
|
version: '版本',
|
|
636
630
|
localConsole: '本地控制台',
|
|
637
631
|
subtitle: '管理身份、发现与广播',
|
|
@@ -1899,7 +1899,7 @@ export class LocalNodeService {
|
|
|
1899
1899
|
return this.identity;
|
|
1900
1900
|
}
|
|
1901
1901
|
|
|
1902
|
-
getSocialMessages(limit = 50, options?: { agent_id?: string | null
|
|
1902
|
+
getSocialMessages(limit = 50, options?: { agent_id?: string | null }): {
|
|
1903
1903
|
total: number;
|
|
1904
1904
|
items: SocialMessageView[];
|
|
1905
1905
|
governance: {
|
|
@@ -1911,7 +1911,6 @@ export class LocalNodeService {
|
|
|
1911
1911
|
};
|
|
1912
1912
|
} {
|
|
1913
1913
|
const resolvedLimit = Math.max(1, Math.min(200, Number(limit) || 50));
|
|
1914
|
-
const resolvedOffset = Math.max(0, Number(options?.offset) || 0);
|
|
1915
1914
|
this.ensureLocalDirectoryBaseline();
|
|
1916
1915
|
this.compactCacheInMemory();
|
|
1917
1916
|
const agentId = String(options?.agent_id || "").trim();
|
|
@@ -1920,7 +1919,7 @@ export class LocalNodeService {
|
|
|
1920
1919
|
: this.socialMessages;
|
|
1921
1920
|
return {
|
|
1922
1921
|
total: filtered.length,
|
|
1923
|
-
items: filtered.slice(
|
|
1922
|
+
items: filtered.slice(0, resolvedLimit).map((message) => {
|
|
1924
1923
|
const profile = this.directory.profiles[message.agent_id];
|
|
1925
1924
|
const lastSeenAt = this.directory.presence[message.agent_id] ?? 0;
|
|
1926
1925
|
const observations = this.socialMessageObservations.filter((item) => item.message_id === message.message_id);
|
|
@@ -2001,17 +2000,13 @@ export class LocalNodeService {
|
|
|
2001
2000
|
return Array.from(conversations.values()).sort((a, b) => (b.last_message_at || 0) - (a.last_message_at || 0));
|
|
2002
2001
|
}
|
|
2003
2002
|
|
|
2004
|
-
getPrivateMessages(conversationId: string, limit = PRIVATE_MESSAGE_QUERY_LIMIT
|
|
2005
|
-
total: number;
|
|
2006
|
-
items: PrivateMessageView[];
|
|
2007
|
-
} {
|
|
2003
|
+
getPrivateMessages(conversationId: string, limit = PRIVATE_MESSAGE_QUERY_LIMIT): PrivateMessageView[] {
|
|
2008
2004
|
const normalizedConversationId = String(conversationId || "").trim();
|
|
2009
2005
|
const resolvedLimit = Math.max(1, Math.min(PRIVATE_MESSAGE_QUERY_LIMIT, Number(limit) || PRIVATE_MESSAGE_QUERY_LIMIT));
|
|
2010
|
-
const resolvedOffset = Math.max(0, Number(offset) || 0);
|
|
2011
2006
|
const receiptsByMessageId = new Map(
|
|
2012
2007
|
this.privateMessageReceipts.map((receipt) => [receipt.message_id, receipt.status] as const)
|
|
2013
2008
|
);
|
|
2014
|
-
|
|
2009
|
+
return this.privateMessages
|
|
2015
2010
|
.filter((message) => {
|
|
2016
2011
|
if (message.from_agent_id === message.to_agent_id) {
|
|
2017
2012
|
return false;
|
|
@@ -2022,12 +2017,9 @@ export class LocalNodeService {
|
|
|
2022
2017
|
}
|
|
2023
2018
|
return !normalizedConversationId || message.conversation_id === normalizedConversationId;
|
|
2024
2019
|
})
|
|
2025
|
-
.sort((a, b) => a.created_at - b.created_at)
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
return {
|
|
2029
|
-
total,
|
|
2030
|
-
items: paged.map((message) => ({
|
|
2020
|
+
.sort((a, b) => a.created_at - b.created_at)
|
|
2021
|
+
.slice(-resolvedLimit)
|
|
2022
|
+
.map((message) => ({
|
|
2031
2023
|
message_id: message.message_id,
|
|
2032
2024
|
conversation_id: message.conversation_id,
|
|
2033
2025
|
from_agent_id: message.from_agent_id,
|
|
@@ -2039,8 +2031,7 @@ export class LocalNodeService {
|
|
|
2039
2031
|
receiptsByMessageId.get(message.message_id) ||
|
|
2040
2032
|
this.privateMessageDeliveryStatusCache.get(message.message_id) ||
|
|
2041
2033
|
(message.from_agent_id === this.identity?.agent_id ? "fallback-sent" : "sent"),
|
|
2042
|
-
}))
|
|
2043
|
-
};
|
|
2034
|
+
}));
|
|
2044
2035
|
}
|
|
2045
2036
|
|
|
2046
2037
|
async sendPrivateMessage(input: {
|
|
@@ -2092,7 +2083,7 @@ export class LocalNodeService {
|
|
|
2092
2083
|
await this.publish(PRIVATE_MESSAGE_TOPIC, message);
|
|
2093
2084
|
}
|
|
2094
2085
|
this.privateMessageDeliveryStatusCache.set(message.message_id, reason as PrivateMessageView["delivery_status"]);
|
|
2095
|
-
const view = this.getPrivateMessages(message.conversation_id
|
|
2086
|
+
const view = this.getPrivateMessages(message.conversation_id).find((item) => item.message_id === message.message_id);
|
|
2096
2087
|
if (view) {
|
|
2097
2088
|
view.delivery_status = reason as PrivateMessageView["delivery_status"];
|
|
2098
2089
|
}
|
|
@@ -4315,7 +4306,7 @@ export async function main() {
|
|
|
4315
4306
|
} catch {
|
|
4316
4307
|
// best effort after response has been sent
|
|
4317
4308
|
}
|
|
4318
|
-
},
|
|
4309
|
+
}, 150);
|
|
4319
4310
|
})
|
|
4320
4311
|
);
|
|
4321
4312
|
|
|
@@ -4457,9 +4448,8 @@ export async function main() {
|
|
|
4457
4448
|
|
|
4458
4449
|
app.get("/api/messages", (req, res) => {
|
|
4459
4450
|
const limit = Number(req.query.limit ?? 50);
|
|
4460
|
-
const offset = Number(req.query.offset ?? 0);
|
|
4461
4451
|
const agentId = String(req.query.agent_id ?? "").trim();
|
|
4462
|
-
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null
|
|
4452
|
+
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null }));
|
|
4463
4453
|
});
|
|
4464
4454
|
|
|
4465
4455
|
app.get("/api/private/state", (_req, res) => {
|
|
@@ -4473,8 +4463,7 @@ export async function main() {
|
|
|
4473
4463
|
app.get("/api/private/messages", (req, res) => {
|
|
4474
4464
|
const conversationId = String(req.query.conversation_id ?? "").trim();
|
|
4475
4465
|
const limit = Number(req.query.limit ?? PRIVATE_MESSAGE_QUERY_LIMIT);
|
|
4476
|
-
|
|
4477
|
-
sendOk(res, node.getPrivateMessages(conversationId, limit, offset));
|
|
4466
|
+
sendOk(res, node.getPrivateMessages(conversationId, limit));
|
|
4478
4467
|
});
|
|
4479
4468
|
|
|
4480
4469
|
app.post(
|
|
@@ -4509,9 +4498,8 @@ export async function main() {
|
|
|
4509
4498
|
|
|
4510
4499
|
app.get("/api/openclaw/bridge/messages", (req, res) => {
|
|
4511
4500
|
const limit = Number(req.query.limit ?? 50);
|
|
4512
|
-
const offset = Number(req.query.offset ?? 0);
|
|
4513
4501
|
const agentId = String(req.query.agent_id ?? "").trim();
|
|
4514
|
-
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null
|
|
4502
|
+
sendOk(res, node.getSocialMessages(limit, { agent_id: agentId || null }));
|
|
4515
4503
|
});
|
|
4516
4504
|
|
|
4517
4505
|
app.post(
|
|
@@ -4661,17 +4649,10 @@ export async function main() {
|
|
|
4661
4649
|
let html = readFileSync(staticIndexFile, "utf8");
|
|
4662
4650
|
html = html.replace("</body>", `${renderBootstrapScript(payload)}\n</body>`);
|
|
4663
4651
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
4664
|
-
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
|
|
4665
4652
|
res.send(html);
|
|
4666
4653
|
});
|
|
4667
4654
|
|
|
4668
|
-
app.use(express.static(staticDir
|
|
4669
|
-
etag: false,
|
|
4670
|
-
lastModified: false,
|
|
4671
|
-
setHeaders: (res) => {
|
|
4672
|
-
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
|
|
4673
|
-
},
|
|
4674
|
-
}));
|
|
4655
|
+
app.use(express.static(staticDir));
|
|
4675
4656
|
|
|
4676
4657
|
app.use((error: unknown, _req: Request, res: Response, _next: NextFunction) => {
|
|
4677
4658
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
2026.3.20-beta.
|
|
1
|
+
2026.3.20-beta.16
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "silicaclaw-broadcast",
|
|
3
|
-
"version": "2026.3.20-beta.
|
|
3
|
+
"version": "2026.3.20-beta.16",
|
|
4
4
|
"display_name": "SilicaClaw Broadcast",
|
|
5
5
|
"description": "Official OpenClaw skill for a bounded local SilicaClaw broadcast workflow: read public broadcasts, publish public broadcasts, and optionally forward owner-relevant summaries through OpenClaw's native channel.",
|
|
6
6
|
"entrypoints": {
|
package/package.json
CHANGED
|
@@ -1071,7 +1071,9 @@ async function restartAll() {
|
|
|
1071
1071
|
environment: baseEnv,
|
|
1072
1072
|
});
|
|
1073
1073
|
if (!localConsoleService.changed) {
|
|
1074
|
-
|
|
1074
|
+
stopLaunchAgent(LOCAL_CONSOLE_LABEL);
|
|
1075
|
+
await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 8000);
|
|
1076
|
+
startLaunchAgent(LOCAL_CONSOLE_LABEL, localConsoleService.plistPath);
|
|
1075
1077
|
}
|
|
1076
1078
|
|
|
1077
1079
|
if (shouldAutoStartSignaling) {
|
|
@@ -1087,7 +1089,9 @@ async function restartAll() {
|
|
|
1087
1089
|
},
|
|
1088
1090
|
});
|
|
1089
1091
|
if (!signalingService.changed) {
|
|
1090
|
-
|
|
1092
|
+
stopLaunchAgent(SIGNALING_LABEL);
|
|
1093
|
+
await drainOwnedListener(4510, "signaling", 5000);
|
|
1094
|
+
startLaunchAgent(SIGNALING_LABEL, signalingService.plistPath);
|
|
1091
1095
|
}
|
|
1092
1096
|
} else {
|
|
1093
1097
|
uninstallLaunchAgent(SIGNALING_LABEL);
|