@hienlh/ppm 0.11.14 → 0.11.16

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 (28) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/web/assets/{audio-preview-DNMaA2Iy.js → audio-preview-DjLLuzUD.js} +1 -1
  3. package/dist/web/assets/{chat-tab-C1bWBIuO.js → chat-tab-CL9_hlGE.js} +9 -9
  4. package/dist/web/assets/{code-editor-bumY3csF.js → code-editor-YaQFb5Db.js} +2 -2
  5. package/dist/web/assets/{conflict-editor-C4vVGggc.js → conflict-editor-Dk6MS9pE.js} +1 -1
  6. package/dist/web/assets/{database-viewer-C2R4BmYb.js → database-viewer-BO58nGFL.js} +1 -1
  7. package/dist/web/assets/{diff-viewer-BkLjsOlF.js → diff-viewer-DPgNFO4j.js} +1 -1
  8. package/dist/web/assets/{extension-webview-CYdFTUiW.js → extension-webview-B8361xT-.js} +2 -2
  9. package/dist/web/assets/{image-preview-D7GaiqMk.js → image-preview-B8oAGvHG.js} +1 -1
  10. package/dist/web/assets/index-B0V_IYbX.css +2 -0
  11. package/dist/web/assets/index-Bl3W1FYm.js +23 -0
  12. package/dist/web/assets/{markdown-renderer-BUP7_3I1.js → markdown-renderer-B8Gp0FKa.js} +1 -1
  13. package/dist/web/assets/{pdf-preview-7pWtxUJf.js → pdf-preview-D7JrByDM.js} +1 -1
  14. package/dist/web/assets/{port-forwarding-tab-CJgjwcA4.js → port-forwarding-tab-D2w0zW8n.js} +1 -1
  15. package/dist/web/assets/{postgres-viewer-CCr2drUV.js → postgres-viewer-ei8XhyiT.js} +1 -1
  16. package/dist/web/assets/{settings-tab-CJ9mBPMc.js → settings-tab-Dd4mGQHq.js} +1 -1
  17. package/dist/web/assets/{sqlite-viewer-W17NY9K0.js → sqlite-viewer-BNkPwKNL.js} +1 -1
  18. package/dist/web/assets/{terminal-tab-CPZdKlsT.js → terminal-tab-DwYueV8K.js} +1 -1
  19. package/dist/web/assets/{video-preview-DDqJpn2U.js → video-preview-BnZt6xtr.js} +1 -1
  20. package/dist/web/index.html +2 -2
  21. package/dist/web/sw.js +1 -1
  22. package/package.json +1 -1
  23. package/src/web/components/chat/message-list.tsx +34 -3
  24. package/src/web/components/chat/tool-cards.tsx +1 -1
  25. package/src/web/components/extensions/extension-webview.tsx +6 -1
  26. package/src/web/hooks/use-extension-ws.ts +25 -2
  27. package/dist/web/assets/index-DDyfOgAn.js +0 -23
  28. package/dist/web/assets/index-FKwHNxD8.css +0 -2
@@ -153,15 +153,20 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
153
153
 
154
154
  // On unmount: notify server to dispose the panel so extension clears activePanel state
155
155
  const panelIdForCleanup = useRef<string | null>(null);
156
+ const viewTypeForCleanup = useRef<string | undefined>(viewType);
156
157
  useEffect(() => {
157
158
  panelIdForCleanup.current = resolvedPanelId ?? null;
158
159
  }, [resolvedPanelId]);
160
+ useEffect(() => {
161
+ viewTypeForCleanup.current = viewType;
162
+ }, [viewType]);
159
163
  useEffect(() => {
160
164
  return () => {
161
165
  const id = panelIdForCleanup.current;
162
166
  if (id) {
167
+ const vt = viewTypeForCleanup.current;
163
168
  useExtensionStore.getState().removeWebviewPanel(id);
164
- window.dispatchEvent(new CustomEvent("ext:webview:close", { detail: { panelId: id } }));
169
+ window.dispatchEvent(new CustomEvent("ext:webview:close", { detail: { panelId: id, viewType: vt } }));
165
170
  }
166
171
  };
167
172
  }, []);
@@ -7,6 +7,15 @@ import { getAuthToken } from "@/lib/api-client";
7
7
  import type { ExtServerMsg, ExtClientMsg } from "../../types/extension-messages.ts";
8
8
  import { toast } from "sonner";
9
9
 
10
+ /**
11
+ * Track recently closed extension viewTypes to prevent auto-reopen.
12
+ * When user closes an extension tab, the viewType is added here.
13
+ * If a `webview:create` arrives for a recently closed viewType, we skip
14
+ * creating a new tab (the close was intentional).
15
+ * Cleared when user explicitly dispatches a command for the same viewType.
16
+ */
17
+ const recentlyClosedViews = new Set<string>();
18
+
10
19
  /**
11
20
  * Hook that manages the WebSocket connection for extension UI bridge.
12
21
  * Dispatches server messages into the extension Zustand store.
@@ -147,7 +156,10 @@ export function useExtensionWs(enabled = true) {
147
156
  title: msg.title,
148
157
  metadata: { viewType: viewTypeSlug, panelId: msg.panelId, extensionId: msg.extensionId },
149
158
  });
150
- } else {
159
+ // Focus the existing tab so Cmd+G / command palette switches to it
160
+ useTabStore.getState().setActiveTab(existingTabId);
161
+ } else if (!recentlyClosedViews.has(viewTypeSlug)) {
162
+ // Only create a new tab if this viewType wasn't recently closed by user
151
163
  const currentProject = useTabStore.getState().currentProject;
152
164
  useTabStore.getState().openTab({
153
165
  type: "extension",
@@ -207,14 +219,25 @@ export function useExtensionWs(enabled = true) {
207
219
  // Listen for command:execute requests (dispatched by StatusBar / TreeView)
208
220
  const commandHandler = (e: Event) => {
209
221
  const { command, args } = (e as CustomEvent).detail;
222
+ // User explicitly opened an extension — clear "recently closed" so tab can be created
223
+ const slug = (command as string).replace(/\.view$/, "");
224
+ recentlyClosedViews.delete(slug);
210
225
  client.send(JSON.stringify({ type: "command:execute", command, args }));
211
226
  };
212
227
  window.addEventListener("ext:command:execute", commandHandler);
213
228
 
214
229
  // Listen for webview close requests (dispatched by ExtensionWebview on unmount)
215
230
  const webviewCloseHandler = (e: Event) => {
216
- const { panelId } = (e as CustomEvent).detail;
231
+ const { panelId, viewType } = (e as CustomEvent).detail;
217
232
  client.send(JSON.stringify({ type: "webview:close", panelId }));
233
+ // Track that user intentionally closed this extension tab
234
+ if (viewType) {
235
+ const slug = (viewType as string).replace(/\.view$/, "");
236
+ recentlyClosedViews.add(slug);
237
+ // Auto-clear after 5s — stale entries are harmless but could block
238
+ // legitimate reopens if user waits too long
239
+ setTimeout(() => recentlyClosedViews.delete(slug), 5_000);
240
+ }
218
241
  };
219
242
  window.addEventListener("ext:webview:close", webviewCloseHandler);
220
243