diff --git a/docs/API-Reference/view/SidebarTabs.md b/docs/API-Reference/view/SidebarTabs.md
index 430d35d52a..3503e9e151 100644
--- a/docs/API-Reference/view/SidebarTabs.md
+++ b/docs/API-Reference/view/SidebarTabs.md
@@ -33,7 +33,7 @@ cached jQuery/DOM references held by extensions remain valid.
* [.removeTab(id)](#module_view/SidebarTabs..removeTab) ⇒ boolean
* [.setActiveTab(id)](#module_view/SidebarTabs..setActiveTab)
* [.getActiveTab()](#module_view/SidebarTabs..getActiveTab) ⇒ string
- * [.getAllTabs()](#module_view/SidebarTabs..getAllTabs) ⇒ Array.<{id: string, label: string, iconClass: string, priority: number}>
+ * [.TabDescriptor](#module_view/SidebarTabs..TabDescriptor) ⇒ Array.<TabDescriptor>
@@ -146,9 +146,18 @@ tab, hides all others.
Get the currently active tab id.
**Kind**: inner method of [view/SidebarTabs](#module_view/SidebarTabs)
-
+
-### view/SidebarTabs.getAllTabs() ⇒ Array.<{id: string, label: string, iconClass: string, priority: number}>
+### view/SidebarTabs.TabDescriptor ⇒ Array.<TabDescriptor>
Get an array of all registered tab descriptors.
-**Kind**: inner method of [view/SidebarTabs](#module_view/SidebarTabs)
+**Kind**: inner typedef of [view/SidebarTabs](#module_view/SidebarTabs)
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| id | string | Unique tab identifier |
+| label | string | Display text shown in the tab bar |
+| iconClass | string | Icon class string |
+| priority | number | Sort priority (lower = further left) |
+
diff --git a/docs/API-Reference/widgets/NotificationUI.md b/docs/API-Reference/widgets/NotificationUI.md
index 13bbe3631e..08bed134b0 100644
--- a/docs/API-Reference/widgets/NotificationUI.md
+++ b/docs/API-Reference/widgets/NotificationUI.md
@@ -6,12 +6,43 @@ const NotificationUI = brackets.getModule("widgets/NotificationUI")
## widgets/NotificationUI
-The global NotificationUI can be used to create popup notifications over dom elements or generics app notifications.
A global `window.EventManager` object is made available in phoenix that can be called anytime after AppStart.
This global can be triggered from anywhere without using require context.
## Usage
### Simple example
For Eg. Let's say we have to create a popup notification over the HTML element with ID `showInfileTree`.
We can do this with the following
+The global NotificationUI can be used to create popup notifications over dom elements or generics app notifications.
+
+A global `window.EventManager` object is made available in phoenix that can be called anytime after AppStart.
+This global can be triggered from anywhere without using require context.
+
+## Usage
+### Simple example
+For Eg. Let's say we have to create a popup notification over the HTML element with ID `showInfileTree`.
+We can do this with the following
**Example**
-```js
const NotificationUI = brackets.getModule("widgets/NotificationUI");
// or use window.NotificationUI global object has the same effect.
let notification = NotificationUI.createFromTemplate("Click me to locate the file in file tree", "showInfileTree",{});
notification.done(()=>{
console.log("notification is closed in ui.");
})
```
### Advanced example
Another advanced example where you can specify html and interactive components in the notification
+```js
+const NotificationUI = brackets.getModule("widgets/NotificationUI");
+// or use window.NotificationUI global object has the same effect.
+let notification = NotificationUI.createFromTemplate("Click me to locate the file in file tree", "showInfileTree",{});
+notification.done(()=>{
+ console.log("notification is closed in ui.");
+})
+```
+### Advanced example
+Another advanced example where you can specify html and interactive components in the notification
**Example**
-```js
// note that you can even provide an HTML Element node with
// custom event handlers directly here instead of HTML text.
let notification1 = NotificationUI.createFromTemplate(
"
Notification
* [.createToastFromTemplate(title, template, [options])](#module_widgets/NotificationUI..createToastFromTemplate) ⇒ Notification
* [.showToastOn(containerOrSelector, template, [options])](#module_widgets/NotificationUI..showToastOn) ⇒ Notification
+ * [.showHUD(iconClass, label, [options])](#module_widgets/NotificationUI..showHUD) ⇒ Notification
@@ -60,7 +92,21 @@ Closing notification reason.
### widgets/NotificationUI.createFromTemplate(title, template, [elementID], [options]) ⇒ Notification
-Creates a new notification popup from given template.
The template can either be a string or a jQuery object representing a DOM node that is *not* in the current DOM.
Creating a notification popup
```js
// note that you can even provide an HTML Element node with
// custom event handlers directly here instead of HTML text.
let notification1 = NotificationUI.createFromTemplate(
"widgets/NotificationUI](#module_widgets/NotificationUI)
**Returns**: Notification - Object with a done handler that resolves when the notification closes.
@@ -75,7 +121,20 @@ Creates a new notification popup from given template.
The template can either be
### widgets/NotificationUI.createToastFromTemplate(title, template, [options]) ⇒ Notification
-Creates a new toast notification popup from given title and html message.
The message can either be a string or a jQuery object representing a DOM node that is *not* in the current DOM.
Creating a toast notification popup
```js
// note that you can even provide an HTML Element node with
// custom event handlers directly here instead of HTML text.
let notification1 = NotificationUI.createToastFromTemplate( "Title here",
"widgets/NotificationUI](#module_widgets/NotificationUI)
**Returns**: Notification - Object with a done handler that resolves when the notification closes.
@@ -89,7 +148,15 @@ Creates a new toast notification popup from given title and html message.
The me
### widgets/NotificationUI.showToastOn(containerOrSelector, template, [options]) ⇒ Notification
-Shows a small, transient inline toast notification inside a given DOM container.
The toast is centered at the bottom of the container and auto-dismisses.
```js
NotificationUI.showToastOn(document.getElementById("my-panel"), "Hello!", {
autoCloseTimeS: 5,
dismissOnClick: true
});
```
+Shows a small, transient inline toast notification inside a given DOM container.
+The toast is centered at the bottom of the container and auto-dismisses.
+
+```js
+NotificationUI.showToastOn(document.getElementById("my-panel"), "Hello!", {
+ autoCloseTimeS: 5,
+ dismissOnClick: true
+});
+```
**Kind**: inner method of [widgets/NotificationUI](#module_widgets/NotificationUI)
**Returns**: Notification - Object with a done handler that resolves when the toast closes.
@@ -100,3 +167,23 @@ Shows a small, transient inline toast notification inside a given DOM container.
| template | string \| Element | HTML string or DOM Element for the toast content. |
| [options] | Object | optional, supported options: * `autoCloseTimeS` - Time in seconds after which the toast auto-closes. Default is 5. * `dismissOnClick` - If true, clicking the toast dismisses it. Default is true. |
+
+
+### widgets/NotificationUI.showHUD(iconClass, label, [options]) ⇒ Notification
+Shows a large, centered HUD overlay (like macOS volume/brightness indicator) with an icon and label.
+The HUD fades in/out and auto-dismisses. Only one HUD is shown at a time — calling this while a
+previous HUD is visible replaces it instantly.
+
+```js
+NotificationUI.showHUD("fa-solid fa-magnifying-glass-plus", "110%");
+```
+
+**Kind**: inner method of [widgets/NotificationUI](#module_widgets/NotificationUI)
+**Returns**: Notification - Object with a done handler that resolves when the HUD closes.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| iconClass | string | Font Awesome class string for the icon (e.g. "fa-solid fa-magnifying-glass-plus"). |
+| label | string | Text to display below the icon (e.g. "110%"). |
+| [options] | Object | optional, supported options: * `autoCloseTimeS` - Time in seconds after which the HUD auto-closes. Default is 1. |
+
diff --git a/src-node/claude-code-agent.js b/src-node/claude-code-agent.js
index 921c286a0c..f779b957ea 100644
--- a/src-node/claude-code-agent.js
+++ b/src-node/claude-code-agent.js
@@ -318,6 +318,7 @@ async function _runQuery(requestId, prompt, projectPath, model, signal, locale,
const queryOptions = {
cwd: projectPath || process.cwd(),
maxTurns: undefined,
+ stderr: (data) => console.log("[AI stderr]", data),
allowedTools: [
"Read", "Edit", "Write", "Glob", "Grep", "Bash",
"AskUserQuestion", "Task",
@@ -584,10 +585,27 @@ async function _runQuery(requestId, prompt, projectPath, model, signal, locale,
let sdkPrompt = prompt;
if (images && images.length > 0) {
const contentBlocks = [{ type: "text", text: prompt }];
- images.forEach(function (img) {
+ images.forEach(function (img, idx) {
+ // Infer media type from base64 header if missing
+ let mediaType = img.mediaType;
+ if (!mediaType && img.base64Data) {
+ if (img.base64Data.startsWith("iVBOR")) {
+ mediaType = "image/png";
+ } else if (img.base64Data.startsWith("/9j/")) {
+ mediaType = "image/jpeg";
+ } else if (img.base64Data.startsWith("R0lGOD")) {
+ mediaType = "image/gif";
+ } else if (img.base64Data.startsWith("UklGR")) {
+ mediaType = "image/webp";
+ } else {
+ mediaType = "image/png";
+ }
+ }
+ _log("Image[" + idx + "]:", "mediaType=" + mediaType,
+ "base64Len=" + (img.base64Data ? img.base64Data.length : "null"));
contentBlocks.push({
type: "image",
- source: { type: "base64", media_type: img.mediaType, data: img.base64Data }
+ source: { type: "base64", media_type: mediaType, data: img.base64Data }
});
});
sdkPrompt = (async function* () {
diff --git a/src/core-ai/AIChatPanel.js b/src/core-ai/AIChatPanel.js
index 1d542c8ad5..e73948ebcc 100644
--- a/src/core-ai/AIChatPanel.js
+++ b/src/core-ai/AIChatPanel.js
@@ -443,6 +443,10 @@ define(function (require, exports, module) {
}
imageFound = true;
const blob = item.getAsFile();
+ // Capture mediaType synchronously — DataTransferItem properties
+ // become invalid after the paste event handler returns, but
+ // the File object's type persists across the async boundary.
+ const mediaType = blob.type || item.type;
const reader = new FileReader();
reader.onload = function (ev) {
const dataUrl = ev.target.result;
@@ -454,7 +458,7 @@ define(function (require, exports, module) {
_addImageIfUnique(resized.dataUrl, resized.mediaType, resized.base64Data);
});
} else {
- _addImageIfUnique(dataUrl, item.type, base64Data);
+ _addImageIfUnique(dataUrl, mediaType, base64Data);
}
};
reader.readAsDataURL(blob);
diff --git a/src/view/SidebarTabs.js b/src/view/SidebarTabs.js
index bd44689e0b..a4fdbcbcac 100644
--- a/src/view/SidebarTabs.js
+++ b/src/view/SidebarTabs.js
@@ -460,7 +460,13 @@ define(function (require, exports, module) {
/**
* Get an array of all registered tab descriptors.
- * @return {Array.<{id: string, label: string, iconClass: string, priority: number}>}
+ * @typedef {Object} TabDescriptor
+ * @property {string} id - Unique tab identifier
+ * @property {string} label - Display text shown in the tab bar
+ * @property {string} iconClass - Icon class string
+ * @property {number} priority - Sort priority (lower = further left)
+ *
+ * @return {Array