@nextclaw/ui 0.13.11 → 0.13.12

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.
Files changed (27) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/assets/{channels-list-page-bkKDqaO5.js → channels-list-page-D-WYFmcG.js} +1 -1
  3. package/dist/assets/{chat-page-YKdeGoVx.js → chat-page-D1X8YNTC.js} +2 -2
  4. package/dist/assets/{desktop-update-config-CLXdVz9r.js → desktop-update-config-DOi5R1fX.js} +1 -1
  5. package/dist/assets/{index-DKflQCOL.js → index-ZDJP_uJc.js} +5 -5
  6. package/dist/assets/mcp-marketplace-page-LmMhKH5a.js +1 -0
  7. package/dist/assets/{mcp-marketplace-page-BaBuHB2L.js → mcp-marketplace-page-RqISBSqO.js} +1 -1
  8. package/dist/assets/{model-config-B-qg70S4.js → model-config-JUsW1Khb.js} +1 -1
  9. package/dist/assets/{provider-scoped-model-input-BgPTQa8H.js → provider-scoped-model-input-IMD4W0jD.js} +1 -1
  10. package/dist/assets/{providers-list-cBeeslbc.js → providers-list-BsDpxNzy.js} +1 -1
  11. package/dist/assets/{runtime-config-page-DYH2ejUI.js → runtime-config-page-DzbTVebD.js} +1 -1
  12. package/dist/assets/{search-config-BRsrQ4zK.js → search-config-CJ6OPxAf.js} +1 -1
  13. package/dist/assets/{secrets-config-eYdx5_AW.js → secrets-config-CYOHWL7P.js} +1 -1
  14. package/dist/index.html +1 -1
  15. package/package.json +8 -8
  16. package/src/features/chat/components/chat-session-workspace-file-preview.test.tsx +39 -0
  17. package/src/features/chat/components/chat-session-workspace-file-preview.tsx +11 -4
  18. package/src/features/chat/components/chat-session-workspace-panel.tsx +3 -0
  19. package/src/features/chat/components/conversation/chat-conversation-panel.test.tsx +4 -0
  20. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +1 -0
  21. package/src/features/chat/hooks/use-ncp-chat-derived-state.ts +2 -0
  22. package/src/features/chat/pages/ncp-chat-page.tsx +4 -0
  23. package/src/features/chat/stores/chat-thread.store.ts +2 -0
  24. package/src/features/chat/utils/ncp-session-adapter.utils.test.ts +21 -0
  25. package/src/features/chat/utils/ncp-session-adapter.utils.ts +6 -0
  26. package/src/shared/lib/api/ncp-session.types.ts +1 -0
  27. package/dist/assets/mcp-marketplace-page-ooEvG_bB.js +0 -1
@@ -43,6 +43,7 @@ type ChatSessionWorkspacePanelProps = {
43
43
  activePanelKind?: "child-session" | "file" | "cron" | null;
44
44
  sessionCronJobs?: readonly CronJobView[];
45
45
  sessionProjectRoot: string | null;
46
+ sessionWorkingDir: string | null;
46
47
  displayMode?: "docked" | "overlay";
47
48
  };
48
49
 
