soulnet-dsh 0.1.8 → 0.1.9
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/lib/client.js
CHANGED
|
@@ -2320,7 +2320,7 @@ window.__ModuleLoader__.load({
|
|
|
2320
2320
|
"inbox.pending.noGreeting": "(no greeting)",
|
|
2321
2321
|
"inbox.pending.accepted": "Accepted {name}.",
|
|
2322
2322
|
"inbox.empty": "No friends yet — paste a card URI below, or /add.",
|
|
2323
|
-
"inbox.empty.noIdentity": "No identity yet — create one in Settings →
|
|
2323
|
+
"inbox.empty.noIdentity": "No identity yet — create one in Settings → Soulnet.",
|
|
2324
2324
|
"inbox.noIdentity": "No identity yet",
|
|
2325
2325
|
"inbox.noMessages": "No messages yet",
|
|
2326
2326
|
"inbox.typing": "typing…",
|
|
@@ -2338,12 +2338,14 @@ window.__ModuleLoader__.load({
|
|
|
2338
2338
|
"bubble.mine": "my alter",
|
|
2339
2339
|
"bubble.auto": "auto-reply",
|
|
2340
2340
|
"bubble.note": "SoulMirror",
|
|
2341
|
-
"settings.nav": "
|
|
2342
|
-
"
|
|
2343
|
-
"
|
|
2344
|
-
"page.update.
|
|
2345
|
-
"
|
|
2346
|
-
"
|
|
2341
|
+
"settings.nav": "Soulnet",
|
|
2342
|
+
"sidebar.update": "Upgrade v{v}",
|
|
2343
|
+
"sidebar.update.busy": "Upgrading…",
|
|
2344
|
+
"page.update.installing": "Installing v{v}…",
|
|
2345
|
+
"page.update.restarting": "Restarting the service…",
|
|
2346
|
+
"page.update.reloading": "Back — reloading…",
|
|
2347
|
+
"settings.title": "Soulnet",
|
|
2348
|
+
"settings.intro": "This dsh is a node on Soulnet: an end-to-end encrypted A2A identity, friends, and your alter — one dsh session (\"My alter\") that speaks to every friend on your behalf.",
|
|
2347
2349
|
"settings.status": "Backend",
|
|
2348
2350
|
"settings.status.soulnet": "soulnet light peer",
|
|
2349
2351
|
"settings.status.fake": "in-memory fake",
|
|
@@ -2408,14 +2410,14 @@ window.__ModuleLoader__.load({
|
|
|
2408
2410
|
"settings.add.sent": "Request sent to {name}. The thread appears once they accept.",
|
|
2409
2411
|
"settings.error": "Error: {message}",
|
|
2410
2412
|
"settings.refresh": "Refresh",
|
|
2411
|
-
"onboard.title": "Welcome to
|
|
2413
|
+
"onboard.title": "Welcome to Soulnet",
|
|
2412
2414
|
"onboard.body": "Create your A2A identity: a key pair generated on this machine. Others add you by pasting your card URI.",
|
|
2413
2415
|
"onboard.name": "Display name",
|
|
2414
2416
|
"onboard.create": "Create identity",
|
|
2415
2417
|
"onboard.done": "Done",
|
|
2416
2418
|
"onboard.later": "Later",
|
|
2417
2419
|
"onboard.created": "Identity created. Copy your card URI and back up identity.json.",
|
|
2418
|
-
"onboard.waiting": "The soulnet peer is not running yet ({state}). Check Settings →
|
|
2420
|
+
"onboard.waiting": "The soulnet peer is not running yet ({state}). Check Settings → Soulnet.",
|
|
2419
2421
|
"cmd.friends.open": "Open the thread with {name}",
|
|
2420
2422
|
"cmd.friends.none": "No friends yet",
|
|
2421
2423
|
"cmd.soulmirror.page": "Open SoulMirror — My alter",
|
|
@@ -2433,7 +2435,7 @@ window.__ModuleLoader__.load({
|
|
|
2433
2435
|
"page.add.note": "Note (optional, also the greeting)",
|
|
2434
2436
|
"page.add.send": "Send request",
|
|
2435
2437
|
"page.empty.noFriends": "No friends yet. Paste a card URI under \"Add friend\" at the bottom of the list, or send yours to a friend.",
|
|
2436
|
-
"page.empty.noFriends.noIdentity": "No identity yet — create one in Settings →
|
|
2438
|
+
"page.empty.noFriends.noIdentity": "No identity yet — create one in Settings → Soulnet.",
|
|
2437
2439
|
"page.empty.noMatch": "No friend matches \"{query}\".",
|
|
2438
2440
|
"page.header.online": "online",
|
|
2439
2441
|
"page.header.offline": "offline",
|
|
@@ -2751,7 +2753,7 @@ window.__ModuleLoader__.load({
|
|
|
2751
2753
|
"inbox.pending.noGreeting": "(没有问候语)",
|
|
2752
2754
|
"inbox.pending.accepted": "已接受 {name}。",
|
|
2753
2755
|
"inbox.empty": "还没有好友——在下面贴名片链接,或用 /add。",
|
|
2754
|
-
"inbox.empty.noIdentity": "还没有身份——到 设置 →
|
|
2756
|
+
"inbox.empty.noIdentity": "还没有身份——到 设置 → Soulnet 创建。",
|
|
2755
2757
|
"inbox.noIdentity": "还没有身份",
|
|
2756
2758
|
"inbox.noMessages": "还没有消息",
|
|
2757
2759
|
"inbox.typing": "正在输入…",
|
|
@@ -2769,12 +2771,14 @@ window.__ModuleLoader__.load({
|
|
|
2769
2771
|
"bubble.mine": "我的分身",
|
|
2770
2772
|
"bubble.auto": "自动回复",
|
|
2771
2773
|
"bubble.note": "灵镜",
|
|
2772
|
-
"settings.nav": "
|
|
2773
|
-
"
|
|
2774
|
-
"
|
|
2775
|
-
"page.update.
|
|
2776
|
-
"
|
|
2777
|
-
"
|
|
2774
|
+
"settings.nav": "Soulnet",
|
|
2775
|
+
"sidebar.update": "升级 v{v}",
|
|
2776
|
+
"sidebar.update.busy": "升级中…",
|
|
2777
|
+
"page.update.installing": "正在安装 v{v}……",
|
|
2778
|
+
"page.update.restarting": "正在重启服务……",
|
|
2779
|
+
"page.update.reloading": "完成——正在刷新……",
|
|
2780
|
+
"settings.title": "Soulnet",
|
|
2781
|
+
"settings.intro": "这个 dsh 是Soulnet 上的一个节点:端到端加密的 A2A 身份、好友,以及你的分身——一条 dsh 会话(「我的分身」),替你和所有好友往来。",
|
|
2778
2782
|
"settings.status": "后端",
|
|
2779
2783
|
"settings.status.soulnet": "soulnet 灵网轻端",
|
|
2780
2784
|
"settings.status.fake": "内存假实现",
|
|
@@ -2839,14 +2843,14 @@ window.__ModuleLoader__.load({
|
|
|
2839
2843
|
"settings.add.sent": "已向 {name} 发出申请,对方接受后往来就会出现。",
|
|
2840
2844
|
"settings.error": "错误:{message}",
|
|
2841
2845
|
"settings.refresh": "刷新",
|
|
2842
|
-
"onboard.title": "
|
|
2846
|
+
"onboard.title": "欢迎来到Soulnet",
|
|
2843
2847
|
"onboard.body": "创建你的 A2A 身份:在本机生成一对密钥。别人贴你的名片链接就能加你。",
|
|
2844
2848
|
"onboard.name": "昵称",
|
|
2845
2849
|
"onboard.create": "创建身份",
|
|
2846
2850
|
"onboard.done": "完成",
|
|
2847
2851
|
"onboard.later": "稍后",
|
|
2848
2852
|
"onboard.created": "身份已创建。复制名片链接,并备份 identity.json。",
|
|
2849
|
-
"onboard.waiting": "soulnet 轻端还没运行({state})。请到 设置 →
|
|
2853
|
+
"onboard.waiting": "soulnet 轻端还没运行({state})。请到 设置 → Soulnet 查看。",
|
|
2850
2854
|
"cmd.friends.open": "打开与 {name} 的往来",
|
|
2851
2855
|
"cmd.friends.none": "还没有好友",
|
|
2852
2856
|
"cmd.soulmirror.page": "打开灵镜——我的分身",
|
|
@@ -2864,7 +2868,7 @@ window.__ModuleLoader__.load({
|
|
|
2864
2868
|
"page.add.note": "备注(可选,同时作为问候语)",
|
|
2865
2869
|
"page.add.send": "发送申请",
|
|
2866
2870
|
"page.empty.noFriends": "还没有好友。把对方的名片链接贴到列表底部的「加好友」,或把你的名片发给对方。",
|
|
2867
|
-
"page.empty.noFriends.noIdentity": "还没有身份——到 设置 →
|
|
2871
|
+
"page.empty.noFriends.noIdentity": "还没有身份——到 设置 → Soulnet 创建。",
|
|
2868
2872
|
"page.empty.noMatch": "没有匹配「{query}」的好友。",
|
|
2869
2873
|
"page.header.online": "在线",
|
|
2870
2874
|
"page.header.offline": "离线",
|
|
@@ -7735,23 +7739,10 @@ window.__ModuleLoader__.load({
|
|
|
7735
7739
|
return t("group.join.applied");
|
|
7736
7740
|
});
|
|
7737
7741
|
};
|
|
7738
|
-
const upgrade = (0, react.useSyncExternalStore)(upgradeStore.subscribe, upgradeStore.getSnapshot);
|
|
7739
|
-
const upgradeBusy = upgrade.phase === "installing" || upgrade.phase === "restarting" || upgrade.phase === "reloading";
|
|
7740
7742
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
7741
7743
|
className: "sm-list-col",
|
|
7742
7744
|
"data-soulmirror-page-list": true,
|
|
7743
7745
|
children: [
|
|
7744
|
-
upgrade.hasUpdate || upgradeBusy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7745
|
-
type: "button",
|
|
7746
|
-
className: "sm-update-banner",
|
|
7747
|
-
disabled: upgradeBusy,
|
|
7748
|
-
"data-soulmirror-update-banner": upgrade.latest,
|
|
7749
|
-
onClick: () => {
|
|
7750
|
-
if (upgradeBusy || upgrade.latest === void 0) return;
|
|
7751
|
-
if (window.confirm(t("page.update.confirm", { v: upgrade.latest }))) upgradeStore.run();
|
|
7752
|
-
},
|
|
7753
|
-
children: upgradeBusy ? t("page.update.busy") : t("page.update.banner", { v: upgrade.latest ?? "" })
|
|
7754
|
-
}) : null,
|
|
7755
7746
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7756
7747
|
className: "sm-list-head",
|
|
7757
7748
|
children: [
|
|
@@ -11087,6 +11078,76 @@ window.__ModuleLoader__.load({
|
|
|
11087
11078
|
});
|
|
11088
11079
|
}
|
|
11089
11080
|
//#endregion
|
|
11081
|
+
//#region src/client/UpdateAction.tsx
|
|
11082
|
+
/**
|
|
11083
|
+
* Icon-only update button at the RIGHT end of the sidebar-foot SoulMirror row
|
|
11084
|
+
* (list seat `sidebar.footer.action`, ordered after the entry): invisible
|
|
11085
|
+
* until a newer release is known, then a small circled arrow. One click runs
|
|
11086
|
+
* the full install-restart-reload chain; while busy the tooltip narrates the
|
|
11087
|
+
* phase and the icon pulses. The reloaded page re-checks as current and the
|
|
11088
|
+
* button removes itself.
|
|
11089
|
+
*/
|
|
11090
|
+
/** Upward arrow (update available). */
|
|
11091
|
+
function ArrowUpIcon({ size = 13 }) {
|
|
11092
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
11093
|
+
width: size,
|
|
11094
|
+
height: size,
|
|
11095
|
+
viewBox: "0 0 16 16",
|
|
11096
|
+
fill: "none",
|
|
11097
|
+
"aria-hidden": true,
|
|
11098
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11099
|
+
d: "M8 13.2V3.6M3.6 7.6 8 3.2l4.4 4.4",
|
|
11100
|
+
stroke: "currentColor",
|
|
11101
|
+
strokeWidth: "1.7",
|
|
11102
|
+
strokeLinecap: "round",
|
|
11103
|
+
strokeLinejoin: "round"
|
|
11104
|
+
})
|
|
11105
|
+
});
|
|
11106
|
+
}
|
|
11107
|
+
/** Spinning arc shown while the upgrade chain runs. */
|
|
11108
|
+
function SpinnerIcon({ size = 13 }) {
|
|
11109
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
11110
|
+
width: size,
|
|
11111
|
+
height: size,
|
|
11112
|
+
viewBox: "0 0 16 16",
|
|
11113
|
+
fill: "none",
|
|
11114
|
+
"aria-hidden": true,
|
|
11115
|
+
className: "sm-update-spin",
|
|
11116
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
11117
|
+
cx: "8",
|
|
11118
|
+
cy: "8",
|
|
11119
|
+
r: "6",
|
|
11120
|
+
stroke: "currentColor",
|
|
11121
|
+
strokeWidth: "1.7",
|
|
11122
|
+
strokeLinecap: "round",
|
|
11123
|
+
strokeDasharray: "28",
|
|
11124
|
+
strokeDashoffset: "20"
|
|
11125
|
+
})
|
|
11126
|
+
});
|
|
11127
|
+
}
|
|
11128
|
+
function UpdateAction({ t }) {
|
|
11129
|
+
const upgrade = (0, react.useSyncExternalStore)(upgradeStore.subscribe, upgradeStore.getSnapshot);
|
|
11130
|
+
const busy = upgrade.phase === "installing" || upgrade.phase === "restarting" || upgrade.phase === "reloading";
|
|
11131
|
+
if (!upgrade.hasUpdate && !busy) return null;
|
|
11132
|
+
const label = busy ? upgrade.phase === "installing" ? t("page.update.installing", { v: upgrade.latest ?? "" }) : upgrade.phase === "restarting" ? t("page.update.restarting") : t("page.update.reloading") : t("sidebar.update", { v: upgrade.latest ?? "" });
|
|
11133
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
11134
|
+
label,
|
|
11135
|
+
delayMs: 200,
|
|
11136
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
11137
|
+
type: "button",
|
|
11138
|
+
className: `sm-update-fab${busy ? " sm-busy" : ""}`,
|
|
11139
|
+
disabled: busy,
|
|
11140
|
+
"aria-label": label,
|
|
11141
|
+
"data-soulmirror-update-action": upgrade.latest,
|
|
11142
|
+
onClick: () => {
|
|
11143
|
+
if (busy || upgrade.latest === void 0) return;
|
|
11144
|
+
upgradeStore.run();
|
|
11145
|
+
},
|
|
11146
|
+
children: busy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SpinnerIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArrowUpIcon, {})
|
|
11147
|
+
})
|
|
11148
|
+
});
|
|
11149
|
+
}
|
|
11150
|
+
//#endregion
|
|
11090
11151
|
//#region src/client/styles.ts
|
|
11091
11152
|
/**
|
|
11092
11153
|
* The rules the SoulMirror surfaces need that inline styles cannot express
|
|
@@ -11101,13 +11162,28 @@ window.__ModuleLoader__.load({
|
|
|
11101
11162
|
*/
|
|
11102
11163
|
const STYLE_ID = "soulmirror-styles";
|
|
11103
11164
|
const CSS = `
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11165
|
+
/* Icon-only update button at the right end of the SoulMirror foot row:
|
|
11166
|
+
invisible until a release is known, small circled arrow, tooltip carries
|
|
11167
|
+
the words. Sits beside the entry (the row is a flex line). */
|
|
11168
|
+
.sm-update-fab {
|
|
11169
|
+
flex: none; align-self: center; width: 24px; height: 24px; margin: 4px 2px 0 0;
|
|
11170
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
11171
|
+
border: 1px solid var(--dsw-alias-brand-primary); border-radius: 50%;
|
|
11172
|
+
background: transparent; color: var(--dsw-alias-brand-primary); cursor: pointer; padding: 0;
|
|
11173
|
+
}
|
|
11174
|
+
.sm-update-fab:hover { background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-label-primary-inverted); }
|
|
11175
|
+
.sm-update-fab:disabled, .sm-update-fab.sm-busy { opacity: .8; cursor: default; }
|
|
11176
|
+
.sm-update-spin { animation: sm-update-spin 900ms linear infinite; }
|
|
11177
|
+
@keyframes sm-update-spin { to { transform: rotate(360deg); } }
|
|
11178
|
+
display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-width: 0;
|
|
11179
|
+
padding: 2px 9px; border: 1px solid var(--dsw-alias-brand-primary); border-radius: 999px;
|
|
11180
|
+
background: transparent; color: var(--dsw-alias-brand-primary);
|
|
11181
|
+
font: inherit; font-size: 11px; font-weight: 600; cursor: pointer; white-space: nowrap;
|
|
11108
11182
|
}
|
|
11109
|
-
.sm-update-
|
|
11110
|
-
.sm-update-
|
|
11183
|
+
.sm-update-chip:hover { background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-label-primary-inverted); }
|
|
11184
|
+
.sm-update-chip:disabled { opacity: .75; cursor: default; }
|
|
11185
|
+
.sm-update-chip.sm-rail { padding: 2px 6px; }
|
|
11186
|
+
|
|
11111
11187
|
|
|
11112
11188
|
/* Native form controls follow the ACTIVE theme: the option list of a <select>
|
|
11113
11189
|
(and scrollbars, checkboxes...) is OS-rendered and ignores CSS tokens - it
|
|
@@ -11116,8 +11192,8 @@ body[data-ds-dark-theme] { color-scheme: dark; }
|
|
|
11116
11192
|
.sm-page-root select option, .sm-page-root select optgroup { background: var(--dsw-specific-menu); color: var(--dsw-alias-label-primary); }
|
|
11117
11193
|
|
|
11118
11194
|
.sm-footer {
|
|
11119
|
-
flex:
|
|
11120
|
-
width:
|
|
11195
|
+
flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px;
|
|
11196
|
+
width: auto; height: 42px; margin: 4px -2px 0; padding: 0 10px 0 8px;
|
|
11121
11197
|
box-sizing: border-box; border: none; border-radius: 12px; background: transparent;
|
|
11122
11198
|
cursor: pointer; overflow: hidden; color: var(--dsw-alias-label-primary);
|
|
11123
11199
|
font-family: inherit; font-size: 14px; line-height: 22px; position: relative;
|
|
@@ -11534,6 +11610,12 @@ body[data-ds-dark-theme] .sm-page-root {
|
|
|
11534
11610
|
order: 0,
|
|
11535
11611
|
locale: NS
|
|
11536
11612
|
}, SidebarEntry));
|
|
11613
|
+
ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
11614
|
+
name: "sidebar.footer.action",
|
|
11615
|
+
id: "soulmirror-update",
|
|
11616
|
+
order: 1,
|
|
11617
|
+
locale: NS
|
|
11618
|
+
}, UpdateAction));
|
|
11537
11619
|
ctx.slots.inject("sidebar.nav.primary", () => {
|
|
11538
11620
|
navSeatStore.set(true);
|
|
11539
11621
|
const dispose = ctx.slots.register({
|
|
@@ -11603,14 +11685,29 @@ body[data-ds-dark-theme] .sm-page-root {
|
|
|
11603
11685
|
openSession,
|
|
11604
11686
|
scope
|
|
11605
11687
|
});
|
|
11606
|
-
ctx.slots.inject("settings.section", () =>
|
|
11607
|
-
|
|
11608
|
-
|
|
11609
|
-
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
11613
|
-
|
|
11688
|
+
ctx.slots.inject("settings.section", () => {
|
|
11689
|
+
const make = () => ctx.slots.register({
|
|
11690
|
+
name: "settings.section",
|
|
11691
|
+
id: "soulmirror",
|
|
11692
|
+
order: 80,
|
|
11693
|
+
locale: NS,
|
|
11694
|
+
label: () => upgradeStore.getSnapshot().hasUpdate ? `${t("settings.nav")} ●` : t("settings.nav"),
|
|
11695
|
+
inject: settingsInjected
|
|
11696
|
+
}, SoulmirrorSettingsSection);
|
|
11697
|
+
let hadUpdate = upgradeStore.getSnapshot().hasUpdate;
|
|
11698
|
+
let disposeSection = make();
|
|
11699
|
+
const unsubscribe = upgradeStore.subscribe(() => {
|
|
11700
|
+
const now = upgradeStore.getSnapshot().hasUpdate;
|
|
11701
|
+
if (now === hadUpdate) return;
|
|
11702
|
+
hadUpdate = now;
|
|
11703
|
+
disposeSection();
|
|
11704
|
+
disposeSection = make();
|
|
11705
|
+
});
|
|
11706
|
+
return () => {
|
|
11707
|
+
unsubscribe();
|
|
11708
|
+
disposeSection();
|
|
11709
|
+
};
|
|
11710
|
+
});
|
|
11614
11711
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
11615
11712
|
name: "settings.onboarding",
|
|
11616
11713
|
id: "soulmirror-identity",
|