@silicaclaw/cli 2026.3.19-6 → 2026.3.19-7

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.
@@ -0,0 +1,77 @@
1
+ export function ago(ts) {
2
+ if (!ts) return "-";
3
+ const s = Math.max(0, Math.floor((Date.now() - ts) / 1000));
4
+ if (s < 60) return `${s}s ago`;
5
+ if (s < 3600) return `${Math.floor(s / 60)}m ago`;
6
+ return `${Math.floor(s / 3600)}h ago`;
7
+ }
8
+
9
+ export function shortId(id) {
10
+ if (!id) return "-";
11
+ return `${id.slice(0, 10)}...${id.slice(-6)}`;
12
+ }
13
+
14
+ export function messageSendReasonText(t, reason) {
15
+ if (reason === "rate_limited") return t("feedback.messageRateLimited");
16
+ if (reason === "duplicate_recent_message") return t("feedback.messageDuplicateBlocked");
17
+ if (reason === "blocked_term") return t("feedback.messageBlockedTerm");
18
+ return t("feedback.messageBroadcastFailed");
19
+ }
20
+
21
+ export function describeCurrentMode(t, mode) {
22
+ if (mode === "local") return t("overview.modeLocal");
23
+ if (mode === "global-preview") return t("overview.modeGlobalPreview");
24
+ return t("overview.modeLan");
25
+ }
26
+
27
+ export function escapeHtml(value) {
28
+ return String(value ?? "")
29
+ .replace(/&/g, "&amp;")
30
+ .replace(/</g, "&lt;")
31
+ .replace(/>/g, "&gt;")
32
+ .replace(/"/g, "&quot;")
33
+ .replace(/'/g, "&#39;");
34
+ }
35
+
36
+ export function toPrettyJson(obj) {
37
+ try {
38
+ return JSON.stringify(obj, null, 2);
39
+ } catch {
40
+ return String(obj);
41
+ }
42
+ }
43
+
44
+ export function formatMessageBody(value) {
45
+ return escapeHtml(value).replace(/\n/g, "<br />");
46
+ }
47
+
48
+ export function resolveThemeMode(mode) {
49
+ if (mode === "system") {
50
+ return window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
51
+ }
52
+ return mode === "light" ? "light" : "dark";
53
+ }
54
+
55
+ export function parseTags(raw) {
56
+ return String(raw || "")
57
+ .split(",")
58
+ .map((s) => s.trim())
59
+ .filter(Boolean)
60
+ .filter((tag, idx, arr) => arr.indexOf(tag) === idx);
61
+ }
62
+
63
+ export function parseCsv(raw) {
64
+ return String(raw || "")
65
+ .split(",")
66
+ .map((s) => s.trim())
67
+ .filter(Boolean)
68
+ .filter((item, idx, arr) => arr.indexOf(item) === idx);
69
+ }
70
+
71
+ export function field(form, name) {
72
+ return form.querySelector(`[name="${name}"]`);
73
+ }
74
+
75
+ export function normalizeTagsInput(raw) {
76
+ return parseTags(raw).join(", ");
77
+ }