Skip to content

Commit a1e1d4f

Browse files
committed
feat: stream sub-agent events, add live preview selection to editor state
- Handle sub-agent streaming events separately in claude-code-agent.js so Skill/Task tool activity is visible in the AI chat UI - Add livePreviewSelectedElement to getEditorState MCP tool response - Rename "Live Preview JS" tool label to "Inspecting preview" - Fix todo task list: reduce left padding, allow text wrapping
1 parent 0df1ca2 commit a1e1d4f

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

src-node/mcp-editor-tools.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ function createEditorMcpServer(sdkModule, nodeConnector) {
4242
const getEditorStateTool = sdkModule.tool(
4343
"getEditorState",
4444
"Get the current Phoenix editor state: active file, working set (open files), live preview file, " +
45-
"and cursor/selection info (current line text with surrounding context, or selected text). " +
45+
"cursor/selection info (current line text with surrounding context, or selected text), " +
46+
"and the currently selected element in the live preview (tag, selector, text preview) if any. " +
47+
"The live preview selected element may differ from the editor cursor — use execJsInLivePreview to inspect it further. " +
4648
"Long lines are trimmed to 200 chars and selections to 10K chars — use the Read tool for full content.",
4749
{},
4850
async function () {

src/core-ai/aiPhoenixConnectors.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ define(function (require, exports, module) {
5454
* Called from the node-side MCP server via execPeer.
5555
*/
5656
function getEditorState() {
57+
const deferred = new $.Deferred();
5758
const activeFile = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);
5859
const workingSet = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES);
5960

@@ -138,7 +139,37 @@ define(function (require, exports, module) {
138139
}
139140
}
140141

141-
return result;
142+
// If live preview is connected, query the selected element (best-effort)
143+
if (LiveDevProtocol.getConnectionIds().length > 0) {
144+
const LP_SELECTED_EL_JS =
145+
"(function(){" +
146+
"var el=window.__current_ph_lp_selected;" +
147+
"if(!el||!el.isConnected)return null;" +
148+
"var tag=el.tagName.toLowerCase();" +
149+
"var id=el.id?'#'+el.id:'';" +
150+
"var cls=el.className&&typeof el.className==='string'?" +
151+
"'.'+el.className.trim().split(/\\s+/).join('.'):" +
152+
"'';" +
153+
"var text=el.textContent||'';" +
154+
"if(text.length>80)text=text.slice(0,80)+'...';" +
155+
"text=text.replace(/\\n/g,' ').trim();" +
156+
"return{tag:tag,selector:tag+id+cls,textPreview:text};" +
157+
"})()";
158+
LiveDevProtocol.evaluate(LP_SELECTED_EL_JS)
159+
.done(function (evalResult) {
160+
if (evalResult && evalResult.tag) {
161+
result.livePreviewSelectedElement = evalResult;
162+
}
163+
deferred.resolve(result);
164+
})
165+
.fail(function () {
166+
deferred.resolve(result);
167+
});
168+
} else {
169+
deferred.resolve(result);
170+
}
171+
172+
return deferred.promise();
142173
}
143174

144175
// --- Screenshot ---

src/styles/Extn-AIChatPanel.less

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@
409409

410410
/* ── TodoWrite task list widget ────────────────────────────────────── */
411411
.ai-todo-list {
412-
padding: 2px 8px 4px 28px;
412+
padding: 2px 8px 4px 0;
413413
}
414414

415415
.ai-todo-item {
@@ -434,6 +434,9 @@
434434
.ai-todo-content {
435435
color: @project-panel-text-2;
436436
line-height: 1.4;
437+
white-space: normal;
438+
overflow-wrap: break-word;
439+
min-width: 0;
437440

438441
&.completed {
439442
text-decoration: line-through;

0 commit comments

Comments
 (0)