lisichatbot 2.0.8 → 2.1.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +245 -40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisichatbot",
3
- "version": "2.0.8",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -19,7 +19,11 @@ let chatState = {
19
19
  returnToStep: null,
20
20
  completed: false,
21
21
  editPath: [], // ✅ NEW: Array of step names/numbers to edit in sequence
22
- chatMode: 'create' // ✅ NEW: Track if in 'create' or 'edit' mode
22
+ chatMode: 'create', // ✅ NEW: Track if in 'create' or 'edit' mode
23
+ editSteps: null, // ✅ Array of step indices to walk through in edit-steps mode
24
+ editStepsIndex: 0, // ✅ Current position within editSteps array
25
+ onEditComplete: null, // ✅ Callback when editSteps flow finishes
26
+ editFinalButtonText: null // ✅ Button text for the last step in editSteps
23
27
  };
24
28
 
25
29
  let elements = {
@@ -197,45 +201,74 @@ function updateEditIcons() {
197
201
  const allBotMessages = elements.messages.querySelectorAll('[data-chat-element="bot-message-wrapper"]');
198
202
 
199
203
  console.log(`\n🔄 Updating edit icons - Current step: ${chatState.step}, Completed: ${chatState.completed}`);
200
-
204
+
201
205
  allBotMessages.forEach(wrapper => {
202
206
  const stepNumber = parseInt(wrapper.getAttribute('data-chat-step'));
203
207
  const editIcon = wrapper.querySelector('[data-chat-element="bot-edit-icon"]');
204
208
  const isLatest = wrapper.hasAttribute('data-chat-latest');
205
-
209
+
206
210
  if (editIcon && !isNaN(stepNumber)) {
207
211
  const stepData = flowData.flow[stepNumber];
208
212
  const hasInput = stepData && !!stepData.input;
209
-
213
+
210
214
  // ✅ NEW: Check if edit is disabled for this step
211
215
  if (stepData && stepData.disableEdit === true) {
212
216
  editIcon.style.setProperty('display', 'none', 'important');
213
217
  console.log(` 🚫 Step ${stepNumber}: Icon HIDDEN (edit disabled)`);
214
218
  return;
215
219
  }
216
-
220
+
217
221
  // ✅ FIX: In edit mode, keep edit icons visible even after completion
218
222
  if (chatState.completed && chatState.chatMode !== 'edit') {
219
223
  editIcon.style.setProperty('display', 'none', 'important');
220
224
  console.log(` 🏁 Step ${stepNumber}: Icon HIDDEN (flow completed in create mode)`);
221
225
  return;
222
226
  }
223
-
227
+
224
228
  // ✅ NEW: Check if edit icon should be forced to show (even without input)
225
229
  const forceShowEdit = stepData && stepData.showEditIcon === true;
226
-
230
+
227
231
  // ✅ FIX: In edit mode, show edit icons for all completed steps (not just previous)
228
232
  const shouldShowInEditMode = chatState.chatMode === 'edit' && chatState.completed && isLatest;
229
233
  const shouldShowNormally = stepNumber < chatState.step && isLatest;
230
-
231
- if ((hasInput || forceShowEdit) && (shouldShowInEditMode || shouldShowNormally)) {
234
+ // ✅ In editSteps mode, show edit icons for steps already visited in the editSteps list
235
+ const shouldShowInEditSteps = chatState.editSteps && chatState.editSteps.length > 0 &&
236
+ chatState.editSteps.includes(stepNumber) &&
237
+ chatState.editSteps.indexOf(stepNumber) < chatState.editStepsIndex && isLatest;
238
+
239
+ if ((hasInput || forceShowEdit) && (shouldShowInEditMode || shouldShowNormally || shouldShowInEditSteps)) {
232
240
  editIcon.onclick = (e) => {
233
241
  e.stopPropagation();
234
242
  e.preventDefault();
235
243
  console.log(`\n🖱️ EDIT ICON CLICKED (from updateEditIcons) - Step ${stepNumber}`);
236
244
  console.log(` Current step: ${chatState.step}`);
237
-
238
- // ✅ NEW: Check if this step has an editSteps path
245
+
246
+ // ✅ In editSteps mode, go back to that step within the editSteps flow
247
+ if (chatState.editSteps && chatState.editSteps.length > 0) {
248
+ const editStepIdx = chatState.editSteps.indexOf(stepNumber);
249
+ if (editStepIdx !== -1) {
250
+ console.log(` 🛤️ editSteps: jumping back to editSteps[${editStepIdx}] (step ${stepNumber})`);
251
+ chatState.editStepsIndex = editStepIdx;
252
+ chatState.step = stepNumber;
253
+ chatState.currentSelection = null;
254
+
255
+ // Remove history from this editStep onward
256
+ const stepsToRemove = chatState.editSteps.slice(editStepIdx);
257
+ chatState.history = chatState.history.filter(h => !stepsToRemove.includes(h.step));
258
+
259
+ // Set prefill override
260
+ const targetStepData = flowData.flow[stepNumber];
261
+ if (targetStepData?.input?.field && chatState.data[targetStepData.input.field] !== undefined) {
262
+ chatState.prefillOverrideFields = [targetStepData.input.field];
263
+ }
264
+
265
+ disableNextButton();
266
+ showNextStep();
267
+ return;
268
+ }
269
+ }
270
+
271
+ // ✅ Check if this step has an editSteps path (normal mode)
239
272
  if (stepData.editSteps && Array.isArray(stepData.editSteps) && stepData.editSteps.length > 0) {
240
273
  console.log(` 🛤️ Step has editSteps path:`, stepData.editSteps);
241
274
  startEditPath(stepData.editSteps);
@@ -320,8 +353,9 @@ function renderMultiSelectDropdown(options, field) {
320
353
  // ✅ NEW: Check if prefill is disabled for this step
321
354
  const currentStep = flowData.flow[chatState.step];
322
355
  const hasOverride = chatState.prefillOverrideFields && chatState.prefillOverrideFields.includes(field);
323
- const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride;
324
-
356
+ const isEditing = (chatState.returnToStep !== null && chatState.returnToStep !== undefined) || (chatState.editSteps && chatState.editSteps.length > 0);
357
+ const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride && !isEditing;
358
+
325
359
  const existingData = disablePrefill ? [] : (chatState.data[field] || []);
326
360
  const selectedValues = new Set(existingData);
327
361
 
@@ -621,14 +655,15 @@ function renderOptions(options, field, isSingleSelect = true) {
621
655
  // ✅ NEW: Check if prefill is disabled for this step
622
656
  const currentStep = flowData.flow[chatState.step];
623
657
  const hasOverride = chatState.prefillOverrideFields && chatState.prefillOverrideFields.includes(field);
624
- const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride;
625
-
658
+ const isEditing = (chatState.returnToStep !== null && chatState.returnToStep !== undefined) || (chatState.editSteps && chatState.editSteps.length > 0);
659
+ const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride && !isEditing;
660
+
626
661
  const existingData = disablePrefill ? (isSingleSelect ? null : []) : chatState.data[field];
627
-
662
+
628
663
  if (disablePrefill) {
629
664
  console.log(`⏭️ Pre-fill disabled for ${field} - starting fresh`);
630
665
  } else {
631
- if (hasOverride) {
666
+ if (hasOverride || isEditing) {
632
667
  console.log(` 🔓 Pre-fill override active for ${field}:`, existingData);
633
668
  } else {
634
669
  console.log(`📝 Pre-filling ${field}:`, existingData);
@@ -761,14 +796,15 @@ function renderColorOptions(options, field) {
761
796
  // ✅ NEW: Check if prefill is disabled for this step
762
797
  const currentStep = flowData.flow[chatState.step];
763
798
  const hasOverride = chatState.prefillOverrideFields && chatState.prefillOverrideFields.includes(field);
764
- const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride;
765
-
799
+ const isEditing = (chatState.returnToStep !== null && chatState.returnToStep !== undefined) || (chatState.editSteps && chatState.editSteps.length > 0);
800
+ const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride && !isEditing;
801
+
766
802
  const existingData = disablePrefill ? [] : chatState.data[field];
767
-
803
+
768
804
  if (disablePrefill) {
769
805
  console.log(`⏭️ Pre-fill disabled for ${field} (color) - starting fresh`);
770
806
  } else {
771
- if (hasOverride) {
807
+ if (hasOverride || isEditing) {
772
808
  console.log(` 🔓 Pre-fill override active for ${field} (color):`, existingData);
773
809
  } else {
774
810
  console.log(`📝 Pre-filling ${field} (color):`, existingData);
@@ -898,12 +934,14 @@ function renderCustomSelectOptions(options, field, customConfig) {
898
934
  // ✅ NEW: Check if prefill is disabled for this step
899
935
  const currentStep = flowData.flow[chatState.step];
900
936
  const hasOverride = chatState.prefillOverrideFields && chatState.prefillOverrideFields.includes(field);
901
- const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride;
902
-
937
+ const isEditing = (chatState.returnToStep !== null && chatState.returnToStep !== undefined) || (chatState.editSteps && chatState.editSteps.length > 0);
938
+ const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride && !isEditing;
939
+
903
940
  console.log(`\n🔍 === PREFILL DEBUG for field: ${field} ===`);
904
941
  console.log(` disableInputValuePrefill:`, currentStep?.disableInputValuePrefill);
905
942
  console.log(` prefillOverrideFields:`, chatState.prefillOverrideFields);
906
943
  console.log(` hasOverride:`, hasOverride);
944
+ console.log(` isEditing:`, isEditing);
907
945
  console.log(` disablePrefill:`, disablePrefill);
908
946
  console.log(` chatState.data[${field}]:`, chatState.data[field]);
909
947
 
@@ -1076,7 +1114,7 @@ function renderCustomSelectOptions(options, field, customConfig) {
1076
1114
  // ✅ FIX: Enable Next button if option is pre-selected
1077
1115
  if (hasPreselectedOption) {
1078
1116
  // Set currentSelection
1079
- const isCustomSelected = Array.isArray(existingData) && existingData.length === 2;
1117
+ const isCustomSelected = Array.isArray(existingData) && existingData.length === 2 && !hasMatchingNormalOption;
1080
1118
 
1081
1119
  if (isCustomSelected) {
1082
1120
  // Custom range selected - currentSelection will be set by validateMinMax
@@ -1687,8 +1725,9 @@ function renderTextInput(field, inputType = 'text', inputConfig = {}) {
1687
1725
  // ✅ NEW: Check if prefill is disabled for this step
1688
1726
  const currentStep = flowData.flow[chatState.step];
1689
1727
  const hasOverride = chatState.prefillOverrideFields && chatState.prefillOverrideFields.includes(field);
1690
- const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride;
1691
-
1728
+ const isEditing = (chatState.returnToStep !== null && chatState.returnToStep !== undefined) || (chatState.editSteps && chatState.editSteps.length > 0);
1729
+ const disablePrefill = currentStep?.disableInputValuePrefill === true && !hasOverride && !isEditing;
1730
+
1692
1731
  const existingValue = disablePrefill ? null : chatState.data[field];
1693
1732
 
1694
1733
  if (disablePrefill) {
@@ -2535,6 +2574,89 @@ async function handleNext() {
2535
2574
  chatState.currentSelection = null;
2536
2575
  disableNextButton();
2537
2576
 
2577
+ // ✅ Edit-steps mode: jump to next step in the list or finish
2578
+ if (chatState.editSteps && chatState.editSteps.length > 0) {
2579
+ const currentEditIndex = chatState.editStepsIndex;
2580
+ const nextEditIndex = currentEditIndex + 1;
2581
+
2582
+ if (nextEditIndex < chatState.editSteps.length) {
2583
+ // More steps to edit
2584
+ chatState.editStepsIndex = nextEditIndex;
2585
+ const nextStepIndex = chatState.editSteps[nextEditIndex];
2586
+ console.log(`\n🛤️ Edit-steps: moving to step ${nextEditIndex + 1}/${chatState.editSteps.length} (flow index ${nextStepIndex})`);
2587
+
2588
+ chatState.step = nextStepIndex;
2589
+
2590
+ // Set prefillOverrideFields for the next step
2591
+ const targetStep = flowData.flow[nextStepIndex];
2592
+ if (targetStep?.input?.field && chatState.data[targetStep.input.field] !== undefined) {
2593
+ chatState.prefillOverrideFields = [targetStep.input.field];
2594
+ }
2595
+
2596
+ const allRangeWrappers = document.querySelectorAll('[data-chat-element="range-wrapper"]');
2597
+ allRangeWrappers.forEach(wrapper => {
2598
+ wrapper.style.display = 'none';
2599
+ });
2600
+
2601
+ updateEditIcons();
2602
+ await showNextStep();
2603
+ scrollToBottom();
2604
+ return;
2605
+ } else {
2606
+ // All edit steps done - call onEditComplete
2607
+ console.log(`\n✅ Edit-steps complete! All ${chatState.editSteps.length} steps finished.`);
2608
+
2609
+ const dataCopy = { ...chatState.data };
2610
+ const historyCopy = [...chatState.history];
2611
+ const callback = chatState.onEditComplete;
2612
+
2613
+ // Clean up edit-steps state
2614
+ chatState.editSteps = null;
2615
+ chatState.editStepsIndex = 0;
2616
+ chatState.onEditComplete = null;
2617
+ chatState.editFinalButtonText = null;
2618
+ chatState.completed = true;
2619
+
2620
+ // Hide inputs and next button
2621
+ const allRangeWrappers = document.querySelectorAll('[data-chat-element="range-wrapper"]');
2622
+ allRangeWrappers.forEach(wrapper => { wrapper.style.display = 'none'; });
2623
+
2624
+ const previousInputs = elements.messages.querySelectorAll(
2625
+ '[data-chat-element="options-wrapper"], ' +
2626
+ '[data-chat-element="text-input"]:not([style*="display: none"]), ' +
2627
+ '[data-chat-element="number-input"]:not([style*="display: none"]), ' +
2628
+ '[data-chat-element="multi-select-dropdown"]:not([style*="display: none"])'
2629
+ );
2630
+ previousInputs.forEach(input => { input.style.display = 'none'; });
2631
+
2632
+ if (elements.nextBtn) {
2633
+ elements.nextBtn.style.display = 'none';
2634
+ }
2635
+
2636
+ updateEditIcons();
2637
+
2638
+ // Dispatch event
2639
+ if (typeof window !== 'undefined') {
2640
+ const event = new CustomEvent('conversationalFlowEditStepsComplete', {
2641
+ detail: { data: dataCopy, history: historyCopy }
2642
+ });
2643
+ window.dispatchEvent(event);
2644
+ }
2645
+
2646
+ // Call onEditComplete callback with updated data
2647
+ if (callback) {
2648
+ console.log('📞 Calling onEditComplete with data:', dataCopy);
2649
+ try {
2650
+ callback(dataCopy);
2651
+ } catch (error) {
2652
+ console.error('Error in onEditComplete callback:', error);
2653
+ }
2654
+ }
2655
+
2656
+ return;
2657
+ }
2658
+ }
2659
+
2538
2660
  if (chatState.returnToStep !== null) {
2539
2661
  const targetStep = chatState.returnToStep;
2540
2662
  console.log(`\n🔙 Returning to saved step ${targetStep} (edited step complete)`);
@@ -2642,7 +2764,12 @@ async function handleNext() {
2642
2764
  });
2643
2765
 
2644
2766
  updateEditIcons();
2645
- await showNextStep();
2767
+
2768
+ if (chatState.step >= flowData.flow.length) {
2769
+ handleCompletion();
2770
+ } else {
2771
+ await showNextStep();
2772
+ }
2646
2773
  return;
2647
2774
  }
2648
2775
  }
@@ -2689,6 +2816,12 @@ function findNextAccessibleStep(currentStep) {
2689
2816
  }
2690
2817
 
2691
2818
  async function showNextStep() {
2819
+ // ✅ FIX: Bounds check - if step is out of range, trigger completion
2820
+ if (chatState.step >= flowData.flow.length) {
2821
+ handleCompletion();
2822
+ return;
2823
+ }
2824
+
2692
2825
  const nextStep = flowData.flow[chatState.step];
2693
2826
 
2694
2827
  // ✅ NEW: Clean up any previously injected elements (from addElements)
@@ -2723,7 +2856,12 @@ async function showNextStep() {
2723
2856
  }
2724
2857
 
2725
2858
  // ✅ NEW: Check if step should be displayed based on condition
2726
- if (nextStep.shouldDisplay) {
2859
+ // ✅ Skip shouldDisplay check entirely if this step is explicitly in editSteps
2860
+ const isInEditSteps = chatState.editSteps && chatState.editSteps.includes(chatState.step);
2861
+ if (isInEditSteps) {
2862
+ console.log(` 🔓 Step ${chatState.step} is in editSteps - overriding shouldDisplay, always showing`);
2863
+ }
2864
+ if (nextStep.shouldDisplay && !isInEditSteps) {
2727
2865
  let shouldShow = false;
2728
2866
 
2729
2867
  if (typeof nextStep.shouldDisplay === 'function') {
@@ -2745,13 +2883,31 @@ async function showNextStep() {
2745
2883
 
2746
2884
  if (!shouldShow) {
2747
2885
  console.log(` ⏭️ Skipping step ${chatState.step} (shouldDisplay returned false)`);
2886
+
2887
+ // ✅ In editSteps mode, skip to the next step in the editSteps list
2888
+ if (chatState.editSteps && chatState.editSteps.length > 0) {
2889
+ const nextEditIndex = chatState.editStepsIndex + 1;
2890
+ if (nextEditIndex < chatState.editSteps.length) {
2891
+ chatState.editStepsIndex = nextEditIndex;
2892
+ chatState.step = chatState.editSteps[nextEditIndex];
2893
+ console.log(` 🛤️ editSteps: skipping to next edit step ${chatState.step}`);
2894
+ await showNextStep();
2895
+ return;
2896
+ } else {
2897
+ // All remaining edit steps should be skipped - trigger edit completion
2898
+ console.log(` 🛤️ editSteps: no more steps - completing`);
2899
+ handleCompletion();
2900
+ return;
2901
+ }
2902
+ }
2903
+
2748
2904
  chatState.step++;
2749
-
2905
+
2750
2906
  if (chatState.step >= flowData.flow.length) {
2751
2907
  handleCompletion();
2752
2908
  return;
2753
2909
  }
2754
-
2910
+
2755
2911
  // Recursively check next step
2756
2912
  await showNextStep();
2757
2913
  return;
@@ -3331,12 +3487,20 @@ async function showNextStep() {
3331
3487
 
3332
3488
  if (elements.nextBtn) {
3333
3489
  const nextBtnTextElement = elements.nextBtn.querySelector('[data-chat-element="next-button-text"]');
3334
-
3490
+
3335
3491
  if (nextBtnTextElement) {
3336
- // ✅ Priority: step-level > global config > original
3492
+ // ✅ Priority: editFinalButtonText (last edit step) > step-level > global config > original
3337
3493
  let buttonText;
3338
-
3339
- if (nextStep.nextButtonText) {
3494
+
3495
+ // Check if this is the last step in editSteps mode
3496
+ const isLastEditStep = chatState.editSteps &&
3497
+ chatState.editStepsIndex === chatState.editSteps.length - 1 &&
3498
+ chatState.editFinalButtonText;
3499
+
3500
+ if (isLastEditStep) {
3501
+ buttonText = chatState.editFinalButtonText;
3502
+ console.log(` 📝 Next button text: "${buttonText}" (editFinalButtonText - last edit step)`);
3503
+ } else if (nextStep.nextButtonText) {
3340
3504
  // Step-level override takes highest priority
3341
3505
  buttonText = nextStep.nextButtonText;
3342
3506
  console.log(` 📝 Next button text: "${buttonText}" (step-level)`);
@@ -3349,7 +3513,7 @@ async function showNextStep() {
3349
3513
  buttonText = elements.originalNextBtnText;
3350
3514
  console.log(` 📝 Next button text: "${buttonText}" (original)`);
3351
3515
  }
3352
-
3516
+
3353
3517
  nextBtnTextElement.textContent = buttonText;
3354
3518
  } else if (nextStep.nextButtonText || config.nextButtonText) {
3355
3519
  console.warn(` ⚠️ nextButtonText specified but next-button-text element not found`);
@@ -3422,16 +3586,16 @@ function handleCompletion() {
3422
3586
 
3423
3587
  if (typeof window !== 'undefined') {
3424
3588
  const event = new CustomEvent('conversationalFlowComplete', {
3425
- detail: {
3426
- data: chatState.data,
3427
- history: chatState.history
3589
+ detail: {
3590
+ data: { ...chatState.data },
3591
+ history: [...chatState.history]
3428
3592
  }
3429
3593
  });
3430
3594
  window.dispatchEvent(event);
3431
3595
  }
3432
3596
 
3433
3597
  if (flowData.onComplete && typeof flowData.onComplete === 'function') {
3434
- flowData.onComplete(chatState.data);
3598
+ flowData.onComplete({ ...chatState.data });
3435
3599
  }
3436
3600
  }
3437
3601
 
@@ -3497,6 +3661,43 @@ function init(flowName, flowConfig, options = {}) {
3497
3661
  chatState.history = [];
3498
3662
  chatState.currentSelection = null;
3499
3663
 
3664
+ // ✅ NEW: Edit-steps mode - only walk through specific steps by name
3665
+ if (options.editSteps && Array.isArray(options.editSteps) && options.editSteps.length > 0) {
3666
+ // Resolve step names to indices
3667
+ const resolvedSteps = [];
3668
+ options.editSteps.forEach(stepName => {
3669
+ const index = flowConfig.flow.findIndex(s => s.name === stepName);
3670
+ if (index !== -1) {
3671
+ resolvedSteps.push(index);
3672
+ console.log(` 🔍 editSteps: "${stepName}" → step index ${index}`);
3673
+ } else {
3674
+ console.warn(` ⚠️ editSteps: step name "${stepName}" not found in flow`);
3675
+ }
3676
+ });
3677
+
3678
+ if (resolvedSteps.length > 0) {
3679
+ chatState.editSteps = resolvedSteps;
3680
+ chatState.editStepsIndex = 0;
3681
+ chatState.onEditComplete = typeof options.onEditComplete === 'function' ? options.onEditComplete : null;
3682
+ chatState.editFinalButtonText = options.editFinalButtonText || null;
3683
+ chatState.step = resolvedSteps[0]; // Start at the first edit step
3684
+ console.log(`🛤️ Edit-steps mode: ${resolvedSteps.length} steps to edit`, resolvedSteps);
3685
+ console.log(` onEditComplete: ${chatState.onEditComplete ? 'provided' : 'not provided'}`);
3686
+ console.log(` editFinalButtonText: ${chatState.editFinalButtonText || 'not set'}`);
3687
+ } else {
3688
+ console.warn('⚠️ editSteps provided but no valid step names found - using normal flow');
3689
+ chatState.editSteps = null;
3690
+ chatState.editStepsIndex = 0;
3691
+ chatState.onEditComplete = null;
3692
+ chatState.editFinalButtonText = null;
3693
+ }
3694
+ } else {
3695
+ chatState.editSteps = null;
3696
+ chatState.editStepsIndex = 0;
3697
+ chatState.onEditComplete = null;
3698
+ chatState.editFinalButtonText = null;
3699
+ }
3700
+
3500
3701
  elements.messages = elements.container.querySelector('[data-chat-element="messages-container"]');
3501
3702
  elements.nextBtn = elements.container.querySelector('[data-chat-element="next-button"]');
3502
3703
  elements.cancelBtn = elements.container.querySelector('[data-chat-element="cancel-button"]');
@@ -3600,7 +3801,11 @@ function reset() {
3600
3801
  chatState.history = [];
3601
3802
  chatState.currentSelection = null;
3602
3803
  chatState.chatMode = 'create'; // ✅ Reset to create mode
3603
-
3804
+ chatState.editSteps = null;
3805
+ chatState.editStepsIndex = 0;
3806
+ chatState.onEditComplete = null;
3807
+ chatState.editFinalButtonText = null;
3808
+
3604
3809
  // ✅ Move back any injected elements before clearing
3605
3810
  if (elements.messages) {
3606
3811
  const injectedElements = elements.messages.querySelectorAll('[data-chat-injected="true"]');