@nextclaw/ui 0.15.19 → 0.15.21
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 +40 -0
- package/dist/assets/api-CHo2gekJ.js +13 -0
- package/dist/assets/app-presenter-provider-2_DmWYT9.js +108 -0
- package/dist/assets/appearance-settings-page-BEy2UE7R.js +1 -0
- package/dist/assets/{book-open-HtUSPwoS.js → book-open-BrZL4o9L.js} +1 -1
- package/dist/assets/card-B5rRLu_6.js +1 -0
- package/dist/assets/{channels-list-page-Bspr1Jp4.js → channels-list-page-C1dnm68I.js} +2 -2
- package/dist/assets/chat-page-Dz6tvZ91.js +1 -0
- package/dist/assets/config-split-page-6y6W6dz4.js +1 -0
- package/dist/assets/confirm-dialog-q1CpEmR8.js +5 -0
- package/dist/assets/desktop-update-config-DrdlwP4j.js +1 -0
- package/dist/assets/{dist-CZx9Q6jc.js → dist-C9EX46wM.js} +1 -1
- package/dist/assets/doc-browser-BfttDSti.js +1 -0
- package/dist/assets/{doc-browser-B4l0Xu7u.js → doc-browser-DH-3hDnI.js} +1 -1
- package/dist/assets/{doc-browser-context-Dy7EhLI8.js → doc-browser-context-TU2heon0.js} +1 -1
- package/dist/assets/{eye-DU7p1-7X.js → eye-B-3dyZNA.js} +1 -1
- package/dist/assets/form-actions-DvvxCpL4.js +1 -0
- package/dist/assets/index-CXDPLDFD.css +1 -0
- package/dist/assets/index-k_eWScvN.js +2 -0
- package/dist/assets/loader-circle-B35NlHTI.js +1 -0
- package/dist/assets/logo-badge-DB51c0cS.js +1 -0
- package/dist/assets/mcp-marketplace-page-CkPtwPBk.js +1 -0
- package/dist/assets/{mcp-marketplace-page-Dg03SZX1.js → mcp-marketplace-page-DWtsIqml.js} +3 -3
- package/dist/assets/{model-config-page-DOBqLZoQ.js → model-config-page-D6cGNnMM.js} +1 -1
- package/dist/assets/{navigation-link-Ct6xtnVM.js → navigation-link-BSJEUiwD.js} +1 -1
- package/dist/assets/plus-BRVe5jSJ.js +1 -0
- package/dist/assets/{popover-C2oIpGBF.js → popover-Bp9IpE_N.js} +1 -1
- package/dist/assets/provider-scoped-model-input-dk7fz9NL.js +1 -0
- package/dist/assets/{providers-config-page-BAVPJKpx.js → providers-config-page-DTP2YfxA.js} +1 -1
- package/dist/assets/react-D6ShNq95.js +8 -0
- package/dist/assets/{refresh-cw-BZ8giusN.js → refresh-cw-C2e94pmp.js} +1 -1
- package/dist/assets/remote-FllhXW3o.js +1 -0
- package/dist/assets/rotate-cw-CTC-Qszi.js +1 -0
- package/dist/assets/runtime-config-page-C57OLdPm.js +1 -0
- package/dist/assets/{save-CSzFGRse.js → save-CkwDOgvt.js} +1 -1
- package/dist/assets/{search-BmSWsiG2.js → search-CLXM2reO.js} +1 -1
- package/dist/assets/{search-config-page-CrL1pUzy.js → search-config-page-tnJXaaSr.js} +1 -1
- package/dist/assets/{secrets-config-page-BlgsD0-L.js → secrets-config-page-DQ_Curaj.js} +1 -1
- package/dist/assets/security-config-S00DjFfO.js +1 -0
- package/dist/assets/{select-CklWb6Rs.js → select-CNFBf00l.js} +1 -1
- package/dist/assets/{settings-2-BSZf8327.js → settings-2-B9IT2HGd.js} +1 -1
- package/dist/assets/skeleton-Dc06gatK.js +1 -0
- package/dist/assets/{tabs-Cah5klko.js → tabs-BuNr8LSO.js} +1 -1
- package/dist/assets/{tag-chip-DcrirDgN.js → tag-chip-CDkB5smU.js} +1 -1
- package/dist/assets/{trash-2-BLQOULWD.js → trash-2-GchaJuEM.js} +1 -1
- package/dist/assets/{use-config-CuFIsUVG.js → use-config-C69rR15i.js} +1 -1
- package/dist/assets/use-confirm-dialog-DF_EgPYx.js +1 -0
- package/dist/assets/{use-viewport-layout-DU29bUJS.js → use-viewport-layout-BACNZyMY.js} +1 -1
- package/dist/assets/x-BXFquY9e.js +1 -0
- package/dist/index.html +28 -28
- package/package.json +9 -9
- package/src/app/components/__tests__/app-notification-runtime.test.tsx +32 -0
- package/src/app/components/app-notification-runtime.tsx +15 -0
- package/src/app/components/layout/sidebar-items.tsx +23 -9
- package/src/app/configs/app-navigation.config.ts +21 -0
- package/src/app/index.tsx +22 -2
- package/src/app/presenters/app.presenter.ts +8 -0
- package/src/features/chat/components/layout/chat-page-shell.tsx +7 -2
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +12 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-run-queue.test.tsx +28 -0
- package/src/features/chat/features/conversation/hooks/use-session-run-queue.ts +4 -5
- package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +13 -0
- package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +31 -8
- package/src/features/chat/features/input/input-surface-plugins/__tests__/context-reference-plugin.test.ts +79 -9
- package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +16 -4
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +10 -2
- package/src/features/chat/features/input/input-surface-plugins/context-reference-items.utils.ts +240 -0
- package/src/features/chat/features/input/input-surface-plugins/context-reference-plugin.utils.ts +62 -173
- package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +29 -0
- package/src/features/chat/features/input/utils/chat-composer-token-protocol.utils.ts +5 -0
- package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +26 -5
- package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +12 -1
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +9 -5
- package/src/features/chat/index.ts +1 -0
- package/src/features/chat/managers/__tests__/chat-completion-notification.manager.test.ts +177 -0
- package/src/features/chat/managers/chat-completion-notification.manager.ts +146 -0
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +26 -0
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.tsx +29 -2
- package/src/features/chat/pages/ncp-chat-page.tsx +9 -0
- package/src/features/inbox/components/inbox-delivery-content.test.tsx +57 -0
- package/src/features/inbox/components/inbox-delivery-content.tsx +118 -0
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +77 -0
- package/src/features/inbox/components/inbox-reader-dialog.tsx +224 -0
- package/src/features/inbox/components/inbox-runtime.tsx +14 -0
- package/src/features/inbox/hooks/use-inbox-deliveries.ts +14 -0
- package/src/features/inbox/index.ts +7 -0
- package/src/features/inbox/managers/inbox.manager.test.ts +86 -0
- package/src/features/inbox/managers/inbox.manager.ts +178 -0
- package/src/features/inbox/pages/inbox-page.test.ts +28 -0
- package/src/features/inbox/pages/inbox-page.tsx +385 -0
- package/src/features/inbox/stores/inbox.store.ts +23 -0
- package/src/features/notifications/components/__tests__/app-notification-toast.test.tsx +48 -0
- package/src/features/notifications/components/app-notification-toast.tsx +80 -0
- package/src/features/notifications/index.ts +8 -0
- package/src/features/notifications/managers/__tests__/app-notification.manager.test.ts +75 -0
- package/src/features/notifications/managers/app-notification.manager.ts +41 -0
- package/src/platforms/mobile/components/mobile-bottom-nav.tsx +14 -7
- package/src/shared/hooks/use-projects.ts +2 -1
- package/src/shared/lib/i18n/index.ts +4 -0
- package/src/shared/lib/i18n/locales/en-US/chat.json +16 -4
- package/src/shared/lib/i18n/locales/en-US/inbox.json +30 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +16 -4
- package/src/shared/lib/i18n/locales/zh-CN/inbox.json +30 -0
- package/dist/assets/api-O5yEgzBt.js +0 -13
- package/dist/assets/app-presenter-provider-DXTYtH78.js +0 -106
- package/dist/assets/appearance-settings-page-BuGxSvlJ.js +0 -1
- package/dist/assets/card-GkBc-UMw.js +0 -1
- package/dist/assets/chat-page-BKQ89f4s.js +0 -1
- package/dist/assets/config-split-page-CvLXSFSC.js +0 -1
- package/dist/assets/confirm-dialog-BVH7haN0.js +0 -5
- package/dist/assets/desktop-update-config-C9ZUI8UW.js +0 -1
- package/dist/assets/doc-browser-DsVF1DrS.js +0 -1
- package/dist/assets/form-actions-aM9_jSJC.js +0 -1
- package/dist/assets/index-6pHX0DZH.js +0 -2
- package/dist/assets/index-DN6KM7WD.css +0 -1
- package/dist/assets/loader-circle-Dd6jw700.js +0 -1
- package/dist/assets/logo-badge-2-iV1pkr.js +0 -1
- package/dist/assets/mcp-marketplace-page-C-d0RMfg.js +0 -1
- package/dist/assets/plus-CsgeRId8.js +0 -1
- package/dist/assets/provider-scoped-model-input-DDqCdnTU.js +0 -1
- package/dist/assets/react-CeMr9V52.js +0 -8
- package/dist/assets/remote-C-r0SHcz.js +0 -1
- package/dist/assets/rotate-cw-DVdRfMSO.js +0 -1
- package/dist/assets/runtime-config-page-D0244uxJ.js +0 -1
- package/dist/assets/security-config-cDrdpMJW.js +0 -1
- package/dist/assets/skeleton-DG9u1BmA.js +0 -1
- package/dist/assets/use-confirm-dialog-CcySmkWp.js +0 -1
- package/dist/assets/x-BVoeXny1.js +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Link } from "react-router-dom";
|
|
2
|
+
|
|
3
|
+
export type AppNotificationToastProps = {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
href?: string;
|
|
7
|
+
iconSrc?: string;
|
|
8
|
+
ariaLabel?: string;
|
|
9
|
+
onDismiss: () => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const NOTIFICATION_CARD_CLASS =
|
|
13
|
+
"group ml-auto flex min-h-[74px] w-[320px] max-w-[calc(100vw-2rem)] items-center gap-3 rounded-[20px] border border-border/80 bg-background px-[18px] py-3 text-left text-foreground shadow-[0_8px_18px_rgba(0,0,0,0.12),0_2px_5px_rgba(0,0,0,0.06)] transition-colors duration-150 hover:bg-muted/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background active:bg-muted/20 motion-reduce:transition-none";
|
|
14
|
+
|
|
15
|
+
function AppNotificationContent({
|
|
16
|
+
title,
|
|
17
|
+
description,
|
|
18
|
+
iconSrc,
|
|
19
|
+
}: Pick<AppNotificationToastProps, "title" | "description" | "iconSrc">) {
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md border border-border/80 bg-background p-[3px]">
|
|
23
|
+
<img
|
|
24
|
+
aria-hidden="true"
|
|
25
|
+
alt=""
|
|
26
|
+
src={iconSrc ?? "/logo.svg"}
|
|
27
|
+
className="h-full w-full object-contain"
|
|
28
|
+
/>
|
|
29
|
+
</span>
|
|
30
|
+
<span className="min-w-0 flex-1">
|
|
31
|
+
<span className="block truncate text-[15px] font-semibold leading-5 tracking-[-0.01em]">
|
|
32
|
+
{title}
|
|
33
|
+
</span>
|
|
34
|
+
{description ? (
|
|
35
|
+
<span className="mt-0.5 block truncate text-[14px] leading-5 text-muted-foreground">
|
|
36
|
+
{description}
|
|
37
|
+
</span>
|
|
38
|
+
) : null}
|
|
39
|
+
</span>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function AppNotificationToast({
|
|
45
|
+
title,
|
|
46
|
+
description,
|
|
47
|
+
href,
|
|
48
|
+
iconSrc,
|
|
49
|
+
ariaLabel,
|
|
50
|
+
onDismiss,
|
|
51
|
+
}: AppNotificationToastProps) {
|
|
52
|
+
const accessibleLabel = ariaLabel ?? [title, description].filter(Boolean).join(": ");
|
|
53
|
+
|
|
54
|
+
if (href) {
|
|
55
|
+
return (
|
|
56
|
+
<Link
|
|
57
|
+
to={href}
|
|
58
|
+
aria-label={accessibleLabel}
|
|
59
|
+
className={NOTIFICATION_CARD_CLASS}
|
|
60
|
+
onClick={onDismiss}
|
|
61
|
+
>
|
|
62
|
+
<AppNotificationContent
|
|
63
|
+
title={title}
|
|
64
|
+
description={description}
|
|
65
|
+
iconSrc={iconSrc}
|
|
66
|
+
/>
|
|
67
|
+
</Link>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div role="status" aria-label={accessibleLabel} className={NOTIFICATION_CARD_CLASS}>
|
|
73
|
+
<AppNotificationContent
|
|
74
|
+
title={title}
|
|
75
|
+
description={description}
|
|
76
|
+
iconSrc={iconSrc}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import {
|
|
4
|
+
AppNotificationManager,
|
|
5
|
+
AppNotificationToast,
|
|
6
|
+
type AppNotificationToastProps,
|
|
7
|
+
} from "@/features/notifications";
|
|
8
|
+
|
|
9
|
+
const mocks = vi.hoisted(() => ({
|
|
10
|
+
custom: vi.fn(),
|
|
11
|
+
dismiss: vi.fn(),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
vi.mock("sonner", () => ({
|
|
15
|
+
toast: {
|
|
16
|
+
custom: mocks.custom,
|
|
17
|
+
dismiss: mocks.dismiss,
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
describe("AppNotificationManager", () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
mocks.custom.mockReset();
|
|
24
|
+
mocks.dismiss.mockReset();
|
|
25
|
+
mocks.custom.mockReturnValue("toast-result");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("uses the shared custom notification surface and stable lifecycle defaults", () => {
|
|
29
|
+
const manager = new AppNotificationManager();
|
|
30
|
+
const result = manager.show({
|
|
31
|
+
id: "reply:message-1",
|
|
32
|
+
title: "Research complete",
|
|
33
|
+
description: "The findings are ready.",
|
|
34
|
+
href: "/chat/session-1",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(result).toBe("toast-result");
|
|
38
|
+
expect(mocks.custom).toHaveBeenCalledWith(expect.any(Function), {
|
|
39
|
+
id: "reply:message-1",
|
|
40
|
+
duration: 8_000,
|
|
41
|
+
unstyled: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const renderer = mocks.custom.mock.calls[0]?.[0] as (
|
|
45
|
+
id: string | number,
|
|
46
|
+
) => unknown;
|
|
47
|
+
const element = renderer("toast-rendered");
|
|
48
|
+
expect(isValidElement<AppNotificationToastProps>(element)).toBe(true);
|
|
49
|
+
if (!isValidElement<AppNotificationToastProps>(element)) {
|
|
50
|
+
throw new Error("Expected AppNotificationToast element");
|
|
51
|
+
}
|
|
52
|
+
expect(element.type).toBe(AppNotificationToast);
|
|
53
|
+
expect(element.props).toEqual(expect.objectContaining({
|
|
54
|
+
title: "Research complete",
|
|
55
|
+
description: "The findings are ready.",
|
|
56
|
+
href: "/chat/session-1",
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
element.props.onDismiss();
|
|
60
|
+
expect(mocks.dismiss).toHaveBeenCalledWith("toast-rendered");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("supports a caller-owned duration and explicit dismiss", () => {
|
|
64
|
+
const manager = new AppNotificationManager();
|
|
65
|
+
manager.show({ title: "Saved", durationMs: 2_500 });
|
|
66
|
+
manager.dismiss("saved-toast");
|
|
67
|
+
|
|
68
|
+
expect(mocks.custom).toHaveBeenCalledWith(expect.any(Function), {
|
|
69
|
+
id: undefined,
|
|
70
|
+
duration: 2_500,
|
|
71
|
+
unstyled: true,
|
|
72
|
+
});
|
|
73
|
+
expect(mocks.dismiss).toHaveBeenCalledWith("saved-toast");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createElement } from "react";
|
|
2
|
+
import { toast } from "sonner";
|
|
3
|
+
import { AppNotificationToast } from "@/features/notifications/components/app-notification-toast";
|
|
4
|
+
|
|
5
|
+
export type AppNotification = {
|
|
6
|
+
id?: string | number;
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
href?: string;
|
|
10
|
+
iconSrc?: string;
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
durationMs?: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const DEFAULT_NOTIFICATION_DURATION_MS = 8_000;
|
|
16
|
+
|
|
17
|
+
export class AppNotificationManager {
|
|
18
|
+
show = (notification: AppNotification): string | number =>
|
|
19
|
+
toast.custom(
|
|
20
|
+
(toastId) =>
|
|
21
|
+
createElement(AppNotificationToast, {
|
|
22
|
+
title: notification.title,
|
|
23
|
+
description: notification.description,
|
|
24
|
+
href: notification.href,
|
|
25
|
+
iconSrc: notification.iconSrc,
|
|
26
|
+
ariaLabel: notification.ariaLabel,
|
|
27
|
+
onDismiss: () => {
|
|
28
|
+
toast.dismiss(toastId);
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
{
|
|
32
|
+
id: notification.id,
|
|
33
|
+
duration: notification.durationMs ?? DEFAULT_NOTIFICATION_DURATION_MS,
|
|
34
|
+
unstyled: true,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
dismiss = (id: string | number): void => {
|
|
39
|
+
toast.dismiss(id);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
matchesRouteTarget,
|
|
7
7
|
} from "@/app/configs/app-navigation.config";
|
|
8
8
|
import { openApps } from "@/features/panel-apps";
|
|
9
|
+
import { useInboxUnreadCount } from "@/features/inbox";
|
|
9
10
|
import { useDocBrowser } from "@/shared/components/doc-browser";
|
|
10
11
|
import { t } from "@/shared/lib/i18n";
|
|
11
12
|
import { cn } from "@/shared/lib/utils";
|
|
@@ -13,6 +14,7 @@ import { cn } from "@/shared/lib/utils";
|
|
|
13
14
|
export function MobileBottomNav() {
|
|
14
15
|
const { pathname } = useLocation();
|
|
15
16
|
const docBrowser = useDocBrowser();
|
|
17
|
+
const unreadCount = useInboxUnreadCount();
|
|
16
18
|
|
|
17
19
|
return (
|
|
18
20
|
<nav
|
|
@@ -23,7 +25,7 @@ export function MobileBottomNav() {
|
|
|
23
25
|
paddingBottom: "calc(env(safe-area-inset-bottom, 0px) + 0.25rem)",
|
|
24
26
|
}}
|
|
25
27
|
>
|
|
26
|
-
<ul className="grid grid-cols-
|
|
28
|
+
<ul className="grid grid-cols-6 gap-1 px-2 pt-1">
|
|
27
29
|
{getMobileBottomNavItems(t).map((item) => {
|
|
28
30
|
const active = item.target === "/settings"
|
|
29
31
|
? isSettingsRoute(pathname)
|
|
@@ -41,12 +43,17 @@ export function MobileBottomNav() {
|
|
|
41
43
|
: "text-gray-500 hover:bg-gray-50 hover:text-gray-800",
|
|
42
44
|
)}
|
|
43
45
|
>
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
<span className="relative">
|
|
47
|
+
<item.icon
|
|
48
|
+
className={cn(
|
|
49
|
+
"h-3.5 w-3.5",
|
|
50
|
+
active ? "text-gray-900" : "text-gray-400",
|
|
51
|
+
)}
|
|
52
|
+
/>
|
|
53
|
+
{item.target === "/inbox" && unreadCount > 0 ? (
|
|
54
|
+
<span className="absolute -right-1 -top-1 h-1.5 w-1.5 rounded-full bg-primary ring-1 ring-white" />
|
|
55
|
+
) : null}
|
|
56
|
+
</span>
|
|
50
57
|
<span className="max-w-full truncate">{item.label}</span>
|
|
51
58
|
</Link>
|
|
52
59
|
</li>
|
|
@@ -5,10 +5,11 @@ import { t } from "@/shared/lib/i18n";
|
|
|
5
5
|
|
|
6
6
|
const PROJECTS_QUERY_KEY = ["projects"] as const;
|
|
7
7
|
|
|
8
|
-
export function useProjects() {
|
|
8
|
+
export function useProjects(options: { enabled?: boolean } = {}) {
|
|
9
9
|
return useQuery({
|
|
10
10
|
queryKey: PROJECTS_QUERY_KEY,
|
|
11
11
|
queryFn: fetchProjects,
|
|
12
|
+
enabled: options.enabled ?? true,
|
|
12
13
|
staleTime: 30_000,
|
|
13
14
|
});
|
|
14
15
|
}
|
|
@@ -7,6 +7,7 @@ import zhCron from './locales/zh-CN/cron.json';
|
|
|
7
7
|
import zhDesktopUpdate from './locales/zh-CN/desktop-update.json';
|
|
8
8
|
import zhDocBrowser from './locales/zh-CN/doc-browser.json';
|
|
9
9
|
import zhMarketplace from './locales/zh-CN/marketplace.json';
|
|
10
|
+
import zhInbox from './locales/zh-CN/inbox.json';
|
|
10
11
|
import zhPathPicker from './locales/zh-CN/path-picker.json';
|
|
11
12
|
import zhPwa from './locales/zh-CN/pwa.json';
|
|
12
13
|
import zhRemote from './locales/zh-CN/remote.json';
|
|
@@ -21,6 +22,7 @@ import enCron from './locales/en-US/cron.json';
|
|
|
21
22
|
import enDesktopUpdate from './locales/en-US/desktop-update.json';
|
|
22
23
|
import enDocBrowser from './locales/en-US/doc-browser.json';
|
|
23
24
|
import enMarketplace from './locales/en-US/marketplace.json';
|
|
25
|
+
import enInbox from './locales/en-US/inbox.json';
|
|
24
26
|
import enPathPicker from './locales/en-US/path-picker.json';
|
|
25
27
|
import enPwa from './locales/en-US/pwa.json';
|
|
26
28
|
import enRemote from './locales/en-US/remote.json';
|
|
@@ -54,6 +56,7 @@ const zhCatalog: MessageCatalog = {
|
|
|
54
56
|
...zhChat,
|
|
55
57
|
...zhAgents,
|
|
56
58
|
...zhMarketplace,
|
|
59
|
+
...zhInbox,
|
|
57
60
|
...zhDocBrowser,
|
|
58
61
|
...zhPathPicker,
|
|
59
62
|
...zhPwa,
|
|
@@ -71,6 +74,7 @@ const enCatalog: MessageCatalog = {
|
|
|
71
74
|
...enChat,
|
|
72
75
|
...enAgents,
|
|
73
76
|
...enMarketplace,
|
|
77
|
+
...enInbox,
|
|
74
78
|
...enDocBrowser,
|
|
75
79
|
...enPathPicker,
|
|
76
80
|
...enPwa,
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"chatProcessSummaryCancelled": "cancelled",
|
|
201
201
|
"chatRuntimeInitializing": "Chat is still initializing. You can keep typing and send once startup finishes.",
|
|
202
202
|
"chatRuntimeInitializationFailed": "Chat startup failed. Please retry in a moment or inspect the service logs.",
|
|
203
|
-
"chatInputPlaceholder": "Type a message, / for commands, apps or skills, @ for files, folders or panel apps, Enter to send, Shift + Enter for newline",
|
|
203
|
+
"chatInputPlaceholder": "Type a message, / for commands, apps or skills, @ for files, folders, projects or panel apps, Enter to send, Shift + Enter for newline",
|
|
204
204
|
"chatInputPlaceholderCompact": "Message NextClaw...",
|
|
205
205
|
"chatInputHint": "Multi-turn context is preserved in the current session.",
|
|
206
206
|
"chatSlashSection": "Slash menu",
|
|
@@ -239,15 +239,15 @@
|
|
|
239
239
|
"chatPanelAppReferenceNoDescription": "No panel app description",
|
|
240
240
|
"chatContextReferenceLoading": "Searching references...",
|
|
241
241
|
"chatContextReferenceSection": "References",
|
|
242
|
-
"chatContextReferenceNoResult": "No matching files, folders, or panel apps",
|
|
243
|
-
"chatContextReferenceHint": "Type @ to reference a file, folder, or panel app",
|
|
242
|
+
"chatContextReferenceNoResult": "No matching files, folders, projects, or panel apps",
|
|
243
|
+
"chatContextReferenceHint": "Type @ to reference a file, folder, project, or panel app",
|
|
244
244
|
"chatContextReferenceItemHint": "Press Enter to add this reference.",
|
|
245
245
|
"chatContextReferenceFilesLabel": "Files & Folders",
|
|
246
246
|
"chatContextReferenceFilesType": "Project Context",
|
|
247
247
|
"chatContextReferenceFilesDescription": "Search and reference files or folders in the current project.",
|
|
248
248
|
"chatContextReferenceFilesHint": "Press Enter to browse files and folders.",
|
|
249
249
|
"chatContextReferenceBack": "Back to all references",
|
|
250
|
-
"chatContextReferenceBackDescription": "Return to the unified file, folder, and panel app reference menu.",
|
|
250
|
+
"chatContextReferenceBackDescription": "Return to the unified file, folder, project, and panel app reference menu.",
|
|
251
251
|
"chatContextReferenceBackHint": "Press Enter to go back.",
|
|
252
252
|
"chatContextReferenceParent": "Up one folder",
|
|
253
253
|
"chatContextReferenceParentDescription": "Browse the parent folder without closing the reference menu.",
|
|
@@ -255,6 +255,15 @@
|
|
|
255
255
|
"chatContextReferenceCurrentDirectory": "Reference current folder",
|
|
256
256
|
"chatContextReferenceFileDescription": "Use this file as explicit context for the current message.",
|
|
257
257
|
"chatContextReferenceDirectoryDescription": "Use this folder as a context scope for the current message.",
|
|
258
|
+
"chatContextReferenceProjectsLabel": "Projects",
|
|
259
|
+
"chatContextReferenceProjectsType": "Project Context",
|
|
260
|
+
"chatContextReferenceProjectsDescription": "Choose a registered project as context for the current message.",
|
|
261
|
+
"chatContextReferenceProjectsHint": "Press Enter to browse projects.",
|
|
262
|
+
"chatContextReferenceProjectType": "Project",
|
|
263
|
+
"chatContextReferenceProjectDescription": "Use this project's name, path, and directory outline as explicit context for the current message.",
|
|
264
|
+
"chatContextReferenceProjectPath": "Project path",
|
|
265
|
+
"chatContextReferenceProjectSection": "Projects",
|
|
266
|
+
"chatContextReferenceProjectsLoadFailed": "Failed to load projects",
|
|
258
267
|
"chatContextReferenceProjectRoot": "Project directory",
|
|
259
268
|
"chatContextReferenceWorkspaceSection": "Files & Folders",
|
|
260
269
|
"chatContextReferenceSearchFailed": "File search failed",
|
|
@@ -410,6 +419,9 @@
|
|
|
410
419
|
"chatSidebarExpandProject": "Expand project",
|
|
411
420
|
"chatSidebarCollapseProject": "Collapse project",
|
|
412
421
|
"chatSidebarProjectViewEmpty": "No projects yet",
|
|
422
|
+
"chatBackgroundReplyFallbackTitle": "New reply",
|
|
423
|
+
"chatBackgroundReplyFallbackPreview": "A reply is ready. Open the session to view it.",
|
|
424
|
+
"chatBackgroundReplyOpenAriaLabel": "Open the new reply in {title}",
|
|
413
425
|
"chatWelcomeTitle": "Hello, how can I help you?",
|
|
414
426
|
"chatWelcomeSubtitle": "Describe the goal, choose the project context, and let NextClaw take it from there.",
|
|
415
427
|
"chatWelcomeProjectPickerLabel": "Choose working directory",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inboxTitle": "Inbox",
|
|
3
|
+
"inboxDescription": "Reports, recommendations, and articles delivered by AI",
|
|
4
|
+
"inboxUnread": "Unread",
|
|
5
|
+
"inboxAll": "All",
|
|
6
|
+
"inboxArchived": "Archived",
|
|
7
|
+
"inboxEmptyTitle": "Nothing here yet",
|
|
8
|
+
"inboxEmptyDescription": "Reports, recommendations, and articles from AI will be saved here.",
|
|
9
|
+
"inboxSelectTitle": "Select something to read",
|
|
10
|
+
"inboxSelectDescription": "Open an item from the list and its reading state will stay in sync.",
|
|
11
|
+
"inboxDeliveredBy": "Delivered by AI",
|
|
12
|
+
"inboxReaderPosition": "{current} of {total}",
|
|
13
|
+
"inboxPrevious": "Previous",
|
|
14
|
+
"inboxNext": "Next",
|
|
15
|
+
"inboxOpenInbox": "Open in Inbox",
|
|
16
|
+
"inboxReadLater": "Read later",
|
|
17
|
+
"inboxMarkRead": "Mark as read",
|
|
18
|
+
"inboxMarkUnread": "Mark as unread",
|
|
19
|
+
"inboxArchive": "Archive",
|
|
20
|
+
"inboxRestore": "Restore",
|
|
21
|
+
"inboxDelete": "Delete",
|
|
22
|
+
"inboxContinueChat": "Continue in chat",
|
|
23
|
+
"inboxDeleteTitle": "Delete this item?",
|
|
24
|
+
"inboxDeleteDescription": "It cannot be recovered from Inbox. Any chat already created will remain.",
|
|
25
|
+
"inboxDeleteConfirm": "Delete",
|
|
26
|
+
"inboxLoadError": "Inbox could not be loaded. Try again shortly.",
|
|
27
|
+
"inboxActionError": "The action failed. Please try again.",
|
|
28
|
+
"inboxUnreadCount": "{count} unread",
|
|
29
|
+
"inboxNoSummary": "No summary"
|
|
30
|
+
}
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"chatProcessSummaryCancelled": "已取消",
|
|
201
201
|
"chatRuntimeInitializing": "聊天能力正在初始化。你可以先输入内容,完成后即可发送。",
|
|
202
202
|
"chatRuntimeInitializationFailed": "聊天能力启动失败,请稍后重试或检查服务日志。",
|
|
203
|
-
"chatInputPlaceholder": "输入消息,/ 选命令、应用或技能,@
|
|
203
|
+
"chatInputPlaceholder": "输入消息,/ 选命令、应用或技能,@ 引用文件、目录、项目或面板应用,Enter 发送,Shift + Enter 换行",
|
|
204
204
|
"chatInputPlaceholderCompact": "发消息...",
|
|
205
205
|
"chatInputHint": "支持多轮上下文,默认走当前会话。",
|
|
206
206
|
"chatSlashSection": "斜杠菜单",
|
|
@@ -239,15 +239,15 @@
|
|
|
239
239
|
"chatPanelAppReferenceNoDescription": "暂无面板应用描述",
|
|
240
240
|
"chatContextReferenceLoading": "搜索引用中…",
|
|
241
241
|
"chatContextReferenceSection": "引用",
|
|
242
|
-
"chatContextReferenceNoResult": "
|
|
243
|
-
"chatContextReferenceHint": "输入 @
|
|
242
|
+
"chatContextReferenceNoResult": "没有匹配的文件、目录、项目或面板应用",
|
|
243
|
+
"chatContextReferenceHint": "输入 @ 引用文件、目录、项目或面板应用",
|
|
244
244
|
"chatContextReferenceItemHint": "回车添加这个引用。",
|
|
245
245
|
"chatContextReferenceFilesLabel": "文件与文件夹",
|
|
246
246
|
"chatContextReferenceFilesType": "项目上下文",
|
|
247
247
|
"chatContextReferenceFilesDescription": "搜索并引用当前项目中的文件或目录。",
|
|
248
248
|
"chatContextReferenceFilesHint": "回车进入文件与文件夹。",
|
|
249
249
|
"chatContextReferenceBack": "返回全部引用",
|
|
250
|
-
"chatContextReferenceBackDescription": "
|
|
250
|
+
"chatContextReferenceBackDescription": "返回文件、目录、项目和面板应用的统一引用入口。",
|
|
251
251
|
"chatContextReferenceBackHint": "回车返回。",
|
|
252
252
|
"chatContextReferenceParent": "返回上一级",
|
|
253
253
|
"chatContextReferenceParentDescription": "在不关闭引用菜单的情况下浏览上一级文件夹。",
|
|
@@ -255,6 +255,15 @@
|
|
|
255
255
|
"chatContextReferenceCurrentDirectory": "引用当前文件夹",
|
|
256
256
|
"chatContextReferenceFileDescription": "把这个文件作为本次消息的显式上下文。",
|
|
257
257
|
"chatContextReferenceDirectoryDescription": "把这个目录作为本次消息的上下文范围。",
|
|
258
|
+
"chatContextReferenceProjectsLabel": "项目",
|
|
259
|
+
"chatContextReferenceProjectsType": "项目上下文",
|
|
260
|
+
"chatContextReferenceProjectsDescription": "从已登记项目中选择一个,作为本次消息的上下文。",
|
|
261
|
+
"chatContextReferenceProjectsHint": "回车进入项目列表。",
|
|
262
|
+
"chatContextReferenceProjectType": "项目",
|
|
263
|
+
"chatContextReferenceProjectDescription": "把这个项目的名称、路径和目录概览作为本次消息的显式上下文。",
|
|
264
|
+
"chatContextReferenceProjectPath": "项目路径",
|
|
265
|
+
"chatContextReferenceProjectSection": "项目",
|
|
266
|
+
"chatContextReferenceProjectsLoadFailed": "项目加载失败",
|
|
258
267
|
"chatContextReferenceProjectRoot": "项目目录",
|
|
259
268
|
"chatContextReferenceWorkspaceSection": "文件与文件夹",
|
|
260
269
|
"chatContextReferenceSearchFailed": "文件搜索失败",
|
|
@@ -410,6 +419,9 @@
|
|
|
410
419
|
"chatSidebarExpandProject": "展开项目",
|
|
411
420
|
"chatSidebarCollapseProject": "收起项目",
|
|
412
421
|
"chatSidebarProjectViewEmpty": "还没有项目",
|
|
422
|
+
"chatBackgroundReplyFallbackTitle": "有新回复",
|
|
423
|
+
"chatBackgroundReplyFallbackPreview": "回复已完成,点击查看。",
|
|
424
|
+
"chatBackgroundReplyOpenAriaLabel": "打开“{title}”的新回复",
|
|
413
425
|
"chatWelcomeTitle": "你好,有什么可以帮你的吗?",
|
|
414
426
|
"chatWelcomeSubtitle": "描述目标,选择项目上下文,让 NextClaw 接住这次任务。",
|
|
415
427
|
"chatWelcomeProjectPickerLabel": "选择工作目录",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inboxTitle": "收件箱",
|
|
3
|
+
"inboxDescription": "AI 主动送达的报告、推荐和文章",
|
|
4
|
+
"inboxUnread": "未读",
|
|
5
|
+
"inboxAll": "全部",
|
|
6
|
+
"inboxArchived": "已归档",
|
|
7
|
+
"inboxEmptyTitle": "这里还没有内容",
|
|
8
|
+
"inboxEmptyDescription": "AI 送达的报告、推荐和文章会保存在这里。",
|
|
9
|
+
"inboxSelectTitle": "选择一项开始阅读",
|
|
10
|
+
"inboxSelectDescription": "打开左侧列表中的内容,阅读状态会在这里同步。",
|
|
11
|
+
"inboxDeliveredBy": "由 AI 送达",
|
|
12
|
+
"inboxReaderPosition": "第 {current} 项,共 {total} 项",
|
|
13
|
+
"inboxPrevious": "上一项",
|
|
14
|
+
"inboxNext": "下一项",
|
|
15
|
+
"inboxOpenInbox": "在收件箱中打开",
|
|
16
|
+
"inboxReadLater": "稍后阅读",
|
|
17
|
+
"inboxMarkRead": "标记已读",
|
|
18
|
+
"inboxMarkUnread": "标记未读",
|
|
19
|
+
"inboxArchive": "归档",
|
|
20
|
+
"inboxRestore": "恢复",
|
|
21
|
+
"inboxDelete": "删除",
|
|
22
|
+
"inboxContinueChat": "继续聊",
|
|
23
|
+
"inboxDeleteTitle": "删除这项内容?",
|
|
24
|
+
"inboxDeleteDescription": "删除后将无法从收件箱恢复,但已经创建的会话不会被删除。",
|
|
25
|
+
"inboxDeleteConfirm": "删除",
|
|
26
|
+
"inboxLoadError": "无法加载收件箱,请稍后重试。",
|
|
27
|
+
"inboxActionError": "操作失败,请重试。",
|
|
28
|
+
"inboxUnreadCount": "{count} 项未读",
|
|
29
|
+
"inboxNoSummary": "没有摘要"
|
|
30
|
+
}
|