@nextclaw/ui 0.23.0 → 0.24.0-beta.1
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 +31 -0
- package/dist/assets/api-BqVIq0lF.js +13 -0
- package/dist/assets/{appearance-settings-page-C_AqxSF_.js → appearance-settings-page-CTWn1eAT.js} +1 -1
- package/dist/assets/{book-open-DYRapW_h.js → book-open-o2x7OLiO.js} +1 -1
- package/dist/assets/{channels-list-page-uR-M4Ls8.js → channels-list-page-Bzn-pzyJ.js} +2 -2
- package/dist/assets/{config-split-page-DJDp86Ne.js → config-split-page-CnRbXXlh.js} +1 -1
- package/dist/assets/{confirm-dialog-CHVBMpla.js → confirm-dialog-B_Hbcra2.js} +1 -1
- package/dist/assets/{createLucideIcon-CgM0rnsa.js → createLucideIcon-rwwpqyks.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-phMuNq1B.js → desktop-capabilities-page-C2ayYQTr.js} +1 -1
- package/dist/assets/desktop-update-config-C13czpyL.js +1 -0
- package/dist/assets/{dist-N9zc5bkM.js → dist-BsF3hfOi.js} +1 -1
- package/dist/assets/{dist-BjYvUhPL.js → dist-aNN3iQxV.js} +1 -1
- package/dist/assets/{doc-browser-DwRLokCI.js → doc-browser-D8dIOo9E.js} +1 -1
- package/dist/assets/doc-browser-DcuOOtpP.js +1 -0
- package/dist/assets/{doc-browser-context-BDuypObS.js → doc-browser-context-Dhsit2Ma.js} +1 -1
- package/dist/assets/{extensions-CQKXTqTI.js → extensions-CD6xvKF_.js} +1 -1
- package/dist/assets/{form-actions-CzGmrPAv.js → form-actions-CC4Wz_lL.js} +1 -1
- package/dist/assets/index-BTsbdtv6.js +109 -0
- package/dist/assets/index-Bcfy2kTh.css +1 -0
- package/dist/assets/loader-circle-B6aFbB-8.js +1 -0
- package/dist/assets/mcp-marketplace-page-BtUAypA7.js +1 -0
- package/dist/assets/{mcp-marketplace-page-s9PTnSDT.js → mcp-marketplace-page-r2MmD9xO.js} +1 -1
- package/dist/assets/{model-config-page-CxnCUWRW.js → model-config-page-DboxoT-I.js} +1 -1
- package/dist/assets/{navigation-link-Ci4Z7Phi.js → navigation-link-C_6oj3zz.js} +1 -1
- package/dist/assets/plus-DRsq9Kvs.js +1 -0
- package/dist/assets/privacy-settings-page-C2sDBqhb.js +1 -0
- package/dist/assets/projects-BcPcx-uD.js +1 -0
- package/dist/assets/providers-config-page-CmUFl9RF.js +1 -0
- package/dist/assets/react-BjO9I4WZ.js +8 -0
- package/dist/assets/{refresh-cw-C-3_thgr.js → refresh-cw-DsT2kvXi.js} +1 -1
- package/dist/assets/remote-Ci6x91ES.js +1 -0
- package/dist/assets/{rotate-cw-DSFTq_yu.js → rotate-cw-BCAs6c3R.js} +1 -1
- package/dist/assets/runtime-config-page-cQKNeAjL.js +1 -0
- package/dist/assets/{save-CpPr78_S.js → save-CadRMTMQ.js} +1 -1
- package/dist/assets/{search-msqk2-rd.js → search-B6tB4fzB.js} +1 -1
- package/dist/assets/{search-config-page-D3_qNXbB.js → search-config-page-C8lOIkxn.js} +1 -1
- package/dist/assets/{secrets-config-page-Be4P1E8o.js → secrets-config-page-8clzAag2.js} +2 -2
- package/dist/assets/security-config-DPbM6IVT.js +1 -0
- package/dist/assets/{select-DPKCWajZ.js → select-CO9S_C2C.js} +1 -1
- package/dist/assets/skeleton-IHILNhIW.js +1 -0
- package/dist/assets/{tag-chip-Dc_NcCEe.js → tag-chip-BZKk0UkK.js} +1 -1
- package/dist/assets/x-BuvHIb1d.js +1 -0
- package/dist/index.html +21 -21
- package/package.json +6 -6
- package/src/app/configs/__tests__/app-navigation.config.test.ts +20 -0
- package/src/app/configs/app-navigation.config.ts +10 -0
- package/src/app/index.tsx +8 -1
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +362 -241
- package/src/features/apps/components/app-document-access-section.tsx +187 -0
- package/src/features/apps/components/app-package-card.tsx +150 -275
- package/src/features/apps/hooks/use-app-packages.ts +91 -35
- package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +29 -0
- package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +4 -2
- package/src/features/chat/components/layout/__tests__/chat-page-shell.test.tsx +21 -0
- package/src/features/chat/components/layout/chat-page-shell.tsx +19 -4
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +1 -1
- package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +0 -1
- package/src/features/chat/features/conversation/utils/__tests__/session-message-composer.utils.test.ts +11 -4
- package/src/features/chat/features/conversation/utils/__tests__/session-queued-input.utils.test.ts +0 -1
- package/src/features/chat/features/conversation/utils/session-message-composer.utils.ts +10 -11
- package/src/features/chat/features/input/input-surface-plugins/__tests__/context-reference-plugin.test.ts +1 -0
- package/src/features/chat/features/message/hooks/use-chat-message-actions.tsx +0 -2
- package/src/features/chat/features/runtime/utils/chat-runtime.utils.ts +0 -14
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +70 -22
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +79 -32
- package/src/features/chat/features/session/utils/__tests__/chat-sidebar-session-groups.utils.test.ts +2 -0
- package/src/features/chat/features/session/utils/chat-run-metadata.utils.ts +0 -6
- package/src/features/chat/features/session/utils/chat-sidebar-session-groups.utils.ts +2 -0
- package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +1 -0
- package/src/features/chat/index.ts +5 -1
- package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +27 -0
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +2 -14
- package/src/features/chat/types/chat-run.types.ts +0 -1
- package/src/features/projects/AGENTS.md +7 -0
- package/src/features/projects/components/project-agreement.tsx +92 -0
- package/src/features/projects/components/project-artifacts.test.tsx +77 -0
- package/src/features/projects/components/project-artifacts.tsx +188 -0
- package/src/features/projects/components/project-overview.tsx +81 -0
- package/src/features/projects/components/project-requests.tsx +57 -0
- package/src/features/projects/components/project-runs.tsx +60 -0
- package/src/features/projects/components/project-section.tsx +60 -0
- package/src/features/projects/components/project-skills.tsx +53 -0
- package/src/features/projects/components/work/project-work-item-drawer.test.tsx +65 -0
- package/src/features/projects/components/work/project-work-item-drawer.tsx +367 -0
- package/src/features/projects/components/work/project-work-items.test.tsx +98 -0
- package/src/features/projects/components/work/project-work-items.tsx +199 -0
- package/src/features/projects/components/work/project-work-state-settings.tsx +285 -0
- package/src/features/projects/hooks/use-project-observation.test.tsx +93 -0
- package/src/features/projects/hooks/use-project-observation.ts +115 -0
- package/src/features/projects/hooks/use-project-work.test.tsx +58 -0
- package/src/features/projects/hooks/use-project-work.ts +215 -0
- package/src/features/projects/index.ts +2 -0
- package/src/features/projects/pages/project-home-page.tsx +234 -0
- package/src/features/projects/pages/projects-page.test.tsx +137 -0
- package/src/features/projects/presenters/project-home.presenter.test.ts +74 -0
- package/src/features/projects/presenters/project-home.presenter.ts +55 -0
- package/src/features/projects/utils/project-artifact-view.utils.test.ts +63 -0
- package/src/features/projects/utils/project-artifact-view.utils.ts +62 -0
- package/src/features/projects/utils/project-request-response.utils.test.ts +44 -0
- package/src/features/projects/utils/project-request-response.utils.ts +39 -0
- package/src/shared/lib/i18n/index.ts +6 -2
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +16 -1
- package/src/shared/lib/i18n/locales/en-US/projects.json +149 -0
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +16 -1
- package/src/shared/lib/i18n/locales/zh-CN/projects.json +149 -0
- package/src/shared/lib/ui-document-title/__tests__/ui-document-title.test.ts +6 -0
- package/src/shared/lib/ui-document-title/index.ts +1 -0
- package/dist/assets/api-n96IfCKb.js +0 -13
- package/dist/assets/desktop-update-config-C77hkbor.js +0 -1
- package/dist/assets/doc-browser-JlXVLNRe.js +0 -1
- package/dist/assets/index-CLw9DuCJ.js +0 -109
- package/dist/assets/index-CwCTiMM9.css +0 -1
- package/dist/assets/loader-circle-D9etMT9f.js +0 -1
- package/dist/assets/mcp-marketplace-page-CbWOamyW.js +0 -1
- package/dist/assets/plus-DKGD04AO.js +0 -1
- package/dist/assets/privacy-settings-page-D8HZHHjL.js +0 -1
- package/dist/assets/providers-config-page-C0GIoGxm.js +0 -1
- package/dist/assets/react-CVFx225w.js +0 -8
- package/dist/assets/remote-DvTCSAxQ.js +0 -1
- package/dist/assets/runtime-config-page-VNJZui5f.js +0 -1
- package/dist/assets/security-config-BtcpKIhQ.js +0 -1
- package/dist/assets/skeleton-BsR5rwB7.js +0 -1
- package/dist/assets/x-Dp5GAFmP.js +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ObservedRequest,
|
|
3
|
+
ObservedWorkItem,
|
|
4
|
+
ObservedWorkflow,
|
|
5
|
+
ProjectObservationSnapshot,
|
|
6
|
+
} from "@nextclaw/client-sdk";
|
|
7
|
+
|
|
8
|
+
export type ProjectHomeTab = "overview" | "work" | "artifacts" | "skills" | "agreement";
|
|
9
|
+
export type ProjectWorkView = "list" | "board" | "gantt";
|
|
10
|
+
|
|
11
|
+
export type ProjectBoardColumn = {
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
items: ObservedWorkItem[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function isProjectHomeTab(value: string | undefined): value is ProjectHomeTab {
|
|
18
|
+
return value === "overview" || value === "work" || value === "artifacts" || value === "skills" || value === "agreement";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createProjectBoardColumns(
|
|
22
|
+
workflows: readonly ObservedWorkflow[],
|
|
23
|
+
workItems: readonly ObservedWorkItem[],
|
|
24
|
+
): ProjectBoardColumn[] {
|
|
25
|
+
return workflows.flatMap((workflow) => workflow.stages.map((stage) => ({
|
|
26
|
+
id: `${workflow.id}:${stage.id}`,
|
|
27
|
+
label: stage.label,
|
|
28
|
+
items: workItems.filter((item) => (
|
|
29
|
+
item.workflowId === workflow.id && item.stageId === stage.id
|
|
30
|
+
)),
|
|
31
|
+
})));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getUnstagedWorkItems(
|
|
35
|
+
workItems: readonly ObservedWorkItem[],
|
|
36
|
+
): ObservedWorkItem[] {
|
|
37
|
+
return workItems.filter((item) => !item.workflowId || !item.stageId);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getScheduledWorkItems(
|
|
41
|
+
workItems: readonly ObservedWorkItem[],
|
|
42
|
+
): ObservedWorkItem[] {
|
|
43
|
+
return workItems.filter((item) => item.schedule?.start || item.schedule?.end);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function canReplyToProjectRequest(request: ObservedRequest): boolean {
|
|
47
|
+
return request.status === "open"
|
|
48
|
+
&& request.response === "confirm-reject"
|
|
49
|
+
&& Boolean(request.reference.sessionId)
|
|
50
|
+
&& !request.reply;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getOpenProjectRequests(snapshot: ProjectObservationSnapshot): ObservedRequest[] {
|
|
54
|
+
return snapshot.requests.filter((request) => request.status === "open");
|
|
55
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
formatProjectRelativeTime,
|
|
4
|
+
sortProjectArtifacts,
|
|
5
|
+
} from "./project-artifact-view.utils";
|
|
6
|
+
|
|
7
|
+
const artifacts = [
|
|
8
|
+
{
|
|
9
|
+
id: "older-update",
|
|
10
|
+
path: "docs/designs/older.md",
|
|
11
|
+
categoryId: "designs",
|
|
12
|
+
categoryLabel: "Designs",
|
|
13
|
+
exists: true,
|
|
14
|
+
fileCreatedAt: "2026-08-01T00:00:00.000Z",
|
|
15
|
+
fileUpdatedAt: "2026-08-28T00:00:00.000Z",
|
|
16
|
+
references: [],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "newer-update",
|
|
20
|
+
path: "docs/designs/newer.md",
|
|
21
|
+
categoryId: "designs",
|
|
22
|
+
categoryLabel: "Designs",
|
|
23
|
+
exists: true,
|
|
24
|
+
fileCreatedAt: "2026-08-29T00:00:00.000Z",
|
|
25
|
+
fileUpdatedAt: "2026-08-30T00:00:00.000Z",
|
|
26
|
+
references: [],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "untimed",
|
|
30
|
+
path: "docs/designs/alpha.md",
|
|
31
|
+
categoryId: "designs",
|
|
32
|
+
categoryLabel: "Designs",
|
|
33
|
+
exists: false,
|
|
34
|
+
references: [],
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
describe("project artifact view", () => {
|
|
39
|
+
it("prioritizes recent updates by default and supports alternate sort orders", () => {
|
|
40
|
+
expect(sortProjectArtifacts(artifacts).map((artifact) => artifact.id)).toEqual([
|
|
41
|
+
"newer-update",
|
|
42
|
+
"older-update",
|
|
43
|
+
"untimed",
|
|
44
|
+
]);
|
|
45
|
+
expect(sortProjectArtifacts(artifacts, "created-desc").map((artifact) => artifact.id)).toEqual([
|
|
46
|
+
"newer-update",
|
|
47
|
+
"older-update",
|
|
48
|
+
"untimed",
|
|
49
|
+
]);
|
|
50
|
+
expect(sortProjectArtifacts(artifacts, "name").map((artifact) => artifact.id)).toEqual([
|
|
51
|
+
"untimed",
|
|
52
|
+
"newer-update",
|
|
53
|
+
"older-update",
|
|
54
|
+
]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("renders recent timestamps in people-friendly language", () => {
|
|
58
|
+
const now = new Date("2026-08-30T12:00:00.000Z");
|
|
59
|
+
expect(formatProjectRelativeTime("2026-08-30T11:57:00.000Z", now)).toBe("3 minutes ago");
|
|
60
|
+
expect(formatProjectRelativeTime("2026-08-30T09:00:00.000Z", now)).toBe("3 hours ago");
|
|
61
|
+
expect(formatProjectRelativeTime("2026-08-29T12:00:00.000Z", now)).toBe("Yesterday");
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ProjectObservationSnapshot } from "@nextclaw/client-sdk";
|
|
2
|
+
import { formatDateShort, t } from "@/shared/lib/i18n";
|
|
3
|
+
|
|
4
|
+
export type ProjectArtifactSort =
|
|
5
|
+
| "updated-desc"
|
|
6
|
+
| "updated-asc"
|
|
7
|
+
| "created-desc"
|
|
8
|
+
| "name";
|
|
9
|
+
|
|
10
|
+
export const DEFAULT_PROJECT_ARTIFACT_SORT: ProjectArtifactSort = "updated-desc";
|
|
11
|
+
|
|
12
|
+
function timestamp(value?: string): number {
|
|
13
|
+
if (!value) return Number.NEGATIVE_INFINITY;
|
|
14
|
+
const parsed = new Date(value).getTime();
|
|
15
|
+
return Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function byName(
|
|
19
|
+
left: ProjectObservationSnapshot["artifacts"][number],
|
|
20
|
+
right: ProjectObservationSnapshot["artifacts"][number],
|
|
21
|
+
): number {
|
|
22
|
+
return left.path.localeCompare(right.path);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function sortProjectArtifacts(
|
|
26
|
+
artifacts: ProjectObservationSnapshot["artifacts"],
|
|
27
|
+
sort: ProjectArtifactSort = DEFAULT_PROJECT_ARTIFACT_SORT,
|
|
28
|
+
): ProjectObservationSnapshot["artifacts"] {
|
|
29
|
+
return [...artifacts].sort((left, right) => {
|
|
30
|
+
if (sort === "name") return byName(left, right);
|
|
31
|
+
const leftTimestamp = timestamp(
|
|
32
|
+
sort === "created-desc"
|
|
33
|
+
? left.fileCreatedAt ?? left.fileUpdatedAt
|
|
34
|
+
: left.fileUpdatedAt ?? left.fileCreatedAt,
|
|
35
|
+
);
|
|
36
|
+
const rightTimestamp = timestamp(
|
|
37
|
+
sort === "created-desc"
|
|
38
|
+
? right.fileCreatedAt ?? right.fileUpdatedAt
|
|
39
|
+
: right.fileUpdatedAt ?? right.fileCreatedAt,
|
|
40
|
+
);
|
|
41
|
+
const order = sort === "updated-asc"
|
|
42
|
+
? leftTimestamp - rightTimestamp
|
|
43
|
+
: rightTimestamp - leftTimestamp;
|
|
44
|
+
return order || byName(left, right);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function formatProjectRelativeTime(value?: string, now: Date = new Date()): string {
|
|
49
|
+
if (!value) return "-";
|
|
50
|
+
const date = new Date(value);
|
|
51
|
+
const differenceMs = now.getTime() - date.getTime();
|
|
52
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
53
|
+
if (differenceMs < 60_000) return t("projectsTimeJustNow");
|
|
54
|
+
const minutes = Math.floor(differenceMs / 60_000);
|
|
55
|
+
if (minutes < 60) return t("projectsTimeMinutesAgo").replace("{count}", String(minutes));
|
|
56
|
+
const hours = Math.floor(minutes / 60);
|
|
57
|
+
if (hours < 24) return t("projectsTimeHoursAgo").replace("{count}", String(hours));
|
|
58
|
+
const days = Math.floor(hours / 24);
|
|
59
|
+
if (days === 1) return t("projectsTimeYesterday");
|
|
60
|
+
if (days < 7) return t("projectsTimeDaysAgo").replace("{count}", String(days));
|
|
61
|
+
return formatDateShort(value);
|
|
62
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { nextclawClient } from "@/shared/lib/api";
|
|
3
|
+
import { sendProjectRequestResponse } from "./project-request-response.utils";
|
|
4
|
+
|
|
5
|
+
vi.mock("@/shared/lib/api", () => ({
|
|
6
|
+
nextclawClient: { agentRuns: { send: vi.fn() } },
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe("sendProjectRequestResponse", () => {
|
|
10
|
+
beforeEach(() => vi.mocked(nextclawClient.agentRuns.send).mockReset());
|
|
11
|
+
|
|
12
|
+
it("sends a stable, traceable reply through the existing agent-run ingress", async () => {
|
|
13
|
+
vi.mocked(nextclawClient.agentRuns.send).mockResolvedValue({
|
|
14
|
+
delivery: "queued",
|
|
15
|
+
runId: null,
|
|
16
|
+
sessionId: "session-1",
|
|
17
|
+
userMessageId: "project-response-approve-release-confirmed",
|
|
18
|
+
assistantMessageId: null,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await sendProjectRequestResponse({
|
|
22
|
+
requestId: "approve-release",
|
|
23
|
+
sessionId: "session-1",
|
|
24
|
+
decision: "confirmed",
|
|
25
|
+
prompt: "继续发布 v1",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(nextclawClient.agentRuns.send).toHaveBeenCalledWith(expect.objectContaining({
|
|
29
|
+
sessionId: "session-1",
|
|
30
|
+
idempotencyKey: "project-response-approve-release-confirmed",
|
|
31
|
+
delivery: "prefer-steer",
|
|
32
|
+
message: expect.objectContaining({
|
|
33
|
+
id: "project-response-approve-release-confirmed",
|
|
34
|
+
metadata: {
|
|
35
|
+
project_observation_response: {
|
|
36
|
+
protocol: "nextclaw.project/v1",
|
|
37
|
+
requestId: "approve-release",
|
|
38
|
+
decision: "confirmed",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
}));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { nextclawClient } from "@/shared/lib/api";
|
|
2
|
+
|
|
3
|
+
export type ProjectRequestDecision = "confirmed" | "rejected";
|
|
4
|
+
|
|
5
|
+
export type SendProjectRequestResponseInput = {
|
|
6
|
+
requestId: string;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
decision: ProjectRequestDecision;
|
|
9
|
+
prompt: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export async function sendProjectRequestResponse(
|
|
13
|
+
input: SendProjectRequestResponseInput,
|
|
14
|
+
) {
|
|
15
|
+
const messageId = `project-response-${input.requestId}-${input.decision}`;
|
|
16
|
+
return await nextclawClient.agentRuns.send({
|
|
17
|
+
sessionId: input.sessionId,
|
|
18
|
+
idempotencyKey: messageId,
|
|
19
|
+
delivery: "prefer-steer",
|
|
20
|
+
message: {
|
|
21
|
+
id: messageId,
|
|
22
|
+
sessionId: input.sessionId,
|
|
23
|
+
role: "user",
|
|
24
|
+
status: "final",
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
parts: [{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: `${input.decision === "confirmed" ? "确认" : "拒绝"}:${input.prompt}`,
|
|
29
|
+
}],
|
|
30
|
+
metadata: {
|
|
31
|
+
project_observation_response: {
|
|
32
|
+
protocol: "nextclaw.project/v1",
|
|
33
|
+
requestId: input.requestId,
|
|
34
|
+
decision: input.decision,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -10,6 +10,7 @@ import zhMarketplace from './locales/zh-CN/marketplace.json';
|
|
|
10
10
|
import zhInbox from './locales/zh-CN/inbox.json';
|
|
11
11
|
import zhPathPicker from './locales/zh-CN/path-picker.json';
|
|
12
12
|
import zhPwa from './locales/zh-CN/pwa.json';
|
|
13
|
+
import zhProjects from './locales/zh-CN/projects.json';
|
|
13
14
|
import zhRemote from './locales/zh-CN/remote.json';
|
|
14
15
|
import zhRuntimeControl from './locales/zh-CN/runtime-control.json';
|
|
15
16
|
import zhSearch from './locales/zh-CN/search.json';
|
|
@@ -25,6 +26,7 @@ import enMarketplace from './locales/en-US/marketplace.json';
|
|
|
25
26
|
import enInbox from './locales/en-US/inbox.json';
|
|
26
27
|
import enPathPicker from './locales/en-US/path-picker.json';
|
|
27
28
|
import enPwa from './locales/en-US/pwa.json';
|
|
29
|
+
import enProjects from './locales/en-US/projects.json';
|
|
28
30
|
import enRemote from './locales/en-US/remote.json';
|
|
29
31
|
import enRuntimeControl from './locales/en-US/runtime-control.json';
|
|
30
32
|
import enSearch from './locales/en-US/search.json';
|
|
@@ -60,7 +62,8 @@ const zhCatalog: MessageCatalog = {
|
|
|
60
62
|
...zhDocBrowser,
|
|
61
63
|
...zhPathPicker,
|
|
62
64
|
...zhPwa,
|
|
63
|
-
...zhChannelAuth
|
|
65
|
+
...zhChannelAuth,
|
|
66
|
+
...zhProjects
|
|
64
67
|
};
|
|
65
68
|
|
|
66
69
|
const enCatalog: MessageCatalog = {
|
|
@@ -78,7 +81,8 @@ const enCatalog: MessageCatalog = {
|
|
|
78
81
|
...enDocBrowser,
|
|
79
82
|
...enPathPicker,
|
|
80
83
|
...enPwa,
|
|
81
|
-
...enChannelAuth
|
|
84
|
+
...enChannelAuth,
|
|
85
|
+
...enProjects
|
|
82
86
|
};
|
|
83
87
|
|
|
84
88
|
const CATALOGS: Record<I18nLanguage, MessageCatalog> = {
|
|
@@ -251,5 +251,20 @@
|
|
|
251
251
|
"serviceActionAuthorizationRisk": "Risk",
|
|
252
252
|
"serviceActionAuthorizationInput": "Input",
|
|
253
253
|
"serviceActionAuthorizationReject": "Reject",
|
|
254
|
-
"serviceActionAuthorizationAllow": "Allow"
|
|
254
|
+
"serviceActionAuthorizationAllow": "Allow",
|
|
255
|
+
"appPackagesDocumentAccessTitle": "Files and folders",
|
|
256
|
+
"appPackagesDocumentAccessUngranted": "Not granted",
|
|
257
|
+
"appPackagesDocumentAccessUnavailable": "Folder unavailable",
|
|
258
|
+
"appPackagesDocumentAccessRead": "Read only",
|
|
259
|
+
"appPackagesDocumentAccessReadWrite": "Read and write",
|
|
260
|
+
"appPackagesDocumentAccessMode": "Access mode",
|
|
261
|
+
"appPackagesDocumentAccessChoose": "Choose folder",
|
|
262
|
+
"appPackagesDocumentAccessReplace": "Replace",
|
|
263
|
+
"appPackagesDocumentAccessRevoke": "Revoke access",
|
|
264
|
+
"appPackagesDocumentAccessGrant": "Grant this folder",
|
|
265
|
+
"appPackagesDocumentAccessChooseTitle": "Choose a folder on the runtime host",
|
|
266
|
+
"appPackagesDocumentAccessChooseDescription": "Choose the folder this app may access.",
|
|
267
|
+
"appPackagesDocumentAccessPath": "Granted folder",
|
|
268
|
+
"appPackagesDocumentAccessWriteWarning": "Read and write access lets this app modify the original files in this folder. You can revoke it from the app card at any time.",
|
|
269
|
+
"appPackagesDocumentAccessReadHint": "Read-only access lets this app view the folder but not modify files through this mount."
|
|
255
270
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectsTitle": "Projects",
|
|
3
|
+
"projectsOverview": "Overview",
|
|
4
|
+
"projectsWork": "Work items",
|
|
5
|
+
"projectsArtifacts": "Artifacts",
|
|
6
|
+
"projectsSkills": "Skills",
|
|
7
|
+
"projectsSkillsCountSuffix": "skills",
|
|
8
|
+
"projectsAgreement": "Working rules",
|
|
9
|
+
"projectsVisionAndContext": "Vision and context",
|
|
10
|
+
"projectsLoading": "Loading project…",
|
|
11
|
+
"projectsLoadFailed": "Failed to load project",
|
|
12
|
+
"projectsEmpty": "No registered projects",
|
|
13
|
+
"projectsChoose": "Choose a project",
|
|
14
|
+
"projectsAsOf": "Observed at",
|
|
15
|
+
"projectsQuality": "Data quality",
|
|
16
|
+
"projectsQuality_complete": "Complete",
|
|
17
|
+
"projectsQuality_partial": "Partially available",
|
|
18
|
+
"projectsQuality_unavailable": "Unavailable",
|
|
19
|
+
"projectsNoSummary": "This project has no configured summary. Existing sources remain available under Working rules.",
|
|
20
|
+
"projectsObservationSetupTitle": "Set up project observation",
|
|
21
|
+
"projectsObservationSetupDescription": "This project has no observation convention yet. Ask AI to inspect existing materials, recommend a work-item lifecycle and artifact scope, and prepare the project configuration, always-on rule, and project tracking Skill. Nothing is written until you confirm.",
|
|
22
|
+
"projectsObservationSetupAction": "Let AI set up project observation",
|
|
23
|
+
"projectsObservationSetupPrompt": "Follow the built-in project observation setup guidance to establish a durable work-tracking convention for this project. Read the existing materials, then directly propose one editable recommendation containing all three assets: .nextclaw/project.yaml, the minimal always-on section in the root AGENTS.md, and the project-specific .agents/skills/project-work-tracking/SKILL.md. A Workflow describes how one work item progresses; it is not the macro lifecycle of the whole project. Markers must be emitted before a stage starts, never batched at the end. Do not turn this into a long interview; recommend directly when the evidence is sufficient. Write nothing until I confirm, then write and verify all three files together.",
|
|
24
|
+
"projectsNoData": "No observable data",
|
|
25
|
+
"projectsUnavailable": "Currently unavailable",
|
|
26
|
+
"projectsWorkList": "List",
|
|
27
|
+
"projectsWorkBoard": "Board",
|
|
28
|
+
"projectsWorkGantt": "Gantt",
|
|
29
|
+
"projectsWorkViews": "Work item views",
|
|
30
|
+
"projectsWorkDetails": "Work item details",
|
|
31
|
+
"projectsCloseDetails": "Close details",
|
|
32
|
+
"projectsNoWork": "No work items explicitly reported by AI",
|
|
33
|
+
"projectsWorkNeedsSetup": "Set up project observation first so AI can report real progress using this project's workflow.",
|
|
34
|
+
"projectsWorkNoSessions": "No conversation has started in this project yet. Once substantive project work begins, AI-reported progress will appear here.",
|
|
35
|
+
"projectsWorkNoReports": "AI has not explicitly reported any work items from the existing project conversations yet. Real progress will appear here as the work continues.",
|
|
36
|
+
"projectsAiActivity": "AI runs",
|
|
37
|
+
"projectsAiRun": "Project session",
|
|
38
|
+
"projectsRunUnreported": "Work item and stage not reported yet",
|
|
39
|
+
"projectsRunState_running": "Running",
|
|
40
|
+
"projectsRunState_completed": "Finished",
|
|
41
|
+
"projectsRunState_failed": "Failed",
|
|
42
|
+
"projectsRunState_cancelled": "Cancelled",
|
|
43
|
+
"projectsRunState_idle": "Idle",
|
|
44
|
+
"projectsStartProjectWork": "Start project work",
|
|
45
|
+
"projectsStartProjectWorkPrompt": "Start working on this project. First read the project configuration and the materials relevant to this goal; I will add or revise the specific goal before sending.",
|
|
46
|
+
"projectsBoardNeedsWorkflow": "No workflow stages are available. The board does not invent stages.",
|
|
47
|
+
"projectsGanttNeedsSchedule": "No schedule markers are available. The Gantt view does not infer dates from files.",
|
|
48
|
+
"projectsUnstaged": "Stage not reported",
|
|
49
|
+
"projectsStage": "Stage",
|
|
50
|
+
"projectsSchedule": "Schedule",
|
|
51
|
+
"projectsNoArtifacts": "No artifacts matched by configuration or reported by AI",
|
|
52
|
+
"projectsNoSkills": "No project Skills are available",
|
|
53
|
+
"projectsNoContext": "No vision or working-rule sources are configured",
|
|
54
|
+
"projectsRequests": "Waiting for your reply",
|
|
55
|
+
"projectsConfirm": "Confirm",
|
|
56
|
+
"projectsReject": "Reject",
|
|
57
|
+
"projectsResponseSent": "Reply sent; waiting for AI to update",
|
|
58
|
+
"projectsResponseWaiting": "Replied; waiting for AI to update",
|
|
59
|
+
"projectsResponseFailed": "Failed to send reply",
|
|
60
|
+
"projectsActivity": "Recent activity",
|
|
61
|
+
"projectsNoActivity": "No AI-reported activity",
|
|
62
|
+
"projectsOpenSession": "Open source session",
|
|
63
|
+
"projectsAttention": "Needs attention",
|
|
64
|
+
"projectsNoAttention": "No open attention signals",
|
|
65
|
+
"projectsSourceHealth": "Sources and diagnostics",
|
|
66
|
+
"projectsArtifactsCountSuffix": "artifacts",
|
|
67
|
+
"projectsArtifactsSearchPlaceholder": "Search artifacts",
|
|
68
|
+
"projectsArtifactsShowMore": "Show more",
|
|
69
|
+
"projectsArtifactsNoMatches": "No matching artifacts",
|
|
70
|
+
"projectsArtifactsSort": "Sort",
|
|
71
|
+
"projectsArtifactsSortUpdatedDesc": "Recently updated",
|
|
72
|
+
"projectsArtifactsSortUpdatedAsc": "Oldest updated",
|
|
73
|
+
"projectsArtifactsSortCreatedDesc": "Recently created",
|
|
74
|
+
"projectsArtifactsSortName": "File name",
|
|
75
|
+
"projectsTimeJustNow": "Just now",
|
|
76
|
+
"projectsTimeMinutesAgo": "{count} minutes ago",
|
|
77
|
+
"projectsTimeHoursAgo": "{count} hours ago",
|
|
78
|
+
"projectsTimeYesterday": "Yesterday",
|
|
79
|
+
"projectsTimeDaysAgo": "{count} days ago",
|
|
80
|
+
"projectsReadable": "Readable",
|
|
81
|
+
"projectsStatus": "Status",
|
|
82
|
+
"projectsUpdated": "Updated",
|
|
83
|
+
"projectsStatus_active": "Active",
|
|
84
|
+
"projectsStatus_blocked": "Blocked",
|
|
85
|
+
"projectsStatus_completed": "Completed",
|
|
86
|
+
"projectsStatus_cancelled": "Cancelled",
|
|
87
|
+
"projectsSource_available": "Available",
|
|
88
|
+
"projectsSource_empty": "No data",
|
|
89
|
+
"projectsSource_error": "Failed",
|
|
90
|
+
"projectsWorkNewItem": "Add a work item",
|
|
91
|
+
"projectsWorkEmpty": "No work items yet. Add one here or ask AI from a project conversation.",
|
|
92
|
+
"projectsWorkShowDeleted": "Show deleted work items",
|
|
93
|
+
"projectsWorkTitle": "Title",
|
|
94
|
+
"projectsWorkDescription": "Description",
|
|
95
|
+
"projectsWorkAttention": "Attention",
|
|
96
|
+
"projectsWorkAttention_none": "No special attention",
|
|
97
|
+
"projectsWorkAttention_blocked": "Blocked",
|
|
98
|
+
"projectsWorkAttention_awaiting-user": "Waiting for you",
|
|
99
|
+
"projectsWorkVersion": "Version",
|
|
100
|
+
"projectsWorkItemSaved": "Work item saved",
|
|
101
|
+
"projectsWorkItemSaveFailed": "Failed to save work item",
|
|
102
|
+
"projectsWorkItemLoadFailed": "Failed to load work item details",
|
|
103
|
+
"projectsWorkItemCreateFailed": "Failed to create work item",
|
|
104
|
+
"projectsDeleteWorkItem": "Delete work item?",
|
|
105
|
+
"projectsDeleteWorkItemDescription": "The work item will remain available under Show deleted and can be restored.",
|
|
106
|
+
"projectsDeleted": "Deleted",
|
|
107
|
+
"projectsDelete": "Delete",
|
|
108
|
+
"projectsRestore": "Restore",
|
|
109
|
+
"projectsCreate": "Create",
|
|
110
|
+
"projectsAdd": "Add",
|
|
111
|
+
"projectsWorkArtifacts": "Linked artifacts",
|
|
112
|
+
"projectsWorkNoArtifacts": "No artifacts linked",
|
|
113
|
+
"projectsWorkArtifactPath": "Project-relative file path",
|
|
114
|
+
"projectsWorkArtifactLabel": "Optional label",
|
|
115
|
+
"projectsWorkLinkArtifact": "Link",
|
|
116
|
+
"projectsWorkUnlinkArtifact": "Unlink artifact",
|
|
117
|
+
"projectsWorkArtifactLinkFailed": "Failed to link artifact",
|
|
118
|
+
"projectsWorkActionFailed": "Could not update project work",
|
|
119
|
+
"projectsWorkStateSettings": "Work states",
|
|
120
|
+
"projectsWorkStateSettingsDescription": "Customize names and ordering while keeping each state's lifecycle category explicit.",
|
|
121
|
+
"projectsWorkStateName": "State name",
|
|
122
|
+
"projectsWorkStateCategory": "Lifecycle category",
|
|
123
|
+
"projectsWorkDefaultState": "Use for new work items",
|
|
124
|
+
"projectsWorkNewState": "New state name",
|
|
125
|
+
"projectsWorkStateMigration": "Move existing work items to",
|
|
126
|
+
"projectsWorkStateMigrationOptional": "Choose when this state is in use",
|
|
127
|
+
"projectsDeleteState": "Delete state",
|
|
128
|
+
"projectsDeleteStateDescription": "Existing work items must be moved to another state before this state can be deleted.",
|
|
129
|
+
"projectsMoveUp": "Move state up",
|
|
130
|
+
"projectsMoveDown": "Move state down",
|
|
131
|
+
"projectsWorkCategory_backlog": "Backlog",
|
|
132
|
+
"projectsWorkCategory_unstarted": "Not started",
|
|
133
|
+
"projectsWorkCategory_started": "In progress",
|
|
134
|
+
"projectsWorkCategory_completed": "Completed",
|
|
135
|
+
"projectsWorkCategory_canceled": "Canceled",
|
|
136
|
+
"projectsWorkSummary": "Work summary",
|
|
137
|
+
"projectsWorkTotal": "Total",
|
|
138
|
+
"projectsWorkActive": "Active",
|
|
139
|
+
"projectsWorkNeedsAttention": "Needs attention",
|
|
140
|
+
"projectsWorkCompleted": "Completed",
|
|
141
|
+
"projectsWorkRecentlyUpdated": "Recently updated",
|
|
142
|
+
"projectsWorkActivity_created": "Created",
|
|
143
|
+
"projectsWorkActivity_updated": "Updated",
|
|
144
|
+
"projectsWorkActivity_state-changed": "State changed",
|
|
145
|
+
"projectsWorkActivity_deleted": "Deleted",
|
|
146
|
+
"projectsWorkActivity_restored": "Restored",
|
|
147
|
+
"projectsWorkActivity_artifact-linked": "Artifact linked",
|
|
148
|
+
"projectsWorkActivity_artifact-unlinked": "Artifact unlinked"
|
|
149
|
+
}
|
|
@@ -251,5 +251,20 @@
|
|
|
251
251
|
"serviceActionAuthorizationRisk": "风险",
|
|
252
252
|
"serviceActionAuthorizationInput": "输入",
|
|
253
253
|
"serviceActionAuthorizationReject": "拒绝",
|
|
254
|
-
"serviceActionAuthorizationAllow": "允许"
|
|
254
|
+
"serviceActionAuthorizationAllow": "允许",
|
|
255
|
+
"appPackagesDocumentAccessTitle": "文件与文件夹",
|
|
256
|
+
"appPackagesDocumentAccessUngranted": "未授权",
|
|
257
|
+
"appPackagesDocumentAccessUnavailable": "目录不可用",
|
|
258
|
+
"appPackagesDocumentAccessRead": "只读",
|
|
259
|
+
"appPackagesDocumentAccessReadWrite": "读写",
|
|
260
|
+
"appPackagesDocumentAccessMode": "访问模式",
|
|
261
|
+
"appPackagesDocumentAccessChoose": "选择目录",
|
|
262
|
+
"appPackagesDocumentAccessReplace": "替换",
|
|
263
|
+
"appPackagesDocumentAccessRevoke": "撤销访问",
|
|
264
|
+
"appPackagesDocumentAccessGrant": "授权此目录",
|
|
265
|
+
"appPackagesDocumentAccessChooseTitle": "选择运行主机上的目录",
|
|
266
|
+
"appPackagesDocumentAccessChooseDescription": "选择此应用可以访问的目录。",
|
|
267
|
+
"appPackagesDocumentAccessPath": "授权目录",
|
|
268
|
+
"appPackagesDocumentAccessWriteWarning": "读写授权允许应用直接修改这个目录中的原始文件;你可以随时在应用卡片中撤销。",
|
|
269
|
+
"appPackagesDocumentAccessReadHint": "只读授权允许应用查看这个目录,但不能通过此挂载修改文件。"
|
|
255
270
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectsTitle": "项目",
|
|
3
|
+
"projectsOverview": "概览",
|
|
4
|
+
"projectsWork": "工作项",
|
|
5
|
+
"projectsArtifacts": "产物",
|
|
6
|
+
"projectsSkills": "Skills",
|
|
7
|
+
"projectsSkillsCountSuffix": "个 Skills",
|
|
8
|
+
"projectsAgreement": "工作约定",
|
|
9
|
+
"projectsVisionAndContext": "愿景与上下文",
|
|
10
|
+
"projectsLoading": "正在读取项目…",
|
|
11
|
+
"projectsLoadFailed": "项目读取失败",
|
|
12
|
+
"projectsEmpty": "还没有注册项目",
|
|
13
|
+
"projectsChoose": "选择项目",
|
|
14
|
+
"projectsAsOf": "观测时间",
|
|
15
|
+
"projectsQuality": "数据质量",
|
|
16
|
+
"projectsQuality_complete": "完整",
|
|
17
|
+
"projectsQuality_partial": "部分可用",
|
|
18
|
+
"projectsQuality_unavailable": "暂不可用",
|
|
19
|
+
"projectsNoSummary": "项目没有配置摘要,可在工作约定中查看已有来源。",
|
|
20
|
+
"projectsObservationSetupTitle": "建立项目观察",
|
|
21
|
+
"projectsObservationSetupDescription": "项目还没有建立观察约定。让 AI 阅读已有材料,推荐工作项流程和产物范围,并同时准备项目配置、常驻规则与项目追踪 Skill;确认后再统一写入。",
|
|
22
|
+
"projectsObservationSetupAction": "让 AI 帮我建立项目观察",
|
|
23
|
+
"projectsObservationSetupPrompt": "请按内置的项目观察 setup 规范,为当前项目建立可持续生效的工作追踪约定。先读取已有材料,根据项目实际情况直接给出一套可修改的推荐,完整包含:.nextclaw/project.yaml、根 AGENTS.md 的最小常驻规则,以及 .agents/skills/project-work-tracking/SKILL.md 的项目日常追踪方法。Workflow 描述单个工作项如何推进,不是整个项目的宏观阶段。Marker 必须在节点开始前报告,不能在结束时批量补写。不要反复提问;信息足够时直接推荐。未经我确认不要写入,确认后一次写入并复核三份文件。",
|
|
24
|
+
"projectsNoData": "暂无可观测数据",
|
|
25
|
+
"projectsUnavailable": "暂不可用",
|
|
26
|
+
"projectsWorkList": "列表",
|
|
27
|
+
"projectsWorkBoard": "看板",
|
|
28
|
+
"projectsWorkGantt": "甘特图",
|
|
29
|
+
"projectsWorkViews": "工作项视图",
|
|
30
|
+
"projectsWorkDetails": "工作项详情",
|
|
31
|
+
"projectsCloseDetails": "关闭详情",
|
|
32
|
+
"projectsNoWork": "暂无 AI 明确报告的工作项",
|
|
33
|
+
"projectsWorkNeedsSetup": "先建立项目观察配置,AI 才能按这个项目的流程报告真实进展。",
|
|
34
|
+
"projectsWorkNoSessions": "还没有在这个项目中开始会话。开始实际项目工作后,AI 报告的进展会显示在这里。",
|
|
35
|
+
"projectsWorkNoReports": "项目会话中还没有 AI 明确报告的工作项。继续实际工作后,真实进展会显示在这里。",
|
|
36
|
+
"projectsAiActivity": "AI 运行",
|
|
37
|
+
"projectsAiRun": "项目会话",
|
|
38
|
+
"projectsRunUnreported": "尚未报告工作项与阶段",
|
|
39
|
+
"projectsRunState_running": "运行中",
|
|
40
|
+
"projectsRunState_completed": "已结束",
|
|
41
|
+
"projectsRunState_failed": "运行失败",
|
|
42
|
+
"projectsRunState_cancelled": "已中止",
|
|
43
|
+
"projectsRunState_idle": "空闲",
|
|
44
|
+
"projectsStartProjectWork": "开始项目工作",
|
|
45
|
+
"projectsStartProjectWorkPrompt": "请开始处理这个项目。先读取项目配置和与本次目标相关的材料;我会在发送前补充或修改具体目标。",
|
|
46
|
+
"projectsBoardNeedsWorkflow": "没有可用的 Workflow 阶段;看板不会自动生成阶段。",
|
|
47
|
+
"projectsGanttNeedsSchedule": "没有 schedule Marker;甘特图不会从文件时间推断日期。",
|
|
48
|
+
"projectsUnstaged": "未声明阶段",
|
|
49
|
+
"projectsStage": "阶段",
|
|
50
|
+
"projectsSchedule": "计划",
|
|
51
|
+
"projectsNoArtifacts": "暂无配置匹配或 AI 标记的产物",
|
|
52
|
+
"projectsNoSkills": "项目目录中暂无可用 Skills",
|
|
53
|
+
"projectsNoContext": "项目没有配置愿景或工作约定来源",
|
|
54
|
+
"projectsRequests": "等待你回复",
|
|
55
|
+
"projectsConfirm": "确认",
|
|
56
|
+
"projectsReject": "拒绝",
|
|
57
|
+
"projectsResponseSent": "回复已发送,等待 AI 更新",
|
|
58
|
+
"projectsResponseWaiting": "已回复,等待 AI 更新",
|
|
59
|
+
"projectsResponseFailed": "回复发送失败",
|
|
60
|
+
"projectsActivity": "最近动态",
|
|
61
|
+
"projectsNoActivity": "暂无 AI 报告的动态",
|
|
62
|
+
"projectsOpenSession": "打开原会话",
|
|
63
|
+
"projectsAttention": "待关注",
|
|
64
|
+
"projectsNoAttention": "暂无待关注信号",
|
|
65
|
+
"projectsSourceHealth": "来源与诊断",
|
|
66
|
+
"projectsArtifactsCountSuffix": "个产物",
|
|
67
|
+
"projectsArtifactsSearchPlaceholder": "搜索产物",
|
|
68
|
+
"projectsArtifactsShowMore": "显示更多",
|
|
69
|
+
"projectsArtifactsNoMatches": "没有匹配的产物",
|
|
70
|
+
"projectsArtifactsSort": "排序",
|
|
71
|
+
"projectsArtifactsSortUpdatedDesc": "最近更新",
|
|
72
|
+
"projectsArtifactsSortUpdatedAsc": "最早更新",
|
|
73
|
+
"projectsArtifactsSortCreatedDesc": "最近创建",
|
|
74
|
+
"projectsArtifactsSortName": "文件名",
|
|
75
|
+
"projectsTimeJustNow": "刚刚",
|
|
76
|
+
"projectsTimeMinutesAgo": "{count} 分钟前",
|
|
77
|
+
"projectsTimeHoursAgo": "{count} 小时前",
|
|
78
|
+
"projectsTimeYesterday": "昨天",
|
|
79
|
+
"projectsTimeDaysAgo": "{count} 天前",
|
|
80
|
+
"projectsReadable": "可读取",
|
|
81
|
+
"projectsStatus": "状态",
|
|
82
|
+
"projectsUpdated": "更新时间",
|
|
83
|
+
"projectsStatus_active": "进行中",
|
|
84
|
+
"projectsStatus_blocked": "受阻",
|
|
85
|
+
"projectsStatus_completed": "已完成",
|
|
86
|
+
"projectsStatus_cancelled": "已取消",
|
|
87
|
+
"projectsSource_available": "可用",
|
|
88
|
+
"projectsSource_empty": "暂无数据",
|
|
89
|
+
"projectsSource_error": "读取失败",
|
|
90
|
+
"projectsWorkNewItem": "添加工作项",
|
|
91
|
+
"projectsWorkEmpty": "还没有工作项。你可以在这里添加,也可以在项目会话中让 AI 创建。",
|
|
92
|
+
"projectsWorkShowDeleted": "显示已删除的工作项",
|
|
93
|
+
"projectsWorkTitle": "标题",
|
|
94
|
+
"projectsWorkDescription": "说明",
|
|
95
|
+
"projectsWorkAttention": "关注状态",
|
|
96
|
+
"projectsWorkAttention_none": "无需特别关注",
|
|
97
|
+
"projectsWorkAttention_blocked": "受阻",
|
|
98
|
+
"projectsWorkAttention_awaiting-user": "等待你处理",
|
|
99
|
+
"projectsWorkVersion": "版本",
|
|
100
|
+
"projectsWorkItemSaved": "工作项已保存",
|
|
101
|
+
"projectsWorkItemSaveFailed": "工作项保存失败",
|
|
102
|
+
"projectsWorkItemLoadFailed": "工作项详情读取失败",
|
|
103
|
+
"projectsWorkItemCreateFailed": "工作项创建失败",
|
|
104
|
+
"projectsDeleteWorkItem": "删除这个工作项?",
|
|
105
|
+
"projectsDeleteWorkItemDescription": "删除后仍可通过“显示已删除的工作项”找到并恢复。",
|
|
106
|
+
"projectsDeleted": "已删除",
|
|
107
|
+
"projectsDelete": "删除",
|
|
108
|
+
"projectsRestore": "恢复",
|
|
109
|
+
"projectsCreate": "创建",
|
|
110
|
+
"projectsAdd": "添加",
|
|
111
|
+
"projectsWorkArtifacts": "关联产物",
|
|
112
|
+
"projectsWorkNoArtifacts": "还没有关联产物",
|
|
113
|
+
"projectsWorkArtifactPath": "项目内的文件路径",
|
|
114
|
+
"projectsWorkArtifactLabel": "显示名称(可选)",
|
|
115
|
+
"projectsWorkLinkArtifact": "关联",
|
|
116
|
+
"projectsWorkUnlinkArtifact": "解除关联",
|
|
117
|
+
"projectsWorkArtifactLinkFailed": "产物关联失败",
|
|
118
|
+
"projectsWorkActionFailed": "无法更新项目工作项",
|
|
119
|
+
"projectsWorkStateSettings": "工作项状态",
|
|
120
|
+
"projectsWorkStateSettingsDescription": "你可以修改名称和顺序;每个状态仍需归入明确的生命周期类别。",
|
|
121
|
+
"projectsWorkStateName": "状态名称",
|
|
122
|
+
"projectsWorkStateCategory": "生命周期类别",
|
|
123
|
+
"projectsWorkDefaultState": "新工作项默认使用此状态",
|
|
124
|
+
"projectsWorkNewState": "新状态名称",
|
|
125
|
+
"projectsWorkStateMigration": "把已有工作项迁移到",
|
|
126
|
+
"projectsWorkStateMigrationOptional": "状态被使用时必须选择",
|
|
127
|
+
"projectsDeleteState": "删除状态",
|
|
128
|
+
"projectsDeleteStateDescription": "如果已有工作项使用这个状态,需要先把它们迁移到另一个状态。",
|
|
129
|
+
"projectsMoveUp": "上移状态",
|
|
130
|
+
"projectsMoveDown": "下移状态",
|
|
131
|
+
"projectsWorkCategory_backlog": "待整理",
|
|
132
|
+
"projectsWorkCategory_unstarted": "未开始",
|
|
133
|
+
"projectsWorkCategory_started": "推进中",
|
|
134
|
+
"projectsWorkCategory_completed": "已完成",
|
|
135
|
+
"projectsWorkCategory_canceled": "已取消",
|
|
136
|
+
"projectsWorkSummary": "工作项概况",
|
|
137
|
+
"projectsWorkTotal": "全部工作项",
|
|
138
|
+
"projectsWorkActive": "推进中",
|
|
139
|
+
"projectsWorkNeedsAttention": "需要关注",
|
|
140
|
+
"projectsWorkCompleted": "已完成",
|
|
141
|
+
"projectsWorkRecentlyUpdated": "最近更新",
|
|
142
|
+
"projectsWorkActivity_created": "创建了工作项",
|
|
143
|
+
"projectsWorkActivity_updated": "更新了工作项",
|
|
144
|
+
"projectsWorkActivity_state-changed": "切换了状态",
|
|
145
|
+
"projectsWorkActivity_deleted": "删除了工作项",
|
|
146
|
+
"projectsWorkActivity_restored": "恢复了工作项",
|
|
147
|
+
"projectsWorkActivity_artifact-linked": "关联了产物",
|
|
148
|
+
"projectsWorkActivity_artifact-unlinked": "解除了产物关联"
|
|
149
|
+
}
|