@pheem49/mint 1.5.1 → 1.5.2

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 (33) hide show
  1. package/README.md +8 -0
  2. package/mint-cli.js +148 -921
  3. package/models/Shiroko_Model/Shiroko/Shiroko_Core//345/221/206/347/214/253.exp3.json +31 -1
  4. package/models/Shiroko_Model/Shiroko/Shiroko_Core//347/202/271/344/270/200/344/270/213.exp3.json +6 -1
  5. package/package.json +18 -20
  6. package/src/AI_Brain/proactive_engine.js +12 -2
  7. package/src/Automation_Layer/browser_automation.js +26 -24
  8. package/src/CLI/approval_handler.js +42 -0
  9. package/src/CLI/chat_ui.js +192 -7
  10. package/src/CLI/cli_colors.js +32 -0
  11. package/src/CLI/cli_formatters.js +89 -0
  12. package/src/CLI/code_agent.js +166 -57
  13. package/src/CLI/intent_detectors.js +181 -0
  14. package/src/CLI/interactive_chat.js +479 -0
  15. package/src/CLI/list_features.js +3 -0
  16. package/src/CLI/repo_summarizer.js +282 -0
  17. package/src/CLI/semantic_code_search.js +312 -0
  18. package/src/CLI/skill_manager.js +41 -0
  19. package/src/CLI/slash_command_handler.js +418 -0
  20. package/src/CLI/symbol_indexer.js +231 -0
  21. package/src/Channels/discord_bridge.js +11 -13
  22. package/src/Channels/line_bridge.js +10 -10
  23. package/src/Channels/slack_bridge.js +7 -12
  24. package/src/Channels/telegram_bridge.js +6 -14
  25. package/src/Channels/whatsapp_bridge.js +11 -9
  26. package/src/System/chat_history_manager.js +20 -12
  27. package/src/System/optional_require.js +23 -0
  28. package/src/UI/live2d_manager.js +211 -13
  29. package/src/UI/renderer.js +163 -3
  30. package/src/UI/settings.css +655 -420
  31. package/src/UI/settings.html +478 -432
  32. package/src/UI/settings.js +10 -8
  33. package/src/UI/styles.css +89 -25
@@ -604,6 +604,95 @@ function formatProviderInfo(providerInfo) {
604
604
  return model ? `${provider || 'AI'} • ${model}` : provider;
605
605
  }
606
606
 
607
+ function splitListOutro(text) {
608
+ const value = String(text || '').trim();
609
+ const markers = [
610
+ ' คุณภีมอยาก',
611
+ ' อยากให้',
612
+ ' อยากดู',
613
+ ' บอกมิ้นท์',
614
+ ' Would you',
615
+ ' Do you want',
616
+ ' Tell me'
617
+ ];
618
+
619
+ for (const marker of markers) {
620
+ const index = value.indexOf(marker);
621
+ if (index > 60) {
622
+ return {
623
+ main: value.slice(0, index).trim(),
624
+ outro: value.slice(index).trim()
625
+ };
626
+ }
627
+ }
628
+
629
+ return { main: value, outro: '' };
630
+ }
631
+
632
+ function buildAiTextBlocks(text) {
633
+ const normalized = normalizeAiText(text).replace(/\r\n/g, '\n').trim();
634
+ if (!normalized) return [];
635
+
636
+ const readable = normalized
637
+ .replace(/\s+(\d+)[.)]\s+/g, '\n$1. ')
638
+ .replace(/\n{3,}/g, '\n\n');
639
+
640
+ const blocks = [];
641
+ const lines = readable.split(/\n+/).map(line => line.trim()).filter(Boolean);
642
+
643
+ for (const line of lines) {
644
+ const numbered = line.match(/^\d+[.)]\s+(.+)$/);
645
+ const bullet = line.match(/^[-*•]\s+(.+)$/);
646
+
647
+ if (numbered || bullet) {
648
+ const content = numbered ? numbered[1] : bullet[1];
649
+ const { main, outro } = splitListOutro(content);
650
+ blocks.push({ type: 'bullet', text: main });
651
+ if (outro) blocks.push({ type: 'paragraph', text: outro });
652
+ } else {
653
+ blocks.push({ type: 'paragraph', text: line });
654
+ }
655
+ }
656
+
657
+ return blocks;
658
+ }
659
+
660
+ function appendFormattedMessageText(bubble, text, sender) {
661
+ if (sender !== 'ai') {
662
+ const textSpan = document.createElement('span');
663
+ textSpan.textContent = text;
664
+ bubble.appendChild(textSpan);
665
+ return;
666
+ }
667
+
668
+ const blocks = buildAiTextBlocks(text);
669
+ if (blocks.length === 0) return;
670
+
671
+ const wrapper = document.createElement('div');
672
+ wrapper.classList.add('formatted-ai-text');
673
+
674
+ for (const block of blocks) {
675
+ const item = document.createElement(block.type === 'bullet' ? 'div' : 'p');
676
+ item.classList.add(block.type === 'bullet' ? 'ai-list-item' : 'ai-paragraph');
677
+
678
+ if (block.type === 'bullet') {
679
+ const bullet = document.createElement('span');
680
+ bullet.classList.add('ai-list-bullet');
681
+ bullet.textContent = '•';
682
+ const content = document.createElement('span');
683
+ content.textContent = block.text;
684
+ item.appendChild(bullet);
685
+ item.appendChild(content);
686
+ } else {
687
+ item.textContent = block.text;
688
+ }
689
+
690
+ wrapper.appendChild(item);
691
+ }
692
+
693
+ bubble.appendChild(wrapper);
694
+ }
695
+
607
696
  function appendMessage(text, sender, base64Image = null, timestamp = null, options = {}) {
608
697
  const messageDiv = document.createElement('div');
609
698
  messageDiv.classList.add('message', `${sender}-message`);
@@ -625,9 +714,7 @@ function appendMessage(text, sender, base64Image = null, timestamp = null, optio
625
714
  }
626
715
 
627
716
  if (text) {
628
- const textSpan = document.createElement('span');
629
- textSpan.textContent = text;
630
- bubble.appendChild(textSpan);
717
+ appendFormattedMessageText(bubble, text, sender);
631
718
  }
632
719
 
633
720
  bubbleWrapper.appendChild(bubble);
@@ -673,6 +760,9 @@ function normalizeAiText(input) {
673
760
  function splitAiMessages(text) {
674
761
  const normalized = normalizeAiText(text).trim();
675
762
  if (!normalized) return [];
763
+ if (/(^|\s)\d+[.)]\s+/.test(normalized) || /(^|\n)\s*[-*•]\s+/.test(normalized)) {
764
+ return [normalized];
765
+ }
676
766
  const byBlankLine = normalized
677
767
  .split(/\n\s*\n/)
678
768
  .map((part) => part.trim())
@@ -1172,6 +1262,76 @@ if (changeExpressionBtn) {
1172
1262
  });
1173
1263
  }
