PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
← All changes | src/QuickEdit/lib/ask-ai.js +2 -55 3.1.23.2.1 View file →
@@ -23,31 +23,8 @@
23 23 }
24 24 });
25 25 };
26 26
27 -// Synchronous-readable cache of the agent sidebar's open state. The click
28 -// rule runs in a sync capture-phase listener and can't await a dynamic
29 -// import to choose between today's commit and the silent-stage bridge.
30 -// Watcher is kicked off lazily on first read so a Jest resetModules + doMock
31 -// can swap the agent store before the import resolves.
32 -let cachedSidebarOpen = false;
33 -let watcherStarted = false;
34 -const startSidebarWatcher = () => {
35 - if (watcherStarted || !isAgentAvailable()) return;
36 - watcherStarted = true;
37 - import('@agent/state/global').then(({ useGlobalStore }) => {
38 - cachedSidebarOpen = !!useGlobalStore.getState().open;
39 - useGlobalStore.subscribe((state) => {
40 - cachedSidebarOpen = !!state.open;
41 - });
42 - });
43 -};
44 -
45 -export const isAgentSidebarOpen = () => {
46 - startSidebarWatcher();
47 - return cachedSidebarOpen;
48 -};
49 -
50 27 const findAgentTagged = (el) => {
51 28 let node = el;
52 29 while (node && node !== document.body) {
53 30 if (node.hasAttribute?.(AGENT_ATTR) || node.hasAttribute?.(AGENT_PART_ID)) {
@@ -57,18 +34,8 @@
57 34 }
58 35 return null;
59 36 };
60 37
61 -// Bridges the gap between the click and the Agent's own selection
62 -// outline (which renders after panel mount + ResizeObserver settles).
63 -const flashSelection = (el) => {
64 - if (!el) return;
65 - el.classList.add('extendify-quick-edit-ask-flash');
66 - window.setTimeout(() => {
67 - el.classList.remove('extendify-quick-edit-ask-flash');
68 - }, 1500);
69 -};
70 -
71 38 // Focus the agent chat textarea so the user can type their request right
72 39 // away. The textarea is created when the panel mounts; the brief retry
73 40 // covers the open-from-closed case where it isn't in the DOM yet (when the
74 41 // sidebar is already open it's found on the first try). preventScroll keeps
@@ -73,8 +40,10 @@
73 40 // covers the open-from-closed case where it isn't in the DOM yet (when the
74 41 // sidebar is already open it's found on the first try). preventScroll keeps
75 42 // the block the user just clicked in view rather than yanking to the chat.
76 43 const focusChatInput = (tries = 20) => {
44 + // Pinning a block puts focus on its pill; a late retry would yank it away.
45 + if (document.activeElement?.closest?.('.extendify-quick-edit-bar')) return;
77 46 const ta = document.querySelector('#extendify-agent-chat-textarea');
78 47 if (ta) {
79 48 ta.focus({ preventScroll: true });
80 49 return;
@@ -81,34 +50,12 @@
81 50 }
82 51 if (tries > 0) setTimeout(() => focusChatInput(tries - 1), 50);
83 52 };
84 53
85 -// Stage a block for the already-open agent. No setOpen — the sidebar is
86 -// already up — but we DO focus the chat so the cursor lands ready to type,
87 -// matching the Ask AI pill and the selector behavior on a fresh open. The
88 -// visual bridge is the same flash + the agent's DOMHighlighter outline that
89 -// engages once agentBlock is set.
90 -export const stageAgentBlock = (el) => {
91 - if (!isAgentAvailable()) return;
92 - const match = findAgentTagged(el);
93 - if (!match) return;
94 - flashSelection(match);
95 - const next = buildAgentBlockDescriptor(match);
96 - const current = useQuickEditStore.getState().agentBlock;
97 - if (!current || current.id !== next.id || current.target !== next.target) {
98 - useQuickEditStore.setState({
99 - agentBlock: next,
100 - agentBlockCode: null,
101 - });
102 - }
103 - focusChatInput();
104 -};
105 -
106 54 export const askAiAboutElement = async (el) => {
107 55 if (!isAgentAvailable()) return;
108 56
109 57 const match = findAgentTagged(el);
110 - flashSelection(match || el);
111 58
112 59 // setBlock before setOpen so DOMHighlighter sees the block on mount.
113 60 const { useGlobalStore } = await import('@agent/state/global');
114 61 const { useEditModeStore } = await import('@quick-edit/state/edit-mode');