PluginProbe
Extendify / trunk
Extendify vtrunk
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.2 → trunk 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');