1174
1264
 
1265
+ // Cycle Live2D accessories
1266
+ const accessoryStorageKey = 'mint-live2d-accessories';
1267
+ const accessoryCycleBtn = document.getElementById('accessory-cycle-btn');
1268
+ const accessoryCycleLabel = document.getElementById('accessory-cycle-label');
1269
+ const accessoryCycleOrder = [null, 'glasses', 'pen', 'cat'];
1270
+ const accessoryLabels = {
1271
+ glasses: 'Glasses',
1272
+ pen: 'Pen',
1273
+ cat: 'Cat'
1274
+ };
1275
+ let savedAccessories = {};
1276
+ try {
1277
+ savedAccessories = JSON.parse(localStorage.getItem(accessoryStorageKey) || '{}') || {};
1278
+ } catch (_) {
1279
+ savedAccessories = {};
1280
+ }
1281
+
1282
+ const getSavedAccessoryId = () => accessoryCycleOrder.find(id => id && savedAccessories[id] === true) || null;
1283
+
1284
+ function updateAccessoryCycleButton(accessoryId) {
1285
+ if (!accessoryCycleBtn) return;
1286
+ const isActive = Boolean(accessoryId);
1287
+ const label = accessoryId ? accessoryLabels[accessoryId] : 'Accessory';
1288
+ accessoryCycleBtn.classList.toggle('active', isActive);
1289
+ accessoryCycleBtn.setAttribute('aria-pressed', String(isActive));
1290
+ accessoryCycleBtn.title = `Accessory: ${label}`;
1291
+ if (accessoryCycleLabel) accessoryCycleLabel.textContent = label;
1292
+ }
1293
+
1294
+ let currentAccessoryId = getSavedAccessoryId();
1295
+ updateAccessoryCycleButton(currentAccessoryId);
1296
+
1297
+ if (accessoryCycleBtn) {
1298
+ accessoryCycleBtn.addEventListener('click', () => {
1299
+ const currentIndex = accessoryCycleOrder.indexOf(currentAccessoryId);
1300
+ currentAccessoryId = accessoryCycleOrder[(currentIndex + 1) % accessoryCycleOrder.length];
1301
+ updateAccessoryCycleButton(currentAccessoryId);
1302
+
1303
+ if (window.Live2DManager) {
1304
+ Live2DManager.setExclusiveAccessory(currentAccessoryId, true);
1305
+ } else {
1306
+ savedAccessories = {};
1307
+ if (currentAccessoryId) savedAccessories[currentAccessoryId] = true;
1308
+ localStorage.setItem(accessoryStorageKey, JSON.stringify(savedAccessories));
1309
+ }
1310
+ });
1311
+ }
1312
+
1313
+ // Toggle Live2D model interaction
1314
+ const toggleInteractionBtn = document.getElementById('toggle-interaction-btn');
1315
+ if (toggleInteractionBtn) {
1316
+ const savedInteractionEnabled = localStorage.getItem('mint-model-interaction-enabled') !== 'false';
1317
+ toggleInteractionBtn.classList.toggle('active', savedInteractionEnabled);
1318
+ toggleInteractionBtn.setAttribute('aria-pressed', String(savedInteractionEnabled));
1319
+ if (window.Live2DManager) {
1320
+ Live2DManager.setInteractionEnabled(savedInteractionEnabled);
1321
+ }
1322
+
1323
+ toggleInteractionBtn.addEventListener('click', () => {
1324
+ const isEnabled = !toggleInteractionBtn.classList.contains('active');
1325
+ toggleInteractionBtn.classList.toggle('active', isEnabled);
1326
+ toggleInteractionBtn.setAttribute('aria-pressed', String(isEnabled));
1327
+ if (window.Live2DManager) {
1328
+ Live2DManager.setInteractionEnabled(isEnabled, true);
1329
+ } else {
1330
+ localStorage.setItem('mint-model-interaction-enabled', String(isEnabled));
1331
+ }
1332
+ });
1333
+ }
1334
+
1175
1335
  // Toggle Live2D interaction area guide
1176
1336
  const interactionGuideBtn = document.getElementById('interaction-guide-btn');
1177
1337
  if (interactionGuideBtn && modelShell) {