@atlaskit/editor-plugin-mentions 18.2.7 → 18.2.9

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.
@@ -6,27 +6,17 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.ACTIONS = void 0;
8
8
  exports.createMentionPlugin = createMentionPlugin;
9
- exports.resolveAndDispatchPastedAgentMentionName = void 0;
10
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
10
  var _analytics = require("@atlaskit/editor-common/analytics");
13
11
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
14
- var _view = require("@atlaskit/editor-prosemirror/view");
15
12
  var _insm = require("@atlaskit/insm");
16
13
  var _resource = require("@atlaskit/mention/resource");
17
14
  var _types = require("@atlaskit/mention/types");
18
- var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
19
15
  var _fg = require("@atlaskit/platform-feature-flags/fg");
20
- var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment");
21
16
  var _mentionNodeView = require("../nodeviews/mentionNodeView");
22
17
  var _types2 = require("../types");
23
- var _agentMentionContext = require("./agent-mention-context");
24
- var _agentRunState = require("./agent-run-state");
25
18
  var _key = require("./key");
26
19
  var _utils = require("./utils");
27
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
28
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
29
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
30
20
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
31
21
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
32
22
  var ACTIONS = exports.ACTIONS = {
@@ -52,29 +42,8 @@ var ACTIONS = exports.ACTIONS = {
52
42
  */
53
43
  CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION'
54
44
  };
55
-
56
- // 'AGENT' is not in the ADF schema UserType enum but is used at runtime.
57
-
58
- var AGENT_USER_TYPES = new Set(['APP', 'AGENT']);
59
- var isAgentUserType = function isAgentUserType(userType) {
60
- return typeof userType === 'string' && AGENT_USER_TYPES.has(userType);
61
- };
62
- var getAgentMentionName = function getAgentMentionName(text, fallbackName) {
63
- var trimmedFallbackName = typeof fallbackName === 'string' ? fallbackName.trim() : '';
64
- var normalizedFallbackName = (trimmedFallbackName.startsWith('@') ? trimmedFallbackName.slice(1).trim() : trimmedFallbackName) || null;
65
- if (typeof text !== 'string') {
66
- return normalizedFallbackName;
67
- }
68
- var trimmedText = text.trim();
69
- var displayName = trimmedText.startsWith('@') ? trimmedText.slice(1).trim() : trimmedText;
70
- var normalizedName = displayName || normalizedFallbackName;
71
- return normalizedName;
72
- };
73
- var AI_STREAMING_TRANSFORMATION_META_KEY = 'isAIStreamingTransformation';
74
- var AGENT_MENTION_INACTIVITY_MS = 3000;
75
- var MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS = 20;
76
45
  var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
77
- var PACKAGE_VERSION = "18.2.6";
46
+ var PACKAGE_VERSION = "18.2.8";
78
47
  var setProvider = function setProvider(provider) {
79
48
  return function (state, dispatch) {
80
49
  if (dispatch) {
@@ -88,277 +57,11 @@ var setProvider = function setProvider(provider) {
88
57
  return true;
89
58
  };
90
59
  };
91
-
92
- /**
93
- * Returns true when a transaction represents a local user document edit that
94
- * should restart pending agent-mention inactivity tracking.
95
- *
96
- * Remote/collab updates, replace-document transactions, AI streaming transforms,
97
- * selection-only movements, and metadata-only transactions are intentionally ignored.
98
- */
99
- var isQualifyingLocalUserDocChange = function isQualifyingLocalUserDocChange(tr) {
100
- var isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
101
- return tr.docChanged && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
102
- };
103
- var isLocalSelectionChange = function isLocalSelectionChange(tr, hasPositionChanged) {
104
- var isAIStreaming = Boolean(tr.getMeta(AI_STREAMING_TRANSFORMATION_META_KEY));
105
-
106
- // Pressing Enter can move selection through a doc split without setting tr.selectionSet
107
- // or changing from/to numerically, so local doc changes are checked against the
108
- // pending mention's current parent before publishing.
109
- return (hasPositionChanged || tr.docChanged) && !tr.getMeta('isRemote') && !tr.getMeta('replaceDocument') && !isAIStreaming;
110
- };
111
-
112
- /**
113
- * Reads agent-mention details from a known document position without traversing
114
- * the document. Callers pass a matcher so mapped positions are only accepted
115
- * when they still point at the same pending/tracked mention.
116
- */
117
- var getAgentMentionDetailsAtPos = function getAgentMentionDetailsAtPos(state, pos, matchesMention, fallbackName) {
118
- var _parentNode$type$name;
119
- if (pos < 0 || pos > state.doc.content.size) {
120
- return null;
121
- }
122
- var node = state.doc.nodeAt(pos);
123
- var mentionSchema = state.schema.nodes.mention;
124
- if ((node === null || node === void 0 ? void 0 : node.type) !== mentionSchema || !isAgentUserType(node.attrs.userType) || !matchesMention(node.attrs) || !node.attrs.id || !node.attrs.localId) {
125
- return null;
126
- }
127
- var $mentionPos = state.doc.resolve(Math.min(pos + node.nodeSize, state.doc.content.size));
128
- var parentNode = $mentionPos.node($mentionPos.depth);
129
- var id = node.attrs.id;
130
- var name = getAgentMentionName(node.attrs.text, fallbackName);
131
- return {
132
- id: id,
133
- localId: node.attrs.localId,
134
- context: (0, _agentMentionContext.getAgentMentionParentContext)(parentNode, node.attrs.localId),
135
- name: name,
136
- prompt: parentNode.textContent.trim() || null,
137
- nodeSize: node.nodeSize,
138
- parentEnd: $mentionPos.end($mentionPos.depth),
139
- parentNodeType: (_parentNode$type$name = parentNode.type.name) !== null && _parentNode$type$name !== void 0 ? _parentNode$type$name : null,
140
- parentStart: $mentionPos.start($mentionPos.depth),
141
- pos: pos
142
- };
143
- };
144
-
145
- /**
146
- * Finds an agent mention that survived a document change when the changed-range
147
- * scan did not find one. Uses the tracked localId as the mention instance identity
148
- * so same-agent mentions elsewhere in the document cannot be selected as fallback.
149
- */
150
- var getSurvivingAgentMentionDetails = function getSurvivingAgentMentionDetails(state, preferredLocalId, preferredName) {
151
- var mentionSchema = state.schema.nodes.mention;
152
- var result = null;
153
- state.doc.descendants(function (node, pos) {
154
- if (result) {
155
- return false;
156
- }
157
- if (node.type !== mentionSchema || !isAgentUserType(node.attrs.userType) || node.attrs.localId !== preferredLocalId) {
158
- return true;
159
- }
160
- result = getAgentMentionDetailsAtPos(state, pos, function (attrs) {
161
- return attrs.localId === preferredLocalId;
162
- }, preferredName);
163
- return !result;
164
- });
165
- return result;
166
- };
167
-
168
- /**
169
- * Maps a pending typed agent mention through a document-changing transaction and
170
- * returns the updated pending state. If the mapped position was deleted or no
171
- * longer points at the same local mention, the pending mention is cleared.
172
- */
173
- var getPendingTypedAgentMentionAfterDocChange = function getPendingTypedAgentMentionAfterDocChange(state, tr, pendingTypedAgentMention, _ref) {
174
- var resetTimer = _ref.resetTimer;
175
- var mappedPos = tr.mapping.mapResult(pendingTypedAgentMention.pos, 1);
176
- var resetCount = resetTimer ? pendingTypedAgentMention.resetCount + 1 : pendingTypedAgentMention.resetCount;
177
- if (mappedPos.deleted) {
178
- return null;
179
- }
180
- var pendingMentionDetails = getAgentMentionDetailsAtPos(state, mappedPos.pos, function (attrs) {
181
- return attrs.localId === pendingTypedAgentMention.localId;
182
- }, pendingTypedAgentMention.name);
183
- return pendingMentionDetails ? {
184
- id: pendingMentionDetails.id,
185
- localId: pendingTypedAgentMention.localId,
186
- name: pendingMentionDetails.name,
187
- nodeSize: pendingMentionDetails.nodeSize,
188
- parentNodeType: pendingMentionDetails.parentNodeType,
189
- pos: pendingMentionDetails.pos,
190
- resetCount: resetCount
191
- } : null;
192
- };
193
- var hasPendingMentionMovedToNewParent = function hasPendingMentionMovedToNewParent(oldState, tr, previousPendingTypedAgentMention, pendingMentionDetails) {
194
- if (!previousPendingTypedAgentMention) {
195
- return false;
196
- }
197
- var previousMentionDetails = getAgentMentionDetailsAtPos(oldState, previousPendingTypedAgentMention.pos, function (attrs) {
198
- return attrs.localId === previousPendingTypedAgentMention.localId;
199
- });
200
-
201
- // Keep the previous parent boundary associated with the left side of an
202
- // insertion at that boundary, so typing at the start of the parent does not
203
- // look like the pending mention moved into a new parent.
204
- var mappedPreviousParentStart = previousMentionDetails && tr.mapping.map(previousMentionDetails.parentStart, -1);
205
- return Boolean(previousMentionDetails && mappedPreviousParentStart !== pendingMentionDetails.parentStart);
206
- };
207
- var isSelectionOutsideDirectParent = function isSelectionOutsideDirectParent(state, pendingMentionDetails) {
208
- return state.selection.from < pendingMentionDetails.parentStart || state.selection.to > pendingMentionDetails.parentEnd;
209
- };
210
-
211
- /**
212
- * Finalises a pending typed agent mention by copying its details into the
213
- * public lastInserted* plugin state after the caller has already resolved the
214
- * pending mention from the current document.
215
- */
216
- var commitResolvedPendingTypedAgentMention = function commitResolvedPendingTypedAgentMention(pluginState, pendingMentionDetails) {
217
- var _pluginState$lastAgen;
218
- return {
219
- hasPublicPluginStateChanged: true,
220
- pluginState: _objectSpread(_objectSpread({}, pluginState), {}, {
221
- pendingTypedAgentMention: null,
222
- lastInsertedAgentMentionId: pendingMentionDetails.id,
223
- lastInsertedAgentMentionLocalId: pendingMentionDetails.localId,
224
- lastInsertedAgentMentionContext: pendingMentionDetails.context,
225
- lastInsertedAgentMentionName: pendingMentionDetails.name,
226
- lastInsertedAgentMentionPrompt: pendingMentionDetails.prompt,
227
- lastInsertedAgentMentionParentNodeType: pendingMentionDetails.parentNodeType,
228
- lastAgentMentionInsertionCount: ((_pluginState$lastAgen = pluginState.lastAgentMentionInsertionCount) !== null && _pluginState$lastAgen !== void 0 ? _pluginState$lastAgen : 0) + 1
229
- })
230
- };
231
- };
232
-
233
- /**
234
- * Resolves and finalises a pending typed agent mention. If the tracked mention
235
- * no longer resolves, the stale pending state is cleared without dispatching a
236
- * public update.
237
- */
238
- var commitPendingTypedAgentMention = function commitPendingTypedAgentMention(state, pluginState, pendingTypedAgentMention) {
239
- var pendingMentionDetails = getAgentMentionDetailsAtPos(state, pendingTypedAgentMention.pos, function (attrs) {
240
- return attrs.localId === pendingTypedAgentMention.localId;
241
- }, pendingTypedAgentMention.name);
242
- if (!pendingMentionDetails) {
243
- return {
244
- hasPublicPluginStateChanged: false,
245
- pluginState: _objectSpread(_objectSpread({}, pluginState), {}, {
246
- pendingTypedAgentMention: null
247
- })
248
- };
249
- }
250
- return commitResolvedPendingTypedAgentMention(pluginState, pendingMentionDetails);
251
- };
252
- var hasTrackedAgentMentionState = function hasTrackedAgentMentionState(pluginState) {
253
- return Boolean(pluginState.pendingTypedAgentMention) || Boolean(pluginState.pendingPastedAgentMention) && (0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes') || pluginState.lastInsertedAgentMentionId != null || pluginState.lastInsertedAgentMentionLocalId != null || pluginState.lastInsertedAgentMentionContext != null || pluginState.lastInsertedAgentMentionName != null || pluginState.lastInsertedAgentMentionPrompt != null || pluginState.lastInsertedAgentMentionParentNodeType != null;
254
- };
255
-
256
- /**
257
- * Clears agent mention state that points at a specific document snapshot.
258
- * replaceDocument swaps content wholesale, so pending typed mentions and
259
- * lastInserted* details from the previous document must be cleared together.
260
- */
261
- var clearTrackedAgentMentionState = function clearTrackedAgentMentionState(pluginState) {
262
- return _objectSpread(_objectSpread(_objectSpread({}, pluginState), {}, {
263
- pendingTypedAgentMention: null
264
- }, (0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes') ? {
265
- pendingPastedAgentMention: null
266
- } : {}), {}, {
267
- lastInsertedAgentMentionId: null,
268
- lastInsertedAgentMentionLocalId: null,
269
- lastInsertedAgentMentionContext: null,
270
- lastInsertedAgentMentionName: null,
271
- lastInsertedAgentMentionPrompt: null,
272
- lastInsertedAgentMentionParentNodeType: null
273
- });
274
- };
275
-
276
- /**
277
- * Attempts to synchronously resolve an agent mention name from the mention
278
- * provider's cache. Falls back to undefined if the provider doesn't support
279
- * name resolution, the result is a Promise (async/cache miss), or the status
280
- * is not OK.
281
- */
282
- var resolveCachedAgentMentionName = function resolveCachedAgentMentionName(mentionProvider, params, id) {
283
- if (params !== null && params !== void 0 && params.name || !(0, _resource.isResolvingMentionProvider)(mentionProvider)) {
284
- var _params$name;
285
- return (_params$name = params === null || params === void 0 ? void 0 : params.name) !== null && _params$name !== void 0 ? _params$name : undefined;
286
- }
287
- var result = mentionProvider.resolveMentionName(id);
288
- if (!(result instanceof Promise) && result.status === _resource.MentionNameStatus.OK) {
289
- return result.name || undefined;
290
- }
291
- return undefined;
292
- };
293
-
294
- /**
295
- * Resolves the name of a pasted agent mention via the mention provider and
296
- * dispatches the appropriate action to update plugin state.
297
- *
298
- * Handles both async (Promise) and synchronous cache-hit results:
299
- * - On OK resolution → dispatches RESOLVE_PASTED_AGENT_MENTION_NAME so the nudge
300
- * shows the correct agent name.
301
- * - On non-OK result → dispatches CLEAR_PENDING_PASTED_AGENT_MENTION to prevent
302
- * an infinite retry loop on subsequent update() calls.
303
- *
304
- * Guards against duplicate in-flight requests via pendingResolveMentionIds.
305
- */
306
- var resolveAndDispatchPastedAgentMentionName = exports.resolveAndDispatchPastedAgentMentionName = function resolveAndDispatchPastedAgentMentionName(agentId, mentionProvider, pendingResolveMentionIds, view) {
307
- if (pendingResolveMentionIds.has(agentId)) {
308
- return;
309
- }
310
- pendingResolveMentionIds.add(agentId);
311
- var result = mentionProvider.resolveMentionName(agentId);
312
- if (result instanceof Promise) {
313
- result.then(function (nameDetails) {
314
- pendingResolveMentionIds.delete(agentId);
315
- if (nameDetails.status === _resource.MentionNameStatus.OK && nameDetails.name) {
316
- view.dispatch(view.state.tr.setMeta(_key.mentionPluginKey, {
317
- action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
318
- params: {
319
- id: agentId,
320
- name: nameDetails.name
321
- }
322
- }));
323
- } else {
324
- // Non-OK status — clear pendingPastedAgentMention to prevent
325
- // an infinite retry loop on subsequent update() calls.
326
- view.dispatch(view.state.tr.setMeta(_key.mentionPluginKey, {
327
- action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
328
- params: {
329
- id: agentId
330
- }
331
- }));
332
- }
333
- });
334
- } else if (result.status === _resource.MentionNameStatus.OK && result.name) {
335
- pendingResolveMentionIds.delete(agentId);
336
- // Synchronous hit on a second update cycle (e.g. provider warmed up
337
- // between the paste transaction and this view update).
338
- view.dispatch(view.state.tr.setMeta(_key.mentionPluginKey, {
339
- action: ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME,
340
- params: {
341
- id: agentId,
342
- name: result.name
343
- }
344
- }));
345
- } else {
346
- pendingResolveMentionIds.delete(agentId);
347
- // Non-OK synchronous status — clear pendingPastedAgentMention to prevent
348
- // an infinite retry loop on subsequent update() calls.
349
- view.dispatch(view.state.tr.setMeta(_key.mentionPluginKey, {
350
- action: ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION,
351
- params: {
352
- id: agentId
353
- }
354
- }));
355
- }
356
- };
357
- function createMentionPlugin(_ref2) {
358
- var pmPluginFactoryParams = _ref2.pmPluginFactoryParams,
359
- fireEvent = _ref2.fireEvent,
360
- options = _ref2.options,
361
- api = _ref2.api;
60
+ function createMentionPlugin(_ref) {
61
+ var pmPluginFactoryParams = _ref.pmPluginFactoryParams,
62
+ fireEvent = _ref.fireEvent,
63
+ options = _ref.options,
64
+ api = _ref.api;
362
65
  var mentionProvider;
363
66
  var sendAnalytics = function sendAnalytics(event, actionSubject, action, attributes) {
364
67
  if (event === _resource.SLI_EVENT_TYPE || event === _resource.SMART_EVENT_TYPE) {
@@ -384,13 +87,12 @@ function createMentionPlugin(_ref2) {
384
87
  };
385
88
  },
386
89
  apply: function apply(tr, pluginState, oldState, newState) {
387
- var _params$runStateByLoc;
388
- var _ref3 = tr.getMeta(_key.mentionPluginKey) || {
90
+ var _ref2 = tr.getMeta(_key.mentionPluginKey) || {
389
91
  action: null,
390
92
  params: null
391
93
  },
392
- action = _ref3.action,
393
- params = _ref3.params;
94
+ action = _ref2.action,
95
+ params = _ref2.params;
394
96
  var hasPublicPluginStateChanged = false;
395
97
  var newPluginState = pluginState;
396
98
  var hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to;
@@ -408,78 +110,7 @@ function createMentionPlugin(_ref2) {
408
110
  hasPublicPluginStateChanged = true;
409
111
  break;
410
112
  }
411
- var nextDecorations = (0, _agentRunState.nextRunStateDecorations)(newPluginState.runStateDecorations, tr, newState, action === ACTIONS.SET_AGENT_RUN_STATES ? (_params$runStateByLoc = params === null || params === void 0 ? void 0 : params.runStateByLocalId) !== null && _params$runStateByLoc !== void 0 ? _params$runStateByLoc : {} : undefined);
412
- if (nextDecorations !== newPluginState.runStateDecorations) {
413
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
414
- runStateDecorations: nextDecorations
415
- });
416
- }
417
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true)) {
418
- switch (action) {
419
- case ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION:
420
- {
421
- var pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
422
- // Ignore stale timer callbacks. The localId and resetCount must still match the
423
- // current pending mention so older timers cannot publish after later user edits.
424
- if (!pendingTypedAgentMention || pendingTypedAgentMention.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMention.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
425
- break;
426
- }
427
- var commitResult = commitPendingTypedAgentMention(newState, newPluginState, pendingTypedAgentMention);
428
- newPluginState = commitResult.pluginState;
429
- hasPublicPluginStateChanged = hasPublicPluginStateChanged || commitResult.hasPublicPluginStateChanged;
430
- break;
431
- }
432
- case ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION:
433
- {
434
- // Silently discard the pending typed agent mention without committing it.
435
- var pendingTypedAgentMentionToDiscard = newPluginState.pendingTypedAgentMention;
436
- if (!pendingTypedAgentMentionToDiscard || pendingTypedAgentMentionToDiscard.localId !== (params === null || params === void 0 ? void 0 : params.localId) || pendingTypedAgentMentionToDiscard.resetCount !== (params === null || params === void 0 ? void 0 : params.resetCount)) {
437
- break;
438
- }
439
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
440
- pendingTypedAgentMention: null
441
- });
442
- hasPublicPluginStateChanged = true;
443
- break;
444
- }
445
- case ACTIONS.RESOLVE_PASTED_AGENT_MENTION_NAME:
446
- {
447
- var _newPluginState$pendi, _newPluginState$pendi2, _newPluginState$pendi3, _newPluginState$pendi4, _newPluginState$pendi5, _newPluginState$pendi6;
448
- // Guard: only apply if there is a matching pending pasted mention (staleness check).
449
- if (!(params !== null && params !== void 0 && params.id) || !(params !== null && params !== void 0 && params.name) || ((_newPluginState$pendi = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi === void 0 ? void 0 : _newPluginState$pendi.id) !== params.id || !(0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes')) {
450
- break;
451
- }
452
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
453
- pendingPastedAgentMention: null,
454
- lastInsertedAgentMentionId: (_newPluginState$pendi2 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi2 === void 0 ? void 0 : _newPluginState$pendi2.id,
455
- lastInsertedAgentMentionLocalId: (_newPluginState$pendi3 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi3 === void 0 ? void 0 : _newPluginState$pendi3.localId,
456
- lastInsertedAgentMentionContext: (_newPluginState$pendi4 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi4 === void 0 ? void 0 : _newPluginState$pendi4.context,
457
- lastInsertedAgentMentionName: params.name,
458
- lastInsertedAgentMentionPrompt: (_newPluginState$pendi5 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi5 === void 0 ? void 0 : _newPluginState$pendi5.prompt,
459
- lastInsertedAgentMentionParentNodeType: (_newPluginState$pendi6 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi6 === void 0 ? void 0 : _newPluginState$pendi6.parentNodeType
460
- });
461
- hasPublicPluginStateChanged = true;
462
- break;
463
- }
464
- case ACTIONS.CLEAR_PENDING_PASTED_AGENT_MENTION:
465
- {
466
- var _newPluginState$pendi7;
467
- if (!(params !== null && params !== void 0 && params.id) || ((_newPluginState$pendi7 = newPluginState.pendingPastedAgentMention) === null || _newPluginState$pendi7 === void 0 ? void 0 : _newPluginState$pendi7.id) !== params.id || !(0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes')) {
468
- break;
469
- }
470
- // resolveMentionName() returned a non-OK status — clear the pending state.
471
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
472
- pendingPastedAgentMention: null
473
- });
474
- break;
475
- }
476
- }
477
- }
478
-
479
- // When the agent mentions experiment is off, dispatch immediately (original behaviour).
480
- // When it's on, defer dispatch to after the agent tracking block below so that
481
- // agent-mention state changes are included in the notification.
482
- if (hasPublicPluginStateChanged && ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') || !(0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true))) {
113
+ if (hasPublicPluginStateChanged) {
483
114
  pmPluginFactoryParams.dispatch(_key.mentionPluginKey, newPluginState);
484
115
  }
485
116
  if (options !== null && options !== void 0 && options.handleMentionsChanged && tr.docChanged) {
@@ -541,297 +172,6 @@ function createMentionPlugin(_ref2) {
541
172
  }
542
173
  (_insm$session2 = _insm.insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('mentionDeletionDetection');
543
174
  }
544
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true) && isQualifyingLocalUserDocChange(tr)) {
545
- var _mentionSchema = newState.schema.nodes.mention;
546
- var newDocRanges = [];
547
- var oldDocRanges = [];
548
- var stepsTouchMentions = false;
549
- tr.steps.forEach(function (step) {
550
- var found = false;
551
- // Only merge a step's ranges if it actually touched an agent mention,
552
- // so unrelated steps (e.g. mark-only changes) don't inflate the scan area.
553
- var stepNewRanges = [];
554
- var stepOldRanges = [];
555
- step.getMap().forEach(function (oldFrom, oldTo, newFrom, newTo) {
556
- stepOldRanges.push([oldFrom, oldTo]);
557
- stepNewRanges.push([newFrom, newTo]);
558
- if (!found) {
559
- // Clamp positions: delete-only steps can produce newTo > doc.content.size.
560
- var clampedNewFrom = Math.min(newFrom, newState.doc.content.size);
561
- var clampedNewTo = Math.min(newTo, newState.doc.content.size);
562
- if (clampedNewFrom < clampedNewTo) {
563
- newState.doc.nodesBetween(clampedNewFrom, clampedNewTo, function (node) {
564
- if (node.type === _mentionSchema && isAgentUserType(node.attrs.userType)) {
565
- found = true;
566
- }
567
- return !found;
568
- });
569
- }
570
- if (!found) {
571
- var clampedOldFrom = Math.min(oldFrom, oldState.doc.content.size);
572
- var clampedOldTo = Math.min(oldTo, oldState.doc.content.size);
573
- if (clampedOldFrom < clampedOldTo) {
574
- oldState.doc.nodesBetween(clampedOldFrom, clampedOldTo, function (node) {
575
- if (node.type === _mentionSchema && AGENT_USER_TYPES.has(node.attrs.userType)) {
576
- found = true;
577
- }
578
- return !found;
579
- });
580
- }
581
- }
582
- }
583
- });
584
- if (found) {
585
- stepsTouchMentions = true;
586
- newDocRanges.push.apply(newDocRanges, stepNewRanges);
587
- oldDocRanges.push.apply(oldDocRanges, stepOldRanges);
588
- }
589
- });
590
- var shouldResolveAgentMentionState = stepsTouchMentions || Boolean(newPluginState.lastInsertedAgentMentionLocalId);
591
- if (shouldResolveAgentMentionState) {
592
- var _newPluginState$lastI, _newPluginState$lastA, _newPluginState$lastI2, _newPluginState$lastI3, _newPluginState$lastI4, _newPluginState$lastI5, _newPluginState$lastI6;
593
- var agentMentionId = null;
594
- var agentMentionLocalId = null;
595
- var agentMentionContext = null;
596
- var agentMentionName = null;
597
- var agentMentionPrompt = null;
598
- var agentMentionParentNodeType = null;
599
- var existingAgentMentionLocalIdsInChangedRanges = new Set();
600
- var pendingTypedAgentMentionDetails = null;
601
- if (stepsTouchMentions) {
602
- var _iterator = _createForOfIteratorHelper(newDocRanges),
603
- _step;
604
- try {
605
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
606
- var _step$value = (0, _slicedToArray2.default)(_step.value, 2),
607
- from = _step$value[0],
608
- to = _step$value[1];
609
- var clampedTo = Math.min(to, newState.doc.content.size);
610
- if (from >= clampedTo) {
611
- continue;
612
- }
613
- newState.doc.nodesBetween(from, clampedTo, function (node, pos) {
614
- if (node.type !== _mentionSchema || !isAgentUserType(node.attrs.userType)) {
615
- return true;
616
- }
617
- if (pendingTypedAgentMentionDetails === null && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && node.attrs.localId === (params === null || params === void 0 ? void 0 : params.localId)) {
618
- pendingTypedAgentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, function (attrs) {
619
- return attrs.localId === params.localId;
620
- }, params.name);
621
- }
622
- if (agentMentionLocalId === null && node.attrs.localId) {
623
- // Try to recover the name synchronously from the mention provider's
624
- // name cache (populated by cacheMentionName on typed insert).
625
- var cachedName = (0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes') ? resolveCachedAgentMentionName(mentionProvider, params, node.attrs.id) : params === null || params === void 0 ? void 0 : params.name;
626
- var agentMentionDetails = getAgentMentionDetailsAtPos(newState, pos, function (attrs) {
627
- return attrs.localId === node.attrs.localId;
628
- }, cachedName);
629
- if (agentMentionDetails) {
630
- agentMentionId = agentMentionDetails.id;
631
- agentMentionLocalId = agentMentionDetails.localId;
632
- agentMentionContext = agentMentionDetails.context;
633
- agentMentionName = agentMentionDetails.name;
634
- agentMentionPrompt = agentMentionDetails.prompt;
635
- agentMentionParentNodeType = agentMentionDetails.parentNodeType;
636
- }
637
- }
638
- return true;
639
- });
640
- }
641
- } catch (err) {
642
- _iterator.e(err);
643
- } finally {
644
- _iterator.f();
645
- }
646
- var _iterator2 = _createForOfIteratorHelper(oldDocRanges),
647
- _step2;
648
- try {
649
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
650
- var _step2$value = (0, _slicedToArray2.default)(_step2.value, 2),
651
- _from = _step2$value[0],
652
- _to = _step2$value[1];
653
- var clampedOldTo = Math.min(_to, oldState.doc.content.size);
654
- if (_from >= clampedOldTo) {
655
- continue;
656
- }
657
- oldState.doc.nodesBetween(_from, clampedOldTo, function (node) {
658
- if (node.type !== _mentionSchema || !isAgentUserType(node.attrs.userType)) {
659
- return true;
660
- }
661
- if (node.attrs.localId) {
662
- existingAgentMentionLocalIdsInChangedRanges.add(node.attrs.localId);
663
- }
664
- return true;
665
- });
666
- }
667
- } catch (err) {
668
- _iterator2.e(err);
669
- } finally {
670
- _iterator2.f();
671
- }
672
- }
673
-
674
- // When a deletion collapses the new-doc range to a zero-width point, or when
675
- // the doc changed but no step covered the tracked mention, the new-doc scan
676
- // above finds nothing. Check whether any agent mention survived in the document.
677
- var resolvedFromFullDocFallback = false;
678
- if (agentMentionId === null && newPluginState.lastInsertedAgentMentionLocalId) {
679
- var survivorDetails = getSurvivingAgentMentionDetails(newState, newPluginState.lastInsertedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName);
680
- if (survivorDetails) {
681
- agentMentionId = survivorDetails.id;
682
- agentMentionLocalId = survivorDetails.localId;
683
- agentMentionContext = survivorDetails.context;
684
- agentMentionName = survivorDetails.name;
685
- agentMentionPrompt = survivorDetails.prompt;
686
- agentMentionParentNodeType = survivorDetails.parentNodeType;
687
- resolvedFromFullDocFallback = true;
688
- }
689
- }
690
- var trackedAgentMentionLocalId = (_newPluginState$lastI = newPluginState.lastInsertedAgentMentionLocalId) !== null && _newPluginState$lastI !== void 0 ? _newPluginState$lastI : null;
691
- var changedRangeMentionIsNew = agentMentionLocalId !== null && !existingAgentMentionLocalIdsInChangedRanges.has(agentMentionLocalId);
692
- if (agentMentionLocalId !== null && !changedRangeMentionIsNew && agentMentionLocalId !== trackedAgentMentionLocalId) {
693
- var _survivorDetails = trackedAgentMentionLocalId ? getSurvivingAgentMentionDetails(newState, trackedAgentMentionLocalId, newPluginState.lastInsertedAgentMentionName) : null;
694
- if (_survivorDetails) {
695
- agentMentionId = _survivorDetails.id;
696
- agentMentionLocalId = _survivorDetails.localId;
697
- agentMentionContext = _survivorDetails.context;
698
- agentMentionName = _survivorDetails.name;
699
- agentMentionParentNodeType = _survivorDetails.parentNodeType;
700
- resolvedFromFullDocFallback = true;
701
- } else {
702
- agentMentionId = null;
703
- agentMentionLocalId = null;
704
- agentMentionContext = null;
705
- agentMentionName = null;
706
- agentMentionParentNodeType = null;
707
- }
708
- }
709
- var isNewInsertion = agentMentionId !== null && !resolvedFromFullDocFallback && changedRangeMentionIsNew;
710
- var isPendingTypedAgentMentionInsertion = isNewInsertion && action === ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && typeof (params === null || params === void 0 ? void 0 : params.localId) === 'string';
711
- var newInsertionCount = isNewInsertion ? ((_newPluginState$lastA = newPluginState.lastAgentMentionInsertionCount) !== null && _newPluginState$lastA !== void 0 ? _newPluginState$lastA : 0) + 1 : undefined;
712
- var pendingTypedAgentMentionDetailsForState = pendingTypedAgentMentionDetails;
713
- if (isPendingTypedAgentMentionInsertion && pendingTypedAgentMentionDetailsForState) {
714
- var pendingTypedAgentMentionLocalId = params === null || params === void 0 ? void 0 : params.localId;
715
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
716
- pendingTypedAgentMention: {
717
- id: pendingTypedAgentMentionDetailsForState.id,
718
- localId: pendingTypedAgentMentionLocalId,
719
- name: pendingTypedAgentMentionDetailsForState.name,
720
- nodeSize: pendingTypedAgentMentionDetailsForState.nodeSize,
721
- parentNodeType: pendingTypedAgentMentionDetailsForState.parentNodeType,
722
- pos: pendingTypedAgentMentionDetailsForState.pos,
723
- resetCount: 1
724
- }
725
- });
726
- } else if (isPendingTypedAgentMentionInsertion) {
727
- // Fallback: if the localId-specific scan missed the typed mention,
728
- // publish immediately so the insertion is not dropped.
729
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
730
- pendingTypedAgentMention: null,
731
- lastInsertedAgentMentionId: agentMentionId,
732
- lastInsertedAgentMentionLocalId: agentMentionLocalId,
733
- lastInsertedAgentMentionContext: agentMentionContext,
734
- lastInsertedAgentMentionName: agentMentionName,
735
- lastInsertedAgentMentionPrompt: agentMentionPrompt,
736
- lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType
737
- }, newInsertionCount !== undefined ? {
738
- lastAgentMentionInsertionCount: newInsertionCount
739
- } : {});
740
- hasPublicPluginStateChanged = true;
741
- } else if (agentMentionId !== ((_newPluginState$lastI2 = newPluginState.lastInsertedAgentMentionId) !== null && _newPluginState$lastI2 !== void 0 ? _newPluginState$lastI2 : null) || agentMentionLocalId !== ((_newPluginState$lastI3 = newPluginState.lastInsertedAgentMentionLocalId) !== null && _newPluginState$lastI3 !== void 0 ? _newPluginState$lastI3 : null) || agentMentionName !== ((_newPluginState$lastI4 = newPluginState.lastInsertedAgentMentionName) !== null && _newPluginState$lastI4 !== void 0 ? _newPluginState$lastI4 : null) || agentMentionPrompt !== ((_newPluginState$lastI5 = newPluginState.lastInsertedAgentMentionPrompt) !== null && _newPluginState$lastI5 !== void 0 ? _newPluginState$lastI5 : null) || agentMentionParentNodeType !== ((_newPluginState$lastI6 = newPluginState.lastInsertedAgentMentionParentNodeType) !== null && _newPluginState$lastI6 !== void 0 ? _newPluginState$lastI6 : null) || newInsertionCount !== undefined) {
742
- var _options$getIsRovoPan;
743
- // Suppress the nudge for pasted/non-typed agent mentions when Rovo is already
744
- // open.
745
- // Task items are exempt only while
746
- // platform_editor_agent_mentions_no_task_autofire is off (they auto-fire
747
- // instead). With it on they are suppressed like every other block.
748
- var isTaskItemMentionForPaste = agentMentionParentNodeType === 'taskItem' && !(0, _fg.fg)('platform_editor_agent_mentions_no_task_autofire');
749
- if (!isTaskItemMentionForPaste && isNewInsertion && options !== null && options !== void 0 && (_options$getIsRovoPan = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan !== void 0 && _options$getIsRovoPan.call(options)) {
750
- // Rovo is already open — skip setting lastInsertedAgentMention* so the
751
- // downstream nudge listener never fires.
752
- } else if (agentMentionName === null && agentMentionId !== null && (0, _resource.isResolvingMentionProvider)(newPluginState.mentionProvider) && (0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes')) {
753
- // Store details in pendingPastedAgentMention (private, not broadcast), preventing a double-nudge.
754
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
755
- pendingPastedAgentMention: {
756
- id: agentMentionId,
757
- localId: agentMentionLocalId,
758
- context: agentMentionContext,
759
- prompt: agentMentionPrompt,
760
- parentNodeType: agentMentionParentNodeType
761
- }
762
- }, newInsertionCount !== undefined ? {
763
- lastAgentMentionInsertionCount: newInsertionCount
764
- } : {});
765
- // the nudge does not fire until the name is resolved.
766
- } else {
767
- // Not suppressed — update state so the nudge fires normally.
768
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
769
- lastInsertedAgentMentionId: agentMentionId,
770
- lastInsertedAgentMentionLocalId: agentMentionLocalId,
771
- lastInsertedAgentMentionContext: agentMentionContext,
772
- lastInsertedAgentMentionName: agentMentionName,
773
- lastInsertedAgentMentionPrompt: agentMentionPrompt,
774
- lastInsertedAgentMentionParentNodeType: agentMentionParentNodeType
775
- }, newInsertionCount !== undefined ? {
776
- lastAgentMentionInsertionCount: newInsertionCount
777
- } : {});
778
- hasPublicPluginStateChanged = true;
779
- }
780
- }
781
- }
782
- }
783
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true) && tr.docChanged && tr.getMeta('replaceDocument') && hasTrackedAgentMentionState(newPluginState)) {
784
- newPluginState = clearTrackedAgentMentionState(newPluginState);
785
- hasPublicPluginStateChanged = true;
786
- }
787
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true) && newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && tr.docChanged) {
788
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
789
- pendingTypedAgentMention: getPendingTypedAgentMentionAfterDocChange(newState, tr, newPluginState.pendingTypedAgentMention, {
790
- resetTimer: isQualifyingLocalUserDocChange(tr)
791
- })
792
- });
793
- }
794
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true)) {
795
- // Typed agent mentions stay pending while the user is still editing around them,
796
- // but leaving the mention's direct parent means they have moved on from that
797
- // paragraph/block. Publish immediately in that case instead of waiting for the
798
- // inactivity timer.
799
- var shouldCheckPendingTypedAgentMentionParent = isLocalSelectionChange(tr, hasPositionChanged);
800
- if (newPluginState.pendingTypedAgentMention && action !== ACTIONS.SET_PENDING_TYPED_AGENT_MENTION && action !== ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION && shouldCheckPendingTypedAgentMentionParent) {
801
- var _pendingTypedAgentMention = newPluginState.pendingTypedAgentMention;
802
- var pendingMentionDetails = getAgentMentionDetailsAtPos(newState, _pendingTypedAgentMention.pos, function (attrs) {
803
- return attrs.localId === _pendingTypedAgentMention.localId;
804
- }, _pendingTypedAgentMention.name);
805
- if (!pendingMentionDetails) {
806
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
807
- pendingTypedAgentMention: null
808
- });
809
- } else if (hasPendingMentionMovedToNewParent(oldState, tr, pluginState.pendingTypedAgentMention, pendingMentionDetails) || isSelectionOutsideDirectParent(newState, pendingMentionDetails)) {
810
- var _options$getIsRovoPan2;
811
- // Suppress the nudge when Rovo chat is already open, mirroring the same
812
- // guard used in the inactivity-timer path. Task-item mentions are
813
- // exempt only while platform_editor_agent_mentions_no_task_autofire is off
814
- // (they auto-fire the mini modal and never show a nudge). With it on they
815
- // are suppressed like any block.
816
- var isTaskItemMention = pendingMentionDetails.parentNodeType === 'taskItem' && !(0, _fg.fg)('platform_editor_agent_mentions_no_task_autofire');
817
- if (!isTaskItemMention && options !== null && options !== void 0 && (_options$getIsRovoPan2 = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan2 !== void 0 && _options$getIsRovoPan2.call(options)) {
818
- // Discard without committing so lastInsertedAgentMention* fields are
819
- // never set and the downstream nudge listener never fires.
820
- newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, {
821
- pendingTypedAgentMention: null
822
- });
823
- hasPublicPluginStateChanged = true;
824
- } else {
825
- var _commitResult = commitResolvedPendingTypedAgentMention(newPluginState, pendingMentionDetails);
826
- newPluginState = _commitResult.pluginState;
827
- hasPublicPluginStateChanged = hasPublicPluginStateChanged || _commitResult.hasPublicPluginStateChanged;
828
- }
829
- }
830
- }
831
- }
832
- if (hasPublicPluginStateChanged && !(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') && (0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true)) {
833
- pmPluginFactoryParams.dispatch(_key.mentionPluginKey, newPluginState);
834
- }
835
175
  return newPluginState;
836
176
  }
