@hienlh/ppm 0.8.59 → 0.9.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 +30 -0
- package/dist/web/assets/chat-tab-BDyjEN8p.js +7 -0
- package/dist/web/assets/{code-editor-DgTfBijB.js → code-editor-BmFI-Khj.js} +1 -1
- package/dist/web/assets/{database-viewer-DSlQhR7c.js → database-viewer-Cb7tqJqX.js} +1 -1
- package/dist/web/assets/{diff-viewer-C5A-ZnrC.js → diff-viewer-D_f9S4Ya.js} +1 -1
- package/dist/web/assets/{git-graph-B5QR_Cf-.js → git-graph-Co3a8y4i.js} +1 -1
- package/dist/web/assets/index-BAioKo_2.css +2 -0
- package/dist/web/assets/{index-frRaTxEm.js → index-CqMDTnLp.js} +3 -3
- package/dist/web/assets/keybindings-store-CulLCWPX.js +1 -0
- package/dist/web/assets/{markdown-renderer-DK-YZN0m.js → markdown-renderer-xipSjvIr.js} +1 -1
- package/dist/web/assets/{postgres-viewer-CV0kVl2C.js → postgres-viewer-p5tz14oN.js} +1 -1
- package/dist/web/assets/{settings-tab-DofusrxH.js → settings-tab-CCz5ftre.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-D5L6DIMB.js → sqlite-viewer-vF9L6tfk.js} +1 -1
- package/dist/web/assets/{terminal-tab-lu-7WWOT.js → terminal-tab-XbV1JFTB.js} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/src/providers/claude-agent-sdk.ts +16 -14
- package/src/providers/mock-provider.ts +6 -1
- package/src/server/ws/chat.ts +194 -139
- package/src/types/api.ts +9 -1
- package/src/web/components/chat/chat-tab.tsx +14 -5
- package/src/web/components/chat/message-list.tsx +15 -12
- package/src/web/hooks/use-chat.ts +196 -203
- package/dist/web/assets/chat-tab-CM6zFolq.js +0 -7
- package/dist/web/assets/index-WKLuYsBY.css +0 -2
- package/dist/web/assets/keybindings-store-Bjy78BoD.js +0 -1
|
@@ -2,7 +2,7 @@ import { useEffect, useRef, useState, useMemo, useCallback } from "react";
|
|
|
2
2
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
3
3
|
import { getAuthToken } from "@/lib/api-client";
|
|
4
4
|
import type { ChatMessage, ChatEvent } from "../../../types/chat";
|
|
5
|
-
import type {
|
|
5
|
+
import type { SessionPhase } from "../../../types/api";
|
|
6
6
|
import { ToolCard } from "./tool-cards";
|
|
7
7
|
import { MarkdownRenderer } from "@/components/shared/markdown-renderer";
|
|
8
8
|
import { cn, basename } from "@/lib/utils";
|
|
@@ -39,9 +39,8 @@ interface MessageListProps {
|
|
|
39
39
|
pendingApproval: { requestId: string; tool: string; input: unknown } | null;
|
|
40
40
|
onApprovalResponse: (requestId: string, approved: boolean, data?: unknown) => void;
|
|
41
41
|
isStreaming: boolean;
|
|
42
|
-
|
|
42
|
+
phase?: SessionPhase;
|
|
43
43
|
connectingElapsed?: number;
|
|
44
|
-
thinkingWarningThreshold?: number;
|
|
45
44
|
projectName?: string;
|
|
46
45
|
/** Called when user clicks Fork/Rewind — opens new forked chat tab */
|
|
47
46
|
onFork?: (userMessage: string) => void;
|
|
@@ -53,9 +52,8 @@ export function MessageList({
|
|
|
53
52
|
pendingApproval,
|
|
54
53
|
onApprovalResponse,
|
|
55
54
|
isStreaming,
|
|
56
|
-
|
|
55
|
+
phase,
|
|
57
56
|
connectingElapsed,
|
|
58
|
-
thinkingWarningThreshold,
|
|
59
57
|
projectName,
|
|
60
58
|
onFork,
|
|
61
59
|
}: MessageListProps) {
|
|
@@ -108,7 +106,7 @@ export function MessageList({
|
|
|
108
106
|
: <ApprovalCard approval={pendingApproval} onRespond={onApprovalResponse} />
|
|
109
107
|
)}
|
|
110
108
|
|
|
111
|
-
{isStreaming && <ThinkingIndicator lastMessage={messages[messages.length - 1]}
|
|
109
|
+
{isStreaming && <ThinkingIndicator lastMessage={messages[messages.length - 1]} phase={phase} elapsed={connectingElapsed} />}
|
|
112
110
|
</StickToBottom.Content>
|
|
113
111
|
<ScrollToBottomButton />
|
|
114
112
|
</StickToBottom>
|
|
@@ -751,14 +749,13 @@ function StreamingText({ content, animate: isStreaming, projectName }: { content
|
|
|
751
749
|
* - After tool: "Processing..."
|
|
752
750
|
* - Text streaming: hidden
|
|
753
751
|
*/
|
|
754
|
-
function ThinkingIndicator({ lastMessage,
|
|
755
|
-
// Show
|
|
752
|
+
function ThinkingIndicator({ lastMessage, phase, elapsed }: { lastMessage?: ChatMessage; phase?: SessionPhase; elapsed?: number }) {
|
|
753
|
+
// Show indicator when:
|
|
756
754
|
// 1. No assistant message yet (waiting for first response)
|
|
757
|
-
// 2. Last event is
|
|
755
|
+
// 2. Last event is tool_result (Claude thinking after tool execution)
|
|
758
756
|
// Hide when text is actively streaming (text itself is the indicator)
|
|
759
757
|
|
|
760
758
|
const isWaiting = !lastMessage || lastMessage.role !== "assistant";
|
|
761
|
-
// Show Thinking only after tool_result (tool finished), not tool_use (tool still running)
|
|
762
759
|
const isAfterTool = (() => {
|
|
763
760
|
if (!lastMessage?.events?.length) return false;
|
|
764
761
|
const last = lastMessage.events[lastMessage.events.length - 1]!;
|
|
@@ -767,13 +764,19 @@ function ThinkingIndicator({ lastMessage, streamingStatus, elapsed, warningThres
|
|
|
767
764
|
|
|
768
765
|
if (!isWaiting && !isAfterTool) return null;
|
|
769
766
|
|
|
770
|
-
const
|
|
767
|
+
const label = phase === "initializing" ? "Initializing"
|
|
768
|
+
: phase === "connecting" ? "Connecting"
|
|
769
|
+
: phase === "thinking" ? "Thinking"
|
|
770
|
+
: "Processing";
|
|
771
|
+
|
|
772
|
+
const isLong = phase === "connecting" && (elapsed ?? 0) >= 30;
|
|
773
|
+
|
|
771
774
|
return (
|
|
772
775
|
<div className="flex flex-col gap-1 text-sm">
|
|
773
776
|
<div className="flex items-center gap-2 text-text-subtle">
|
|
774
777
|
<Loader2 className="size-3 animate-spin" />
|
|
775
778
|
<span>
|
|
776
|
-
|
|
779
|
+
{label}
|
|
777
780
|
{isWaiting && (elapsed ?? 0) > 0 && <span className="text-text-subtle/60">... ({elapsed}s)</span>}
|
|
778
781
|
</span>
|
|
779
782
|
</div>
|