@@ -249,6 +250,7 @@ export function ChatSessionWorkspacePanel({
249
250
  activePanelKind,
250
251
  sessionCronJobs = [],
251
252
  sessionProjectRoot,
253
+ sessionWorkingDir,
252
254
  displayMode = "docked",
253
255
  }: ChatSessionWorkspacePanelProps) {
254
256
  const presenter = usePresenter();
@@ -357,6 +359,7 @@ export function ChatSessionWorkspacePanel({
357
359
  <ChatSessionWorkspaceFilePreview
358
360
  file={activeSelection.file}
359
361
  sessionProjectRoot={sessionProjectRoot}
362
+ sessionWorkingDir={sessionWorkingDir}
360
363
  onFileOpen={presenter.chatThreadManager.openFilePreview}
361
364
  />
362
365
  ) : (
@@ -552,6 +552,7 @@ describe("ChatSessionWorkspacePanel", () => {
552
552
  workspaceFileTabs={[]}
553
553
  activeWorkspaceFileKey={null}
554
554
  sessionProjectRoot="/Users/demo/project-alpha"
555
+ sessionWorkingDir="/Users/demo/project-alpha"
555
556
  />,
556
557
  );
557
558
 
@@ -622,6 +623,7 @@ describe("ChatSessionWorkspacePanel", () => {
622
623
  workspaceFileTabs={[]}
623
624
  activeWorkspaceFileKey={null}
624
625
  sessionProjectRoot="/Users/demo/project-alpha"
626
+ sessionWorkingDir="/Users/demo/project-alpha"
625
627
  />,
626
628
  );
627
629
 
@@ -645,6 +647,7 @@ describe("ChatSessionWorkspacePanel", () => {
645
647
  ]}
646
648
  activeWorkspaceFileKey="parent-session-1::preview::README.md"
647
649
  sessionProjectRoot="/Users/demo/project-alpha"
650
+ sessionWorkingDir="/Users/demo/project-alpha"
648
651
  />,
649
652
  );
650
653
 
@@ -691,6 +694,7 @@ describe("ChatSessionWorkspacePanel", () => {
691
694
  activePanelKind="cron"
692
695
  sessionCronJobs={[job]}
693
696
  sessionProjectRoot="/Users/demo/project-alpha"
697
+ sessionWorkingDir="/Users/demo/project-alpha"
694
698
  />,
695
699
  );
696
700
 
@@ -366,6 +366,7 @@ function ChatSessionWorkspacePanelContainer({
366
366
  activePanelKind={snapshot.activeWorkspacePanelKind ?? null}
367
367
  sessionCronJobs={sessionCronJobs}
368
368
  sessionProjectRoot={snapshot.sessionProjectRoot ?? null}
369
+ sessionWorkingDir={snapshot.sessionWorkingDir ?? snapshot.sessionProjectRoot ?? null}
369
370
  displayMode={layoutMode === "mobile" ? "overlay" : "docked"}
370
371
  />
371
372
  );
@@ -119,6 +119,7 @@ export function useNcpChatSnapshotSync(params: {
119
119
  availableAgents: AgentProfileView[];
120
120
  currentSessionDisplayName?: string;
121
121
  effectiveSessionProjectRoot: string | null;
122
+ effectiveSessionWorkingDir: string | null;
122
123
  effectiveSessionProjectName: string | null;
123
124
  selectedSession: SessionEntryView | null;
124
125
  threadRef: MutableRefObject<HTMLDivElement | null>;
@@ -159,6 +160,7 @@ export function useNcpChatSnapshotSync(params: {
159
160
  availableAgents: params.availableAgents,
160
161
  sessionDisplayName: params.currentSessionDisplayName,
161
162
  sessionProjectRoot: params.effectiveSessionProjectRoot,
163
+ sessionWorkingDir: params.effectiveSessionWorkingDir,
162
164
  sessionProjectName: params.effectiveSessionProjectName,
163
165
  canDeleteSession: Boolean(params.selectedSession),
164
166
  threadRef: params.threadRef,
@@ -195,6 +195,8 @@ function useNcpChatPageState(presenter: NcpChatPresenter) {
195
195
  const effectiveSessionProjectRoot = hasSessionProjectRootOverride
196
196
  ? pendingProjectRoot
197
197
  : (selectedSession?.projectRoot ?? null);
198
+ const effectiveSessionWorkingDir =
199
+ selectedSession?.workingDir ?? effectiveSessionProjectRoot;
198
200
  const effectiveSessionProjectName = hasSessionProjectRootOverride
199
201
  ? getSessionProjectName(effectiveSessionProjectRoot)
200
202
  : (selectedSession?.projectName ??
@@ -224,6 +226,7 @@ function useNcpChatPageState(presenter: NcpChatPresenter) {
224
226
  ...baseState,
225
227
  availableAgents,
226
228
  effectiveSessionProjectRoot,
229
+ effectiveSessionWorkingDir,
227
230
  effectiveSessionProjectName,
228
231
  isSending: agent.isSending || currentSessionRunning,
229
232
  isAwaitingAssistantOutput: currentSessionRunning,
@@ -438,6 +441,7 @@ export function NcpChatPage({ view }: ChatPageProps) {
438
441
  availableAgents: state.availableAgents,
439
442
  currentSessionDisplayName: state.currentSessionDisplayName,
440
443
  effectiveSessionProjectRoot: state.effectiveSessionProjectRoot,
444
+ effectiveSessionWorkingDir: state.effectiveSessionWorkingDir,
441
445
  effectiveSessionProjectName: state.effectiveSessionProjectName,
442
446
  selectedSession: state.selectedSession,
443
447
  threadRef: state.threadRef,
@@ -47,6 +47,7 @@ export type ChatThreadSnapshot = {
47
47
  availableAgents?: AgentProfileView[];
48
48
  sessionDisplayName?: string;
49
49
  sessionProjectRoot?: string | null;
50
+ sessionWorkingDir?: string | null;
50
51
  sessionProjectName?: string | null;
51
52
  canDeleteSession: boolean;
52
53
  isDeletePending: boolean;
@@ -86,6 +87,7 @@ const initialSnapshot: ChatThreadSnapshot = {
86
87
  availableAgents: [],
87
88
  sessionDisplayName: undefined,
88
89
  sessionProjectRoot: null,
90
+ sessionWorkingDir: null,
89
91
  sessionProjectName: null,
90
92
  canDeleteSession: false,
91
93
  isDeletePending: false,
@@ -22,6 +22,7 @@ describe('adaptNcpSessionSummary', () => {
22
22
  createSummary({
23
23
  agentId: 'engineer',
24
24
  lastMessageAt: '2026-03-18T00:00:00.000Z',
25
+ workingDir: '/Users/demo/workspace/project-alpha',
25
26
  metadata: {
26
27
  label: 'NCP Planning Thread',
27
28
  model: 'openai/gpt-5',
@@ -40,6 +41,7 @@ describe('adaptNcpSessionSummary', () => {
40
41
  preferredModel: 'openai/gpt-5',
41
42
  preferredThinking: 'medium',
42
43
  projectRoot: '/Users/demo/workspace/project-alpha',
44
+ workingDir: '/Users/demo/workspace/project-alpha',
43
45
  projectName: 'project-alpha',
44
46
  lastMessageAt: '2026-03-18T00:00:00.000Z',
45
47
  readAt: '2026-03-17T23:59:00.000Z',
@@ -50,6 +52,25 @@ describe('adaptNcpSessionSummary', () => {
50
52
  });
51
53
  });
52
54
 
55
+ it('uses workingDir as the local file base even when projectRoot is absent', () => {
56
+ const adapted = adaptNcpSessionSummary(
57
+ createSummary({
58
+ workingDir: '/Users/demo/workspace',
59
+ metadata: {
60
+ label: 'Workspace Thread',
61
+ session_type: 'native',
62
+ },
63
+ }),
64
+ );
65
+
66
+ expect(adapted).toMatchObject({
67
+ key: 'ncp-session-1',
68
+ label: 'Workspace Thread',
69
+ workingDir: '/Users/demo/workspace',
70
+ });
71
+ expect(adapted.projectRoot).toBeUndefined();
72
+ });
73
+
53
74
  it('marks child sessions from parent_session_id metadata and keeps the request link', () => {
54
75
  const adapted = adaptNcpSessionSummary(
55
76
  createSummary({
@@ -120,6 +120,10 @@ function readNcpSessionProjectRoot(summary: NcpSessionSummaryView): string | nul
120
120
  return normalizeSessionProjectRootValue(metadata.project_root ?? metadata.projectRoot);
121
121
  }
122
122
 
123
+ function readNcpSessionWorkingDir(summary: NcpSessionSummaryView): string | null {
124
+ return readOptionalString(summary.workingDir);
125
+ }
126
+
123
127
  function readNcpSessionReadAt(summary: NcpSessionSummaryView): string | null {
124
128
  const metadata = readMetadata(summary);
125
129
  if (!metadata) {
@@ -308,6 +312,7 @@ export function adaptNcpSessionSummary(summary: NcpSessionSummaryView): SessionE
308
312
  const preferredModel = readNcpSessionPreferredModel(summary);
309
313
  const preferredThinking = readNcpSessionPreferredThinking(summary);
310
314
  const projectRoot = readNcpSessionProjectRoot(summary);
315
+ const workingDir = readNcpSessionWorkingDir(summary) ?? projectRoot;
311
316
  const readAt = readNcpSessionReadAt(summary);
312
317
  const lastMessageAt = readOptionalString(summary.lastMessageAt);
313
318
  const projectName = getSessionProjectName(projectRoot);
@@ -328,6 +333,7 @@ export function adaptNcpSessionSummary(summary: NcpSessionSummaryView): SessionE
328
333
  ...(preferredModel ? { preferredModel } : {}),
329
334
  ...(preferredThinking ? { preferredThinking } : {}),
330
335
  ...(projectRoot ? { projectRoot } : {}),
336
+ ...(workingDir ? { workingDir } : {}),
331
337
  ...(projectName ? { projectName } : {}),
332
338
  sessionType: readNcpSessionType(summary),
333
339
  sessionTypeMutable: false,
@@ -51,6 +51,7 @@ export type SessionEntryView = {
51
51
  preferredModel?: string;
52
52
  preferredThinking?: ThinkingLevel | null;
53
53
  projectRoot?: string | null;
54
+ workingDir?: string | null;
54
55
  projectName?: string | null;
55
56
  sessionType: string;
56
57
  sessionTypeMutable: boolean;
@@ -1 +0,0 @@
1
- import{t as e}from"./mcp-marketplace-page-BaBuHB2L.js";export{e as McpMarketplacePage};