@assistkick/create 1.9.0 → 1.11.0
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/dist/src/scaffolder.d.ts +12 -1
- package/dist/src/scaffolder.js +40 -3
- package/dist/src/scaffolder.js.map +1 -1
- package/package.json +1 -1
- package/templates/assistkick-product-system/package.json +1 -1
- package/templates/assistkick-product-system/packages/backend/package.json +1 -0
- package/templates/assistkick-product-system/packages/backend/src/mcp/permission_mcp_server.ts +196 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/agents.ts +31 -7
- package/templates/assistkick-product-system/packages/backend/src/routes/auth.ts +15 -12
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_files.test.ts +95 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_files.ts +97 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_permission.ts +94 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_sessions.ts +189 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_upload.test.ts +131 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_upload.ts +94 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/files.test.ts +12 -3
- package/templates/assistkick-product-system/packages/backend/src/routes/files.ts +2 -2
- package/templates/assistkick-product-system/packages/backend/src/routes/git.ts +391 -23
- package/templates/assistkick-product-system/packages/backend/src/routes/git_branches.test.ts +306 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/git_connect.test.ts +133 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/pipeline.ts +66 -9
- package/templates/assistkick-product-system/packages/backend/src/routes/preview.ts +204 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/projects.test.ts +205 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/projects.ts +37 -9
- package/templates/assistkick-product-system/packages/backend/src/routes/skills.test.ts +139 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/skills.ts +95 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/terminal.ts +5 -4
- package/templates/assistkick-product-system/packages/backend/src/routes/users.ts +4 -4
- package/templates/assistkick-product-system/packages/backend/src/routes/video.ts +8 -8
- package/templates/assistkick-product-system/packages/backend/src/routes/workflow_groups.ts +5 -5
- package/templates/assistkick-product-system/packages/backend/src/routes/workflows.ts +6 -6
- package/templates/assistkick-product-system/packages/backend/src/server.ts +107 -27
- package/templates/assistkick-product-system/packages/backend/src/services/agent_service.test.ts +105 -203
- package/templates/assistkick-product-system/packages/backend/src/services/agent_service.ts +76 -266
- package/templates/assistkick-product-system/packages/backend/src/services/chat_cli_bridge.test.ts +427 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_cli_bridge.ts +345 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_message_repository.test.ts +170 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_message_repository.ts +106 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_session_service.test.ts +217 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_session_service.ts +188 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_ws_handler.test.ts +1243 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_ws_handler.ts +894 -0
- package/templates/assistkick-product-system/packages/backend/src/services/coherence-review.ts +3 -3
- package/templates/assistkick-product-system/packages/backend/src/services/dev_command_detector.test.ts +85 -0
- package/templates/assistkick-product-system/packages/backend/src/services/dev_command_detector.ts +54 -0
- package/templates/assistkick-product-system/packages/backend/src/services/email_service.ts +13 -10
- package/templates/assistkick-product-system/packages/backend/src/services/init.ts +11 -3
- package/templates/assistkick-product-system/packages/backend/src/services/invitation_service.ts +1 -1
- package/templates/assistkick-product-system/packages/backend/src/services/password_reset_service.ts +1 -1
- package/templates/assistkick-product-system/packages/backend/src/services/permission_service.test.ts +243 -0
- package/templates/assistkick-product-system/packages/backend/src/services/permission_service.ts +259 -0
- package/templates/assistkick-product-system/packages/backend/src/services/preview_server_manager.test.ts +172 -0
- package/templates/assistkick-product-system/packages/backend/src/services/preview_server_manager.ts +225 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_service.test.ts +29 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_service.ts +17 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.test.ts +255 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.ts +300 -25
- package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.test.ts +44 -0
- package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.ts +62 -7
- package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.test.ts +77 -6
- package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.ts +149 -14
- package/templates/assistkick-product-system/packages/backend/src/services/terminal_ws_handler.ts +2 -1
- package/templates/assistkick-product-system/packages/backend/src/services/title_generator_service.test.ts +45 -0
- package/templates/assistkick-product-system/packages/backend/src/services/title_generator_service.ts +157 -0
- package/templates/assistkick-product-system/packages/backend/src/services/tts_service.ts +4 -3
- package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.ts +3 -3
- package/templates/assistkick-product-system/packages/frontend/package.json +5 -0
- package/templates/assistkick-product-system/packages/frontend/src/App.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/api/client.ts +336 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/AgentsView.tsx +192 -12
- package/templates/assistkick-product-system/packages/frontend/src/components/AttachmentPreviewList.tsx +98 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/AutocompleteDropdown.tsx +65 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatAttachButton.tsx +56 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatDropZone.tsx +80 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageBubble.tsx +155 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageContent.tsx +182 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageInput.tsx +233 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatSessionSidebar.tsx +218 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatStopButton.tsx +32 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatTodoSidebar.tsx +113 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatView.tsx +842 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/CommitMessageModal.tsx +82 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/DiagramOverlay.tsx +160 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/EditorTabBar.tsx +5 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/FileTree.tsx +9 -10
- package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeInlineInput.tsx +5 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/FilesView.tsx +112 -41
- package/templates/assistkick-product-system/packages/frontend/src/components/GraphLegend.tsx +2 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/HighlightedText.tsx +87 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ImageLightbox.tsx +192 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/KanbanView.tsx +2 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/MentionPill.tsx +33 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/MermaidBlock.tsx +148 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/PermissionDialog.tsx +91 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/PermissionModeSelector.tsx +229 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ProjectSelector.tsx +249 -83
- package/templates/assistkick-product-system/packages/frontend/src/components/QueuedMessageBubble.tsx +38 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/SidePanel.tsx +212 -117
- package/templates/assistkick-product-system/packages/frontend/src/components/SystemPromptAccordion.tsx +48 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/TaskIcon.tsx +11 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/TerminalView.tsx +25 -9
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolDiffView.tsx +114 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolResultCard.tsx +87 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolUseCard.tsx +149 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/Toolbar.tsx +25 -8
- package/templates/assistkick-product-system/packages/frontend/src/components/UnifiedGitWidget.tsx +722 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/GroupNode.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/NodePalette.tsx +2 -1
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/ProgrammableNode.tsx +178 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowCanvas.tsx +3 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowMonitorModal.tsx +103 -9
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/monitor_nodes.tsx +26 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.ts +42 -1
- package/templates/assistkick-product-system/packages/frontend/src/hooks/useDocumentTitle.ts +11 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/useProjects.ts +1 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_chat_stream.ts +826 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_file_tree_cache.ts +69 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_mention_autocomplete.ts +284 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/attachment_manager.test.ts +183 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/attachment_manager.ts +150 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/chat_message_helpers.test.ts +305 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/chat_message_helpers.ts +113 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/context_usage_helpers.test.ts +157 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/context_usage_helpers.ts +95 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/mermaid_helpers.test.ts +65 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/mermaid_helpers.ts +110 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/message_queue.ts +66 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/tool_use_summary.test.ts +124 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/tool_use_summary.ts +112 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/AgentsRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/ChatRoute.tsx +8 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/CoherenceRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/DashboardLayout.tsx +0 -4
- package/templates/assistkick-product-system/packages/frontend/src/routes/DesignSystemRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/FilesRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/GraphRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/KanbanRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/TerminalRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/UsersRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/VideographyRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/WorkflowsRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/accept_invitation.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/forgot_password.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/login.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/register.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/reset_password.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useAttachmentStore.ts +66 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useChatSessionStore.ts +107 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useMessageQueueStore.ts +110 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/usePreviewStore.ts +78 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useProjectStore.ts +7 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useSidePanelStore.ts +6 -1
- package/templates/assistkick-product-system/packages/frontend/src/styles/index.css +30 -357
- package/templates/assistkick-product-system/packages/frontend/src/utils/parse_node_markdown.test.ts +115 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/parse_node_markdown.ts +91 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/preview_utils.test.ts +30 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/preview_utils.ts +3 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0015_magenta_jazinda.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0016_giant_xorn.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0017_sloppy_mentor.sql +6 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0018_vengeful_kabuki.sql +9 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0019_careful_sentinels.sql +8 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0020_clever_spot.sql +27 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0021_graceful_hex.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0022_short_kingpin.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0023_ambiguous_sharon_carter.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0024_fat_unus.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0015_snapshot.json +1552 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0016_snapshot.json +1560 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0017_snapshot.json +1598 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0018_snapshot.json +1657 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0019_snapshot.json +1709 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0020_snapshot.json +1733 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0021_snapshot.json +1740 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0022_snapshot.json +1755 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0023_snapshot.json +1762 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0024_snapshot.json +1769 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/_journal.json +70 -0
- package/templates/assistkick-product-system/packages/shared/db/schema.ts +40 -1
- package/templates/assistkick-product-system/packages/shared/lib/claude-service.test.ts +236 -0
- package/templates/assistkick-product-system/packages/shared/lib/claude-service.ts +46 -5
- package/templates/assistkick-product-system/packages/shared/lib/git_workflow.ts +65 -39
- package/templates/assistkick-product-system/packages/shared/lib/programmable_node_executor.test.ts +173 -0
- package/templates/assistkick-product-system/packages/shared/lib/programmable_node_executor.ts +213 -0
- package/templates/assistkick-product-system/packages/shared/lib/validator.test.ts +70 -0
- package/templates/assistkick-product-system/packages/shared/lib/validator.ts +17 -1
- package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.test.ts +803 -27
- package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.ts +502 -68
- package/templates/assistkick-product-system/packages/shared/lib/workflow_orchestrator.ts +4 -4
- package/templates/assistkick-product-system/packages/shared/package.json +2 -1
- package/templates/assistkick-product-system/packages/shared/test_fixtures/hanging_stream.mjs +46 -0
- package/templates/assistkick-product-system/packages/shared/tools/add_node.test.ts +44 -0
- package/templates/assistkick-product-system/packages/shared/tools/add_node.ts +7 -0
- package/templates/assistkick-product-system/packages/shared/tools/remove_node.ts +2 -1
- package/templates/assistkick-product-system/packages/shared/tools/resolve_question.ts +2 -1
- package/templates/assistkick-product-system/packages/shared/tools/update_node.ts +2 -1
- package/templates/assistkick-product-system/tests/message_queue.test.ts +178 -0
- package/templates/assistkick-product-system/tests/message_queue_per_session.test.ts +143 -0
- package/templates/skills/assistkick-bootstrap/SKILL.md +26 -26
- package/templates/skills/assistkick-code-reviewer/SKILL.md +45 -46
- package/templates/skills/assistkick-db-explorer/SKILL.md +13 -13
- package/templates/skills/assistkick-debugger/SKILL.md +23 -23
- package/templates/skills/assistkick-developer/SKILL.md +59 -63
- package/templates/skills/assistkick-interview/SKILL.md +26 -26
- package/templates/skills/assistkick-video-composition-agent/SKILL.md +231 -0
- package/templates/skills/assistkick-video-script-writer/SKILL.md +136 -0
package/templates/assistkick-product-system/packages/frontend/src/components/ToolResultCard.tsx
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToolResultCard — displays a tool result as a collapsible accordion card
|
|
3
|
+
* in the chat stream. Collapsed by default, showing a brief summary.
|
|
4
|
+
* Expands to reveal the full tool output.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
9
|
+
import type { ToolResultBlock } from '../hooks/use_chat_stream';
|
|
10
|
+
|
|
11
|
+
interface ToolResultCardProps {
|
|
12
|
+
result: ToolResultBlock;
|
|
13
|
+
/** Tool name for display context (e.g. "Read", "Bash") */
|
|
14
|
+
toolName?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Normalize content to a string — handles string, array-of-blocks, or other shapes. */
|
|
18
|
+
const contentToString = (content: ToolResultBlock['content']): string => {
|
|
19
|
+
if (!content) return '';
|
|
20
|
+
if (typeof content === 'string') return content;
|
|
21
|
+
if (Array.isArray(content)) {
|
|
22
|
+
return (content as Array<Record<string, unknown>>)
|
|
23
|
+
.filter(c => typeof c.text === 'string')
|
|
24
|
+
.map(c => c.text as string)
|
|
25
|
+
.join('\n');
|
|
26
|
+
}
|
|
27
|
+
return String(content);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Generate a brief summary of the result for the collapsed view. */
|
|
31
|
+
const summarizeResult = (result: ToolResultBlock, toolName?: string): string => {
|
|
32
|
+
const prefix = result.isError ? '✗ Error' : '✓ Result';
|
|
33
|
+
const label = toolName ? `${prefix} from ${toolName}` : prefix;
|
|
34
|
+
|
|
35
|
+
const text = contentToString(result.content);
|
|
36
|
+
if (!text) return `${label}: (empty)`;
|
|
37
|
+
|
|
38
|
+
// Show first meaningful line, truncated
|
|
39
|
+
const firstLine = text.split('\n').find(l => l.trim()) ?? '';
|
|
40
|
+
const MAX = 100;
|
|
41
|
+
const preview = firstLine.length > MAX ? `${firstLine.slice(0, MAX)}…` : firstLine;
|
|
42
|
+
return preview ? `${label}: ${preview}` : label;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const ToolResultCard = ({ result, toolName }: ToolResultCardProps) => {
|
|
46
|
+
const [expanded, setExpanded] = useState(false);
|
|
47
|
+
const summary = summarizeResult(result, toolName);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div className="rounded-lg border border-edge bg-surface-alt overflow-hidden my-1">
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
onClick={() => setExpanded(prev => !prev)}
|
|
54
|
+
className="flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-surface-raised/50 transition-colors cursor-pointer"
|
|
55
|
+
>
|
|
56
|
+
<span className="shrink-0 text-sm" aria-hidden="true">
|
|
57
|
+
{result.isError ? '❌' : '📤'}
|
|
58
|
+
</span>
|
|
59
|
+
<span
|
|
60
|
+
className={`text-[12px] font-mono flex-1 truncate ${
|
|
61
|
+
result.isError ? 'text-error' : 'text-content-secondary'
|
|
62
|
+
}`}
|
|
63
|
+
>
|
|
64
|
+
{summary}
|
|
65
|
+
</span>
|
|
66
|
+
{expanded
|
|
67
|
+
? <ChevronDown size={13} className="text-content-muted shrink-0" />
|
|
68
|
+
: <ChevronRight size={13} className="text-content-muted shrink-0" />}
|
|
69
|
+
</button>
|
|
70
|
+
|
|
71
|
+
{expanded && (
|
|
72
|
+
<div className="border-t border-edge px-3 py-2">
|
|
73
|
+
<div className="text-[10px] font-mono text-content-muted uppercase tracking-wider mb-1">
|
|
74
|
+
{result.isError ? 'Error' : 'Output'}
|
|
75
|
+
</div>
|
|
76
|
+
<pre
|
|
77
|
+
className={`text-[12px] font-mono whitespace-pre-wrap break-words m-0 max-h-[400px] overflow-y-auto ${
|
|
78
|
+
result.isError ? 'text-error' : 'text-content-secondary'
|
|
79
|
+
}`}
|
|
80
|
+
>
|
|
81
|
+
{contentToString(result.content) || '(empty)'}
|
|
82
|
+
</pre>
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToolUseCard — displays a Claude tool invocation as a collapsible card
|
|
3
|
+
* in the chat stream. Shows tool name and a brief summary when collapsed;
|
|
4
|
+
* expands to reveal the full tool input.
|
|
5
|
+
*
|
|
6
|
+
* Follows the design system: surface-alt background, edge borders,
|
|
7
|
+
* content-secondary text, monospace font at 13px.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
12
|
+
import { summarizeToolUse, toolIcon } from '../lib/tool_use_summary';
|
|
13
|
+
import { ToolDiffView } from './ToolDiffView';
|
|
14
|
+
import type { ToolResultBlock } from '../hooks/use_chat_stream';
|
|
15
|
+
|
|
16
|
+
interface ToolUseCardProps {
|
|
17
|
+
name: string;
|
|
18
|
+
input: Record<string, unknown>;
|
|
19
|
+
isStreaming?: boolean;
|
|
20
|
+
result?: ToolResultBlock;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Format tool input as indented JSON for the expanded view.
|
|
25
|
+
* Omits very large string values (e.g. file contents) to keep the card readable.
|
|
26
|
+
*/
|
|
27
|
+
const formatInput = (input: Record<string, unknown>): string => {
|
|
28
|
+
const MAX_STRING_LEN = 500;
|
|
29
|
+
|
|
30
|
+
const replacer = (_key: string, value: unknown): unknown => {
|
|
31
|
+
if (typeof value === 'string' && value.length > MAX_STRING_LEN) {
|
|
32
|
+
return `${value.slice(0, MAX_STRING_LEN)}… (${value.length} chars)`;
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return JSON.stringify(input, replacer, 2);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Normalize result content to a string — handles string, array-of-blocks, or other shapes. */
|
|
41
|
+
const contentToString = (content: ToolResultBlock['content']): string => {
|
|
42
|
+
if (!content) return '';
|
|
43
|
+
if (typeof content === 'string') return content;
|
|
44
|
+
if (Array.isArray(content)) {
|
|
45
|
+
return (content as Array<Record<string, unknown>>)
|
|
46
|
+
.filter(c => typeof c.text === 'string')
|
|
47
|
+
.map(c => c.text as string)
|
|
48
|
+
.join('\n');
|
|
49
|
+
}
|
|
50
|
+
return String(content);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
type ViewTab = 'humanized' | 'raw';
|
|
54
|
+
|
|
55
|
+
const hasHumanizedView = (name: string): boolean => name === 'Edit' || name === 'Write';
|
|
56
|
+
|
|
57
|
+
export const ToolUseCard = ({ name, input, isStreaming, result }: ToolUseCardProps) => {
|
|
58
|
+
const [expanded, setExpanded] = useState(false);
|
|
59
|
+
const [viewTab, setViewTab] = useState<ViewTab>('humanized');
|
|
60
|
+
const summary = summarizeToolUse(name, input);
|
|
61
|
+
const icon = toolIcon(name);
|
|
62
|
+
|
|
63
|
+
// Build collapsed summary: include result status indicator
|
|
64
|
+
const resultIcon = result
|
|
65
|
+
? result.isError ? '✗' : '✓'
|
|
66
|
+
: null;
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div className="rounded-lg border border-edge bg-surface-alt overflow-hidden my-1">
|
|
70
|
+
<button
|
|
71
|
+
type="button"
|
|
72
|
+
onClick={() => setExpanded(prev => !prev)}
|
|
73
|
+
className="flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-surface-raised/50 transition-colors cursor-pointer"
|
|
74
|
+
>
|
|
75
|
+
<span className="shrink-0 text-sm" aria-hidden="true">{icon}</span>
|
|
76
|
+
<span className="text-[12px] font-mono text-content-secondary flex-1 truncate">
|
|
77
|
+
{resultIcon && (
|
|
78
|
+
<span className={`mr-1.5 ${result?.isError ? 'text-error' : 'text-green-400'}`}>
|
|
79
|
+
{resultIcon}
|
|
80
|
+
</span>
|
|
81
|
+
)}
|
|
82
|
+
{summary}
|
|
83
|
+
</span>
|
|
84
|
+
{isStreaming && (
|
|
85
|
+
<span className="shrink-0 w-1.5 h-1.5 rounded-full bg-accent animate-pulse" />
|
|
86
|
+
)}
|
|
87
|
+
{expanded
|
|
88
|
+
? <ChevronDown size={13} className="text-content-muted shrink-0" />
|
|
89
|
+
: <ChevronRight size={13} className="text-content-muted shrink-0" />}
|
|
90
|
+
</button>
|
|
91
|
+
|
|
92
|
+
{expanded && (
|
|
93
|
+
<div className="border-t border-edge">
|
|
94
|
+
{/* Tab bar for Edit/Write tools */}
|
|
95
|
+
{hasHumanizedView(name) && (
|
|
96
|
+
<div className="flex gap-0 border-b border-edge">
|
|
97
|
+
{(['humanized', 'raw'] as const).map(tab => (
|
|
98
|
+
<button
|
|
99
|
+
key={tab}
|
|
100
|
+
type="button"
|
|
101
|
+
onClick={() => setViewTab(tab)}
|
|
102
|
+
className={`px-3 py-1.5 text-[11px] font-mono uppercase tracking-wider transition-colors cursor-pointer ${
|
|
103
|
+
viewTab === tab
|
|
104
|
+
? 'text-accent border-b-2 border-accent -mb-px'
|
|
105
|
+
: 'text-content-muted hover:text-content-secondary'
|
|
106
|
+
}`}
|
|
107
|
+
>
|
|
108
|
+
{tab === 'humanized' ? 'Humanized' : 'Raw'}
|
|
109
|
+
</button>
|
|
110
|
+
))}
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
|
|
114
|
+
{/* Tool input — humanized or raw */}
|
|
115
|
+
{hasHumanizedView(name) && viewTab === 'humanized' ? (
|
|
116
|
+
<div className="px-3 py-2">
|
|
117
|
+
<ToolDiffView toolName={name as 'Edit' | 'Write'} input={input} />
|
|
118
|
+
</div>
|
|
119
|
+
) : (
|
|
120
|
+
<div className="px-3 py-2">
|
|
121
|
+
<div className="text-[10px] font-mono text-content-muted uppercase tracking-wider mb-1">
|
|
122
|
+
Input
|
|
123
|
+
</div>
|
|
124
|
+
<pre className="text-[12px] font-mono text-content-secondary whitespace-pre-wrap break-words m-0 max-h-[300px] overflow-y-auto">
|
|
125
|
+
{formatInput(input)}
|
|
126
|
+
</pre>
|
|
127
|
+
</div>
|
|
128
|
+
)}
|
|
129
|
+
|
|
130
|
+
{/* Tool output — shown inline when result is available */}
|
|
131
|
+
{result && (
|
|
132
|
+
<div className="border-t border-edge px-3 py-2">
|
|
133
|
+
<div className="text-[10px] font-mono text-content-muted uppercase tracking-wider mb-1">
|
|
134
|
+
{result.isError ? 'Error' : 'Output'}
|
|
135
|
+
</div>
|
|
136
|
+
<pre
|
|
137
|
+
className={`text-[12px] font-mono whitespace-pre-wrap break-words m-0 max-h-[400px] overflow-y-auto ${
|
|
138
|
+
result.isError ? 'text-error' : 'text-content-secondary'
|
|
139
|
+
}`}
|
|
140
|
+
>
|
|
141
|
+
{contentToString(result.content) || '(empty)'}
|
|
142
|
+
</pre>
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
|
+
)}
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import React, { useCallback, useEffect } from 'react';
|
|
2
2
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
3
3
|
import {
|
|
4
|
-
Columns3, MessageSquare, Network, ShieldCheck, Palette, Users, Bot, Workflow,
|
|
5
|
-
FolderOpen, Maximize, Settings, Sun, Moon, Video,
|
|
4
|
+
Columns3, MessageSquare, MessagesSquare, Network, ShieldCheck, Palette, Users, Bot, Workflow,
|
|
5
|
+
FolderOpen, Maximize, Settings, Sun, Moon, Video, Terminal,
|
|
6
6
|
} from 'lucide-react';
|
|
7
7
|
import { NavBarSidekick } from './ds/NavBarSidekick';
|
|
8
8
|
import type { NavItem } from './ds/NavBarSidekick';
|
|
9
9
|
import { ProjectSelector } from './ProjectSelector';
|
|
10
10
|
import { useProjectStore } from '../stores/useProjectStore';
|
|
11
|
+
import { usePreviewStore } from '../stores/usePreviewStore';
|
|
11
12
|
import { useGraphStore } from '../stores/useGraphStore';
|
|
12
13
|
import { useGraphUIStore } from '../stores/useGraphUIStore';
|
|
13
|
-
import { useGitModalStore } from '../stores/useGitModalStore';
|
|
14
14
|
import { useTheme } from '../hooks/useTheme';
|
|
15
15
|
import { useAuth } from '../hooks/useAuth';
|
|
16
16
|
import { apiClient } from '../api/client';
|
|
17
17
|
|
|
18
|
-
const VALID_TABS = new Set(['graph', 'kanban', 'coherence', 'users', 'terminal', 'agents', 'workflows', 'design-system', 'files', 'videography']);
|
|
18
|
+
const VALID_TABS = new Set(['graph', 'kanban', 'coherence', 'users', 'terminal', 'chat', 'agents', 'workflows', 'design-system', 'files', 'videography']);
|
|
19
19
|
|
|
20
20
|
function tabFromPath(pathname: string): string {
|
|
21
21
|
const seg = pathname.replace(/^\//, '');
|
|
@@ -26,7 +26,8 @@ const ICON_PROPS = { size: 14, strokeWidth: 2 } as const;
|
|
|
26
26
|
|
|
27
27
|
const TAB_ITEMS: NavItem[] = [
|
|
28
28
|
{ id: 'kanban', label: 'Kanban', icon: <Columns3 {...ICON_PROPS} />, description: 'Board view of features', href: '/kanban' },
|
|
29
|
-
{ id: 'terminal', label: '
|
|
29
|
+
{ id: 'terminal', label: 'Terminal', icon: <Terminal {...ICON_PROPS} />, description: 'AI assistant terminal', href: '/terminal' },
|
|
30
|
+
{ id: 'chat', label: 'Chat', icon: <MessagesSquare {...ICON_PROPS} />, description: 'Chat v2 web interface', href: '/chat' },
|
|
30
31
|
{ id: 'graph', label: 'Graph', icon: <Network {...ICON_PROPS} />, description: 'Knowledge graph visualization', href: '/graph' },
|
|
31
32
|
{ id: 'coherence', label: 'Coherence', icon: <ShieldCheck {...ICON_PROPS} />, description: 'Coherence analysis', href: '/coherence' },
|
|
32
33
|
{ id: 'agents', label: 'Agents', icon: <Bot {...ICON_PROPS} />, description: 'Manage agent prompts', href: '/agents' },
|
|
@@ -60,15 +61,27 @@ export function Toolbar() {
|
|
|
60
61
|
const selectProject = useProjectStore((s) => s.selectProject);
|
|
61
62
|
const createProject = useProjectStore((s) => s.createProject);
|
|
62
63
|
const renameProject = useProjectStore((s) => s.renameProject);
|
|
64
|
+
const updatePreviewCommand = useProjectStore((s) => s.updatePreviewCommand);
|
|
63
65
|
const archiveProject = useProjectStore((s) => s.archiveProject);
|
|
64
66
|
|
|
67
|
+
const previewApps = usePreviewStore((s) => s.apps);
|
|
68
|
+
const previewLoading = usePreviewStore((s) => s.loading);
|
|
69
|
+
const startPreview = usePreviewStore((s) => s.startPreview);
|
|
70
|
+
const stopPreview = usePreviewStore((s) => s.stopPreview);
|
|
71
|
+
const startPolling = usePreviewStore((s) => s.startPolling);
|
|
72
|
+
const stopPolling = usePreviewStore((s) => s.stopPolling);
|
|
73
|
+
|
|
74
|
+
// Start polling preview status on mount, stop on unmount
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
startPolling();
|
|
77
|
+
return () => stopPolling();
|
|
78
|
+
}, [startPolling, stopPolling]);
|
|
79
|
+
|
|
65
80
|
const graphData = useGraphStore((s) => s.graphData);
|
|
66
81
|
const onFit = useGraphUIStore((s) => s.onFit);
|
|
67
82
|
const settingsOpen = useGraphUIStore((s) => s.settingsOpen);
|
|
68
83
|
const onSettingsToggle = useGraphUIStore((s) => s.onSettingsToggle);
|
|
69
84
|
|
|
70
|
-
const openGitModal = useGitModalStore((s) => s.open);
|
|
71
|
-
|
|
72
85
|
const completeness = graphData
|
|
73
86
|
? Math.round((graphData.nodes.reduce((acc: number, n: any) => acc + (n.completeness || 0), 0) / Math.max(graphData.nodes.length, 1)) * 100)
|
|
74
87
|
: 0;
|
|
@@ -117,8 +130,12 @@ export function Toolbar() {
|
|
|
117
130
|
onSelect={selectProject}
|
|
118
131
|
onCreate={createProject}
|
|
119
132
|
onRename={renameProject}
|
|
133
|
+
onUpdatePreviewCommand={updatePreviewCommand}
|
|
120
134
|
onArchive={archiveProject}
|
|
121
|
-
|
|
135
|
+
previewApps={previewApps}
|
|
136
|
+
onPreviewStart={startPreview}
|
|
137
|
+
onPreviewStop={stopPreview}
|
|
138
|
+
previewLoading={previewLoading}
|
|
122
139
|
/>
|
|
123
140
|
}
|
|
124
141
|
center={
|