@silicaclaw/cli 2026.3.20-1 → 2026.3.20-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.
- package/CHANGELOG.md +54 -0
- package/INSTALL.md +13 -7
- package/README.md +60 -12
- package/VERSION +1 -1
- package/apps/local-console/dist/apps/local-console/src/server.d.ts +129 -2
- package/apps/local-console/dist/apps/local-console/src/server.js +887 -91
- package/apps/local-console/dist/packages/core/src/index.d.ts +2 -0
- package/apps/local-console/dist/packages/core/src/index.js +2 -0
- package/apps/local-console/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/apps/local-console/dist/packages/core/src/privateCrypto.js +40 -0
- package/apps/local-console/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/apps/local-console/dist/packages/core/src/privateMessage.js +74 -0
- package/apps/local-console/dist/packages/core/src/profile.js +2 -0
- package/apps/local-console/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/apps/local-console/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/apps/local-console/dist/packages/core/src/types.d.ts +40 -0
- package/apps/local-console/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/apps/local-console/dist/packages/network/src/relayPreview.js +108 -8
- package/apps/local-console/dist/packages/network/src/types.d.ts +4 -0
- package/apps/local-console/dist/packages/storage/src/repos.d.ts +13 -1
- package/apps/local-console/dist/packages/storage/src/repos.js +19 -1
- package/apps/local-console/public/app/app.js +465 -11
- package/apps/local-console/public/app/events.js +21 -0
- package/apps/local-console/public/app/network.js +144 -32
- package/apps/local-console/public/app/overview.js +60 -52
- package/apps/local-console/public/app/social.js +316 -93
- package/apps/local-console/public/app/styles.css +127 -1
- package/apps/local-console/public/app/template.js +121 -35
- package/apps/local-console/public/app/translations.js +430 -316
- package/apps/local-console/src/server.ts +1024 -89
- package/apps/public-explorer/public/app/template.js +2 -2
- package/apps/public-explorer/public/app/translations.js +36 -36
- package/docs/NEW_USER_OPERATIONS.md +5 -5
- package/docs/OPENCLAW_BRIDGE.md +7 -7
- package/docs/OPENCLAW_BRIDGE_ZH.md +6 -6
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.js +40 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.js +74 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +40 -0
- package/node_modules/@silicaclaw/core/src/index.ts +2 -0
- package/node_modules/@silicaclaw/core/src/privateCrypto.ts +57 -0
- package/node_modules/@silicaclaw/core/src/privateMessage.ts +101 -0
- package/node_modules/@silicaclaw/core/src/profile.ts +2 -0
- package/node_modules/@silicaclaw/core/src/publicProfileSummary.ts +7 -0
- package/node_modules/@silicaclaw/core/src/types.ts +44 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +108 -8
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +4 -0
- package/node_modules/@silicaclaw/network/src/relayPreview.ts +120 -10
- package/node_modules/@silicaclaw/network/src/types.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.js +40 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.js +74 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +40 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +13 -1
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +19 -1
- package/node_modules/@silicaclaw/storage/src/repos.ts +31 -1
- package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -1
- package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-broadcast/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
- package/openclaw-skills/silicaclaw-broadcast/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-network-config/SKILL.md +158 -0
- package/openclaw-skills/silicaclaw-network-config/VERSION +1 -0
- package/openclaw-skills/silicaclaw-network-config/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-network-config/manifest.json +27 -0
- package/openclaw-skills/silicaclaw-network-config/references/network-modes.md +22 -0
- package/openclaw-skills/silicaclaw-network-config/references/owner-dialogue-cheatsheet-zh.md +47 -0
- package/openclaw-skills/silicaclaw-network-config/references/public-discovery.md +22 -0
- package/openclaw-skills/silicaclaw-owner-push/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -1
- package/openclaw-skills/silicaclaw-owner-push/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +3 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +151 -9
- package/package.json +1 -1
- package/packages/core/dist/packages/core/src/index.d.ts +2 -0
- package/packages/core/dist/packages/core/src/index.js +2 -0
- package/packages/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/packages/core/dist/packages/core/src/privateCrypto.js +40 -0
- package/packages/core/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/packages/core/dist/packages/core/src/privateMessage.js +74 -0
- package/packages/core/dist/packages/core/src/profile.js +2 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/packages/core/dist/packages/core/src/types.d.ts +40 -0
- package/packages/core/src/index.ts +2 -0
- package/packages/core/src/privateCrypto.ts +57 -0
- package/packages/core/src/privateMessage.ts +101 -0
- package/packages/core/src/profile.ts +2 -0
- package/packages/core/src/publicProfileSummary.ts +7 -0
- package/packages/core/src/types.ts +44 -0
- package/packages/network/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/packages/network/dist/packages/network/src/relayPreview.js +108 -8
- package/packages/network/dist/packages/network/src/types.d.ts +4 -0
- package/packages/network/src/relayPreview.ts +120 -10
- package/packages/network/src/types.ts +2 -0
- package/packages/storage/dist/packages/core/src/index.d.ts +2 -0
- package/packages/storage/dist/packages/core/src/index.js +2 -0
- package/packages/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/packages/storage/dist/packages/core/src/privateCrypto.js +40 -0
- package/packages/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/packages/storage/dist/packages/core/src/privateMessage.js +74 -0
- package/packages/storage/dist/packages/core/src/profile.js +2 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/packages/storage/dist/packages/core/src/types.d.ts +40 -0
- package/packages/storage/dist/packages/storage/src/repos.d.ts +13 -1
- package/packages/storage/dist/packages/storage/src/repos.js +19 -1
- package/packages/storage/src/repos.ts +31 -1
- package/scripts/silicaclaw-cli.mjs +59 -6
- package/scripts/silicaclaw-gateway.mjs +108 -0
- package/scripts/validate-openclaw-skill.mjs +19 -0
|
@@ -24,6 +24,134 @@ export function createSocialController({
|
|
|
24
24
|
toPrettyJson,
|
|
25
25
|
writeUiCache,
|
|
26
26
|
}) {
|
|
27
|
+
const SKILLS_SECTION_LIMIT = 4;
|
|
28
|
+
const SKILLS_DIALOGUE_LIMIT = 1;
|
|
29
|
+
let lastMessagesRenderKey = "";
|
|
30
|
+
let lastLogsRenderKey = "";
|
|
31
|
+
const sectionRenderCache = new Map();
|
|
32
|
+
let skillsQuery = "";
|
|
33
|
+
let skillsFilter = "all";
|
|
34
|
+
const skillsExpanded = {
|
|
35
|
+
bundled: false,
|
|
36
|
+
installed: false,
|
|
37
|
+
dialogue: false,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function skillModeLabel(mode) {
|
|
41
|
+
if (mode === "workspace") return t("labels.skillsModeWorkspace");
|
|
42
|
+
if (mode === "legacy") return t("labels.skillsModeLegacy");
|
|
43
|
+
if (mode === "bundled") return t("labels.skillsModeBundled");
|
|
44
|
+
if (mode === "installed") return t("labels.skillsModeInstalled");
|
|
45
|
+
return mode ? String(mode) : t("labels.skillsModeGeneric");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function normalizeSkillSearchText(value) {
|
|
49
|
+
return String(value || "").trim().toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function setSkillsQuery(value) {
|
|
53
|
+
skillsQuery = normalizeSkillSearchText(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function setSkillsFilter(value) {
|
|
57
|
+
const next = String(value || "").trim();
|
|
58
|
+
skillsFilter = ["all", "attention", "updates", "installed"].includes(next) ? next : "all";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function toggleSkillsExpanded(section) {
|
|
62
|
+
if (!(section in skillsExpanded)) return;
|
|
63
|
+
skillsExpanded[section] = !skillsExpanded[section];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function skillMatchesSearch(skill) {
|
|
67
|
+
if (!skillsQuery) return true;
|
|
68
|
+
const haystack = [
|
|
69
|
+
skill.display_name,
|
|
70
|
+
skill.name,
|
|
71
|
+
skill.description,
|
|
72
|
+
skill.version,
|
|
73
|
+
...(Array.isArray(skill.capabilities) ? skill.capabilities : []),
|
|
74
|
+
...(Array.isArray(skill.owner_dialogue_examples_zh) ? skill.owner_dialogue_examples_zh : []),
|
|
75
|
+
].map((item) => normalizeSkillSearchText(item)).join(" ");
|
|
76
|
+
return haystack.includes(skillsQuery);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function skillMatchesFilter(skill, section) {
|
|
80
|
+
if (skillsFilter === "all") return true;
|
|
81
|
+
if (skillsFilter === "updates") return Boolean(skill.update_available);
|
|
82
|
+
if (skillsFilter === "installed") {
|
|
83
|
+
return section === "installed" ? true : Boolean(skill.installed_in_openclaw);
|
|
84
|
+
}
|
|
85
|
+
if (skillsFilter === "attention") {
|
|
86
|
+
return section === "installed"
|
|
87
|
+
? Boolean(skill.update_available)
|
|
88
|
+
: Boolean(skill.update_available || !skill.installed_in_openclaw);
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function renderSkillsSectionFooter({ footerId, section, totalCount, visibleCount, limit }) {
|
|
94
|
+
const footer = document.getElementById(footerId);
|
|
95
|
+
if (!footer) return;
|
|
96
|
+
if (totalCount <= limit) {
|
|
97
|
+
footer.innerHTML = "";
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const expanded = skillsExpanded[section];
|
|
101
|
+
const hiddenCount = Math.max(totalCount - visibleCount, 0);
|
|
102
|
+
footer.innerHTML = `
|
|
103
|
+
<button class="secondary skills-section__toggle" type="button" data-skills-toggle="${section}">
|
|
104
|
+
${expanded ? t("actions.showLess") : t("actions.showMoreCount", { count: String(hiddenCount) })}
|
|
105
|
+
</button>
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function renderFilteredSkillCards({ skills, section, gridId, footerId, renderer, limit }) {
|
|
110
|
+
const filtered = skills.filter((skill) => skillMatchesSearch(skill) && skillMatchesFilter(skill, section));
|
|
111
|
+
const expanded = skillsExpanded[section];
|
|
112
|
+
const visible = expanded ? filtered : filtered.slice(0, limit);
|
|
113
|
+
document.getElementById(gridId).innerHTML = visible.length
|
|
114
|
+
? visible.map((skill) => renderer(skill)).join("")
|
|
115
|
+
: `<div class="skills-empty">${t("hints.skillsNoFilterMatch")}</div>`;
|
|
116
|
+
renderSkillsSectionFooter({
|
|
117
|
+
footerId,
|
|
118
|
+
section,
|
|
119
|
+
totalCount: filtered.length,
|
|
120
|
+
visibleCount: visible.length,
|
|
121
|
+
limit,
|
|
122
|
+
});
|
|
123
|
+
return filtered.length;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function renderSkillsFilterMeta({ bundledCount, installedCount, dialogueCount }) {
|
|
127
|
+
const matchedTotal = bundledCount + installedCount + dialogueCount;
|
|
128
|
+
const filterLabel = t(`labels.skillsFilter${skillsFilter.charAt(0).toUpperCase()}${skillsFilter.slice(1)}`);
|
|
129
|
+
document.getElementById("skillsFilterMeta").textContent = t("hints.skillsFilterMeta", {
|
|
130
|
+
count: String(matchedTotal),
|
|
131
|
+
filter: filterLabel,
|
|
132
|
+
});
|
|
133
|
+
document.querySelectorAll("[data-skills-filter]").forEach((btn) => {
|
|
134
|
+
btn.classList.toggle("active", btn.getAttribute("data-skills-filter") === skillsFilter);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setCachedContent(id, value, mode = "html") {
|
|
139
|
+
const cacheKey = `${mode}:${id}`;
|
|
140
|
+
if (sectionRenderCache.get(cacheKey) === value) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const el = document.getElementById(id);
|
|
144
|
+
if (!el) return;
|
|
145
|
+
if (mode === "text") {
|
|
146
|
+
el.textContent = value;
|
|
147
|
+
} else if (mode === "class") {
|
|
148
|
+
el.className = value;
|
|
149
|
+
} else {
|
|
150
|
+
el.innerHTML = value;
|
|
151
|
+
}
|
|
152
|
+
sectionRenderCache.set(cacheKey, value);
|
|
153
|
+
}
|
|
154
|
+
|
|
27
155
|
function renderSocialMessages() {
|
|
28
156
|
const listEl = document.getElementById("socialMessageList");
|
|
29
157
|
const metaEl = document.getElementById("socialMessageMeta");
|
|
@@ -37,10 +165,16 @@ export function createSocialController({
|
|
|
37
165
|
seconds: String(Math.floor((governance.send_limit?.window_ms || 60000) / 1000)),
|
|
38
166
|
})}`
|
|
39
167
|
: t("overview.messageHint");
|
|
40
|
-
hintEl.textContent = governanceHint;
|
|
41
168
|
if (!socialMessagesCache.length) {
|
|
42
|
-
|
|
43
|
-
|
|
169
|
+
const nextMeta = t("overview.noMessagesMeta");
|
|
170
|
+
const nextHtml = `<div class="empty-state">${t("overview.noMessagesEmpty")}</div>`;
|
|
171
|
+
const renderKey = JSON.stringify({ hint: governanceHint, meta: nextMeta, html: nextHtml });
|
|
172
|
+
if (renderKey !== lastMessagesRenderKey) {
|
|
173
|
+
hintEl.textContent = governanceHint;
|
|
174
|
+
metaEl.textContent = nextMeta;
|
|
175
|
+
listEl.innerHTML = nextHtml;
|
|
176
|
+
lastMessagesRenderKey = renderKey;
|
|
177
|
+
}
|
|
44
178
|
return;
|
|
45
179
|
}
|
|
46
180
|
|
|
@@ -59,16 +193,28 @@ export function createSocialController({
|
|
|
59
193
|
seconds: String(Math.floor((governance.send_limit?.window_ms || 60000) / 1000)),
|
|
60
194
|
})}`
|
|
61
195
|
: "";
|
|
62
|
-
|
|
196
|
+
const nextMeta = `${baseMeta}${governanceMeta}`;
|
|
63
197
|
|
|
64
198
|
if (!filteredMessages.length) {
|
|
65
|
-
|
|
199
|
+
const nextHtml = `<div class="empty-state">${t("overview.noMessagesEmpty")}</div>`;
|
|
200
|
+
const renderKey = JSON.stringify({ hint: governanceHint, meta: nextMeta, html: nextHtml });
|
|
201
|
+
if (renderKey !== lastMessagesRenderKey) {
|
|
202
|
+
hintEl.textContent = governanceHint;
|
|
203
|
+
metaEl.textContent = nextMeta;
|
|
204
|
+
listEl.innerHTML = nextHtml;
|
|
205
|
+
lastMessagesRenderKey = renderKey;
|
|
206
|
+
}
|
|
66
207
|
return;
|
|
67
208
|
}
|
|
68
209
|
|
|
69
|
-
|
|
210
|
+
const nextHtml = filteredMessages
|
|
70
211
|
.map((item) => {
|
|
71
212
|
const visibleRemoteCount = getVisibleRemotePublicCount();
|
|
213
|
+
const avatarUrl = String(item.avatar_url || "").trim();
|
|
214
|
+
const displayName = String(item.display_name || t("overview.unnamed")).trim() || t("overview.unnamed");
|
|
215
|
+
const avatar = avatarUrl
|
|
216
|
+
? `<img class="agent-card__avatar" src="${escapeHtml(avatarUrl)}" alt="${escapeHtml(displayName)}" loading="lazy" />`
|
|
217
|
+
: `<div class="agent-card__avatar-fallback">${escapeHtml((displayName[0] || "?").toUpperCase())}</div>`;
|
|
72
218
|
const selfStatusChips = item.is_self
|
|
73
219
|
? `
|
|
74
220
|
<span class="tag-chip" style="margin-left:8px;">${t("overview.selfMessagePublished")}</span>
|
|
@@ -101,14 +247,17 @@ export function createSocialController({
|
|
|
101
247
|
return `
|
|
102
248
|
<div class="log-item">
|
|
103
249
|
<div style="display:flex; align-items:center; justify-content:space-between; gap:12px;">
|
|
104
|
-
<div>
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
250
|
+
<div style="display:flex; align-items:flex-start; gap:10px; min-width:0;">
|
|
251
|
+
${avatar}
|
|
252
|
+
<div style="min-width:0;">
|
|
253
|
+
<strong>${escapeHtml(displayName)}</strong>
|
|
254
|
+
<span class="mono" style="color:#90a2c3; margin-left:8px;">${escapeHtml(shortId(item.agent_id || ""))}</span>
|
|
255
|
+
<span class="tag-chip" style="margin-left:8px;">${escapeHtml(item.topic || t("labels.globalTopic"))}</span>
|
|
256
|
+
${item.is_self ? `<span class="tag-chip" style="margin-left:8px;">${t("overview.messageFilterSelf")}</span>` : ""}
|
|
257
|
+
<span class="tag-chip" style="margin-left:8px;">${item.online ? t("overview.online") : t("overview.offline")}</span>
|
|
258
|
+
${observationChip}
|
|
259
|
+
${selfStatusChips}
|
|
260
|
+
</div>
|
|
112
261
|
</div>
|
|
113
262
|
<div class="mono" style="color:#90a2c3;">${new Date(item.created_at).toLocaleString()}</div>
|
|
114
263
|
</div>
|
|
@@ -118,6 +267,25 @@ export function createSocialController({
|
|
|
118
267
|
`;
|
|
119
268
|
})
|
|
120
269
|
.join("");
|
|
270
|
+
const renderKey = JSON.stringify({
|
|
271
|
+
hint: governanceHint,
|
|
272
|
+
meta: nextMeta,
|
|
273
|
+
filter: socialMessageFilter,
|
|
274
|
+
messages: filteredMessages.map((item) => [
|
|
275
|
+
item.message_id,
|
|
276
|
+
item.updated_at || item.created_at,
|
|
277
|
+
item.remote_observation_count || 0,
|
|
278
|
+
item.online ? 1 : 0,
|
|
279
|
+
]),
|
|
280
|
+
visibleRemoteCount: getVisibleRemotePublicCount(),
|
|
281
|
+
});
|
|
282
|
+
if (renderKey === lastMessagesRenderKey) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
hintEl.textContent = governanceHint;
|
|
286
|
+
metaEl.textContent = nextMeta;
|
|
287
|
+
listEl.innerHTML = nextHtml;
|
|
288
|
+
lastMessagesRenderKey = renderKey;
|
|
121
289
|
}
|
|
122
290
|
|
|
123
291
|
async function refreshMessages() {
|
|
@@ -162,19 +330,29 @@ export function createSocialController({
|
|
|
162
330
|
const publicDiscoveryText = status.public_enabled ? t("social.publicDiscoveryEnabled") : t("social.publicDiscoveryDisabled");
|
|
163
331
|
|
|
164
332
|
const namespaceText = `${status.connected_to_silicaclaw ? t("social.connectedToSilicaClaw") : t("social.notConnected")} · ${publicDiscoveryText} · ${t("social.mode")} ${mode}`;
|
|
165
|
-
|
|
166
|
-
|
|
333
|
+
setCachedContent("socialStatusLine", summaryLine, "text");
|
|
334
|
+
setCachedContent("socialStatusSubline", namespaceText, "text");
|
|
167
335
|
const bar = document.getElementById("integrationStatusBar");
|
|
168
|
-
|
|
169
|
-
|
|
336
|
+
const barClassName = `integration-strip ${status.connected_to_silicaclaw && status.public_enabled ? "ok" : "warn"}${getActiveTab() === "overview" ? "" : " hidden"}`;
|
|
337
|
+
const barText = t("social.barStatus", {
|
|
170
338
|
connected: status.connected_to_silicaclaw ? t("common.yes") : t("common.no"),
|
|
171
339
|
mode,
|
|
172
340
|
public: status.public_enabled ? t("common.on") : t("common.off"),
|
|
173
341
|
});
|
|
174
|
-
|
|
342
|
+
if (bar.className !== barClassName) {
|
|
343
|
+
bar.className = barClassName;
|
|
344
|
+
}
|
|
345
|
+
if (bar.textContent !== barText) {
|
|
346
|
+
bar.textContent = barText;
|
|
347
|
+
}
|
|
348
|
+
const brandStatusDot = document.getElementById("brandStatusDot");
|
|
349
|
+
const brandStatusClassName = `sidebar-version__status ${status.connected_to_silicaclaw ? "ok" : "warn"}`;
|
|
350
|
+
if (brandStatusDot.className !== brandStatusClassName) {
|
|
351
|
+
brandStatusDot.className = brandStatusClassName;
|
|
352
|
+
}
|
|
175
353
|
writeUiCache("silicaclaw_ui_social", {
|
|
176
|
-
integrationStatusText:
|
|
177
|
-
integrationStatusClassName:
|
|
354
|
+
integrationStatusText: barText,
|
|
355
|
+
integrationStatusClassName: barClassName,
|
|
178
356
|
socialStatusLineText: summaryLine,
|
|
179
357
|
socialStatusSublineText: namespaceText,
|
|
180
358
|
});
|
|
@@ -182,14 +360,14 @@ export function createSocialController({
|
|
|
182
360
|
if (!status.configured && status.configured_reason) reasons.push(t("social.configuredReason", { reason: status.configured_reason }));
|
|
183
361
|
if (!status.running && status.running_reason) reasons.push(t("social.runningReason", { reason: status.running_reason }));
|
|
184
362
|
if (!status.discoverable && status.discoverable_reason) reasons.push(t("social.discoverableReasonFull", { reason: status.discoverable_reason }));
|
|
185
|
-
|
|
363
|
+
setCachedContent("socialStateHint", reasons.length ? reasons.join(" · ") : t("hints.allIntegrationChecksPassed"), "text");
|
|
186
364
|
const modeSelect = document.getElementById("socialModeSelect");
|
|
187
365
|
const displayedSelectedMode = getSocialModeDirty() && getSocialModePending() ? getSocialModePending() : selectedMode;
|
|
188
366
|
if (modeSelect && displayedSelectedMode !== "-") modeSelect.value = displayedSelectedMode;
|
|
189
367
|
renderSocialModeHint(displayedSelectedMode, mode, !!social.network_requires_restart, getSocialModeDirty());
|
|
190
368
|
setSocialModePendingState(getSocialModeDirty());
|
|
191
369
|
|
|
192
|
-
|
|
370
|
+
setCachedContent("socialPrimaryCards", [
|
|
193
371
|
[t("social.configured"), status.configured ? t("common.yes") : t("common.no")],
|
|
194
372
|
[t("social.running"), status.running ? t("common.yes") : t("common.no")],
|
|
195
373
|
[t("social.discoverable"), discoverable ? t("common.yes") : t("common.no")],
|
|
@@ -197,9 +375,9 @@ export function createSocialController({
|
|
|
197
375
|
[t("social.networkMode"), mode],
|
|
198
376
|
[t("labels.adapter"), effectiveAdapter],
|
|
199
377
|
[t("social.discoverableReason"), status.discoverable_reason || "-"],
|
|
200
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
378
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join(""));
|
|
201
379
|
|
|
202
|
-
|
|
380
|
+
setCachedContent("socialIntegrationCards", [
|
|
203
381
|
[t("social.connected"), bridge.connected_to_silicaclaw ? t("common.yes") : t("common.no")],
|
|
204
382
|
[t("social.messageBroadcast"), bridge.message_broadcast_enabled ? t("common.on") : t("common.off")],
|
|
205
383
|
[t("social.displayName"), status.display_name || t("overview.unnamed")],
|
|
@@ -207,9 +385,9 @@ export function createSocialController({
|
|
|
207
385
|
[t("social.socialFound"), summary.social_md_found ? t("common.yes") : t("common.no")],
|
|
208
386
|
[t("social.socialSource"), summary.social_md_source_path || "-"],
|
|
209
387
|
[t("social.reuseOpenClawIdentity"), summary.reused_openclaw_identity ? t("common.yes") : t("common.no")],
|
|
210
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
388
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join(""));
|
|
211
389
|
|
|
212
|
-
|
|
390
|
+
setCachedContent("socialMessagePathCards", [
|
|
213
391
|
[t("social.messageBroadcast"), bridge.message_broadcast_enabled ? t("common.on") : t("common.off")],
|
|
214
392
|
[t("social.publicDiscovery"), status.public_enabled ? t("common.on") : t("common.off")],
|
|
215
393
|
[t("social.namespace"), effectiveNamespace],
|
|
@@ -218,7 +396,7 @@ export function createSocialController({
|
|
|
218
396
|
[t("network.lastPoll"), networkDiag.last_poll_at ? new Date(networkDiag.last_poll_at).toLocaleTimeString() : "-"],
|
|
219
397
|
[t("network.lastPublish"), networkDiag.last_publish_at ? new Date(networkDiag.last_publish_at).toLocaleTimeString() : "-"],
|
|
220
398
|
[t("network.lastError"), networkDiag.last_error || t("network.none")],
|
|
221
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${escapeHtml(String(v))}</div></div>`).join("");
|
|
399
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${escapeHtml(String(v))}</div></div>`).join(""));
|
|
222
400
|
|
|
223
401
|
const skillLearning = bridge.skill_learning || {};
|
|
224
402
|
const ownerDelivery = bridge.owner_delivery || {};
|
|
@@ -246,21 +424,21 @@ export function createSocialController({
|
|
|
246
424
|
ownerDeliveryHeadline = t("feedback.openclawRoleNotRunning");
|
|
247
425
|
ownerDeliveryBody = ownerDelivery.reason || "-";
|
|
248
426
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
427
|
+
setCachedContent("socialOwnerDeliveryStatus", `feedback ${ownerDeliveryTone}`, "class");
|
|
428
|
+
setCachedContent("socialOwnerDeliveryStatus", ownerDeliveryHeadline, "text");
|
|
429
|
+
setCachedContent("socialOwnerDeliverySubline", [
|
|
252
430
|
`${t("social.broadcastReadable")}: ${ownerDelivery.bridge_messages_readable ? t("common.yes") : t("common.no")}`,
|
|
253
431
|
`${t("social.ownerForwardCommand")}: ${ownerDelivery.forward_command_configured ? t("common.yes") : t("common.no")}`,
|
|
254
432
|
`${t("social.ownerForwardReady")}: ${ownerDelivery.ready ? t("common.yes") : t("common.no")}`,
|
|
255
|
-
].join(" · ");
|
|
256
|
-
|
|
257
|
-
|
|
433
|
+
].join(" · "), "text");
|
|
434
|
+
setCachedContent("socialOwnerDeliveryReason", ownerDeliveryBody, "text");
|
|
435
|
+
setCachedContent("socialCapabilityCards", [
|
|
258
436
|
[t("socialCapability.publicBroadcast"), bridge.message_broadcast_enabled ? t("common.yes") : t("common.no")],
|
|
259
437
|
[t("socialCapability.monitorBroadcasts"), ownerDelivery.bridge_messages_readable ? t("common.yes") : t("common.no")],
|
|
260
438
|
[t("socialCapability.autoPushToOwner"), ownerDelivery.ready ? t("common.yes") : t("common.no")],
|
|
261
439
|
[t("socialCapability.ownerPrivateBoundary"), t("socialCapability.ownerPrivateBoundaryValue")],
|
|
262
|
-
].map(([k, v]) => `<div class="card"><div class="label">${escapeHtml(String(k))}</div><div class="value" style="font-size:17px;">${escapeHtml(String(v))}</div></div>`).join("");
|
|
263
|
-
|
|
440
|
+
].map(([k, v]) => `<div class="card"><div class="label">${escapeHtml(String(k))}</div><div class="value" style="font-size:17px;">${escapeHtml(String(v))}</div></div>`).join(""));
|
|
441
|
+
setCachedContent("openclawSkillCards", [
|
|
264
442
|
[t("social.openclawInstalled"), openclawDetected ? t("common.yes") : t("common.no")],
|
|
265
443
|
[t("social.running"), openclawRunning ? t("common.yes") : t("common.no")],
|
|
266
444
|
[t("social.skillInstalled"), skillInstalled ? t("common.yes") : t("common.no")],
|
|
@@ -268,16 +446,17 @@ export function createSocialController({
|
|
|
268
446
|
[t("social.ownerForwardReady"), ownerDelivery.ready ? t("common.yes") : t("common.no")],
|
|
269
447
|
[t("social.ownerForwardCommand"), ownerDelivery.forward_command_configured ? t("common.yes") : t("common.no")],
|
|
270
448
|
[t("social.openclawDetectionMode"), bridge.openclaw_runtime?.detection_mode || "-"],
|
|
449
|
+
["Gateway probe", bridge.openclaw_runtime?.gateway_probe_ok ? t("common.yes") : t("common.no")],
|
|
271
450
|
[t("social.openclawGateway"), bridge.openclaw_runtime?.gateway_url || "-"],
|
|
272
451
|
[t("social.installMode"), skillLearning.install_mode || "-"],
|
|
273
452
|
[t("social.installedPath"), skillInstalled ? installedSkillPath : "-"],
|
|
274
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${escapeHtml(v)}</div></div>`).join("");
|
|
275
|
-
|
|
453
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${escapeHtml(v)}</div></div>`).join(""));
|
|
454
|
+
setCachedContent("openclawSkillPath", ownerDelivery.forward_command
|
|
276
455
|
? `${ownerDelivery.forward_command}${ownerDelivery.owner_channel ? ` · ${ownerDelivery.owner_channel}` : ""}${ownerDelivery.owner_target ? ` · ${ownerDelivery.owner_target}` : ""}`
|
|
277
456
|
: skillInstalled
|
|
278
457
|
? installedSkillPath
|
|
279
|
-
: `${installAction.recommended_command || "-"}${bridge.openclaw_runtime?.gateway_url ? ` · detect ${bridge.openclaw_runtime.gateway_url}` : ""}
|
|
280
|
-
|
|
458
|
+
: `${installAction.recommended_command || "-"}${bridge.openclaw_runtime?.gateway_url ? ` · detect ${bridge.openclaw_runtime.gateway_url}` : ""}`, "text");
|
|
459
|
+
setCachedContent("openclawSkillHint", !openclawDetected
|
|
281
460
|
? t("feedback.openclawRoleBroadcasterOnly")
|
|
282
461
|
: !openclawRunning
|
|
283
462
|
? t("feedback.openclawRoleNotRunning")
|
|
@@ -285,11 +464,11 @@ export function createSocialController({
|
|
|
285
464
|
? t("feedback.openclawRoleReadyToLearn")
|
|
286
465
|
: ownerDelivery.ready
|
|
287
466
|
? t("feedback.openclawRoleOwnerReady")
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
: t("feedback.openclawRoleLearned");
|
|
467
|
+
: ownerDelivery.bridge_messages_readable && !ownerDelivery.forward_command_configured
|
|
468
|
+
? t("feedback.openclawRoleLearningOnly")
|
|
469
|
+
: ownerDelivery.bridge_messages_readable
|
|
470
|
+
? t("feedback.openclawRoleNeedsOwnerRoute")
|
|
471
|
+
: t("feedback.openclawRoleLearned"), "text");
|
|
293
472
|
const skillInstallBtn = document.getElementById("openclawSkillInstallBtn");
|
|
294
473
|
skillInstallBtn.textContent = !openclawDetected
|
|
295
474
|
? t("actions.openclawNotInstalled")
|
|
@@ -310,33 +489,33 @@ export function createSocialController({
|
|
|
310
489
|
document.getElementById("governanceDuplicateWindowInput").value = String(Math.floor((policy.duplicate_window_ms ?? 180000) / 1000));
|
|
311
490
|
document.getElementById("governanceBlockedAgentsInput").value = blockedAgentIds.join(", ");
|
|
312
491
|
document.getElementById("governanceBlockedTermsInput").value = blockedTerms.join(", ");
|
|
313
|
-
|
|
492
|
+
setCachedContent("socialGovernanceCards", [
|
|
314
493
|
[t("labels.sendLimit"), `${policy.send_limit?.max ?? "-"} / ${Math.floor((policy.send_limit?.window_ms ?? 60000) / 1000)}s`],
|
|
315
494
|
[t("labels.receiveLimit"), `${policy.receive_limit?.max ?? "-"} / ${Math.floor((policy.receive_limit?.window_ms ?? 60000) / 1000)}s`],
|
|
316
495
|
[t("labels.duplicateWindowSeconds"), `${Math.floor((policy.duplicate_window_ms ?? 0) / 1000)}s`],
|
|
317
496
|
[t("labels.blockedAgentIds"), blockedAgentIds.length],
|
|
318
497
|
[t("labels.blockedTerms"), blockedTerms.length],
|
|
319
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
498
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join(""));
|
|
320
499
|
|
|
321
500
|
const moderationEvents = Array.isArray(governance.recent_events) ? governance.recent_events : [];
|
|
322
|
-
|
|
501
|
+
setCachedContent("socialModerationList", moderationEvents.length === 0
|
|
323
502
|
? `<div class="empty-state">${t("network.noModerationEvents")}</div>`
|
|
324
503
|
: moderationEvents.map((event) => `
|
|
325
504
|
<div class="log-item">
|
|
326
505
|
<div class="log-${event.level || "warn"}">[${String(event.level || "warn").toUpperCase()}] ${escapeHtml(event.message || "-")}</div>
|
|
327
506
|
<div class="mono" style="color:#90a2c3;">${new Date(event.timestamp).toLocaleString()}</div>
|
|
328
507
|
</div>
|
|
329
|
-
`).join("");
|
|
508
|
+
`).join(""));
|
|
330
509
|
|
|
331
|
-
|
|
510
|
+
setCachedContent("socialAdvancedCards", [
|
|
332
511
|
[t("labels.adapter"), effectiveAdapter],
|
|
333
512
|
[t("social.namespace"), effectiveNamespace],
|
|
334
513
|
[t("labels.room"), effectiveRoom],
|
|
335
514
|
[t("social.bridgeStatus"), bridge.connected_to_silicaclaw ? t("common.yes") : t("common.no")],
|
|
336
515
|
[t("social.messageBroadcast"), bridge.message_broadcast_enabled ? t("common.on") : t("common.off")],
|
|
337
516
|
[t("social.restartRequired"), social.network_requires_restart ? t("common.yes") : t("common.no")],
|
|
338
|
-
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
339
|
-
|
|
517
|
+
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join(""));
|
|
518
|
+
setCachedContent("socialAdvancedWrap", toPrettyJson({
|
|
340
519
|
effective_runtime: {
|
|
341
520
|
mode: effectiveMode,
|
|
342
521
|
adapter: effectiveAdapter,
|
|
@@ -358,17 +537,17 @@ export function createSocialController({
|
|
|
358
537
|
social_md_found: summary.social_md_found,
|
|
359
538
|
social_md_source_path: summary.social_md_source_path,
|
|
360
539
|
},
|
|
361
|
-
});
|
|
540
|
+
}), "text");
|
|
362
541
|
|
|
363
|
-
|
|
542
|
+
setCachedContent("socialSourceWrap", toPrettyJson({
|
|
364
543
|
found: social.found,
|
|
365
544
|
source_path: social.source_path,
|
|
366
545
|
parse_error: social.parse_error,
|
|
367
|
-
});
|
|
368
|
-
|
|
546
|
+
}), "text");
|
|
547
|
+
setCachedContent("socialRawWrap", toPrettyJson({
|
|
369
548
|
raw_frontmatter: social.raw_frontmatter || null,
|
|
370
|
-
});
|
|
371
|
-
|
|
549
|
+
}), "text");
|
|
550
|
+
setCachedContent("socialRuntimeWrap", toPrettyJson(runtime), "text");
|
|
372
551
|
}
|
|
373
552
|
|
|
374
553
|
async function exportSocialTemplate() {
|
|
@@ -383,23 +562,43 @@ export function createSocialController({
|
|
|
383
562
|
const logLevelFilter = getLogLevelFilter();
|
|
384
563
|
const el = document.getElementById("logList");
|
|
385
564
|
if (!logsCache.length) {
|
|
386
|
-
|
|
565
|
+
const nextHtml = `<div class="empty-state">${t("network.noLogsYet")}</div>`;
|
|
566
|
+
if (nextHtml !== lastLogsRenderKey) {
|
|
567
|
+
el.innerHTML = nextHtml;
|
|
568
|
+
lastLogsRenderKey = nextHtml;
|
|
569
|
+
}
|
|
387
570
|
return;
|
|
388
571
|
}
|
|
389
572
|
const filtered = logLevelFilter === "all" ? logsCache : logsCache.filter((item) => String(item.level || "").toLowerCase() === logLevelFilter);
|
|
390
573
|
if (!filtered.length) {
|
|
391
|
-
|
|
574
|
+
const nextHtml = `<div class="empty-state">${t("network.noLogsForLevel", { level: logLevelFilter })}</div>`;
|
|
575
|
+
if (nextHtml !== lastLogsRenderKey) {
|
|
576
|
+
el.innerHTML = nextHtml;
|
|
577
|
+
lastLogsRenderKey = nextHtml;
|
|
578
|
+
}
|
|
392
579
|
return;
|
|
393
580
|
}
|
|
394
|
-
|
|
581
|
+
const nextHtml = filtered.map((item) => `
|
|
395
582
|
<div class="log-item">
|
|
396
583
|
<div class="log-${item.level}">[${String(item.level).toUpperCase()}] ${item.message}</div>
|
|
397
584
|
<div class="mono" style="color:#90a2c3;">${new Date(item.timestamp).toLocaleString()}</div>
|
|
398
585
|
</div>
|
|
399
586
|
`).join("");
|
|
587
|
+
const renderKey = JSON.stringify({
|
|
588
|
+
level: logLevelFilter,
|
|
589
|
+
items: filtered.map((item) => [item.timestamp, item.level, item.message]),
|
|
590
|
+
});
|
|
591
|
+
if (renderKey === lastLogsRenderKey) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
el.innerHTML = nextHtml;
|
|
595
|
+
lastLogsRenderKey = renderKey;
|
|
400
596
|
}
|
|
401
597
|
|
|
402
598
|
async function refreshLogs() {
|
|
599
|
+
if (getActiveTab() !== "network") {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
403
602
|
setLogsCache((await api("/api/logs")).data || []);
|
|
404
603
|
renderLogs();
|
|
405
604
|
}
|
|
@@ -425,8 +624,8 @@ export function createSocialController({
|
|
|
425
624
|
<div class="skill-card">
|
|
426
625
|
<div class="skill-card__top">
|
|
427
626
|
<div>
|
|
428
|
-
<div class="skill-card__eyebrow">${escapeHtml(options.eyebrow || skill.install_mode || "skill")}</div>
|
|
429
|
-
<div class="skill-card__title">${escapeHtml(skill.display_name || skill.name || "
|
|
627
|
+
<div class="skill-card__eyebrow">${escapeHtml(skillModeLabel(options.eyebrow || skill.install_mode || "skill"))}</div>
|
|
628
|
+
<div class="skill-card__title">${escapeHtml(skill.display_name || skill.name || t("labels.skillsModeGeneric"))}</div>
|
|
430
629
|
</div>
|
|
431
630
|
<div class="skill-card__version mono">${escapeHtml(versionText)}</div>
|
|
432
631
|
</div>
|
|
@@ -476,7 +675,7 @@ export function createSocialController({
|
|
|
476
675
|
<div class="skill-card">
|
|
477
676
|
<div class="skill-card__top">
|
|
478
677
|
<div>
|
|
479
|
-
<div class="skill-card__eyebrow">${escapeHtml(skill.display_name || skill.name || "
|
|
678
|
+
<div class="skill-card__eyebrow">${escapeHtml(skill.display_name || skill.name || t("labels.skillsModeGeneric"))}</div>
|
|
480
679
|
<div class="skill-card__title">${escapeHtml(t("labels.skillsDialogueExamples"))}</div>
|
|
481
680
|
</div>
|
|
482
681
|
<div class="skill-card__version mono">${escapeHtml(skill.version || "-")}</div>
|
|
@@ -604,36 +803,57 @@ export function createSocialController({
|
|
|
604
803
|
`).join("")
|
|
605
804
|
: `<div class="skills-empty">${t("hints.skillsNoBundled")}</div>`;
|
|
606
805
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
806
|
+
const bundledMatchCount = renderFilteredSkillCards({
|
|
807
|
+
skills: bundledSorted,
|
|
808
|
+
section: "bundled",
|
|
809
|
+
gridId: "skillsBundledGrid",
|
|
810
|
+
footerId: "skillsBundledFooter",
|
|
811
|
+
limit: SKILLS_SECTION_LIMIT,
|
|
812
|
+
renderer: (skill) => renderSkillCard(skill, {
|
|
813
|
+
eyebrow: skill.install_mode === "workspace" || skill.install_mode === "legacy" ? skill.install_mode : "bundled",
|
|
814
|
+
statusText: skill.update_available
|
|
815
|
+
? t("labels.skillsUpdateAvailable")
|
|
816
|
+
: skill.installed_in_openclaw
|
|
817
|
+
? `${t("labels.skillsStatus")}: ${t("common.yes")}`
|
|
818
|
+
: t("hints.skillsNotInstalled"),
|
|
819
|
+
installable: true,
|
|
820
|
+
updateAvailable: skill.update_available,
|
|
821
|
+
installedVersion: skill.installed_version,
|
|
822
|
+
bundledVersion: skill.version,
|
|
823
|
+
}),
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
const installedMatchCount = renderFilteredSkillCards({
|
|
827
|
+
skills: installedSorted,
|
|
828
|
+
section: "installed",
|
|
829
|
+
gridId: "skillsInstalledGrid",
|
|
830
|
+
footerId: "skillsInstalledFooter",
|
|
831
|
+
limit: SKILLS_SECTION_LIMIT,
|
|
832
|
+
renderer: (skill) => renderSkillCard(skill, {
|
|
833
|
+
eyebrow: skill.install_mode || "installed",
|
|
834
|
+
statusText: skill.update_available
|
|
835
|
+
? t("labels.skillsUpdateAvailable")
|
|
836
|
+
: `${t("labels.skillsStatus")}: ${escapeHtml(skillModeLabel(skill.install_mode || "installed"))}`,
|
|
837
|
+
updateAvailable: skill.update_available,
|
|
838
|
+
installedVersion: skill.version,
|
|
839
|
+
bundledVersion: skill.bundled_version,
|
|
840
|
+
}),
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
const dialogueMatchCount = renderFilteredSkillCards({
|
|
844
|
+
skills: featuredSkills,
|
|
845
|
+
section: "dialogue",
|
|
846
|
+
gridId: "skillsDialogueGrid",
|
|
847
|
+
footerId: "skillsDialogueFooter",
|
|
848
|
+
limit: SKILLS_DIALOGUE_LIMIT,
|
|
849
|
+
renderer: (skill) => renderDialogueCard(skill),
|
|
850
|
+
});
|
|
621
851
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
: `${t("labels.skillsStatus")}: ${escapeHtml(String(skill.install_mode || "-"))}`,
|
|
628
|
-
updateAvailable: skill.update_available,
|
|
629
|
-
installedVersion: skill.version,
|
|
630
|
-
bundledVersion: skill.bundled_version,
|
|
631
|
-
})).join("")
|
|
632
|
-
: `<div class="skills-empty">${t("hints.skillsNoInstalled")}</div>`;
|
|
633
|
-
|
|
634
|
-
document.getElementById("skillsDialogueGrid").innerHTML = featuredSkills.length
|
|
635
|
-
? featuredSkills.map((skill) => renderDialogueCard(skill)).join("")
|
|
636
|
-
: `<div class="skills-empty">${t("hints.skillsNoDialogueExamples")}</div>`;
|
|
852
|
+
renderSkillsFilterMeta({
|
|
853
|
+
bundledCount: bundledMatchCount,
|
|
854
|
+
installedCount: installedMatchCount,
|
|
855
|
+
dialogueCount: dialogueMatchCount,
|
|
856
|
+
});
|
|
637
857
|
|
|
638
858
|
const installBtn = document.getElementById("skillsInstallBtn");
|
|
639
859
|
installBtn.textContent = !openclawDetected
|
|
@@ -659,6 +879,9 @@ export function createSocialController({
|
|
|
659
879
|
refreshSocial,
|
|
660
880
|
renderLogs,
|
|
661
881
|
renderSocialMessages,
|
|
882
|
+
setSkillsFilter,
|
|
883
|
+
setSkillsQuery,
|
|
662
884
|
setLogLevelFilter,
|
|
885
|
+
toggleSkillsExpanded,
|
|
663
886
|
};
|
|
664
887
|
}
|