claude-ws 0.3.97 → 0.3.99
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/locales/de.json +374 -12
- package/locales/en.json +374 -12
- package/locales/es.json +398 -11
- package/locales/fr.json +398 -11
- package/locales/ja.json +398 -11
- package/locales/ko.json +398 -11
- package/locales/vi.json +374 -12
- package/locales/zh.json +398 -11
- package/package.json +1 -1
- package/server.ts +283 -6
- package/src/app/[locale]/not-found.tsx +6 -3
- package/src/app/[locale]/page.tsx +14 -4
- package/src/app/api/attempts/[id]/workflow/route.ts +76 -0
- package/src/app/api/questions/answer/route.ts +58 -0
- package/src/app/api/questions/route.ts +68 -0
- package/src/app/api/tasks/[id]/compact/route.ts +62 -0
- package/src/components/access-anywhere/api-access-key-setup-modal.tsx +2 -2
- package/src/components/access-anywhere/tunnel-settings-dialog.tsx +6 -6
- package/src/components/access-anywhere/wizard-step-ctunnel.tsx +8 -8
- package/src/components/agent-factory/dependency-tree.tsx +5 -3
- package/src/components/agent-factory/discovery-dialog.tsx +26 -22
- package/src/components/agent-factory/plugin-detail-dialog.tsx +41 -38
- package/src/components/agent-factory/plugin-form-dialog.tsx +23 -20
- package/src/components/agent-factory/plugin-list.tsx +20 -17
- package/src/components/agent-factory/upload-dialog.tsx +17 -14
- package/src/components/auth/agent-provider-dialog.tsx +67 -65
- package/src/components/auth/api-key-dialog.tsx +14 -11
- package/src/components/auth/auth-error-message.tsx +6 -3
- package/src/components/editor/code-editor-with-inline-edit.tsx +4 -2
- package/src/components/editor/file-diff-resolver-modal.tsx +31 -26
- package/src/components/editor/inline-edit-dialog.tsx +9 -6
- package/src/components/editor/selection-mention-popup.tsx +3 -1
- package/src/components/header/project-selector.tsx +7 -4
- package/src/components/header.tsx +70 -4
- package/src/components/kanban/column.tsx +11 -0
- package/src/components/kanban/task-card.tsx +70 -4
- package/src/components/project-settings/component-selector.tsx +3 -1
- package/src/components/project-settings/plugin-upload-dialog.tsx +7 -5
- package/src/components/project-settings/project-settings-dialog.tsx +5 -3
- package/src/components/questions/questions-panel.tsx +136 -0
- package/src/components/settings/folder-browser-dialog.tsx +29 -25
- package/src/components/settings/settings-page.tsx +64 -18
- package/src/components/settings/setup-dialog.tsx +26 -23
- package/src/components/setup/unified-setup-wizard.tsx +12 -9
- package/src/components/sidebar/file-browser/file-create-buttons.tsx +7 -3
- package/src/components/sidebar/file-browser/file-tab-content.tsx +19 -15
- package/src/components/sidebar/file-browser/file-tabs-panel.tsx +7 -4
- package/src/components/sidebar/file-browser/file-tree.tsx +3 -1
- package/src/components/sidebar/git-changes/branch-checkout-modal.tsx +6 -4
- package/src/components/sidebar/git-changes/commit-details-modal.tsx +5 -3
- package/src/components/sidebar/git-changes/diff-tabs-panel.tsx +3 -1
- package/src/components/sidebar/git-changes/git-file-item.tsx +8 -6
- package/src/components/sidebar/git-changes/git-graph.tsx +8 -5
- package/src/components/sidebar/git-changes/git-panel.tsx +28 -27
- package/src/components/sidebar/git-changes/git-section.tsx +5 -3
- package/src/components/sidebar/shells/shell-panel.tsx +3 -1
- package/src/components/task/attachment-bar.tsx +4 -1
- package/src/components/task/attempt-item.tsx +7 -5
- package/src/components/task/conversation-view.tsx +21 -13
- package/src/components/task/floating-chat-window.tsx +14 -5
- package/src/components/task/interactive-command/checkpoint-list.tsx +5 -3
- package/src/components/task/interactive-command/confirm-dialog.tsx +9 -4
- package/src/components/task/interactive-command/interactive-command-overlay.tsx +23 -9
- package/src/components/task/interactive-command/question-prompt.tsx +12 -8
- package/src/components/task/pending-question-indicator.tsx +5 -3
- package/src/components/task/prompt-input.tsx +1 -1
- package/src/components/task/shell-log-view.tsx +3 -1
- package/src/components/task/status-line.tsx +84 -23
- package/src/components/task/task-detail-panel.tsx +27 -27
- package/src/components/task/task-shell-indicator.tsx +10 -6
- package/src/components/terminal/terminal-context-menu.tsx +6 -4
- package/src/components/terminal/terminal-instance.tsx +11 -3
- package/src/components/terminal/terminal-panel.tsx +6 -3
- package/src/components/terminal/terminal-shortcut-bar.tsx +3 -1
- package/src/components/terminal/terminal-tab-bar.tsx +5 -3
- package/src/components/workflow/workflow-panel.tsx +181 -0
- package/src/hooks/use-attempt-stream.ts +96 -3
- package/src/lib/agent-manager.ts +89 -3
- package/src/lib/db/index.ts +18 -0
- package/src/lib/db/schema.ts +29 -0
- package/src/lib/process-manager.ts +28 -7
- package/src/lib/session-manager.ts +60 -0
- package/src/lib/usage-tracker.ts +19 -19
- package/src/lib/workflow-tracker.ts +118 -20
- package/src/stores/questions-store.ts +76 -0
- package/src/stores/workflow-store.ts +71 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
|
|
3
|
+
export interface PendingQuestionEntry {
|
|
4
|
+
attemptId: string;
|
|
5
|
+
taskId: string;
|
|
6
|
+
taskTitle: string;
|
|
7
|
+
projectId: string;
|
|
8
|
+
toolUseId: string;
|
|
9
|
+
questions: unknown[];
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface QuestionsStore {
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
pendingQuestions: Map<string, PendingQuestionEntry>;
|
|
16
|
+
togglePanel: () => void;
|
|
17
|
+
openPanel: () => void;
|
|
18
|
+
closePanel: () => void;
|
|
19
|
+
fetchQuestions: (projectIds?: string[]) => Promise<void>;
|
|
20
|
+
addQuestion: (entry: PendingQuestionEntry) => void;
|
|
21
|
+
removeQuestion: (attemptId: string) => void;
|
|
22
|
+
getCount: () => number;
|
|
23
|
+
getByTaskId: (taskId: string) => PendingQuestionEntry | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const useQuestionsStore = create<QuestionsStore>((set, get) => ({
|
|
27
|
+
isOpen: false,
|
|
28
|
+
pendingQuestions: new Map<string, PendingQuestionEntry>(),
|
|
29
|
+
|
|
30
|
+
togglePanel: () => set((state) => ({ isOpen: !state.isOpen })),
|
|
31
|
+
openPanel: () => set({ isOpen: true }),
|
|
32
|
+
closePanel: () => set({ isOpen: false }),
|
|
33
|
+
|
|
34
|
+
fetchQuestions: async (projectIds?: string[]) => {
|
|
35
|
+
try {
|
|
36
|
+
const params = projectIds?.length ? `?projectIds=${projectIds.join(',')}` : '';
|
|
37
|
+
const res = await fetch(`/api/questions${params}`);
|
|
38
|
+
if (!res.ok) return;
|
|
39
|
+
const data = await res.json();
|
|
40
|
+
const newMap = new Map<string, PendingQuestionEntry>();
|
|
41
|
+
for (const q of data.questions || []) {
|
|
42
|
+
newMap.set(q.attemptId, q);
|
|
43
|
+
}
|
|
44
|
+
set({ pendingQuestions: newMap });
|
|
45
|
+
} catch {
|
|
46
|
+
// Silently fail — will retry on next poll
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
addQuestion: (entry) => {
|
|
51
|
+
set((state) => {
|
|
52
|
+
const newMap = new Map(state.pendingQuestions);
|
|
53
|
+
newMap.set(entry.attemptId, entry);
|
|
54
|
+
return { pendingQuestions: newMap };
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
removeQuestion: (attemptId) => {
|
|
59
|
+
set((state) => {
|
|
60
|
+
const newMap = new Map(state.pendingQuestions);
|
|
61
|
+
newMap.delete(attemptId);
|
|
62
|
+
return { pendingQuestions: newMap };
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
getCount: () => {
|
|
67
|
+
return get().pendingQuestions.size;
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
getByTaskId: (taskId) => {
|
|
71
|
+
for (const entry of get().pendingQuestions.values()) {
|
|
72
|
+
if (entry.taskId === taskId) return entry;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import type { SubagentNode, AgentMessage, WorkflowSummary } from '@/lib/workflow-tracker';
|
|
3
|
+
|
|
4
|
+
export interface WorkflowEntry {
|
|
5
|
+
attemptId: string;
|
|
6
|
+
taskId: string;
|
|
7
|
+
taskTitle: string;
|
|
8
|
+
nodes: SubagentNode[];
|
|
9
|
+
messages: AgentMessage[];
|
|
10
|
+
summary: WorkflowSummary;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface WorkflowStore {
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
workflows: Map<string, WorkflowEntry>;
|
|
16
|
+
togglePanel: () => void;
|
|
17
|
+
openPanel: () => void;
|
|
18
|
+
closePanel: () => void;
|
|
19
|
+
updateWorkflow: (attemptId: string, data: Partial<WorkflowEntry>) => void;
|
|
20
|
+
removeWorkflow: (attemptId: string) => void;
|
|
21
|
+
getActiveAgentCount: () => number;
|
|
22
|
+
getByTaskId: (taskId: string) => WorkflowEntry | undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const useWorkflowStore = create<WorkflowStore>((set, get) => ({
|
|
26
|
+
isOpen: false,
|
|
27
|
+
workflows: new Map<string, WorkflowEntry>(),
|
|
28
|
+
|
|
29
|
+
togglePanel: () => set((state) => ({ isOpen: !state.isOpen })),
|
|
30
|
+
openPanel: () => set({ isOpen: true }),
|
|
31
|
+
closePanel: () => set({ isOpen: false }),
|
|
32
|
+
|
|
33
|
+
updateWorkflow: (attemptId, data) => {
|
|
34
|
+
set((state) => {
|
|
35
|
+
const newMap = new Map(state.workflows);
|
|
36
|
+
const existing = newMap.get(attemptId);
|
|
37
|
+
newMap.set(attemptId, {
|
|
38
|
+
attemptId,
|
|
39
|
+
taskId: data.taskId || existing?.taskId || '',
|
|
40
|
+
taskTitle: data.taskTitle || existing?.taskTitle || '',
|
|
41
|
+
nodes: data.nodes || existing?.nodes || [],
|
|
42
|
+
messages: data.messages || existing?.messages || [],
|
|
43
|
+
summary: data.summary || existing?.summary || { chain: [], completedCount: 0, activeCount: 0, totalCount: 0 },
|
|
44
|
+
});
|
|
45
|
+
return { workflows: newMap };
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
removeWorkflow: (attemptId) => {
|
|
50
|
+
set((state) => {
|
|
51
|
+
const newMap = new Map(state.workflows);
|
|
52
|
+
newMap.delete(attemptId);
|
|
53
|
+
return { workflows: newMap };
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
getActiveAgentCount: () => {
|
|
58
|
+
let count = 0;
|
|
59
|
+
for (const entry of get().workflows.values()) {
|
|
60
|
+
count += entry.summary.activeCount;
|
|
61
|
+
}
|
|
62
|
+
return count;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
getByTaskId: (taskId) => {
|
|
66
|
+
for (const entry of get().workflows.values()) {
|
|
67
|
+
if (entry.taskId === taskId) return entry;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
},
|
|
71
|
+
}));
|