837
177
  },
@@ -845,129 +185,9 @@ function createMentionPlugin(_ref2) {
845
185
  portalProviderAPI: pmPluginFactoryParams.portalProviderAPI
846
186
  });
847
187
  }
848
- },
849
- // Duplicated in platform/packages/editor/editor-plugin-mentions/src/pm-plugins/agent.ts
850
- // Can remove once platform_editor_agent_mentions_separate_pm_plugin has been cleaned up
851
- decorations: function decorations(state) {
852
- var _mentionPluginKey$get;
853
- var runStateDecorations = (_mentionPluginKey$get = _key.mentionPluginKey.getState(state)) === null || _mentionPluginKey$get === void 0 ? void 0 : _mentionPluginKey$get.runStateDecorations;
854
- if (!runStateDecorations || runStateDecorations === _view.DecorationSet.empty) {
855
- return undefined;
856
- }
857
- if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') || !(0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true) || !(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mention_state_anim')) {
858
- return undefined;
859
- }
860
- return runStateDecorations;
861
188
  }
862
189
  },
863
190
  view: function view(editorView) {
864
- var pendingTypedAgentMentionTimer;
865
- var pendingTypedAgentMentionTimerKey = null;
866
- var pendingTypedAgentMentionFocusDeferCount = 0;
867
- // Tracks agent IDs for which resolveMentionName() is already in-flight,
868
- // preventing duplicate concurrent Promises for the same ID across update() cycles.
869
- var pendingResolveMentionIds = new Set();
870
-
871
- /**
872
- * Clears the currently scheduled pending typed-agent-mention timer.
873
- *
874
- * By default this also resets the focus defer count because a new pending mention,
875
- * local edit reset, or cleanup should start a fresh escape-hatch window. Focus-based
876
- * retries pass `preserveFocusDeferCount` so repeated defers for the same pending
877
- * mention are counted toward the bounded retry cap.
878
- */
879
- var clearPendingTypedAgentMentionTimer = function clearPendingTypedAgentMentionTimer() {
880
- var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
881
- _ref4$preserveFocusDe = _ref4.preserveFocusDeferCount,
882
- preserveFocusDeferCount = _ref4$preserveFocusDe === void 0 ? false : _ref4$preserveFocusDe;
883
- if (pendingTypedAgentMentionTimer) {
884
- clearTimeout(pendingTypedAgentMentionTimer);
885
- pendingTypedAgentMentionTimer = undefined;
886
- }
887
- pendingTypedAgentMentionTimerKey = null;
888
- if (!preserveFocusDeferCount) {
889
- pendingTypedAgentMentionFocusDeferCount = 0;
890
- }
891
- };
892
-
893
- /**
894
- * Typed agent mentions intentionally wait before invoking the agent so content the
895
- * user adds next can become context. That context can be authored through
896
- * editor-adjacent UI, such as mention typeahead, date picker, or status picker,
897
- * where focus leaves the ProseMirror editor but remains in the active document.
898
- * Treat that as continued authoring activity by restarting the inactivity window.
899
- * This only defers the inactivity timer path: existing selection-change handling can
900
- * still publish or clear the pending mention sooner. After 20 focus defers (~1 minute),
901
- * publish anyway so pathological focus states cannot keep the mention pending indefinitely.
902
- */
903
- var shouldDeferPendingTypedAgentMention = function shouldDeferPendingTypedAgentMention() {
904
- return typeof document !== 'undefined' && document.hasFocus() && !editorView.hasFocus();
905
- };
906
- var _schedulePendingTypedAgentMentionTimer = function schedulePendingTypedAgentMentionTimer(mentionPluginState) {
907
- var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
908
- _ref5$preserveFocusDe = _ref5.preserveFocusDeferCount,
909
- preserveFocusDeferCount = _ref5$preserveFocusDe === void 0 ? false : _ref5$preserveFocusDe;
910
- if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin') || !(0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true)) {
911
- clearPendingTypedAgentMentionTimer();
912
- return;
913
- }
914
- var pendingTypedAgentMention = mentionPluginState === null || mentionPluginState === void 0 ? void 0 : mentionPluginState.pendingTypedAgentMention;
915
- if (!pendingTypedAgentMention) {
916
- clearPendingTypedAgentMentionTimer();
917
- return;
918
- }
919
- var timerKey = "".concat(pendingTypedAgentMention.localId, ":").concat(pendingTypedAgentMention.resetCount);
920
- if (timerKey === pendingTypedAgentMentionTimerKey) {
921
- return;
922
- }
923
- clearPendingTypedAgentMentionTimer({
924
- preserveFocusDeferCount: preserveFocusDeferCount
925
- });
926
- pendingTypedAgentMentionTimerKey = timerKey;
927
- pendingTypedAgentMentionTimer = setTimeout(function () {
928
- var _mentionPluginKey$get2;
929
- {
930
- var _options$getIsRovoPan3;
931
- // Suppress the agent-mention nudge when the Rovo panel is already open. Task
932
- // items are exempt only while platform_editor_agent_mentions_no_task_autofire
933
- // is off (they auto-fire instead). With it on they are suppressed like every
934
- // other block.
935
- var isTaskItemMention = pendingTypedAgentMention.parentNodeType === 'taskItem' && !(0, _fg.fg)('platform_editor_agent_mentions_no_task_autofire');
936
- if (!isTaskItemMention && options !== null && options !== void 0 && (_options$getIsRovoPan3 = options.getIsRovoPanelOpen) !== null && _options$getIsRovoPan3 !== void 0 && _options$getIsRovoPan3.call(options)) {
937
- // Dispatch a discard so pendingTypedAgentMention is nulled out of plugin
938
- // state.
939
- editorView.dispatch(editorView.state.tr.setMeta(_key.mentionPluginKey, {
940
- action: ACTIONS.DISCARD_PENDING_TYPED_AGENT_MENTION,
941
- params: {
942
- localId: pendingTypedAgentMention.localId,
943
- resetCount: pendingTypedAgentMention.resetCount
944
- }
945
- }));
946
- return;
947
- }
948
- }
949
- var latestPendingTypedAgentMention = (_mentionPluginKey$get2 = _key.mentionPluginKey.getState(editorView.state)) === null || _mentionPluginKey$get2 === void 0 ? void 0 : _mentionPluginKey$get2.pendingTypedAgentMention;
950
- if (!latestPendingTypedAgentMention || latestPendingTypedAgentMention.localId !== pendingTypedAgentMention.localId || latestPendingTypedAgentMention.resetCount !== pendingTypedAgentMention.resetCount) {
951
- return;
952
- }
953
- if (shouldDeferPendingTypedAgentMention() && pendingTypedAgentMentionFocusDeferCount < MAX_PENDING_TYPED_AGENT_MENTION_FOCUS_DEFERS) {
954
- pendingTypedAgentMentionFocusDeferCount++;
955
- pendingTypedAgentMentionTimerKey = null;
956
- _schedulePendingTypedAgentMentionTimer(_key.mentionPluginKey.getState(editorView.state), {
957
- preserveFocusDeferCount: true
958
- });
959
- return;
960
- }
961
- pendingTypedAgentMentionFocusDeferCount = 0;
962
- editorView.dispatch(editorView.state.tr.setMeta(_key.mentionPluginKey, {
963
- action: ACTIONS.COMMIT_PENDING_TYPED_AGENT_MENTION,
964
- params: {
965
- localId: pendingTypedAgentMention.localId,
966
- resetCount: pendingTypedAgentMention.resetCount
967
- }
968
- }));
969
- }, AGENT_MENTION_INACTIVITY_MS);
970
- };
971
191
  var providerHandler = function providerHandler(name, providerPromise) {
972
192
  switch (name) {
973
193
  case 'mentionProvider':
@@ -1013,25 +233,7 @@ function createMentionPlugin(_ref2) {
1013
233
  pmPluginFactoryParams.providerFactory.subscribe('mentionProvider', providerHandler);
1014
234
  }
1015
235
  return {
1016
- update: function update(view, prevState) {
1017
- var mentionPluginState = _key.mentionPluginKey.getState(view.state);
1018
- if (mentionPluginState === _key.mentionPluginKey.getState(prevState)) {
1019
- return;
1020
- }
1021
- if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_agent_mentions_separate_pm_plugin')) {
1022
- var _mentionPluginState$p;
1023
- _schedulePendingTypedAgentMentionTimer(mentionPluginState);
1024
-
1025
- // If a pasted agent mention has no name (cache miss), resolve it async
1026
- // via the mention provider and dispatch RESOLVE_PASTED_AGENT_MENTION_NAME
1027
- // so the nudge displays the correct name.
1028
- if ((0, _editorExperiment.editorExperiment)('platform_editor_agent_mentions', true) && (mentionPluginState === null || mentionPluginState === void 0 || (_mentionPluginState$p = mentionPluginState.pendingPastedAgentMention) === null || _mentionPluginState$p === void 0 ? void 0 : _mentionPluginState$p.id) != null && mentionPluginState !== null && mentionPluginState !== void 0 && mentionPluginState.mentionProvider && (0, _resource.isResolvingMentionProvider)(mentionPluginState.mentionProvider) && (0, _fg.fg)('platform_editor_agent_mentions_drop_one_fixes')) {
1029
- resolveAndDispatchPastedAgentMentionName(mentionPluginState.pendingPastedAgentMention.id, mentionPluginState.mentionProvider, pendingResolveMentionIds, view);
1030
- }
1031
- }
1032
- },
1033
236
  destroy: function destroy() {
1034
- clearPendingTypedAgentMentionTimer();
1035
237
  if (pmPluginFactoryParams.providerFactory) {
1036
238
  pmPluginFactoryParams.providerFactory.unsubscribe('mentionProvider', providerHandler);
1037
239
  }